Files
star-erp/resources/js/Pages/Landlord/Tenant/Show.tsx
sky121113 43d7cada34
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Successful in 44s
Koori-ERP-Deploy-System / deploy-production (push) Has been skipped
fix: tenancy middleware order and ui consistency for user profile
2026-01-16 11:56:44 +08:00

168 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import LandlordLayout from "@/Layouts/LandlordLayout";
import { Link, useForm, router } from "@inertiajs/react";
import { Globe, Plus, Trash2, ArrowLeft } from "lucide-react";
import { FormEvent, useState } from "react";
interface Domain {
id: number;
domain: string;
}
interface Tenant {
id: string;
name: string;
email: string | null;
is_active: boolean;
created_at: string;
updated_at: string;
domains: Domain[];
}
interface Props {
tenant: Tenant;
}
export default function TenantShow({ tenant }: Props) {
const [showAddDomain, setShowAddDomain] = useState(false);
const { data, setData, post, processing, errors, reset } = useForm({
domain: "",
});
const handleAddDomain = (e: FormEvent) => {
e.preventDefault();
post(route("landlord.tenants.domains.store", tenant.id), {
onSuccess: () => {
reset();
setShowAddDomain(false);
},
});
};
const handleRemoveDomain = (domainId: number) => {
if (confirm("確定要移除這個域名嗎?")) {
router.delete(route("landlord.tenants.domains.destroy", [tenant.id, domainId]));
}
};
return (
<LandlordLayout
title="客戶詳情"
>
<div className="max-w-3xl space-y-6">
{/* Back Link */}
<Link
href="/landlord/tenants"
className="inline-flex items-center gap-1 text-slate-600 hover:text-slate-900"
>
<ArrowLeft className="w-4 h-4" />
</Link>
{/* Header */}
<div className="flex items-start justify-between">
<div>
<h1 className="text-2xl font-bold text-slate-900">{tenant.name}</h1>
<p className="text-slate-500 mt-1"> ID: {tenant.id}</p>
</div>
<Link
href={`/landlord/tenants/${tenant.id}/edit`}
className="bg-slate-100 hover:bg-slate-200 text-slate-700 px-4 py-2 rounded-lg transition-colors"
>
</Link>
</div>
{/* Info Card */}
<div className="bg-white rounded-xl border border-slate-200 p-6">
<h2 className="text-lg font-semibold text-slate-900 mb-4"></h2>
<dl className="grid grid-cols-2 gap-4">
<div>
<dt className="text-sm text-slate-500"></dt>
<dd className="mt-1">
<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>
</dd>
</div>
<div>
<dt className="text-sm text-slate-500"></dt>
<dd className="mt-1 text-slate-900">{tenant.email || "-"}</dd>
</div>
<div>
<dt className="text-sm text-slate-500"></dt>
<dd className="mt-1 text-slate-900">{tenant.created_at}</dd>
</div>
<div>
<dt className="text-sm text-slate-500"></dt>
<dd className="mt-1 text-slate-900">{tenant.updated_at}</dd>
</div>
</dl>
</div>
{/* Domains Card */}
<div className="bg-white rounded-xl border border-slate-200 p-6">
<div className="flex items-center justify-between mb-4">
<h2 className="text-lg font-semibold text-slate-900"></h2>
<button
onClick={() => setShowAddDomain(!showAddDomain)}
className="text-primary-main hover:text-primary-dark flex items-center gap-1 text-sm"
>
<Plus className="w-4 h-4" />
</button>
</div>
{showAddDomain && (
<form onSubmit={handleAddDomain} className="mb-4 flex gap-2">
<input
type="text"
value={data.domain}
onChange={(e) => setData("domain", e.target.value)}
placeholder="例如koori.erp.koori.tw"
className="flex-1 px-4 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary-main focus:border-primary-main"
/>
<button
type="submit"
disabled={processing}
className="bg-primary-main hover:bg-primary-dark text-white px-4 py-2 rounded-lg disabled:opacity-50"
>
</button>
</form>
)}
{errors.domain && <p className="mb-4 text-sm text-red-500">{errors.domain}</p>}
{tenant.domains.length === 0 ? (
<p className="text-slate-500 text-sm"></p>
) : (
<ul className="space-y-2">
{tenant.domains.map((domain) => (
<li
key={domain.id}
className="flex items-center justify-between p-3 bg-slate-50 rounded-lg"
>
<div className="flex items-center gap-2">
<Globe className="w-4 h-4 text-slate-400" />
<span className="text-slate-900">{domain.domain}</span>
</div>
<button
onClick={() => handleRemoveDomain(domain.id)}
className="p-1 text-slate-400 hover:text-red-600 hover:bg-red-50 rounded transition-colors"
>
<Trash2 className="w-4 h-4" />
</button>
</li>
))}
</ul>
)}
</div>
</div>
</LandlordLayout>
);
}