update categories,
This commit is contained in:
@@ -116,4 +116,4 @@
|
|||||||
"protobufjs"
|
"protobufjs"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,8 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
// import type { Metadata } from 'next';
|
// import type { Metadata } from 'next';
|
||||||
import RouterLink from 'next/link';
|
import RouterLink from 'next/link';
|
||||||
|
import { useParams, useRouter } from 'next/navigation';
|
||||||
|
import { COL_LESSON_CATEGORIES } from '@/constants';
|
||||||
import Avatar from '@mui/material/Avatar';
|
import Avatar from '@mui/material/Avatar';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import Button from '@mui/material/Button';
|
import Button from '@mui/material/Button';
|
||||||
@@ -26,22 +28,58 @@ import { PencilSimple as PencilSimpleIcon } from '@phosphor-icons/react/dist/ssr
|
|||||||
import { Plus as PlusIcon } from '@phosphor-icons/react/dist/ssr/Plus';
|
import { Plus as PlusIcon } from '@phosphor-icons/react/dist/ssr/Plus';
|
||||||
import { ShieldWarning as ShieldWarningIcon } from '@phosphor-icons/react/dist/ssr/ShieldWarning';
|
import { ShieldWarning as ShieldWarningIcon } from '@phosphor-icons/react/dist/ssr/ShieldWarning';
|
||||||
import { User as UserIcon } from '@phosphor-icons/react/dist/ssr/User';
|
import { User as UserIcon } from '@phosphor-icons/react/dist/ssr/User';
|
||||||
|
import { RecordModel } from 'pocketbase';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { config } from '@/config';
|
|
||||||
import { paths } from '@/paths';
|
import { paths } from '@/paths';
|
||||||
import { dayjs } from '@/lib/dayjs';
|
import { dayjs } from '@/lib/dayjs';
|
||||||
|
import { logger } from '@/lib/default-logger';
|
||||||
|
import { pb } from '@/lib/pb';
|
||||||
import { PropertyItem } from '@/components/core/property-item';
|
import { PropertyItem } from '@/components/core/property-item';
|
||||||
import { PropertyList } from '@/components/core/property-list';
|
import { PropertyList } from '@/components/core/property-list';
|
||||||
|
import { toast } from '@/components/core/toaster';
|
||||||
|
import { defaultLessonCategory } from '@/components/dashboard/lesson_category/_constants.ts';
|
||||||
|
// import { defaultLessonCategory } from '@/components/dashboard/lesson_category/defaultLessonCategory';
|
||||||
import { Notifications } from '@/components/dashboard/lesson_category/notifications';
|
import { Notifications } from '@/components/dashboard/lesson_category/notifications';
|
||||||
import { Payments } from '@/components/dashboard/lesson_category/payments';
|
import { Payments } from '@/components/dashboard/lesson_category/payments';
|
||||||
import type { Address } from '@/components/dashboard/lesson_category/shipping-address';
|
import type { Address } from '@/components/dashboard/lesson_category/shipping-address';
|
||||||
import { ShippingAddress } from '@/components/dashboard/lesson_category/shipping-address';
|
import { ShippingAddress } from '@/components/dashboard/lesson_category/shipping-address';
|
||||||
|
import type { LessonCategory } from '@/components/dashboard/lesson_category/type.d.ts';
|
||||||
|
import FormLoading from '@/components/loading';
|
||||||
|
|
||||||
// export const metadata = { title: `Details | Customers | Dashboard | ${config.site.name}` } satisfies Metadata;
|
// export const metadata = { title: `Details | Customers | Dashboard | ${config.site.name}` } satisfies Metadata;
|
||||||
|
|
||||||
export default function Page(): React.JSX.Element {
|
export default function Page(): React.JSX.Element {
|
||||||
let { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const router = useRouter();
|
||||||
|
//
|
||||||
|
const { cat_id: catId } = useParams<{ cat_id: string }>();
|
||||||
|
//
|
||||||
|
const [showLoadin, setIsLoading] = React.useState<boolean>(true);
|
||||||
|
const [showError, setShowError] = React.useState<boolean>(false);
|
||||||
|
//
|
||||||
|
const [showLessonCategory, setShowLessonCategory] = React.useState<LessonCategory>(defaultLessonCategory);
|
||||||
|
|
||||||
|
function handleEditClick() {
|
||||||
|
router.push(paths.dashboard.lesson_categories.edit(showLessonCategory.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (catId) {
|
||||||
|
pb.collection(COL_LESSON_CATEGORIES)
|
||||||
|
.getOne(catId)
|
||||||
|
.then((model: RecordModel) => {
|
||||||
|
setShowLessonCategory({ ...defaultLessonCategory, ...model });
|
||||||
|
setIsLoading(false);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
logger.error(err);
|
||||||
|
toast(t('dashboard.lessonTypes.list.error'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [catId]);
|
||||||
|
|
||||||
|
if (showLoadin) return <FormLoading />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@@ -73,16 +111,16 @@ export default function Page(): React.JSX.Element {
|
|||||||
</Avatar>
|
</Avatar>
|
||||||
<div>
|
<div>
|
||||||
<Stack direction="row" spacing={2} sx={{ alignItems: 'center', flexWrap: 'wrap' }}>
|
<Stack direction="row" spacing={2} sx={{ alignItems: 'center', flexWrap: 'wrap' }}>
|
||||||
<Typography variant="h4">Miron Vitold</Typography>
|
<Typography variant="h4">{showLessonCategory.name}</Typography>
|
||||||
<Chip
|
<Chip
|
||||||
icon={<CheckCircleIcon color="var(--mui-palette-success-main)" weight="fill" />}
|
icon={<CheckCircleIcon color="var(--mui-palette-success-main)" weight="fill" />}
|
||||||
label="Active"
|
label={showLessonCategory.visible}
|
||||||
size="small"
|
size="small"
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
<Typography color="text.secondary" variant="body1">
|
<Typography color="text.secondary" variant="body1">
|
||||||
miron.vitold@domain.com
|
{showLessonCategory.id}
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
</Stack>
|
</Stack>
|
||||||
@@ -99,7 +137,11 @@ export default function Page(): React.JSX.Element {
|
|||||||
<Card>
|
<Card>
|
||||||
<CardHeader
|
<CardHeader
|
||||||
action={
|
action={
|
||||||
<IconButton>
|
<IconButton
|
||||||
|
onClick={() => {
|
||||||
|
handleEditClick();
|
||||||
|
}}
|
||||||
|
>
|
||||||
<PencilSimpleIcon />
|
<PencilSimpleIcon />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
}
|
}
|
||||||
@@ -117,11 +159,20 @@ export default function Page(): React.JSX.Element {
|
|||||||
>
|
>
|
||||||
{(
|
{(
|
||||||
[
|
[
|
||||||
{ key: 'Customer ID', value: <Chip label="USR-001" size="small" variant="soft" /> },
|
{ key: 'Customer ID', value: <Chip label={showLessonCategory.id} size="small" variant="soft" /> },
|
||||||
{ key: 'Name', value: 'Miron Vitold' },
|
{ key: 'Name', value: showLessonCategory.name },
|
||||||
{ key: 'Email', value: 'miron.vitold@domain.com' },
|
{ key: 'Pos', value: showLessonCategory.pos },
|
||||||
{ key: 'Phone', value: '(425) 434-5535' },
|
{
|
||||||
{ key: 'Company', value: 'Devias IO' },
|
key: 'Visible',
|
||||||
|
value: (
|
||||||
|
<Chip
|
||||||
|
//
|
||||||
|
label={showLessonCategory.visible}
|
||||||
|
size="small"
|
||||||
|
variant="soft"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'Quota',
|
key: 'Quota',
|
||||||
value: (
|
value: (
|
||||||
@@ -158,7 +209,7 @@ export default function Page(): React.JSX.Element {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Typography color="text.secondary" variant="body2">
|
<Typography color="text.secondary" variant="body2">
|
||||||
A deleted customer cannot be restored. All data will be permanently removed.
|
A deleted lesson category cannot be restored. All data will be permanently removed.
|
||||||
</Typography>
|
</Typography>
|
||||||
</Stack>
|
</Stack>
|
||||||
</CardContent>
|
</CardContent>
|
@@ -1,6 +1,8 @@
|
|||||||
import { dayjs } from '@/lib/dayjs';
|
import { dayjs } from '@/lib/dayjs';
|
||||||
|
import { LessonCategory } from '@/components/dashboard/lesson_category/type';
|
||||||
|
|
||||||
// import type { LessonCategory } from '@/components/dashboard/lesson_category/lesson-categories-table';
|
// import type { LessonCategory } from '@/components/dashboard/lesson_category/lesson-categories-table';
|
||||||
import type { LessonCategory } from '@/components/dashboard/lesson_category/interfaces';
|
// import type { LessonCategory } from '@/components/dashboard/lesson_category/interfaces';
|
||||||
|
|
||||||
export const lessonCategoriesSampleData = [
|
export const lessonCategoriesSampleData = [
|
||||||
{
|
{
|
||||||
|
@@ -18,15 +18,17 @@ import { logger } from '@/lib/default-logger';
|
|||||||
import { pb } from '@/lib/pb';
|
import { pb } from '@/lib/pb';
|
||||||
import { toast } from '@/components/core/toaster';
|
import { toast } from '@/components/core/toaster';
|
||||||
import ErrorDisplay from '@/components/dashboard/error';
|
import ErrorDisplay from '@/components/dashboard/error';
|
||||||
import { defaultLessonCategory, type LessonCategory } from '@/components/dashboard/lesson_category/interfaces';
|
import { defaultLessonCategory } from '@/components/dashboard/lesson_category/_constants';
|
||||||
|
// import { defaultLessonCategory, type LessonCategory } from '@/components/dashboard/lesson_category/interfaces';
|
||||||
import { LessonCategoriesFilters } from '@/components/dashboard/lesson_category/lesson-categories-filters';
|
import { LessonCategoriesFilters } from '@/components/dashboard/lesson_category/lesson-categories-filters';
|
||||||
import type { Filters } from '@/components/dashboard/lesson_category/lesson-categories-filters';
|
import type { Filters } from '@/components/dashboard/lesson_category/lesson-categories-filters';
|
||||||
import { LessonCategoriesPagination } from '@/components/dashboard/lesson_category/lesson-categories-pagination';
|
import { LessonCategoriesPagination } from '@/components/dashboard/lesson_category/lesson-categories-pagination';
|
||||||
import { LessonCategoriesSelectionProvider } from '@/components/dashboard/lesson_category/lesson-categories-selection-context';
|
import { LessonCategoriesSelectionProvider } from '@/components/dashboard/lesson_category/lesson-categories-selection-context';
|
||||||
import { LessonCategoriesTable } from '@/components/dashboard/lesson_category/lesson-categories-table';
|
import { LessonCategoriesTable } from '@/components/dashboard/lesson_category/lesson-categories-table';
|
||||||
|
import type { LessonCategory } from '@/components/dashboard/lesson_category/type';
|
||||||
import FormLoading from '@/components/loading';
|
import FormLoading from '@/components/loading';
|
||||||
|
|
||||||
import { lessonCategoriesSampleData } from './lesson-categories-sample-data';
|
// import { lessonCategoriesSampleData } from './lesson-categories-sample-data';
|
||||||
|
|
||||||
interface PageProps {
|
interface PageProps {
|
||||||
searchParams: {
|
searchParams: {
|
||||||
|
@@ -27,7 +27,6 @@ import { Plus as PlusIcon } from '@phosphor-icons/react/dist/ssr/Plus';
|
|||||||
import { ShieldWarning as ShieldWarningIcon } from '@phosphor-icons/react/dist/ssr/ShieldWarning';
|
import { ShieldWarning as ShieldWarningIcon } from '@phosphor-icons/react/dist/ssr/ShieldWarning';
|
||||||
import { User as UserIcon } from '@phosphor-icons/react/dist/ssr/User';
|
import { User as UserIcon } from '@phosphor-icons/react/dist/ssr/User';
|
||||||
import type { RecordModel } from 'pocketbase';
|
import type { RecordModel } from 'pocketbase';
|
||||||
import PocketBase from 'pocketbase';
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { paths } from '@/paths';
|
import { paths } from '@/paths';
|
||||||
@@ -47,11 +46,15 @@ import { ShippingAddress } from '@/components/dashboard/lesson_type/shipping-add
|
|||||||
|
|
||||||
export default function Page(): React.JSX.Element {
|
export default function Page(): React.JSX.Element {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { typeId } = useParams<{ typeId: string }>();
|
|
||||||
const [isLoading, setIsLoading] = React.useState<boolean>(true);
|
|
||||||
const [showLessonType, setShowLessonType] = React.useState<LessonType>(LessonTypeDefaultValue);
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
const { type_id: typeId } = useParams<{ type_id: string }>();
|
||||||
|
//
|
||||||
|
const [showLoading, setIsLoading] = React.useState<boolean>(true);
|
||||||
|
const [showError, setShowError] = React.useState<boolean>(false);
|
||||||
|
//
|
||||||
|
const [showLessonType, setShowLessonType] = React.useState<LessonType>(LessonTypeDefaultValue);
|
||||||
|
|
||||||
function handleEditClick() {
|
function handleEditClick() {
|
||||||
router.push(paths.dashboard.lesson_types.edit(showLessonType.id));
|
router.push(paths.dashboard.lesson_types.edit(showLessonType.id));
|
||||||
}
|
}
|
||||||
@@ -71,7 +74,7 @@ export default function Page(): React.JSX.Element {
|
|||||||
}
|
}
|
||||||
}, [typeId]);
|
}, [typeId]);
|
||||||
|
|
||||||
if (isLoading) return <div>{t('common.loading')}</div>;
|
if (showLoading) return <div>{t('common.loading')}</div>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@@ -155,7 +158,17 @@ export default function Page(): React.JSX.Element {
|
|||||||
{ key: 'Name', value: showLessonType.name },
|
{ key: 'Name', value: showLessonType.name },
|
||||||
{ key: 'Type', value: showLessonType.type },
|
{ key: 'Type', value: showLessonType.type },
|
||||||
{ key: 'Pos', value: showLessonType.pos },
|
{ key: 'Pos', value: showLessonType.pos },
|
||||||
{ key: 'Visible', value: <Chip label={showLessonType.visible} size="small" variant="soft" /> },
|
{
|
||||||
|
key: 'Visible',
|
||||||
|
value: (
|
||||||
|
<Chip
|
||||||
|
//
|
||||||
|
label={showLessonType.visible}
|
||||||
|
size="small"
|
||||||
|
variant="soft"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'Quota',
|
key: 'Quota',
|
||||||
value: (
|
value: (
|
@@ -0,0 +1,37 @@
|
|||||||
|
import { dayjs } from '@/lib/dayjs';
|
||||||
|
|
||||||
|
import type { CreateForm, LessonCategory } from './type';
|
||||||
|
|
||||||
|
export const defaultLessonCategory: LessonCategory = {
|
||||||
|
isEmpty: false,
|
||||||
|
id: 'default-id',
|
||||||
|
cat_name: 'default-category-name',
|
||||||
|
cat_image_url: undefined,
|
||||||
|
cat_image: undefined,
|
||||||
|
pos: 0,
|
||||||
|
visible: 'hidden',
|
||||||
|
lesson_id: 'default-lesson-id',
|
||||||
|
description: 'default-description',
|
||||||
|
remarks: 'default-remarks',
|
||||||
|
//
|
||||||
|
createdAt: dayjs('2099-01-01').toDate(),
|
||||||
|
//
|
||||||
|
name: '',
|
||||||
|
avatar: '',
|
||||||
|
email: '',
|
||||||
|
phone: '',
|
||||||
|
quota: 0,
|
||||||
|
status: 'NA',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LessonCategoryCreateFormDefault: CreateForm = {
|
||||||
|
name: '',
|
||||||
|
type: '',
|
||||||
|
pos: 1,
|
||||||
|
visible: 'visible',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const emptyLessonCategory: LessonCategory = {
|
||||||
|
...defaultLessonCategory,
|
||||||
|
isEmpty: true,
|
||||||
|
};
|
@@ -4,8 +4,11 @@ import * as React from 'react';
|
|||||||
|
|
||||||
import { useSelection } from '@/hooks/use-selection';
|
import { useSelection } from '@/hooks/use-selection';
|
||||||
import type { Selection } from '@/hooks/use-selection';
|
import type { Selection } from '@/hooks/use-selection';
|
||||||
|
|
||||||
|
import type { LessonCategory } from './type';
|
||||||
|
|
||||||
// import type { LessonCategory } from './lesson-categories-table';
|
// import type { LessonCategory } from './lesson-categories-table';
|
||||||
import type { LessonCategory } from '@/components/dashboard/lesson_category/interfaces';
|
// import type { LessonCategory } from '@/components/dashboard/lesson_category/interfaces';
|
||||||
|
|
||||||
function noop(): void {
|
function noop(): void {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@@ -26,8 +26,9 @@ import { DataTable } from '@/components/core/data-table';
|
|||||||
import type { ColumnDef } from '@/components/core/data-table';
|
import type { ColumnDef } from '@/components/core/data-table';
|
||||||
|
|
||||||
import ConfirmDeleteModal from './confirm-delete-modal';
|
import ConfirmDeleteModal from './confirm-delete-modal';
|
||||||
import type { LessonCategory } from './interfaces';
|
// import type { LessonCategory } from './interfaces.1ts';
|
||||||
import { useLessonCategoriesSelection } from './lesson-categories-selection-context';
|
import { useLessonCategoriesSelection } from './lesson-categories-selection-context';
|
||||||
|
import { LessonCategory } from './type';
|
||||||
|
|
||||||
function columns(handleDeleteClick: (testId: string) => void): ColumnDef<LessonCategory>[] {
|
function columns(handleDeleteClick: (testId: string) => void): ColumnDef<LessonCategory>[] {
|
||||||
return [
|
return [
|
||||||
|
28
002_source/cms/src/components/dashboard/lesson_category/type.d.ts
vendored
Normal file
28
002_source/cms/src/components/dashboard/lesson_category/type.d.ts
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
export interface LessonCategory {
|
||||||
|
isEmpty?: boolean;
|
||||||
|
//
|
||||||
|
id: string;
|
||||||
|
cat_name: string;
|
||||||
|
cat_image_url?: string;
|
||||||
|
cat_image?: string;
|
||||||
|
pos: number;
|
||||||
|
visible: string;
|
||||||
|
lesson_id: string;
|
||||||
|
description: string;
|
||||||
|
remarks: string;
|
||||||
|
//
|
||||||
|
name: string;
|
||||||
|
avatar: string;
|
||||||
|
email: string;
|
||||||
|
phone: string;
|
||||||
|
quota: number;
|
||||||
|
status: 'pending' | 'active' | 'blocked' | 'NA';
|
||||||
|
createdAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateForm {
|
||||||
|
name: string;
|
||||||
|
type: string;
|
||||||
|
pos: number;
|
||||||
|
visible: string;
|
||||||
|
}
|
@@ -79,13 +79,14 @@ export const paths = {
|
|||||||
lesson_types: {
|
lesson_types: {
|
||||||
list: '/dashboard/lesson_types',
|
list: '/dashboard/lesson_types',
|
||||||
create: '/dashboard/lesson_types/create',
|
create: '/dashboard/lesson_types/create',
|
||||||
details: (lessonTypeId: string) => `/dashboard/lesson_types/${lessonTypeId}`,
|
details: (typeId: string) => `/dashboard/lesson_types/${typeId}`,
|
||||||
edit: (lessonTypeId: string) => `/dashboard/lesson_types/edit/${lessonTypeId}`,
|
edit: (typeId: string) => `/dashboard/lesson_types/edit/${typeId}`,
|
||||||
},
|
},
|
||||||
lesson_categories: {
|
lesson_categories: {
|
||||||
list: '/dashboard/lesson_categories',
|
list: '/dashboard/lesson_categories',
|
||||||
create: '/dashboard/lesson_categories/create',
|
create: '/dashboard/lesson_categories/create',
|
||||||
details: (lessonTypeId: string) => `/dashboard/lesson_categories/${lessonTypeId}`,
|
details: (catId: string) => `/dashboard/lesson_categories/${catId}`,
|
||||||
|
edit: (catId: string) => `/dashboard/lesson_categories/edit/${catId}`,
|
||||||
},
|
},
|
||||||
customers: {
|
customers: {
|
||||||
list: '/dashboard/customers',
|
list: '/dashboard/customers',
|
||||||
|
Reference in New Issue
Block a user