MVP Build
This commit is contained in:
89
frontend/src/features/vehicles/pages/VehiclesPage.tsx
Normal file
89
frontend/src/features/vehicles/pages/VehiclesPage.tsx
Normal file
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @ai-summary Main vehicles page
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { useVehicles, useCreateVehicle, useDeleteVehicle } from '../hooks/useVehicles';
|
||||
import { VehicleCard } from '../components/VehicleCard';
|
||||
import { VehicleForm } from '../components/VehicleForm';
|
||||
import { Button } from '../../../shared-minimal/components/Button';
|
||||
import { Card } from '../../../shared-minimal/components/Card';
|
||||
import { useAppStore } from '../../../core/store';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
export const VehiclesPage: React.FC = () => {
|
||||
const navigate = useNavigate();
|
||||
const { data: vehicles, isLoading } = useVehicles();
|
||||
const createVehicle = useCreateVehicle();
|
||||
const deleteVehicle = useDeleteVehicle();
|
||||
const setSelectedVehicle = useAppStore(state => state.setSelectedVehicle);
|
||||
|
||||
const [showForm, setShowForm] = useState(false);
|
||||
|
||||
const handleSelectVehicle = (id: string) => {
|
||||
setSelectedVehicle(id);
|
||||
navigate(`/vehicles/${id}`);
|
||||
};
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
if (confirm('Are you sure you want to delete this vehicle?')) {
|
||||
await deleteVehicle.mutateAsync(id);
|
||||
}
|
||||
};
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center h-64">
|
||||
<div className="text-gray-500">Loading vehicles...</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<div className="flex justify-between items-center">
|
||||
<h1 className="text-2xl font-bold text-gray-900">My Vehicles</h1>
|
||||
{!showForm && (
|
||||
<Button onClick={() => setShowForm(true)}>Add Vehicle</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{showForm && (
|
||||
<Card>
|
||||
<h2 className="text-lg font-semibold mb-4">Add New Vehicle</h2>
|
||||
<VehicleForm
|
||||
onSubmit={async (data) => {
|
||||
await createVehicle.mutateAsync(data);
|
||||
setShowForm(false);
|
||||
}}
|
||||
onCancel={() => setShowForm(false)}
|
||||
loading={createVehicle.isPending}
|
||||
/>
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{vehicles?.length === 0 ? (
|
||||
<Card>
|
||||
<div className="text-center py-12">
|
||||
<p className="text-gray-500 mb-4">No vehicles added yet</p>
|
||||
{!showForm && (
|
||||
<Button onClick={() => setShowForm(true)}>Add Your First Vehicle</Button>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{vehicles?.map((vehicle) => (
|
||||
<VehicleCard
|
||||
key={vehicle.id}
|
||||
vehicle={vehicle}
|
||||
onEdit={(v) => console.log('Edit', v)}
|
||||
onDelete={handleDelete}
|
||||
onSelect={handleSelectVehicle}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user