Files
motovaultpro/frontend/src/features/dashboard/components/DashboardScreen.tsx
Eric Gullickson 98a4a62ea5
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 2m35s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 36s
Deploy to Staging / Verify Staging (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
fix: add vehicle button opens add vehicle form (refs #2)
- Add onAddVehicle prop to DashboardScreen
- Mobile: triggers setShowAddVehicle(true) in App.tsx
- Desktop: navigates to /garage/vehicles with showAddForm state
- VehiclesPage auto-opens form when receiving showAddForm state

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 22:25:35 -06:00

138 lines
4.6 KiB
TypeScript

/**
* @ai-summary Main dashboard screen component showing fleet overview
*/
import React from 'react';
import { Box } from '@mui/material';
import WarningAmberRoundedIcon from '@mui/icons-material/WarningAmberRounded';
import DirectionsCarRoundedIcon from '@mui/icons-material/DirectionsCarRounded';
import { SummaryCards, SummaryCardsSkeleton } from './SummaryCards';
import { VehicleAttention, VehicleAttentionSkeleton } from './VehicleAttention';
import { QuickActions, QuickActionsSkeleton } from './QuickActions';
import { useDashboardSummary, useVehiclesNeedingAttention } from '../hooks/useDashboardData';
import { GlassCard } from '../../../shared-minimal/components/mobile/GlassCard';
import { Button } from '../../../shared-minimal/components/Button';
import { MobileScreen } from '../../../core/store';
import { Vehicle } from '../../vehicles/types/vehicles.types';
interface DashboardScreenProps {
onNavigate?: (screen: MobileScreen, metadata?: Record<string, any>) => void;
onVehicleClick?: (vehicle: Vehicle) => void;
onViewMaintenance?: () => void;
onAddVehicle?: () => void;
}
export const DashboardScreen: React.FC<DashboardScreenProps> = ({
onNavigate,
onVehicleClick,
onViewMaintenance,
onAddVehicle
}) => {
const { data: summary, isLoading: summaryLoading, error: summaryError } = useDashboardSummary();
const { data: vehiclesNeedingAttention, isLoading: attentionLoading, error: attentionError } = useVehiclesNeedingAttention();
// Error state
if (summaryError || attentionError) {
return (
<div className="space-y-4">
<GlassCard>
<div className="text-center py-12">
<Box sx={{ color: 'warning.main', mb: 1.5 }}>
<WarningAmberRoundedIcon sx={{ fontSize: 48 }} />
</Box>
<h2 className="text-lg font-semibold text-slate-800 dark:text-avus mb-2">
Unable to Load Dashboard
</h2>
<p className="text-slate-500 dark:text-titanio mb-4">
There was an error loading your dashboard data
</p>
<Button
variant="primary"
size="md"
onClick={() => window.location.reload()}
>
Retry
</Button>
</div>
</GlassCard>
</div>
);
}
// Loading state
if (summaryLoading || attentionLoading || !summary || !vehiclesNeedingAttention) {
return (
<div className="space-y-6">
<SummaryCardsSkeleton />
<VehicleAttentionSkeleton />
<QuickActionsSkeleton />
</div>
);
}
// Empty state - no vehicles
if (summary.totalVehicles === 0) {
return (
<div className="space-y-6">
<GlassCard>
<div className="text-center py-12">
<Box sx={{ color: 'primary.main', mb: 2 }}>
<DirectionsCarRoundedIcon sx={{ fontSize: 64 }} />
</Box>
<h2 className="text-xl font-semibold text-slate-800 dark:text-avus mb-3">
Welcome to MotoVaultPro
</h2>
<p className="text-slate-500 dark:text-titanio mb-6 max-w-md mx-auto">
Get started by adding your first vehicle to track fuel logs, maintenance, and more
</p>
<Button
variant="primary"
size="lg"
onClick={onAddVehicle ?? (() => onNavigate?.('Vehicles'))}
>
Add Your First Vehicle
</Button>
</div>
</GlassCard>
</div>
);
}
// Main dashboard view
return (
<div className="space-y-6">
{/* Summary Cards */}
<SummaryCards summary={summary} />
{/* Vehicles Needing Attention */}
{vehiclesNeedingAttention && vehiclesNeedingAttention.length > 0 && (
<VehicleAttention
vehicles={vehiclesNeedingAttention}
onVehicleClick={(vehicleId) => {
const vehicle = vehiclesNeedingAttention.find(v => v.id === vehicleId);
if (vehicle && onVehicleClick) {
onVehicleClick(vehicle);
}
}}
/>
)}
{/* Quick Actions */}
<QuickActions
onAddVehicle={onAddVehicle ?? (() => onNavigate?.('Vehicles'))}
onLogFuel={() => onNavigate?.('Log Fuel')}
onViewMaintenance={onViewMaintenance ?? (() => onNavigate?.('Vehicles'))}
onViewVehicles={() => onNavigate?.('Vehicles')}
/>
{/* Footer Hint */}
<div className="text-center py-4">
<p className="text-xs text-slate-400 dark:text-canna">
Dashboard updates every 2 minutes
</p>
</div>
</div>
);
};