feat: Scheduled Maintenance feature complete
This commit is contained in:
@@ -4,20 +4,26 @@
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { Grid, Typography, Box } from '@mui/material';
|
||||
import { Grid, Typography, Box, Tabs, Tab } from '@mui/material';
|
||||
import { useQueryClient } from '@tanstack/react-query';
|
||||
import { MaintenanceRecordForm } from '../components/MaintenanceRecordForm';
|
||||
import { MaintenanceRecordsList } from '../components/MaintenanceRecordsList';
|
||||
import { MaintenanceRecordEditDialog } from '../components/MaintenanceRecordEditDialog';
|
||||
import { MaintenanceScheduleForm } from '../components/MaintenanceScheduleForm';
|
||||
import { MaintenanceSchedulesList } from '../components/MaintenanceSchedulesList';
|
||||
import { MaintenanceScheduleEditDialog } from '../components/MaintenanceScheduleEditDialog';
|
||||
import { useMaintenanceRecords } from '../hooks/useMaintenanceRecords';
|
||||
import { FormSuspense } from '../../../components/SuspenseWrappers';
|
||||
import type { MaintenanceRecordResponse, UpdateMaintenanceRecordRequest } from '../types/maintenance.types';
|
||||
import type { MaintenanceRecordResponse, UpdateMaintenanceRecordRequest, MaintenanceScheduleResponse, UpdateScheduleRequest } from '../types/maintenance.types';
|
||||
|
||||
export const MaintenancePage: React.FC = () => {
|
||||
const { records, isRecordsLoading, recordsError, updateRecord, deleteRecord } = useMaintenanceRecords();
|
||||
const { records, schedules, isRecordsLoading, isSchedulesLoading, recordsError, schedulesError, updateRecord, deleteRecord, updateSchedule, deleteSchedule } = useMaintenanceRecords();
|
||||
const queryClient = useQueryClient();
|
||||
const [activeTab, setActiveTab] = useState<'records' | 'schedules'>('records');
|
||||
const [editingRecord, setEditingRecord] = useState<MaintenanceRecordResponse | null>(null);
|
||||
const [editDialogOpen, setEditDialogOpen] = useState(false);
|
||||
const [editingSchedule, setEditingSchedule] = useState<MaintenanceScheduleResponse | null>(null);
|
||||
const [scheduleEditDialogOpen, setScheduleEditDialogOpen] = useState(false);
|
||||
|
||||
const handleEdit = (record: MaintenanceRecordResponse) => {
|
||||
setEditingRecord(record);
|
||||
@@ -52,7 +58,43 @@ export const MaintenancePage: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
if (isRecordsLoading) {
|
||||
const handleScheduleEdit = (schedule: MaintenanceScheduleResponse) => {
|
||||
setEditingSchedule(schedule);
|
||||
setScheduleEditDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleScheduleEditSave = async (id: string, data: UpdateScheduleRequest) => {
|
||||
try {
|
||||
await updateSchedule({ id, data });
|
||||
// Refetch queries after update
|
||||
queryClient.refetchQueries({ queryKey: ['maintenanceSchedules'] });
|
||||
setScheduleEditDialogOpen(false);
|
||||
setEditingSchedule(null);
|
||||
} catch (error) {
|
||||
console.error('Failed to update maintenance schedule:', error);
|
||||
throw error; // Re-throw to let dialog handle the error
|
||||
}
|
||||
};
|
||||
|
||||
const handleScheduleEditClose = () => {
|
||||
setScheduleEditDialogOpen(false);
|
||||
setEditingSchedule(null);
|
||||
};
|
||||
|
||||
const handleScheduleDelete = async (scheduleId: string) => {
|
||||
try {
|
||||
await deleteSchedule(scheduleId);
|
||||
// Refetch queries after delete
|
||||
queryClient.refetchQueries({ queryKey: ['maintenanceSchedules'] });
|
||||
} catch (error) {
|
||||
console.error('Failed to delete maintenance schedule:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const isLoading = activeTab === 'records' ? isRecordsLoading : isSchedulesLoading;
|
||||
const hasError = activeTab === 'records' ? recordsError : schedulesError;
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@@ -62,12 +104,14 @@ export const MaintenancePage: React.FC = () => {
|
||||
height: '50vh',
|
||||
}}
|
||||
>
|
||||
<Typography color="text.secondary">Loading maintenance records...</Typography>
|
||||
<Typography color="text.secondary">
|
||||
Loading maintenance {activeTab}...
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
if (recordsError) {
|
||||
if (hasError) {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@@ -78,7 +122,7 @@ export const MaintenancePage: React.FC = () => {
|
||||
}}
|
||||
>
|
||||
<Typography color="error">
|
||||
Failed to load maintenance records. Please try again.
|
||||
Failed to load maintenance {activeTab}. Please try again.
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
@@ -86,32 +130,72 @@ export const MaintenancePage: React.FC = () => {
|
||||
|
||||
return (
|
||||
<FormSuspense>
|
||||
<Grid container spacing={3}>
|
||||
{/* Top: Form */}
|
||||
<Grid item xs={12}>
|
||||
<MaintenanceRecordForm />
|
||||
</Grid>
|
||||
<Box sx={{ borderBottom: 1, borderColor: 'divider', mb: 3 }}>
|
||||
<Tabs
|
||||
value={activeTab}
|
||||
onChange={(_, v) => setActiveTab(v as 'records' | 'schedules')}
|
||||
aria-label="Maintenance tabs"
|
||||
>
|
||||
<Tab label="Records" value="records" />
|
||||
<Tab label="Schedules" value="schedules" />
|
||||
</Tabs>
|
||||
</Box>
|
||||
|
||||
{/* Bottom: Records List */}
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
Recent Maintenance Records
|
||||
</Typography>
|
||||
<MaintenanceRecordsList
|
||||
records={records}
|
||||
onEdit={handleEdit}
|
||||
onDelete={handleDelete}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
{activeTab === 'records' && (
|
||||
<Grid container spacing={3}>
|
||||
{/* Top: Form */}
|
||||
<Grid item xs={12}>
|
||||
<MaintenanceRecordForm />
|
||||
</Grid>
|
||||
|
||||
{/* Edit Dialog */}
|
||||
{/* Bottom: Records List */}
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
Recent Maintenance Records
|
||||
</Typography>
|
||||
<MaintenanceRecordsList
|
||||
records={records}
|
||||
onEdit={handleEdit}
|
||||
onDelete={handleDelete}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
{activeTab === 'schedules' && (
|
||||
<Grid container spacing={3}>
|
||||
{/* Top: Form */}
|
||||
<Grid item xs={12}>
|
||||
<MaintenanceScheduleForm />
|
||||
</Grid>
|
||||
|
||||
{/* Bottom: Schedules List */}
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
Maintenance Schedules
|
||||
</Typography>
|
||||
<MaintenanceSchedulesList
|
||||
schedules={schedules || []}
|
||||
onEdit={handleScheduleEdit}
|
||||
onDelete={handleScheduleDelete}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
{/* Edit Dialogs */}
|
||||
<MaintenanceRecordEditDialog
|
||||
open={editDialogOpen}
|
||||
record={editingRecord}
|
||||
onClose={handleEditClose}
|
||||
onSave={handleEditSave}
|
||||
/>
|
||||
<MaintenanceScheduleEditDialog
|
||||
open={scheduleEditDialogOpen}
|
||||
schedule={editingSchedule}
|
||||
onClose={handleScheduleEditClose}
|
||||
onSave={handleScheduleEditSave}
|
||||
/>
|
||||
</FormSuspense>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user