update build ok,
This commit is contained in:
@@ -2,7 +2,47 @@
|
|||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import RouterLink from 'next/link';
|
import RouterLink from 'next/link';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import Link from '@mui/material/Link';
|
||||||
|
import Stack from '@mui/material/Stack';
|
||||||
|
import Typography from '@mui/material/Typography';
|
||||||
|
import { ArrowLeft as ArrowLeftIcon } from '@phosphor-icons/react/dist/ssr/ArrowLeft';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
import { paths } from '@/paths';
|
||||||
|
import { LessonTypeEditForm } from '@/components/dashboard/lesson_type/lesson-type-edit-form';
|
||||||
|
|
||||||
export default function Page(): React.JSX.Element {
|
export default function Page(): React.JSX.Element {
|
||||||
return <>helloworld</>;
|
const { t } = useTranslation();
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
maxWidth: 'var(--Content-maxWidth)',
|
||||||
|
m: 'var(--Content-margin)',
|
||||||
|
p: 'var(--Content-padding)',
|
||||||
|
width: 'var(--Content-width)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack spacing={4}>
|
||||||
|
<Stack spacing={3}>
|
||||||
|
<div>
|
||||||
|
<Link
|
||||||
|
color="text.primary"
|
||||||
|
component={RouterLink}
|
||||||
|
href={paths.dashboard.lesson_types.list}
|
||||||
|
sx={{ alignItems: 'center', display: 'inline-flex', gap: 1 }}
|
||||||
|
variant="subtitle2"
|
||||||
|
>
|
||||||
|
<ArrowLeftIcon fontSize="var(--icon-fontSize-md)" />
|
||||||
|
{t('dashboard.lessonTypes.title')}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Typography variant="h4">{t('dashboard.lessonTypes.edit.title')}</Typography>
|
||||||
|
</div>
|
||||||
|
</Stack>
|
||||||
|
<LessonTypeEditForm />
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,25 @@
|
|||||||
|
export interface LessonTypeEditFormProps {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
pos: number;
|
||||||
|
visible: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RestLessonTypeUpdateForm {
|
||||||
|
id: string;
|
||||||
|
data: LessonTypeEditFormProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LessonTypeCreateForm {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
pos: number;
|
||||||
|
visible: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LessonTypeCreateFormDefault: LessonTypeCreateForm = {
|
||||||
|
name: '',
|
||||||
|
type: '',
|
||||||
|
pos: 1,
|
||||||
|
visible: 'visible',
|
||||||
|
};
|
@@ -0,0 +1,266 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import RouterLink from 'next/link';
|
||||||
|
import { useParams, useRouter } from 'next/navigation';
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { LoadingButton } from '@mui/lab';
|
||||||
|
import { MenuItem } from '@mui/material';
|
||||||
|
// import Avatar from '@mui/material/Avatar';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import Button from '@mui/material/Button';
|
||||||
|
import Card from '@mui/material/Card';
|
||||||
|
import CardActions from '@mui/material/CardActions';
|
||||||
|
import CardContent from '@mui/material/CardContent';
|
||||||
|
// import Checkbox from '@mui/material/Checkbox';
|
||||||
|
import Divider from '@mui/material/Divider';
|
||||||
|
import FormControl from '@mui/material/FormControl';
|
||||||
|
// import FormControlLabel from '@mui/material/FormControlLabel';
|
||||||
|
import FormHelperText from '@mui/material/FormHelperText';
|
||||||
|
import InputLabel from '@mui/material/InputLabel';
|
||||||
|
import OutlinedInput from '@mui/material/OutlinedInput';
|
||||||
|
import Select from '@mui/material/Select';
|
||||||
|
import Stack from '@mui/material/Stack';
|
||||||
|
import Typography from '@mui/material/Typography';
|
||||||
|
import Grid from '@mui/material/Unstable_Grid2';
|
||||||
|
// import { Camera as CameraIcon } from '@phosphor-icons/react/dist/ssr/Camera';
|
||||||
|
// import axios from 'axios';
|
||||||
|
import { Controller, useForm } from 'react-hook-form';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { z as zod } from 'zod';
|
||||||
|
|
||||||
|
import { paths } from '@/paths';
|
||||||
|
import { logger } from '@/lib/default-logger';
|
||||||
|
// import { Option } from '@/components/core/option';
|
||||||
|
import { toast } from '@/components/core/toaster';
|
||||||
|
|
||||||
|
// import { getLessonTypeById, updateLessonType } from './http-actions';
|
||||||
|
// TODO: this may be wrong
|
||||||
|
import type { LessonType } from './ILessonType';
|
||||||
|
import type { LessonTypeEditFormProps } from './interfaces';
|
||||||
|
|
||||||
|
// function fileToBase64(file: Blob): Promise<string> {
|
||||||
|
// return new Promise((resolve, reject) => {
|
||||||
|
// const reader = new FileReader();
|
||||||
|
// reader.readAsDataURL(file);
|
||||||
|
// reader.onload = () => {
|
||||||
|
// resolve(reader.result as string);
|
||||||
|
// };
|
||||||
|
// reader.onerror = () => {
|
||||||
|
// reject(new Error('Error converting file to base64'));
|
||||||
|
// };
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
const schema = zod.object({
|
||||||
|
name: zod.string().min(1, 'Name is required').max(255),
|
||||||
|
type: zod.string().min(1, 'Name is required').max(255),
|
||||||
|
pos: zod.number().min(1, 'Phone is required').max(15),
|
||||||
|
visible_to_user: zod.string().max(255),
|
||||||
|
});
|
||||||
|
|
||||||
|
type Values = zod.infer<typeof schema>;
|
||||||
|
|
||||||
|
const defaultValues = {
|
||||||
|
name: '',
|
||||||
|
type: '',
|
||||||
|
pos: 1,
|
||||||
|
visible_to_user: 'visible',
|
||||||
|
} satisfies Values;
|
||||||
|
|
||||||
|
export function LessonTypeEditForm(): React.JSX.Element {
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const { typeId } = useParams<{ typeId: string }>();
|
||||||
|
const [isUpdating, setIsUpdating] = React.useState<boolean>(false);
|
||||||
|
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },
|
||||||
|
setValue,
|
||||||
|
reset,
|
||||||
|
// watch,
|
||||||
|
} = useForm<Values>({ defaultValues, resolver: zodResolver(schema) });
|
||||||
|
|
||||||
|
const onSubmit = React.useCallback(
|
||||||
|
async (values: Values): Promise<void> => {
|
||||||
|
setIsUpdating(true);
|
||||||
|
const tempUpdate: LessonTypeEditFormProps = {
|
||||||
|
name: values.name,
|
||||||
|
type: values.type,
|
||||||
|
pos: values.pos,
|
||||||
|
visible: values.visible_to_user ? 'visible' : 'hidden',
|
||||||
|
};
|
||||||
|
|
||||||
|
// updateLessonType(tempUpdate, typeId)
|
||||||
|
// .then((res) => {
|
||||||
|
// logger.debug(res);
|
||||||
|
// toast.success(t('dashboard.lessonTypes.update.success'));
|
||||||
|
// setIsUpdating(false);
|
||||||
|
// router.push(paths.dashboard.lesson_types.list);
|
||||||
|
// })
|
||||||
|
// .catch((err) => {
|
||||||
|
// logger.error(err);
|
||||||
|
// toast.error('Something went wrong!');
|
||||||
|
// setIsUpdating(false);
|
||||||
|
// });
|
||||||
|
},
|
||||||
|
[router]
|
||||||
|
);
|
||||||
|
|
||||||
|
const avatarInputRef = React.useRef<HTMLInputElement>(null);
|
||||||
|
// const avatar = watch('avatar');
|
||||||
|
|
||||||
|
const handleAvatarChange = React.useCallback(
|
||||||
|
async (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const file = event.target.files?.[0];
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
// const url = await fileToBase64(file);
|
||||||
|
// setValue('avatar', url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[setValue]
|
||||||
|
);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
// getLessonTypeById(typeId)
|
||||||
|
// .then((lessonType: LessonType) => {
|
||||||
|
// reset({
|
||||||
|
// name: lessonType.name,
|
||||||
|
// type: lessonType.type,
|
||||||
|
// pos: lessonType.pos,
|
||||||
|
// visible_to_user: lessonType.visible,
|
||||||
|
// });
|
||||||
|
// })
|
||||||
|
// .catch((err) => {
|
||||||
|
// // console.error(err);
|
||||||
|
// });
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<Card>
|
||||||
|
<CardContent>
|
||||||
|
<Stack divider={<Divider />} spacing={4}>
|
||||||
|
<Stack spacing={3}>
|
||||||
|
<Typography variant="h6">{t('dashboard.lessonTypes.edit.typeInformation')}</Typography>
|
||||||
|
<Grid container spacing={3}>
|
||||||
|
<Grid xs={12}>
|
||||||
|
<Stack direction="row" spacing={3} sx={{ alignItems: 'center' }}>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
border: '1px dashed var(--mui-palette-divider)',
|
||||||
|
borderRadius: '50%',
|
||||||
|
display: 'inline-flex',
|
||||||
|
p: '4px',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/*
|
||||||
|
<Avatar
|
||||||
|
src={avatar}
|
||||||
|
sx={{
|
||||||
|
'--Avatar-size': '100px',
|
||||||
|
'--Icon-fontSize': 'var(--icon-fontSize-lg)',
|
||||||
|
alignItems: 'center',
|
||||||
|
bgcolor: 'var(--mui-palette-background-level1)',
|
||||||
|
color: 'var(--mui-palette-text-primary)',
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CameraIcon fontSize="var(--Icon-fontSize)" />
|
||||||
|
</Avatar>
|
||||||
|
*/}
|
||||||
|
</Box>
|
||||||
|
<Stack spacing={1} sx={{ alignItems: 'flex-start' }}>
|
||||||
|
<Typography variant="subtitle1">{t('dashboard.lessonTypes.edit.avatar')}</Typography>
|
||||||
|
<Typography variant="caption">{t('dashboard.lessonTypes.edit.avatarRequirements')}</Typography>
|
||||||
|
<Button
|
||||||
|
color="secondary"
|
||||||
|
onClick={() => {
|
||||||
|
avatarInputRef.current?.click();
|
||||||
|
}}
|
||||||
|
variant="outlined"
|
||||||
|
>
|
||||||
|
{t('dashboard.lessonTypes.edit.select')}
|
||||||
|
</Button>
|
||||||
|
<input hidden onChange={handleAvatarChange} ref={avatarInputRef} type="file" />
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</Grid>
|
||||||
|
<Grid md={6} xs={12}>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="name"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormControl error={Boolean(errors.name)} fullWidth>
|
||||||
|
<InputLabel required>{t('dashboard.lessonTypes.edit.name')}</InputLabel>
|
||||||
|
<OutlinedInput {...field} />
|
||||||
|
{errors.name ? <FormHelperText>{errors.name.message}</FormHelperText> : null}
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid md={6} xs={12}>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="type"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormControl error={Boolean(errors.type)} fullWidth>
|
||||||
|
<InputLabel required>{t('dashboard.lessonTypes.edit.type')}</InputLabel>
|
||||||
|
<OutlinedInput {...field} />
|
||||||
|
{errors.type ? <FormHelperText>{errors.type.message}</FormHelperText> : null}
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid md={6} xs={12}>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="pos"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormControl error={Boolean(errors.pos)} fullWidth>
|
||||||
|
<InputLabel required>{t('dashboard.lessonTypes.edit.position')}</InputLabel>
|
||||||
|
<OutlinedInput {...field} />
|
||||||
|
{errors.pos ? <FormHelperText>{errors.pos.message}</FormHelperText> : null}
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid md={6} xs={12}>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="visible_to_user"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormControl error={Boolean(errors.visible_to_user)} fullWidth>
|
||||||
|
<InputLabel>{t('dashboard.lessonTypes.edit.visibleToUser')}</InputLabel>
|
||||||
|
<Select {...field}>
|
||||||
|
<MenuItem value={'visible'}>{t('dashboard.lessonTypes.edit.visible')}</MenuItem>
|
||||||
|
<MenuItem value={'hidden'}>{t('dashboard.lessonTypes.edit.hidden')}</MenuItem>
|
||||||
|
</Select>
|
||||||
|
|
||||||
|
{errors.visible_to_user ? (
|
||||||
|
<FormHelperText>{errors.visible_to_user.message}</FormHelperText>
|
||||||
|
) : null}
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Stack>
|
||||||
|
</Stack>
|
||||||
|
</CardContent>
|
||||||
|
<CardActions sx={{ justifyContent: 'flex-end' }}>
|
||||||
|
<Button color="secondary" component={RouterLink} href={paths.dashboard.lesson_types.list}>
|
||||||
|
{t('dashboard.lessonTypes.edit.cancelButton')}
|
||||||
|
</Button>
|
||||||
|
<LoadingButton disabled={isUpdating} type="submit" variant="contained" loading={isUpdating}>
|
||||||
|
{t('dashboard.lessonTypes.edit.updateButton')}
|
||||||
|
</LoadingButton>
|
||||||
|
</CardActions>
|
||||||
|
</Card>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
Reference in New Issue
Block a user