update,
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { dayjs } from '@/lib/dayjs';
|
||||
|
||||
import type { CreateForm, LessonCategory } from './types';
|
||||
import { CreateForm, LessonCategory } from './type';
|
||||
|
||||
// import type { CreateForm, LessonCategory } from '../lp_categories/type';
|
||||
|
||||
export const defaultLessonCategory: LessonCategory = {
|
||||
isEmpty: false,
|
||||
@@ -30,6 +32,10 @@ export const LessonCategoryCreateFormDefault: CreateForm = {
|
||||
type: '',
|
||||
pos: 1,
|
||||
visible: 'visible',
|
||||
description: '',
|
||||
isActive: true,
|
||||
order: 1,
|
||||
imageUrl: '',
|
||||
};
|
||||
|
||||
export const emptyLessonCategory: LessonCategory = {
|
||||
|
@@ -24,8 +24,9 @@ import { pb } from '@/lib/pb';
|
||||
import { FilterButton, FilterPopover, useFilterContext } from '@/components/core/filter-button';
|
||||
import { Option } from '@/components/core/option';
|
||||
|
||||
// import { LessonCategory } from '../lp_categories/type';
|
||||
import { useLessonCategoriesSelection } from './lesson-categories-selection-context';
|
||||
import { LessonCategory } from './types';
|
||||
import { LessonCategory } from './type';
|
||||
|
||||
export interface Filters {
|
||||
email?: string;
|
||||
|
@@ -2,10 +2,13 @@
|
||||
|
||||
import * as React from 'react';
|
||||
|
||||
// import type { LessonCategory } from '@/types/lesson-type';
|
||||
import { useSelection } from '@/hooks/use-selection';
|
||||
import type { Selection } from '@/hooks/use-selection';
|
||||
|
||||
import type { LessonCategory } from './types';
|
||||
import { LessonCategory } from './type';
|
||||
|
||||
// import type { LessonCategory } from '../lp_categories/type';
|
||||
|
||||
// import type { LessonCategory } from './lesson-categories-table';
|
||||
// import type { LessonCategory } from '@/components/dashboard/lesson_category/interfaces';
|
||||
|
@@ -25,10 +25,11 @@ import { dayjs } from '@/lib/dayjs';
|
||||
import { DataTable } from '@/components/core/data-table';
|
||||
import type { ColumnDef } from '@/components/core/data-table';
|
||||
|
||||
// import { LessonCategory } from '../lp_categories/type';
|
||||
import ConfirmDeleteModal from './confirm-delete-modal';
|
||||
// import type { LessonCategory } from './interfaces.1ts';
|
||||
import { useLessonCategoriesSelection } from './lesson-categories-selection-context';
|
||||
import { LessonCategory } from './types';
|
||||
import { LessonCategory } from './type';
|
||||
|
||||
function columns(handleDeleteClick: (testId: string) => void): ColumnDef<LessonCategory>[] {
|
||||
return [
|
||||
|
@@ -42,7 +42,7 @@ import FormLoading from '@/components/loading';
|
||||
|
||||
import ErrorDisplay from '../error';
|
||||
import { defaultLessonCategory } from './_constants';
|
||||
import { EditFormProps, LessonCategory } from './types';
|
||||
import type { EditFormProps, LessonCategory } from './type';
|
||||
|
||||
// TODO: review this
|
||||
const schema = zod.object({
|
||||
@@ -97,6 +97,7 @@ export function LessonCategoryEditForm(): React.JSX.Element {
|
||||
visible: values.visible,
|
||||
description: values.description,
|
||||
remarks: values.remarks,
|
||||
type: '',
|
||||
};
|
||||
|
||||
pb.collection(COL_LESSON_CATEGORIES)
|
||||
@@ -325,7 +326,7 @@ export function LessonCategoryEditForm(): React.JSX.Element {
|
||||
onUpdate={({ editor }) => {
|
||||
field.onChange({ target: { value: editor.getText() } });
|
||||
}}
|
||||
hideToolbar={true}
|
||||
hideToolbar
|
||||
placeholder={t('edit.write-something', NS_DEFAULT)}
|
||||
/>
|
||||
</Box>
|
||||
|
@@ -2,6 +2,8 @@ export interface LessonCategory {
|
||||
isEmpty?: boolean;
|
||||
//
|
||||
id: string;
|
||||
collectionId: string;
|
||||
//
|
||||
cat_name: string;
|
||||
cat_image_url?: string;
|
||||
cat_image?: string;
|
||||
@@ -10,7 +12,6 @@ export interface LessonCategory {
|
||||
lesson_id: string;
|
||||
description: string;
|
||||
remarks: string;
|
||||
collectionId: string;
|
||||
//
|
||||
name: string;
|
||||
avatar: string;
|
||||
@@ -26,6 +27,10 @@ export interface CreateForm {
|
||||
type: string;
|
||||
pos: number;
|
||||
visible: string;
|
||||
description: string;
|
||||
isActive: boolean;
|
||||
order: number;
|
||||
imageUrl: string;
|
||||
}
|
||||
|
||||
export interface EditFormProps {
|
||||
@@ -34,4 +39,9 @@ export interface EditFormProps {
|
||||
visible: string;
|
||||
description?: string;
|
||||
remarks?: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface Helloworld {
|
||||
helloworld: string;
|
||||
}
|
@@ -4,7 +4,7 @@ import type { RecordModel } from 'pocketbase';
|
||||
import { dayjs } from '@/lib/dayjs';
|
||||
|
||||
// import type { LessonType } from './ILessonType';
|
||||
import type { CreateForm, LessonType } from './types';
|
||||
import type { CreateForm, LessonType } from './lesson-type';
|
||||
|
||||
export const LessonTypeCreateFormDefault: CreateForm = {
|
||||
name: '',
|
||||
|
@@ -37,7 +37,7 @@ import { pb } from '@/lib/pb';
|
||||
import { toast } from '@/components/core/toaster';
|
||||
|
||||
import { LessonTypeCreateFormDefault } from './_constants';
|
||||
import { CreateForm } from './types';
|
||||
import { CreateForm } from './lesson-type';
|
||||
|
||||
// import { CreateForm, LessonTypeCreateFormDefault } from './interfaces';
|
||||
|
||||
|
@@ -41,7 +41,7 @@ import { defaultLessonType } from './_constants';
|
||||
// import { getLessonTypeById, updateLessonType } from './http-actions';
|
||||
// TODO: this may be wrong
|
||||
// import type { LessonType } from './ILessonType';
|
||||
import { LessonTypeEditFormProps } from './types';
|
||||
import type { LessonTypeEditFormProps } from './lesson-type';
|
||||
|
||||
// import { defaultLessonType, type LessonTypeEditFormProps } from './interfaces';
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import { NO_NUM, NO_VALUE } from '@/constants';
|
||||
import type { RecordModel } from 'pocketbase';
|
||||
|
||||
import { dayjs } from '@/lib/dayjs';
|
@@ -24,8 +24,8 @@ import { pb } from '@/lib/pb';
|
||||
import { FilterButton, FilterPopover, useFilterContext } from '@/components/core/filter-button';
|
||||
import { Option } from '@/components/core/option';
|
||||
|
||||
import type { LessonType } from './lesson-type';
|
||||
import { useLessonTypesSelection } from './lesson-types-selection-context';
|
||||
import type { LessonType } from './types';
|
||||
|
||||
export interface Filters {
|
||||
email?: string;
|
||||
|
@@ -5,7 +5,7 @@ import * as React from 'react';
|
||||
import { useSelection } from '@/hooks/use-selection';
|
||||
import type { Selection } from '@/hooks/use-selection';
|
||||
|
||||
import { LessonType } from './types';
|
||||
import { LessonType } from './lesson-type';
|
||||
|
||||
// import { LessonType } from './ILessonType';
|
||||
|
||||
|
@@ -26,9 +26,9 @@ import { DataTable } from '@/components/core/data-table';
|
||||
import type { ColumnDef } from '@/components/core/data-table';
|
||||
|
||||
import ConfirmDeleteModal from './confirm-delete-modal';
|
||||
import { LessonType } from './lesson-type';
|
||||
// import type { LessonType } from './ILessonType';
|
||||
import { useLessonTypesSelection } from './lesson-types-selection-context';
|
||||
import { LessonType } from './types';
|
||||
|
||||
function columns(handleDeleteClick: (testId: string) => void): ColumnDef<LessonType>[] {
|
||||
return [
|
||||
|
53
002_source/cms/src/components/dashboard/lesson_type/type.d.ts
vendored
Normal file
53
002_source/cms/src/components/dashboard/lesson_type/type.d.ts
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
export interface LessonTypeEditFormProps {
|
||||
name: string;
|
||||
type: string;
|
||||
pos: number;
|
||||
visible: string;
|
||||
}
|
||||
|
||||
export interface RestLessonTypeUpdateForm {
|
||||
id: string;
|
||||
data: LessonTypeEditFormProps;
|
||||
}
|
||||
|
||||
export interface CreateForm {
|
||||
name: string;
|
||||
type: string;
|
||||
pos: number;
|
||||
visible: string;
|
||||
}
|
||||
|
||||
export interface LessonType {
|
||||
id: string;
|
||||
isEmpty?: boolean;
|
||||
name: string;
|
||||
type: string;
|
||||
pos: number;
|
||||
visible: 'visible' | 'hidden';
|
||||
createdAt: Date;
|
||||
//
|
||||
// original
|
||||
// id: string;
|
||||
// name: string;
|
||||
//
|
||||
avatar?: string;
|
||||
email: string;
|
||||
phone?: string;
|
||||
quota: number;
|
||||
status: 'pending' | 'active' | 'blocked';
|
||||
// createdAt: Date;
|
||||
}
|
||||
|
||||
export interface DBLessonType {
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
pos: number;
|
||||
visible: 'visible' | 'hidden';
|
||||
createdAt: Date;
|
||||
created: 'string';
|
||||
}
|
||||
|
||||
export interface Helloworld {
|
||||
id: string;
|
||||
}
|
@@ -1,13 +1,17 @@
|
||||
import { NO_NUM, NO_VALUE } from '@/constants';
|
||||
import type { RecordModel } from 'pocketbase';
|
||||
|
||||
import { CreateForm, LpCategory } from '@/types/LpCategory';
|
||||
import { dayjs } from '@/lib/dayjs';
|
||||
|
||||
import type { CreateForm, LpCategory } from './type';
|
||||
|
||||
// import type { CreateForm, LpCategory } from './types';
|
||||
|
||||
export const LpCategoryCreateFormDefault: CreateForm = {
|
||||
name: '',
|
||||
type: '',
|
||||
pos: 1,
|
||||
visible: 'visible',
|
||||
description: '',
|
||||
isActive: true,
|
||||
order: 1,
|
||||
@@ -16,18 +20,27 @@ export const LpCategoryCreateFormDefault: CreateForm = {
|
||||
|
||||
export const defaultLpCategory: LpCategory = {
|
||||
id: '',
|
||||
name: '',
|
||||
cat_name: '',
|
||||
cat_image: '',
|
||||
collectionId: '',
|
||||
//
|
||||
cat_name: '',
|
||||
cat_image_url: '',
|
||||
cat_image: '',
|
||||
pos: 1,
|
||||
lesson_id: '1',
|
||||
description: '',
|
||||
isActive: true,
|
||||
order: 1,
|
||||
imageUrl: '',
|
||||
remarks: '',
|
||||
createdAt: dayjs().toDate(),
|
||||
updatedAt: dayjs().toDate(),
|
||||
visible: 'active',
|
||||
status: '',
|
||||
visible: 'visible',
|
||||
//
|
||||
name: '',
|
||||
avatar: '',
|
||||
email: '',
|
||||
phone: '',
|
||||
quota: 0,
|
||||
order: 1,
|
||||
status: 'NA',
|
||||
isActive: true,
|
||||
imageUrl: '',
|
||||
};
|
||||
|
||||
export const emptyLpCategory: LpCategory = {
|
||||
|
@@ -18,12 +18,13 @@ import Tabs from '@mui/material/Tabs';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import type { LpCategory } from '@/types/LpCategory';
|
||||
import { paths } from '@/paths';
|
||||
import { FilterButton, FilterPopover, useFilterContext } from '@/components/core/filter-button';
|
||||
import { Option } from '@/components/core/option';
|
||||
|
||||
import { useLpCategoriesSelection } from './lp-categories-selection-context';
|
||||
// import type { LpCategory } from '@/types/type.d';
|
||||
import type { LpCategory } from './type';
|
||||
|
||||
export interface Filters {
|
||||
email?: string;
|
||||
|
@@ -5,7 +5,7 @@ import * as React from 'react';
|
||||
import { useSelection } from '@/hooks/use-selection';
|
||||
import type { Selection } from '@/hooks/use-selection';
|
||||
|
||||
import type { LpCategory } from '../../../types/LpCategory.tsx';
|
||||
import type { LpCategory } from './type';
|
||||
|
||||
function noop(): void {
|
||||
return undefined;
|
||||
|
@@ -0,0 +1,295 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import RouterLink from 'next/link';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { COL_LESSON_TYPES } from '@/constants';
|
||||
import getQuizListeningById from '@/db/QuizListenings/GetById';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import { Avatar, 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 type { RecordModel } from 'pocketbase';
|
||||
import PocketBase from 'pocketbase';
|
||||
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 { pb } from '@/lib/pb';
|
||||
// import { Option } from '@/components/core/option';
|
||||
import { toast } from '@/components/core/toaster';
|
||||
import { EditFormProps } from '@/components/dashboard/lp_categories/type';
|
||||
import FormLoading from '@/components/loading';
|
||||
|
||||
import { LessonTypeEditFormProps } from '../lesson_type/lesson-type';
|
||||
import { defaultLpCategory } from './_constants';
|
||||
|
||||
// import { getLessonTypeById, updateLessonType } from './http-actions';
|
||||
// import { LessonTypeEditFormProps } from './types';
|
||||
|
||||
// import { defaultLessonType, 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({
|
||||
cat_name: zod.string().min(1, 'Name is required').max(255),
|
||||
type: zod.string().min(1, 'Name is required').max(255),
|
||||
slug: 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 = {
|
||||
cat_name: '',
|
||||
slug: '',
|
||||
type: '',
|
||||
pos: 1,
|
||||
visible_to_user: 'visible',
|
||||
} satisfies Values;
|
||||
|
||||
export function LpCategoryEditForm(): React.JSX.Element {
|
||||
const router = useRouter();
|
||||
const { t } = useTranslation();
|
||||
const { typeId } = useParams<{ typeId: string }>();
|
||||
//
|
||||
const [isUpdating, setIsUpdating] = React.useState<boolean>(false);
|
||||
const [showLoading, setShowLoading] = 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: EditFormProps = {
|
||||
cat_name: values.cat_name,
|
||||
type: values.type,
|
||||
pos: values.pos,
|
||||
visible: values.visible_to_user ? 'visible' : 'hidden',
|
||||
};
|
||||
|
||||
pb.collection(COL_LESSON_TYPES)
|
||||
.update(typeId, tempUpdate)
|
||||
.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);
|
||||
});
|
||||
}, []);
|
||||
|
||||
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]
|
||||
);
|
||||
|
||||
const handleLoad = React.useCallback(
|
||||
(id: string) => {
|
||||
setShowLoading(true);
|
||||
|
||||
getQuizListeningById(id)
|
||||
.then((model: RecordModel) => {
|
||||
reset({ ...defaultLpCategory, ...model });
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error(err);
|
||||
toast(t('dashboard.lessonTypes.list.error'));
|
||||
})
|
||||
.finally(() => {
|
||||
setShowLoading(false);
|
||||
});
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[typeId]
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
handleLoad(typeId);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [typeId]);
|
||||
|
||||
if (showLoading) return <FormLoading />;
|
||||
|
||||
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="cat_name"
|
||||
render={({ field }) => (
|
||||
<FormControl error={Boolean(errors.cat_name)} fullWidth>
|
||||
<InputLabel required>{t('dashboard.lessonTypes.edit.name')}</InputLabel>
|
||||
<OutlinedInput {...field} />
|
||||
{errors.cat_name ? <FormHelperText>{errors.cat_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}
|
||||
onChange={(e) => {
|
||||
field.onChange(parseInt(e.target.value));
|
||||
}}
|
||||
type="number"
|
||||
/>
|
||||
|
||||
{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} loading={isUpdating} type="submit" variant="contained">
|
||||
{t('dashboard.lessonTypes.edit.updateButton')}
|
||||
</LoadingButton>
|
||||
</CardActions>
|
||||
</Card>
|
||||
</form>
|
||||
);
|
||||
}
|
@@ -20,14 +20,14 @@ import { TrashSimple as TrashSimpleIcon } from '@phosphor-icons/react/dist/ssr/T
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
import type { LpCategory } from '@/types/LpCategory';
|
||||
import { paths } from '@/paths';
|
||||
import { dayjs } from '@/lib/dayjs';
|
||||
import { DataTable } from '@/components/core/data-table';
|
||||
import type { ColumnDef } from '@/components/core/data-table';
|
||||
|
||||
import type { LessonCategory } from '../lesson_category/types';
|
||||
import ConfirmDeleteModal from './confirm-delete-modal';
|
||||
import { useLpCategoriesSelection } from './lp-categories-selection-context';
|
||||
import type { LpCategory } from './type';
|
||||
|
||||
function columns(handleDeleteClick: (testId: string) => void): ColumnDef<LpCategory>[] {
|
||||
return [
|
||||
@@ -83,10 +83,8 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef<LpCateg
|
||||
blocked: { label: 'Blocked', icon: <MinusIcon color="var(--mui-palette-error-main)" /> },
|
||||
pending: { label: 'Pending', icon: <ClockIcon color="var(--mui-palette-warning-main)" weight="fill" /> },
|
||||
NA: { label: 'NA', icon: <ClockIcon color="var(--mui-palette-warning-main)" weight="fill" /> },
|
||||
visible: { label: 'visible', icon: <ClockIcon color="var(--mui-palette-warning-main)" weight="fill" /> },
|
||||
hidden: { label: 'hidden', icon: <ClockIcon color="var(--mui-palette-warning-main)" weight="fill" /> },
|
||||
} as const;
|
||||
const { label, icon } = mapping[row.visible] ?? { label: 'Unknown', icon: null };
|
||||
const { label, icon } = mapping[row.status] ?? { label: 'Unknown', icon: null };
|
||||
|
||||
return (
|
||||
<Button
|
||||
@@ -139,15 +137,16 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef<LpCateg
|
||||
];
|
||||
}
|
||||
|
||||
export interface LpCategoriesTableProps {
|
||||
export interface LpCategoryTableProps {
|
||||
rows: LpCategory[];
|
||||
reloadRows: () => void;
|
||||
}
|
||||
|
||||
function getCatImageFromId(row: LpCategory): string | undefined {
|
||||
return `http://127.0.0.1:8090/api/files/${row.collectionId}/${row.id}/${row.cat_image}`;
|
||||
}
|
||||
|
||||
export function LpCategoriesTable({ rows }: LpCategoriesTableProps): React.JSX.Element {
|
||||
export function LpCategoriesTable({ rows, reloadRows }: LpCategoryTableProps): React.JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
const { deselectAll, deselectOne, selectAll, selectOne, selected } = useLpCategoriesSelection();
|
||||
|
||||
@@ -161,6 +160,7 @@ export function LpCategoriesTable({ rows }: LpCategoriesTableProps): React.JSX.E
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<ConfirmDeleteModal idToDelete={idToDelete} open={open} reloadRows={reloadRows} setOpen={setOpen} />
|
||||
<DataTable<LpCategory>
|
||||
columns={columns(handleDeleteClick)}
|
||||
onDeselectAll={deselectAll}
|
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import { Notification } from '@/app/dashboard/Sample/Notifications/type';
|
||||
import Avatar from '@mui/material/Avatar';
|
||||
import Box from '@mui/material/Box';
|
||||
import Button from '@mui/material/Button';
|
||||
@@ -14,7 +15,7 @@ import Typography from '@mui/material/Typography';
|
||||
import { EnvelopeSimple as EnvelopeSimpleIcon } from '@phosphor-icons/react/dist/ssr/EnvelopeSimple';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import type { Notification } from '@/types/notification';
|
||||
// import type { Notification } from '@/types/type';
|
||||
import { dayjs } from '@/lib/dayjs';
|
||||
import { DataTable } from '@/components/core/data-table';
|
||||
import type { ColumnDef } from '@/components/core/data-table';
|
||||
|
50
002_source/cms/src/components/dashboard/lp_categories/type.d.ts
vendored
Normal file
50
002_source/cms/src/components/dashboard/lp_categories/type.d.ts
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
export interface LpCategory {
|
||||
isEmpty?: boolean;
|
||||
//
|
||||
id: string;
|
||||
collectionId: string;
|
||||
//
|
||||
cat_name: string;
|
||||
cat_image_url?: string;
|
||||
cat_image?: string;
|
||||
pos: number;
|
||||
visible: string;
|
||||
lesson_id: string;
|
||||
description: string;
|
||||
remarks: string;
|
||||
createdAt: Date;
|
||||
visible: 'pending' | 'active' | 'blocked' | 'NA' | 'visible' | 'hidden';
|
||||
name: string;
|
||||
avatar: string;
|
||||
email: string;
|
||||
phone: string;
|
||||
quota: number;
|
||||
status: 'pending' | 'active' | 'blocked' | 'NA';
|
||||
isActive: boolean;
|
||||
order: number;
|
||||
imageUrl: string;
|
||||
}
|
||||
|
||||
export interface CreateForm {
|
||||
name: string;
|
||||
type: string;
|
||||
pos: number;
|
||||
visible: string;
|
||||
description: string;
|
||||
isActive: boolean;
|
||||
order: number;
|
||||
imageUrl: string;
|
||||
}
|
||||
|
||||
export interface EditFormProps {
|
||||
cat_name: string;
|
||||
pos: number;
|
||||
visible: string;
|
||||
description?: string;
|
||||
remarks?: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface Helloworld {
|
||||
helloworld: string;
|
||||
}
|
Reference in New Issue
Block a user