111 lines
3.5 KiB
TypeScript
111 lines
3.5 KiB
TypeScript
import * as React from 'react';
|
|
import { Box, Typography, Paper, CircularProgress } from '@mui/material';
|
|
import { ResourceConfig } from '../types/config';
|
|
import { useResource } from '../hooks/useResource';
|
|
import GenericForm from './GenericForm';
|
|
import EnhancedTable from './EnhancedTable';
|
|
import { useParams, useLocation, useNavigate, Routes, Route } from 'react-router-dom';
|
|
|
|
interface ResourceViewProps {
|
|
config: ResourceConfig;
|
|
onNavigateToResource?: (resourceName: string, id: string) => void;
|
|
}
|
|
|
|
import { GridPaginationModel } from '@mui/x-data-grid';
|
|
|
|
export default function ResourceView({ config, onNavigateToResource }: ResourceViewProps) {
|
|
const { id } = useParams();
|
|
const location = useLocation();
|
|
const navigate = useNavigate();
|
|
|
|
const isCreate = location.pathname.endsWith('/create');
|
|
const isEdit = location.pathname.includes('/edit/');
|
|
const isView = !!id && !isEdit;
|
|
const isList = !id && !isCreate;
|
|
|
|
const [paginationModel, setPaginationModel] = React.useState<GridPaginationModel>({
|
|
page: 0,
|
|
pageSize: 10,
|
|
});
|
|
|
|
const { useList, useRead, useCreate, useUpdate, useDelete } = useResource(config);
|
|
|
|
// Determine query parameters based on pagination config
|
|
const queryParams = React.useMemo(() => {
|
|
if (!config.pagination) return {};
|
|
return {
|
|
skip: paginationModel.page * paginationModel.pageSize,
|
|
limit: paginationModel.pageSize,
|
|
};
|
|
}, [config.pagination, paginationModel]);
|
|
|
|
const listQuery = useList(queryParams);
|
|
const itemQuery = useRead(id || "");
|
|
|
|
const paginatedData = listQuery.data || { data: [], total: undefined };
|
|
const createMutation = useCreate();
|
|
const updateMutation = useUpdate();
|
|
const deleteMutation = useDelete();
|
|
|
|
const handleEdit = (item: any) => {
|
|
navigate(`/admin/${config.name}/edit/${item[config.primaryKey]}`);
|
|
};
|
|
|
|
const handleCreate = () => {
|
|
navigate(`/admin/${config.name}/create`);
|
|
};
|
|
|
|
const handleSave = async (formData: any) => {
|
|
try {
|
|
if (isEdit) {
|
|
await updateMutation.mutateAsync({ id: id!, data: formData });
|
|
} else {
|
|
await createMutation.mutateAsync(formData);
|
|
}
|
|
navigate(`/admin/${config.name}`);
|
|
} catch (err) {
|
|
console.error('Save failed:', err);
|
|
}
|
|
};
|
|
|
|
const handleDelete = async (itemId: string) => {
|
|
if (window.confirm('Are you sure you want to delete this item?')) {
|
|
await deleteMutation.mutateAsync(itemId);
|
|
}
|
|
};
|
|
|
|
if (isList && listQuery.isLoading) return <CircularProgress />;
|
|
if ((isEdit || isView) && itemQuery.isLoading) return <CircularProgress />;
|
|
|
|
return (
|
|
<Box>
|
|
{isList ? (
|
|
<EnhancedTable
|
|
config={config}
|
|
data={paginatedData.data || []}
|
|
total={paginatedData.total}
|
|
paginationModel={paginationModel}
|
|
onPaginationModelChange={setPaginationModel}
|
|
loading={listQuery.isFetching}
|
|
onEdit={handleEdit}
|
|
onDelete={handleDelete}
|
|
onCreate={handleCreate}
|
|
onNavigateToResource={(res, id) => navigate(`/admin/${res}/${id}`)}
|
|
/>
|
|
) : (
|
|
<Paper sx={{ p: 4 }}>
|
|
<GenericForm
|
|
config={config}
|
|
initialData={isCreate ? null : itemQuery.data}
|
|
onSave={handleSave}
|
|
onCancel={() => navigate(`/admin/${config.name}`)}
|
|
loading={createMutation.isPending || updateMutation.isPending}
|
|
readOnly={isView}
|
|
onEditClick={() => navigate(`/admin/${config.name}/edit/${id}`)}
|
|
/>
|
|
</Paper>
|
|
)}
|
|
</Box>
|
|
);
|
|
}
|