Files
GSB-Construction/Modules/UserManagement/resources/js/Pages/Users/Show.tsx

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