Files
star-erp/resources/js/Pages/Landlord/Tenant/Index.tsx

189 lines
9.8 KiB
TypeScript
Raw Normal View History

import LandlordLayout from "@/Layouts/LandlordLayout";
import { Link, router } from "@inertiajs/react";
import { Plus, Edit, Trash2, Globe } from "lucide-react";
import { useState } from "react";
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/Components/ui/alert-dialog";
interface Tenant {
id: string;
name: string;
email: string | null;
is_active: boolean;
created_at: string;
domains: string[];
}
interface Props {
tenants: Tenant[];
}
export default function TenantIndex({ tenants }: Props) {
const [deleteTarget, setDeleteTarget] = useState<Tenant | null>(null);
const handleDelete = () => {
if (deleteTarget) {
router.delete(route("landlord.tenants.destroy", deleteTarget.id));
setDeleteTarget(null);
}
};
return (
<LandlordLayout title="租戶管理">
<div className="space-y-6">
{/* Header */}
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-bold text-slate-900"></h1>
<p className="text-slate-500 mt-1"></p>
</div>
<Link
href="/landlord/tenants/create"
className="bg-primary-main hover:bg-primary-dark text-white px-4 py-2 rounded-lg flex items-center gap-2 transition-colors"
>
<Plus className="w-4 h-4" />
</Link>
</div>
{/* Table */}
<div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
<table className="w-full">
<thead className="bg-slate-50">
<tr>
<th className="px-6 py-3 text-left text-xs font-semibold text-slate-500 uppercase">
ID
</th>
<th className="px-6 py-3 text-left text-xs font-semibold text-slate-500 uppercase">
</th>
<th className="px-6 py-3 text-left text-xs font-semibold text-slate-500 uppercase">
</th>
<th className="px-6 py-3 text-left text-xs font-semibold text-slate-500 uppercase">
</th>
<th className="px-6 py-3 text-left text-xs font-semibold text-slate-500 uppercase">
</th>
<th className="px-6 py-3 text-right text-xs font-semibold text-slate-500 uppercase">
</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-100">
{tenants.length === 0 ? (
<tr>
<td colSpan={6} className="px-6 py-12 text-center text-slate-500">
</td>
</tr>
) : (
tenants.map((tenant) => (
<tr key={tenant.id} className="hover:bg-slate-50">
<td className="px-6 py-4 font-mono text-sm text-slate-600">
{tenant.id}
</td>
<td className="px-6 py-4">
<div>
<p className="font-medium text-slate-900">{tenant.name}</p>
{tenant.email && (
<p className="text-sm text-slate-500">{tenant.email}</p>
)}
</div>
</td>
<td className="px-6 py-4">
{tenant.domains.length > 0 ? (
<div className="flex items-center gap-1 flex-wrap">
{tenant.domains.map((domain) => (
<span
key={domain}
className="inline-flex items-center gap-1 px-2 py-1 bg-slate-100 rounded text-xs"
>
<Globe className="w-3 h-3" />
{domain}
</span>
))}
</div>
) : (
<span className="text-slate-400 text-sm"></span>
)}
</td>
<td className="px-6 py-4">
<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>
</td>
<td className="px-6 py-4 text-sm text-slate-500">
{tenant.created_at}
</td>
<td className="px-6 py-4 text-right">
<div className="flex items-center justify-end gap-2">
<Link
href={`/landlord/tenants/${tenant.id}`}
className="p-2 text-slate-400 hover:text-primary-main hover:bg-slate-100 rounded-lg transition-colors"
title="查看詳情"
>
<Globe className="w-4 h-4" />
</Link>
<Link
href={`/landlord/tenants/${tenant.id}/edit`}
className="p-2 text-slate-400 hover:text-blue-600 hover:bg-slate-100 rounded-lg transition-colors"
title="編輯"
>
<Edit className="w-4 h-4" />
</Link>
<button
onClick={() => setDeleteTarget(tenant)}
className="p-2 text-slate-400 hover:text-red-600 hover:bg-red-50 rounded-lg transition-colors"
title="刪除"
>
<Trash2 className="w-4 h-4" />
</button>
</div>
</td>
</tr>
))
)}
</tbody>
</table>
</div>
</div>
{/* Delete Confirmation */}
<AlertDialog open={!!deleteTarget} onOpenChange={() => setDeleteTarget(null)}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle></AlertDialogTitle>
<AlertDialogDescription>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel></AlertDialogCancel>
<AlertDialogAction
onClick={handleDelete}
className="bg-red-600 hover:bg-red-700"
>
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</LandlordLayout>
);
}