Files
pn-new-crm/src/components/clients/client-tabs.tsx

202 lines
6.0 KiB
TypeScript
Raw Normal View History

'use client';
import type { DetailTab } from '@/components/shared/detail-layout';
import { NotesList } from '@/components/shared/notes-list';
import { ClientYachtsTab } from '@/components/clients/client-yachts-tab';
import { ClientCompaniesTab } from '@/components/clients/client-companies-tab';
import { ClientReservationsTab } from '@/components/clients/client-reservations-tab';
interface ClientTabsOptions {
clientId: string;
currentUserId?: string;
client: {
fullName: string;
nationality?: string | null;
preferredContactMethod?: string | null;
preferredLanguage?: string | null;
timezone?: string | null;
source?: string | null;
sourceDetails?: string | null;
contacts?: Array<{
id: string;
channel: string;
value: string;
label?: string | null;
isPrimary: boolean;
}>;
yachts: Array<{
id: string;
name: string;
hullNumber: string | null;
registration: string | null;
lengthFt: string | null;
widthFt: string | null;
status: string;
}>;
companies: Array<{
membershipId: string;
role: string;
isPrimary: boolean;
startDate: string | Date;
company: {
id: string;
name: string;
legalName: string | null;
status: string;
};
}>;
activeReservations: Array<{
id: string;
berthId: string;
yachtId: string;
startDate: string | Date;
tenureType: string;
status: string;
}>;
tags?: Array<{ id: string; name: string; color: string }>;
};
}
function InfoRow({ label, value }: { label: string; value?: string | null }) {
if (!value) return null;
return (
<div className="flex gap-2 py-1.5 border-b last:border-0">
<dt className="w-40 shrink-0 text-sm text-muted-foreground">{label}</dt>
<dd className="text-sm">{value}</dd>
</div>
);
}
function OverviewTab({ client }: { client: ClientTabsOptions['client'] }) {
return (
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{/* Personal Info */}
<div className="space-y-1">
<h3 className="text-sm font-medium mb-2">Personal Information</h3>
<dl>
<InfoRow label="Full Name" value={client.fullName} />
<InfoRow label="Nationality" value={client.nationality} />
<InfoRow label="Preferred Language" value={client.preferredLanguage} />
<InfoRow label="Timezone" value={client.timezone} />
<InfoRow label="Preferred Contact" value={client.preferredContactMethod} />
</dl>
</div>
{/* Contacts */}
<div className="space-y-1">
<h3 className="text-sm font-medium mb-2">Contact Details</h3>
{client.contacts && client.contacts.length > 0 ? (
<div className="space-y-2">
{client.contacts.map((c) => (
<div
key={c.id}
className="flex items-center gap-2 p-2 rounded-lg border bg-muted/30 text-sm"
>
<span className="capitalize text-muted-foreground w-20 shrink-0">{c.channel}</span>
<span className="flex-1">{c.value}</span>
{c.label && (
<span className="text-xs text-muted-foreground capitalize">{c.label}</span>
)}
{c.isPrimary && <span className="text-xs font-medium text-primary">Primary</span>}
</div>
))}
</div>
) : (
<p className="text-sm text-muted-foreground">No contacts added</p>
)}
</div>
{/* Source */}
{(client.source || client.sourceDetails) && (
<div className="space-y-1">
<h3 className="text-sm font-medium mb-2">Source</h3>
<dl>
<InfoRow label="Source" value={client.source} />
<InfoRow label="Source Details" value={client.sourceDetails} />
</dl>
</div>
)}
{/* Tags */}
{client.tags && client.tags.length > 0 && (
<div className="space-y-1">
<h3 className="text-sm font-medium mb-2">Tags</h3>
<div className="flex flex-wrap gap-1">
{client.tags.map((tag) => (
<span
key={tag.id}
className="inline-block rounded-full px-2 py-0.5 text-xs font-medium"
style={{ backgroundColor: `${tag.color}20`, color: tag.color }}
>
{tag.name}
</span>
))}
</div>
</div>
)}
</div>
);
}
export function getClientTabs({ clientId, currentUserId, client }: ClientTabsOptions): DetailTab[] {
return [
{
id: 'overview',
label: 'Overview',
content: <OverviewTab client={client} />,
},
{
id: 'yachts',
label: 'Yachts',
badge: client.yachts.length,
content: <ClientYachtsTab clientId={clientId} yachts={client.yachts} />,
},
{
id: 'companies',
label: 'Companies',
badge: client.companies.length,
content: <ClientCompaniesTab clientId={clientId} companies={client.companies} />,
},
{
id: 'reservations',
label: 'Reservations',
badge: client.activeReservations.length,
content: (
<ClientReservationsTab clientId={clientId} activeReservations={client.activeReservations} />
),
},
{
id: 'interests',
label: 'Interests',
content: (
<div className="text-center py-12 text-muted-foreground">
<p>Interests will appear here once created.</p>
</div>
),
},
{
id: 'notes',
label: 'Notes',
content: <NotesList entityType="clients" entityId={clientId} currentUserId={currentUserId} />,
},
{
id: 'files',
label: 'Files',
content: (
<div className="text-center py-12 text-muted-foreground">
<p>File attachments coming soon.</p>
</div>
),
},
{
id: 'activity',
label: 'Activity',
content: (
<div className="text-center py-12 text-muted-foreground">
<p>Activity log coming soon.</p>
</div>
),
},
];
}