feat: Enhance Documents UX with detail view, type-specific cards, and expiration alerts (#43) #44

Merged
egullickson merged 2 commits from issue-43-documents-ux-enhancement into main 2026-01-18 03:04:19 +00:00
3 changed files with 29 additions and 8 deletions
Showing only changes of commit 7c3eaeb5a3 - Show all commits

View File

@@ -200,7 +200,7 @@ export const DocumentsMobileScreen: React.FC = () => {
</button>
</div>
<div className="flex gap-2 items-center flex-wrap">
<Button onClick={() => navigate(`/garage/documents/${doc.id}`)}>Open</Button>
<Button onClick={() => navigate(`/garage/documents/${doc.id}`)}>View Details</Button>
<Button onClick={() => triggerUpload(doc.id)}>Upload</Button>
{upload.isPending && currentId === doc.id && (
<span className="text-xs text-slate-500">{upload.progress}%</span>

View File

@@ -27,6 +27,25 @@ export const DocumentDetailPage: React.FC = () => {
const vehiclesMap = useMemo(() => new Map(vehicles?.map(v => [v.id, v]) || []), [vehicles]);
// Check if document has displayable metadata
const hasDisplayableMetadata = useMemo(() => {
if (!doc) return false;
const details = doc.details || {};
if (doc.documentType === 'insurance') {
return !!(doc.expirationDate || details.policyNumber || details.insuranceCompany ||
doc.issuedDate || details.bodilyInjuryPerson || details.bodilyInjuryIncident ||
details.propertyDamage || details.premium);
}
if (doc.documentType === 'registration') {
return !!(doc.expirationDate || details.licensePlate || details.cost);
}
if (doc.documentType === 'manual') {
return !!(doc.issuedDate || doc.notes);
}
return false;
}, [doc]);
const handleDownload = async () => {
if (!id) return;
const blob = await documentsApi.download(id);
@@ -167,7 +186,7 @@ export const DocumentDetailPage: React.FC = () => {
{getVehicleLabel(vehicle)}
</button>
</div>
<DocumentCardMetadata doc={doc} variant="mobile" />
{hasDisplayableMetadata && <DocumentCardMetadata doc={doc} variant="mobile" />}
</div>
</Card>
@@ -262,11 +281,13 @@ export const DocumentDetailPage: React.FC = () => {
</div>
)}
{/* Type-specific Metadata */}
<div>
<div className="text-sm text-slate-500 dark:text-titanio mb-2">Details</div>
<DocumentCardMetadata doc={doc} variant="detail" />
</div>
{/* Type-specific Metadata - only show if there's data */}
{hasDisplayableMetadata && (
<div>
<div className="text-sm text-slate-500 dark:text-titanio mb-2">Details</div>
<DocumentCardMetadata doc={doc} variant="detail" />
</div>
)}
{/* Actions */}
<div className="pt-2 border-t border-slate-200 dark:border-silverstone">

View File

@@ -158,7 +158,7 @@ export const DocumentsPage: React.FC = () => {
</div>
)}
<div className="flex gap-2 pt-2">
<Button onClick={() => navigate(`/garage/documents/${doc.id}`)}>Open</Button>
<Button onClick={() => navigate(`/garage/documents/${doc.id}`)}>View Details</Button>
<Button variant="danger" onClick={() => removeDoc.mutate(doc.id)}>Delete</Button>
</div>
</div>