107 lines
4.5 KiB
TypeScript
107 lines
4.5 KiB
TypeScript
|
|
import LandlordLayout from "@/Layouts/LandlordLayout";
|
||
|
|
import { Building2, Users, Activity } from "lucide-react";
|
||
|
|
import { Link } from "@inertiajs/react";
|
||
|
|
|
||
|
|
interface Tenant {
|
||
|
|
id: string;
|
||
|
|
name: string;
|
||
|
|
is_active: boolean;
|
||
|
|
created_at: string;
|
||
|
|
domains: string[];
|
||
|
|
}
|
||
|
|
|
||
|
|
interface DashboardProps {
|
||
|
|
totalTenants: number;
|
||
|
|
activeTenants: number;
|
||
|
|
recentTenants: Tenant[];
|
||
|
|
}
|
||
|
|
|
||
|
|
export default function Dashboard({ totalTenants, activeTenants, recentTenants }: DashboardProps) {
|
||
|
|
const statsCards = [
|
||
|
|
{
|
||
|
|
title: "租戶總數",
|
||
|
|
value: totalTenants,
|
||
|
|
icon: Building2,
|
||
|
|
color: "bg-blue-500",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: "啟用中",
|
||
|
|
value: activeTenants,
|
||
|
|
icon: Activity,
|
||
|
|
color: "bg-green-500",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
title: "停用中",
|
||
|
|
value: totalTenants - activeTenants,
|
||
|
|
icon: Users,
|
||
|
|
color: "bg-slate-400",
|
||
|
|
},
|
||
|
|
];
|
||
|
|
|
||
|
|
return (
|
||
|
|
<LandlordLayout title="儀表板">
|
||
|
|
<div className="space-y-6">
|
||
|
|
{/* Stats Cards */}
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||
|
|
{statsCards.map((stat) => (
|
||
|
|
<div
|
||
|
|
key={stat.title}
|
||
|
|
className="bg-white rounded-xl border border-slate-200 p-6 flex items-center gap-4"
|
||
|
|
>
|
||
|
|
<div className={`w-12 h-12 ${stat.color} rounded-lg flex items-center justify-center`}>
|
||
|
|
<stat.icon className="w-6 h-6 text-white" />
|
||
|
|
</div>
|
||
|
|
<div>
|
||
|
|
<p className="text-sm text-slate-500">{stat.title}</p>
|
||
|
|
<p className="text-2xl font-bold text-slate-900">{stat.value}</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Recent Tenants */}
|
||
|
|
<div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
|
||
|
|
<div className="px-6 py-4 border-b border-slate-200 flex items-center justify-between">
|
||
|
|
<h2 className="text-lg font-semibold text-slate-900">最近新增的租戶</h2>
|
||
|
|
<Link
|
||
|
|
href="/landlord/tenants"
|
||
|
|
className="text-sm text-primary-main hover:underline"
|
||
|
|
>
|
||
|
|
查看全部 →
|
||
|
|
</Link>
|
||
|
|
</div>
|
||
|
|
<div className="divide-y divide-slate-100">
|
||
|
|
{recentTenants.length === 0 ? (
|
||
|
|
<div className="px-6 py-8 text-center text-slate-500">
|
||
|
|
尚無租戶資料
|
||
|
|
</div>
|
||
|
|
) : (
|
||
|
|
recentTenants.map((tenant) => (
|
||
|
|
<div key={tenant.id} className="px-6 py-4 flex items-center justify-between">
|
||
|
|
<div>
|
||
|
|
<p className="font-medium text-slate-900">{tenant.name}</p>
|
||
|
|
<p className="text-sm text-slate-500">
|
||
|
|
{tenant.domains.length > 0 ? tenant.domains.join(", ") : "無綁定域名"}
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
<div className="flex items-center gap-3">
|
||
|
|
<span
|
||
|
|
className={`px-2 py-1 rounded-full text-xs font-medium ${tenant.is_active
|
||
|
|
? "bg-green-100 text-green-700"
|
||
|
|
: "bg-slate-100 text-slate-600"
|
||
|
|
}`}
|
||
|
|
>
|
||
|
|
{tenant.is_active ? "啟用" : "停用"}
|
||
|
|
</span>
|
||
|
|
<span className="text-sm text-slate-400">{tenant.created_at}</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
))
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</LandlordLayout>
|
||
|
|
);
|
||
|
|
}
|