'use client'; import Link from 'next/link'; import { useMemo, useState } from 'react'; import { useSuspenseQuery } from '@tanstack/react-query'; import { Icons } from '@/components/icons'; import { Badge } from '@/components/ui/badge'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Separator } from '@/components/ui/separator'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { customerByIdOptions } from '../api/queries'; import type { CustomerReferenceData } from '../api/types'; import { CustomerFormSheet } from './customer-form-sheet'; import { CustomerContactsTab } from './customer-contacts-tab'; import { CustomerStatusBadge } from './customer-status-badge'; function FieldItem({ label, value }: { label: string; value: string | null | undefined }) { return (
{label}
{value || '-'}
); } export function CustomerDetail({ customerId, referenceData, canUpdate, canManageContacts }: { customerId: string; referenceData: CustomerReferenceData; canUpdate: boolean; canManageContacts: { create: boolean; update: boolean; delete: boolean; }; }) { const { data } = useSuspenseQuery(customerByIdOptions(customerId)); const [editOpen, setEditOpen] = useState(false); const branchMap = useMemo( () => new Map(referenceData.branches.map((item) => [item.id, item.name])), [referenceData] ); const typeMap = useMemo( () => new Map(referenceData.customerTypes.map((item) => [item.id, item])), [referenceData] ); const statusMap = useMemo( () => new Map(referenceData.customerStatuses.map((item) => [item.id, item])), [referenceData] ); const leadMap = useMemo( () => new Map(referenceData.leadChannels.map((item) => [item.id, item.label])), [referenceData] ); const groupMap = useMemo( () => new Map(referenceData.customerGroups.map((item) => [item.id, item.label])), [referenceData] ); const customer = data.customer; const status = statusMap.get(customer.customerStatus); const type = typeMap.get(customer.customerType); return (
{customer.code} {type ? {type.label} : null} {customer.branchId ? ( {branchMap.get(customer.branchId) ?? 'Unknown branch'} ) : null}

{customer.name}

{customer.abbr || customer.email || customer.phone || 'Customer detail record'}

{canUpdate ? ( ) : null}
Overview Contacts Activity Related Documents Overview Core account data, location, and CRM classification.
Activity Audit log entries captured from customer mutations. {!data.activity.length ? (
No activity recorded yet.
) : ( data.activity.map((item, index) => (
{item.action} {item.actorName ?? item.userId}
{new Date(item.createdAt).toLocaleString()}
{index < data.activity.length - 1 ? : null}
)) )} Related Documents Task C stops at customer and contact scope, so downstream CRM documents stay intentionally deferred.
Enquiry, quotation, and approval links will land here in Task D and later.
Record Snapshot Operational metadata for this customer row.
); }