From 57e25ef65f5f53566c401ba4ecdf0eedce87d4bb Mon Sep 17 00:00:00 2001 From: louiscklaw Date: Fri, 16 May 2025 12:51:32 +0800 Subject: [PATCH] update fix eslint, --- 002_source/cms/.eslintrc.js | 8 +- 002_source/cms/package.json | 2 +- .../__tests__/app/_helloworld/page.test.tsx | 21 - 002_source/cms/src/__tests__/snapshot.js | 9 - .../lesson-categories-sample-data.tsx | 2 +- .../connectives/view/[cat_id]/page.tsx | 4 +- .../app/dashboard/cr/categories/list/page.tsx | 4 +- .../categories/lp-categories-sample-data.tsx | 2 +- .../view/[cat_id]/BasicDetailCard.tsx | 2 +- .../cr/questions/[cat_id]/BasicDetailCard.tsx | 2 +- .../cr/questions/[cat_id]/TitleCard.tsx | 2 +- .../questions/cr-categories-sample-data.tsx | 2 +- .../lesson-categories-sample-data.tsx | 2 +- .../lesson_types/lesson-types-data.tsx | 2 +- .../lesson_types/lesson-types-sample-data.tsx | 2 +- .../app/dashboard/lp/categories/list/page.tsx | 4 +- .../categories/lp-categories-sample-data.tsx | 2 +- .../view/[cat_id]/BasicDetailCard.tsx | 2 +- .../app/dashboard/lp/questions/list/page.tsx | 4 +- .../questions/lp-categories-sample-data.tsx | 2 +- .../view/[cat_id]/BasicDetailCard.tsx | 2 +- .../lp/questions/view/[cat_id]/TitleCard.tsx | 2 +- .../app/dashboard/mf/categories/list/page.tsx | 4 +- .../categories/lp-categories-sample-data.tsx | 2 +- .../app/dashboard/mf/questions/list/page.tsx | 4 +- .../questions/lp-categories-sample-data.tsx | 2 +- .../view/[cat_id]/BasicDetailCard.tsx | 2 +- .../app/dashboard/user_metas/list/page.tsx | 2 +- .../lesson-categories-sample-data.tsx | 2 +- .../auth/custom/sign-in-form/index.tsx | 4 +- .../auth/custom/sign-up-form/index.tsx | 2 +- .../dashboard/connective/_constants.ts | 2 +- .../connective/lesson-categories-filters.tsx | 2 +- .../lesson-categories-selection-context.tsx | 2 +- .../connective/lesson-categories-table.tsx | 2 +- .../dashboard/cr/categories/_constants.ts | 3 +- .../cr-categories-selection-context.tsx | 2 +- .../cr/categories/cr-categories-table.tsx | 2 +- .../dashboard/cr/questions/_constants.ts | 3 +- .../cr/questions/cr-questions-filters.tsx | 2 +- .../cr/questions/cr-questions-table.tsx | 2 +- .../dashboard/customer/customers-table.tsx | 2 +- .../src/components/dashboard/error/index.tsx | 2 +- .../layout/notifications-popover/index.tsx | 2 +- .../sample-notifications.tsx | 2 +- .../main-nav/notifications-button.tsx | 2 +- .../dashboard/lesson_category/_constants.ts | 2 +- .../lesson-categories-filters.tsx | 2 +- .../lesson-categories-selection-context.tsx | 2 +- .../lesson-categories-table.tsx | 2 +- .../lesson_type/lesson-type-create-form.tsx | 2 +- .../lesson-types-selection-context.tsx | 2 +- .../dashboard/lp/categories/_constants.ts | 3 +- .../lp/categories/lp-categories-filters.tsx | 2 +- .../lp-categories-selection-context.tsx | 2 +- .../lp/categories/lp-categories-table.tsx | 2 +- .../lp/categories/mf-categories-filters.tsx | 2 +- .../mf-categories-selection-context.tsx | 2 +- .../lp/categories/mf-categories-table.tsx | 2 +- .../dashboard/lp/questions/_constants.ts | 3 +- .../lp/questions/lp-questions-filters.tsx | 2 +- .../lp/questions/lp-questions-table.tsx | 2 +- .../dashboard/mf/categories/_constants.ts | 3 +- .../mf/categories/mf-categories-filters.tsx | 2 +- .../mf-categories-selection-context.tsx | 2 +- .../mf/categories/mf-categories-table.tsx | 2 +- .../dashboard/mf/questions/_constants.ts | 3 +- .../mf/questions/mf-questions-filters.tsx | 2 +- .../mf/questions/mf-questions-table.tsx | 2 +- .../dashboard/student/student-create-form.tsx | 2 +- .../dashboard/student/students-pagination.tsx | 9 +- .../dashboard/student/students-table.tsx | 4 - .../teacher/confirm-delete-modal.tsx | 4 +- .../dashboard/teacher/teacher-create-form.tsx | 2 +- .../dashboard/teacher/teacher-edit-form.tsx | 5 +- .../dashboard/teacher/teachers-filters.tsx | 2 + .../dashboard/teacher/teachers-pagination.tsx | 9 +- .../dashboard/user.de/_GUIDELINES.md | 25 - .../dashboard/user.de/_constants.ts | 21 - .../user.de/confirm-delete-modal.tsx | 124 ---- .../user.de/email-filter-popover.tsx | 50 -- .../dashboard/user.de/helloworld.tsx | 3 - .../dashboard/user.de/notifications.tsx | 101 --- .../components/dashboard/user.de/payments.tsx | 138 ---- .../user.de/phone-filter-popover.tsx | 50 -- .../dashboard/user.de/shipping-address.tsx | 46 -- .../components/dashboard/user.de/type.d.tsx | 69 -- .../dashboard/user.de/user-create-form.tsx | 529 --------------- .../dashboard/user.de/user-edit-form.tsx | 604 ------------------ .../dashboard/user.de/users-filters.tsx | 242 ------- .../dashboard/user.de/users-pagination.tsx | 50 -- .../user.de/users-selection-context.tsx | 40 -- .../dashboard/user.de/users-table.tsx | 222 ------- .../user_meta/confirm-delete-modal.tsx | 4 +- .../user_meta/user-metas-filters.tsx | 3 +- .../user_meta/user-metas-pagination.tsx | 9 +- .../dashboard/user_meta/user-metas-table.tsx | 3 - .../dashboard/vocabulary/_constants.ts | 3 +- .../vocabulary/confirm-delete-modal.tsx | 12 +- .../vocabulary/vocabularies-filters.tsx | 124 ++-- .../vocabulary/vocabularies-pagination.tsx | 11 +- .../vocabulary/vocabularies-table.tsx | 2 +- .../vocabulary/vocabulary-create-form.tsx | 12 +- .../vocabulary/vocabulary-edit-form.tsx | 60 +- .../cms/src/components/loading/index.tsx | 7 +- .../components/marketing/home/included.tsx | 2 +- .../cms/src/db/Customers/GetActiveCount.tsx | 3 +- 002_source/cms/src/db/Customers/GetAll.tsx | 2 +- .../cms/src/db/Customers/GetBlockedCount.tsx | 3 +- 002_source/cms/src/db/Customers/GetById.tsx | 2 +- .../cms/src/db/Customers/GetPendingCount.tsx | 3 +- .../cms/src/db/Customers/Helloworld.tsx | 2 +- ...ategories.tsx => ListLessonCategories.tsx} | 0 .../cms/src/db/Notifications/GetAll.tsx | 2 +- .../cms/src/db/Notifications/GetById.tsx | 2 +- .../cms/src/db/Notifications/Helloworld.tsx | 2 +- .../src/db/Notifications/mark-one-as-read.tsx | 4 +- .../cms/src/db/QuizCRCategories/Create.tsx | 2 +- .../cms/src/db/QuizLPCategories/Create.tsx | 2 +- 002_source/cms/src/db/Students/Delete.tsx | 3 +- .../cms/src/db/Students/GetActiveCount.tsx | 3 +- 002_source/cms/src/db/Students/GetAll.tsx | 2 +- 002_source/cms/src/db/Students/Helloworld.tsx | 2 +- .../cms/src/db/Teachers/GetActiveCount.tsx | 3 +- 002_source/cms/src/db/Teachers/GetAll.tsx | 2 +- 002_source/cms/src/db/Teachers/Helloworld.tsx | 2 +- 002_source/cms/src/db/UserMetas/GetAll.tsx | 2 +- .../cms/src/db/UserMetas/Helloworld.tsx | 2 +- 002_source/cms/src/db/Users/GetAll.tsx | 2 +- 002_source/cms/src/db/Users/Helloworld.tsx | 2 +- 002_source/cms/src/db/Vocabularies/Create.tsx | 3 +- 002_source/cms/src/db/Vocabularies/Delete.tsx | 1 + 002_source/cms/src/db/Vocabularies/GetAll.tsx | 3 +- .../cms/src/db/Vocabularies/GetById.tsx | 3 +- .../src/db/Vocabularies/GetHiddenCount.tsx | 1 + .../src/db/Vocabularies/GetVisibleCount.tsx | 1 + 002_source/cms/src/db/Vocabularies/Update.tsx | 2 + .../db/Vocabularies/{type.d.tsx => type.d.ts} | 0 .../cms/src/db/billingAddress/Delete.tsx | 3 +- .../src/db/billingAddress/GetActiveCount.tsx | 3 +- .../cms/src/db/billingAddress/GetAll.tsx | 2 +- .../cms/src/db/billingAddress/Helloworld.tsx | 2 +- 002_source/cms/src/hooks/use-helloworld.ts | 1 + 002_source/cms/src/lib/file-to-base64.tsx | 2 +- 144 files changed, 277 insertions(+), 2597 deletions(-) delete mode 100644 002_source/cms/src/__tests__/app/_helloworld/page.test.tsx delete mode 100644 002_source/cms/src/__tests__/snapshot.js delete mode 100644 002_source/cms/src/components/dashboard/user.de/_GUIDELINES.md delete mode 100644 002_source/cms/src/components/dashboard/user.de/_constants.ts delete mode 100644 002_source/cms/src/components/dashboard/user.de/confirm-delete-modal.tsx delete mode 100644 002_source/cms/src/components/dashboard/user.de/email-filter-popover.tsx delete mode 100644 002_source/cms/src/components/dashboard/user.de/helloworld.tsx delete mode 100644 002_source/cms/src/components/dashboard/user.de/notifications.tsx delete mode 100644 002_source/cms/src/components/dashboard/user.de/payments.tsx delete mode 100644 002_source/cms/src/components/dashboard/user.de/phone-filter-popover.tsx delete mode 100644 002_source/cms/src/components/dashboard/user.de/shipping-address.tsx delete mode 100644 002_source/cms/src/components/dashboard/user.de/type.d.tsx delete mode 100644 002_source/cms/src/components/dashboard/user.de/user-create-form.tsx delete mode 100644 002_source/cms/src/components/dashboard/user.de/user-edit-form.tsx delete mode 100644 002_source/cms/src/components/dashboard/user.de/users-filters.tsx delete mode 100644 002_source/cms/src/components/dashboard/user.de/users-pagination.tsx delete mode 100644 002_source/cms/src/components/dashboard/user.de/users-selection-context.tsx delete mode 100644 002_source/cms/src/components/dashboard/user.de/users-table.tsx rename 002_source/cms/src/db/LessonCategories/{listLessonCategories.tsx => ListLessonCategories.tsx} (100%) rename 002_source/cms/src/db/Vocabularies/{type.d.tsx => type.d.ts} (100%) diff --git a/002_source/cms/.eslintrc.js b/002_source/cms/.eslintrc.js index 9df006e..3660e61 100644 --- a/002_source/cms/.eslintrc.js +++ b/002_source/cms/.eslintrc.js @@ -82,7 +82,13 @@ module.exports = { 'eslintreact/jsx-sort-props': 'off', 'react/jsx-sort-props': 'off', }, - ignorePatterns: ['**/*del', '**/*bak', '**/*copy.*', '**/*copy*.*'], + ignorePatterns: [ + '**/*.del', + '**/*.bak', + '**/*copy.*', + '**/*copy*.*', + // + ], overrides: [ { // override to ignore no-def for `describe`, `it`, and `expect` diff --git a/002_source/cms/package.json b/002_source/cms/package.json index bad6a2b..47bd08c 100644 --- a/002_source/cms/package.json +++ b/002_source/cms/package.json @@ -117,4 +117,4 @@ "protobufjs" ] } -} \ No newline at end of file +} diff --git a/002_source/cms/src/__tests__/app/_helloworld/page.test.tsx b/002_source/cms/src/__tests__/app/_helloworld/page.test.tsx deleted file mode 100644 index 5c198ca..0000000 --- a/002_source/cms/src/__tests__/app/_helloworld/page.test.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/// -import '@testing-library/jest-dom'; -import { render, screen } from '@testing-library/react'; -import Page from '@/app/_helloworld/page'; - -// Mock the translation hook -jest.mock('react-i18next', () => ({ - useTranslation: () => ({ - t: (key: string) => key, - }), -})); - -describe('Page', () => { - it('renders a heading', () => { - render(); - - const heading = screen.getByRole('heading', { level: 1 }); - - expect(heading).toBeInTheDocument(); - }); -}); diff --git a/002_source/cms/src/__tests__/snapshot.js b/002_source/cms/src/__tests__/snapshot.js deleted file mode 100644 index c070dc2..0000000 --- a/002_source/cms/src/__tests__/snapshot.js +++ /dev/null @@ -1,9 +0,0 @@ -import { render } from '@testing-library/react'; - -// CUT = Component Under Test -import CUT from '../components/_helloworld'; - -it('renders homepage unchanged', () => { - const { container } = render(); - expect(container).toMatchSnapshot(); -}); diff --git a/002_source/cms/src/app/dashboard/connectives/lesson-categories-sample-data.tsx b/002_source/cms/src/app/dashboard/connectives/lesson-categories-sample-data.tsx index 6a815ad..3d72108 100644 --- a/002_source/cms/src/app/dashboard/connectives/lesson-categories-sample-data.tsx +++ b/002_source/cms/src/app/dashboard/connectives/lesson-categories-sample-data.tsx @@ -1,5 +1,5 @@ import { dayjs } from '@/lib/dayjs'; -import { LessonCategory } from '@/components/dashboard/lesson_category/type'; +import type { LessonCategory } from '@/components/dashboard/lesson_category/type'; // import type { LessonCategory } from '@/components/dashboard/lp_categories/type'; diff --git a/002_source/cms/src/app/dashboard/connectives/view/[cat_id]/page.tsx b/002_source/cms/src/app/dashboard/connectives/view/[cat_id]/page.tsx index 0d7f505..25c80a9 100644 --- a/002_source/cms/src/app/dashboard/connectives/view/[cat_id]/page.tsx +++ b/002_source/cms/src/app/dashboard/connectives/view/[cat_id]/page.tsx @@ -28,7 +28,7 @@ import { PencilSimple as PencilSimpleIcon } from '@phosphor-icons/react/dist/ssr import { Plus as PlusIcon } from '@phosphor-icons/react/dist/ssr/Plus'; import { ShieldWarning as ShieldWarningIcon } from '@phosphor-icons/react/dist/ssr/ShieldWarning'; import { User as UserIcon } from '@phosphor-icons/react/dist/ssr/User'; -import { RecordModel } from 'pocketbase'; +import type { RecordModel } from 'pocketbase'; import { useTranslation } from 'react-i18next'; import { paths } from '@/paths'; @@ -46,7 +46,7 @@ import { Notifications } from '@/components/dashboard/lesson_category/notificati import { Payments } from '@/components/dashboard/lesson_category/payments'; import type { Address } from '@/components/dashboard/lesson_category/shipping-address'; import { ShippingAddress } from '@/components/dashboard/lesson_category/shipping-address'; -import { LessonCategory } from '@/components/dashboard/lesson_category/type'; +import type { LessonCategory } from '@/components/dashboard/lesson_category/type'; // import type { LessonCategory } from '@/components/dashboard/lp_categories/type'; import FormLoading from '@/components/loading'; diff --git a/002_source/cms/src/app/dashboard/cr/categories/list/page.tsx b/002_source/cms/src/app/dashboard/cr/categories/list/page.tsx index c00990e..b3fcdbb 100644 --- a/002_source/cms/src/app/dashboard/cr/categories/list/page.tsx +++ b/002_source/cms/src/app/dashboard/cr/categories/list/page.tsx @@ -90,8 +90,7 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { React.useEffect(() => { if (!isFirstRun.current) { isFirstRun.current = true; - } else { - if (JSON.stringify(listOption) !== JSON.stringify(lastListOption)) { + } else if (JSON.stringify(listOption) !== JSON.stringify(lastListOption)) { // reset page number as tab changes setLastListOption(listOption); setCurrentPage(0); @@ -99,7 +98,6 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { } else { void reloadRows(); } - } }, [currentPage, rowsPerPage, listOption]); React.useEffect(() => { diff --git a/002_source/cms/src/app/dashboard/cr/categories/lp-categories-sample-data.tsx b/002_source/cms/src/app/dashboard/cr/categories/lp-categories-sample-data.tsx index 0c1aa79..8054df7 100644 --- a/002_source/cms/src/app/dashboard/cr/categories/lp-categories-sample-data.tsx +++ b/002_source/cms/src/app/dashboard/cr/categories/lp-categories-sample-data.tsx @@ -1,5 +1,5 @@ import { dayjs } from '@/lib/dayjs'; -import { LessonCategory } from '@/components/dashboard/lesson_category/type'; +import type { LessonCategory } from '@/components/dashboard/lesson_category/type'; export const LpCategoriesSampleData = [ { diff --git a/002_source/cms/src/app/dashboard/cr/categories/view/[cat_id]/BasicDetailCard.tsx b/002_source/cms/src/app/dashboard/cr/categories/view/[cat_id]/BasicDetailCard.tsx index e79c927..8012466 100644 --- a/002_source/cms/src/app/dashboard/cr/categories/view/[cat_id]/BasicDetailCard.tsx +++ b/002_source/cms/src/app/dashboard/cr/categories/view/[cat_id]/BasicDetailCard.tsx @@ -13,7 +13,7 @@ import { useTranslation } from 'react-i18next'; import { PropertyItem } from '@/components/core/property-item'; import { PropertyList } from '@/components/core/property-list'; -import { CrCategory } from '@/components/dashboard/cr/categories/type'; +import type { CrCategory } from '@/components/dashboard/cr/categories/type'; export default function BasicDetailCard({ lpModel: model, diff --git a/002_source/cms/src/app/dashboard/cr/questions/[cat_id]/BasicDetailCard.tsx b/002_source/cms/src/app/dashboard/cr/questions/[cat_id]/BasicDetailCard.tsx index 6683056..3a1a777 100644 --- a/002_source/cms/src/app/dashboard/cr/questions/[cat_id]/BasicDetailCard.tsx +++ b/002_source/cms/src/app/dashboard/cr/questions/[cat_id]/BasicDetailCard.tsx @@ -13,7 +13,7 @@ import { useTranslation } from 'react-i18next'; import { PropertyItem } from '@/components/core/property-item'; import { PropertyList } from '@/components/core/property-list'; -import { LpCategory } from '@/components/dashboard/lp/categories/type'; +import type { LpCategory } from '@/components/dashboard/lp/categories/type'; export default function BasicDetailCard({ lpModel: model, diff --git a/002_source/cms/src/app/dashboard/cr/questions/[cat_id]/TitleCard.tsx b/002_source/cms/src/app/dashboard/cr/questions/[cat_id]/TitleCard.tsx index 553cbd0..5dfa618 100644 --- a/002_source/cms/src/app/dashboard/cr/questions/[cat_id]/TitleCard.tsx +++ b/002_source/cms/src/app/dashboard/cr/questions/[cat_id]/TitleCard.tsx @@ -11,7 +11,7 @@ import { CheckCircle as CheckCircleIcon } from '@phosphor-icons/react/dist/ssr/C import { useTranslation } from 'react-i18next'; import getImageUrlFromFile from '@/lib/get-image-url-from-file.ts'; -import { LpCategory } from '@/components/dashboard/lp/categories/type'; +import type { LpCategory } from '@/components/dashboard/lp/categories/type'; export default function SampleTitleCard({ lpModel }: { lpModel: LpCategory }): React.JSX.Element { const { t } = useTranslation(); diff --git a/002_source/cms/src/app/dashboard/cr/questions/cr-categories-sample-data.tsx b/002_source/cms/src/app/dashboard/cr/questions/cr-categories-sample-data.tsx index 6a9b57e..c85443e 100644 --- a/002_source/cms/src/app/dashboard/cr/questions/cr-categories-sample-data.tsx +++ b/002_source/cms/src/app/dashboard/cr/questions/cr-categories-sample-data.tsx @@ -1,5 +1,5 @@ import { dayjs } from '@/lib/dayjs'; -import { LessonCategory } from '@/components/dashboard/lesson_category/type'; +import type { LessonCategory } from '@/components/dashboard/lesson_category/type'; export const CrCategoriesSampleData = [ { diff --git a/002_source/cms/src/app/dashboard/lesson_categories/lesson-categories-sample-data.tsx b/002_source/cms/src/app/dashboard/lesson_categories/lesson-categories-sample-data.tsx index 6a815ad..3d72108 100644 --- a/002_source/cms/src/app/dashboard/lesson_categories/lesson-categories-sample-data.tsx +++ b/002_source/cms/src/app/dashboard/lesson_categories/lesson-categories-sample-data.tsx @@ -1,5 +1,5 @@ import { dayjs } from '@/lib/dayjs'; -import { LessonCategory } from '@/components/dashboard/lesson_category/type'; +import type { LessonCategory } from '@/components/dashboard/lesson_category/type'; // import type { LessonCategory } from '@/components/dashboard/lp_categories/type'; diff --git a/002_source/cms/src/app/dashboard/lesson_types/lesson-types-data.tsx b/002_source/cms/src/app/dashboard/lesson_types/lesson-types-data.tsx index 8a6d02d..16be07b 100644 --- a/002_source/cms/src/app/dashboard/lesson_types/lesson-types-data.tsx +++ b/002_source/cms/src/app/dashboard/lesson_types/lesson-types-data.tsx @@ -1,5 +1,5 @@ import { dayjs } from '@/lib/dayjs'; -import { LessonType } from '@/components/dashboard/lesson_type/lesson-type'; +import type { LessonType } from '@/components/dashboard/lesson_type/lesson-type'; // import type { LessonType } from '@/components/dashboard/lesson_type/ILessonType'; diff --git a/002_source/cms/src/app/dashboard/lesson_types/lesson-types-sample-data.tsx b/002_source/cms/src/app/dashboard/lesson_types/lesson-types-sample-data.tsx index 63b5239..92d609b 100644 --- a/002_source/cms/src/app/dashboard/lesson_types/lesson-types-sample-data.tsx +++ b/002_source/cms/src/app/dashboard/lesson_types/lesson-types-sample-data.tsx @@ -1,5 +1,5 @@ import { dayjs } from '@/lib/dayjs'; -import { LessonType } from '@/components/dashboard/lesson_type/lesson-type'; +import type { LessonType } from '@/components/dashboard/lesson_type/lesson-type'; // import type { LessonType } from '@/components/dashboard/lesson_type/ILessonType'; diff --git a/002_source/cms/src/app/dashboard/lp/categories/list/page.tsx b/002_source/cms/src/app/dashboard/lp/categories/list/page.tsx index 82e2355..164a9f1 100644 --- a/002_source/cms/src/app/dashboard/lp/categories/list/page.tsx +++ b/002_source/cms/src/app/dashboard/lp/categories/list/page.tsx @@ -88,8 +88,7 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { React.useEffect(() => { if (!isFirstRun.current) { isFirstRun.current = true; - } else { - if (JSON.stringify(listOption) !== JSON.stringify(lastListOption)) { + } else if (JSON.stringify(listOption) !== JSON.stringify(lastListOption)) { // reset page number as tab changes setLastListOption(listOption); setCurrentPage(0); @@ -97,7 +96,6 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { } else { void reloadRows(); } - } }, [currentPage, rowsPerPage, listOption]); React.useEffect(() => { diff --git a/002_source/cms/src/app/dashboard/lp/categories/lp-categories-sample-data.tsx b/002_source/cms/src/app/dashboard/lp/categories/lp-categories-sample-data.tsx index 0c1aa79..8054df7 100644 --- a/002_source/cms/src/app/dashboard/lp/categories/lp-categories-sample-data.tsx +++ b/002_source/cms/src/app/dashboard/lp/categories/lp-categories-sample-data.tsx @@ -1,5 +1,5 @@ import { dayjs } from '@/lib/dayjs'; -import { LessonCategory } from '@/components/dashboard/lesson_category/type'; +import type { LessonCategory } from '@/components/dashboard/lesson_category/type'; export const LpCategoriesSampleData = [ { diff --git a/002_source/cms/src/app/dashboard/lp/categories/view/[cat_id]/BasicDetailCard.tsx b/002_source/cms/src/app/dashboard/lp/categories/view/[cat_id]/BasicDetailCard.tsx index 6683056..3a1a777 100644 --- a/002_source/cms/src/app/dashboard/lp/categories/view/[cat_id]/BasicDetailCard.tsx +++ b/002_source/cms/src/app/dashboard/lp/categories/view/[cat_id]/BasicDetailCard.tsx @@ -13,7 +13,7 @@ import { useTranslation } from 'react-i18next'; import { PropertyItem } from '@/components/core/property-item'; import { PropertyList } from '@/components/core/property-list'; -import { LpCategory } from '@/components/dashboard/lp/categories/type'; +import type { LpCategory } from '@/components/dashboard/lp/categories/type'; export default function BasicDetailCard({ lpModel: model, diff --git a/002_source/cms/src/app/dashboard/lp/questions/list/page.tsx b/002_source/cms/src/app/dashboard/lp/questions/list/page.tsx index 062b71d..b6ce73f 100644 --- a/002_source/cms/src/app/dashboard/lp/questions/list/page.tsx +++ b/002_source/cms/src/app/dashboard/lp/questions/list/page.tsx @@ -88,8 +88,7 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { React.useEffect(() => { if (!isFirstRun.current) { isFirstRun.current = true; - } else { - if (JSON.stringify(listOption) !== JSON.stringify(lastListOption)) { + } else if (JSON.stringify(listOption) !== JSON.stringify(lastListOption)) { // reset page number as tab changes setLastListOption(listOption); setCurrentPage(0); @@ -97,7 +96,6 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { } else { void reloadRows(); } - } }, [currentPage, rowsPerPage, listOption]); React.useEffect(() => { diff --git a/002_source/cms/src/app/dashboard/lp/questions/lp-categories-sample-data.tsx b/002_source/cms/src/app/dashboard/lp/questions/lp-categories-sample-data.tsx index 0c1aa79..8054df7 100644 --- a/002_source/cms/src/app/dashboard/lp/questions/lp-categories-sample-data.tsx +++ b/002_source/cms/src/app/dashboard/lp/questions/lp-categories-sample-data.tsx @@ -1,5 +1,5 @@ import { dayjs } from '@/lib/dayjs'; -import { LessonCategory } from '@/components/dashboard/lesson_category/type'; +import type { LessonCategory } from '@/components/dashboard/lesson_category/type'; export const LpCategoriesSampleData = [ { diff --git a/002_source/cms/src/app/dashboard/lp/questions/view/[cat_id]/BasicDetailCard.tsx b/002_source/cms/src/app/dashboard/lp/questions/view/[cat_id]/BasicDetailCard.tsx index 6683056..3a1a777 100644 --- a/002_source/cms/src/app/dashboard/lp/questions/view/[cat_id]/BasicDetailCard.tsx +++ b/002_source/cms/src/app/dashboard/lp/questions/view/[cat_id]/BasicDetailCard.tsx @@ -13,7 +13,7 @@ import { useTranslation } from 'react-i18next'; import { PropertyItem } from '@/components/core/property-item'; import { PropertyList } from '@/components/core/property-list'; -import { LpCategory } from '@/components/dashboard/lp/categories/type'; +import type { LpCategory } from '@/components/dashboard/lp/categories/type'; export default function BasicDetailCard({ lpModel: model, diff --git a/002_source/cms/src/app/dashboard/lp/questions/view/[cat_id]/TitleCard.tsx b/002_source/cms/src/app/dashboard/lp/questions/view/[cat_id]/TitleCard.tsx index 553cbd0..5dfa618 100644 --- a/002_source/cms/src/app/dashboard/lp/questions/view/[cat_id]/TitleCard.tsx +++ b/002_source/cms/src/app/dashboard/lp/questions/view/[cat_id]/TitleCard.tsx @@ -11,7 +11,7 @@ import { CheckCircle as CheckCircleIcon } from '@phosphor-icons/react/dist/ssr/C import { useTranslation } from 'react-i18next'; import getImageUrlFromFile from '@/lib/get-image-url-from-file.ts'; -import { LpCategory } from '@/components/dashboard/lp/categories/type'; +import type { LpCategory } from '@/components/dashboard/lp/categories/type'; export default function SampleTitleCard({ lpModel }: { lpModel: LpCategory }): React.JSX.Element { const { t } = useTranslation(); diff --git a/002_source/cms/src/app/dashboard/mf/categories/list/page.tsx b/002_source/cms/src/app/dashboard/mf/categories/list/page.tsx index 170606f..eff37ea 100644 --- a/002_source/cms/src/app/dashboard/mf/categories/list/page.tsx +++ b/002_source/cms/src/app/dashboard/mf/categories/list/page.tsx @@ -86,8 +86,7 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { React.useEffect(() => { if (!isFirstRun.current) { isFirstRun.current = true; - } else { - if (JSON.stringify(listOption) !== JSON.stringify(lastListOption)) { + } else if (JSON.stringify(listOption) !== JSON.stringify(lastListOption)) { // reset page number as tab changes setLastListOption(listOption); setCurrentPage(0); @@ -95,7 +94,6 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { } else { void reloadRows(); } - } }, [currentPage, rowsPerPage, listOption]); React.useEffect(() => { diff --git a/002_source/cms/src/app/dashboard/mf/categories/lp-categories-sample-data.tsx b/002_source/cms/src/app/dashboard/mf/categories/lp-categories-sample-data.tsx index 0c1aa79..8054df7 100644 --- a/002_source/cms/src/app/dashboard/mf/categories/lp-categories-sample-data.tsx +++ b/002_source/cms/src/app/dashboard/mf/categories/lp-categories-sample-data.tsx @@ -1,5 +1,5 @@ import { dayjs } from '@/lib/dayjs'; -import { LessonCategory } from '@/components/dashboard/lesson_category/type'; +import type { LessonCategory } from '@/components/dashboard/lesson_category/type'; export const LpCategoriesSampleData = [ { diff --git a/002_source/cms/src/app/dashboard/mf/questions/list/page.tsx b/002_source/cms/src/app/dashboard/mf/questions/list/page.tsx index aded80f..aa263e1 100644 --- a/002_source/cms/src/app/dashboard/mf/questions/list/page.tsx +++ b/002_source/cms/src/app/dashboard/mf/questions/list/page.tsx @@ -86,8 +86,7 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { React.useEffect(() => { if (!isFirstRun.current) { isFirstRun.current = true; - } else { - if (JSON.stringify(listOption) !== JSON.stringify(lastListOption)) { + } else if (JSON.stringify(listOption) !== JSON.stringify(lastListOption)) { // reset page number as tab changes setLastListOption(listOption); setCurrentPage(0); @@ -95,7 +94,6 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { } else { void reloadRows(); } - } }, [currentPage, rowsPerPage, listOption]); React.useEffect(() => { diff --git a/002_source/cms/src/app/dashboard/mf/questions/lp-categories-sample-data.tsx b/002_source/cms/src/app/dashboard/mf/questions/lp-categories-sample-data.tsx index 0c1aa79..8054df7 100644 --- a/002_source/cms/src/app/dashboard/mf/questions/lp-categories-sample-data.tsx +++ b/002_source/cms/src/app/dashboard/mf/questions/lp-categories-sample-data.tsx @@ -1,5 +1,5 @@ import { dayjs } from '@/lib/dayjs'; -import { LessonCategory } from '@/components/dashboard/lesson_category/type'; +import type { LessonCategory } from '@/components/dashboard/lesson_category/type'; export const LpCategoriesSampleData = [ { diff --git a/002_source/cms/src/app/dashboard/mf/questions/view/[cat_id]/BasicDetailCard.tsx b/002_source/cms/src/app/dashboard/mf/questions/view/[cat_id]/BasicDetailCard.tsx index 9c013b8..1e885c3 100644 --- a/002_source/cms/src/app/dashboard/mf/questions/view/[cat_id]/BasicDetailCard.tsx +++ b/002_source/cms/src/app/dashboard/mf/questions/view/[cat_id]/BasicDetailCard.tsx @@ -13,7 +13,7 @@ import { useTranslation } from 'react-i18next'; import { PropertyItem } from '@/components/core/property-item'; import { PropertyList } from '@/components/core/property-list'; -import { MfCategory } from '@/components/dashboard/mf/categories/type'; +import type { MfCategory } from '@/components/dashboard/mf/categories/type'; export default function BasicDetailCard({ lpModel: model, diff --git a/002_source/cms/src/app/dashboard/user_metas/list/page.tsx b/002_source/cms/src/app/dashboard/user_metas/list/page.tsx index c0d1c07..65cf321 100644 --- a/002_source/cms/src/app/dashboard/user_metas/list/page.tsx +++ b/002_source/cms/src/app/dashboard/user_metas/list/page.tsx @@ -96,7 +96,7 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { }, [currentPage, rowsPerPage, listOption]); React.useEffect(() => { - let tempFilter = []; + const tempFilter = []; let tempSortDir = ''; if (state) { diff --git a/002_source/cms/src/app/dashboard/vocabularies/lesson-categories-sample-data.tsx b/002_source/cms/src/app/dashboard/vocabularies/lesson-categories-sample-data.tsx index 6a815ad..3d72108 100644 --- a/002_source/cms/src/app/dashboard/vocabularies/lesson-categories-sample-data.tsx +++ b/002_source/cms/src/app/dashboard/vocabularies/lesson-categories-sample-data.tsx @@ -1,5 +1,5 @@ import { dayjs } from '@/lib/dayjs'; -import { LessonCategory } from '@/components/dashboard/lesson_category/type'; +import type { LessonCategory } from '@/components/dashboard/lesson_category/type'; // import type { LessonCategory } from '@/components/dashboard/lp_categories/type'; diff --git a/002_source/cms/src/components/auth/custom/sign-in-form/index.tsx b/002_source/cms/src/components/auth/custom/sign-in-form/index.tsx index 39df856..71fb853 100644 --- a/002_source/cms/src/components/auth/custom/sign-in-form/index.tsx +++ b/002_source/cms/src/components/auth/custom/sign-in-form/index.tsx @@ -31,7 +31,7 @@ import { useUser } from '@/hooks/use-user'; import { DynamicLogo } from '@/components/core/logo'; import { toast } from '@/components/core/toaster'; -import { OAuthProvider } from '../OAuthProvider'; +import type { OAuthProvider } from '../OAuthProvider'; import { oAuthProviders } from '../oAuthProviders'; // interface OAuthProvider { @@ -146,7 +146,7 @@ export function SignInForm(): React.JSX.Element { {oAuthProviders.map( (provider): React.JSX.Element => ( diff --git a/002_source/cms/src/components/auth/custom/sign-up-form/index.tsx b/002_source/cms/src/components/auth/custom/sign-up-form/index.tsx index 694da64..b096069 100644 --- a/002_source/cms/src/components/auth/custom/sign-up-form/index.tsx +++ b/002_source/cms/src/components/auth/custom/sign-up-form/index.tsx @@ -195,7 +195,7 @@ export function SignUpForm(): React.JSX.Element { {t('email-address')}: diff --git a/002_source/cms/src/components/dashboard/connective/_constants.ts b/002_source/cms/src/components/dashboard/connective/_constants.ts index 1458199..7967796 100644 --- a/002_source/cms/src/components/dashboard/connective/_constants.ts +++ b/002_source/cms/src/components/dashboard/connective/_constants.ts @@ -1,6 +1,6 @@ import { dayjs } from '@/lib/dayjs'; -import { CreateForm, LessonCategory } from './type'; +import type { CreateForm, LessonCategory } from './type'; // import type { CreateForm, LessonCategory } from '../lp_categories/type'; diff --git a/002_source/cms/src/components/dashboard/connective/lesson-categories-filters.tsx b/002_source/cms/src/components/dashboard/connective/lesson-categories-filters.tsx index ec387a5..7d4a5df 100644 --- a/002_source/cms/src/components/dashboard/connective/lesson-categories-filters.tsx +++ b/002_source/cms/src/components/dashboard/connective/lesson-categories-filters.tsx @@ -26,7 +26,7 @@ import { Option } from '@/components/core/option'; // import { LessonCategory } from '../lp_categories/type'; import { useLessonCategoriesSelection } from './lesson-categories-selection-context'; -import { LessonCategory } from './type'; +import type { LessonCategory } from './type'; export interface Filters { email?: string; diff --git a/002_source/cms/src/components/dashboard/connective/lesson-categories-selection-context.tsx b/002_source/cms/src/components/dashboard/connective/lesson-categories-selection-context.tsx index 693e000..180e14b 100644 --- a/002_source/cms/src/components/dashboard/connective/lesson-categories-selection-context.tsx +++ b/002_source/cms/src/components/dashboard/connective/lesson-categories-selection-context.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { useSelection } from '@/hooks/use-selection'; import type { Selection } from '@/hooks/use-selection'; -import { LessonCategory } from './type'; +import type { LessonCategory } from './type'; // import type { LessonCategory } from '../lp_categories/type'; diff --git a/002_source/cms/src/components/dashboard/connective/lesson-categories-table.tsx b/002_source/cms/src/components/dashboard/connective/lesson-categories-table.tsx index f90667a..bc9d5e5 100644 --- a/002_source/cms/src/components/dashboard/connective/lesson-categories-table.tsx +++ b/002_source/cms/src/components/dashboard/connective/lesson-categories-table.tsx @@ -99,7 +99,7 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef { - // eslint-disable-next-line react-hooks/rules-of-hooks + const mapping = { active: { diff --git a/002_source/cms/src/components/dashboard/cr/categories/_constants.ts b/002_source/cms/src/components/dashboard/cr/categories/_constants.ts index d530c06..9c82fd5 100644 --- a/002_source/cms/src/components/dashboard/cr/categories/_constants.ts +++ b/002_source/cms/src/components/dashboard/cr/categories/_constants.ts @@ -1,6 +1,7 @@ import { dayjs } from '@/lib/dayjs'; -import { CrCategory, CreateFormProps } from './type'; +import type { CrCategory} from './type'; +import { CreateFormProps } from './type'; export const defaultCrCategory: CrCategory = { isEmpty: false, diff --git a/002_source/cms/src/components/dashboard/cr/categories/cr-categories-selection-context.tsx b/002_source/cms/src/components/dashboard/cr/categories/cr-categories-selection-context.tsx index fbc2620..2f14530 100644 --- a/002_source/cms/src/components/dashboard/cr/categories/cr-categories-selection-context.tsx +++ b/002_source/cms/src/components/dashboard/cr/categories/cr-categories-selection-context.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { useSelection } from '@/hooks/use-selection'; import type { Selection } from '@/hooks/use-selection'; -import { CrCategory } from './type'; +import type { CrCategory } from './type'; function noop(): void { return undefined; diff --git a/002_source/cms/src/components/dashboard/cr/categories/cr-categories-table.tsx b/002_source/cms/src/components/dashboard/cr/categories/cr-categories-table.tsx index 1c342f4..2d140ff 100644 --- a/002_source/cms/src/components/dashboard/cr/categories/cr-categories-table.tsx +++ b/002_source/cms/src/components/dashboard/cr/categories/cr-categories-table.tsx @@ -97,7 +97,7 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef { - // eslint-disable-next-line react-hooks/rules-of-hooks + const mapping = { active: { diff --git a/002_source/cms/src/components/dashboard/cr/questions/_constants.ts b/002_source/cms/src/components/dashboard/cr/questions/_constants.ts index 4c6d940..2f595ee 100644 --- a/002_source/cms/src/components/dashboard/cr/questions/_constants.ts +++ b/002_source/cms/src/components/dashboard/cr/questions/_constants.ts @@ -1,6 +1,7 @@ import { dayjs } from '@/lib/dayjs'; -import { CreateFormProps, CrQuestion } from './type'; +import type { CrQuestion } from './type'; +import { CreateFormProps } from './type'; export const defaultCrQuestion: CrQuestion = { isEmpty: false, diff --git a/002_source/cms/src/components/dashboard/cr/questions/cr-questions-filters.tsx b/002_source/cms/src/components/dashboard/cr/questions/cr-questions-filters.tsx index 9822163..6583fcf 100644 --- a/002_source/cms/src/components/dashboard/cr/questions/cr-questions-filters.tsx +++ b/002_source/cms/src/components/dashboard/cr/questions/cr-questions-filters.tsx @@ -24,7 +24,7 @@ import { FilterButton, FilterPopover, useFilterContext } from '@/components/core import { Option } from '@/components/core/option'; import { useCrQuestionsSelection } from './cr-questions-selection-context'; -import { CrQuestion } from './type'; +import type { CrQuestion } from './type'; export interface Filters { email?: string; diff --git a/002_source/cms/src/components/dashboard/cr/questions/cr-questions-table.tsx b/002_source/cms/src/components/dashboard/cr/questions/cr-questions-table.tsx index 12cb058..12e28af 100644 --- a/002_source/cms/src/components/dashboard/cr/questions/cr-questions-table.tsx +++ b/002_source/cms/src/components/dashboard/cr/questions/cr-questions-table.tsx @@ -97,7 +97,7 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef { - // eslint-disable-next-line react-hooks/rules-of-hooks + const mapping = { active: { diff --git a/002_source/cms/src/components/dashboard/customer/customers-table.tsx b/002_source/cms/src/components/dashboard/customer/customers-table.tsx index f064433..c490f28 100644 --- a/002_source/cms/src/components/dashboard/customer/customers-table.tsx +++ b/002_source/cms/src/components/dashboard/customer/customers-table.tsx @@ -89,7 +89,7 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef { - // eslint-disable-next-line react-hooks/rules-of-hooks + const mapping = { active: { diff --git a/002_source/cms/src/components/dashboard/error/index.tsx b/002_source/cms/src/components/dashboard/error/index.tsx index 75b2ee2..6aa3eb8 100644 --- a/002_source/cms/src/components/dashboard/error/index.tsx +++ b/002_source/cms/src/components/dashboard/error/index.tsx @@ -81,7 +81,7 @@ function ErrorDisplay({ message, code, details, severity = 'error' }: PropsError {formattedMessage} - {details && } + {details ? : null} ); diff --git a/002_source/cms/src/components/dashboard/layout/notifications-popover/index.tsx b/002_source/cms/src/components/dashboard/layout/notifications-popover/index.tsx index 5fd1a8e..6c94914 100644 --- a/002_source/cms/src/components/dashboard/layout/notifications-popover/index.tsx +++ b/002_source/cms/src/components/dashboard/layout/notifications-popover/index.tsx @@ -133,7 +133,7 @@ export function NotificationsPopover({ {t('list-is-empty')} diff --git a/002_source/cms/src/components/dashboard/layout/notifications-popover/sample-notifications.tsx b/002_source/cms/src/components/dashboard/layout/notifications-popover/sample-notifications.tsx index f2b9615..3133184 100644 --- a/002_source/cms/src/components/dashboard/layout/notifications-popover/sample-notifications.tsx +++ b/002_source/cms/src/components/dashboard/layout/notifications-popover/sample-notifications.tsx @@ -1,5 +1,5 @@ 'use client'; -import { Notification } from '@/db/Notifications/type'; +import type { Notification } from '@/db/Notifications/type'; import { dayjs } from '@/lib/dayjs'; // import type { Notification } from './type.d.tsx'; diff --git a/002_source/cms/src/components/dashboard/layout/vertical/main-nav/notifications-button.tsx b/002_source/cms/src/components/dashboard/layout/vertical/main-nav/notifications-button.tsx index ef87378..30aa64f 100644 --- a/002_source/cms/src/components/dashboard/layout/vertical/main-nav/notifications-button.tsx +++ b/002_source/cms/src/components/dashboard/layout/vertical/main-nav/notifications-button.tsx @@ -14,7 +14,7 @@ import { logger } from '@/lib/default-logger'; import { toast } from '@/components/core/toaster'; import { MarkOneAsRead } from '@/db/Notifications/mark-one-as-read'; import { getUnreadNotificationsByUserId } from '@/db/Notifications/GetUnreadNotificationsByUserId'; -import { Notification } from '@/db/Notifications/type'; +import type { Notification } from '@/db/Notifications/type'; import { useUser } from '@/hooks/use-user'; export function NotificationsButton(): React.JSX.Element { diff --git a/002_source/cms/src/components/dashboard/lesson_category/_constants.ts b/002_source/cms/src/components/dashboard/lesson_category/_constants.ts index 1458199..7967796 100644 --- a/002_source/cms/src/components/dashboard/lesson_category/_constants.ts +++ b/002_source/cms/src/components/dashboard/lesson_category/_constants.ts @@ -1,6 +1,6 @@ import { dayjs } from '@/lib/dayjs'; -import { CreateForm, LessonCategory } from './type'; +import type { CreateForm, LessonCategory } from './type'; // import type { CreateForm, LessonCategory } from '../lp_categories/type'; diff --git a/002_source/cms/src/components/dashboard/lesson_category/lesson-categories-filters.tsx b/002_source/cms/src/components/dashboard/lesson_category/lesson-categories-filters.tsx index ec387a5..7d4a5df 100644 --- a/002_source/cms/src/components/dashboard/lesson_category/lesson-categories-filters.tsx +++ b/002_source/cms/src/components/dashboard/lesson_category/lesson-categories-filters.tsx @@ -26,7 +26,7 @@ import { Option } from '@/components/core/option'; // import { LessonCategory } from '../lp_categories/type'; import { useLessonCategoriesSelection } from './lesson-categories-selection-context'; -import { LessonCategory } from './type'; +import type { LessonCategory } from './type'; export interface Filters { email?: string; diff --git a/002_source/cms/src/components/dashboard/lesson_category/lesson-categories-selection-context.tsx b/002_source/cms/src/components/dashboard/lesson_category/lesson-categories-selection-context.tsx index 693e000..180e14b 100644 --- a/002_source/cms/src/components/dashboard/lesson_category/lesson-categories-selection-context.tsx +++ b/002_source/cms/src/components/dashboard/lesson_category/lesson-categories-selection-context.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { useSelection } from '@/hooks/use-selection'; import type { Selection } from '@/hooks/use-selection'; -import { LessonCategory } from './type'; +import type { LessonCategory } from './type'; // import type { LessonCategory } from '../lp_categories/type'; diff --git a/002_source/cms/src/components/dashboard/lesson_category/lesson-categories-table.tsx b/002_source/cms/src/components/dashboard/lesson_category/lesson-categories-table.tsx index f90667a..bc9d5e5 100644 --- a/002_source/cms/src/components/dashboard/lesson_category/lesson-categories-table.tsx +++ b/002_source/cms/src/components/dashboard/lesson_category/lesson-categories-table.tsx @@ -99,7 +99,7 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef { - // eslint-disable-next-line react-hooks/rules-of-hooks + const mapping = { active: { diff --git a/002_source/cms/src/components/dashboard/lesson_type/lesson-type-create-form.tsx b/002_source/cms/src/components/dashboard/lesson_type/lesson-type-create-form.tsx index d5f9dd4..d6e57f2 100644 --- a/002_source/cms/src/components/dashboard/lesson_type/lesson-type-create-form.tsx +++ b/002_source/cms/src/components/dashboard/lesson_type/lesson-type-create-form.tsx @@ -37,7 +37,7 @@ import { pb } from '@/lib/pb'; import { toast } from '@/components/core/toaster'; import { LessonTypeCreateFormDefault } from './_constants'; -import { CreateForm } from './lesson-type'; +import type { CreateForm } from './lesson-type'; const schema = zod.object({ name: zod.string().min(1, 'Name is required').max(255), diff --git a/002_source/cms/src/components/dashboard/lesson_type/lesson-types-selection-context.tsx b/002_source/cms/src/components/dashboard/lesson_type/lesson-types-selection-context.tsx index ae5fd37..a38ffef 100644 --- a/002_source/cms/src/components/dashboard/lesson_type/lesson-types-selection-context.tsx +++ b/002_source/cms/src/components/dashboard/lesson_type/lesson-types-selection-context.tsx @@ -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 './lesson-type'; +import type { LessonType } from './lesson-type'; // import { LessonType } from './ILessonType'; diff --git a/002_source/cms/src/components/dashboard/lp/categories/_constants.ts b/002_source/cms/src/components/dashboard/lp/categories/_constants.ts index 885067e..1e11ac4 100644 --- a/002_source/cms/src/components/dashboard/lp/categories/_constants.ts +++ b/002_source/cms/src/components/dashboard/lp/categories/_constants.ts @@ -1,6 +1,7 @@ import { dayjs } from '@/lib/dayjs'; -import { CreateFormProps, LpCategory } from './type'; +import type { LpCategory } from './type'; +import { CreateFormProps } from './type'; export const defaultLpCategory: LpCategory = { isEmpty: false, diff --git a/002_source/cms/src/components/dashboard/lp/categories/lp-categories-filters.tsx b/002_source/cms/src/components/dashboard/lp/categories/lp-categories-filters.tsx index 7573cc6..ee17903 100644 --- a/002_source/cms/src/components/dashboard/lp/categories/lp-categories-filters.tsx +++ b/002_source/cms/src/components/dashboard/lp/categories/lp-categories-filters.tsx @@ -24,7 +24,7 @@ import { FilterButton, FilterPopover, useFilterContext } from '@/components/core import { Option } from '@/components/core/option'; import { useLpCategoriesSelection } from './lp-categories-selection-context'; -import { LpCategory } from './type'; +import type { LpCategory } from './type'; export interface Filters { email?: string; diff --git a/002_source/cms/src/components/dashboard/lp/categories/lp-categories-selection-context.tsx b/002_source/cms/src/components/dashboard/lp/categories/lp-categories-selection-context.tsx index a6c6502..0f79e68 100644 --- a/002_source/cms/src/components/dashboard/lp/categories/lp-categories-selection-context.tsx +++ b/002_source/cms/src/components/dashboard/lp/categories/lp-categories-selection-context.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { useSelection } from '@/hooks/use-selection'; import type { Selection } from '@/hooks/use-selection'; -import { LpCategory } from './type'; +import type { LpCategory } from './type'; function noop(): void { return undefined; diff --git a/002_source/cms/src/components/dashboard/lp/categories/lp-categories-table.tsx b/002_source/cms/src/components/dashboard/lp/categories/lp-categories-table.tsx index 26034f1..fe09ce3 100644 --- a/002_source/cms/src/components/dashboard/lp/categories/lp-categories-table.tsx +++ b/002_source/cms/src/components/dashboard/lp/categories/lp-categories-table.tsx @@ -97,7 +97,7 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef { - // eslint-disable-next-line react-hooks/rules-of-hooks + const mapping = { active: { diff --git a/002_source/cms/src/components/dashboard/lp/categories/mf-categories-filters.tsx b/002_source/cms/src/components/dashboard/lp/categories/mf-categories-filters.tsx index 7573cc6..ee17903 100644 --- a/002_source/cms/src/components/dashboard/lp/categories/mf-categories-filters.tsx +++ b/002_source/cms/src/components/dashboard/lp/categories/mf-categories-filters.tsx @@ -24,7 +24,7 @@ import { FilterButton, FilterPopover, useFilterContext } from '@/components/core import { Option } from '@/components/core/option'; import { useLpCategoriesSelection } from './lp-categories-selection-context'; -import { LpCategory } from './type'; +import type { LpCategory } from './type'; export interface Filters { email?: string; diff --git a/002_source/cms/src/components/dashboard/lp/categories/mf-categories-selection-context.tsx b/002_source/cms/src/components/dashboard/lp/categories/mf-categories-selection-context.tsx index a6c6502..0f79e68 100644 --- a/002_source/cms/src/components/dashboard/lp/categories/mf-categories-selection-context.tsx +++ b/002_source/cms/src/components/dashboard/lp/categories/mf-categories-selection-context.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { useSelection } from '@/hooks/use-selection'; import type { Selection } from '@/hooks/use-selection'; -import { LpCategory } from './type'; +import type { LpCategory } from './type'; function noop(): void { return undefined; diff --git a/002_source/cms/src/components/dashboard/lp/categories/mf-categories-table.tsx b/002_source/cms/src/components/dashboard/lp/categories/mf-categories-table.tsx index 26034f1..fe09ce3 100644 --- a/002_source/cms/src/components/dashboard/lp/categories/mf-categories-table.tsx +++ b/002_source/cms/src/components/dashboard/lp/categories/mf-categories-table.tsx @@ -97,7 +97,7 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef { - // eslint-disable-next-line react-hooks/rules-of-hooks + const mapping = { active: { diff --git a/002_source/cms/src/components/dashboard/lp/questions/_constants.ts b/002_source/cms/src/components/dashboard/lp/questions/_constants.ts index 95a4d17..894d497 100644 --- a/002_source/cms/src/components/dashboard/lp/questions/_constants.ts +++ b/002_source/cms/src/components/dashboard/lp/questions/_constants.ts @@ -1,6 +1,7 @@ import { dayjs } from '@/lib/dayjs'; -import { CreateFormProps, LpQuestion } from './type'; +import type { LpQuestion } from './type'; +import { CreateFormProps } from './type'; export const defaultLpQuestion: LpQuestion = { isEmpty: false, diff --git a/002_source/cms/src/components/dashboard/lp/questions/lp-questions-filters.tsx b/002_source/cms/src/components/dashboard/lp/questions/lp-questions-filters.tsx index d5b5486..3fa2cb0 100644 --- a/002_source/cms/src/components/dashboard/lp/questions/lp-questions-filters.tsx +++ b/002_source/cms/src/components/dashboard/lp/questions/lp-questions-filters.tsx @@ -24,7 +24,7 @@ import { FilterButton, FilterPopover, useFilterContext } from '@/components/core import { Option } from '@/components/core/option'; import { useLpQuestionsSelection } from './lp-questions-selection-context'; -import { LpQuestion } from './type'; +import type { LpQuestion } from './type'; export interface Filters { email?: string; diff --git a/002_source/cms/src/components/dashboard/lp/questions/lp-questions-table.tsx b/002_source/cms/src/components/dashboard/lp/questions/lp-questions-table.tsx index 319ff9c..d344405 100644 --- a/002_source/cms/src/components/dashboard/lp/questions/lp-questions-table.tsx +++ b/002_source/cms/src/components/dashboard/lp/questions/lp-questions-table.tsx @@ -97,7 +97,7 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef { - // eslint-disable-next-line react-hooks/rules-of-hooks + const mapping = { active: { diff --git a/002_source/cms/src/components/dashboard/mf/categories/_constants.ts b/002_source/cms/src/components/dashboard/mf/categories/_constants.ts index 23fb774..ea7990a 100644 --- a/002_source/cms/src/components/dashboard/mf/categories/_constants.ts +++ b/002_source/cms/src/components/dashboard/mf/categories/_constants.ts @@ -1,6 +1,7 @@ import { dayjs } from '@/lib/dayjs'; -import { CreateFormProps, MfCategory } from './type'; +import type { MfCategory } from './type'; +import { CreateFormProps } from './type'; export const defaultMfCategory: MfCategory = { isEmpty: false, diff --git a/002_source/cms/src/components/dashboard/mf/categories/mf-categories-filters.tsx b/002_source/cms/src/components/dashboard/mf/categories/mf-categories-filters.tsx index f04f0e7..bae040e 100644 --- a/002_source/cms/src/components/dashboard/mf/categories/mf-categories-filters.tsx +++ b/002_source/cms/src/components/dashboard/mf/categories/mf-categories-filters.tsx @@ -24,7 +24,7 @@ import { FilterButton, FilterPopover, useFilterContext } from '@/components/core import { Option } from '@/components/core/option'; import { useMfCategoriesSelection } from './mf-categories-selection-context'; -import { MfCategory } from './type'; +import type { MfCategory } from './type'; export interface Filters { email?: string; diff --git a/002_source/cms/src/components/dashboard/mf/categories/mf-categories-selection-context.tsx b/002_source/cms/src/components/dashboard/mf/categories/mf-categories-selection-context.tsx index 6427133..a1f6a46 100644 --- a/002_source/cms/src/components/dashboard/mf/categories/mf-categories-selection-context.tsx +++ b/002_source/cms/src/components/dashboard/mf/categories/mf-categories-selection-context.tsx @@ -6,7 +6,7 @@ import * as React from 'react'; import { useSelection } from '@/hooks/use-selection'; import type { Selection } from '@/hooks/use-selection'; -import { MfCategory } from './type'; +import type { MfCategory } from './type'; function noop(): void { return undefined; diff --git a/002_source/cms/src/components/dashboard/mf/categories/mf-categories-table.tsx b/002_source/cms/src/components/dashboard/mf/categories/mf-categories-table.tsx index 3cc015c..e72f1e2 100644 --- a/002_source/cms/src/components/dashboard/mf/categories/mf-categories-table.tsx +++ b/002_source/cms/src/components/dashboard/mf/categories/mf-categories-table.tsx @@ -97,7 +97,7 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef { - // eslint-disable-next-line react-hooks/rules-of-hooks + const mapping = { active: { diff --git a/002_source/cms/src/components/dashboard/mf/questions/_constants.ts b/002_source/cms/src/components/dashboard/mf/questions/_constants.ts index 076328c..5c77aed 100644 --- a/002_source/cms/src/components/dashboard/mf/questions/_constants.ts +++ b/002_source/cms/src/components/dashboard/mf/questions/_constants.ts @@ -1,6 +1,7 @@ import { dayjs } from '@/lib/dayjs'; -import { CreateFormProps, MfQuestion } from './type'; +import type { MfQuestion } from './type'; +import { CreateFormProps } from './type'; export const defaultMfQuestion: MfQuestion = { isEmpty: false, diff --git a/002_source/cms/src/components/dashboard/mf/questions/mf-questions-filters.tsx b/002_source/cms/src/components/dashboard/mf/questions/mf-questions-filters.tsx index 49a85f4..29f54be 100644 --- a/002_source/cms/src/components/dashboard/mf/questions/mf-questions-filters.tsx +++ b/002_source/cms/src/components/dashboard/mf/questions/mf-questions-filters.tsx @@ -24,7 +24,7 @@ import { FilterButton, FilterPopover, useFilterContext } from '@/components/core import { Option } from '@/components/core/option'; import { useMfQuestionsSelection } from './mf-questions-selection-context'; -import { MfQuestion } from './type'; +import type { MfQuestion } from './type'; export interface Filters { email?: string; diff --git a/002_source/cms/src/components/dashboard/mf/questions/mf-questions-table.tsx b/002_source/cms/src/components/dashboard/mf/questions/mf-questions-table.tsx index 7202f0a..819e062 100644 --- a/002_source/cms/src/components/dashboard/mf/questions/mf-questions-table.tsx +++ b/002_source/cms/src/components/dashboard/mf/questions/mf-questions-table.tsx @@ -97,7 +97,7 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef { - // eslint-disable-next-line react-hooks/rules-of-hooks + const mapping = { active: { diff --git a/002_source/cms/src/components/dashboard/student/student-create-form.tsx b/002_source/cms/src/components/dashboard/student/student-create-form.tsx index ee5ee3d..eb67aec 100644 --- a/002_source/cms/src/components/dashboard/student/student-create-form.tsx +++ b/002_source/cms/src/components/dashboard/student/student-create-form.tsx @@ -43,7 +43,7 @@ import { base64ToFile, fileToBase64 } from '@/lib/file-to-base64'; import { toast } from '@/components/core/toaster'; // import ErrorDisplay from '../../error'; -import { CreateFormProps } from './type.d'; +import type { CreateFormProps } from './type.d'; // TODO: review schema const schema = zod.object({ diff --git a/002_source/cms/src/components/dashboard/student/students-pagination.tsx b/002_source/cms/src/components/dashboard/student/students-pagination.tsx index 98e17f2..124c45d 100644 --- a/002_source/cms/src/components/dashboard/student/students-pagination.tsx +++ b/002_source/cms/src/components/dashboard/student/students-pagination.tsx @@ -3,9 +3,10 @@ import * as React from 'react'; import TablePagination from '@mui/material/TablePagination'; -function noop(): void { - return undefined; -} +// TODO: remove noop +// function noop(): void { +// return undefined; +// } interface StudentsPaginationProps { count: number; @@ -30,7 +31,7 @@ export function StudentsPagination({ setPage(newPage); }; - const handleChangeRowsPerPage = (event: React.ChangeEvent) => { + const handleChangeRowsPerPage = (event: React.ChangeEvent): void => { setRowsPerPage(parseInt(event.target.value)); // console.log(parseInt(event.target.value)); }; diff --git a/002_source/cms/src/components/dashboard/student/students-table.tsx b/002_source/cms/src/components/dashboard/student/students-table.tsx index 1a5b556..8806116 100644 --- a/002_source/cms/src/components/dashboard/student/students-table.tsx +++ b/002_source/cms/src/components/dashboard/student/students-table.tsx @@ -5,21 +5,17 @@ import RouterLink from 'next/link'; import { LoadingButton } from '@mui/lab'; import Avatar from '@mui/material/Avatar'; import Box from '@mui/material/Box'; -import Button from '@mui/material/Button'; import Chip from '@mui/material/Chip'; -import IconButton from '@mui/material/IconButton'; import LinearProgress from '@mui/material/LinearProgress'; import Link from '@mui/material/Link'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { CheckCircle as CheckCircleIcon } from '@phosphor-icons/react/dist/ssr/CheckCircle'; import { Clock as ClockIcon } from '@phosphor-icons/react/dist/ssr/Clock'; -import { Images as ImagesIcon } from '@phosphor-icons/react/dist/ssr/Images'; import { Minus as MinusIcon } from '@phosphor-icons/react/dist/ssr/Minus'; import { PencilSimple as PencilSimpleIcon } from '@phosphor-icons/react/dist/ssr/PencilSimple'; import { TrashSimple as TrashSimpleIcon } from '@phosphor-icons/react/dist/ssr/TrashSimple'; import { useTranslation } from 'react-i18next'; -import { toast } from 'sonner'; import { paths } from '@/paths'; import { dayjs } from '@/lib/dayjs'; diff --git a/002_source/cms/src/components/dashboard/teacher/confirm-delete-modal.tsx b/002_source/cms/src/components/dashboard/teacher/confirm-delete-modal.tsx index afbb10e..be78618 100644 --- a/002_source/cms/src/components/dashboard/teacher/confirm-delete-modal.tsx +++ b/002_source/cms/src/components/dashboard/teacher/confirm-delete-modal.tsx @@ -1,6 +1,7 @@ 'use client'; import * as React from 'react'; +import { deleteTeacher } from '@/db/Teachers/Delete'; import { LoadingButton } from '@mui/lab'; import { Button, Container, Modal, Paper } from '@mui/material'; import Avatar from '@mui/material/Avatar'; @@ -12,7 +13,6 @@ import { useTranslation } from 'react-i18next'; import { logger } from '@/lib/default-logger'; import { toast } from '@/components/core/toaster'; -import { deleteTeacher } from '@/db/Teachers/Delete'; export default function ConfirmDeleteModal({ open, @@ -105,7 +105,7 @@ export default function ConfirmDeleteModal({ { + onClick={() => { handleUserConfirmDelete(); }} loading={isDeleteing} diff --git a/002_source/cms/src/components/dashboard/teacher/teacher-create-form.tsx b/002_source/cms/src/components/dashboard/teacher/teacher-create-form.tsx index 47204ca..adda8d5 100644 --- a/002_source/cms/src/components/dashboard/teacher/teacher-create-form.tsx +++ b/002_source/cms/src/components/dashboard/teacher/teacher-create-form.tsx @@ -50,7 +50,7 @@ import FormLoading from '@/components/loading'; // import ErrorDisplay from '../../error'; import ErrorDisplay from '../error'; -import { CreateFormProps } from './type.d'; +import type { CreateFormProps } from './type.d'; // TODO: review schema const schema = zod.object({ diff --git a/002_source/cms/src/components/dashboard/teacher/teacher-edit-form.tsx b/002_source/cms/src/components/dashboard/teacher/teacher-edit-form.tsx index 51c8d1a..d22e1d9 100644 --- a/002_source/cms/src/components/dashboard/teacher/teacher-edit-form.tsx +++ b/002_source/cms/src/components/dashboard/teacher/teacher-edit-form.tsx @@ -148,7 +148,7 @@ export function TeacherEditForm(): React.JSX.Element { setIsUpdating(false); } }, - [teacherId, router] + [teacherId, router, t] ); const avatarInputRef = React.useRef(null); @@ -197,7 +197,8 @@ export function TeacherEditForm(): React.JSX.Element { setShowLoading(false); } }, - [reset, setValue] + + [reset, setValue, t] ); React.useEffect(() => { diff --git a/002_source/cms/src/components/dashboard/teacher/teachers-filters.tsx b/002_source/cms/src/components/dashboard/teacher/teachers-filters.tsx index 1288682..530b8a6 100644 --- a/002_source/cms/src/components/dashboard/teacher/teachers-filters.tsx +++ b/002_source/cms/src/components/dashboard/teacher/teachers-filters.tsx @@ -33,6 +33,8 @@ import type { Filters, SortDir, TeachersFiltersProps } from './type.d'; export function TeachersFilters({ filters = {}, sortDir = 'desc', + // TODO: remove fullData + // eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars fullData, // }: TeachersFiltersProps): React.JSX.Element { diff --git a/002_source/cms/src/components/dashboard/teacher/teachers-pagination.tsx b/002_source/cms/src/components/dashboard/teacher/teachers-pagination.tsx index 5aea10d..ec05e27 100644 --- a/002_source/cms/src/components/dashboard/teacher/teachers-pagination.tsx +++ b/002_source/cms/src/components/dashboard/teacher/teachers-pagination.tsx @@ -3,9 +3,10 @@ import * as React from 'react'; import TablePagination from '@mui/material/TablePagination'; -function noop(): void { - return undefined; -} +// TODO: remove noop +// function noop(): void { +// return undefined; +// } interface CustomersPaginationProps { count: number; @@ -30,7 +31,7 @@ export function TeachersPagination({ setPage(newPage); }; - const handleChangeRowsPerPage = (event: React.ChangeEvent) => { + const handleChangeRowsPerPage = (event: React.ChangeEvent): void => { setRowsPerPage(parseInt(event.target.value)); // console.log(parseInt(event.target.value)); }; diff --git a/002_source/cms/src/components/dashboard/user.de/_GUIDELINES.md b/002_source/cms/src/components/dashboard/user.de/_GUIDELINES.md deleted file mode 100644 index 9e5a150..0000000 --- a/002_source/cms/src/components/dashboard/user.de/_GUIDELINES.md +++ /dev/null @@ -1,25 +0,0 @@ -# GUIDELINES & KEY COMPONENTS - -- `_constants.ts` contains the constant for - - - default value (defaultValue) - - empty value (emptyValue) - -- `users-table.tsx` - -- `confirm-delete-modal.tsx` - delete modal component when click delete button on list - - - `users-filters.tsx` - - `users-pagination.tsx` - - `email-filter-popover.tsx` - - `phone-filter-popover.tsx` - - `users-selection-context.tsx` - -- `user-create-form.tsx` - form to create a new user -- `user-edit-form.tsx` - form to edit a existing user - -- `type.d.tsx` - contains type definition - -- `notifications.tsx` - constants used for demonstration -- `payments.tsx` - constants used for demonstration -- `shipping-address.tsx` - constants used for demonstration diff --git a/002_source/cms/src/components/dashboard/user.de/_constants.ts b/002_source/cms/src/components/dashboard/user.de/_constants.ts deleted file mode 100644 index 62097e2..0000000 --- a/002_source/cms/src/components/dashboard/user.de/_constants.ts +++ /dev/null @@ -1,21 +0,0 @@ -// RULES: -// default variable value for customer -// empty valur for customer - -import { dayjs } from '@/lib/dayjs'; -import type { User } from './type.d'; - -export const defaultUser: User = { - id: '', - name: '', - avatar: undefined, - email: '', - phone: undefined, - quota: 0, - status: 'pending', - createdAt: dayjs().toDate(), -}; - -export const emptyLpCategory: User = { - ...defaultUser, -}; diff --git a/002_source/cms/src/components/dashboard/user.de/confirm-delete-modal.tsx b/002_source/cms/src/components/dashboard/user.de/confirm-delete-modal.tsx deleted file mode 100644 index 3a4f946..0000000 --- a/002_source/cms/src/components/dashboard/user.de/confirm-delete-modal.tsx +++ /dev/null @@ -1,124 +0,0 @@ -'use client'; - -import * as React from 'react'; -import { LoadingButton } from '@mui/lab'; -import { Button, Container, Modal, Paper } from '@mui/material'; -import Avatar from '@mui/material/Avatar'; -import Box from '@mui/material/Box'; -import Stack from '@mui/material/Stack'; -import Typography from '@mui/material/Typography'; -import { Note as NoteIcon } from '@phosphor-icons/react/dist/ssr/Note'; -import { useTranslation } from 'react-i18next'; - -import { logger } from '@/lib/default-logger'; -import { toast } from '@/components/core/toaster'; -import { deleteUser } from '@/db/Users/Delete'; - -export default function ConfirmDeleteModal({ - open, - setOpen, - idToDelete, - reloadRows, -}: { - open: boolean; - setOpen: (b: boolean) => void; - idToDelete: string; - reloadRows: () => void; -}): React.JSX.Element { - const { t } = useTranslation(); - - // const handleClose = () => setOpen(false); - function handleClose(): void { - setOpen(false); - } - - const [isDeleteing, setIsDeleteing] = React.useState(false); - const style = { - position: 'absolute', - top: '50%', - left: '50%', - transform: 'translate(-50%, -50%)', - }; - - function handleUserConfirmDelete(): void { - if (idToDelete) { - setIsDeleteing(true); - - // RULES: delete - deleteUser(idToDelete) - .then(() => { - reloadRows(); - handleClose(); - toast(t('delete.success')); - }) - .catch((err) => { - // console.error(err) - logger.error(err); - toast(t('delete.error')); - }) - .finally(() => { - setIsDeleteing(false); - }); - } - } - - return ( -
- - - - - - - - - - - {t('Delete User ?')} - - {t('Are you sure you want to delete this user ?')} - - - - - { - handleUserConfirmDelete(); - }} - loading={isDeleteing} - > - {t('Delete')} - - - - - - - - -
- ); -} diff --git a/002_source/cms/src/components/dashboard/user.de/email-filter-popover.tsx b/002_source/cms/src/components/dashboard/user.de/email-filter-popover.tsx deleted file mode 100644 index 2636af0..0000000 --- a/002_source/cms/src/components/dashboard/user.de/email-filter-popover.tsx +++ /dev/null @@ -1,50 +0,0 @@ -'use client'; - -import * as React from 'react'; - -import Button from '@mui/material/Button'; -import FormControl from '@mui/material/FormControl'; -import OutlinedInput from '@mui/material/OutlinedInput'; - -import { FilterPopover, useFilterContext } from '@/components/core/filter-button'; - -// EmailFilterPopover -> email-filter-popover.tsx -export default function EmailFilterPopover(): React.JSX.Element { - const { anchorEl, onApply, onClose, open, value: initialValue } = useFilterContext(); - const [value, setValue] = React.useState(''); - - React.useEffect(() => { - setValue((initialValue as string | undefined) ?? ''); - }, [initialValue]); - - return ( - - - { - setValue(event.target.value); - }} - onKeyUp={(event) => { - if (event.key === 'Enter') { - onApply(value); - } - }} - value={value} - /> - - - - ); -} diff --git a/002_source/cms/src/components/dashboard/user.de/helloworld.tsx b/002_source/cms/src/components/dashboard/user.de/helloworld.tsx deleted file mode 100644 index 3989cb1..0000000 --- a/002_source/cms/src/components/dashboard/user.de/helloworld.tsx +++ /dev/null @@ -1,3 +0,0 @@ -const helloworld = 'helloworld'; - -export { helloworld }; diff --git a/002_source/cms/src/components/dashboard/user.de/notifications.tsx b/002_source/cms/src/components/dashboard/user.de/notifications.tsx deleted file mode 100644 index a6c16bd..0000000 --- a/002_source/cms/src/components/dashboard/user.de/notifications.tsx +++ /dev/null @@ -1,101 +0,0 @@ -'use client'; - -import * as React from 'react'; -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 CardContent from '@mui/material/CardContent'; -import CardHeader from '@mui/material/CardHeader'; -import Chip from '@mui/material/Chip'; -import Select from '@mui/material/Select'; -import Stack from '@mui/material/Stack'; -import Typography from '@mui/material/Typography'; -import { EnvelopeSimple as EnvelopeSimpleIcon } from '@phosphor-icons/react/dist/ssr/EnvelopeSimple'; - -import { dayjs } from '@/lib/dayjs'; -import { DataTable } from '@/components/core/data-table'; -import type { ColumnDef } from '@/components/core/data-table'; -import { Option } from '@/components/core/option'; - -export interface Notification { - id: string; - type: string; - status: 'delivered' | 'pending' | 'failed'; - createdAt: Date; -} - -const columns = [ - { - formatter: (row): React.JSX.Element => ( - - {row.type} - - ), - name: 'Type', - width: '300px', - }, - { - formatter: (row): React.JSX.Element => { - const mapping = { - delivered: { label: 'Delivered', color: 'success' }, - pending: { label: 'Pending', color: 'warning' }, - failed: { label: 'Failed', color: 'error' }, - } as const; - const { label, color } = mapping[row.status] ?? { label: 'Unknown', color: 'secondary' }; - - return ; - }, - name: 'Status', - width: '200px', - }, - { - formatter: (row): React.JSX.Element => ( - - {dayjs(row.createdAt).format('MMM D, YYYY hh:mm A')} - - ), - name: 'Date', - align: 'right', - }, -] satisfies ColumnDef[]; - -export interface NotificationsProps { - notifications: Notification[]; -} - -export function Notifications({ notifications }: NotificationsProps): React.JSX.Element { - return ( - - - - - } - title="Notifications" - /> - - - - -
- -
-
- - - columns={columns} rows={notifications} /> - - -
-
-
- ); -} diff --git a/002_source/cms/src/components/dashboard/user.de/payments.tsx b/002_source/cms/src/components/dashboard/user.de/payments.tsx deleted file mode 100644 index 0420d32..0000000 --- a/002_source/cms/src/components/dashboard/user.de/payments.tsx +++ /dev/null @@ -1,138 +0,0 @@ -'use client'; - -import * as React from 'react'; -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 CardContent from '@mui/material/CardContent'; -import CardHeader from '@mui/material/CardHeader'; -import Chip from '@mui/material/Chip'; -import Divider from '@mui/material/Divider'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import Typography from '@mui/material/Typography'; -import { Plus as PlusIcon } from '@phosphor-icons/react/dist/ssr/Plus'; -import { ShoppingCartSimple as ShoppingCartSimpleIcon } from '@phosphor-icons/react/dist/ssr/ShoppingCartSimple'; - -import { dayjs } from '@/lib/dayjs'; -import type { ColumnDef } from '@/components/core/data-table'; -import { DataTable } from '@/components/core/data-table'; - -export interface Payment { - currency: string; - amount: number; - invoiceId: string; - status: 'pending' | 'completed' | 'canceled' | 'refunded'; - createdAt: Date; -} - -const columns = [ - { - formatter: (row): React.JSX.Element => ( - - {new Intl.NumberFormat('en-US', { style: 'currency', currency: row.currency }).format(row.amount)} - - ), - name: 'Amount', - width: '200px', - }, - { - formatter: (row): React.JSX.Element => { - const mapping = { - pending: { label: 'Pending', color: 'warning' }, - completed: { label: 'Completed', color: 'success' }, - canceled: { label: 'Canceled', color: 'error' }, - refunded: { label: 'Refunded', color: 'error' }, - } as const; - const { label, color } = mapping[row.status] ?? { label: 'Unknown', color: 'secondary' }; - - return ; - }, - name: 'Status', - width: '200px', - }, - { - formatter: (row): React.JSX.Element => { - return {row.invoiceId}; - }, - name: 'Invoice ID', - width: '150px', - }, - { - formatter: (row): React.JSX.Element => ( - - {dayjs(row.createdAt).format('MMM D, YYYY hh:mm A')} - - ), - name: 'Date', - align: 'right', - }, -] satisfies ColumnDef[]; - -export interface PaymentsProps { - ordersValue: number; - payments: Payment[]; - refundsValue: number; - totalOrders: number; -} - -export function Payments({ ordersValue, payments = [], refundsValue, totalOrders }: PaymentsProps): React.JSX.Element { - return ( - - }> - Create Payment - - } - avatar={ - - - - } - title="Payments" - /> - - - - } - spacing={3} - sx={{ justifyContent: 'space-between', p: 2 }} - > -
- - Total orders - - {new Intl.NumberFormat('en-US').format(totalOrders)} -
-
- - Orders value - - - {new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(ordersValue)} - -
-
- - Refunds - - - {new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(refundsValue)} - -
-
-
- - - columns={columns} rows={payments} /> - - -
-
-
- ); -} diff --git a/002_source/cms/src/components/dashboard/user.de/phone-filter-popover.tsx b/002_source/cms/src/components/dashboard/user.de/phone-filter-popover.tsx deleted file mode 100644 index 08cbad7..0000000 --- a/002_source/cms/src/components/dashboard/user.de/phone-filter-popover.tsx +++ /dev/null @@ -1,50 +0,0 @@ -'use client'; - -import * as React from 'react'; - -import Button from '@mui/material/Button'; -import FormControl from '@mui/material/FormControl'; -import OutlinedInput from '@mui/material/OutlinedInput'; - -import { FilterPopover, useFilterContext } from '@/components/core/filter-button'; - -// phone-filter-popover.tsx -export default function PhoneFilterPopover(): React.JSX.Element { - const { anchorEl, onApply, onClose, open, value: initialValue } = useFilterContext(); - const [value, setValue] = React.useState(''); - - React.useEffect(() => { - setValue((initialValue as string | undefined) ?? ''); - }, [initialValue]); - - return ( - - - { - setValue(event.target.value); - }} - onKeyUp={(event) => { - if (event.key === 'Enter') { - onApply(value); - } - }} - value={value} - /> - - - - ); -} diff --git a/002_source/cms/src/components/dashboard/user.de/shipping-address.tsx b/002_source/cms/src/components/dashboard/user.de/shipping-address.tsx deleted file mode 100644 index 8793e5c..0000000 --- a/002_source/cms/src/components/dashboard/user.de/shipping-address.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import * as React from 'react'; -import Button from '@mui/material/Button'; -import Card from '@mui/material/Card'; -import CardContent from '@mui/material/CardContent'; -import Chip from '@mui/material/Chip'; -import Stack from '@mui/material/Stack'; -import Typography from '@mui/material/Typography'; -import { PencilSimple as PencilSimpleIcon } from '@phosphor-icons/react/dist/ssr/PencilSimple'; - -export interface Address { - id: string; - country: string; - state: string; - city: string; - zipCode: string; - street: string; - primary?: boolean; -} - -export interface ShippingAddressProps { - address: Address; -} - -export function ShippingAddress({ address }: ShippingAddressProps): React.ReactElement { - return ( - - - - - {address.street}, -
- {address.city}, {address.state}, {address.country}, -
- {address.zipCode} -
- - {address.primary ? : } - - -
-
-
- ); -} diff --git a/002_source/cms/src/components/dashboard/user.de/type.d.tsx b/002_source/cms/src/components/dashboard/user.de/type.d.tsx deleted file mode 100644 index 847764a..0000000 --- a/002_source/cms/src/components/dashboard/user.de/type.d.tsx +++ /dev/null @@ -1,69 +0,0 @@ -'use client'; - -export type SortDir = 'asc' | 'desc'; - -export interface User { - id: string; - name: string; - avatar?: string; - email: string; - phone?: string; - quota: number; - status: 'pending' | 'active' | 'blocked'; - createdAt: Date; - updatedAt?: Date; -} - -export interface CreateFormProps { - name: string; - email: string; - phone?: string; - company?: string; - billingAddress?: { - country: string; - state: string; - city: string; - zipCode: string; - line1: string; - line2?: string; - }; - taxId?: string; - timezone: string; - language: string; - currency: string; - avatar?: string; - // quota?: number; - // status?: 'pending' | 'active' | 'blocked'; -} - -export interface EditFormProps { - name: string; - email: string; - phone?: string; - company?: string; - billingAddress?: { - country: string; - state: string; - city: string; - zipCode: string; - line1: string; - line2?: string; - }; - taxId?: string; - timezone: string; - language: string; - currency: string; - avatar?: string; - // quota?: number; - // status?: 'pending' | 'active' | 'blocked'; -} -export interface CustomersFiltersProps { - filters?: Filters; - sortDir?: SortDir; - fullData: User[]; -} -export interface Filters { - email?: string; - phone?: string; - status?: string; -} diff --git a/002_source/cms/src/components/dashboard/user.de/user-create-form.tsx b/002_source/cms/src/components/dashboard/user.de/user-create-form.tsx deleted file mode 100644 index 7762893..0000000 --- a/002_source/cms/src/components/dashboard/user.de/user-create-form.tsx +++ /dev/null @@ -1,529 +0,0 @@ -'use client'; - -import * as React from 'react'; -import RouterLink from 'next/link'; -import { useRouter } from 'next/navigation'; -import { zodResolver } from '@hookform/resolvers/zod'; -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 { Controller, useForm } from 'react-hook-form'; -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 { createCustomer as createUser } from '@/db/Customers/Create'; -import isDevelopment from '@/lib/check-is-development'; - -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({ - avatar: zod.string().optional(), - name: zod.string().min(1, 'Name is required').max(255), - email: zod.string().email('Must be a valid email').min(1, 'Email is required').max(255), - phone: zod.string().min(1, 'Phone is required').max(15), - company: zod.string().max(255), - billingAddress: zod.object({ - country: zod.string().min(1, 'Country is required').max(255), - state: zod.string().min(1, 'State is required').max(255), - city: zod.string().min(1, 'City is required').max(255), - zipCode: zod.string().min(1, 'Zip code is required').max(255), - line1: zod.string().min(1, 'Street line 1 is required').max(255), - line2: zod.string().max(255).optional(), - }), - taxId: zod.string().max(255).optional(), - timezone: zod.string().min(1, 'Timezone is required').max(255), - language: zod.string().min(1, 'Language is required').max(255), - currency: zod.string().min(1, 'Currency is required').max(255), -}); - -type Values = zod.infer; - -const defaultValues = { - avatar: '', - name: 'new name', - email: '123@123.com', - phone: '91234567', - company: '', - billingAddress: { - country: 'US', - state: '00000', - city: 'NY', - zipCode: '00000', - line1: 'test line 1', - line2: 'test line 2', - }, - taxId: '12345', - timezone: 'new_york', - language: 'en', - currency: 'USD', -} satisfies Values; - -export function UserCreateForm(): React.JSX.Element { - const router = useRouter(); - - const { - control, - handleSubmit, - formState: { errors }, - setValue, - watch, - } = useForm({ defaultValues, resolver: zodResolver(schema) }); - - const onSubmit = React.useCallback( - async (values: Values): Promise => { - try { - // Use standard create method from db/Customers/Create - const record = await createUser(values); - toast.success('User created successfully'); - router.push(paths.dashboard.user_metas.details(record.id)); - } catch (err) { - logger.error(err); - toast.error('Failed to create user. Please try again.'); - } - }, - [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] - ); - - return ( -
- - - } - spacing={4} - > - - Account information - - - - - - - - - - Avatar - Min 400x400px, PNG or JPEG - - - - - - - ( - - Name - - {errors.name ? {errors.name.message} : null} - - )} - /> - - - ( - - Email address - - {errors.email ? {errors.email.message} : null} - - )} - /> - - - ( - - Phone number - - {errors.phone ? {errors.phone.message} : null} - - )} - /> - - - ( - - Company - - {errors.company ? {errors.company.message} : null} - - )} - /> - - - - - Billing information - - - ( - - Country - - {errors.billingAddress?.country ? ( - {errors.billingAddress?.country?.message} - ) : null} - - )} - /> - - - ( - - State - - {errors.billingAddress?.state ? ( - {errors.billingAddress?.state?.message} - ) : null} - - )} - /> - - - ( - - City - - {errors.billingAddress?.city ? ( - {errors.billingAddress?.city?.message} - ) : null} - - )} - /> - - - ( - - Zip code - - {errors.billingAddress?.zipCode ? ( - {errors.billingAddress?.zipCode?.message} - ) : null} - - )} - /> - - - ( - - Address - - {errors.billingAddress?.line1 ? ( - {errors.billingAddress?.line1?.message} - ) : null} - - )} - /> - - - ( - - Tax ID - - {errors.taxId ? {errors.taxId.message} : null} - - )} - /> - - - - - Shipping information - } - label="Same as billing address" - /> - - - Additional information - - - ( - - Timezone - - {errors.timezone ? {errors.timezone.message} : null} - - )} - /> - - - ( - - Language - - {errors.language ? {errors.language.message} : null} - - )} - /> - - - ( - - Currency - - {errors.currency ? {errors.currency.message} : null} - - )} - /> - - - - - - - - - - - -
{JSON.stringify({ errors }, null, 2)}
-
-
- ); -} diff --git a/002_source/cms/src/components/dashboard/user.de/user-edit-form.tsx b/002_source/cms/src/components/dashboard/user.de/user-edit-form.tsx deleted file mode 100644 index a4fb402..0000000 --- a/002_source/cms/src/components/dashboard/user.de/user-edit-form.tsx +++ /dev/null @@ -1,604 +0,0 @@ -'use client'; - -import * as React from 'react'; -import RouterLink from 'next/link'; -import { useParams, useRouter } from 'next/navigation'; -// -import { COL_USERS } from '@/constants'; -import { zodResolver } from '@hookform/resolvers/zod'; -import { LoadingButton } from '@mui/lab'; -// -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 Divider from '@mui/material/Divider'; -import FormControl from '@mui/material/FormControl'; -import FormHelperText from '@mui/material/FormHelperText'; -import InputLabel from '@mui/material/InputLabel'; -import MenuItem from '@mui/material/MenuItem'; -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 { Controller, useForm } from 'react-hook-form'; -import { useTranslation } from 'react-i18next'; -import { z as zod } from 'zod'; - -import { paths } from '@/paths'; -import isDevelopment from '@/lib/check-is-development'; -import { logger } from '@/lib/default-logger'; -import { base64ToFile, fileToBase64 } from '@/lib/file-to-base64'; -import { pb } from '@/lib/pb'; -import { toast } from '@/components/core/toaster'; -import FormLoading from '@/components/loading'; - -// import ErrorDisplay from '../../error'; -import ErrorDisplay from '../error'; - -// TODO: review this -const schema = zod.object({ - name: zod.string().min(1, 'Name is required').max(255), - email: zod.string().email('Must be a valid email').min(1, 'Email is required').max(255), - phone: zod.string().min(1, 'Phone is required').max(25), - company: zod.string().max(255).optional(), - billingAddress: zod.object({ - country: zod.string().min(1, 'Country is required').max(255), - state: zod.string().min(1, 'State is required').max(255), - city: zod.string().min(1, 'City is required').max(255), - zipCode: zod.string().min(1, 'Zip code is required').max(255), - line1: zod.string().min(1, 'Street line 1 is required').max(255), - line2: zod.string().max(255).optional(), - }), - taxId: zod.string().max(255).optional(), - timezone: zod.string().min(1, 'Timezone is required').max(255), - language: zod.string().min(1, 'Language is required').max(255), - currency: zod.string().min(1, 'Currency is required').max(255), - avatar: zod.string().optional(), -}); - -type Values = zod.infer; - -const defaultValues = { - name: '', - email: '', - phone: '', - company: '', - billingAddress: { - country: '', - state: '', - city: '', - zipCode: '', - line1: '', - line2: '', - }, - taxId: '', - timezone: '', - language: '', - currency: '', - avatar: '', -} satisfies Values; - -export function UserEditForm(): React.JSX.Element { - const router = useRouter(); - const { t } = useTranslation(['lp_categories']); - - const { id: userId } = useParams<{ userId: string }>(); - // - const [isUpdating, setIsUpdating] = React.useState(false); - const [showLoading, setShowLoading] = React.useState(false); - // - const [showError, setShowError] = React.useState({ show: false, detail: '' }); - - const { - control, - handleSubmit, - formState: { errors }, - setValue, - reset, - watch, - } = useForm({ defaultValues, resolver: zodResolver(schema) }); - - const onSubmit = React.useCallback( - async (values: Values): Promise => { - setIsUpdating(true); - - const updateData = { - name: values.name, - email: values.email, - phone: values.phone, - company: values.company, - billingAddress: values.billingAddress, - taxId: values.taxId, - timezone: values.timezone, - language: values.language, - currency: values.currency, - avatar: values.avatar ? await base64ToFile(values.avatar) : null, - }; - - try { - await pb.collection(COL_USERS).update(userId, updateData); - toast.success('User updated successfully'); - router.push(paths.dashboard.user_metas.list); - } catch (error) { - logger.error(error); - toast.error('Failed to update user'); - } finally { - setIsUpdating(false); - } - }, - [userId, 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] - ); - - // TODO: need to align with save form - // use trycatch - const [textDescription, setTextDescription] = React.useState(''); - const [textRemarks, setTextRemarks] = React.useState(''); - - // load existing data when user arrive - const loadExistingData = React.useCallback( - async (id: string) => { - setShowLoading(true); - - try { - const result = await pb.collection(COL_USERS).getOne(id); - reset({ ...defaultValues, ...result }); - console.log({ result }); - - if (result.avatar_file) { - const fetchResult = await fetch( - `http://127.0.0.1:8090/api/files/${result.collectionId}/${result.id}/${result.avatar_file}` - ); - const blob = await fetchResult.blob(); - const url = await fileToBase64(blob); - setValue('avatar', url); - } - } catch (error) { - logger.error(error); - toast.error('Failed to load user data'); - setShowError({ show: true, detail: JSON.stringify(error, null, 2) }); - } finally { - setShowLoading(false); - } - }, - [reset, setValue] - ); - - React.useEffect(() => { - void loadExistingData(userId); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [userId]); - - if (showLoading) return ; - if (showError.show) - return ( - - ); - - return ( -
- - - } - spacing={4} - > - - {t('edit.basic-info')} - - - - - - - - - - {t('edit.avatar')} - {t('edit.avatarRequirements')} - - - - - - - ( - - Name - - {errors.name ? {errors.name.message} : null} - - )} - /> - - - ( - - Email - - {errors.email ? {errors.email.message} : null} - - )} - /> - - - ( - - Phone - - {errors.phone ? {errors.phone.message} : null} - - )} - /> - - - ( - - Company - - {errors.company ? {errors.company.message} : null} - - )} - /> - - - - {/* */} - - Billing Information - - - ( - - Country - - {errors.billingAddress?.country ? ( - {errors.billingAddress.country.message} - ) : null} - - )} - /> - - - ( - - State - - {errors.billingAddress?.state ? ( - {errors.billingAddress.state.message} - ) : null} - - )} - /> - - - ( - - City - - {errors.billingAddress?.city ? ( - {errors.billingAddress.city.message} - ) : null} - - )} - /> - - - ( - - Zip Code - - {errors.billingAddress?.zipCode ? ( - {errors.billingAddress.zipCode.message} - ) : null} - - )} - /> - - - ( - - Address Line 1 - - {errors.billingAddress?.line1 ? ( - {errors.billingAddress.line1.message} - ) : null} - - )} - /> - - - ( - - Tax ID - - {errors.taxId ? {errors.taxId.message} : null} - - )} - /> - - - - - - Additional Information - - - ( - - Timezone - - {errors.timezone ? {errors.timezone.message} : null} - - )} - /> - - - ( - - Language - - {errors.language ? {errors.language.message} : null} - - )} - /> - - - ( - - Currency - - {errors.currency ? {errors.currency.message} : null} - - )} - /> - - - - - - - - - - {t('edit.updateButton')} - - - - -
{JSON.stringify({ errors }, null, 2)}
-
-
- ); -} diff --git a/002_source/cms/src/components/dashboard/user.de/users-filters.tsx b/002_source/cms/src/components/dashboard/user.de/users-filters.tsx deleted file mode 100644 index 418c7eb..0000000 --- a/002_source/cms/src/components/dashboard/user.de/users-filters.tsx +++ /dev/null @@ -1,242 +0,0 @@ -'use client'; -// RULES: -// T.B.A. -// -import * as React from 'react'; -import { useRouter } from 'next/navigation'; -import { getAllCustomersCount } from '@/db/Customers/GetAllCount'; - -import Button from '@mui/material/Button'; -import Chip from '@mui/material/Chip'; -import Divider from '@mui/material/Divider'; -import Select from '@mui/material/Select'; -import type { SelectChangeEvent } from '@mui/material/Select'; -import Stack from '@mui/material/Stack'; -import Tab from '@mui/material/Tab'; -import Tabs from '@mui/material/Tabs'; -import Typography from '@mui/material/Typography'; -import { useTranslation } from 'react-i18next'; - -import { paths } from '@/paths'; -import { FilterButton } from '@/components/core/filter-button'; -import { Option } from '@/components/core/option'; - -import { useCustomersSelection } from './users-selection-context'; -import GetBlockedCount from '@/db/Customers/GetBlockedCount'; -import GetPendingCount from '@/db/Customers/GetPendingCount'; -import GetActiveCount from '@/db/Customers/GetActiveCount'; -import PhoneFilterPopover from './phone-filter-popover'; -import EmailFilterPopover from './email-filter-popover'; -import type { CustomersFiltersProps, Filters, SortDir } from './type.d'; - -export function UsersFilters({ filters = {}, sortDir = 'desc', fullData }: CustomersFiltersProps): React.JSX.Element { - const { t } = useTranslation(); - - const { email, phone, status } = filters; - - const [totalCount, setTotalCount] = React.useState(0); - const [activeCount, setActiveCount] = React.useState(0); - const [pendingCount, setPendingCount] = React.useState(0); - const [blockedCount, setBlockedCount] = React.useState(0); - - const router = useRouter(); - - const selection = useCustomersSelection(); - - // function getVisible(): number { - // return fullData.reduce((count, item: CrQuestion) => { - // return item.visible === 'visible' ? count + 1 : count; - // }, 0); - // } - - // function getHidden(): number { - // return fullData.reduce((count, item: CrQuestion) => { - // return item.visible === 'hidden' ? count + 1 : count; - // }, 0); - // } - - // The tabs should be generated using API data. - const tabs = [ - { label: 'All', value: '', count: totalCount }, - { label: 'Active', value: 'active', count: activeCount }, - { label: 'Pending', value: 'pending', count: pendingCount }, - { label: 'Blocked', value: 'blocked', count: blockedCount }, - ] as const; - - const updateSearchParams = React.useCallback( - (newFilters: Filters, newSortDir: SortDir): void => { - const searchParams = new URLSearchParams(); - - if (newSortDir === 'asc') { - searchParams.set('sortDir', newSortDir); - } - - if (newFilters.status) { - searchParams.set('status', newFilters.status); - } - - if (newFilters.email) { - searchParams.set('email', newFilters.email); - } - - if (newFilters.phone) { - searchParams.set('phone', newFilters.phone); - } - - router.push(`${paths.dashboard.customers.list}?${searchParams.toString()}`); - }, - [router] - ); - - const handleClearFilters = React.useCallback(() => { - updateSearchParams({}, sortDir); - }, [updateSearchParams, sortDir]); - - const handleStatusChange = React.useCallback( - (_: React.SyntheticEvent, value: string) => { - updateSearchParams({ ...filters, status: value }, sortDir); - }, - [updateSearchParams, filters, sortDir] - ); - - const handleEmailChange = React.useCallback( - (value?: string) => { - updateSearchParams({ ...filters, email: value }, sortDir); - }, - [updateSearchParams, filters, sortDir] - ); - - const handlePhoneChange = React.useCallback( - (value?: string) => { - updateSearchParams({ ...filters, phone: value }, sortDir); - }, - [updateSearchParams, filters, sortDir] - ); - - const handleSortChange = React.useCallback( - (event: SelectChangeEvent) => { - updateSearchParams(filters, event.target.value as SortDir); - }, - [updateSearchParams, filters] - ); - - const hasFilters = status || email || phone; - - React.useEffect(() => { - const fetchCount = async (): Promise => { - try { - const tc = await getAllCustomersCount(); - setTotalCount(tc); - - const bc = await GetBlockedCount(); - setBlockedCount(bc); - const pc = await GetPendingCount(); - setPendingCount(pc); - const ac = await GetActiveCount(); - setActiveCount(ac); - } catch (error) { - // - } - }; - void fetchCount(); - }, []); - - return ( -
- - {tabs.map((tab) => ( - - } - iconPosition="end" - key={tab.value} - label={tab.label} - sx={{ minHeight: 'auto' }} - tabIndex={0} - value={tab.value} - /> - ))} - - - - - { - handleEmailChange(value as string); - }} - onFilterDelete={() => { - handleEmailChange(); - }} - popover={} - value={email} - /> - - { - handlePhoneChange(value as string); - }} - onFilterDelete={() => { - handlePhoneChange(); - }} - popover={} - value={phone} - /> - - {hasFilters ? : null} - - {selection.selectedAny ? ( - - - {selection.selected.size} selected - - - - ) : null} - - -
- ); -} diff --git a/002_source/cms/src/components/dashboard/user.de/users-pagination.tsx b/002_source/cms/src/components/dashboard/user.de/users-pagination.tsx deleted file mode 100644 index 1d92ade..0000000 --- a/002_source/cms/src/components/dashboard/user.de/users-pagination.tsx +++ /dev/null @@ -1,50 +0,0 @@ -'use client'; - -import * as React from 'react'; -import TablePagination from '@mui/material/TablePagination'; - -function noop(): void { - return undefined; -} - -interface UsersPaginationProps { - count: number; - page: number; - // - setPage: (page: number) => void; - setRowsPerPage: (page: number) => void; - rowsPerPage: number; -} - -export function UsersPagination({ - count, - page, - // - setPage, - setRowsPerPage, - rowsPerPage, -}: UsersPaginationProps): React.JSX.Element { - // You should implement the pagination using a similar logic as the filters. - // Note that when page change, you should keep the filter search params. - const handleChangePage = (event: unknown, newPage: number) => { - setPage(newPage); - }; - - const handleChangeRowsPerPage = (event: React.ChangeEvent) => { - setRowsPerPage(parseInt(event.target.value)); - // console.log(parseInt(event.target.value)); - }; - - return ( - - ); -} diff --git a/002_source/cms/src/components/dashboard/user.de/users-selection-context.tsx b/002_source/cms/src/components/dashboard/user.de/users-selection-context.tsx deleted file mode 100644 index f2a5c1e..0000000 --- a/002_source/cms/src/components/dashboard/user.de/users-selection-context.tsx +++ /dev/null @@ -1,40 +0,0 @@ -'use client'; - -import * as React from 'react'; - -import { useSelection } from '@/hooks/use-selection'; -import type { Selection } from '@/hooks/use-selection'; - -import type { User } from './type.d'; - -function noop(): void { - return undefined; -} - -export interface CustomersSelectionContextValue extends Selection {} - -export const CustomersSelectionContext = React.createContext({ - deselectAll: noop, - deselectOne: noop, - selectAll: noop, - selectOne: noop, - selected: new Set(), - selectedAny: false, - selectedAll: false, -}); - -interface UsersSelectionProviderProps { - children: React.ReactNode; - users: User[]; -} - -export function UsersSelectionProvider({ children, users = [] }: UsersSelectionProviderProps): React.JSX.Element { - const customerIds = React.useMemo(() => users.map((customer) => customer.id), [users]); - const selection = useSelection(customerIds); - - return {children}; -} - -export function useCustomersSelection(): CustomersSelectionContextValue { - return React.useContext(CustomersSelectionContext); -} diff --git a/002_source/cms/src/components/dashboard/user.de/users-table.tsx b/002_source/cms/src/components/dashboard/user.de/users-table.tsx deleted file mode 100644 index 8e13573..0000000 --- a/002_source/cms/src/components/dashboard/user.de/users-table.tsx +++ /dev/null @@ -1,222 +0,0 @@ -'use client'; - -import * as React from 'react'; -import RouterLink from 'next/link'; -import { LoadingButton } from '@mui/lab'; -import Avatar from '@mui/material/Avatar'; -import Box from '@mui/material/Box'; -import Button from '@mui/material/Button'; -import Chip from '@mui/material/Chip'; -import IconButton from '@mui/material/IconButton'; -import LinearProgress from '@mui/material/LinearProgress'; -import Link from '@mui/material/Link'; -import Stack from '@mui/material/Stack'; -import Typography from '@mui/material/Typography'; -import { CheckCircle as CheckCircleIcon } from '@phosphor-icons/react/dist/ssr/CheckCircle'; -import { Clock as ClockIcon } from '@phosphor-icons/react/dist/ssr/Clock'; -import { Images as ImagesIcon } from '@phosphor-icons/react/dist/ssr/Images'; -import { Minus as MinusIcon } from '@phosphor-icons/react/dist/ssr/Minus'; -import { PencilSimple as PencilSimpleIcon } from '@phosphor-icons/react/dist/ssr/PencilSimple'; -import { TrashSimple as TrashSimpleIcon } from '@phosphor-icons/react/dist/ssr/TrashSimple'; -import { useTranslation } from 'react-i18next'; -import { toast } from 'sonner'; - -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 ConfirmDeleteModal from './confirm-delete-modal'; -import { useCustomersSelection } from './users-selection-context'; -import type { User } from './type.d'; - -function columns(handleDeleteClick: (testId: string) => void): ColumnDef[] { - return [ - { - formatter: (row): React.JSX.Element => ( - - {' '} -
- - {row.name} - - - {row.email} - -
-
- ), - name: 'Name', - width: '250px', - }, - { - formatter: (row): React.JSX.Element => ( - - - - {new Intl.NumberFormat('en-US', { style: 'percent', maximumFractionDigits: 2 }).format(row.quota / 100)} - - - ), - name: 'Quota', - width: '150px', - }, - { field: 'phone', name: 'Phone number', width: '150px' }, - - { - formatter: (row): React.JSX.Element => { - // eslint-disable-next-line react-hooks/rules-of-hooks - - const mapping = { - active: { - label: 'Active', - icon: ( - - ), - }, - blocked: { label: 'Blocked', icon: }, - pending: { - label: 'Pending', - icon: ( - - ), - }, - } as const; - const { label, icon } = mapping[row.status] ?? { label: 'Unknown', icon: null }; - - return ( - - ); - }, - name: 'Status', - width: '150px', - }, - { - formatter(row) { - return dayjs(row.createdAt).format('MMM D, YYYY'); - }, - name: 'Created at', - width: '150px', - }, - { - formatter: (row): React.JSX.Element => ( - - - - - { - handleDeleteClick(row.id); - }} - > - - - - ), - name: 'Actions', - hideName: true, - align: 'right', - }, - ]; -} - -export interface UsersTableProps { - rows: User[]; - reloadRows: () => void; -} - -export function UsersTable({ rows, reloadRows }: UsersTableProps): React.JSX.Element { - const { t } = useTranslation(['customers']); - const { deselectAll, deselectOne, selectAll, selectOne, selected } = useCustomersSelection(); - - const [idToDelete, setIdToDelete] = React.useState(''); - const [open, setOpen] = React.useState(false); - - function handleDeleteClick(testId: string): void { - setOpen(true); - setIdToDelete(testId); - } - - return ( - - - - columns={columns(handleDeleteClick)} - onDeselectAll={deselectAll} - onDeselectOne={(_, row) => { - deselectOne(row.id); - }} - onSelectAll={selectAll} - onSelectOne={(_, row) => { - selectOne(row.id); - }} - rows={rows} - selectable - selected={selected} - /> - {!rows.length ? ( - - - {/* TODO: update this */} - {t('no-record-found')} - - - ) : null} - - ); -} diff --git a/002_source/cms/src/components/dashboard/user_meta/confirm-delete-modal.tsx b/002_source/cms/src/components/dashboard/user_meta/confirm-delete-modal.tsx index 55d5ddf..70094ef 100644 --- a/002_source/cms/src/components/dashboard/user_meta/confirm-delete-modal.tsx +++ b/002_source/cms/src/components/dashboard/user_meta/confirm-delete-modal.tsx @@ -1,6 +1,7 @@ 'use client'; import * as React from 'react'; +import { deleteUserMeta } from '@/db/UserMetas/Delete'; import { LoadingButton } from '@mui/lab'; import { Button, Container, Modal, Paper } from '@mui/material'; import Avatar from '@mui/material/Avatar'; @@ -12,7 +13,6 @@ import { useTranslation } from 'react-i18next'; import { logger } from '@/lib/default-logger'; import { toast } from '@/components/core/toaster'; -import { deleteUserMeta } from '@/db/UserMetas/Delete'; export default function ConfirmDeleteModal({ open, @@ -105,7 +105,7 @@ export default function ConfirmDeleteModal({ { + onClick={() => { handleUserConfirmDelete(); }} loading={isDeleteing} diff --git a/002_source/cms/src/components/dashboard/user_meta/user-metas-filters.tsx b/002_source/cms/src/components/dashboard/user_meta/user-metas-filters.tsx index cefff38..fffbab3 100644 --- a/002_source/cms/src/components/dashboard/user_meta/user-metas-filters.tsx +++ b/002_source/cms/src/components/dashboard/user_meta/user-metas-filters.tsx @@ -34,8 +34,9 @@ import { useUserMetasSelection } from './user-metas-selection-context'; export function UserMetasFilters({ filters = {}, sortDir = 'desc', + // TODO: remove fullData + // eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars fullData, - // }: UserMetasFiltersProps): React.JSX.Element { const { t } = useTranslation(); diff --git a/002_source/cms/src/components/dashboard/user_meta/user-metas-pagination.tsx b/002_source/cms/src/components/dashboard/user_meta/user-metas-pagination.tsx index 986e6c9..fe855d6 100644 --- a/002_source/cms/src/components/dashboard/user_meta/user-metas-pagination.tsx +++ b/002_source/cms/src/components/dashboard/user_meta/user-metas-pagination.tsx @@ -3,9 +3,10 @@ import * as React from 'react'; import TablePagination from '@mui/material/TablePagination'; -function noop(): void { - return undefined; -} +// TODO remove noop +// function noop(): void { +// return undefined; +// } interface UserMetasPaginationProps { count: number; @@ -30,7 +31,7 @@ export function UserMetasPagination({ setPage(newPage); }; - const handleChangeRowsPerPage = (event: React.ChangeEvent) => { + const handleChangeRowsPerPage = (event: React.ChangeEvent): void => { setRowsPerPage(parseInt(event.target.value)); // console.log(parseInt(event.target.value)); }; diff --git a/002_source/cms/src/components/dashboard/user_meta/user-metas-table.tsx b/002_source/cms/src/components/dashboard/user_meta/user-metas-table.tsx index 86eec3c..25c0dee 100644 --- a/002_source/cms/src/components/dashboard/user_meta/user-metas-table.tsx +++ b/002_source/cms/src/components/dashboard/user_meta/user-metas-table.tsx @@ -9,16 +9,13 @@ import RouterLink from 'next/link'; import { LoadingButton } from '@mui/lab'; import Avatar from '@mui/material/Avatar'; import Box from '@mui/material/Box'; -import Button from '@mui/material/Button'; import Chip from '@mui/material/Chip'; -import IconButton from '@mui/material/IconButton'; import LinearProgress from '@mui/material/LinearProgress'; import Link from '@mui/material/Link'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { CheckCircle as CheckCircleIcon } from '@phosphor-icons/react/dist/ssr/CheckCircle'; import { Clock as ClockIcon } from '@phosphor-icons/react/dist/ssr/Clock'; -import { Images as ImagesIcon } from '@phosphor-icons/react/dist/ssr/Images'; import { Minus as MinusIcon } from '@phosphor-icons/react/dist/ssr/Minus'; import { PencilSimple as PencilSimpleIcon } from '@phosphor-icons/react/dist/ssr/PencilSimple'; import { TrashSimple as TrashSimpleIcon } from '@phosphor-icons/react/dist/ssr/TrashSimple'; diff --git a/002_source/cms/src/components/dashboard/vocabulary/_constants.ts b/002_source/cms/src/components/dashboard/vocabulary/_constants.ts index a7cba1d..3fb3d67 100644 --- a/002_source/cms/src/components/dashboard/vocabulary/_constants.ts +++ b/002_source/cms/src/components/dashboard/vocabulary/_constants.ts @@ -1,5 +1,4 @@ -import { dayjs } from '@/lib/dayjs'; -import { Vocabulary, CreateForm } from './type'; +import type { CreateForm, Vocabulary } from './type'; export const defaultVocabulary: Vocabulary = { id: 'default-vocabulary-id', diff --git a/002_source/cms/src/components/dashboard/vocabulary/confirm-delete-modal.tsx b/002_source/cms/src/components/dashboard/vocabulary/confirm-delete-modal.tsx index 671b235..7a391d6 100644 --- a/002_source/cms/src/components/dashboard/vocabulary/confirm-delete-modal.tsx +++ b/002_source/cms/src/components/dashboard/vocabulary/confirm-delete-modal.tsx @@ -1,8 +1,7 @@ 'use client'; import * as React from 'react'; -import { useRouter } from 'next/navigation'; -import { COL_LESSON_TYPES } from '@/constants'; +import deleteVocabulary from '@/db/Vocabularies/Delete'; import { LoadingButton } from '@mui/lab'; import { Button, Container, Modal, Paper } from '@mui/material'; import Avatar from '@mui/material/Avatar'; @@ -10,14 +9,15 @@ import Box from '@mui/material/Box'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { Note as NoteIcon } from '@phosphor-icons/react/dist/ssr/Note'; -import PocketBase from 'pocketbase'; +// TODO: remove import +// import PocketBase from 'pocketbase'; import { useTranslation } from 'react-i18next'; import { logger } from '@/lib/default-logger'; import { toast } from '@/components/core/toaster'; -import deleteVocabulary from '@/db/Vocabularies/Delete'; -const pb = new PocketBase(process.env.NEXT_PUBLIC_POCKETBASE_URL); +// TODO: remove pb +// const pb = new PocketBase(process.env.NEXT_PUBLIC_POCKETBASE_URL); export default function ConfirmDeleteModal({ open, @@ -110,7 +110,7 @@ export default function ConfirmDeleteModal({ { + onClick={() => { handleUserConfirmDelete(); }} loading={isDeleteing} diff --git a/002_source/cms/src/components/dashboard/vocabulary/vocabularies-filters.tsx b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-filters.tsx index 83c8354..74e61fc 100644 --- a/002_source/cms/src/components/dashboard/vocabulary/vocabularies-filters.tsx +++ b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-filters.tsx @@ -2,9 +2,12 @@ import * as React from 'react'; import { useRouter } from 'next/navigation'; +import { listLessonCategories } from '@/db/LessonCategories/ListLessonCategories'; import GetAllCount from '@/db/Vocabularies/GetAllCount'; import GetHiddenCount from '@/db/Vocabularies/GetHiddenCount'; import GetVisibleCount from '@/db/Vocabularies/GetVisibleCount'; +// import { listLessonCategories } from '@/db/LessonCategories/ListLessonCategories'; +import { MenuItem } from '@mui/material'; import Button from '@mui/material/Button'; import Chip from '@mui/material/Chip'; import Divider from '@mui/material/Divider'; @@ -19,14 +22,12 @@ import Typography from '@mui/material/Typography'; import { useTranslation } from 'react-i18next'; import { paths } from '@/paths'; +import { logger } from '@/lib/default-logger'; import { FilterButton, FilterPopover, useFilterContext } from '@/components/core/filter-button'; import { Option } from '@/components/core/option'; -import { useVocabulariesSelection } from './vocabularies-selection-context'; import type { Vocabulary } from './type'; -import { listLessonCategories } from '@/db/LessonCategories/listLessonCategories'; -import { MenuItem } from '@mui/material'; -import { logger } from '@/lib/default-logger'; +import { useVocabulariesSelection } from './vocabularies-selection-context'; export interface Filters { email?: string; @@ -50,6 +51,7 @@ export interface VocabulariesFiltersProps { export function VocabulariesFilters({ filters = {}, sortDir = 'desc', + // eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars fullData, }: VocabulariesFiltersProps): React.JSX.Element { const { t } = useTranslation(); @@ -119,12 +121,13 @@ export function VocabulariesFilters({ updateSearchParams({}, sortDir); }, [updateSearchParams, sortDir]); - const handleStatusChange = React.useCallback( - (_: React.SyntheticEvent, value: string) => { - updateSearchParams({ ...filters, status: value }, sortDir); - }, - [updateSearchParams, filters, sortDir] - ); + // TODO: remove me + // const handleStatusChange = React.useCallback( + // (_: React.SyntheticEvent, value: string) => { + // updateSearchParams({ ...filters, status: value }, sortDir); + // }, + // [updateSearchParams, filters, sortDir] + // ); const handleVisibleChange = React.useCallback( (_: React.SyntheticEvent, value: string) => { @@ -161,19 +164,19 @@ export function VocabulariesFilters({ [updateSearchParams, filters, sortDir] ); - const handleEmailChange = React.useCallback( - (value?: string) => { - updateSearchParams({ ...filters, email: value }, sortDir); - }, - [updateSearchParams, filters, sortDir] - ); + // const handleEmailChange = React.useCallback( + // (value?: string) => { + // updateSearchParams({ ...filters, email: value }, sortDir); + // }, + // [updateSearchParams, filters, sortDir] + // ); - const handlePhoneChange = React.useCallback( - (value?: string) => { - updateSearchParams({ ...filters, phone: value }, sortDir); - }, - [updateSearchParams, filters, sortDir] - ); + // const handlePhoneChange = React.useCallback( + // (value?: string) => { + // updateSearchParams({ ...filters, phone: value }, sortDir); + // }, + // [updateSearchParams, filters, sortDir] + // ); const handleSortChange = React.useCallback( (event: SelectChangeEvent) => { @@ -185,7 +188,7 @@ export function VocabulariesFilters({ const [allCategories, setAllCategories] = React.useState<{ value: string; label: string }[]>([]); async function listAllCategories() { try { - let result = await listLessonCategories(); + const result = await listLessonCategories(); const tempAllCategories = result.map((c) => { return { value: c.id, @@ -568,42 +571,43 @@ function EmailFilterPopover(): React.JSX.Element { ); } -function PhoneFilterPopover(): React.JSX.Element { - const { anchorEl, onApply, onClose, open, value: initialValue } = useFilterContext(); - const [value, setValue] = React.useState(''); +// remove PhoneFilterPopover +// function PhoneFilterPopover(): React.JSX.Element { +// const { anchorEl, onApply, onClose, open, value: initialValue } = useFilterContext(); +// const [value, setValue] = React.useState(''); - React.useEffect(() => { - setValue((initialValue as string | undefined) ?? ''); - }, [initialValue]); +// React.useEffect(() => { +// setValue((initialValue as string | undefined) ?? ''); +// }, [initialValue]); - return ( - - - { - setValue(event.target.value); - }} - onKeyUp={(event) => { - if (event.key === 'Enter') { - onApply(value); - } - }} - value={value} - /> - - - - ); -} +// return ( +// +// +// { +// setValue(event.target.value); +// }} +// onKeyUp={(event) => { +// if (event.key === 'Enter') { +// onApply(value); +// } +// }} +// value={value} +// /> +// +// +// +// ); +// } diff --git a/002_source/cms/src/components/dashboard/vocabulary/vocabularies-pagination.tsx b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-pagination.tsx index b7256e4..1dcf2f6 100644 --- a/002_source/cms/src/components/dashboard/vocabulary/vocabularies-pagination.tsx +++ b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-pagination.tsx @@ -6,9 +6,10 @@ import * as React from 'react'; import TablePagination from '@mui/material/TablePagination'; -function noop(): void { - return undefined; -} +// TODO: remove noop +// function noop(): void { +// return undefined; +// } interface VocabulariesPaginationProps { count: number; @@ -29,11 +30,11 @@ export function VocabulariesPagination({ }: VocabulariesPaginationProps): React.JSX.Element { // You should implement the pagination using a similar logic as the filters. // Note that when page change, you should keep the filter search params. - const handleChangePage = (event: unknown, newPage: number) => { + const handleChangePage = (event: unknown, newPage: number): void => { setPage(newPage); }; - const handleChangeRowsPerPage = (event: React.ChangeEvent) => { + const handleChangeRowsPerPage = (event: React.ChangeEvent): void => { setRowsPerPage(parseInt(event.target.value)); // console.log(parseInt(event.target.value)); }; diff --git a/002_source/cms/src/components/dashboard/vocabulary/vocabularies-table.tsx b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-table.tsx index 5d10647..9161d28 100644 --- a/002_source/cms/src/components/dashboard/vocabulary/vocabularies-table.tsx +++ b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-table.tsx @@ -105,7 +105,7 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef { setShowLoading(true); diff --git a/002_source/cms/src/components/dashboard/vocabulary/vocabulary-edit-form.tsx b/002_source/cms/src/components/dashboard/vocabulary/vocabulary-edit-form.tsx index 47ef720..fafb941 100644 --- a/002_source/cms/src/components/dashboard/vocabulary/vocabulary-edit-form.tsx +++ b/002_source/cms/src/components/dashboard/vocabulary/vocabulary-edit-form.tsx @@ -4,7 +4,7 @@ import * as React from 'react'; import RouterLink from 'next/link'; import { useParams, useRouter } from 'next/navigation'; import { COL_VOCABULARIES } from '@/constants'; -import { listLessonCategories } from '@/db/LessonCategories/listLessonCategories'; +import { listLessonCategories } from '@/db/LessonCategories/ListLessonCategories'; import { zodResolver } from '@hookform/resolvers/zod'; import { LoadingButton } from '@mui/lab'; import { Avatar, Divider } from '@mui/material'; @@ -39,34 +39,6 @@ import FormLoading from '@/components/loading'; import ErrorDisplay from '../error'; import type { EditFormProps } from './type'; -const schema = zod.object({ - image: zod.union([zod.array(zod.any()), zod.string()]).optional(), - sound: zod.union([zod.array(zod.any()), zod.string()]).optional(), - word: zod.string().min(1, 'Word is required').max(255), - word_c: zod.string().min(1, 'Chinese word is required').max(255), - sample_e: zod.string().optional(), - sample_c: zod.string().optional(), - cat_id: zod.string().min(1, 'Category ID is required'), - category: zod.string().optional(), - lesson_type_id: zod.string().optional(), - // NOTE: for image handling - avatar: zod.string().optional(), -}); - -type Values = zod.infer; - -const defaultValues = { - image: undefined, - sound: undefined, - word: '', - word_c: '', - sample_e: '', - sample_c: '', - cat_id: '', - category: '', - lesson_type_id: '', -} satisfies Values; - export function VocabularyEditForm(): React.JSX.Element { const router = useRouter(); const { t } = useTranslation(); @@ -78,6 +50,36 @@ export function VocabularyEditForm(): React.JSX.Element { // const [showError, setShowError] = React.useState({ show: false, detail: '' }); + const schema = zod.object({ + image: zod.union([zod.array(zod.any()), zod.string()]).optional(), + sound: zod.union([zod.array(zod.any()), zod.string()]).optional(), + word: zod.string().min(1, 'Word is required').max(255), + word_c: zod.string().min(1, 'Chinese word is required').max(255), + sample_e: zod.string().optional(), + sample_c: zod.string().optional(), + cat_id: zod.string().min(1, 'Category ID is required'), + category: zod.string().optional(), + lesson_type_id: zod.string().optional(), + // NOTE: for image handling + avatar: zod.string().optional(), + visible: zod.string(), + }); + + type Values = zod.infer; + + const defaultValues = { + image: undefined, + sound: undefined, + word: '', + word_c: '', + sample_e: '', + sample_c: '', + cat_id: '', + category: '', + lesson_type_id: '', + visible: 'visible', + } satisfies Values; + const { control, handleSubmit, diff --git a/002_source/cms/src/components/loading/index.tsx b/002_source/cms/src/components/loading/index.tsx index 219a67e..8d5d23d 100644 --- a/002_source/cms/src/components/loading/index.tsx +++ b/002_source/cms/src/components/loading/index.tsx @@ -19,15 +19,16 @@ function Loading(): React.JSX.Element { alignItems: 'center', }} > - +
{t('loading')}
); } export default function FormLoading(): React.JSX.Element { - const { t } = useTranslation(); - return ( { diff --git a/002_source/cms/src/db/Customers/GetAll.tsx b/002_source/cms/src/db/Customers/GetAll.tsx index 1130771..6d63b06 100644 --- a/002_source/cms/src/db/Customers/GetAll.tsx +++ b/002_source/cms/src/db/Customers/GetAll.tsx @@ -1,6 +1,6 @@ import { pb } from '@/lib/pb'; import { COL_CUSTOMERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; +import type { RecordModel } from 'pocketbase'; export async function getAllCustomers(options = {}): Promise { return pb.collection(COL_CUSTOMERS).getFullList(options); diff --git a/002_source/cms/src/db/Customers/GetBlockedCount.tsx b/002_source/cms/src/db/Customers/GetBlockedCount.tsx index 62e649d..57c537d 100644 --- a/002_source/cms/src/db/Customers/GetBlockedCount.tsx +++ b/002_source/cms/src/db/Customers/GetBlockedCount.tsx @@ -1,4 +1,5 @@ -import { COL_CUSTOMERS, COL_USER_METAS } from '@/constants'; +import { COL_USER_METAS } from '@/constants'; + import { pb } from '@/lib/pb'; export default async function GetBlockedCount(): Promise { diff --git a/002_source/cms/src/db/Customers/GetById.tsx b/002_source/cms/src/db/Customers/GetById.tsx index 7c8ef98..731480b 100644 --- a/002_source/cms/src/db/Customers/GetById.tsx +++ b/002_source/cms/src/db/Customers/GetById.tsx @@ -1,6 +1,6 @@ import { pb } from '@/lib/pb'; import { COL_CUSTOMERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; +import type { RecordModel } from 'pocketbase'; export async function getCustomerById(id: string): Promise { return pb.collection(COL_CUSTOMERS).getOne(id); diff --git a/002_source/cms/src/db/Customers/GetPendingCount.tsx b/002_source/cms/src/db/Customers/GetPendingCount.tsx index eff76fc..b56183c 100644 --- a/002_source/cms/src/db/Customers/GetPendingCount.tsx +++ b/002_source/cms/src/db/Customers/GetPendingCount.tsx @@ -1,4 +1,5 @@ -import { COL_CUSTOMERS, COL_USER_METAS } from '@/constants'; +import { COL_USER_METAS } from '@/constants'; + import { pb } from '@/lib/pb'; export default async function GetPendingCount(): Promise { diff --git a/002_source/cms/src/db/Customers/Helloworld.tsx b/002_source/cms/src/db/Customers/Helloworld.tsx index 2487997..a8e5889 100644 --- a/002_source/cms/src/db/Customers/Helloworld.tsx +++ b/002_source/cms/src/db/Customers/Helloworld.tsx @@ -1,3 +1,3 @@ -export function helloCustomer() { +export function helloCustomer(): string { return 'Hello from Customers module!'; } diff --git a/002_source/cms/src/db/LessonCategories/listLessonCategories.tsx b/002_source/cms/src/db/LessonCategories/ListLessonCategories.tsx similarity index 100% rename from 002_source/cms/src/db/LessonCategories/listLessonCategories.tsx rename to 002_source/cms/src/db/LessonCategories/ListLessonCategories.tsx diff --git a/002_source/cms/src/db/Notifications/GetAll.tsx b/002_source/cms/src/db/Notifications/GetAll.tsx index f43121c..b869865 100644 --- a/002_source/cms/src/db/Notifications/GetAll.tsx +++ b/002_source/cms/src/db/Notifications/GetAll.tsx @@ -3,7 +3,7 @@ // TBA import { pb } from '@/lib/pb'; import { COL_NOTIFICATIONS } from '@/constants'; -import { RecordModel } from 'pocketbase'; +import type { RecordModel } from 'pocketbase'; export async function getAllNotifications(options = {}): Promise { return pb.collection(COL_NOTIFICATIONS).getFullList(options); diff --git a/002_source/cms/src/db/Notifications/GetById.tsx b/002_source/cms/src/db/Notifications/GetById.tsx index ed3f66b..ffae20b 100644 --- a/002_source/cms/src/db/Notifications/GetById.tsx +++ b/002_source/cms/src/db/Notifications/GetById.tsx @@ -3,7 +3,7 @@ // TBA import { pb } from '@/lib/pb'; import { COL_NOTIFICATIONS } from '@/constants'; -import { RecordModel } from 'pocketbase'; +import type { RecordModel } from 'pocketbase'; export async function getNotificationById(id: string): Promise { return pb.collection(COL_NOTIFICATIONS).getOne(id); diff --git a/002_source/cms/src/db/Notifications/Helloworld.tsx b/002_source/cms/src/db/Notifications/Helloworld.tsx index 2487997..a8e5889 100644 --- a/002_source/cms/src/db/Notifications/Helloworld.tsx +++ b/002_source/cms/src/db/Notifications/Helloworld.tsx @@ -1,3 +1,3 @@ -export function helloCustomer() { +export function helloCustomer(): string { return 'Hello from Customers module!'; } diff --git a/002_source/cms/src/db/Notifications/mark-one-as-read.tsx b/002_source/cms/src/db/Notifications/mark-one-as-read.tsx index 828f6f3..e8591f7 100644 --- a/002_source/cms/src/db/Notifications/mark-one-as-read.tsx +++ b/002_source/cms/src/db/Notifications/mark-one-as-read.tsx @@ -1,10 +1,10 @@ // api method for update notification record // RULES: // TBA -import { pb } from '@/lib/pb'; import { COL_NOTIFICATIONS } from '@/constants'; import type { RecordModel } from 'pocketbase'; -import type { NotificationFormProps } from '@/components/dashboard/notification/type.d'; + +import { pb } from '@/lib/pb'; export async function MarkOneAsRead(id: string): Promise { return pb.collection(COL_NOTIFICATIONS).update(id, { read: true }); diff --git a/002_source/cms/src/db/QuizCRCategories/Create.tsx b/002_source/cms/src/db/QuizCRCategories/Create.tsx index 186299f..aa7121c 100644 --- a/002_source/cms/src/db/QuizCRCategories/Create.tsx +++ b/002_source/cms/src/db/QuizCRCategories/Create.tsx @@ -2,7 +2,7 @@ import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; import type { RecordModel } from 'pocketbase'; import { pb } from '@/lib/pb'; -import { CreateFormProps } from '@/components/dashboard/cr/categories/type'; +import type { CreateFormProps } from '@/components/dashboard/cr/categories/type'; export default function createQuizCRCategory(data: CreateFormProps): Promise { return pb.collection(COL_QUIZ_CR_CATEGORIES).create(data); diff --git a/002_source/cms/src/db/QuizLPCategories/Create.tsx b/002_source/cms/src/db/QuizLPCategories/Create.tsx index 5afbb3f..e4f6ab0 100644 --- a/002_source/cms/src/db/QuizLPCategories/Create.tsx +++ b/002_source/cms/src/db/QuizLPCategories/Create.tsx @@ -2,7 +2,7 @@ import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; import type { RecordModel } from 'pocketbase'; import { pb } from '@/lib/pb'; -import { CreateFormProps } from '@/components/dashboard/lp/categories/type'; +import type { CreateFormProps } from '@/components/dashboard/lp/categories/type'; export default function createQuizLPCategory(data: CreateFormProps): Promise { return pb.collection(COL_QUIZ_LP_CATEGORIES).create(data); diff --git a/002_source/cms/src/db/Students/Delete.tsx b/002_source/cms/src/db/Students/Delete.tsx index 9f29ed9..e3d42a6 100644 --- a/002_source/cms/src/db/Students/Delete.tsx +++ b/002_source/cms/src/db/Students/Delete.tsx @@ -1,5 +1,6 @@ +import { COL_USER_METAS } from '@/constants'; + import { pb } from '@/lib/pb'; -import { COL_STUDENTS, COL_USER_METAS } from '@/constants'; export async function deleteStudent(id: string): Promise { return pb.collection(COL_USER_METAS).delete(id); diff --git a/002_source/cms/src/db/Students/GetActiveCount.tsx b/002_source/cms/src/db/Students/GetActiveCount.tsx index 58eb51b..3be4a14 100644 --- a/002_source/cms/src/db/Students/GetActiveCount.tsx +++ b/002_source/cms/src/db/Students/GetActiveCount.tsx @@ -1,4 +1,5 @@ -import { COL_STUDENTS, COL_USER_METAS } from '@/constants'; +import { COL_USER_METAS } from '@/constants'; + import { pb } from '@/lib/pb'; export default async function GetActiveCount(): Promise { diff --git a/002_source/cms/src/db/Students/GetAll.tsx b/002_source/cms/src/db/Students/GetAll.tsx index 1e7c2c1..b6b23fc 100644 --- a/002_source/cms/src/db/Students/GetAll.tsx +++ b/002_source/cms/src/db/Students/GetAll.tsx @@ -1,6 +1,6 @@ import { pb } from '@/lib/pb'; import { COL_STUDENTS } from '@/constants'; -import { RecordModel } from 'pocketbase'; +import type { RecordModel } from 'pocketbase'; export async function getAllStudents(options = {}): Promise { return pb.collection(COL_STUDENTS).getFullList(options); diff --git a/002_source/cms/src/db/Students/Helloworld.tsx b/002_source/cms/src/db/Students/Helloworld.tsx index 2812827..c6b9ffa 100644 --- a/002_source/cms/src/db/Students/Helloworld.tsx +++ b/002_source/cms/src/db/Students/Helloworld.tsx @@ -2,6 +2,6 @@ // RULES: // T.B.A. // -export function helloCustomer() { +export function helloCustomer(): string { return 'Hello from Customers module!'; } diff --git a/002_source/cms/src/db/Teachers/GetActiveCount.tsx b/002_source/cms/src/db/Teachers/GetActiveCount.tsx index bb5c779..d43a207 100644 --- a/002_source/cms/src/db/Teachers/GetActiveCount.tsx +++ b/002_source/cms/src/db/Teachers/GetActiveCount.tsx @@ -1,4 +1,5 @@ -import { COL_TEACHERS, COL_USER_METAS } from '@/constants'; +import { COL_USER_METAS } from '@/constants'; + import { pb } from '@/lib/pb'; export default async function GetActiveCount(): Promise { diff --git a/002_source/cms/src/db/Teachers/GetAll.tsx b/002_source/cms/src/db/Teachers/GetAll.tsx index d5985d5..f37b099 100644 --- a/002_source/cms/src/db/Teachers/GetAll.tsx +++ b/002_source/cms/src/db/Teachers/GetAll.tsx @@ -1,5 +1,5 @@ import { COL_TEACHERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; +import type { RecordModel } from 'pocketbase'; import { pb } from '@/lib/pb'; diff --git a/002_source/cms/src/db/Teachers/Helloworld.tsx b/002_source/cms/src/db/Teachers/Helloworld.tsx index 2487997..a8e5889 100644 --- a/002_source/cms/src/db/Teachers/Helloworld.tsx +++ b/002_source/cms/src/db/Teachers/Helloworld.tsx @@ -1,3 +1,3 @@ -export function helloCustomer() { +export function helloCustomer(): string { return 'Hello from Customers module!'; } diff --git a/002_source/cms/src/db/UserMetas/GetAll.tsx b/002_source/cms/src/db/UserMetas/GetAll.tsx index 4dd4c4c..673b9a1 100644 --- a/002_source/cms/src/db/UserMetas/GetAll.tsx +++ b/002_source/cms/src/db/UserMetas/GetAll.tsx @@ -1,6 +1,6 @@ import { pb } from '@/lib/pb'; import { COL_USER_METAS } from '@/constants'; -import { RecordModel } from 'pocketbase'; +import type { RecordModel } from 'pocketbase'; export async function getAllUserMetas(options = {}): Promise { return pb.collection(COL_USER_METAS).getFullList(options); diff --git a/002_source/cms/src/db/UserMetas/Helloworld.tsx b/002_source/cms/src/db/UserMetas/Helloworld.tsx index 2487997..a8e5889 100644 --- a/002_source/cms/src/db/UserMetas/Helloworld.tsx +++ b/002_source/cms/src/db/UserMetas/Helloworld.tsx @@ -1,3 +1,3 @@ -export function helloCustomer() { +export function helloCustomer(): string { return 'Hello from Customers module!'; } diff --git a/002_source/cms/src/db/Users/GetAll.tsx b/002_source/cms/src/db/Users/GetAll.tsx index 1130771..6d63b06 100644 --- a/002_source/cms/src/db/Users/GetAll.tsx +++ b/002_source/cms/src/db/Users/GetAll.tsx @@ -1,6 +1,6 @@ import { pb } from '@/lib/pb'; import { COL_CUSTOMERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; +import type { RecordModel } from 'pocketbase'; export async function getAllCustomers(options = {}): Promise { return pb.collection(COL_CUSTOMERS).getFullList(options); diff --git a/002_source/cms/src/db/Users/Helloworld.tsx b/002_source/cms/src/db/Users/Helloworld.tsx index efbb76d..0714592 100644 --- a/002_source/cms/src/db/Users/Helloworld.tsx +++ b/002_source/cms/src/db/Users/Helloworld.tsx @@ -1,3 +1,3 @@ -export function helloUser() { +export function helloUser(): string { return 'Hello from Users module!'; } diff --git a/002_source/cms/src/db/Vocabularies/Create.tsx b/002_source/cms/src/db/Vocabularies/Create.tsx index 6b475be..58a76e4 100644 --- a/002_source/cms/src/db/Vocabularies/Create.tsx +++ b/002_source/cms/src/db/Vocabularies/Create.tsx @@ -1,8 +1,9 @@ import { COL_VOCABULARIES } from '@/constants'; -import type { Vocabulary, VocabularyCreate } from './type'; import { pb } from '@/lib/pb'; +import type { Vocabulary, VocabularyCreate } from './type'; + export default function createVocabulary(data: VocabularyCreate): Promise { return pb.collection(COL_VOCABULARIES).create(data); } diff --git a/002_source/cms/src/db/Vocabularies/Delete.tsx b/002_source/cms/src/db/Vocabularies/Delete.tsx index 39a001b..8e20b07 100644 --- a/002_source/cms/src/db/Vocabularies/Delete.tsx +++ b/002_source/cms/src/db/Vocabularies/Delete.tsx @@ -1,4 +1,5 @@ import { COL_VOCABULARIES } from '@/constants'; + import { pb } from '@/lib/pb'; export default function deleteVocabulary(id: string): Promise { diff --git a/002_source/cms/src/db/Vocabularies/GetAll.tsx b/002_source/cms/src/db/Vocabularies/GetAll.tsx index f6c35a9..d52fa41 100644 --- a/002_source/cms/src/db/Vocabularies/GetAll.tsx +++ b/002_source/cms/src/db/Vocabularies/GetAll.tsx @@ -1,8 +1,9 @@ import { COL_VOCABULARIES } from '@/constants'; -import type { Vocabularies } from './type'; import { pb } from '@/lib/pb'; +import type { Vocabularies } from './type'; + export default function getAllVocabularies(): Promise { return pb.collection(COL_VOCABULARIES).getFullList(); } diff --git a/002_source/cms/src/db/Vocabularies/GetById.tsx b/002_source/cms/src/db/Vocabularies/GetById.tsx index defcf4d..d4015a1 100644 --- a/002_source/cms/src/db/Vocabularies/GetById.tsx +++ b/002_source/cms/src/db/Vocabularies/GetById.tsx @@ -1,8 +1,9 @@ import { COL_VOCABULARIES } from '@/constants'; -import type { Vocabulary } from './type'; import { pb } from '@/lib/pb'; +import type { Vocabulary } from './type'; + export default function getVocabularyById(id: string): Promise { return pb.collection(COL_VOCABULARIES).getOne(id); } diff --git a/002_source/cms/src/db/Vocabularies/GetHiddenCount.tsx b/002_source/cms/src/db/Vocabularies/GetHiddenCount.tsx index d5abacd..4203026 100644 --- a/002_source/cms/src/db/Vocabularies/GetHiddenCount.tsx +++ b/002_source/cms/src/db/Vocabularies/GetHiddenCount.tsx @@ -1,4 +1,5 @@ import { COL_VOCABULARIES } from '@/constants'; + import { pb } from '@/lib/pb'; export default function getHiddenVocabulariesCount(): Promise { diff --git a/002_source/cms/src/db/Vocabularies/GetVisibleCount.tsx b/002_source/cms/src/db/Vocabularies/GetVisibleCount.tsx index 68d5e6c..a208af1 100644 --- a/002_source/cms/src/db/Vocabularies/GetVisibleCount.tsx +++ b/002_source/cms/src/db/Vocabularies/GetVisibleCount.tsx @@ -1,4 +1,5 @@ import { COL_VOCABULARIES } from '@/constants'; + import { pb } from '@/lib/pb'; export default function getVisibleVocabulariesCount(): Promise { diff --git a/002_source/cms/src/db/Vocabularies/Update.tsx b/002_source/cms/src/db/Vocabularies/Update.tsx index ac961b9..6c1db27 100644 --- a/002_source/cms/src/db/Vocabularies/Update.tsx +++ b/002_source/cms/src/db/Vocabularies/Update.tsx @@ -1,6 +1,8 @@ import { COL_VOCABULARIES } from '@/constants'; import type { RecordModel } from 'pocketbase'; + import { pb } from '@/lib/pb'; + import type { EditFormProps } from './type'; export default function updateVocabulary(id: string, data: EditFormProps): Promise { diff --git a/002_source/cms/src/db/Vocabularies/type.d.tsx b/002_source/cms/src/db/Vocabularies/type.d.ts similarity index 100% rename from 002_source/cms/src/db/Vocabularies/type.d.tsx rename to 002_source/cms/src/db/Vocabularies/type.d.ts diff --git a/002_source/cms/src/db/billingAddress/Delete.tsx b/002_source/cms/src/db/billingAddress/Delete.tsx index 9f29ed9..e3d42a6 100644 --- a/002_source/cms/src/db/billingAddress/Delete.tsx +++ b/002_source/cms/src/db/billingAddress/Delete.tsx @@ -1,5 +1,6 @@ +import { COL_USER_METAS } from '@/constants'; + import { pb } from '@/lib/pb'; -import { COL_STUDENTS, COL_USER_METAS } from '@/constants'; export async function deleteStudent(id: string): Promise { return pb.collection(COL_USER_METAS).delete(id); diff --git a/002_source/cms/src/db/billingAddress/GetActiveCount.tsx b/002_source/cms/src/db/billingAddress/GetActiveCount.tsx index 58eb51b..3be4a14 100644 --- a/002_source/cms/src/db/billingAddress/GetActiveCount.tsx +++ b/002_source/cms/src/db/billingAddress/GetActiveCount.tsx @@ -1,4 +1,5 @@ -import { COL_STUDENTS, COL_USER_METAS } from '@/constants'; +import { COL_USER_METAS } from '@/constants'; + import { pb } from '@/lib/pb'; export default async function GetActiveCount(): Promise { diff --git a/002_source/cms/src/db/billingAddress/GetAll.tsx b/002_source/cms/src/db/billingAddress/GetAll.tsx index 1e7c2c1..b6b23fc 100644 --- a/002_source/cms/src/db/billingAddress/GetAll.tsx +++ b/002_source/cms/src/db/billingAddress/GetAll.tsx @@ -1,6 +1,6 @@ import { pb } from '@/lib/pb'; import { COL_STUDENTS } from '@/constants'; -import { RecordModel } from 'pocketbase'; +import type { RecordModel } from 'pocketbase'; export async function getAllStudents(options = {}): Promise { return pb.collection(COL_STUDENTS).getFullList(options); diff --git a/002_source/cms/src/db/billingAddress/Helloworld.tsx b/002_source/cms/src/db/billingAddress/Helloworld.tsx index 2487997..a8e5889 100644 --- a/002_source/cms/src/db/billingAddress/Helloworld.tsx +++ b/002_source/cms/src/db/billingAddress/Helloworld.tsx @@ -1,3 +1,3 @@ -export function helloCustomer() { +export function helloCustomer(): string { return 'Hello from Customers module!'; } diff --git a/002_source/cms/src/hooks/use-helloworld.ts b/002_source/cms/src/hooks/use-helloworld.ts index f453736..56ceddb 100644 --- a/002_source/cms/src/hooks/use-helloworld.ts +++ b/002_source/cms/src/hooks/use-helloworld.ts @@ -19,6 +19,7 @@ export function useHelloworld(): DialogController { }, []); React.useEffect(() => { + // eslint-disable-next-line no-console console.log('helloworld from useHelloworld'); }, []); diff --git a/002_source/cms/src/lib/file-to-base64.tsx b/002_source/cms/src/lib/file-to-base64.tsx index 5acdf73..40acef5 100644 --- a/002_source/cms/src/lib/file-to-base64.tsx +++ b/002_source/cms/src/lib/file-to-base64.tsx @@ -15,7 +15,7 @@ export function base64ToFile(base64String: string, filename?: string): Promise { const arr = base64String.split(','); // eslint-disable-next-line prefer-named-capture-group - const type = arr[0].match(/:(.*?);/)![1]; + const type = /:(.*?);/.exec(arr[0])![1]; const bstr = atob(arr[1]); let n = bstr.length; const u8arr = new Uint8Array(n);