From f49e6acef3cda5ce52332893a8913ce72aae209e Mon Sep 17 00:00:00 2001 From: louiscklaw Date: Wed, 16 Apr 2025 02:03:46 +0800 Subject: [PATCH] update build ok, --- .../lesson_types/edit/[typeId]/page.tsx | 42 ++- .../dashboard/lesson_type/interfaces.ts | 25 ++ .../lesson_type/lesson-type-edit-form.tsx | 266 ++++++++++++++++++ 3 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 002_source/cms/src/components/dashboard/lesson_type/interfaces.ts create mode 100644 002_source/cms/src/components/dashboard/lesson_type/lesson-type-edit-form.tsx diff --git a/002_source/cms/src/app/dashboard/lesson_types/edit/[typeId]/page.tsx b/002_source/cms/src/app/dashboard/lesson_types/edit/[typeId]/page.tsx index c4b804c..91e89ef 100644 --- a/002_source/cms/src/app/dashboard/lesson_types/edit/[typeId]/page.tsx +++ b/002_source/cms/src/app/dashboard/lesson_types/edit/[typeId]/page.tsx @@ -2,7 +2,47 @@ import * as React from 'react'; 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 { - return <>helloworld; + const { t } = useTranslation(); + return ( + + + +
+ + + {t('dashboard.lessonTypes.title')} + +
+
+ {t('dashboard.lessonTypes.edit.title')} +
+
+ +
+
+ ); } diff --git a/002_source/cms/src/components/dashboard/lesson_type/interfaces.ts b/002_source/cms/src/components/dashboard/lesson_type/interfaces.ts new file mode 100644 index 0000000..5a74d89 --- /dev/null +++ b/002_source/cms/src/components/dashboard/lesson_type/interfaces.ts @@ -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', +}; diff --git a/002_source/cms/src/components/dashboard/lesson_type/lesson-type-edit-form.tsx b/002_source/cms/src/components/dashboard/lesson_type/lesson-type-edit-form.tsx new file mode 100644 index 0000000..555ffc1 --- /dev/null +++ b/002_source/cms/src/components/dashboard/lesson_type/lesson-type-edit-form.tsx @@ -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 { +// 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; + +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(false); + + const { + control, + handleSubmit, + formState: { errors }, + setValue, + reset, + // watch, + } = useForm({ defaultValues, resolver: zodResolver(schema) }); + + const onSubmit = React.useCallback( + async (values: Values): Promise => { + 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(null); + // const avatar = watch('avatar'); + + const handleAvatarChange = React.useCallback( + async (event: React.ChangeEvent) => { + 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 ( +
+ + + } spacing={4}> + + {t('dashboard.lessonTypes.edit.typeInformation')} + + + + + {/* + + + + */} + + + {t('dashboard.lessonTypes.edit.avatar')} + {t('dashboard.lessonTypes.edit.avatarRequirements')} + + + + + + + ( + + {t('dashboard.lessonTypes.edit.name')} + + {errors.name ? {errors.name.message} : null} + + )} + /> + + + ( + + {t('dashboard.lessonTypes.edit.type')} + + {errors.type ? {errors.type.message} : null} + + )} + /> + + + ( + + {t('dashboard.lessonTypes.edit.position')} + + {errors.pos ? {errors.pos.message} : null} + + )} + /> + + + ( + + {t('dashboard.lessonTypes.edit.visibleToUser')} + + + {errors.visible_to_user ? ( + {errors.visible_to_user.message} + ) : null} + + )} + /> + + + + + + + + + {t('dashboard.lessonTypes.edit.updateButton')} + + + +
+ ); +}