From c4c392b91ba43c12b2b63e2a22e806b32959fc7b Mon Sep 17 00:00:00 2001 From: louiscklaw Date: Thu, 17 Apr 2025 06:20:47 +0800 Subject: [PATCH] update page, --- 002_source/cms/src/app/_helloworld/_PROMPT.MD | 9 ++ 002_source/cms/src/app/_helloworld/page.tsx | 55 ++++++++++++ .../app/dashboard/lesson_categories/page.tsx | 21 ++++- .../cms/src/components/_helloworld/index.tsx | 50 +++++++++++ .../src/components/dashboard/error/_PROMPT.MD | 9 ++ .../src/components/dashboard/error/index.tsx | 84 +++++++++++++++++++ .../lesson-categories-table.tsx | 78 +++++++++++------ .../lesson_type/lesson-types-table.tsx | 32 +++---- 8 files changed, 299 insertions(+), 39 deletions(-) create mode 100644 002_source/cms/src/app/_helloworld/_PROMPT.MD create mode 100644 002_source/cms/src/app/_helloworld/page.tsx create mode 100644 002_source/cms/src/components/_helloworld/index.tsx create mode 100644 002_source/cms/src/components/dashboard/error/_PROMPT.MD create mode 100644 002_source/cms/src/components/dashboard/error/index.tsx diff --git a/002_source/cms/src/app/_helloworld/_PROMPT.MD b/002_source/cms/src/app/_helloworld/_PROMPT.MD new file mode 100644 index 0000000..2adf4be --- /dev/null +++ b/002_source/cms/src/app/_helloworld/_PROMPT.MD @@ -0,0 +1,9 @@ +# task + +## instruction + +with reference to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/app/_helloworld/page.tsx` + +please modify `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/error/index.tsx` + +please draft a tsx for showing error to user thanks, diff --git a/002_source/cms/src/app/_helloworld/page.tsx b/002_source/cms/src/app/_helloworld/page.tsx new file mode 100644 index 0000000..9188ee9 --- /dev/null +++ b/002_source/cms/src/app/_helloworld/page.tsx @@ -0,0 +1,55 @@ +'use client'; + +import * as React from 'react'; +import { Typography } from '@mui/material'; +import Box from '@mui/material/Box'; +import { useTranslation } from 'react-i18next'; + +import ErrorDisplay from '@/components/dashboard/error'; +import FormLoading from '@/components/loading'; + +interface PageProps { + hello: { + world: string; + }; +} + +export default function Page({ hello }: PageProps): React.JSX.Element { + const { t } = useTranslation(); + const [state, setState] = React.useState(hello.world); + + // + const [showError, setShowError] = React.useState(false); + const [showLoading, setShowLoading] = React.useState(true); + + React.useEffect(() => { + setShowLoading(false); + setShowError(false); + setState('blablabla'); + }, []); + + if (showLoading) return ; + + if (showError) + return ( + + ); + + return ( + + Hello World + {state} + + ); +} diff --git a/002_source/cms/src/app/dashboard/lesson_categories/page.tsx b/002_source/cms/src/app/dashboard/lesson_categories/page.tsx index e376b8d..1d9371c 100644 --- a/002_source/cms/src/app/dashboard/lesson_categories/page.tsx +++ b/002_source/cms/src/app/dashboard/lesson_categories/page.tsx @@ -17,6 +17,7 @@ import { paths } from '@/paths'; import { logger } from '@/lib/default-logger'; import { pb } from '@/lib/pb'; import { toast } from '@/components/core/toaster'; +import ErrorDisplay from '@/components/dashboard/error'; import { defaultLessonCategory, type LessonCategory } from '@/components/dashboard/lesson_category/interfaces'; import { LessonCategoriesFilters } from '@/components/dashboard/lesson_category/lesson-categories-filters'; import type { Filters } from '@/components/dashboard/lesson_category/lesson-categories-filters'; @@ -48,6 +49,9 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { const [recordCount, setRecordCount] = React.useState(0); const [rowsPerPage, setRowsPerPage] = React.useState(5); const [currentPage, setCurrentPage] = React.useState(1); + // + const [showError, setShowError] = React.useState(false); + const [showLoading, setShowLoading] = React.useState(true); // const [isLoadingAddPage, setIsLoadingAddPage] = React.useState(false); @@ -57,6 +61,8 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { const filteredLessonCategories = applyFilters(sortedLessonCategories, { email, phone, status: spStatus }); const reloadRows = () => { + setShowLoading(true); + pb.collection(COL_LESSON_CATEGORIES) .getList(currentPage, rowsPerPage, {}) .then((lessonCategories: ListResult) => { @@ -72,6 +78,10 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { .catch((err) => { logger.error(err); toast(t('dashboard.lessonTypes.list.error')); + setShowError(true); + }) + .finally(() => { + setShowLoading(false); }); }; @@ -79,7 +89,16 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { reloadRows(); }, []); - if (lessonCategoriesData.length < 1) return ; + if (showLoading) return ; + + if (showError) + return ( + + ); // return
{JSON.stringify(lessonCategoriesData, null, 2)}
; diff --git a/002_source/cms/src/components/_helloworld/index.tsx b/002_source/cms/src/components/_helloworld/index.tsx new file mode 100644 index 0000000..b827db7 --- /dev/null +++ b/002_source/cms/src/components/_helloworld/index.tsx @@ -0,0 +1,50 @@ +'use client'; + +import * as React from 'react'; +import { Typography } from '@mui/material'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import { Box } from '@mui/system'; +import { Trash as TrashIcon } from '@phosphor-icons/react/dist/ssr/Trash'; + +interface PropsHelloworld { + message: string; +} + +// RULES: Sample of function +function funcHelloworld(hello: string): string { + const helloworld: PropsHelloworld = { message: hello }; + const output = `${helloworld.message} world!`; + + return output; +} + +// RULES: sample of inner component +function InnerComponent(): React.JSX.Element { + return ( + + inner component + + + + ); +} + +// RULES: naming should be in Pascal case +// RULES: sample of main component +function MainComponent(): React.JSX.Element { + const [state, setState] = React.useState(''); + + React.useEffect(() => { + setState(funcHelloworld('hello')); + }, []); + + // you should obey react/jsx-no-useless-fragment + return ( + + {state} + + ); +} + +// RULES: component should be exported +export default MainComponent; diff --git a/002_source/cms/src/components/dashboard/error/_PROMPT.MD b/002_source/cms/src/components/dashboard/error/_PROMPT.MD new file mode 100644 index 0000000..bfadd8b --- /dev/null +++ b/002_source/cms/src/components/dashboard/error/_PROMPT.MD @@ -0,0 +1,9 @@ +# task + +## instruction + +with reference to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/_helloworld/index.tsx` + +please modify `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/error/index.tsx` + +please draft a tsx for showing error to user thanks, diff --git a/002_source/cms/src/components/dashboard/error/index.tsx b/002_source/cms/src/components/dashboard/error/index.tsx new file mode 100644 index 0000000..9c13eb1 --- /dev/null +++ b/002_source/cms/src/components/dashboard/error/index.tsx @@ -0,0 +1,84 @@ +'use client'; + +import * as React from 'react'; +import { Alert, AlertTitle, Collapse, Typography } from '@mui/material'; +import { Box } from '@mui/system'; +import { Warning as WarningIcon } from '@phosphor-icons/react/dist/ssr/Warning'; + +interface PropsError { + message: string; + code?: string | number; + details?: string; + severity?: 'error' | 'warning' | 'info' | 'success'; +} + +// RULES: Sample of function +function formatErrorMessage(message: string, code?: string | number): string { + return code ? `[${code}] ${message}` : message; +} + +// RULES: sample of inner component +function ErrorDetails({ details }: { details: string }): React.JSX.Element { + const [expanded, setExpanded] = React.useState(false); + + return ( + + { + setExpanded(!expanded); + }} + > + {expanded ? 'Hide Details' : 'Show Details'} + + + + + + {details} + + + + + ); +} + +// RULES: naming should be in Pascal case +// RULES: sample of main component +function ErrorDisplay({ message, code, details, severity = 'error' }: PropsError): React.JSX.Element { + const [formattedMessage, setFormattedMessage] = React.useState(''); + + React.useEffect(() => { + setFormattedMessage(formatErrorMessage(message, code)); + }, [message, code]); + + return ( + + } + sx={{ + '& .MuiAlert-message': { + width: '100%', + }, + }} + > + {code ? `Error ${code}` : 'Error'} + + + {formattedMessage} + + + {details && } + + + ); +} + +// RULES: component should be exported +export default ErrorDisplay; 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 d1b2c57..863cd58 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 @@ -33,25 +33,27 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef ( - - - - - {' '} -
- {row.cat_name} - - slug: {row.cat_name} - -
-
- + + + + + + {' '} +
+ {row.cat_name} + + slug: {row.cat_name} + +
+
+ +
), name: 'Name', width: '200px', @@ -74,6 +76,9 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef { + // eslint-disable-next-line react-hooks/rules-of-hooks + const { t } = useTranslation(); + const mapping = { active: { label: 'Active', icon: }, blocked: { label: 'Blocked', icon: }, @@ -82,7 +87,17 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef; + return ( + + ); }, name: 'Status', width: '150px', @@ -95,10 +110,25 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef ( - - - + formatter: (row): React.JSX.Element => ( + + + + + { + handleDeleteClick(row.id); + }} + > + + + ), name: 'Actions', hideName: true, diff --git a/002_source/cms/src/components/dashboard/lesson_type/lesson-types-table.tsx b/002_source/cms/src/components/dashboard/lesson_type/lesson-types-table.tsx index c5eb5ab..17845d7 100644 --- a/002_source/cms/src/components/dashboard/lesson_type/lesson-types-table.tsx +++ b/002_source/cms/src/components/dashboard/lesson_type/lesson-types-table.tsx @@ -33,17 +33,15 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef ( -
- - {row.isEmpty ? '--' : row.name} - -
+ + {row.isEmpty ? '--' : row.name} +
), name: 'Name', @@ -129,16 +127,21 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef ( - + void): ColumnDef ), name: 'Actions', + hideName: true, width: '100px', align: 'right', },