Files
star-erp/resources/js/Pages/Landlord/Dashboard.tsx
sky121113 4f745c1021
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Successful in 1m3s
Koori-ERP-Deploy-System / deploy-production (push) Has been skipped
feat: 實作 Multi-tenancy 多租戶架構 (stancl/tenancy)
- 安裝並設定 stancl/tenancy 套件
- 分離 Central / Tenant migrations
- 建立 Tenant Model 與資料遷移指令
- 建立房東後台 CRUD (Landlord Dashboard)
- 新增租戶管理頁面 (列表、新增、編輯、詳情)
- 新增域名管理功能
- 更新部署手冊
2026-01-15 13:15:18 +08:00

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>
);
}