Seed: saas template (34 files)
This commit is contained in:
@@ -0,0 +1,172 @@
|
|||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
import DashboardHeader from "@/components/DashboardHeader";
|
||||||
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
|
||||||
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
|
||||||
|
import { DollarSign, Users, TrendingDown, ThumbsUp, ArrowUpRight, ArrowDownRight, Plus, UserPlus, Download } from "lucide-react";
|
||||||
|
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from "recharts";
|
||||||
|
|
||||||
|
const kpis = [
|
||||||
|
{ label: "MRR", value: "\$48,250", trend: "+12.5%", up: true, icon: DollarSign, color: "bg-sky-100 text-sky-600" },
|
||||||
|
{ label: "Active Users", value: "2,847", trend: "+8.2%", up: true, icon: Users, color: "bg-emerald-100 text-emerald-600" },
|
||||||
|
{ label: "Churn Rate", value: "2.4%", trend: "-0.3%", up: false, icon: TrendingDown, color: "bg-orange-100 text-orange-600" },
|
||||||
|
{ label: "NPS", value: "72", trend: "+4", up: true, icon: ThumbsUp, color: "bg-violet-100 text-violet-600" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const revenueData = [
|
||||||
|
{ month: "Jan", revenue: 32000 }, { month: "Feb", revenue: 34500 },
|
||||||
|
{ month: "Mar", revenue: 36200 }, { month: "Apr", revenue: 38100 },
|
||||||
|
{ month: "May", revenue: 37800 }, { month: "Jun", revenue: 39500 },
|
||||||
|
{ month: "Jul", revenue: 41200 }, { month: "Aug", revenue: 43000 },
|
||||||
|
{ month: "Sep", revenue: 44800 }, { month: "Oct", revenue: 45200 },
|
||||||
|
{ month: "Nov", revenue: 46900 }, { month: "Dec", revenue: 48250 },
|
||||||
|
];
|
||||||
|
|
||||||
|
const activities = [
|
||||||
|
{ name: "Sarah Chen", action: "Upgraded to Pro", date: "2 hours ago", status: "completed", initials: "SC" },
|
||||||
|
{ name: "Marcus Johnson", action: "Created new project", date: "4 hours ago", status: "completed", initials: "MJ" },
|
||||||
|
{ name: "Emily Rivera", action: "Submitted support ticket", date: "5 hours ago", status: "pending", initials: "ER" },
|
||||||
|
{ name: "David Kim", action: "Payment processed", date: "6 hours ago", status: "completed", initials: "DK" },
|
||||||
|
{ name: "Anna Petrov", action: "Account deactivated", date: "8 hours ago", status: "failed", initials: "AP" },
|
||||||
|
{ name: "James Wright", action: "Invited team member", date: "10 hours ago", status: "completed", initials: "JW" },
|
||||||
|
{ name: "Lisa Nguyen", action: "Exported data", date: "12 hours ago", status: "completed", initials: "LN" },
|
||||||
|
{ name: "Tom Bradley", action: "Updated billing info", date: "1 day ago", status: "pending", initials: "TB" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function DashboardPage() {
|
||||||
|
return (
|
||||||
|
<div className="flex min-h-screen bg-slate-50">
|
||||||
|
<Sidebar activePath="/dashboard" />
|
||||||
|
<div className="flex-1 lg:ml-64">
|
||||||
|
<DashboardHeader />
|
||||||
|
<main className="p-6 space-y-6">
|
||||||
|
{/* KPI Cards */}
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
|
{kpis.map((kpi) => {
|
||||||
|
const Icon = kpi.icon;
|
||||||
|
return (
|
||||||
|
<Card key={kpi.label}>
|
||||||
|
<CardContent className="p-6">
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<p className="text-sm text-slate-500">{kpi.label}</p>
|
||||||
|
<p className="text-2xl font-bold mt-1">{kpi.value}</p>
|
||||||
|
</div>
|
||||||
|
<div className={`h-10 w-10 rounded-full flex items-center justify-center \${kpi.color}`}>
|
||||||
|
<Icon className="h-5 w-5" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-1 mt-2 text-sm">
|
||||||
|
{kpi.up ? <ArrowUpRight className="h-4 w-4 text-emerald-500" /> : <ArrowDownRight className="h-4 w-4 text-emerald-500" />}
|
||||||
|
<span className="text-emerald-600 font-medium">{kpi.trend}</span>
|
||||||
|
<span className="text-slate-400">vs last month</span>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Revenue Chart */}
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Revenue Overview</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="h-80">
|
||||||
|
<ResponsiveContainer width="100%" height="100%">
|
||||||
|
<BarChart data={revenueData}>
|
||||||
|
<CartesianGrid strokeDasharray="3 3" stroke="#e2e8f0" />
|
||||||
|
<XAxis dataKey="month" stroke="#94a3b8" fontSize={12} />
|
||||||
|
<YAxis stroke="#94a3b8" fontSize={12} />
|
||||||
|
<Tooltip />
|
||||||
|
<Bar dataKey="revenue" fill="#6366f1" radius={[4, 4, 0, 0]} />
|
||||||
|
</BarChart>
|
||||||
|
</ResponsiveContainer>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
{/* Recent Activity */}
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Recent Activity</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<Table>
|
||||||
|
<TableHeader>
|
||||||
|
<TableRow>
|
||||||
|
<TableHead>User</TableHead>
|
||||||
|
<TableHead>Action</TableHead>
|
||||||
|
<TableHead>Date</TableHead>
|
||||||
|
<TableHead>Status</TableHead>
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{activities.map((a, i) => (
|
||||||
|
<TableRow key={i}>
|
||||||
|
<TableCell>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<Avatar className="h-8 w-8">
|
||||||
|
<AvatarFallback className="bg-indigo-100 text-indigo-600 text-xs">{a.initials}</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
<span className="font-medium">{a.name}</span>
|
||||||
|
</div>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="text-slate-500">{a.action}</TableCell>
|
||||||
|
<TableCell className="text-slate-400">{a.date}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Badge variant={a.status === "completed" ? "default" : a.status === "pending" ? "secondary" : "destructive"}>
|
||||||
|
{a.status}
|
||||||
|
</Badge>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
{/* Quick Actions */}
|
||||||
|
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
|
||||||
|
<Card className="cursor-pointer hover:shadow-md transition-shadow">
|
||||||
|
<CardContent className="p-6 flex items-center gap-4">
|
||||||
|
<div className="h-10 w-10 rounded-full bg-indigo-100 flex items-center justify-center">
|
||||||
|
<Plus className="h-5 w-5 text-indigo-600" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="font-semibold">New Project</p>
|
||||||
|
<p className="text-sm text-slate-500">Create a new project</p>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<Card className="cursor-pointer hover:shadow-md transition-shadow">
|
||||||
|
<CardContent className="p-6 flex items-center gap-4">
|
||||||
|
<div className="h-10 w-10 rounded-full bg-emerald-100 flex items-center justify-center">
|
||||||
|
<UserPlus className="h-5 w-5 text-emerald-600" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="font-semibold">Invite Team</p>
|
||||||
|
<p className="text-sm text-slate-500">Add team members</p>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
<Card className="cursor-pointer hover:shadow-md transition-shadow">
|
||||||
|
<CardContent className="p-6 flex items-center gap-4">
|
||||||
|
<div className="h-10 w-10 rounded-full bg-violet-100 flex items-center justify-center">
|
||||||
|
<Download className="h-5 w-5 text-violet-600" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="font-semibold">Export Report</p>
|
||||||
|
<p className="text-sm text-slate-500">Download analytics</p>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user