Updated packages. Changed date picker package to Day.JS and applied it across whole app.

This commit is contained in:
Eric Gullickson
2025-12-18 16:07:30 -06:00
parent 843825a956
commit 0e85cf48c3
17 changed files with 197 additions and 135 deletions

View File

@@ -96,7 +96,9 @@
"mcp__playwright__browser_close",
"Bash(wc:*)",
"mcp__brave-search__brave_web_search",
"mcp__firecrawl__firecrawl_search"
"mcp__firecrawl__firecrawl_search",
"Bash(ssh:*)",
"Bash(git checkout:*)"
],
"deny": []
}

21
backend/eslint.config.js Normal file
View File

@@ -0,0 +1,21 @@
import js from '@eslint/js';
import tseslint from 'typescript-eslint';
export default tseslint.config(
{ ignores: ['dist', 'node_modules'] },
js.configs.recommended,
...tseslint.configs.recommended,
{
files: ['**/*.ts'],
rules: {
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': ['warn', {
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
ignoreRestSiblings: true,
args: 'after-used'
}],
'@typescript-eslint/no-explicit-any': 'warn',
},
},
);

View File

@@ -13,26 +13,26 @@
"migrate:all": "ts-node src/_system/migrations/run-all.ts",
"migrate:feature": "ts-node src/_system/migrations/run-feature.ts",
"schema:generate": "ts-node src/_system/schema/generate.ts",
"lint": "eslint src --ext .ts"
"lint": "eslint src"
},
"dependencies": {
"pg": "^8.11.3",
"ioredis": "^5.3.2",
"pg": "^8.13.1",
"ioredis": "^5.4.2",
"minio": "^7.1.3",
"@fastify/multipart": "^8.1.0",
"axios": "^1.6.2",
"@fastify/multipart": "^9.0.1",
"axios": "^1.7.9",
"opossum": "^8.0.0",
"winston": "^3.11.0",
"zod": "^3.22.4",
"winston": "^3.17.0",
"zod": "^3.24.1",
"js-yaml": "^4.1.0",
"fastify": "^4.24.3",
"@fastify/cors": "^9.0.1",
"@fastify/helmet": "^11.1.1",
"@fastify/jwt": "^8.0.0",
"@fastify/type-provider-typebox": "^4.0.0",
"@sinclair/typebox": "^0.31.28",
"fastify-plugin": "^4.5.1",
"@fastify/autoload": "^5.8.0",
"fastify": "^5.2.0",
"@fastify/cors": "^10.0.1",
"@fastify/helmet": "^12.0.1",
"@fastify/jwt": "^9.0.1",
"@fastify/type-provider-typebox": "^5.0.0",
"@sinclair/typebox": "^0.34.0",
"fastify-plugin": "^5.0.1",
"@fastify/autoload": "^6.0.1",
"get-jwks": "^9.0.0",
"file-type": "^16.5.4"
},
@@ -40,17 +40,17 @@
"@types/node": "^20.10.0",
"@types/pg": "^8.10.9",
"@types/js-yaml": "^4.0.9",
"typescript": "^5.6.3",
"typescript": "^5.7.2",
"ts-node": "^10.9.1",
"nodemon": "^3.0.1",
"nodemon": "^3.1.9",
"jest": "^29.7.0",
"@types/jest": "^29.5.10",
"ts-jest": "^29.1.1",
"supertest": "^6.3.3",
"@types/supertest": "^2.0.16",
"@types/opossum": "^8.0.0",
"eslint": "^8.54.0",
"@typescript-eslint/eslint-plugin": "^6.12.0",
"@typescript-eslint/parser": "^6.12.0"
"eslint": "^9.17.0",
"@eslint/js": "^9.17.0",
"typescript-eslint": "^8.18.1"
}
}

View File

@@ -2,12 +2,12 @@
* @ai-summary Fastify global error handling plugin
* @ai-context Handles uncaught errors with structured logging
*/
import { FastifyPluginAsync } from 'fastify';
import { FastifyPluginAsync, FastifyError } from 'fastify';
import fp from 'fastify-plugin';
import { logger } from '../logging/logger';
const errorPlugin: FastifyPluginAsync = async (fastify) => {
fastify.setErrorHandler((error, request, reply) => {
fastify.setErrorHandler((error: FastifyError, request, reply) => {
logger.error('Unhandled error', {
error: error.message,
stack: error.stack,

View File

@@ -43,7 +43,10 @@ def load_pairs(snapshot_path: Path) -> List[sqlite3.Row]:
if not snapshot_path.exists():
raise FileNotFoundError(f"Snapshot not found: {snapshot_path}")
conn = sqlite3.connect(snapshot_path)
# Open in immutable mode to prevent any write attempts on read-only filesystems
absolute_path = snapshot_path.resolve()
uri = f"file:{absolute_path}?immutable=1"
conn = sqlite3.connect(uri, uri=True)
conn.row_factory = sqlite3.Row
try:
cursor = conn.execute(

View File

@@ -20,14 +20,16 @@ Your task is to create a plan that can be dispatched to a seprate set of AI agen
*** ROLE ***
You are a senior devops systems reliablity engineer specializing modern web applications. Expert in linux, docker compose and gitlab.
Read README.md CLAUDE.md and AI-INDEX.md to understand this code repository in the context of this change.
You are a senior web deveoper specializing in nodejs, typescript along with CSS and HTML.
*** ACTION ***
- You need to create a plan for the end user to implement to make this application deployable with GitLab runners.
- You need to create a plan to upgrade the node packages to the latest versions that are compatible with each other. Some of the packages are very old and while we might not get to the very latest we need to get as close as possible for security reasons.
- Use context7 mcp to find the latest versions and compatibilities.
- Read README.md CLAUDE.md and AI-INDEX.md to understand this code repository in the context of this change.
*** CONTEXT ***
- This is a docker compose app that is functioning in the local dev environment. It was developed with the plan to move to Kubernetes eventually but right now it's staying in docker compose. There is a secrets architecture that mirrors k8s that needs to be replicated in gitlab deployment into the docker compose environment. The gitlab version is 18.6.2 and is using the shell runtime on the gitlab runners.
- This is a modern web app for managing a vehicle fleet. It has both a desktop and mobile versions of the site that both need to maintain feature parity. The UX will be different between mobile and desktop due to resolution differences but that's it.
*** EXECUTE ***
Create a plan the user can execute to make this app deployable with gitlab. Use brave, context7 and firecrawl if needed. Make no assumptions if your data does not have version 18.6 of gitlab. Save the plan to @docs/CICD-DEPLOY.md. Ultrathink.
Create a plan that can be tasked to sub agents to explore and find dependancies between all the packages. Make sure nothing breaks. Use context7, brave search and firecrawl MCP's extensively. Make no assumptions.

View File

@@ -2,25 +2,23 @@ import js from '@eslint/js';
import globals from 'globals';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import tseslint from '@typescript-eslint/eslint-plugin';
import parser from '@typescript-eslint/parser';
import tseslint from 'typescript-eslint';
export default [
{ ignores: ['dist'] },
export default tseslint.config(
{ ignores: ['dist', 'node_modules'] },
js.configs.recommended,
...tseslint.configs.recommended,
{
files: ['**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parser,
},
plugins: {
'@typescript-eslint': tseslint,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...js.configs.recommended.rules,
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
@@ -36,4 +34,4 @@ export default [
'@typescript-eslint/no-explicit-any': 'warn',
},
},
];
);

View File

@@ -12,47 +12,48 @@
"type-check": "tsc --noEmit"
},
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.8.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router-dom": "^6.28.1",
"@auth0/auth0-react": "^2.2.3",
"axios": "^1.6.2",
"zustand": "^4.4.6",
"@tanstack/react-query": "^5.8.4",
"react-hook-form": "^7.48.2",
"@hookform/resolvers": "^3.3.2",
"zod": "^3.22.4",
"date-fns": "^2.30.0",
"axios": "^1.7.9",
"zustand": "^4.5.6",
"@tanstack/react-query": "^5.84.1",
"react-hook-form": "^7.54.2",
"@hookform/resolvers": "^3.9.1",
"zod": "^3.24.1",
"dayjs": "^1.11.13",
"clsx": "^2.0.0",
"react-hot-toast": "^2.4.1",
"react-slick": "^0.30.2",
"slick-carousel": "^1.8.1",
"framer-motion": "^11.0.0",
"@mui/material": "^5.15.0",
"@mui/x-date-pickers": "^6.19.0",
"@mui/x-data-grid": "^6.19.1",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.0",
"@emotion/cache": "^11.11.0",
"@mui/icons-material": "^5.15.0"
"framer-motion": "^11.15.0",
"@mui/material": "^6.3.0",
"@mui/x-date-pickers": "^7.23.0",
"@mui/x-data-grid": "^7.23.0",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@emotion/cache": "^11.14.0",
"@mui/icons-material": "^6.3.0"
},
"devDependencies": {
"@types/react": "^18.2.0",
"@types/react-dom": "^18.2.0",
"@types/react": "^19.0.2",
"@types/react-dom": "^19.0.2",
"@types/react-slick": "^0.23.13",
"@typescript-eslint/eslint-plugin": "^6.12.0",
"@typescript-eslint/parser": "^6.12.0",
"@vitejs/plugin-react": "^4.2.0",
"autoprefixer": "^10.4.16",
"eslint": "^8.54.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.4",
"postcss": "^8.4.32",
"tailwindcss": "^3.3.6",
"typescript-eslint": "^8.18.1",
"@vitejs/plugin-react": "^4.3.4",
"autoprefixer": "^10.4.20",
"eslint": "^9.17.0",
"@eslint/js": "^9.17.0",
"globals": "^15.14.0",
"eslint-plugin-react-hooks": "^5.1.0",
"eslint-plugin-react-refresh": "^0.4.16",
"postcss": "^8.4.49",
"tailwindcss": "^3.4.17",
"terser": "^5.24.0",
"@emotion/babel-plugin": "^11.11.0",
"typescript": "^5.6.3",
"vite": "^5.0.6",
"typescript": "^5.7.2",
"vite": "^5.4.11",
"jest": "^29.7.0",
"@types/jest": "^29.5.10",
"ts-jest": "^29.1.1",

View File

@@ -15,12 +15,15 @@ import {
Divider,
} from '@mui/material';
import { Close, ChevronLeft, ChevronRight } from '@mui/icons-material';
import { formatDistanceToNow } from 'date-fns';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import { useAuditLogStream } from '../hooks/useAuditLogStream';
import { AdminSkeleton } from './AdminSkeleton';
import { EmptyState } from './EmptyState';
import { ErrorState } from './ErrorState';
dayjs.extend(relativeTime);
/**
* Props for AuditLogDrawer component
*/
@@ -154,9 +157,7 @@ export const AuditLogDrawer: React.FC<AuditLogDrawerProps> = ({
component="span"
color="text.secondary"
>
{formatDistanceToNow(new Date(log.createdAt), {
addSuffix: true,
})}
{dayjs(log.createdAt).fromNow()}
</Typography>
{log.resourceType && (
<Typography
@@ -193,10 +194,7 @@ export const AuditLogDrawer: React.FC<AuditLogDrawerProps> = ({
}}
>
<Typography variant="body2" color="text.secondary">
Updated{' '}
{formatDistanceToNow(lastUpdated, {
addSuffix: true,
})}
Updated {dayjs(lastUpdated).fromNow()}
</Typography>
<Box>
<IconButton

View File

@@ -21,12 +21,15 @@ import {
ChevronLeft,
ChevronRight,
} from '@mui/icons-material';
import { formatDistanceToNow } from 'date-fns';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import { useAuditLogStream } from '../hooks/useAuditLogStream';
import { AdminSkeleton } from './AdminSkeleton';
import { EmptyState } from './EmptyState';
import { ErrorState } from './ErrorState';
dayjs.extend(relativeTime);
/**
* Props for AuditLogPanel component
*/
@@ -148,9 +151,7 @@ export const AuditLogPanel: React.FC<AuditLogPanelProps> = ({
component="span"
color="text.secondary"
>
{formatDistanceToNow(new Date(log.createdAt), {
addSuffix: true,
})}
{dayjs(log.createdAt).fromNow()}
</Typography>
{log.resourceType && (
<Typography
@@ -186,10 +187,7 @@ export const AuditLogPanel: React.FC<AuditLogPanelProps> = ({
}}
>
<Typography variant="caption" color="text.secondary">
Updated{' '}
{formatDistanceToNow(lastUpdated, {
addSuffix: true,
})}
Updated {dayjs(lastUpdated).fromNow()}
</Typography>
<Box>
<IconButton

View File

@@ -1,5 +1,9 @@
import React from 'react';
import { Button } from '../../../shared-minimal/components/Button';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import dayjs from 'dayjs';
import { useCreateDocument } from '../hooks/useDocuments';
import { documentsApi } from '../api/documents.api';
import type { DocumentType } from '../types/documents.types';
@@ -144,6 +148,7 @@ export const DocumentForm: React.FC<DocumentFormProps> = ({ onSuccess, onCancel
};
return (
<LocalizationProvider dateAdapter={AdapterDayjs}>
<form onSubmit={handleSubmit} className="w-full">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="flex flex-col">
@@ -207,21 +212,39 @@ export const DocumentForm: React.FC<DocumentFormProps> = ({ onSuccess, onCancel
</div>
<div className="flex flex-col">
<label className="text-sm font-medium text-slate-700 mb-1">Effective Date</label>
<input
className="h-11 min-h-[44px] rounded-lg border border-slate-300 px-3 focus:outline-none focus:ring-2 focus:ring-primary-500"
type="date"
value={effectiveDate}
onChange={(e) => setEffectiveDate(e.target.value)}
<DatePicker
label="Effective Date"
value={effectiveDate ? dayjs(effectiveDate) : null}
onChange={(newValue) => setEffectiveDate(newValue?.format('YYYY-MM-DD') || '')}
format="MM/DD/YYYY"
slotProps={{
textField: {
fullWidth: true,
sx: {
'& .MuiOutlinedInput-root': {
minHeight: 44,
},
},
},
}}
/>
</div>
<div className="flex flex-col">
<label className="text-sm font-medium text-slate-700 mb-1">Expiration Date</label>
<input
className="h-11 min-h-[44px] rounded-lg border border-slate-300 px-3 focus:outline-none focus:ring-2 focus:ring-primary-500"
type="date"
value={expirationDate}
onChange={(e) => setExpirationDate(e.target.value)}
<DatePicker
label="Expiration Date"
value={expirationDate ? dayjs(expirationDate) : null}
onChange={(newValue) => setExpirationDate(newValue?.format('YYYY-MM-DD') || '')}
format="MM/DD/YYYY"
slotProps={{
textField: {
fullWidth: true,
sx: {
'& .MuiOutlinedInput-root': {
minHeight: 44,
},
},
},
}}
/>
</div>
@@ -282,12 +305,21 @@ export const DocumentForm: React.FC<DocumentFormProps> = ({ onSuccess, onCancel
/>
</div>
<div className="flex flex-col">
<label className="text-sm font-medium text-slate-700 mb-1">Expiration Date</label>
<input
className="h-11 min-h-[44px] rounded-lg border border-slate-300 px-3 focus:outline-none focus:ring-2 focus:ring-primary-500"
type="date"
value={registrationExpirationDate}
onChange={(e) => setRegistrationExpirationDate(e.target.value)}
<DatePicker
label="Expiration Date"
value={registrationExpirationDate ? dayjs(registrationExpirationDate) : null}
onChange={(newValue) => setRegistrationExpirationDate(newValue?.format('YYYY-MM-DD') || '')}
format="MM/DD/YYYY"
slotProps={{
textField: {
fullWidth: true,
sx: {
'& .MuiOutlinedInput-root': {
minHeight: 44,
},
},
},
}}
/>
</div>
<div className="flex flex-col md:col-span-2">
@@ -336,6 +368,7 @@ export const DocumentForm: React.FC<DocumentFormProps> = ({ onSuccess, onCancel
<Button type="button" variant="secondary" onClick={onCancel} className="min-h-[44px]">Cancel</Button>
</div>
</form>
</LocalizationProvider>
);
};

View File

@@ -16,8 +16,9 @@ import {
useMediaQuery
} from '@mui/material';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
import dayjs from 'dayjs';
import { FuelLogResponse, UpdateFuelLogRequest, FuelType } from '../types/fuel-logs.types';
import { useFuelGrades } from '../hooks/useFuelGrades';
@@ -135,7 +136,7 @@ export const FuelLogEditDialog: React.FC<FuelLogEditDialogProps> = ({
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<Dialog
open={open}
onClose={handleCancel}
@@ -154,9 +155,9 @@ export const FuelLogEditDialog: React.FC<FuelLogEditDialogProps> = ({
<Grid item xs={12}>
<DateTimePicker
label="Date & Time"
value={formData.dateTime ? new Date(formData.dateTime) : null}
value={formData.dateTime ? dayjs(formData.dateTime) : null}
onChange={(newValue) => handleInputChange('dateTime', newValue?.toISOString() || '')}
format="MM/dd/yyyy hh:mm a"
format="MM/DD/YYYY hh:mm a"
slotProps={{
textField: {
fullWidth: true,

View File

@@ -4,8 +4,9 @@ import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import { Grid, Card, CardHeader, CardContent, TextField, Box, Button, CircularProgress, ToggleButton, ToggleButtonGroup } from '@mui/material';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DateTimePicker } from '@mui/x-date-pickers/DateTimePicker';
import dayjs from 'dayjs';
import { VehicleSelector } from './VehicleSelector';
import { DistanceInput } from './DistanceInput';
import { FuelTypeSelector } from './FuelTypeSelector';
@@ -143,7 +144,7 @@ const FuelLogFormComponent: React.FC<{ onSuccess?: () => void; initial?: Partial
}, [useOdometer, setValue]);
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<Card>
<CardHeader title="Add Fuel Log" subheader={<UnitSystemDisplay unitSystem={userSettings?.unitSystem} showLabel="Displaying in" />} />
<CardContent>
@@ -161,9 +162,9 @@ const FuelLogFormComponent: React.FC<{ onSuccess?: () => void; initial?: Partial
<Controller name="dateTime" control={control} render={({ field }) => (
<DateTimePicker
label="Date & Time"
value={field.value ? new Date(field.value) : null}
value={field.value ? dayjs(field.value) : null}
onChange={(newValue) => field.onChange(newValue?.toISOString() || '')}
format="MM/dd/yyyy hh:mm a"
format="MM/DD/YYYY hh:mm a"
slotProps={{
textField: {
fullWidth: true,

View File

@@ -21,8 +21,9 @@ import {
useMediaQuery,
} from '@mui/material';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import dayjs from 'dayjs';
import {
MaintenanceRecordResponse,
UpdateMaintenanceRecordRequest,
@@ -149,7 +150,7 @@ export const MaintenanceRecordEditDialog: React.FC<MaintenanceRecordEditDialogPr
}
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<Dialog
open={open}
onClose={handleCancel}
@@ -221,11 +222,11 @@ export const MaintenanceRecordEditDialog: React.FC<MaintenanceRecordEditDialogPr
<Grid item xs={12} sm={6}>
<DatePicker
label="Service Date *"
value={formData.date ? new Date(formData.date) : null}
value={formData.date ? dayjs(formData.date) : null}
onChange={(newValue) =>
handleInputChange('date', newValue?.toISOString().split('T')[0] || '')
}
format="MM/dd/yyyy"
format="MM/DD/YYYY"
slotProps={{
textField: {
fullWidth: true,

View File

@@ -25,8 +25,9 @@ import {
InputAdornment,
} from '@mui/material';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import dayjs from 'dayjs';
import { useMaintenanceRecords } from '../hooks/useMaintenanceRecords';
import { useVehicles } from '../../vehicles/hooks/useVehicles';
import { SubtypeCheckboxGroup } from './SubtypeCheckboxGroup';
@@ -135,7 +136,7 @@ export const MaintenanceRecordForm: React.FC = () => {
}
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<Card>
<CardHeader title="Add Maintenance Record" />
<CardContent>
@@ -238,11 +239,11 @@ export const MaintenanceRecordForm: React.FC = () => {
render={({ field }) => (
<DatePicker
label="Date *"
value={field.value ? new Date(field.value) : null}
value={field.value ? dayjs(field.value) : null}
onChange={(newValue) =>
field.onChange(newValue?.toISOString().split('T')[0] || '')
}
format="MM/dd/yyyy"
format="MM/DD/YYYY"
slotProps={{
textField: {
fullWidth: true,

View File

@@ -3,7 +3,7 @@
*/
import React, { useMemo, useState } from 'react';
import { Box, Typography, Button, Card, CardContent, Divider, FormControl, InputLabel, Select, MenuItem, List, ListItem } from '@mui/material';
import { Box, Typography, Button, Card, CardContent, Divider, FormControl, InputLabel, Select, MenuItem, List, ListItem, ListItemButton } from '@mui/material';
import { useQueryClient } from '@tanstack/react-query';
import { Vehicle } from '../types/vehicles.types';
import { useFuelLogs } from '../../fuel-logs/hooks/useFuelLogs';
@@ -250,7 +250,8 @@ export const VehicleDetailMobile: React.FC<VehicleDetailMobileProps> = ({
) : (
<List disablePadding>
{filteredRecords.map(rec => (
<ListItem key={rec.id} divider button onClick={() => openEditLog(rec.id, rec.type)}>
<ListItem key={rec.id} divider disablePadding>
<ListItemButton onClick={() => openEditLog(rec.id, rec.type)}>
<Box sx={{ flexGrow: 1 }}>
{/* Primary line: MPG/km-L and amount */}
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
@@ -266,6 +267,7 @@ export const VehicleDetailMobile: React.FC<VehicleDetailMobileProps> = ({
{rec.secondary || `${new Date(rec.date).toLocaleDateString()}${rec.type}`}
</Typography>
</Box>
</ListItemButton>
</ListItem>
))}
</List>

View File

@@ -46,7 +46,7 @@ export default defineConfig({
'forms': ['react-hook-form', '@hookform/resolvers', 'zod'],
// Utilities
'utils': ['date-fns', 'clsx'],
'utils': ['dayjs', 'clsx'],
// Animation and UI
'animation': ['framer-motion', 'react-hot-toast']