171 lines
9.6 KiB
TypeScript
171 lines
9.6 KiB
TypeScript
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
|
|
import { Head, Link } from '@inertiajs/react';
|
|
import { Badge } from '@/Components/ui/badge';
|
|
import { Button } from '@/Components/ui/button';
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/Components/ui/card';
|
|
import { Separator } from '@/Components/ui/separator';
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/Components/ui/tabs';
|
|
import { ArrowLeft, Pencil, Mail, Phone, MapPin, Building2, CalendarDays, Hash } from 'lucide-react';
|
|
import { User, PageProps } from '@/types';
|
|
|
|
interface Props extends PageProps {
|
|
user: User;
|
|
}
|
|
|
|
const statusVariant = (status: string) => {
|
|
switch (status) {
|
|
case 'active': return 'default';
|
|
case 'inactive': return 'secondary';
|
|
case 'suspended': return 'destructive';
|
|
default: return 'outline';
|
|
}
|
|
};
|
|
|
|
function InfoRow({ icon: Icon, label, value }: { icon: React.ComponentType<{ className?: string }>; label: string; value?: string | null }) {
|
|
if (!value) return null;
|
|
return (
|
|
<div className="flex items-start gap-3 py-2">
|
|
<Icon className="mt-0.5 h-4 w-4 text-gray-400 shrink-0" />
|
|
<div>
|
|
<p className="text-xs text-gray-500">{label}</p>
|
|
<p className="text-sm font-medium text-gray-900">{value}</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default function Show({ user }: Props) {
|
|
const isEmployee = user.user_type === 'admin' || user.user_type === 'employee';
|
|
const isCustomer = user.user_type === 'customer';
|
|
|
|
return (
|
|
<AuthenticatedLayout
|
|
header={
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-4">
|
|
<Link href={route('users.index')}>
|
|
<Button variant="ghost" size="icon-sm">
|
|
<ArrowLeft className="h-4 w-4" />
|
|
</Button>
|
|
</Link>
|
|
<h2 className="text-xl font-semibold leading-tight text-gray-800">
|
|
{user.name}
|
|
</h2>
|
|
</div>
|
|
<Link href={route('users.edit', user.ulid)}>
|
|
<Button size="sm" variant="outline">
|
|
<Pencil className="mr-2 h-4 w-4" /> Edit
|
|
</Button>
|
|
</Link>
|
|
</div>
|
|
}
|
|
>
|
|
<Head title={user.name} />
|
|
|
|
<div className="py-6">
|
|
<div className="mx-auto max-w-4xl px-4 sm:px-6 lg:px-8">
|
|
<div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
|
|
{/* Summary Card */}
|
|
<Card>
|
|
<CardContent className="pt-6 text-center">
|
|
<div className="mx-auto flex h-20 w-20 items-center justify-center rounded-full bg-gray-100 text-2xl font-bold text-gray-600">
|
|
{user.name.charAt(0).toUpperCase()}
|
|
</div>
|
|
<h3 className="mt-4 text-lg font-semibold">{user.name}</h3>
|
|
<p className="text-sm text-gray-500">{user.email}</p>
|
|
<div className="mt-3 flex justify-center gap-2">
|
|
<Badge variant="outline">{user.user_type}</Badge>
|
|
<Badge variant={statusVariant(user.status)}>{user.status}</Badge>
|
|
</div>
|
|
{user.roles && user.roles.length > 0 && (
|
|
<div className="mt-3">
|
|
<p className="text-xs text-gray-500 mb-1">Roles</p>
|
|
<div className="flex flex-wrap justify-center gap-1">
|
|
{user.roles.map((role) => (
|
|
<Badge key={role.id} variant="secondary" className="text-xs">
|
|
{role.name}
|
|
</Badge>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
<Separator className="my-4" />
|
|
<InfoRow icon={Mail} label="Email" value={user.email} />
|
|
<InfoRow icon={CalendarDays} label="Member Since" value={new Date(user.created_at).toLocaleDateString()} />
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* Detail Tabs */}
|
|
<div className="lg:col-span-2">
|
|
<Tabs defaultValue="profile">
|
|
<TabsList>
|
|
<TabsTrigger value="profile">Profile</TabsTrigger>
|
|
{user.permissions && user.permissions.length > 0 && (
|
|
<TabsTrigger value="permissions">Permissions</TabsTrigger>
|
|
)}
|
|
</TabsList>
|
|
|
|
<TabsContent value="profile">
|
|
{isEmployee && user.employee_profile && (
|
|
<Card>
|
|
<CardHeader><CardTitle>Employee Information</CardTitle></CardHeader>
|
|
<CardContent>
|
|
<div className="grid grid-cols-1 gap-1 sm:grid-cols-2">
|
|
<InfoRow icon={Building2} label="Department" value={user.employee_profile.department} />
|
|
<InfoRow icon={Hash} label="Position" value={user.employee_profile.position} />
|
|
<InfoRow icon={Hash} label="Employee Code" value={user.employee_profile.employee_code} />
|
|
<InfoRow icon={CalendarDays} label="Hire Date" value={user.employee_profile.hire_date ? new Date(user.employee_profile.hire_date).toLocaleDateString() : undefined} />
|
|
<InfoRow icon={Phone} label="Phone" value={user.employee_profile.phone} />
|
|
<InfoRow icon={MapPin} label="Address" value={user.employee_profile.address} />
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
{isCustomer && user.customer_profile && (
|
|
<Card>
|
|
<CardHeader><CardTitle>Customer Information</CardTitle></CardHeader>
|
|
<CardContent>
|
|
<div className="grid grid-cols-1 gap-1 sm:grid-cols-2">
|
|
<InfoRow icon={Building2} label="Company Name" value={user.customer_profile.company_name} />
|
|
<InfoRow icon={Hash} label="Contact Person" value={user.customer_profile.contact_person} />
|
|
<InfoRow icon={Hash} label="TIN Number" value={user.customer_profile.tin_number} />
|
|
<InfoRow icon={Phone} label="Phone" value={user.customer_profile.phone} />
|
|
<InfoRow icon={MapPin} label="Address" value={user.customer_profile.address} />
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
|
|
{!user.employee_profile && !user.customer_profile && (
|
|
<Card>
|
|
<CardContent className="py-8 text-center text-gray-500">
|
|
No profile information available.
|
|
</CardContent>
|
|
</Card>
|
|
)}
|
|
</TabsContent>
|
|
|
|
{user.permissions && user.permissions.length > 0 && (
|
|
<TabsContent value="permissions">
|
|
<Card>
|
|
<CardHeader><CardTitle>Permissions</CardTitle></CardHeader>
|
|
<CardContent>
|
|
<div className="flex flex-wrap gap-2">
|
|
{user.permissions.map((perm) => (
|
|
<Badge key={perm.id} variant="outline">{perm.name}</Badge>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</TabsContent>
|
|
)}
|
|
</Tabs>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</AuthenticatedLayout>
|
|
);
|
|
}
|