157 lines
4.7 KiB
TypeScript
157 lines
4.7 KiB
TypeScript
|
|
'use client';
|
||
|
|
|
||
|
|
import { format } from 'date-fns';
|
||
|
|
|
||
|
|
import type { DetailTab } from '@/components/shared/detail-layout';
|
||
|
|
import { NotesList } from '@/components/shared/notes-list';
|
||
|
|
import { RecommendationList } from '@/components/interests/recommendation-list';
|
||
|
|
import { InterestTimeline } from '@/components/interests/interest-timeline';
|
||
|
|
|
||
|
|
interface InterestTabsOptions {
|
||
|
|
interestId: string;
|
||
|
|
currentUserId?: string;
|
||
|
|
interest: {
|
||
|
|
eoiStatus: string | null;
|
||
|
|
contractStatus: string | null;
|
||
|
|
depositStatus: string | null;
|
||
|
|
reservationStatus: string | null;
|
||
|
|
dateFirstContact: string | null;
|
||
|
|
dateLastContact: string | null;
|
||
|
|
dateEoiSent: string | null;
|
||
|
|
dateEoiSigned: string | null;
|
||
|
|
dateContractSent: string | null;
|
||
|
|
dateContractSigned: string | null;
|
||
|
|
dateDepositReceived: string | null;
|
||
|
|
reminderEnabled: boolean;
|
||
|
|
reminderDays: number | null;
|
||
|
|
reminderLastFired: string | null;
|
||
|
|
notes: string | null;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
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-44 shrink-0 text-sm text-muted-foreground">{label}</dt>
|
||
|
|
<dd className="text-sm">{value}</dd>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
function formatDate(date: string | null) {
|
||
|
|
if (!date) return null;
|
||
|
|
return format(new Date(date), 'MMM d, yyyy');
|
||
|
|
}
|
||
|
|
|
||
|
|
function OverviewTab({ interest }: { interest: InterestTabsOptions['interest'] }) {
|
||
|
|
return (
|
||
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||
|
|
{/* EOI & Contract Status */}
|
||
|
|
<div className="space-y-1">
|
||
|
|
<h3 className="text-sm font-medium mb-2">Status</h3>
|
||
|
|
<dl>
|
||
|
|
<InfoRow label="EOI Status" value={interest.eoiStatus} />
|
||
|
|
<InfoRow label="Contract Status" value={interest.contractStatus} />
|
||
|
|
<InfoRow label="Deposit Status" value={interest.depositStatus} />
|
||
|
|
<InfoRow label="Reservation Status" value={interest.reservationStatus} />
|
||
|
|
</dl>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Key Dates */}
|
||
|
|
<div className="space-y-1">
|
||
|
|
<h3 className="text-sm font-medium mb-2">Key Dates</h3>
|
||
|
|
<dl>
|
||
|
|
<InfoRow label="First Contact" value={formatDate(interest.dateFirstContact)} />
|
||
|
|
<InfoRow label="Last Contact" value={formatDate(interest.dateLastContact)} />
|
||
|
|
<InfoRow label="EOI Sent" value={formatDate(interest.dateEoiSent)} />
|
||
|
|
<InfoRow label="EOI Signed" value={formatDate(interest.dateEoiSigned)} />
|
||
|
|
<InfoRow label="Contract Sent" value={formatDate(interest.dateContractSent)} />
|
||
|
|
<InfoRow label="Contract Signed" value={formatDate(interest.dateContractSigned)} />
|
||
|
|
<InfoRow label="Deposit Received" value={formatDate(interest.dateDepositReceived)} />
|
||
|
|
</dl>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Reminder */}
|
||
|
|
{interest.reminderEnabled && (
|
||
|
|
<div className="space-y-1">
|
||
|
|
<h3 className="text-sm font-medium mb-2">Reminder</h3>
|
||
|
|
<dl>
|
||
|
|
<InfoRow
|
||
|
|
label="Reminder Days"
|
||
|
|
value={interest.reminderDays ? `${interest.reminderDays} days` : null}
|
||
|
|
/>
|
||
|
|
<InfoRow
|
||
|
|
label="Last Fired"
|
||
|
|
value={formatDate(interest.reminderLastFired)}
|
||
|
|
/>
|
||
|
|
</dl>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
|
||
|
|
{/* Notes */}
|
||
|
|
{interest.notes && (
|
||
|
|
<div className="space-y-1 md:col-span-2">
|
||
|
|
<h3 className="text-sm font-medium mb-2">Notes</h3>
|
||
|
|
<p className="text-sm text-muted-foreground whitespace-pre-wrap">
|
||
|
|
{interest.notes}
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
)}
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function getInterestTabs({
|
||
|
|
interestId,
|
||
|
|
currentUserId,
|
||
|
|
interest,
|
||
|
|
}: InterestTabsOptions): DetailTab[] {
|
||
|
|
return [
|
||
|
|
{
|
||
|
|
id: 'overview',
|
||
|
|
label: 'Overview',
|
||
|
|
content: <OverviewTab interest={interest} />,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'notes',
|
||
|
|
label: 'Notes',
|
||
|
|
content: (
|
||
|
|
<NotesList
|
||
|
|
entityType="interests"
|
||
|
|
entityId={interestId}
|
||
|
|
currentUserId={currentUserId}
|
||
|
|
/>
|
||
|
|
),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'documents',
|
||
|
|
label: 'Documents',
|
||
|
|
content: (
|
||
|
|
<div className="text-center py-12 text-muted-foreground">
|
||
|
|
<p>Documents tab available after document system is built</p>
|
||
|
|
</div>
|
||
|
|
),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'files',
|
||
|
|
label: 'Files',
|
||
|
|
content: (
|
||
|
|
<div className="text-center py-12 text-muted-foreground">
|
||
|
|
<p>Files tab available after file system is built</p>
|
||
|
|
</div>
|
||
|
|
),
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'recommendations',
|
||
|
|
label: 'Recommendations',
|
||
|
|
content: <RecommendationList interestId={interestId} />,
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id: 'activity',
|
||
|
|
label: 'Activity',
|
||
|
|
content: <InterestTimeline interestId={interestId} />,
|
||
|
|
},
|
||
|
|
];
|
||
|
|
}
|