This commit is contained in:
louiscklaw
2025-04-26 09:48:37 +08:00
parent 7296a10ec1
commit a00d1ee7ce
7 changed files with 287 additions and 134 deletions

View File

@@ -1,11 +0,0 @@
# task
## instruction
with reference to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/app/_helloworld/page.tsx`
with reference to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/app/dashboard/lesson_types/edit/[typeId]/page.tsx`
please modify `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/app/dashboard/lesson_categories/edit/page.tsx`
please draft a tsx for showing error to user thanks,

View File

@@ -1,3 +1,4 @@
// src/app/dashboard/vocabularies/create/page.tsx
'use client';
import * as React from 'react';
@@ -34,11 +35,11 @@ export default function Page(): React.JSX.Element {
variant="subtitle2"
>
<ArrowLeftIcon fontSize="var(--icon-fontSize-md)" />
{t('title',)}
{t('title')}
</Link>
</div>
<div>
<Typography variant="h4">{t('create.title', )}</Typography>
<Typography variant="h4">{t('create.title')}</Typography>
</div>
</Stack>
<VocabularyCreateForm />

View File

@@ -121,12 +121,22 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
<form onSubmit={handleSubmit(onSubmit)}>
<Card>
<CardContent>
<Stack divider={<Divider />} spacing={4}>
<Stack
divider={<Divider />}
spacing={4}
>
<Stack spacing={3}>
<Typography variant="h6">{t('create.typeInformation', NS_DEFAULT)}</Typography>
<Grid container spacing={3}>
<Typography variant="h6">{t('create.basic')}</Typography>
<Grid
container
spacing={3}
>
<Grid xs={12}>
<Stack direction="row" spacing={3} sx={{ alignItems: 'center' }}>
<Stack
direction="row"
spacing={3}
sx={{ alignItems: 'center' }}
>
<Box
sx={{
border: '1px dashed var(--mui-palette-divider)',
@@ -151,9 +161,12 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
<CameraIcon fontSize="var(--Icon-fontSize)" />
</Avatar>
</Box>
<Stack spacing={1} sx={{ alignItems: 'flex-start' }}>
<Typography variant="subtitle1">{t('create.avatar', NS_DEFAULT)}</Typography>
<Typography variant="caption">{t('create.avatarRequirements', NS_DEFAULT)}</Typography>
<Stack
spacing={1}
sx={{ alignItems: 'flex-start' }}
>
<Typography variant="subtitle1">{t('create.avatar')}</Typography>
<Typography variant="caption">{t('create.avatarRequirements')}</Typography>
<Button
color="secondary"
onClick={() => {
@@ -161,44 +174,70 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
}}
variant="outlined"
>
{t('create.avatar_select', NS_DEFAULT)}
{t('create.avatar_select')}
</Button>
<input hidden onChange={handleAvatarChange} ref={avatarInputRef} type="file" />
<input
hidden
onChange={handleAvatarChange}
ref={avatarInputRef}
type="file"
/>
</Stack>
</Stack>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="name"
render={({ field }) => (
<FormControl error={Boolean(errors.name)} fullWidth>
<InputLabel required>{t('create.name', NS_DEFAULT)}</InputLabel>
<FormControl
error={Boolean(errors.name)}
fullWidth
>
<InputLabel required>{t('create.name')}</InputLabel>
<OutlinedInput {...field} />
{errors.name ? <FormHelperText>{errors.name.message}</FormHelperText> : null}
</FormControl>
)}
/>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="email"
render={({ field }) => (
<FormControl error={Boolean(errors.email)} fullWidth>
<FormControl
error={Boolean(errors.email)}
fullWidth
>
<InputLabel required>Email address</InputLabel>
<OutlinedInput {...field} type="email" />
<OutlinedInput
{...field}
type="email"
/>
{errors.email ? <FormHelperText>{errors.email.message}</FormHelperText> : null}
</FormControl>
)}
/>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="phone"
render={({ field }) => (
<FormControl error={Boolean(errors.phone)} fullWidth>
<FormControl
error={Boolean(errors.phone)}
fullWidth
>
<InputLabel required>Phone number</InputLabel>
<OutlinedInput {...field} />
{errors.phone ? <FormHelperText>{errors.phone.message}</FormHelperText> : null}
@@ -206,12 +245,18 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
)}
/>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="company"
render={({ field }) => (
<FormControl error={Boolean(errors.company)} fullWidth>
<FormControl
error={Boolean(errors.company)}
fullWidth
>
<InputLabel>Company</InputLabel>
<OutlinedInput {...field} />
{errors.company ? <FormHelperText>{errors.company.message}</FormHelperText> : null}
@@ -222,35 +267,56 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
</Grid>
</Stack>
<Stack spacing={3}>
<Typography variant="h6">{t('create.detail-information', NS_DEFAULT)}</Typography>
<Grid container spacing={3}>
<Grid md={6} xs={12}>
<Typography variant="h6">{t('create.detail-information')}</Typography>
<Grid
container
spacing={3}
>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="billingAddress.country"
render={({ field }) => (
<Box>
<Typography variant="subtitle1" color="text-secondary">
{t('create.description', NS_DEFAULT)}
<Typography
variant="subtitle1"
color="text-secondary"
>
{t('create.description')}
</Typography>
<Box sx={{ mt: '8px', '& .tiptap-container': { height: '400px' } }}>
<TextEditor content="" placeholder="Write something" />
<TextEditor
content=""
placeholder="Write something"
/>
</Box>
</Box>
)}
/>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="billingAddress.state"
render={({ field }) => (
<Box>
<Typography variant="subtitle1" color="text.secondary">
{t('create.remarks', NS_DEFAULT)}
<Typography
variant="subtitle1"
color="text.secondary"
>
{t('create.remarks')}
</Typography>
<Box sx={{ mt: '8px', '& .tiptap-container': { height: '400px' } }}>
<TextEditor content="" placeholder="Write something" />
<TextEditor
content=""
placeholder="Write something"
/>
</Box>
</Box>
)}
@@ -261,12 +327,21 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
</Stack>
</CardContent>
<CardActions sx={{ justifyContent: 'flex-end' }}>
<Button color="secondary" component={RouterLink} href={paths.dashboard.lesson_categories.list}>
{t('create.cancelButton', NS_DEFAULT)}
<Button
color="secondary"
component={RouterLink}
href={paths.dashboard.lesson_categories.list}
>
{t('create.cancelButton')}
</Button>
<LoadingButton disabled={isCreating} loading={isCreating} type="submit" variant="contained">
{t('create.createButton', NS_DEFAULT)}
<LoadingButton
disabled={isCreating}
loading={isCreating}
type="submit"
variant="contained"
>
{t('create.createButton')}
</LoadingButton>
</CardActions>
</Card>

View File

@@ -75,8 +75,6 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
const router = useRouter();
const { t } = useTranslation(['common', 'lesson_category']);
const NS_DEFAULT = { ns: 'lesson_category' };
const [isCreating, setIsCreating] = React.useState<boolean>(false);
const {
@@ -121,12 +119,22 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
<form onSubmit={handleSubmit(onSubmit)}>
<Card>
<CardContent>
<Stack divider={<Divider />} spacing={4}>
<Stack
divider={<Divider />}
spacing={4}
>
<Stack spacing={3}>
<Typography variant="h6">{t('create.typeInformation', NS_DEFAULT)}</Typography>
<Grid container spacing={3}>
<Typography variant="h6">{t('create.basic')}</Typography>
<Grid
container
spacing={3}
>
<Grid xs={12}>
<Stack direction="row" spacing={3} sx={{ alignItems: 'center' }}>
<Stack
direction="row"
spacing={3}
sx={{ alignItems: 'center' }}
>
<Box
sx={{
border: '1px dashed var(--mui-palette-divider)',
@@ -151,9 +159,12 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
<CameraIcon fontSize="var(--Icon-fontSize)" />
</Avatar>
</Box>
<Stack spacing={1} sx={{ alignItems: 'flex-start' }}>
<Typography variant="subtitle1">{t('create.avatar', NS_DEFAULT)}</Typography>
<Typography variant="caption">{t('create.avatarRequirements', NS_DEFAULT)}</Typography>
<Stack
spacing={1}
sx={{ alignItems: 'flex-start' }}
>
<Typography variant="subtitle1">{t('create.avatar')}</Typography>
<Typography variant="caption">{t('create.avatarRequirements')}</Typography>
<Button
color="secondary"
onClick={() => {
@@ -161,44 +172,70 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
}}
variant="outlined"
>
{t('create.avatar_select', NS_DEFAULT)}
{t('create.avatar_select')}
</Button>
<input hidden onChange={handleAvatarChange} ref={avatarInputRef} type="file" />
<input
hidden
onChange={handleAvatarChange}
ref={avatarInputRef}
type="file"
/>
</Stack>
</Stack>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="name"
render={({ field }) => (
<FormControl error={Boolean(errors.name)} fullWidth>
<InputLabel required>{t('create.name', NS_DEFAULT)}</InputLabel>
<FormControl
error={Boolean(errors.name)}
fullWidth
>
<InputLabel required>{t('create.name')}</InputLabel>
<OutlinedInput {...field} />
{errors.name ? <FormHelperText>{errors.name.message}</FormHelperText> : null}
</FormControl>
)}
/>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="email"
render={({ field }) => (
<FormControl error={Boolean(errors.email)} fullWidth>
<FormControl
error={Boolean(errors.email)}
fullWidth
>
<InputLabel required>Email address</InputLabel>
<OutlinedInput {...field} type="email" />
<OutlinedInput
{...field}
type="email"
/>
{errors.email ? <FormHelperText>{errors.email.message}</FormHelperText> : null}
</FormControl>
)}
/>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="phone"
render={({ field }) => (
<FormControl error={Boolean(errors.phone)} fullWidth>
<FormControl
error={Boolean(errors.phone)}
fullWidth
>
<InputLabel required>Phone number</InputLabel>
<OutlinedInput {...field} />
{errors.phone ? <FormHelperText>{errors.phone.message}</FormHelperText> : null}
@@ -206,12 +243,18 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
)}
/>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="company"
render={({ field }) => (
<FormControl error={Boolean(errors.company)} fullWidth>
<FormControl
error={Boolean(errors.company)}
fullWidth
>
<InputLabel>Company</InputLabel>
<OutlinedInput {...field} />
{errors.company ? <FormHelperText>{errors.company.message}</FormHelperText> : null}
@@ -222,35 +265,56 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
</Grid>
</Stack>
<Stack spacing={3}>
<Typography variant="h6">{t('create.detail-information', NS_DEFAULT)}</Typography>
<Grid container spacing={3}>
<Grid md={6} xs={12}>
<Typography variant="h6">{t('create.detail-information')}</Typography>
<Grid
container
spacing={3}
>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="billingAddress.country"
render={({ field }) => (
<Box>
<Typography variant="subtitle1" color="text-secondary">
{t('create.description', NS_DEFAULT)}
<Typography
variant="subtitle1"
color="text-secondary"
>
{t('create.description')}
</Typography>
<Box sx={{ mt: '8px', '& .tiptap-container': { height: '400px' } }}>
<TextEditor content="" placeholder="Write something" />
<TextEditor
content=""
placeholder="Write something"
/>
</Box>
</Box>
)}
/>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="billingAddress.state"
render={({ field }) => (
<Box>
<Typography variant="subtitle1" color="text.secondary">
{t('create.remarks', NS_DEFAULT)}
<Typography
variant="subtitle1"
color="text.secondary"
>
{t('create.remarks')}
</Typography>
<Box sx={{ mt: '8px', '& .tiptap-container': { height: '400px' } }}>
<TextEditor content="" placeholder="Write something" />
<TextEditor
content=""
placeholder="Write something"
/>
</Box>
</Box>
)}
@@ -261,12 +325,21 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
</Stack>
</CardContent>
<CardActions sx={{ justifyContent: 'flex-end' }}>
<Button color="secondary" component={RouterLink} href={paths.dashboard.lesson_categories.list}>
{t('create.cancelButton', NS_DEFAULT)}
<Button
color="secondary"
component={RouterLink}
href={paths.dashboard.lesson_categories.list}
>
{t('create.cancelButton')}
</Button>
<LoadingButton disabled={isCreating} loading={isCreating} type="submit" variant="contained">
{t('create.createButton', NS_DEFAULT)}
<LoadingButton
disabled={isCreating}
loading={isCreating}
type="submit"
variant="contained"
>
{t('create.createButton')}
</LoadingButton>
</CardActions>
</Card>

View File

@@ -113,12 +113,22 @@ export function LessonTypeCreateForm(): React.JSX.Element {
<form onSubmit={handleSubmit(onSubmit)}>
<Card>
<CardContent>
<Stack divider={<Divider />} spacing={4}>
<Stack
divider={<Divider />}
spacing={4}
>
<Stack spacing={3}>
<Typography variant="h6">{t('dashboard.lessonTypes.create.typeInformation')}</Typography>
<Grid container spacing={3}>
<Typography variant="h6">{t('create.basic')}</Typography>
<Grid
container
spacing={3}
>
<Grid xs={12}>
<Stack direction="row" spacing={3} sx={{ alignItems: 'center' }}>
<Stack
direction="row"
spacing={3}
sx={{ alignItems: 'center' }}
>
<Box
sx={{
border: '1px dashed var(--mui-palette-divider)',
@@ -127,7 +137,10 @@ export function LessonTypeCreateForm(): React.JSX.Element {
p: '4px',
}}
/>
<Stack spacing={1} sx={{ alignItems: 'flex-start' }}>
<Stack
spacing={1}
sx={{ alignItems: 'flex-start' }}
>
<Typography variant="subtitle1">{t('dashboard.lessonTypes.create.avatar')}</Typography>
<Typography variant="caption">{t('dashboard.lessonTypes.create.avatarRequirements')}</Typography>
<Button
@@ -139,16 +152,27 @@ export function LessonTypeCreateForm(): React.JSX.Element {
>
{t('dashboard.lessonTypes.create.select')}
</Button>
<input hidden onChange={handleAvatarChange} ref={avatarInputRef} type="file" />
<input
hidden
onChange={handleAvatarChange}
ref={avatarInputRef}
type="file"
/>
</Stack>
</Stack>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="name"
render={({ field }) => (
<FormControl error={Boolean(errors.name)} fullWidth>
<FormControl
error={Boolean(errors.name)}
fullWidth
>
<InputLabel required>{t('dashboard.lessonTypes.create.name')}</InputLabel>
<OutlinedInput {...field} />
{errors.name ? <FormHelperText>{errors.name.message}</FormHelperText> : null}
@@ -156,12 +180,18 @@ export function LessonTypeCreateForm(): React.JSX.Element {
)}
/>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="type"
render={({ field }) => (
<FormControl error={Boolean(errors.type)} fullWidth>
<FormControl
error={Boolean(errors.type)}
fullWidth
>
<InputLabel required>{t('dashboard.lessonTypes.create.type')}</InputLabel>
<OutlinedInput {...field} />
{errors.type ? <FormHelperText>{errors.type.message}</FormHelperText> : null}
@@ -169,12 +199,18 @@ export function LessonTypeCreateForm(): React.JSX.Element {
)}
/>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="pos"
render={({ field }) => (
<FormControl error={Boolean(errors.pos)} fullWidth>
<FormControl
error={Boolean(errors.pos)}
fullWidth
>
<InputLabel required>{t('dashboard.lessonTypes.create.position')}</InputLabel>
<OutlinedInput
{...field}
@@ -188,12 +224,18 @@ export function LessonTypeCreateForm(): React.JSX.Element {
)}
/>
</Grid>
<Grid md={6} xs={12}>
<Grid
md={6}
xs={12}
>
<Controller
control={control}
name="visible_to_user"
render={({ field }) => (
<FormControl error={Boolean(errors.visible_to_user)} fullWidth>
<FormControl
error={Boolean(errors.visible_to_user)}
fullWidth
>
<InputLabel>{t('dashboard.lessonTypes.create.visibleToUser')}</InputLabel>
<Select {...field}>
<MenuItem value="visible">visible</MenuItem>
@@ -212,10 +254,19 @@ export function LessonTypeCreateForm(): React.JSX.Element {
</Stack>
</CardContent>
<CardActions sx={{ justifyContent: 'flex-end' }}>
<Button color="secondary" component={RouterLink} href={paths.dashboard.lesson_types.list}>
<Button
color="secondary"
component={RouterLink}
href={paths.dashboard.lesson_types.list}
>
{t('dashboard.lessonTypes.create.cancelButton')}
</Button>
<LoadingButton disabled={isCreating} loading={isCreating} type="submit" variant="contained">
<LoadingButton
disabled={isCreating}
loading={isCreating}
type="submit"
variant="contained"
>
{t('dashboard.lessonTypes.create.createButton')}
</LoadingButton>
</CardActions>

View File

@@ -1,36 +0,0 @@
export interface Vocabulary {
id: string;
created?: string;
updated?: string;
image?: string;
sound?: string;
word?: string;
word_c?: string;
sample_e?: string;
sample_c?: string;
cat_id?: string;
category?: string;
lesson_type_id?: string;
}
export interface CreateForm {
image?: string;
sound?: string;
word?: string;
word_c?: string;
sample_e?: string;
sample_c?: string;
cat_id?: string;
category?: string;
lesson_type_id?: string;
}
export interface EditFormProps {
id: string;
defaultValues: Vocabulary;
onDone: () => void;
}
export interface Helloworld {
helloworld: string;
}

View File

@@ -185,7 +185,7 @@ export function VocabularyCreateForm(): React.JSX.Element {
spacing={4}
>
<Stack spacing={3}>
<Typography variant="h6">{t('create.typeInformation')}</Typography>
<Typography variant="h6">{t('create.basic')}</Typography>
<Grid
container
spacing={3}