diff --git a/frontend/app/components/dashboard/FeaturedGoalCard.tsx b/frontend/app/components/dashboard/FeaturedGoalCard.tsx index c97d03a82..036d35884 100644 --- a/frontend/app/components/dashboard/FeaturedGoalCard.tsx +++ b/frontend/app/components/dashboard/FeaturedGoalCard.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { Plane, Calendar, ChevronRight } from 'lucide-react'; import CircularProgress from './CircularProgress'; +import Button from '../ui/Button'; interface FeaturedGoalCardProps { title: string; @@ -82,13 +83,12 @@ const FeaturedGoalCard: React.FC = ({
- - + +
diff --git a/frontend/app/components/dashboard/GoalCard.tsx b/frontend/app/components/dashboard/GoalCard.tsx index 77d4948c0..547a7bcfc 100644 --- a/frontend/app/components/dashboard/GoalCard.tsx +++ b/frontend/app/components/dashboard/GoalCard.tsx @@ -1,6 +1,7 @@ import React from "react"; import Link from "next/link"; import { Calendar, ChevronRight } from "lucide-react"; +import Button from "../ui/Button"; export type GoalStatus = "On Track" | "At Risk" | "Completed" | "Paused"; @@ -111,9 +112,9 @@ export default function GoalCard({
- + = ({ {/* ── Action buttons ── */}
- - +
); diff --git a/frontend/app/components/dashboard/PassedProposalCard.tsx b/frontend/app/components/dashboard/PassedProposalCard.tsx index 46ac1a740..b6dcb2b9b 100644 --- a/frontend/app/components/dashboard/PassedProposalCard.tsx +++ b/frontend/app/components/dashboard/PassedProposalCard.tsx @@ -2,6 +2,7 @@ import React from "react"; import { CheckCircle2, ChevronRight } from "lucide-react"; +import Button from "../ui/Button"; export interface PassedProposal { id: string; @@ -74,9 +75,9 @@ export default function PassedProposalCard({ proposal }: { proposal: PassedPropo
- +
- +
{/* Mobile-only full-width Vote button placed as the last row */}
- +
); diff --git a/frontend/app/components/dashboard/SavingsPoolCard.tsx b/frontend/app/components/dashboard/SavingsPoolCard.tsx index 6334e214e..5901fe903 100644 --- a/frontend/app/components/dashboard/SavingsPoolCard.tsx +++ b/frontend/app/components/dashboard/SavingsPoolCard.tsx @@ -1,6 +1,7 @@ "use client"; import React from "react"; +import Button from "../ui/Button"; export type RiskLevel = "Low Risk" | "Medium Risk" | "High Risk"; @@ -106,12 +107,13 @@ const SavingsPoolCard: React.FC = ({ {/* Deposit Button */} - + ); }; diff --git a/frontend/app/components/ui/Button.tsx b/frontend/app/components/ui/Button.tsx new file mode 100644 index 000000000..62315319c --- /dev/null +++ b/frontend/app/components/ui/Button.tsx @@ -0,0 +1,87 @@ +"use client"; + +import React from "react"; + +type ButtonVariant = "primary" | "secondary" | "outline" | "ghost" | "danger"; +type ButtonSize = "sm" | "md" | "lg"; + +interface ButtonProps extends React.ButtonHTMLAttributes { + variant?: ButtonVariant; + size?: ButtonSize; + loading?: boolean; + leftIcon?: React.ReactNode; + rightIcon?: React.ReactNode; + fullWidth?: boolean; +} + +const variantStyles: Record = { + primary: + "bg-cyan-500 hover:bg-cyan-400 text-[#061a1a] font-bold shadow-lg hover:shadow-[0_15px_30px_rgba(0,212,192,0.4)] active:scale-95", + secondary: + "bg-cyan-500/20 border border-cyan-500/30 text-cyan-300 font-semibold hover:bg-cyan-500/30", + outline: + "border border-cyan-400/40 text-cyan-200 hover:text-white hover:border-cyan-300", + ghost: + "bg-transparent text-[#5e8c96] hover:text-[#e2f8f8]", + danger: + "bg-red-500/20 border border-red-500/30 text-red-300 hover:bg-red-500/30 hover:text-red-200", +}; + +const sizeStyles: Record = { + sm: "px-3 py-1.5 text-xs rounded-lg gap-1", + md: "px-5 py-2.5 text-sm rounded-xl gap-2", + lg: "px-6 py-3.5 text-base rounded-2xl gap-2", +}; + +export default function Button({ + variant = "primary", + size = "md", + loading = false, + leftIcon, + rightIcon, + fullWidth = false, + disabled, + children, + className = "", + ...props +}: ButtonProps) { + const baseStyles = + "inline-flex items-center justify-center transition-all duration-300 cursor-pointer disabled:cursor-not-allowed disabled:opacity-70"; + + const widthClass = fullWidth ? "w-full" : ""; + + return ( + + ); +} diff --git a/frontend/app/dashboard/notifications/page.tsx b/frontend/app/dashboard/notifications/page.tsx index 0d904dc31..3a16f2d3b 100644 --- a/frontend/app/dashboard/notifications/page.tsx +++ b/frontend/app/dashboard/notifications/page.tsx @@ -2,6 +2,7 @@ import React, { useState } from "react"; import { Bell, CheckCheck, ArrowUpRight, ShieldCheck, Target, Megaphone } from "lucide-react"; +import Button from "../../../components/ui/Button"; type NotifType = "transaction" | "governance" | "milestone" | "announcement"; @@ -77,13 +78,14 @@ export default function NotificationsPage() { {unread > 0 && ( - + )} diff --git a/frontend/app/dashboard/portfolio/page.tsx b/frontend/app/dashboard/portfolio/page.tsx index efb404ea5..3880b4f95 100644 --- a/frontend/app/dashboard/portfolio/page.tsx +++ b/frontend/app/dashboard/portfolio/page.tsx @@ -2,6 +2,7 @@ import React, { useState } from "react"; import { Briefcase, TrendingUp, TrendingDown, Download, MoreHorizontal } from "lucide-react"; +import Button from "../../components/ui/Button"; const ASSETS = [ { name: "USDC Flexible", type: "Savings", balance: 2400, value: 2400, apy: 6.5, pnl: 156, pnlPct: 6.9 }, @@ -66,14 +67,16 @@ export default function PortfolioPage() {

All assets and positions

- + Export CSV + {/* Summary cards */} diff --git a/frontend/app/dashboard/referrals/page.tsx b/frontend/app/dashboard/referrals/page.tsx index 7c6a963fc..375ad2695 100644 --- a/frontend/app/dashboard/referrals/page.tsx +++ b/frontend/app/dashboard/referrals/page.tsx @@ -3,6 +3,7 @@ import React, { useState } from "react"; import { Users, Copy, Check, Trophy, Gift, TrendingUp } from "lucide-react"; import { env } from "../../lib/env"; +import Button from "../../components/ui/Button"; const REFERRED_USERS = [ { name: "Alice K.", joined: "Apr 20, 2026", status: "Active", reward: "$12.00" }, @@ -71,13 +72,14 @@ export default function ReferralsPage() {
{REFERRAL_LINK}
- +

Earn $12 USDC for every friend who deposits at least $100. diff --git a/frontend/app/dashboard/savings-pools/page.tsx b/frontend/app/dashboard/savings-pools/page.tsx index f079ade91..503cd0e00 100644 --- a/frontend/app/dashboard/savings-pools/page.tsx +++ b/frontend/app/dashboard/savings-pools/page.tsx @@ -13,6 +13,7 @@ import SavingsPoolCard, { type SavingsPool, } from "@/app/components/dashboard/SavingsPoolCard"; import { useToast } from "@/app/context/ToastContext"; +import Button from "../../components/ui/Button"; export default function GoalBasedSavingsPage() { const [searchQuery, setSearchQuery] = useState(""); @@ -134,9 +135,9 @@ export default function GoalBasedSavingsPage() { - + @@ -224,12 +225,12 @@ export default function GoalBasedSavingsPage() { Try adjusting your search terms or filters to find what you're looking for.

- + )} diff --git a/frontend/app/dashboard/settings/SettingsClient.tsx b/frontend/app/dashboard/settings/SettingsClient.tsx index c70f9331e..52d085240 100644 --- a/frontend/app/dashboard/settings/SettingsClient.tsx +++ b/frontend/app/dashboard/settings/SettingsClient.tsx @@ -3,6 +3,7 @@ import React, { useEffect, useMemo, useState } from "react"; import { Monitor, Moon, Settings, Sun } from "lucide-react"; import { type Theme, useTheme } from "../../context/ThemeContext"; +import Button from "../../components/ui/Button"; type Prefs = { emailNotifications?: boolean; @@ -177,13 +178,15 @@ export default function SettingsClient() { />
- + Save Preferences +
diff --git a/frontend/app/dashboard/transactions/page.tsx b/frontend/app/dashboard/transactions/page.tsx index 054ec21eb..76c5d9e2c 100644 --- a/frontend/app/dashboard/transactions/page.tsx +++ b/frontend/app/dashboard/transactions/page.tsx @@ -4,6 +4,7 @@ import React, { useEffect, useState } from "react"; import { Download, History, Loader2, Search, ChevronDown } from "lucide-react"; import TransactionRow, { TransactionType, TransactionStatus } from "./components/TransactionRow"; import { useToast } from "../../context/ToastContext"; +import Button from "../../components/ui/Button"; type TransactionRowData = { date: string; @@ -134,13 +135,14 @@ export default function TransactionHistoryPage() { - +
diff --git a/frontend/app/savings/create-goal/components/GoalForm.tsx b/frontend/app/savings/create-goal/components/GoalForm.tsx index 3a0783096..96c68ad5e 100644 --- a/frontend/app/savings/create-goal/components/GoalForm.tsx +++ b/frontend/app/savings/create-goal/components/GoalForm.tsx @@ -2,6 +2,7 @@ import React from "react"; import { Calendar, CircleDollarSign, Flag, Sparkles } from "lucide-react"; +import Button from "../../../components/ui/Button"; type FormState = { goalName: string; @@ -173,12 +174,9 @@ export default function GoalForm() { )}
- +

You’ll be able to contribute and track progress on the dashboard.

diff --git a/frontend/app/savings/page.tsx b/frontend/app/savings/page.tsx index a9072381d..b2a1ae509 100644 --- a/frontend/app/savings/page.tsx +++ b/frontend/app/savings/page.tsx @@ -17,6 +17,7 @@ import { ShoppingBag, } from "lucide-react"; import GoalCard, { GoalStatus } from "./components/GoalCard"; +import Button from "../components/ui/Button"; // export const metadata = { title: "Goal-Based Savings - Nestera" }; @@ -120,9 +121,9 @@ export default function GoalBasedSavingsPage() {

- +
- + )}