chore: UX design audit cleanup and receipt flow improvements #186
@@ -13,6 +13,7 @@
|
||||
- `src/App.tsx`, `src/main.tsx` — app entry.
|
||||
- `src/features/*` — feature pages/components/hooks.
|
||||
- `src/core/*` — auth, api, store, hooks, query config, utils.
|
||||
- `src/core/utils/vehicleDisplay.ts` — shared vehicle display helpers: `getVehicleLabel()` (display name with fallback chain) and `getVehicleSubtitle()` (Year Make Model formatting).
|
||||
- `src/shared-minimal/*` — shared UI components and theme.
|
||||
|
||||
## Mobile + Desktop (required)
|
||||
|
||||
27
frontend/src/core/utils/vehicleDisplay.ts
Normal file
27
frontend/src/core/utils/vehicleDisplay.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
/** Vehicle-like object with minimal fields for display purposes */
|
||||
export interface VehicleLike {
|
||||
year?: number | null;
|
||||
make?: string | null;
|
||||
model?: string | null;
|
||||
trimLevel?: string | null;
|
||||
nickname?: string | null;
|
||||
vin?: string | null;
|
||||
id?: string | null;
|
||||
}
|
||||
|
||||
/** Primary display name with fallback chain: nickname -> year/make/model -> VIN -> ID */
|
||||
export const getVehicleLabel = (vehicle: VehicleLike | undefined): string => {
|
||||
if (!vehicle) return 'Unknown Vehicle';
|
||||
if (vehicle.nickname?.trim()) return vehicle.nickname.trim();
|
||||
const parts = [vehicle.year, vehicle.make, vehicle.model, vehicle.trimLevel].filter(Boolean);
|
||||
if (parts.length > 0) return parts.join(' ');
|
||||
if (vehicle.vin) return vehicle.vin;
|
||||
return vehicle.id ? `${vehicle.id.substring(0, 8)}...` : 'Unknown Vehicle';
|
||||
};
|
||||
|
||||
/** Subtitle line: "Year Make Model" with null safety. Returns empty string if insufficient data. */
|
||||
export const getVehicleSubtitle = (vehicle: VehicleLike | undefined): string => {
|
||||
if (!vehicle) return '';
|
||||
const parts = [vehicle.year?.toString(), vehicle.make, vehicle.model].filter(Boolean);
|
||||
return parts.length >= 2 ? parts.join(' ') : '';
|
||||
};
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
SubscriptionTier,
|
||||
ListUsersParams,
|
||||
} from '../types/admin.types';
|
||||
import { getVehicleSubtitle } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
// Modal component for dialogs
|
||||
interface ModalProps {
|
||||
@@ -128,7 +129,7 @@ const UserVehiclesList: React.FC<{ auth0Sub: string; isOpen: boolean }> = ({ aut
|
||||
<div className="space-y-1">
|
||||
{data.vehicles.map((vehicle, idx) => (
|
||||
<div key={idx} className="text-sm text-slate-600 dark:text-silverstone bg-slate-50 dark:bg-carbon px-2 py-1 rounded">
|
||||
{vehicle.year} {vehicle.make} {vehicle.model}
|
||||
{getVehicleSubtitle(vehicle) || 'Unknown Vehicle'}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,7 @@ import ErrorRoundedIcon from '@mui/icons-material/ErrorRounded';
|
||||
import WarningAmberRoundedIcon from '@mui/icons-material/WarningAmberRounded';
|
||||
import ScheduleRoundedIcon from '@mui/icons-material/ScheduleRounded';
|
||||
import { GlassCard } from '../../../shared-minimal/components/mobile/GlassCard';
|
||||
import { getVehicleLabel } from '@/core/utils/vehicleDisplay';
|
||||
import { VehicleNeedingAttention } from '../types';
|
||||
|
||||
interface VehicleAttentionProps {
|
||||
@@ -104,7 +105,7 @@ export const VehicleAttention: React.FC<VehicleAttentionProps> = ({ vehicles, on
|
||||
mb: 0.5,
|
||||
}}
|
||||
>
|
||||
{vehicle.nickname || `${vehicle.year} ${vehicle.make} ${vehicle.model}`}
|
||||
{getVehicleLabel(vehicle)}
|
||||
</Box>
|
||||
<p className="text-sm text-slate-600 dark:text-titanio">
|
||||
{vehicle.reason}
|
||||
|
||||
@@ -12,7 +12,6 @@ Document management UI with maintenance manual extraction. Handles file uploads,
|
||||
| `mobile/` | Mobile-specific document layout | Mobile UI |
|
||||
| `pages/` | DocumentsPage, DocumentDetailPage | Page layout |
|
||||
| `types/` | TypeScript type definitions | Type changes |
|
||||
| `utils/` | Utility functions (vehicle label formatting) | Helper logic |
|
||||
|
||||
## Key Files
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { AddDocumentDialog } from '../components/AddDocumentDialog';
|
||||
import { ExpirationBadge } from '../components/ExpirationBadge';
|
||||
import { DocumentCardMetadata } from '../components/DocumentCardMetadata';
|
||||
import { useVehicles } from '../../vehicles/hooks/useVehicles';
|
||||
import { getVehicleLabel } from '../utils/vehicleLabel';
|
||||
import { getVehicleLabel } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
export const DocumentsMobileScreen: React.FC = () => {
|
||||
console.log('[DocumentsMobileScreen] Component initializing');
|
||||
|
||||
@@ -12,7 +12,7 @@ import { EditDocumentDialog } from '../components/EditDocumentDialog';
|
||||
import { ExpirationBadge } from '../components/ExpirationBadge';
|
||||
import { DocumentCardMetadata } from '../components/DocumentCardMetadata';
|
||||
import { useVehicle, useVehicles } from '../../vehicles/hooks/useVehicles';
|
||||
import { getVehicleLabel } from '../utils/vehicleLabel';
|
||||
import { getVehicleLabel } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
export const DocumentDetailPage: React.FC = () => {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
|
||||
@@ -21,7 +21,7 @@ import { ExpirationBadge } from '../components/ExpirationBadge';
|
||||
import type { DocumentRecord } from '../types/documents.types';
|
||||
import { DocumentCardMetadata } from '../components/DocumentCardMetadata';
|
||||
import { useVehicles } from '../../vehicles/hooks/useVehicles';
|
||||
import { getVehicleLabel } from '../utils/vehicleLabel';
|
||||
import { getVehicleLabel } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
export const DocumentsPage: React.FC = () => {
|
||||
const { isAuthenticated, isLoading: authLoading, loginWithRedirect } = useAuth0();
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import type { Vehicle } from '../../vehicles/types/vehicles.types';
|
||||
|
||||
export const getVehicleLabel = (vehicle: Vehicle | undefined): string => {
|
||||
if (!vehicle) return 'Unknown Vehicle';
|
||||
if (vehicle.nickname?.trim()) return vehicle.nickname.trim();
|
||||
const parts = [vehicle.year, vehicle.make, vehicle.model, vehicle.trimLevel].filter(Boolean);
|
||||
const primary = parts.join(' ').trim();
|
||||
if (primary.length > 0) return primary;
|
||||
if (vehicle.vin?.length > 0) return vehicle.vin;
|
||||
return vehicle.id.slice(0, 8) + '...';
|
||||
};
|
||||
@@ -23,6 +23,7 @@ import CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded';
|
||||
import { useVehicles } from '../../vehicles/hooks/useVehicles';
|
||||
import { useResolveAssociation } from '../hooks/usePendingAssociations';
|
||||
import type { PendingVehicleAssociation } from '../types/email-ingestion.types';
|
||||
import { getVehicleLabel } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
interface ResolveAssociationDialogProps {
|
||||
open: boolean;
|
||||
@@ -166,9 +167,7 @@ export const ResolveAssociationDialog: React.FC<ResolveAssociationDialogProps> =
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1 }}>
|
||||
{vehicles.map((vehicle) => {
|
||||
const isSelected = selectedVehicleId === vehicle.id;
|
||||
const vehicleName = vehicle.nickname
|
||||
|| [vehicle.year, vehicle.make, vehicle.model].filter(Boolean).join(' ')
|
||||
|| 'Unnamed Vehicle';
|
||||
const vehicleName = getVehicleLabel(vehicle);
|
||||
|
||||
return (
|
||||
<Box
|
||||
|
||||
@@ -36,6 +36,7 @@ import { SubtypeCheckboxGroup } from './SubtypeCheckboxGroup';
|
||||
import { useVehicles } from '../../vehicles/hooks/useVehicles';
|
||||
import { documentsApi } from '../../documents/api/documents.api';
|
||||
import type { Vehicle } from '../../vehicles/types/vehicles.types';
|
||||
import { getVehicleLabel } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
interface MaintenanceRecordEditDialogProps {
|
||||
open: boolean;
|
||||
@@ -218,10 +219,7 @@ export const MaintenanceRecordEditDialog: React.FC<MaintenanceRecordEditDialogPr
|
||||
disabled
|
||||
value={(() => {
|
||||
const vehicle = vehicles?.find((v: Vehicle) => v.id === record.vehicleId);
|
||||
if (!vehicle) return 'Unknown Vehicle';
|
||||
if (vehicle.nickname?.trim()) return vehicle.nickname.trim();
|
||||
const parts = [vehicle.year, vehicle.make, vehicle.model, vehicle.trimLevel].filter(Boolean);
|
||||
return parts.length > 0 ? parts.join(' ') : 'Vehicle';
|
||||
return getVehicleLabel(vehicle);
|
||||
})()}
|
||||
helperText="Vehicle cannot be changed when editing"
|
||||
/>
|
||||
|
||||
@@ -46,6 +46,7 @@ import { useTierAccess } from '../../../core/hooks/useTierAccess';
|
||||
import { UpgradeRequiredDialog } from '../../../shared-minimal/components/UpgradeRequiredDialog';
|
||||
import { documentsApi } from '../../documents/api/documents.api';
|
||||
import toast from 'react-hot-toast';
|
||||
import { getVehicleSubtitle } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
const schema = z.object({
|
||||
vehicle_id: z.string().uuid({ message: 'Please select a vehicle' }),
|
||||
@@ -279,7 +280,7 @@ export const MaintenanceRecordForm: React.FC = () => {
|
||||
{vehicles && vehicles.length > 0 ? (
|
||||
vehicles.map((vehicle) => (
|
||||
<MenuItem key={vehicle.id} value={vehicle.id}>
|
||||
{vehicle.year} {vehicle.make} {vehicle.model}
|
||||
{getVehicleSubtitle(vehicle) || 'Unknown Vehicle'}
|
||||
</MenuItem>
|
||||
))
|
||||
) : (
|
||||
|
||||
@@ -39,6 +39,7 @@ import {
|
||||
import { SubtypeCheckboxGroup } from './SubtypeCheckboxGroup';
|
||||
import { useVehicles } from '../../vehicles/hooks/useVehicles';
|
||||
import type { Vehicle } from '../../vehicles/types/vehicles.types';
|
||||
import { getVehicleLabel } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
interface MaintenanceScheduleEditDialogProps {
|
||||
open: boolean;
|
||||
@@ -206,10 +207,7 @@ export const MaintenanceScheduleEditDialog: React.FC<MaintenanceScheduleEditDial
|
||||
disabled
|
||||
value={(() => {
|
||||
const vehicle = vehicles?.find((v: Vehicle) => v.id === schedule.vehicleId);
|
||||
if (!vehicle) return 'Unknown Vehicle';
|
||||
if (vehicle.nickname?.trim()) return vehicle.nickname.trim();
|
||||
const parts = [vehicle.year, vehicle.make, vehicle.model, vehicle.trimLevel].filter(Boolean);
|
||||
return parts.length > 0 ? parts.join(' ') : 'Vehicle';
|
||||
return getVehicleLabel(vehicle);
|
||||
})()}
|
||||
helperText="Vehicle cannot be changed when editing"
|
||||
/>
|
||||
|
||||
@@ -42,6 +42,7 @@ import {
|
||||
getCategoryDisplayName,
|
||||
} from '../types/maintenance.types';
|
||||
import toast from 'react-hot-toast';
|
||||
import { getVehicleSubtitle } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
const schema = z
|
||||
.object({
|
||||
@@ -214,7 +215,7 @@ export const MaintenanceScheduleForm: React.FC = () => {
|
||||
{vehicles && vehicles.length > 0 ? (
|
||||
vehicles.map((vehicle) => (
|
||||
<MenuItem key={vehicle.id} value={vehicle.id}>
|
||||
{vehicle.year} {vehicle.make} {vehicle.model}
|
||||
{getVehicleSubtitle(vehicle) || 'Unknown Vehicle'}
|
||||
</MenuItem>
|
||||
))
|
||||
) : (
|
||||
|
||||
@@ -16,6 +16,7 @@ import { MaintenanceScheduleForm } from '../components/MaintenanceScheduleForm';
|
||||
import { MaintenanceSchedulesList } from '../components/MaintenanceSchedulesList';
|
||||
import { MaintenanceScheduleEditDialog } from '../components/MaintenanceScheduleEditDialog';
|
||||
import type { MaintenanceRecordResponse, UpdateMaintenanceRecordRequest, MaintenanceScheduleResponse, UpdateScheduleRequest } from '../types/maintenance.types';
|
||||
import { getVehicleSubtitle } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
export const MaintenanceMobileScreen: React.FC = () => {
|
||||
const queryClient = useQueryClient();
|
||||
@@ -125,7 +126,7 @@ export const MaintenanceMobileScreen: React.FC = () => {
|
||||
{vehicles && vehicles.length > 0 ? (
|
||||
vehicles.map((vehicle) => (
|
||||
<MenuItem key={vehicle.id} value={vehicle.id} sx={{ minHeight: 44 }}>
|
||||
{vehicle.year} {vehicle.make} {vehicle.model}
|
||||
{getVehicleSubtitle(vehicle) || 'Unknown Vehicle'}
|
||||
</MenuItem>
|
||||
))
|
||||
) : (
|
||||
|
||||
@@ -16,6 +16,7 @@ import { useMaintenanceRecords } from '../hooks/useMaintenanceRecords';
|
||||
import { useVehicles } from '../../vehicles/hooks/useVehicles';
|
||||
import { FormSuspense } from '../../../components/SuspenseWrappers';
|
||||
import type { MaintenanceRecordResponse, UpdateMaintenanceRecordRequest, MaintenanceScheduleResponse, UpdateScheduleRequest } from '../types/maintenance.types';
|
||||
import { getVehicleSubtitle } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
export const MaintenancePage: React.FC = () => {
|
||||
const { data: vehicles, isLoading: isLoadingVehicles } = useVehicles();
|
||||
@@ -156,7 +157,7 @@ export const MaintenancePage: React.FC = () => {
|
||||
{vehicles && vehicles.length > 0 ? (
|
||||
vehicles.map((vehicle) => (
|
||||
<MenuItem key={vehicle.id} value={vehicle.id}>
|
||||
{vehicle.year} {vehicle.make} {vehicle.model}
|
||||
{getVehicleSubtitle(vehicle) || 'Unknown Vehicle'}
|
||||
</MenuItem>
|
||||
))
|
||||
) : (
|
||||
|
||||
@@ -7,6 +7,7 @@ import { useSettings } from '../hooks/useSettings';
|
||||
import { useProfile, useUpdateProfile } from '../hooks/useProfile';
|
||||
import { useExportUserData } from '../hooks/useExportUserData';
|
||||
import { useVehicles } from '../../vehicles/hooks/useVehicles';
|
||||
import { getVehicleSubtitle } from '@/core/utils/vehicleDisplay';
|
||||
import { useSubscription } from '../../subscription/hooks/useSubscription';
|
||||
import { useAdminAccess } from '../../../core/auth/useAdminAccess';
|
||||
import { useNavigationStore } from '../../../core/store';
|
||||
@@ -373,7 +374,7 @@ export const MobileSettingsScreen: React.FC = () => {
|
||||
className="p-3 bg-slate-50 dark:bg-nero rounded-lg"
|
||||
>
|
||||
<p className="font-medium text-slate-800 dark:text-avus">
|
||||
{vehicle.year} {vehicle.make} {vehicle.model}
|
||||
{getVehicleSubtitle(vehicle) || 'Unknown Vehicle'}
|
||||
</p>
|
||||
{vehicle.nickname && (
|
||||
<p className="text-sm text-slate-500 dark:text-titanio">{vehicle.nickname}</p>
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
Box,
|
||||
} from '@mui/material';
|
||||
import type { SubscriptionTier } from '../types/subscription.types';
|
||||
import { getVehicleLabel } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
interface Vehicle {
|
||||
id: string;
|
||||
@@ -70,13 +71,6 @@ export const VehicleSelectionDialog = ({
|
||||
onConfirm(selectedVehicleIds);
|
||||
};
|
||||
|
||||
const getVehicleLabel = (vehicle: Vehicle): string => {
|
||||
if (vehicle.nickname) {
|
||||
return vehicle.nickname;
|
||||
}
|
||||
const parts = [vehicle.year, vehicle.make, vehicle.model].filter(Boolean);
|
||||
return parts.join(' ') || 'Unknown Vehicle';
|
||||
};
|
||||
|
||||
const canConfirm = selectedVehicleIds.length > 0 && selectedVehicleIds.length <= maxSelections;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import { Vehicle } from '../types/vehicles.types';
|
||||
import { useUnits } from '../../../core/units/UnitsContext';
|
||||
import { VehicleImage } from './VehicleImage';
|
||||
import { getVehicleLabel } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
interface VehicleCardProps {
|
||||
vehicle: Vehicle;
|
||||
@@ -24,8 +25,7 @@ export const VehicleCard: React.FC<VehicleCardProps> = ({
|
||||
onSelect,
|
||||
}) => {
|
||||
const { formatDistance } = useUnits();
|
||||
const displayName = vehicle.nickname ||
|
||||
[vehicle.year, vehicle.make, vehicle.model, vehicle.trimLevel].filter(Boolean).join(' ');
|
||||
const displayName = getVehicleLabel(vehicle);
|
||||
|
||||
return (
|
||||
<Card
|
||||
|
||||
@@ -12,6 +12,7 @@ import { FuelLogEditDialog } from '../../fuel-logs/components/FuelLogEditDialog'
|
||||
import { fuelLogsApi } from '../../fuel-logs/api/fuel-logs.api';
|
||||
import { VehicleImage } from '../components/VehicleImage';
|
||||
import { OwnershipCostsList } from '../../ownership-costs';
|
||||
import { getVehicleLabel } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
interface VehicleDetailMobileProps {
|
||||
vehicle: Vehicle;
|
||||
@@ -38,8 +39,7 @@ export const VehicleDetailMobile: React.FC<VehicleDetailMobileProps> = ({
|
||||
onLogFuel,
|
||||
onEdit
|
||||
}) => {
|
||||
const displayName = vehicle.nickname ||
|
||||
[vehicle.year, vehicle.make, vehicle.model, vehicle.trimLevel].filter(Boolean).join(' ') || 'Vehicle';
|
||||
const displayName = getVehicleLabel(vehicle);
|
||||
const displayModel = vehicle.model || 'Unknown Model';
|
||||
|
||||
const [recordFilter, setRecordFilter] = useState<'All' | 'Fuel Logs' | 'Maintenance' | 'Documents'>('All');
|
||||
|
||||
@@ -6,6 +6,7 @@ import React from 'react';
|
||||
import { Card, CardActionArea, Box, Typography } from '@mui/material';
|
||||
import { Vehicle } from '../types/vehicles.types';
|
||||
import { VehicleImage } from '../components/VehicleImage';
|
||||
import { getVehicleLabel } from '@/core/utils/vehicleDisplay';
|
||||
|
||||
interface VehicleMobileCardProps {
|
||||
vehicle: Vehicle;
|
||||
@@ -18,8 +19,7 @@ export const VehicleMobileCard: React.FC<VehicleMobileCardProps> = ({
|
||||
onClick,
|
||||
compact = false
|
||||
}) => {
|
||||
const displayName = vehicle.nickname ||
|
||||
[vehicle.year, vehicle.make, vehicle.model, vehicle.trimLevel].filter(Boolean).join(' ') || 'Vehicle';
|
||||
const displayName = getVehicleLabel(vehicle);
|
||||
const displayModel = vehicle.model || 'Unknown Model';
|
||||
|
||||
return (
|
||||
|
||||
@@ -12,6 +12,7 @@ import LocalGasStationIcon from '@mui/icons-material/LocalGasStation';
|
||||
import BuildIcon from '@mui/icons-material/Build';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import { Vehicle } from '../types/vehicles.types';
|
||||
import { getVehicleLabel, getVehicleSubtitle } from '@/core/utils/vehicleDisplay';
|
||||
import { vehiclesApi } from '../api/vehicles.api';
|
||||
import { Card } from '../../../shared-minimal/components/Card';
|
||||
import { VehicleForm } from '../components/VehicleForm';
|
||||
@@ -224,8 +225,7 @@ export const VehicleDetailPage: React.FC = () => {
|
||||
);
|
||||
}
|
||||
|
||||
const displayName = vehicle.nickname ||
|
||||
[vehicle.year, vehicle.make, vehicle.model, vehicle.trimLevel].filter(Boolean).join(' ') || 'Vehicle';
|
||||
const displayName = getVehicleLabel(vehicle);
|
||||
|
||||
const handleRowClick = (recId: string, type: VehicleRecord['type']) => {
|
||||
if (type === 'Fuel Logs') {
|
||||
@@ -373,8 +373,7 @@ export const VehicleDetailPage: React.FC = () => {
|
||||
Vehicle Details
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
{vehicle.year} {vehicle.make} {vehicle.model}
|
||||
{vehicle.trimLevel && ` ${vehicle.trimLevel}`}
|
||||
{getVehicleSubtitle(vehicle) || 'Unknown Vehicle'}
|
||||
</Typography>
|
||||
{vehicle.vin && (
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mt: 0.5 }}>
|
||||
|
||||
@@ -11,6 +11,7 @@ import { useAdminAccess } from '../core/auth/useAdminAccess';
|
||||
import { useProfile, useUpdateProfile } from '../features/settings/hooks/useProfile';
|
||||
import { useExportUserData } from '../features/settings/hooks/useExportUserData';
|
||||
import { useVehicles } from '../features/vehicles/hooks/useVehicles';
|
||||
import { getVehicleSubtitle } from '@/core/utils/vehicleDisplay';
|
||||
import { useSubscription } from '../features/subscription/hooks/useSubscription';
|
||||
import { useTheme } from '../shared-minimal/theme/ThemeContext';
|
||||
import { DeleteAccountDialog } from '../features/settings/components/DeleteAccountDialog';
|
||||
@@ -375,7 +376,7 @@ export const SettingsPage: React.FC = () => {
|
||||
{index > 0 && <Divider />}
|
||||
<ListItem sx={{ py: 1.5 }}>
|
||||
<ListItemText
|
||||
primary={`${vehicle.year} ${vehicle.make} ${vehicle.model}`}
|
||||
primary={getVehicleSubtitle(vehicle) || 'Unknown Vehicle'}
|
||||
secondary={vehicle.nickname || undefined}
|
||||
primaryTypographyProps={{ fontWeight: 500 }}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user