2026-05-21 22:57:19 +02:00
|
|
|
'use client';
|
|
|
|
|
|
|
|
|
|
import Link from 'next/link';
|
|
|
|
|
import { Badge } from '@/components/ui/badge';
|
|
|
|
|
import type { ResidentialInterestRow } from './residential-interest-columns';
|
|
|
|
|
import { RESIDENTIAL_STAGE_LABELS } from './residential-interest-filters';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Mobile / grid card for the residential interests list. Mirrors the
|
chore(autonomous-session): consolidate uncommitted work from prior session
Bundles the prior autonomous-session output that was sitting unstaged:
- Em-dash sweep across src/ + tests/ (en-dash/em-dash to hyphen, ~2280 instances)
- country-flag-icons rollout (CountryFlag component, replaces emoji glyphs that
never rendered on Windows; lazy-loads the 3x2 SVG index as a single chunk
after the per-subpath dynamic-import approach silently failed in webpack)
- Admin IA Phase 1+2: 7-domain regroup, 41 to 38 pages, /admin/berths index,
redirects (ocr to ai, reports to dashboard, invitations to users),
docs/admin-ia-proposal.md
- Per-template email tester (registry + endpoint + UI on Email admin page)
- Cancel-document mode picker (delete-from-Documenso vs keep-for-audit)
- Dashboard PDF report: 25 widgets, SVG charts, date-range picker, 11 resolvers
- Customize-widgets per-region sortables at xl+ (charts/rails/feed); single
flat sortable below xl when the layout stacks; per-viewport saved orders
- Audit doc updates capturing each shipped item
- Lint fixes: react-compiler immutability in DonutChart (reduce instead of
let-reassign), set-state-in-effect disables in CountryFlag and
UploadForSigning preview-bytes effect, unused 'confirm' destructures in
interest contract + reservation tabs, unescaped apostrophe in test-template
card copy
2026-05-23 00:52:59 +02:00
|
|
|
* footprint of <InterestCard> on the main list - same touch target
|
2026-05-21 22:57:19 +02:00
|
|
|
* conventions (entire card is clickable, generous padding, truncated
|
|
|
|
|
* meta below the title).
|
|
|
|
|
*/
|
|
|
|
|
export function ResidentialInterestCard({
|
|
|
|
|
interest,
|
|
|
|
|
portSlug,
|
|
|
|
|
}: {
|
|
|
|
|
interest: ResidentialInterestRow;
|
|
|
|
|
portSlug: string;
|
|
|
|
|
}) {
|
|
|
|
|
return (
|
|
|
|
|
<Link
|
|
|
|
|
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
|
|
|
|
href={`/${portSlug}/residential/interests/${interest.id}` as any}
|
|
|
|
|
className="block rounded-lg border bg-card p-3 transition-colors hover:bg-muted/30"
|
|
|
|
|
>
|
|
|
|
|
<div className="flex items-start justify-between gap-2">
|
|
|
|
|
<div className="min-w-0">
|
chore(autonomous-session): consolidate uncommitted work from prior session
Bundles the prior autonomous-session output that was sitting unstaged:
- Em-dash sweep across src/ + tests/ (en-dash/em-dash to hyphen, ~2280 instances)
- country-flag-icons rollout (CountryFlag component, replaces emoji glyphs that
never rendered on Windows; lazy-loads the 3x2 SVG index as a single chunk
after the per-subpath dynamic-import approach silently failed in webpack)
- Admin IA Phase 1+2: 7-domain regroup, 41 to 38 pages, /admin/berths index,
redirects (ocr to ai, reports to dashboard, invitations to users),
docs/admin-ia-proposal.md
- Per-template email tester (registry + endpoint + UI on Email admin page)
- Cancel-document mode picker (delete-from-Documenso vs keep-for-audit)
- Dashboard PDF report: 25 widgets, SVG charts, date-range picker, 11 resolvers
- Customize-widgets per-region sortables at xl+ (charts/rails/feed); single
flat sortable below xl when the layout stacks; per-viewport saved orders
- Audit doc updates capturing each shipped item
- Lint fixes: react-compiler immutability in DonutChart (reduce instead of
let-reassign), set-state-in-effect disables in CountryFlag and
UploadForSigning preview-bytes effect, unused 'confirm' destructures in
interest contract + reservation tabs, unescaped apostrophe in test-template
card copy
2026-05-23 00:52:59 +02:00
|
|
|
<p className="truncate text-sm font-medium">{interest.clientName ?? '-'}</p>
|
2026-05-21 22:57:19 +02:00
|
|
|
<div className="mt-1 flex flex-wrap items-center gap-1.5">
|
|
|
|
|
<Badge variant="secondary" className="text-[10px]">
|
|
|
|
|
{RESIDENTIAL_STAGE_LABELS[interest.pipelineStage] ?? interest.pipelineStage}
|
|
|
|
|
</Badge>
|
|
|
|
|
{interest.source ? (
|
|
|
|
|
<span className="text-[11px] capitalize text-muted-foreground">
|
|
|
|
|
{interest.source}
|
|
|
|
|
</span>
|
|
|
|
|
) : null}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<span className="shrink-0 text-[11px] text-muted-foreground">
|
|
|
|
|
{new Date(interest.updatedAt).toLocaleDateString()}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
{interest.preferences ? (
|
|
|
|
|
<p className="mt-1 line-clamp-2 text-xs text-muted-foreground">{interest.preferences}</p>
|
|
|
|
|
) : null}
|
|
|
|
|
{interest.notes ? (
|
|
|
|
|
<p className="mt-1 line-clamp-1 text-xs text-muted-foreground/80">{interest.notes}</p>
|
|
|
|
|
) : null}
|
|
|
|
|
</Link>
|
|
|
|
|
);
|
|
|
|
|
}
|