feat: display vehicle names instead of UUIDs in document views (refs #31)

- Created shared utility getVehicleLabel() for consistent vehicle display
- Updated DocumentsPage to show vehicle names with clickable links
- Added "Shared with X vehicles" indicator for multi-vehicle docs
- Updated DocumentDetailPage with vehicle name and shared vehicle list
- Updated DocumentsMobileScreen with vehicle names and "Shared" indicator
- All vehicle names link to vehicle detail pages
- Mobile-first with 44px touch targets on all links

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Eric Gullickson
2026-01-14 19:34:02 -06:00
parent e558fdf8f9
commit 8968cad805
4 changed files with 103 additions and 20 deletions

View File

@@ -1,4 +1,4 @@
import React, { useRef } from 'react';
import React, { useRef, useMemo } from 'react';
import { useAuth0 } from '@auth0/auth0-react';
import { isAxiosError } from 'axios';
import { useNavigate } from 'react-router-dom';
@@ -7,6 +7,8 @@ import { useDocumentsList } from '../hooks/useDocuments';
import { useUploadWithProgress } from '../hooks/useUploadWithProgress';
import { Button } from '../../../shared-minimal/components/Button';
import { AddDocumentDialog } from '../components/AddDocumentDialog';
import { useVehicles } from '../../vehicles/hooks/useVehicles';
import { getVehicleLabel } from '../utils/vehicleLabel';
export const DocumentsMobileScreen: React.FC = () => {
console.log('[DocumentsMobileScreen] Component initializing');
@@ -17,12 +19,15 @@ export const DocumentsMobileScreen: React.FC = () => {
// Data hooks (unconditional per React rules)
const { data, isLoading, error } = useDocumentsList();
const { data: vehicles } = useVehicles();
const inputRef = useRef<HTMLInputElement | null>(null);
const [currentId, setCurrentId] = React.useState<string | null>(null);
const upload = useUploadWithProgress(currentId || '');
const navigate = useNavigate();
const [isAddOpen, setIsAddOpen] = React.useState(false);
const vehiclesMap = useMemo(() => new Map(vehicles?.map(v => [v.id, v]) || []), [vehicles]);
const triggerUpload = (docId: string) => {
try {
setCurrentId(docId);
@@ -170,14 +175,25 @@ export const DocumentsMobileScreen: React.FC = () => {
{!isLoading && !hasError && data && data.length > 0 && (
<div className="space-y-3">
{data.map((doc) => {
const vehicleLabel = doc.vehicleId ? `${doc.vehicleId.slice(0, 8)}...` : '—';
const vehicle = vehiclesMap.get(doc.vehicleId);
const vehicleLabel = getVehicleLabel(vehicle);
const isShared = doc.sharedVehicleIds.length > 0;
return (
<div key={doc.id} className="flex items-center justify-between border rounded-xl p-3">
<div key={doc.id} className="border rounded-xl p-3 space-y-2">
<div>
<div className="font-medium text-slate-800 dark:text-avus">{doc.title}</div>
<div className="text-xs text-slate-500 dark:text-titanio">{doc.documentType} {vehicleLabel}</div>
<div className="text-xs text-slate-500 dark:text-titanio">
{doc.documentType}
{isShared && ' • Shared'}
</div>
<button
onClick={() => navigate(`/garage/vehicles/${doc.vehicleId}`)}
className="text-xs text-blue-600 hover:text-blue-800 underline min-h-[44px] inline-flex items-center"
>
{vehicleLabel}
</button>
</div>
<div className="flex gap-2 items-center">
<div className="flex gap-2 items-center flex-wrap">
<Button onClick={() => navigate(`/garage/documents/${doc.id}`)}>Open</Button>
<Button onClick={() => triggerUpload(doc.id)}>Upload</Button>
{upload.isPending && currentId === doc.id && (