garage-erp/apps/dashboard/modules/employees/employee-general-info.tsx
2026-04-06 02:32:47 +03:00

160 lines
5.7 KiB
TypeScript

import {
User,
Mail,
Phone,
Briefcase,
Building2,
Clock,
MapPin,
Calendar,
BadgeCheck,
CircleDot,
} from "lucide-react"
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "@/shared/components/ui/card"
import { Badge } from "@/shared/components/ui/badge"
import { Separator } from "@/shared/components/ui/separator"
type EmployeeData = {
id?: number
type?: string
first_name?: string
last_name?: string
email?: string
phone?: string
position?: string
designation?: string
salary?: string
wage_type?: string
status?: string
track_attendance?: boolean
notify_owner_when_punch_in_out?: boolean
geo_fence_radius?: string | number | null
department?: { id?: number; name?: string } | null
shop_calender?: { id?: number; title?: string } | null
shop_timing?: { id?: number; title?: string } | null
created_at?: string
updated_at?: string
}
type EmployeeGeneralInfoProps = {
employee: EmployeeData
}
function InfoItem({
icon: Icon,
label,
value,
}: {
icon: React.ComponentType<{ className?: string }>
label: string
value?: string | null
}) {
return (
<div className="flex items-start gap-3">
<div className="flex size-9 shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground">
<Icon className="size-4" />
</div>
<div className="flex flex-col gap-0.5">
<span className="text-xs text-muted-foreground">{label}</span>
<span className="text-sm font-medium">
{value || <span className="text-muted-foreground"></span>}
</span>
</div>
</div>
)
}
export function EmployeeGeneralInfo({ employee }: EmployeeGeneralInfoProps) {
const fullName = [employee.first_name, employee.last_name].filter(Boolean).join(" ")
return (
<div className="grid gap-6 md:grid-cols-2">
{/* Personal Information */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<User className="size-4" />
Personal Information
</CardTitle>
</CardHeader>
<CardContent className="grid gap-4">
<div className="flex flex-wrap items-center gap-2">
<Badge variant="secondary">{fullName || "Unknown"}</Badge>
{employee.type && (
<Badge variant="outline" className="capitalize">
{employee.type}
</Badge>
)}
{employee.status && (
<Badge
variant={employee.status === "active" ? "default" : "secondary"}
className="capitalize"
>
{employee.status}
</Badge>
)}
</div>
<Separator />
<div className="grid gap-4 sm:grid-cols-2">
<InfoItem icon={Mail} label="Email" value={employee.email} />
<InfoItem icon={Phone} label="Phone" value={employee.phone} />
<InfoItem icon={Briefcase} label="Position" value={employee.position} />
<InfoItem icon={BadgeCheck} label="Designation" value={employee.designation} />
</div>
</CardContent>
</Card>
{/* Work Details */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Building2 className="size-4" />
Work Details
</CardTitle>
</CardHeader>
<CardContent className="grid gap-4">
<div className="grid gap-4 sm:grid-cols-2">
<InfoItem
icon={Building2}
label="Department"
value={employee.department?.name}
/>
<InfoItem
icon={Calendar}
label="Shop Calendar"
value={employee.shop_calender?.title}
/>
<InfoItem
icon={Clock}
label="Shop Timing"
value={employee.shop_timing?.title}
/>
<InfoItem
icon={MapPin}
label="Geo Fence Radius"
value={employee.geo_fence_radius != null ? String(employee.geo_fence_radius) : null}
/>
</div>
<Separator />
<div className="flex flex-wrap gap-2">
<Badge variant={employee.track_attendance ? "default" : "secondary"}>
<CircleDot className="mr-1 size-3" />
{employee.track_attendance ? "Attendance Tracked" : "No Attendance Tracking"}
</Badge>
{employee.notify_owner_when_punch_in_out && (
<Badge variant="outline">
Punch In/Out Notifications
</Badge>
)}
</div>
</CardContent>
</Card>
</div>
)
}