update build ok,

This commit is contained in:
louiscklaw
2025-04-16 01:15:34 +08:00
parent e6980dceba
commit 07d338b485
4 changed files with 320 additions and 2 deletions

View File

@@ -15,9 +15,12 @@ import { paths } from '@/paths';
import { logger } from '@/lib/default-logger';
import { toast } from '@/components/core/toaster';
import type { LessonType } from '@/components/dashboard/lesson_type/ILessonType';
import { LessonTypesFilters } from '@/components/dashboard/lesson_type/lesson-types-filters';
import type { Filters } from '@/components/dashboard/lesson_type/lesson-types-filters';
import { LessonTypesPagination } from '@/components/dashboard/lesson_type/lesson-types-pagination';
import { LessonTypesSelectionProvider } from '@/components/dashboard/lesson_type/lesson-types-selection-context';
import { LessonTypesTable } from '@/components/dashboard/lesson_type/lesson-types-table';
import FormLoading from '@/components/loading';
interface PageProps {
searchParams: {
@@ -50,6 +53,10 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element {
//
});
const reloadRows = () => {
console.log('reload rows');
};
return (
<Box
sx={{
@@ -79,6 +86,21 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element {
</LoadingButton>
</Box>
</Stack>
<LessonTypesSelectionProvider lessonTypes={filteredLessonTypes}>
<Card>
<LessonTypesFilters
filters={{ email, phone, status, name, visible, type }}
fullData={lessonTypesData}
sortDir={sortDir}
/>
<Divider />
<Box sx={{ overflowX: 'auto' }}>
<LessonTypesTable reloadRows={reloadRows} rows={filteredLessonTypes} />
</Box>
<Divider />
<LessonTypesPagination count={filteredLessonTypes.length + 100} page={0} />
</Card>
</LessonTypesSelectionProvider>
</Stack>
</Box>
);

View File

@@ -0,0 +1,104 @@
'use client';
import * as React from 'react';
import { LoadingButton } from '@mui/lab';
import { Button, Container, Modal, Paper } from '@mui/material';
import Avatar from '@mui/material/Avatar';
import Box from '@mui/material/Box';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import { Note as NoteIcon } from '@phosphor-icons/react/dist/ssr/Note';
import { useTranslation } from 'react-i18next';
// import { deleteLessonType } from './http-actions';
export default function ConfirmDeleteModal({
open,
setOpen,
idToDelete,
reloadRows,
}: {
open: boolean;
setOpen: (b: boolean) => void;
idToDelete: string;
reloadRows: () => void;
}): React.JSX.Element {
const { t } = useTranslation();
// const handleClose = () => setOpen(false);
function handleClose(): void {
setOpen(false);
}
const [isDeleteing, setIsDeleteing] = React.useState(false);
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
};
const handleUserConfirmDelete = (): void => {
if (idToDelete) {
setIsDeleteing(true);
// deleteLessonType(idToDelete)
// .then(() => {
// reloadRows();
// handleClose();
// })
// .catch((err) => {
// // console.error(err);
// setIsDeleteing(false);
// })
// .finally(() => {
// setIsDeleteing(false);
// });
}
};
return (
<div>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style}>
<Container maxWidth="sm">
<Paper sx={{ border: '1px solid var(--mui-palette-divider)', boxShadow: 'var(--mui-shadows-16)' }}>
<Stack direction="row" spacing={2} sx={{ display: 'flex', p: 3 }}>
<Avatar sx={{ bgcolor: 'var(--mui-palette-error-50)', color: 'var(--mui-palette-error-main)' }}>
<NoteIcon fontSize="var(--Icon-fontSize)" />
</Avatar>
<Stack spacing={3}>
<Stack spacing={1}>
<Typography variant="h5">{t('Delete Lesson Type ?')}</Typography>
<Typography color="text.secondary" variant="body2">
{t('Are you sure you want to delete lesson type ?')}
</Typography>
</Stack>
<Stack direction="row" spacing={2} sx={{ justifyContent: 'flex-end' }}>
<Button color="secondary" onClick={handleClose}>
{t('Cancel')}
</Button>
<LoadingButton
color="error"
variant="contained"
onClick={(e) => {
handleUserConfirmDelete();
}}
loading={isDeleteing}
>
{t('Delete')}
</LoadingButton>
</Stack>
</Stack>
</Stack>
</Paper>
</Container>
</Box>
</Modal>
</div>
);
}

View File

@@ -0,0 +1,30 @@
'use client';
import * as React from 'react';
import TablePagination from '@mui/material/TablePagination';
function noop(): void {
return undefined;
}
interface LessonTypesPaginationProps {
count: number;
page: number;
}
export function LessonTypesPagination({ count, page }: LessonTypesPaginationProps): React.JSX.Element {
// You should implement the pagination using a similar logic as the filters.
// Note that when page change, you should keep the filter search params.
return (
<TablePagination
component="div"
count={count}
onPageChange={noop}
onRowsPerPageChange={noop}
page={page}
rowsPerPage={5}
rowsPerPageOptions={[5, 10, 25]}
/>
);
}

View File

@@ -0,0 +1,162 @@
'use client';
import * as React from 'react';
import RouterLink from 'next/link';
import { Button } from '@mui/material';
import Box from '@mui/material/Box';
import Chip from '@mui/material/Chip';
import IconButton from '@mui/material/IconButton';
import Link from '@mui/material/Link';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import { CheckCircle as CheckCircleIcon } from '@phosphor-icons/react/dist/ssr/CheckCircle';
import { Clock as ClockIcon } from '@phosphor-icons/react/dist/ssr/Clock';
import { Minus as MinusIcon } from '@phosphor-icons/react/dist/ssr/Minus';
import { PencilSimple as PencilSimpleIcon } from '@phosphor-icons/react/dist/ssr/PencilSimple';
import { TrashSimple as TrashSimpleIcon } from '@phosphor-icons/react/dist/ssr/TrashSimple';
import { useTranslation } from 'react-i18next';
import { toast } from 'sonner';
import { paths } from '@/paths';
import { dayjs } from '@/lib/dayjs';
import { i18n } from '@/lib/i18n';
import { DataTable } from '@/components/core/data-table';
import type { ColumnDef } from '@/components/core/data-table';
import ConfirmDeleteModal from './confirm-delete-modal';
import type { LessonType } from './ILessonType';
import { useLessonTypesSelection } from './lesson-types-selection-context';
function columns(handleDeleteClick: (testId: string) => void): ColumnDef<LessonType>[] {
return [
{
formatter: (row): React.JSX.Element => (
<Stack direction="row" spacing={1} sx={{ alignItems: 'center' }}>
<div>
<Link
color="inherit"
component={RouterLink}
href={paths.dashboard.lesson_types.details('1')}
sx={{ whiteSpace: 'nowrap' }}
variant="subtitle2"
>
{row.name}
</Link>
</div>
</Stack>
),
name: 'Name',
width: '250px',
},
{ field: 'type', name: 'Lesson type', width: '150px' },
{ field: 'pos', name: 'Lesson position', width: '150px' },
{
formatter: (row): React.JSX.Element => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const { t } = useTranslation();
const mapping = {
active: { label: 'Active', icon: <CheckCircleIcon color="var(--mui-palette-success-main)" weight="fill" /> },
blocked: { label: 'Blocked', icon: <MinusIcon color="var(--mui-palette-error-main)" /> },
pending: { label: 'Pending', icon: <ClockIcon color="var(--mui-palette-warning-main)" weight="fill" /> },
visible: {
label: t('visible'),
icon: <ClockIcon color="var(--mui-palette-success-main)" weight="fill" />,
},
hidden: {
label: t('hidden'),
icon: <ClockIcon color="var(--mui-palette-warning-main)" weight="fill" />,
},
} as const;
const { label, icon } = mapping[row.visible] ?? { label: 'Unknown', icon: null };
return (
<Button
onClick={() => {
toast.error('sorry but not implementd');
}}
style={{ backgroundColor: 'transparent' }}
>
<Chip icon={icon} label={label} size="small" variant="outlined" />
</Button>
);
},
name: 'visible',
width: '150px',
},
{
formatter(row) {
return dayjs(row.createdAt).format('MMM D, YYYY h:mm A');
},
name: 'Created at',
width: '200px',
},
{
formatter: (row): React.JSX.Element => (
<Stack direction="row" spacing={1}>
<IconButton component={RouterLink} href={paths.dashboard.lesson_types.details(row.id)}>
<PencilSimpleIcon />
</IconButton>
<IconButton
color="error"
onClick={() => {
handleDeleteClick(row.id);
}}
>
<TrashSimpleIcon />
</IconButton>
</Stack>
),
name: 'Actions',
width: '100px',
align: 'right',
},
];
}
export interface LessonTypesTableProps {
rows: LessonType[];
reloadRows: () => void;
}
export function LessonTypesTable({ rows, reloadRows }: LessonTypesTableProps): React.JSX.Element {
const { t } = useTranslation();
const { deselectAll, deselectOne, selectAll, selectOne, selected } = useLessonTypesSelection();
const [idToDelete, setIdToDelete] = React.useState('');
const [open, setOpen] = React.useState(false);
function handleDeleteClick(testId: string): void {
setOpen(true);
setIdToDelete(testId);
}
return (
<React.Fragment>
<ConfirmDeleteModal idToDelete={idToDelete} open={open} reloadRows={reloadRows} setOpen={setOpen} />
<DataTable<LessonType>
columns={columns(handleDeleteClick)}
onDeselectAll={deselectAll}
onDeselectOne={(_, row) => {
deselectOne(row.id);
}}
onSelectAll={selectAll}
onSelectOne={(_, row) => {
selectOne(row.id);
}}
rows={rows}
selectable
selected={selected}
/>
{!rows.length ? (
<Box sx={{ p: 3 }}>
<Typography color="text.secondary" sx={{ textAlign: 'center' }} variant="body2">
{t('No lesson types found')}
</Typography>
</Box>
) : null}
</React.Fragment>
);
}