diff --git a/.claude/settings.local.json b/.claude/settings.local.json index cb52a19..692ac60 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -2,7 +2,9 @@ "permissions": { "allow": [ "Bash(cat:*)", - "Bash(tree:*)" + "Bash(tree:*)", + "Bash(pnpm run build:*)", + "Bash(pnpm run dev:*)" ] } } diff --git a/app/page.tsx b/app/page.tsx index 84684f5..f34a6b6 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -6,12 +6,14 @@ import { MetricCard } from "@/components/dashboard/metric-card" import { RevenueChart } from "@/components/dashboard/revenue-chart" import { SalesChart } from "@/components/dashboard/sales-chart" import { PaymentsTable } from "@/components/dashboard/payments-table" +import { UnclassifiedPaymentsTable } from "@/components/dashboard/unclassified-payments-table" import { TeamTable } from "@/components/dashboard/team-table" import { getDashboardData } from "@/lib/mock-data" export default function Home() { const data = getDashboardData() + // return ( <> @@ -40,7 +42,7 @@ export default function Home() {
- +
diff --git a/components/dashboard/payments-table.tsx b/components/dashboard/payments-table.tsx index b76323f..b40ccd4 100644 --- a/components/dashboard/payments-table.tsx +++ b/components/dashboard/payments-table.tsx @@ -30,14 +30,22 @@ interface PaymentsTableProps { } export function PaymentsTable({ payments }: PaymentsTableProps) { - const getStatusColor = (status: Payment["status"]) => { - switch (status) { - case "success": - return "bg-green-500/10 text-green-500 hover:bg-green-500/20" - case "processing": - return "bg-yellow-500/10 text-yellow-500 hover:bg-yellow-500/20" - case "failed": - return "bg-red-500/10 text-red-500 hover:bg-red-500/20" + const getCategoryColor = (category: Payment["category"]) => { + switch (category) { + case "groceries": + return "bg-green-500/15 text-green-500 hover:bg-green-500/20" + case "utilities": + return "bg-blue-500/15 text-blue-500 hover:bg-blue-500/20" + case "transport": + return "bg-purple-500/15 text-purple-500 hover:bg-purple-500/20" + case "entertainment": + return "bg-pink-500/15 text-pink-500 hover:bg-pink-500/20" + case "shopping": + return "bg-orange-500/15 text-orange-500 hover:bg-orange-500/20" + case "insurance": + return "bg-red-500/15 text-red-500 hover:bg-red-500/20" + case "housing": + return "bg-yellow-500/15 text-yellow-500 hover:bg-yellow-500/20" default: return "" } @@ -54,8 +62,8 @@ export function PaymentsTable({ payments }: PaymentsTableProps) { - Status - Email + Category + Description Amount Actions @@ -64,11 +72,11 @@ export function PaymentsTable({ payments }: PaymentsTableProps) { {payments.map((payment) => ( - - {payment.status} + + {payment.category} - {payment.email} + {payment.description} ${payment.amount.toFixed(2)} diff --git a/components/dashboard/revenue-chart.tsx b/components/dashboard/revenue-chart.tsx index cf4a314..99e6991 100644 --- a/components/dashboard/revenue-chart.tsx +++ b/components/dashboard/revenue-chart.tsx @@ -1,7 +1,9 @@ "use client" +import { useTheme } from "next-themes" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { LineChart } from "@/components/charts/line-chart" +import { getChartColors } from "@/lib/chart-config" import type { ChartDataPoint } from "@/types/dashboard" interface RevenueChartProps { @@ -9,32 +11,35 @@ interface RevenueChartProps { } export function RevenueChart({ data }: RevenueChartProps) { + const { theme } = useTheme() + const colors = getChartColors(theme) + const chartData = { labels: data.map((d) => d.label), datasets: [ { label: "Revenue", data: data.map((d) => d.value), - borderColor: "rgb(244, 114, 182)", - backgroundColor: "rgba(244, 114, 182, 0.2)", + borderColor: colors.blue, + backgroundColor: `${colors.blue.replace('rgb', 'rgba').replace(')', ', 0.2)')}`, }, { label: "Subscriptions", data: data.map((d) => d.secondaryValue || 0), - borderColor: "rgb(94, 234, 212)", - backgroundColor: "rgba(94, 234, 212, 0.2)", + borderColor: colors.orange, + backgroundColor: `${colors.orange.replace('rgb', 'rgba').replace(')', ', 0.2)')}`, }, ], } return ( - + Revenue Overview Showing total revenue for the last 6 months - + ) diff --git a/components/dashboard/sales-chart.tsx b/components/dashboard/sales-chart.tsx index c4de32e..affbf8e 100644 --- a/components/dashboard/sales-chart.tsx +++ b/components/dashboard/sales-chart.tsx @@ -1,7 +1,9 @@ "use client" +import { useTheme } from "next-themes" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { BarChart } from "@/components/charts/bar-chart" +import { getChartColors } from "@/lib/chart-config" import type { ChartDataPoint } from "@/types/dashboard" interface SalesChartProps { @@ -9,6 +11,9 @@ interface SalesChartProps { } export function SalesChart({ data }: SalesChartProps) { + const { theme } = useTheme() + const colors = getChartColors(theme) + // Calculate total and change percentage const total = data.reduce((sum, d) => sum + d.value, 0) const lastMonthValue = data[data.length - 2]?.value || 0 @@ -17,16 +22,16 @@ export function SalesChart({ data }: SalesChartProps) { ? (((currentMonthValue - lastMonthValue) / lastMonthValue) * 100).toFixed(1) : "0.0" - // Alternate colors for bars + // Alternate colors for bars using centralized palette const backgroundColors = data.map((_, index) => - index % 2 === 0 ? "rgb(251, 113, 133)" : "rgb(94, 234, 212)" + index % 2 === 0 ? colors.darkBlue : colors.orange ) const chartData = { labels: data.map((d) => d.label), datasets: [ { - label: "Sales", + label: "Expenditure", data: data.map((d) => d.value), backgroundColor: backgroundColors, }, @@ -34,13 +39,13 @@ export function SalesChart({ data }: SalesChartProps) { } return ( - + - Subscriptions + Expenditure +{changePercent}% from last month - + ) diff --git a/components/dashboard/unclassified-payments-table.tsx b/components/dashboard/unclassified-payments-table.tsx new file mode 100644 index 0000000..2645f81 --- /dev/null +++ b/components/dashboard/unclassified-payments-table.tsx @@ -0,0 +1,78 @@ +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card" +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" +import { Button } from "@/components/ui/button" +import { MoreHorizontal } from "lucide-react" +import type { Transaction } from "@/types/dashboard" + +interface TransactionsTableProps { + transactions: Transaction[] +} + +export function UnclassifiedPaymentsTable({ transactions }: TransactionsTableProps) { + return ( + + + Unclassified Transactions + You have {transactions.length} transactions that need to be labeled. + + +
+
+ + + Description + Amount + Actions + + + + {transactions.map((transaction) => ( + + {transaction.description} + + ${transaction.amount.toFixed(2)} + + + + + + + + Actions + View details + Categorize + + + + + ))} + +
+ + + + ) +} diff --git a/lib/chart-config.ts b/lib/chart-config.ts index 4394fd8..44be499 100644 --- a/lib/chart-config.ts +++ b/lib/chart-config.ts @@ -27,9 +27,21 @@ export function getChartColors(theme: string | undefined) { const isDark = theme === "dark" return { - primary: isDark ? "rgb(96, 165, 250)" : "rgb(59, 130, 246)", - secondary: isDark ? "rgb(168, 85, 247)" : "rgb(147, 51, 234)", - success: isDark ? "rgb(74, 222, 128)" : "rgb(34, 197, 94)", + // Primary colors for chart elements + primary: isDark ? "rgb(96, 165, 250)" : "rgb(59, 130, 246)", // blue + secondary: isDark ? "rgb(168, 85, 247)" : "rgb(147, 51, 234)", // purple + success: isDark ? "rgb(74, 222, 128)" : "rgb(34, 197, 94)", // green + + // Additional chart colors + orange: isDark ? "rgb(237, 152, 95)" : "rgb(237, 152, 95)", + pink: isDark ? "rgb(236, 72, 153)" : "rgb(236, 72, 153)", + amber: isDark ? "rgb(251, 191, 36)" : "rgb(251, 191, 36)", + teal: isDark ? "rgb(94, 234, 212)" : "rgb(94, 234, 212)", + rose: isDark ? "rgb(244, 114, 182)" : "rgb(244, 114, 182)", + blue: isDark ? "rgb(96, 123, 143)": "rgb(96, 123, 143)", + darkBlue: isDark ? "rgb(67, 78, 120)" : "rgb(67, 78, 120)", + + // UI colors grid: isDark ? "rgba(255, 255, 255, 0.1)" : "rgba(0, 0, 0, 0.1)", text: isDark ? "rgba(255, 255, 255, 0.7)" : "rgba(0, 0, 0, 0.7)", } diff --git a/lib/mock-data.ts b/lib/mock-data.ts index 7847b9a..e5936be 100644 --- a/lib/mock-data.ts +++ b/lib/mock-data.ts @@ -5,35 +5,35 @@ export function getDashboardData(): DashboardData { metrics: [ { id: "1", - title: "New Subscriptions", - value: "4,682", - change: 15.54, + title: "Income", + value: "45,682", + change: -1.54, changeLabel: "from last month", - icon: "Users", + icon: "DollarSign", }, { id: "2", - title: "New Orders", - value: "1,226", - change: 40.2, + title: "Expenditure", + value: "34,226", + change: 4.2, changeLabel: "from last month", - icon: "ShoppingCart", + icon: "CreditCard", }, { id: "3", - title: "Avg Order Revenue", - value: "$1,080", - change: 10.8, + title: "Saving", + value: "10,000", + change: 0, changeLabel: "from last month", icon: "DollarSign", }, { id: "4", - title: "Total Revenue", - value: "$15,231.89", - change: 20.1, + title: "Pension", + value: "1,500,231", + change: 2.1, changeLabel: "from last month", - icon: "CreditCard", + icon: "DollarSign", }, ], revenueData: [ @@ -45,93 +45,150 @@ export function getDashboardData(): DashboardData { { label: "Jun", value: 5800, secondaryValue: 3100 }, ], salesData: [ - { label: "Jan", value: 1200 }, - { label: "Feb", value: 1900 }, - { label: "Mar", value: 1600 }, - { label: "Apr", value: 2100 }, - { label: "May", value: 1800 }, - { label: "Jun", value: 2400 }, - { label: "Jul", value: 2200 }, - { label: "Aug", value: 2600 }, - { label: "Sep", value: 2300 }, - { label: "Oct", value: 2800 }, - { label: "Nov", value: 2500 }, - { label: "Dec", value: 3100 }, + { label: "Housing", value: 22000 }, + { label: "Groceries", value: 13200 }, + { label: "Transport", value: 3600 }, + { label: "Entertainment", value: 4100 }, + { label: "Shopping", value: 5200 }, + { label: "Insurance", value: 4900 }, + { label: "Other", value: 5800 }, ], payments: [ { id: "1", - status: "success", - email: "olivia.martin@email.com", + category: "groceries", + description: "Costco - Groceries & Household", amount: 316.0, }, { id: "2", - status: "processing", - email: "jackson.lee@email.com", + category: "transport", + description: "BP Gas Station", amount: 242.0, }, { id: "3", - status: "success", - email: "isabella.nguyen@email.com", + category: "housing", + description: "Mortgage Payment - Wells Fargo", amount: 837.0, }, { id: "4", - status: "failed", - email: "william.kim@email.com", + category: "insurance", + description: "Insurance Premium - State Farm", amount: 874.0, }, { id: "5", - status: "success", - email: "sofia.davis@email.com", + category: "utilities", + description: "Internet Service - Comcast", amount: 721.0, }, { id: "6", - status: "processing", - email: "alexander.chen@email.com", + category: "entertainment", + description: "Amazon Prime - Annual Subscription", amount: 456.0, }, { id: "7", - status: "success", - email: "emily.wilson@email.com", + category: "shopping", + description: "Best Buy - Laptop Purchase", amount: 592.0, }, { id: "8", - status: "success", - email: "michael.brown@email.com", + category: "groceries", + description: "Trader Joe's - Groceries", amount: 389.0, }, { id: "9", - status: "failed", - email: "sarah.johnson@email.com", + category: "transport", + description: "Car Repair - AutoZone", amount: 1250.0, }, { id: "10", - status: "success", - email: "daniel.garcia@email.com", + category: "entertainment", + description: "Spotify Premium - Family Plan", amount: 675.0, }, { id: "11", - status: "processing", - email: "jessica.martinez@email.com", + category: "transport", + description: "Delta Airlines - Flight Tickets", amount: 943.0, }, { id: "12", - status: "success", - email: "james.rodriguez@email.com", + category: "shopping", + description: "Home Depot - Home Improvement", amount: 528.0, }, ], + transactions: [ + { + id: "1", + description: "Whole Foods Market - Groceries", + amount: 127.43, + }, + { + id: "2", + description: "Shell Gas Station", + amount: 52.18, + }, + { + id: "3", + description: "Netflix Subscription", + amount: 15.99, + }, + { + id: "4", + description: "Amazon.com - Electronics", + amount: 243.67, + }, + { + id: "5", + description: "Starbucks Coffee", + amount: 6.75, + }, + { + id: "6", + description: "Electric Company - Monthly Bill", + amount: 89.32, + }, + { + id: "7", + description: "Target - Household Items", + amount: 94.21, + }, + { + id: "8", + description: "Uber Ride", + amount: 18.50, + }, + { + id: "9", + description: "Restaurant - Dinner", + amount: 67.89, + }, + { + id: "10", + description: "Gym Membership", + amount: 45.00, + }, + { + id: "11", + description: "Phone Bill - AT&T", + amount: 72.15, + }, + { + id: "12", + description: "Apple Store - App Purchase", + amount: 4.99, + }, + ], team: [ { id: "1", diff --git a/types/dashboard.ts b/types/dashboard.ts index da626f2..40b30fc 100644 --- a/types/dashboard.ts +++ b/types/dashboard.ts @@ -9,8 +9,14 @@ export interface MetricCard { export interface Payment { id: string - status: "success" | "processing" | "failed" - email: string + category: "groceries" | "utilities" | "transport" | "entertainment" | "shopping" | "insurance" | "housing" + description: string + amount: number +} + +export interface Transaction { + id: string + description: string amount: number } @@ -33,5 +39,6 @@ export interface DashboardData { revenueData: ChartDataPoint[] salesData: ChartDataPoint[] payments: Payment[] + transactions: Transaction[] team: TeamMember[] }