Notification updates
This commit is contained in:
@@ -63,9 +63,9 @@ export const MaintenanceRecordEditDialog: React.FC<MaintenanceRecordEditDialogPr
|
||||
category: record.category,
|
||||
subtypes: record.subtypes,
|
||||
date: record.date,
|
||||
odometer_reading: record.odometer_reading || undefined,
|
||||
odometerReading: record.odometerReading || undefined,
|
||||
cost: record.cost ? Number(record.cost) : undefined,
|
||||
shop_name: record.shop_name || undefined,
|
||||
shopName: record.shopName || undefined,
|
||||
notes: record.notes || undefined,
|
||||
});
|
||||
setError(null);
|
||||
@@ -172,7 +172,7 @@ export const MaintenanceRecordEditDialog: React.FC<MaintenanceRecordEditDialogPr
|
||||
fullWidth
|
||||
disabled
|
||||
value={(() => {
|
||||
const vehicle = vehicles?.find((v: Vehicle) => v.id === record.vehicle_id);
|
||||
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);
|
||||
@@ -246,10 +246,10 @@ export const MaintenanceRecordEditDialog: React.FC<MaintenanceRecordEditDialogPr
|
||||
label="Odometer Reading"
|
||||
type="number"
|
||||
fullWidth
|
||||
value={formData.odometer_reading || ''}
|
||||
value={formData.odometerReading || ''}
|
||||
onChange={(e) =>
|
||||
handleInputChange(
|
||||
'odometer_reading',
|
||||
'odometerReading',
|
||||
e.target.value ? parseInt(e.target.value) : undefined
|
||||
)
|
||||
}
|
||||
@@ -278,8 +278,8 @@ export const MaintenanceRecordEditDialog: React.FC<MaintenanceRecordEditDialogPr
|
||||
<TextField
|
||||
label="Shop/Location"
|
||||
fullWidth
|
||||
value={formData.shop_name || ''}
|
||||
onChange={(e) => handleInputChange('shop_name', e.target.value || undefined)}
|
||||
value={formData.shopName || ''}
|
||||
onChange={(e) => handleInputChange('shopName', e.target.value || undefined)}
|
||||
helperText="Service location"
|
||||
inputProps={{ maxLength: 200 }}
|
||||
/>
|
||||
|
||||
@@ -92,13 +92,13 @@ export const MaintenanceRecordForm: React.FC = () => {
|
||||
const onSubmit = async (data: FormData) => {
|
||||
try {
|
||||
const payload: CreateMaintenanceRecordRequest = {
|
||||
vehicle_id: data.vehicle_id,
|
||||
vehicleId: data.vehicle_id,
|
||||
category: data.category as MaintenanceCategory,
|
||||
subtypes: data.subtypes,
|
||||
date: data.date,
|
||||
odometer_reading: data.odometer_reading ? Number(data.odometer_reading) : undefined,
|
||||
odometerReading: data.odometer_reading ? Number(data.odometer_reading) : undefined,
|
||||
cost: data.cost ? Number(data.cost) : undefined,
|
||||
shop_name: data.shop_name || undefined,
|
||||
shopName: data.shop_name || undefined,
|
||||
notes: data.notes || undefined,
|
||||
};
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ export const MaintenanceRecordsList: React.FC<MaintenanceRecordsListProps> = ({
|
||||
{sortedRecords.map((record) => {
|
||||
const dateText = new Date(record.date).toLocaleDateString();
|
||||
const categoryDisplay = getCategoryDisplayName(record.category);
|
||||
const subtypeCount = record.subtype_count || record.subtypes?.length || 0;
|
||||
const subtypeCount = record.subtypeCount || record.subtypes?.length || 0;
|
||||
|
||||
return (
|
||||
<Card key={record.id} variant="outlined">
|
||||
@@ -105,9 +105,9 @@ export const MaintenanceRecordsList: React.FC<MaintenanceRecordsListProps> = ({
|
||||
{categoryDisplay} ({subtypeCount})
|
||||
</Typography>
|
||||
<Stack direction="row" spacing={1} flexWrap="wrap" sx={{ mt: 1 }}>
|
||||
{record.odometer_reading && (
|
||||
{record.odometerReading && (
|
||||
<Chip
|
||||
label={`${Number(record.odometer_reading).toLocaleString()} miles`}
|
||||
label={`${Number(record.odometerReading).toLocaleString()} miles`}
|
||||
size="small"
|
||||
variant="outlined"
|
||||
/>
|
||||
@@ -120,9 +120,9 @@ export const MaintenanceRecordsList: React.FC<MaintenanceRecordsListProps> = ({
|
||||
variant="outlined"
|
||||
/>
|
||||
)}
|
||||
{record.shop_name && (
|
||||
{record.shopName && (
|
||||
<Chip
|
||||
label={record.shop_name}
|
||||
label={record.shopName}
|
||||
size="small"
|
||||
variant="outlined"
|
||||
/>
|
||||
|
||||
@@ -81,9 +81,9 @@ export const useMaintenanceRecords = (vehicleId?: string) => {
|
||||
const createRecordMutation = useMutation({
|
||||
mutationFn: (data: CreateMaintenanceRecordRequest) => maintenanceApi.createRecord(data),
|
||||
onSuccess: (_res, variables) => {
|
||||
queryClient.invalidateQueries({ queryKey: ['maintenanceRecords', variables.vehicle_id] });
|
||||
queryClient.invalidateQueries({ queryKey: ['maintenanceRecords', variables.vehicleId] });
|
||||
queryClient.invalidateQueries({ queryKey: ['maintenanceRecords', 'all'] });
|
||||
queryClient.invalidateQueries({ queryKey: ['maintenanceUpcoming', variables.vehicle_id] });
|
||||
queryClient.invalidateQueries({ queryKey: ['maintenanceUpcoming', variables.vehicleId] });
|
||||
},
|
||||
});
|
||||
|
||||
@@ -110,8 +110,8 @@ export const useMaintenanceRecords = (vehicleId?: string) => {
|
||||
const createScheduleMutation = useMutation({
|
||||
mutationFn: (data: CreateScheduleRequest) => maintenanceApi.createSchedule(data),
|
||||
onSuccess: (_res, variables) => {
|
||||
queryClient.invalidateQueries({ queryKey: ['maintenanceSchedules', variables.vehicle_id] });
|
||||
queryClient.invalidateQueries({ queryKey: ['maintenanceUpcoming', variables.vehicle_id] });
|
||||
queryClient.invalidateQueries({ queryKey: ['maintenanceSchedules', variables.vehicleId] });
|
||||
queryClient.invalidateQueries({ queryKey: ['maintenanceUpcoming', variables.vehicleId] });
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -53,48 +53,49 @@ export const PERFORMANCE_UPGRADE_SUBTYPES = [
|
||||
'Exterior'
|
||||
] as const;
|
||||
|
||||
// Database record types
|
||||
// Database record types (camelCase)
|
||||
export interface MaintenanceRecord {
|
||||
id: string;
|
||||
user_id: string;
|
||||
vehicle_id: string;
|
||||
userId: string;
|
||||
vehicleId: string;
|
||||
category: MaintenanceCategory;
|
||||
subtypes: string[];
|
||||
date: string;
|
||||
odometer_reading?: number;
|
||||
odometerReading?: number;
|
||||
cost?: number;
|
||||
shop_name?: string;
|
||||
shopName?: string;
|
||||
notes?: string;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface MaintenanceSchedule {
|
||||
id: string;
|
||||
user_id: string;
|
||||
vehicle_id: string;
|
||||
userId: string;
|
||||
vehicleId: string;
|
||||
category: MaintenanceCategory;
|
||||
subtypes: string[];
|
||||
interval_months?: number;
|
||||
interval_miles?: number;
|
||||
last_service_date?: string;
|
||||
last_service_mileage?: number;
|
||||
next_due_date?: string;
|
||||
next_due_mileage?: number;
|
||||
is_active: boolean;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
intervalMonths?: number;
|
||||
intervalMiles?: number;
|
||||
lastServiceDate?: string;
|
||||
lastServiceMileage?: number;
|
||||
nextDueDate?: string;
|
||||
nextDueMileage?: number;
|
||||
isActive: boolean;
|
||||
emailNotifications?: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
// Request types
|
||||
// Request types (camelCase)
|
||||
export interface CreateMaintenanceRecordRequest {
|
||||
vehicle_id: string;
|
||||
vehicleId: string;
|
||||
category: MaintenanceCategory;
|
||||
subtypes: string[];
|
||||
date: string;
|
||||
odometer_reading?: number;
|
||||
odometerReading?: number;
|
||||
cost?: number;
|
||||
shop_name?: string;
|
||||
shopName?: string;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
@@ -102,37 +103,39 @@ export interface UpdateMaintenanceRecordRequest {
|
||||
category?: MaintenanceCategory;
|
||||
subtypes?: string[];
|
||||
date?: string;
|
||||
odometer_reading?: number | null;
|
||||
odometerReading?: number | null;
|
||||
cost?: number | null;
|
||||
shop_name?: string | null;
|
||||
shopName?: string | null;
|
||||
notes?: string | null;
|
||||
}
|
||||
|
||||
export interface CreateScheduleRequest {
|
||||
vehicle_id: string;
|
||||
vehicleId: string;
|
||||
category: MaintenanceCategory;
|
||||
subtypes: string[];
|
||||
interval_months?: number;
|
||||
interval_miles?: number;
|
||||
intervalMonths?: number;
|
||||
intervalMiles?: number;
|
||||
emailNotifications?: boolean;
|
||||
}
|
||||
|
||||
export interface UpdateScheduleRequest {
|
||||
category?: MaintenanceCategory;
|
||||
subtypes?: string[];
|
||||
interval_months?: number | null;
|
||||
interval_miles?: number | null;
|
||||
is_active?: boolean;
|
||||
intervalMonths?: number | null;
|
||||
intervalMiles?: number | null;
|
||||
isActive?: boolean;
|
||||
emailNotifications?: boolean;
|
||||
}
|
||||
|
||||
// Response types
|
||||
// Response types (camelCase)
|
||||
export interface MaintenanceRecordResponse extends MaintenanceRecord {
|
||||
subtype_count: number;
|
||||
subtypeCount: number;
|
||||
}
|
||||
|
||||
export interface MaintenanceScheduleResponse extends MaintenanceSchedule {
|
||||
subtype_count: number;
|
||||
is_due_soon?: boolean;
|
||||
is_overdue?: boolean;
|
||||
subtypeCount: number;
|
||||
isDueSoon?: boolean;
|
||||
isOverdue?: boolean;
|
||||
}
|
||||
|
||||
// Validation helpers
|
||||
|
||||
Reference in New Issue
Block a user