diff --git a/002_source/cms/.env.development b/002_source/cms/.env.development index 106ac87..c71db6f 100644 --- a/002_source/cms/.env.development +++ b/002_source/cms/.env.development @@ -58,3 +58,4 @@ NEXT_PUBLIC_MAPBOX_API_KEY= # Google Tag Manager NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ID= +NEXT_PUBLIC_POCKETBASE_URL=http://localhost:8090 \ No newline at end of file diff --git a/002_source/cms/.env.example b/002_source/cms/.env.example index 95da3b6..d11ec44 100644 --- a/002_source/cms/.env.example +++ b/002_source/cms/.env.example @@ -38,3 +38,5 @@ NEXT_PUBLIC_MAPBOX_API_KEY= # Google Tag Manager NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ID= + +NEXT_PUBLIC_POCKETBASE_URL=http://localhost:8090 \ No newline at end of file diff --git a/002_source/cms/src/app/dashboard/lesson_types/db.ts b/002_source/cms/src/app/dashboard/lesson_types/db.ts new file mode 100644 index 0000000..f4a2523 --- /dev/null +++ b/002_source/cms/src/app/dashboard/lesson_types/db.ts @@ -0,0 +1,5 @@ +import PocketBase, { RecordModel } from 'pocketbase'; + +export function Helloworld(): string { + return 'helloworld'; +} diff --git a/002_source/cms/src/app/dashboard/lesson_types/page.tsx b/002_source/cms/src/app/dashboard/lesson_types/page.tsx index af65ff3..cb2352d 100644 --- a/002_source/cms/src/app/dashboard/lesson_types/page.tsx +++ b/002_source/cms/src/app/dashboard/lesson_types/page.tsx @@ -9,12 +9,15 @@ import Divider from '@mui/material/Divider'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; import { Plus as PlusIcon } from '@phosphor-icons/react/dist/ssr/Plus'; +import type { RecordModel } from 'pocketbase'; +import PocketBase from 'pocketbase'; import { useTranslation } from 'react-i18next'; import { paths } from '@/paths'; import { logger } from '@/lib/default-logger'; import { toast } from '@/components/core/toaster'; import type { LessonType } from '@/components/dashboard/lesson_type/ILessonType'; +import { safeAssignment } from '@/components/dashboard/lesson_type/interfaces'; import { LessonTypesFilters } from '@/components/dashboard/lesson_type/lesson-types-filters'; import type { Filters } from '@/components/dashboard/lesson_type/lesson-types-filters'; import { LessonTypesPagination } from '@/components/dashboard/lesson_type/lesson-types-pagination'; @@ -22,46 +25,55 @@ import { LessonTypesSelectionProvider } from '@/components/dashboard/lesson_type import { LessonTypesTable } from '@/components/dashboard/lesson_type/lesson-types-table'; import FormLoading from '@/components/loading'; +import { Helloworld } from './db'; + +const pb = new PocketBase(process.env.NEXT_PUBLIC_POCKETBASE_URL); + interface PageProps { searchParams: { email?: string; phone?: string; sortDir?: 'asc' | 'desc'; - status?: string; - name?: string; - visible?: string; - type?: string; + spStatus?: string; + spName?: string; + spVisible?: string; + spType?: string; // }; } export default function Page({ searchParams }: PageProps): React.JSX.Element { const { t } = useTranslation(); - const { email, phone, sortDir, status, name, visible, type } = searchParams; + const { email, phone, sortDir, spStatus, spName, spVisible, spType } = searchParams; const router = useRouter(); const [isLoadingAddPage, setIsLoadingAddPage] = React.useState(false); const [lessonTypesData, setLessonTypesData] = React.useState([]); + // const [recordModel, setRecordModel] = React.useState([]); const sortedLessonTypes = applySort(lessonTypesData, sortDir); const filteredLessonTypes = applyFilters(sortedLessonTypes, { email, phone, - status, - name, - type, - visible, + spStatus, + spName, + spType, + spVisible, // }); const reloadRows = () => { - // listLessonTypes() - // .then((lessonTypes: LessonType[]) => { - // setLessonTypesData(lessonTypes); - // }) - // .catch((err) => { - // logger.error(err); - // toast(t('dashboard.lessonTypes.list.error')); - // }); + pb.collection('LessonsTypes') + .getFullList() + .then((lessonTypes: RecordModel[]) => { + const tempLessonTypes: LessonType[] = lessonTypes.map((lt) => { + return safeAssignment(lt); + }); + setLessonTypesData(tempLessonTypes); + }) + .catch((err) => { + logger.error(err); + toast(t('dashboard.lessonTypes.list.error')); + }); }; React.useEffect(() => { @@ -102,7 +114,7 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { @@ -131,7 +143,10 @@ function applySort(row: LessonType[], sortDir: 'asc' | 'desc' | undefined): Less }); } -function applyFilters(row: LessonType[], { email, phone, status, name, visible }: Filters): LessonType[] { +function applyFilters( + row: LessonType[], + { email, phone, spStatus: status, spName: name, spVisible: visible }: Filters +): LessonType[] { return row.filter((item) => { if (email) { if (!item.email?.toLowerCase().includes(email.toLowerCase())) { diff --git a/002_source/cms/src/components/dashboard/lesson_type/interfaces.ts b/002_source/cms/src/components/dashboard/lesson_type/interfaces.ts index 5a74d89..e6b18cc 100644 --- a/002_source/cms/src/components/dashboard/lesson_type/interfaces.ts +++ b/002_source/cms/src/components/dashboard/lesson_type/interfaces.ts @@ -1,3 +1,9 @@ +import type { RecordModel } from 'pocketbase'; + +import { dayjs } from '@/lib/dayjs'; + +import type { LessonType } from './ILessonType'; + export interface LessonTypeEditFormProps { name: string; type: string; @@ -23,3 +29,41 @@ export const LessonTypeCreateFormDefault: LessonTypeCreateForm = { pos: 1, visible: 'visible', }; + +export const defaultLessonType: LessonType = { + id: 'string', + name: 'string', + type: 'string', + pos: 1, + visible: 'visible', + createdAt: dayjs().toDate(), + // + // original + // id: 'string', + // name: 'string', + // + avatar: 'string', + email: 'string', + phone: 'string', + quota: 1, + status: 'pending', + // createdAt: Date; +}; + +export function safeAssignment(inTemp: LessonType | RecordModel): LessonType { + const { id, name, type, pos, visible, createdAt, email, quota, status } = { ...defaultLessonType, ...inTemp }; + const oCreatedAt = dayjs(createdAt).toDate(); + + const output: LessonType = { + id, + name, + type, + pos, + visible, + createdAt: oCreatedAt, + email, + quota, + status, + }; + return output; +} diff --git a/002_source/cms/src/components/dashboard/lesson_type/lesson-types-filters.tsx b/002_source/cms/src/components/dashboard/lesson_type/lesson-types-filters.tsx index abb6f42..05c3503 100644 --- a/002_source/cms/src/components/dashboard/lesson_type/lesson-types-filters.tsx +++ b/002_source/cms/src/components/dashboard/lesson_type/lesson-types-filters.tsx @@ -19,16 +19,16 @@ import { paths } from '@/paths'; import { FilterButton, FilterPopover, useFilterContext } from '@/components/core/filter-button'; import { Option } from '@/components/core/option'; -import { LessonType } from './ILessonType'; +import type { LessonType } from './ILessonType'; import { useLessonTypesSelection } from './lesson-types-selection-context'; export interface Filters { email?: string; phone?: string; - status?: string; - name?: string; - visible?: string; - type?: string; + spStatus?: string; + spName?: string; + spVisible?: string; + spType?: string; } export type SortDir = 'asc' | 'desc'; @@ -45,7 +45,7 @@ export function LessonTypesFilters({ fullData, }: LessonTypesFiltersProps): React.JSX.Element { const { t } = useTranslation(); - const { email, phone, status, name, visible, type } = filters; + const { email, phone, spStatus: status, spName, spVisible, spType } = filters; const router = useRouter(); @@ -81,8 +81,8 @@ export function LessonTypesFilters({ searchParams.set('sortDir', newSortDir); } - if (newFilters.status) { - searchParams.set('status', newFilters.status); + if (newFilters.spStatus) { + searchParams.set('status', newFilters.spStatus); } if (newFilters.email) { @@ -93,16 +93,16 @@ export function LessonTypesFilters({ searchParams.set('phone', newFilters.phone); } - if (newFilters.name) { - searchParams.set('name', newFilters.name); + if (newFilters.spName) { + searchParams.set('name', newFilters.spName); } - if (newFilters.type) { - searchParams.set('type', newFilters.type); + if (newFilters.spType) { + searchParams.set('type', newFilters.spType); } - if (newFilters.visible) { - searchParams.set('visible', newFilters.visible); + if (newFilters.spVisible) { + searchParams.set('visible', newFilters.spVisible); } router.push(`${paths.dashboard.lesson_types.list}?${searchParams.toString()}`); @@ -116,28 +116,28 @@ export function LessonTypesFilters({ const handleStatusChange = React.useCallback( (_: React.SyntheticEvent, value: string) => { - updateSearchParams({ ...filters, status: value }, sortDir); + updateSearchParams({ ...filters, spStatus: value }, sortDir); }, [updateSearchParams, filters, sortDir] ); const handleVisibleChange = React.useCallback( (_: React.SyntheticEvent, value: string) => { - updateSearchParams({ ...filters, visible: value }, sortDir); + updateSearchParams({ ...filters, spVisible: value }, sortDir); }, [updateSearchParams, filters, sortDir] ); const handleNameChange = React.useCallback( (value?: string) => { - updateSearchParams({ ...filters, name: value }, sortDir); + updateSearchParams({ ...filters, spName: value }, sortDir); }, [updateSearchParams, filters, sortDir] ); const handleTypeChange = React.useCallback( (value?: string) => { - updateSearchParams({ ...filters, type: value }, sortDir); + updateSearchParams({ ...filters, spType: value }, sortDir); }, [updateSearchParams, filters, sortDir] ); @@ -163,11 +163,11 @@ export function LessonTypesFilters({ [updateSearchParams, filters] ); - const hasFilters = status || email || phone || visible || name || type; + const hasFilters = status || email || phone || spVisible || spName || spType; return (
- + {tabs.map((tab) => ( } @@ -184,7 +184,7 @@ export function LessonTypesFilters({ { handleNameChange(value as string); @@ -193,11 +193,11 @@ export function LessonTypesFilters({ handleNameChange(); }} popover={} - value={name} + value={spName} /> { handleTypeChange(value as string); @@ -206,7 +206,7 @@ export function LessonTypesFilters({ handleTypeChange(); }} popover={} - value={type} + value={spType} /> {/* diff --git a/002_source/cms/src/lib/pb.ts b/002_source/cms/src/lib/pb.ts new file mode 100644 index 0000000..d564382 --- /dev/null +++ b/002_source/cms/src/lib/pb.ts @@ -0,0 +1,3 @@ +import PocketBase from 'pocketbase'; + +export const pb = new PocketBase(process.env.NEXT_PUBLIC_POCKETBASE_URL);