From 6e8fea3bddf92c17b68b7758f47c9b424846d1a3 Mon Sep 17 00:00:00 2001 From: louiscklaw Date: Sat, 26 Apr 2025 06:15:18 +0800 Subject: [PATCH] update, --- .../_AI_WORKSPACE/code/002_update_app_page.md | 20 + .../code/004-update-constants-file.md | 13 + .../code/005_review-function-name.md | 13 + 002_source/cms/_AI_WORKSPACE/db/001_INIT.md | 15 +- .../_AI_WORKSPACE/db/004_clone_db_driver.md | 11 +- 002_source/cms/autogen_config.py | 0 002_source/cms/public/locales/dev/PROMPT.md | 39 - 002_source/cms/public/locales/dev/common.json | 136 +- .../public/locales/dev/lesson_category.json | 70 - .../cms/public/locales/dev/lesson_type.json | 65 - .../locales/dev/listening_practice.json | 36 - .../cms/public/locales/dev/translation.json | 203 - .../edit/[cat_id]/_PROMPT.md | 11 - .../src/app/dashboard/teachers/list/page.tsx | 45 - .../dashboard/vocabularies/create/page.tsx | 10 +- .../vocabularies/edit/[cat_id]/_PROMPT.md | 11 - .../vocabularies/edit/[cat_id]/page.tsx | 12 +- .../app/dashboard/vocabularies/list/page.tsx | 172 +- .../vocabularies/view/[cat_id]/page.tsx | 169 +- .../cr/categories/cr-category-edit-form.tsx | 2 +- .../src/components/dashboard/layout/config.ts | 10 +- .../dashboard/lesson_category/type.d.ts | 2 + .../mf/categories/mf-category-edit-form.tsx | 2 +- .../components/dashboard/student/type.d.tsx | 7 + .../components/dashboard/teacher/type.d.tsx | 6 + .../dashboard/vocabulary/_constants.ts | 68 +- .../vocabulary/confirm-delete-modal.tsx | 50 +- .../dashboard/vocabulary/interfaces.1ts | 64 - .../lesson-categories-selection-context.tsx | 53 - .../vocabulary/lesson-category-edit-form.tsx | 353 - .../dashboard/vocabulary/type.d copy.ts | 36 + .../components/dashboard/vocabulary/type.d.ts | 81 +- ...s-filters.tsx => vocabularies-filters.tsx} | 101 +- ...nation.tsx => vocabularies-pagination.tsx} | 6 +- .../vocabularies-selection-context.tsx | 46 + ...ories-table.tsx => vocabularies-table.tsx} | 136 +- ...te-form.tsx => vocabulary-create-form.tsx} | 152 +- .../vocabulary/vocabulary-edit-form.tsx | 462 + 002_source/cms/src/constants.ts | 4 + .../LessonCategories/listLessonCategories.tsx | 13 + .../cms/src/db/LessonCategories/type.d.ts | 23 + .../Notifications/GetNotificationByUserId.tsx | 2 + 002_source/cms/src/db/Vocabularies/Create.tsx | 8 + 002_source/cms/src/db/Vocabularies/Delete.tsx | 6 + 002_source/cms/src/db/Vocabularies/GetAll.tsx | 8 + .../cms/src/db/Vocabularies/GetAllCount.tsx | 14 + .../cms/src/db/Vocabularies/GetById.tsx | 8 + .../src/db/Vocabularies/GetHiddenCount.tsx | 9 + .../src/db/Vocabularies/GetVisibleCount.tsx | 9 + .../cms/src/db/Vocabularies/Helloworld.tsx | 5 + 002_source/cms/src/db/Vocabularies/Update.tsx | 8 + .../cms/src/db/Vocabularies/_GUIDELINES.md | 30 + 002_source/cms/src/db/Vocabularies/type.d.tsx | 53 + 002_source/cms/src/db/_repomix.md | 12508 ---------------- 002_source/cms/src/db/repomix-output.xml | 6168 -------- .../cms/src/lib/get-image-url-from-file.ts.ts | 3 + 002_source/cms/tsconfig.json | 8 +- 57 files changed, 1392 insertions(+), 20183 deletions(-) create mode 100644 002_source/cms/_AI_WORKSPACE/code/002_update_app_page.md create mode 100644 002_source/cms/_AI_WORKSPACE/code/004-update-constants-file.md create mode 100644 002_source/cms/_AI_WORKSPACE/code/005_review-function-name.md create mode 100644 002_source/cms/autogen_config.py delete mode 100644 002_source/cms/public/locales/dev/PROMPT.md delete mode 100644 002_source/cms/public/locales/dev/lesson_category.json delete mode 100644 002_source/cms/public/locales/dev/lesson_type.json delete mode 100644 002_source/cms/public/locales/dev/listening_practice.json delete mode 100644 002_source/cms/public/locales/dev/translation.json delete mode 100644 002_source/cms/src/app/dashboard/lesson_categories/edit/[cat_id]/_PROMPT.md delete mode 100644 002_source/cms/src/app/dashboard/vocabularies/edit/[cat_id]/_PROMPT.md delete mode 100644 002_source/cms/src/components/dashboard/vocabulary/interfaces.1ts delete mode 100644 002_source/cms/src/components/dashboard/vocabulary/lesson-categories-selection-context.tsx delete mode 100644 002_source/cms/src/components/dashboard/vocabulary/lesson-category-edit-form.tsx create mode 100644 002_source/cms/src/components/dashboard/vocabulary/type.d copy.ts rename 002_source/cms/src/components/dashboard/vocabulary/{lesson-categories-filters.tsx => vocabularies-filters.tsx} (82%) rename 002_source/cms/src/components/dashboard/vocabulary/{lesson-categories-pagination.tsx => vocabularies-pagination.tsx} (88%) create mode 100644 002_source/cms/src/components/dashboard/vocabulary/vocabularies-selection-context.tsx rename 002_source/cms/src/components/dashboard/vocabulary/{lesson-categories-table.tsx => vocabularies-table.tsx} (63%) rename 002_source/cms/src/components/dashboard/vocabulary/{lesson-category-create-form.tsx => vocabulary-create-form.tsx} (70%) create mode 100644 002_source/cms/src/components/dashboard/vocabulary/vocabulary-edit-form.tsx create mode 100644 002_source/cms/src/db/LessonCategories/listLessonCategories.tsx create mode 100644 002_source/cms/src/db/LessonCategories/type.d.ts create mode 100644 002_source/cms/src/db/Vocabularies/Create.tsx create mode 100644 002_source/cms/src/db/Vocabularies/Delete.tsx create mode 100644 002_source/cms/src/db/Vocabularies/GetAll.tsx create mode 100644 002_source/cms/src/db/Vocabularies/GetAllCount.tsx create mode 100644 002_source/cms/src/db/Vocabularies/GetById.tsx create mode 100644 002_source/cms/src/db/Vocabularies/GetHiddenCount.tsx create mode 100644 002_source/cms/src/db/Vocabularies/GetVisibleCount.tsx create mode 100644 002_source/cms/src/db/Vocabularies/Helloworld.tsx create mode 100644 002_source/cms/src/db/Vocabularies/Update.tsx create mode 100644 002_source/cms/src/db/Vocabularies/_GUIDELINES.md create mode 100644 002_source/cms/src/db/Vocabularies/type.d.tsx delete mode 100644 002_source/cms/src/db/_repomix.md delete mode 100644 002_source/cms/src/db/repomix-output.xml create mode 100644 002_source/cms/src/lib/get-image-url-from-file.ts.ts diff --git a/002_source/cms/_AI_WORKSPACE/code/002_update_app_page.md b/002_source/cms/_AI_WORKSPACE/code/002_update_app_page.md new file mode 100644 index 0000000..a0e834d --- /dev/null +++ b/002_source/cms/_AI_WORKSPACE/code/002_update_app_page.md @@ -0,0 +1,20 @@ +# task + +update app page to cover `vocabulary` + +## steps + +1. read `tsx` from folder: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/app/dashboard/vocabularies.draft` +1. fix the paths, variable, function names, class etc from `lesson-categories` to `vocabularies`. + +thanks + +## FAQ + +1. 在 `constants.ts` 中是否已定义 `COL_VOCABULARIES` 常量?没有,需要先定义它。 +2. Vocabulary 相关的类型定义在哪里?是在现有文件中还是需要新建? 需要新建 +3. 是否需要保留原始 `lessonCategories` 驱动文件? 不需要 + +- `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/app/dashboard/vocabularies.draft` + +- `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/vocabulary.draft` diff --git a/002_source/cms/_AI_WORKSPACE/code/004-update-constants-file.md b/002_source/cms/_AI_WORKSPACE/code/004-update-constants-file.md new file mode 100644 index 0000000..b624bdf --- /dev/null +++ b/002_source/cms/_AI_WORKSPACE/code/004-update-constants-file.md @@ -0,0 +1,13 @@ +--- +tags: update-constants-file +--- + +# task + +update constants file + +## steps + +- have a look to `_constants.ts` files in slibing directory +- get the convention +- update `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/vocabulary/_constants.ts` according to dbml thanks diff --git a/002_source/cms/_AI_WORKSPACE/code/005_review-function-name.md b/002_source/cms/_AI_WORKSPACE/code/005_review-function-name.md new file mode 100644 index 0000000..69f8b89 --- /dev/null +++ b/002_source/cms/_AI_WORKSPACE/code/005_review-function-name.md @@ -0,0 +1,13 @@ +--- +tags: review-function-names +--- + +# task + +review function names + +## steps + +- have a look to `tsx` files in slibing directory `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/Vocabularies` +- get the convention +- update the function name of `tsx` file in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/Vocabularies` diff --git a/002_source/cms/_AI_WORKSPACE/db/001_INIT.md b/002_source/cms/_AI_WORKSPACE/db/001_INIT.md index d794e3d..9fcaa0a 100644 --- a/002_source/cms/_AI_WORKSPACE/db/001_INIT.md +++ b/002_source/cms/_AI_WORKSPACE/db/001_INIT.md @@ -16,7 +16,8 @@ they will: ## project background and initial setup -- No need to reply me what you are going on and your digest in this phase. +- **IMPORTANT**: No need to reply me what you are going on and your digest in this phase. + No need to show me your code plan Just reply me "OK" when done - base_dir=`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project` @@ -36,9 +37,13 @@ they will: - look into the md files in folder `/002_source/cms/_AI_WORKSPACE/001_guideline` -- directory may contain `repomix-output.xml` file, that is a simple summary of all files inside the directory - - if the directory user provided contins `_GUIDELINES.md`, please read the file -- read the files, remember and link up the ideas in file stated above, - i will tell them the task afterwards +- read the files, remember and link up the ideas in file stated above, i will tell them the task afterwards + +- please review at least 3 times after you modified the code + +## frameworks documentation and samples + +- `MUI` + - `/002_source/cms/src/components/widgets/forms` contains sample forms, diff --git a/002_source/cms/_AI_WORKSPACE/db/004_clone_db_driver.md b/002_source/cms/_AI_WORKSPACE/db/004_clone_db_driver.md index 96db63c..2dcc01f 100644 --- a/002_source/cms/_AI_WORKSPACE/db/004_clone_db_driver.md +++ b/002_source/cms/_AI_WORKSPACE/db/004_clone_db_driver.md @@ -5,16 +5,15 @@ tags: db, driver # clone db driver please understand the tsx files in folder -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/Notifications` +`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/vocabularies.draft` -change all occurrence of `customer` to `notification` thanks. +change all occurrence of `lessonCategories` to `vocabularies` thanks. ## FAQ -1. 在constants.ts中是否已定义COL_NOTIFICATIONS常量?没有,需要先定义它。 -2. Notification相关的类型定义在哪里?是在现有文件中还是需要新建? 需要新建 -3. 是否需要保留原始Customer驱动文件,还是完全替换为Notification驱动? -用 `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/Notifications` 中的 code +1. 在 `constants.ts` 中是否已定义 `COL_VOCABULARIES` 常量?没有,需要先定义它。 +2. Vocabulary 相关的类型定义在哪里?是在现有文件中还是需要新建? 需要新建 +3. 是否需要保留原始 `lessonCategories` 驱动文件? 不需要 请确认这些信息,以便我制定完整的修改方案。 diff --git a/002_source/cms/autogen_config.py b/002_source/cms/autogen_config.py new file mode 100644 index 0000000..e69de29 diff --git a/002_source/cms/public/locales/dev/PROMPT.md b/002_source/cms/public/locales/dev/PROMPT.md deleted file mode 100644 index 1e8acb1..0000000 --- a/002_source/cms/public/locales/dev/PROMPT.md +++ /dev/null @@ -1,39 +0,0 @@ -# PROMPT - -please update `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/public/locales/dev/translation.json` -to add below translations, thanks. - -``` -dashboard.lessonCategories.edit.title -dashboard.lessonCategories.edit.avatar -dashboard.lessonCategories.edit.avatarRequirements -dashboard.lessonCategories.edit.name -dashboard.lessonCategories.edit.type - -``` - ---- - -please read `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lesson_category/lesson-category-edit-form.tsx` -and update `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/public/locales/dev/translation.json` the missing translations, thanks. - ---- - -please refactor `common.json` to smaller translation files, thanks -e.g. `lessonTypes` -> `lesson_type` - ---- - -Hi, i want you to help merge two translation files. - -base_dir=`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/public/locales/dev` - -I want you to merge the content - -from `/lesson_type.json` (source file) -to `/listening_practice.json` (dest file) - -please extract , link up and remember the document properties -(e.g. types, functions, variables, constants, etc) - -update the variables and properties of dest file to reflect `listening practice categories`/`lp_categories` diff --git a/002_source/cms/public/locales/dev/common.json b/002_source/cms/public/locales/dev/common.json index 4ba7d1e..0967ef4 100644 --- a/002_source/cms/public/locales/dev/common.json +++ b/002_source/cms/public/locales/dev/common.json @@ -1,135 +1 @@ -{ - "languageChanged": "語言已更改", - "type": "類型", - "helloworld": "你好,世界", - "Add": "新增項目", - "visible": "可視", - "hidden": "屏閉", - "Hidden": "屏閉", - "Newest": "最新", - "Oldest": "最舊", - "Lesson position": "位置", - "Lesson type": "種類", - "Type": "種類", - "Name": "名稱", - "Filter by name": "依名稱過濾", - "Filter by type": "依類型過濾", - "Actions": "動作", - "Created at": "建立時間", - "Updated at": "更新時間", - "Position": "位置", - "Visible": "顯示", - "Apply": "套用", - "Overview": "概觀", - "Dashboard": "儀表板", - "Tickets": "票券", - "Sign ups": "註冊", - "Open issues": "開啟問題", - "Closed issues": "關閉問題", - "increase": "增加", - "decrease": "減少", - "common.loading": "載入中", - "vs last month": "與上個月相比", - "Dashboards": "儀表板", - "App usage": "應用程式使用情況", - "Find your dream job": "找到你的夢想工作", - "Need help figuring things out?": "需要幫助嗎?", - "Search for jobs that match your skills and apply to them directly": "搜索符合你技能的工作,直接申請", - "Find answers to your questions and get in touch with our team.": "找到你的問題並與我們的團隊聯繫", - "Explore documentation": "探索文件", - "Learn how to get started with our product and make the most of it.": "學習如何開始使用我們的產品並充分利用它", - "Search Jobs": "搜索工作", - "Help Center": "幫助中心", - "Documentation": "文件", - "increase_in_app_usage_with": "使用者量增加", - "new_products_purchased": "新產品購買", - "Our subscriptions": "我們的訂閱", - "this_year": "今年", - "is_forecasted_to_increase_in_your_traffic_by_the_end_of_the_current_month": "今年預計增加你的流量", - "Jan": "一月", - "Feb": "二月", - "Mar": "三月", - "Apr": "四月", - "May": "五月", - "Jun": "六月", - "Jul": "七月", - "Aug": "八月", - "Sep": "九月", - "Oct": "十月", - "Nov": "十一月", - "Dec": "十二月", - "See all subscriptions": "查看所有訂閱", - "app_chat": "應用程式聊天", - "Upcoming events": "即將發生的事件", - "Based on the linked bank accounts": "基於連結的銀行帳戶", - "App limits": "應用程式限制", - "You have used {percentage} of your available spots.": "您已使用 {percentage} 的可用座位。升級計劃以建立更多專案", - "userMessagesUnread": "hello userMessagesUnread", - "Upgrade plan to create more projects": "升級計劃以建立更多專案", - "You have almost reached your limit": "您已接近您的限制", - "Upgrade plan": "升級計劃", - "Help center": "幫助中心", - "Jobs": "工作", - "go_to_chat": "前往聊天", - "See all events": "查看所有事件", - "You have used": "您已使用", - "of your available spots": "的可用座位", - "Paid": "已付款", - "Canceled": "已取消", - "Pending": "待付款", - "Expiring": "已過期", - "Refunded": "已退款", - "Total": "總計", - "Total paid": "已付款", - "Total cancelled": "已取消", - "Total pending": "待付款", - "year": "年", - "month": "月", - "week": "週", - "day": "日", - "hour": "小時", - "minute": "分鐘", - "second": "秒", - "ago": "前", - "remaining": "剩下", - "days": "天", - "hours": "小時", - "minutes": "分鐘", - "seconds": "秒", - "Clear filters": "清除篩選", - "Type information": "輸入資訊", - "Cancel": "取消", - "Delete": "刪除", - "All": "全部", - "categories": "課程分類", - "loading": "載入中", - "Notifications": "通知", - "Mark all as read": "標記所有為已讀", - "There are no notifications": "沒有通知", - "listenings": "聽講 (Listenings)", - "question_category": "問題分類", - "question_list": "問題", - "matching_frenzy": "配對 (Matching Frenzy)", - "connective_revision": "連接詞 (Connective Revision)", - "settings": "設定", - "students": "學生", - "dashboard.lessonCategories.title": "課程分類", - "dashboard.lessonCategorys.edit.name": "課程分類名稱", - "dashboard.lessonCategorys.edit.position": "課程分類順序", - "dashboard.lessonCategorys.edit.title": "編輯課程分類", - "dashboard.lessonCategorys.edit.visibleToUser": "顯示給使用者", - "dashboard.lessonCategorys.edit.visible": "顯示", - "dashboard.lessonCategorys.edit.hidden": "隱藏", - "dashboard.lessonCategorys.edit.cancelButton": "取消", - "dashboard.lessonCategorys.edit.updateButton": "更新", - "dashboard.lessonCategorys.list.title": "課堂種類", - "word-count": "字數", - "unable-to-process-request": "無法處理請求", - "detailed-error-information": "詳細錯誤資訊", - "error": { - "unable-to-process-request": "無法處理您的請求", - "detailed-error-information": "詳細錯誤資訊" - }, - "name-is-required": "名稱為必填", - "listening-practice": "聽講練習" -} \ No newline at end of file +{} diff --git a/002_source/cms/public/locales/dev/lesson_category.json b/002_source/cms/public/locales/dev/lesson_category.json deleted file mode 100644 index 0449768..0000000 --- a/002_source/cms/public/locales/dev/lesson_category.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "add": "新增課程分類", - "title": "課程分類", - "basic_info": "基本資訊", - "error": { - "unable-to-process-request": "無法處理您的請求", - "detailed-error-information": "詳細錯誤資訊" - }, - "create": { - "title": "建立課程類型", - "createButton": "建立", - "cancelButton": "取消", - "message": "請輸入課程類型名稱", - "success": "課程類型建立成功", - "error": "課程類型建立失敗", - "typeInformation": "輸入課程類型資訊", - "avatar": "上傳課程類型圖片", - "avatar_select": "選擇圖片", - "avatarRequirements": "最小 400x400 像素,PNG 或 JPEG", - "select": "請選擇", - "name": "課程類型名稱", - "position": "課程類型順序", - "visibleToUser": "顯示給使用者", - "detail-information": "詳細資訊", - "description": "課程類型描述", - "remarks": "備註" - }, - "edit": { - "avatar": "上傳圖片", - "avatarRequirements": "最小 400x400 像素,PNG 或 JPEG", - "cancelButton": "取消", - "error": "課程類型更新失敗", - "hidden": "隱藏", - "name": "課程分類名稱", - "position": "課程分類順序", - "select": "請選擇", - "success": "課程類型更新成功", - "title": "編輯課程分類", - "basic-info": "基本資訊", - "type": "類型", - "updateButton": "更新", - "visible": "顯示", - "visibleToUser": "顯示給使用者", - "write-something": "輸入一些內容" - }, - "delete": { - "title": "刪除課程類型", - "message": "確定要刪除課程類型嗎?", - "success": "課程類型刪除成功", - "error": "課程類型刪除失敗", - "cancelButton": "取消", - "deleteButton": "刪除" - }, - "list": { - "title": "課堂種類", - "message": "請選擇課程類型", - "empty": { - "title": "目前沒有課程類型", - "message": "請建立課程類型", - "create": "建立課程類型" - }, - "error": "課程類型載入失敗", - "add": "新增課程分類" - }, - "view": { - "basic-details": "基本資訊" - }, - "Delete Lesson Type ?": "刪除課程類型?", - "Are you sure you want to delete lesson type ?": "確定要刪除課程類型嗎?" -} \ No newline at end of file diff --git a/002_source/cms/public/locales/dev/lesson_type.json b/002_source/cms/public/locales/dev/lesson_type.json deleted file mode 100644 index fcd2823..0000000 --- a/002_source/cms/public/locales/dev/lesson_type.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "add": "新增課程類型", - "title": "課程類型", - "type": "類型", - "error": { - "unable-to-process-request": "無法處理您的請求", - "detailed-error-information": "詳細錯誤資訊" - }, - "create": { - "title": "建立課程類型", - "createButton": "建立", - "cancelButton": "取消", - "message": "請輸入課程類型名稱", - "success": "課程類型建立成功", - "error": "課程類型建立失敗", - "typeInformation": "輸入課程類型資訊", - "avatar": "上傳課程類型圖片", - "avatarRequirements": "上傳課程類型圖片", - "select": "請選擇", - "name": "課程類型名稱", - "position": "課程類型順序", - "visibleToUser": "顯示給使用者" - }, - "edit": { - "avatar": "上傳課程類型圖片", - "avatarRequirements": "上傳課程類型圖片", - "cancelButton": "取消", - "error": "課程類型更新失敗", - "hidden": "隱藏", - "name": "課程類型名稱", - "position": "課程類型順序", - "select": "請選擇", - "success": "課程類型更新成功", - "title": "編輯課程類型", - "typeInformation": "輸入課程類型資訊", - "updateButton": "更新", - "visible": "顯示", - "visibleToUser": "顯示給使用者" - }, - "delete": { - "title": "刪除課程類型", - "message": "確定要刪除課程類型嗎?", - "success": "課程類型刪除成功", - "error": "課程類型刪除失敗", - "cancelButton": "取消", - "deleteButton": "刪除" - }, - "list": { - "title": "課程類型列表1", - "message": "請選擇課程類型", - "empty": { - "title": "目前沒有課程類型", - "message": "請建立課程類型", - "create": "建立課程類型" - }, - "error": "課程類型載入失敗" - }, - "view": { - "basic-details": "基本資訊" - }, - "Lesson Type": "課程類型", - "Lesson Types": "課程類型", - "Delete Lesson Type ?": "刪除課程類型?", - "Are you sure you want to delete lesson type ?": "確定要刪除課程類型嗎?" -} diff --git a/002_source/cms/public/locales/dev/listening_practice.json b/002_source/cms/public/locales/dev/listening_practice.json deleted file mode 100644 index 352e2b2..0000000 --- a/002_source/cms/public/locales/dev/listening_practice.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "add": "新增", - "listening-practice": "聽力練習", - "list": { - "title": "聽力練習分類列表", - "empty": "沒有找到聽力練習分類", - "action": "動作?", - "basic-details": "基本資料" - }, - "helloworld": "listening_practice", - "title": "聽力練習分類", - "type": "聽力練習分類", - "error": { - "invalid": "無效的聽力練習分類", - "not_found": "未找到聽力練習分類" - }, - "create": { - "title": "創建聽力練習分類", - "success": "聽力練習分類創建成功", - "error": "創建聽力練習分類時出錯" - }, - "edit": { - "title": "編輯聽力練習分類", - "success": "聽力練習分類更新成功", - "error": "更新聽力練習分類時出錯" - }, - "delete": { - "title": "刪除聽力練習分類", - "confirm": "確定要刪除聽力練習分類嗎?", - "success": "聽力練習分類刪除成功", - "error": "刪除聽力練習分類時出錯" - }, - "view": { - "title": "查看聽力練習分類詳情" - } -} \ No newline at end of file diff --git a/002_source/cms/public/locales/dev/translation.json b/002_source/cms/public/locales/dev/translation.json deleted file mode 100644 index a515168..0000000 --- a/002_source/cms/public/locales/dev/translation.json +++ /dev/null @@ -1,203 +0,0 @@ -{ - "languageChanged": "語言已更改", - "type": "類型", - "helloworld": "你好,世界", - "Add": "新增項目", - "visible": "可視", - "hidden": "屏閉", - "Hidden": "屏閉", - "Newest": "最新", - "Oldest": "最舊", - "Lesson position": "位置", - "Lesson type": "種類", - "Type": "種類", - "Name": "名稱", - "Filter by name": "依名稱過濾", - "Filter by type": "依類型過濾", - "dashboard.lessonTypes.add": "新增課程類型", - "dashboard.lessonTypes.title": "課程類型", - "dashboard.lessonTypes.type": "類型", - "dashboard.lessonTypes.create.title": "建立課程類型", - "dashboard.lessonTypes.create.createButton": "建立", - "dashboard.lessonTypes.create.cancelButton": "取消", - "dashboard.lessonTypes.edit.title": "編輯課程類型", - "Actions": "動作", - "Created at": "建立時間", - "Updated at": "更新時間", - "dashboard.lessonTypes.edit": "編輯課程類型", - "dashboard.lessonTypes.delete": "刪除課程類型", - "dashboard.lessonTypes.delete.title": "刪除課程類型", - "dashboard.lessonTypes.delete.message": "確定要刪除課程類型嗎?", - "Lesson Type": "課程類型", - "dashboard.lessonTypes.create": "建立課程類型", - "dashboard.lessonTypes.create.message": "請輸入課程類型名稱", - "dashboard.lessonTypes.create.success": "課程類型建立成功", - "dashboard.lessonTypes.create.error": "課程類型建立失敗", - "dashboard.lessonTypes.edit.success": "課程類型更新成功", - "dashboard.lessonTypes.edit.error": "課程類型更新失敗", - "dashboard.lessonTypes.delete.success": "課程類型刪除成功", - "dashboard.lessonTypes.delete.error": "課程類型刪除失敗", - "dashboard.lessonTypes.list": "課程類型", - "dashboard.lessonCategories.list": "詞語種類", - "dashboard.vocabulary.list": "詞語種類", - "dashboard.connective.list": "詞語種類", - "dashboard.lessonTypes.list.title": "課程類型列表3", - "dashboard.lessonTypes.list.message": "請選擇課程類型", - "dashboard.lessonTypes.list.empty": "目前沒有課程類型", - "dashboard.lessonTypes.list.empty.title": "目前沒有課程類型", - "dashboard.lessonTypes.list.empty.message": "請建立課程類型", - "dashboard.lessonTypes.list.empty.create": "建立課程類型", - "Lesson Name": "課程名稱", - "dashboard.lessonTypes.list.empty.create.title": "建立課程類型", - "dashboard.lessonTypes.list.empty.create.message": "請輸入課程名稱", - "dashboard.lessonTypes.list.empty.create.success": "課程建立成功", - "dashboard.lessonTypes.list.empty.create.error": "課程建立失敗", - "dashboard.lessonTypes.list.empty.create.name": "課程名稱", - "dashboard.lessonTypes.list.empty.create.type": "課程類型", - "dashboard.lessonTypes.list.empty.create.type.placeholder": "請選擇課程類型", - "dashboard.lessonTypes.list.empty.create.type.title": "課程類型", - "dashboard.lessonTypes.list.empty.create.type.message": "請選擇課程類型", - "dashboard.lessonTypes.list.empty.create.type.empty": "目前沒有課程類型", - "dashboard.lessonTypes.list.empty.create.type.empty.title": "目前沒有課程類型", - "dashboard.lessonTypes.list.empty.create.type.empty.message": "請建立課程類型", - "dashboard.lessonTypes.list.empty.create.type.empty.create": "建立課程類型", - "Position": "位置", - "Visible": "顯示", - "Lesson Types": "課程類型", - "Apply": "套用", - "Overview": "概觀", - "Dashboard": "儀表板", - "Tickets": "票券", - "Sign ups": "註冊", - "Open issues": "開啟問題", - "Closed issues": "關閉問題", - "increase": "增加", - "decrease": "減少", - "common.loading": "載入中", - "vs last month": "與上個月相比", - "Dashboards": "儀表板", - "App usage": "應用程式使用情況", - "Find your dream job": "找到你的夢想工作", - "Need help figuring things out?": "需要幫助嗎?", - "Search for jobs that match your skills and apply to them directly": "搜索符合你技能的工作,直接申請", - "Find answers to your questions and get in touch with our team.": "找到你的問題並與我們的團隊聯繫", - "Explore documentation": "探索文件", - "Learn how to get started with our product and make the most of it.": "學習如何開始使用我們的產品並充分利用它", - "Search Jobs": "搜索工作", - "Help Center": "幫助中心", - "Documentation": "文件", - "increase_in_app_usage_with": "使用者量增加", - "new_products_purchased": "新產品購買", - "Our subscriptions": "我們的訂閱", - "this_year": "今年", - "is_forecasted_to_increase_in_your_traffic_by_the_end_of_the_current_month": "今年預計增加你的流量", - "Jan": "一月", - "Feb": "二月", - "Mar": "三月", - "Apr": "四月", - "May": "五月", - "Jun": "六月", - "Jul": "七月", - "Aug": "八月", - "Sep": "九月", - "Oct": "十月", - "Nov": "十一月", - "Dec": "十二月", - "See all subscriptions": "查看所有訂閱", - "app_chat": "應用程式聊天", - "Upcoming events": "即將發生的事件", - "Based on the linked bank accounts": "基於連結的銀行帳戶", - "App limits": "應用程式限制", - "You have used {percentage} of your available spots.": "您已使用 {percentage} 的可用座位。升級計劃以建立更多專案", - "userMessagesUnread": "hello userMessagesUnread", - "Upgrade plan to create more projects": "升級計劃以建立更多專案", - "You have almost reached your limit": "您已接近您的限制", - "Upgrade plan": "升級計劃", - "Help center": "幫助中心", - "Jobs": "工作", - "go_to_chat": "前往聊天", - "See all events": "查看所有事件", - "You have used": "您已使用", - "of your available spots": "的可用座位", - "Paid": "已付款", - "Canceled": "已取消", - "Pending": "待付款", - "Expiring": "已過期", - "Refunded": "已退款", - "Total": "總計", - "Total paid": "已付款", - "Total cancelled": "已取消", - "Total pending": "待付款", - "year": "年", - "month": "月", - "week": "週", - "day": "日", - "hour": "小時", - "minute": "分鐘", - "second": "秒", - "ago": "前", - "remaining": "剩下", - "days": "天", - "hours": "小時", - "minutes": "分鐘", - "seconds": "秒", - "Clear filters": "清除篩選", - "Type information": "輸入資訊", - "dashboard.lessonTypes.create.typeInformation": "輸入課程類型資訊", - "dashboard.lessonTypes.create.avatar": "上傳課程類型圖片", - "dashboard.lessonTypes.create.avatarRequirements": "上傳課程類型圖片", - "dashboard.lessonTypes.create.select": "請選擇", - "dashboard.lessonTypes.create.name": "課程類型名稱", - "dashboard.lessonTypes.create.type": "課程類型", - "dashboard.lessonTypes.create.position": "課程類型順序", - "dashboard.lessonTypes.create.visibleToUser": "顯示給使用者", - "dashboard.lessonTypes.edit.typeInformation": "輸入課程類型資訊", - "dashboard.lessonTypes.edit.avatar": "上傳課程類型圖片", - "dashboard.lessonTypes.edit.avatarRequirements": "上傳課程類型圖片", - "dashboard.lessonTypes.edit.select": "請選擇", - "dashboard.lessonTypes.edit.name": "課程類型名稱", - "dashboard.lessonTypes.edit.type": "課程類型", - "dashboard.lessonTypes.edit.position": "課程類型順序", - "dashboard.lessonTypes.edit.visibleToUser": "顯示給使用者", - "dashboard.lessonTypes.edit.visible": "顯示", - "dashboard.lessonTypes.edit.hidden": "隱藏", - "dashboard.lessonTypes.edit.cancelButton": "取消", - "dashboard.lessonTypes.edit.updateButton": "更新", - "Delete Lesson Type ?": "刪除課程類型?", - "Are you sure you want to delete lesson type ?": "確定要刪除課程類型嗎?", - "Cancel": "取消", - "Delete": "刪除", - "All": "全部", - "categories": "問題分類", - "listening-practice": "聽講練習 (LP)", - "matching-frenzy": "配對練習 (MF)", - "connective-revision": "連接詞練習 (CR)", - "teachers": "導師", - "questions": "題目", - "loading": "載入中", - "Notifications": "通知", - "Mark all as read": "標記所有為已讀", - "There are no notifications": "沒有通知", - "listenings": "聽講 (Listenings)", - "question_category": "問題分類", - "question_list": "問題", - "matching_frenzy": "配對 (Matching Frenzy)", - "connective_revision": "連接詞 (Connective Revision)", - "settings": "設定", - "students": "學生", - "dashboard.lessonCategories.add": "新增課程分類", - "dashboard.lessonCategories.title": "課程分類", - "dashboard.lessonCategorys.edit.name": "課程分類名稱", - "dashboard.lessonCategorys.edit.position": "課程分類順序", - "dashboard.lessonCategorys.edit.title": "編輯課程分類", - "dashboard.lessonCategorys.edit.visibleToUser": "顯示給使用者", - "dashboard.lessonCategorys.edit.visible": "顯示", - "dashboard.lessonCategorys.edit.hidden": "隱藏", - "dashboard.lessonCategorys.edit.cancelButton": "取消", - "dashboard.lessonCategorys.edit.updateButton": "更新", - "dashboard.lessonCategorys.list.title": "課堂種類", - "word-count": "字數", - "dashboard.lessonTypes.list.error": "課程類型載入失敗", - "unable-to-process-request": "無法處理請求", - "detailed-error-information": "詳細錯誤資訊" -} diff --git a/002_source/cms/src/app/dashboard/lesson_categories/edit/[cat_id]/_PROMPT.md b/002_source/cms/src/app/dashboard/lesson_categories/edit/[cat_id]/_PROMPT.md deleted file mode 100644 index abf4465..0000000 --- a/002_source/cms/src/app/dashboard/lesson_categories/edit/[cat_id]/_PROMPT.md +++ /dev/null @@ -1,11 +0,0 @@ -# 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` - -with reference to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/app/dashboard/lesson_types/edit/[typeId]/page.tsx` - -please modify `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/app/dashboard/lesson_categories/edit/page.tsx` - -please draft a tsx for showing error to user thanks, diff --git a/002_source/cms/src/app/dashboard/teachers/list/page.tsx b/002_source/cms/src/app/dashboard/teachers/list/page.tsx index bc86dd1..ea5ad6c 100644 --- a/002_source/cms/src/app/dashboard/teachers/list/page.tsx +++ b/002_source/cms/src/app/dashboard/teachers/list/page.tsx @@ -44,7 +44,6 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { const { email, phone, sortDir, status } = searchParams; const [lessonCategoriesData, setLessonCategoriesData] = React.useState([]); - // const [isLoadingAddPage, setIsLoadingAddPage] = React.useState(false); const [showLoading, setShowLoading] = React.useState(true); @@ -73,12 +72,9 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { setLessonCategoriesData(tempLessonTypes); setRecordCount(totalItems); setF(tempLessonTypes); - // console.log({ currentPage, f }); } catch (error) { - // logger.error(error); setShowError({ - // show: true, detail: JSON.stringify(error, null, 2), }); @@ -129,11 +125,6 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { preFinalListOption = { ...preFinalListOption, sort: tempSortDir }; } setListOption(preFinalListOption); - // setListOption({ - // filter: tempFilter.join(' && '), - // sort: tempSortDir, - // // - // }); }, [sortDir, email, phone, status]); if (showLoading) return ; @@ -211,42 +202,6 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { ); } -// Sorting and filtering has to be done on the server. - -function applySort(row: Teacher[], sortDir: 'asc' | 'desc' | undefined): Teacher[] { - return row.sort((a, b) => { - if (sortDir === 'asc') { - return a.createdAt.getTime() - b.createdAt.getTime(); - } - - return b.createdAt.getTime() - a.createdAt.getTime(); - }); -} - -function applyFilters(row: Teacher[], { email, phone, status }: Filters): Teacher[] { - return row.filter((item) => { - if (email) { - if (!item.email?.toLowerCase().includes(email.toLowerCase())) { - return false; - } - } - - if (phone) { - if (!item.phone?.toLowerCase().includes(phone.toLowerCase())) { - return false; - } - } - - if (status) { - if (item.status !== status) { - return false; - } - } - - return true; - }); -} - interface PageProps { searchParams: { email?: string; phone?: string; sortDir?: 'asc' | 'desc'; status?: string }; } diff --git a/002_source/cms/src/app/dashboard/vocabularies/create/page.tsx b/002_source/cms/src/app/dashboard/vocabularies/create/page.tsx index fd45b0a..74bd3dc 100644 --- a/002_source/cms/src/app/dashboard/vocabularies/create/page.tsx +++ b/002_source/cms/src/app/dashboard/vocabularies/create/page.tsx @@ -10,7 +10,7 @@ import { ArrowLeft as ArrowLeftIcon } from '@phosphor-icons/react/dist/ssr/Arrow import { useTranslation } from 'react-i18next'; import { paths } from '@/paths'; -import { LessonCategoryCreateForm } from '@/components/dashboard/lesson_category/lesson-category-create-form'; +import { VocabularyCreateForm } from '@/components/dashboard/vocabulary/vocabulary-create-form'; export default function Page(): React.JSX.Element { const { t } = useTranslation(); @@ -29,19 +29,19 @@ export default function Page(): React.JSX.Element { - {t('title', { ns: 'lesson_category' })} + {t('title',)}
- {t('create.title', { ns: 'lesson_category' })} + {t('create.title', )}
- + ); diff --git a/002_source/cms/src/app/dashboard/vocabularies/edit/[cat_id]/_PROMPT.md b/002_source/cms/src/app/dashboard/vocabularies/edit/[cat_id]/_PROMPT.md deleted file mode 100644 index abf4465..0000000 --- a/002_source/cms/src/app/dashboard/vocabularies/edit/[cat_id]/_PROMPT.md +++ /dev/null @@ -1,11 +0,0 @@ -# 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` - -with reference to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/app/dashboard/lesson_types/edit/[typeId]/page.tsx` - -please modify `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/app/dashboard/lesson_categories/edit/page.tsx` - -please draft a tsx for showing error to user thanks, diff --git a/002_source/cms/src/app/dashboard/vocabularies/edit/[cat_id]/page.tsx b/002_source/cms/src/app/dashboard/vocabularies/edit/[cat_id]/page.tsx index 88737a6..3f2be2c 100644 --- a/002_source/cms/src/app/dashboard/vocabularies/edit/[cat_id]/page.tsx +++ b/002_source/cms/src/app/dashboard/vocabularies/edit/[cat_id]/page.tsx @@ -10,10 +10,10 @@ import { ArrowLeft as ArrowLeftIcon } from '@phosphor-icons/react/dist/ssr/Arrow import { useTranslation } from 'react-i18next'; import { paths } from '@/paths'; -import { LessonCategoryEditForm } from '@/components/dashboard/lesson_category/lesson-category-edit-form'; +import { VocabularyEditForm } from '@/components/dashboard/vocabulary/vocabulary-edit-form'; export default function Page(): React.JSX.Element { - const { t } = useTranslation(['lesson_category']); + const { t } = useTranslation(); return ( - {t('edit.title', { ns: 'lesson_category' })} + {t('edit.title')}
- {t('edit.title', { ns: 'lesson_category' })} + {t('edit.title')}
- +
); diff --git a/002_source/cms/src/app/dashboard/vocabularies/list/page.tsx b/002_source/cms/src/app/dashboard/vocabularies/list/page.tsx index 375b163..f52e83c 100644 --- a/002_source/cms/src/app/dashboard/vocabularies/list/page.tsx +++ b/002_source/cms/src/app/dashboard/vocabularies/list/page.tsx @@ -1,12 +1,11 @@ 'use client'; // RULES: -// contains list page for lesson_categories (LessonCategories) -// contain definition to collection only +// contains list page for vocabularies (Vocabularies) // import * as React from 'react'; import { useRouter } from 'next/navigation'; -import { COL_LESSON_CATEGORIES } from '@/constants'; +import { COL_VOCABULARIES } from '@/constants'; import { LoadingButton } from '@mui/lab'; import Box from '@mui/material/Box'; import Card from '@mui/material/Card'; @@ -21,25 +20,25 @@ import { paths } from '@/paths'; import isDevelopment from '@/lib/check-is-development'; import { logger } from '@/lib/default-logger'; import { pb } from '@/lib/pb'; -import { toast } from '@/components/core/toaster'; +// import { toast } from '@/components/core/toaster'; import ErrorDisplay from '@/components/dashboard/error'; -import { defaultLessonCategory } from '@/components/dashboard/lesson_category/_constants'; -import { LessonCategoriesFilters } from '@/components/dashboard/lesson_category/lesson-categories-filters'; -import type { Filters } from '@/components/dashboard/lesson_category/lesson-categories-filters'; -import { LessonCategoriesPagination } from '@/components/dashboard/lesson_category/lesson-categories-pagination'; -import { LessonCategoriesSelectionProvider } from '@/components/dashboard/lesson_category/lesson-categories-selection-context'; -import { LessonCategoriesTable } from '@/components/dashboard/lesson_category/lesson-categories-table'; -import type { LessonCategory } from '@/components/dashboard/lesson_category/type'; -// import type { LessonCategory } from '@/components/dashboard/lp_categories/type'; +import { defaultVocabulary } from '@/components/dashboard/vocabulary/_constants'; +import { VocabulariesFilters } from '@/components/dashboard/vocabulary/vocabularies-filters'; +import type { Filters } from '@/components/dashboard/vocabulary/vocabularies-filters'; +import { VocabulariesPagination } from '@/components/dashboard/vocabulary/vocabularies-pagination'; +import { VocabulariesSelectionProvider } from '@/components/dashboard/vocabulary/vocabularies-selection-context'; +import { VocabulariesTable } from '@/components/dashboard/vocabulary/vocabularies-table'; +import type { Vocabulary } from '@/components/dashboard/vocabulary/type'; +// import type { Vocabulary } from '@/components/dashboard/lp_categories/type'; import FormLoading from '@/components/loading'; // import { lessonCategoriesSampleData } from './lesson-categories-sample-data'; export default function Page({ searchParams }: PageProps): React.JSX.Element { - const { t } = useTranslation(['lesson_category']); + const { t } = useTranslation(); const { email, phone, sortDir, status, name, visible, type } = searchParams; const router = useRouter(); - const [lessonCategoriesData, setLessonCategoriesData] = React.useState([]); + const [lessonCategoriesData, setLessonCategoriesData] = React.useState([]); // const [isLoadingAddPage, setIsLoadingAddPage] = React.useState(false); @@ -48,69 +47,39 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { // const [rowsPerPage, setRowsPerPage] = React.useState(5); // - const [f, setF] = React.useState([]); + const [f, setF] = React.useState([]); const [currentPage, setCurrentPage] = React.useState(1); // const [recordCount, setRecordCount] = React.useState(0); const [listOption, setListOption] = React.useState({}); const [listSort, setListSort] = React.useState({}); - // - const sortedLessonCategories = applySort(lessonCategoriesData, sortDir); - const filteredLessonCategories = applyFilters(sortedLessonCategories, { email, phone, status }); - // const reloadRows = async (): Promise => { try { - const models: ListResult = await pb - .collection(COL_LESSON_CATEGORIES) - .getList(currentPage + 1, rowsPerPage, listOption); - const { items, totalItems } = models; - const tempLessonTypes: LessonCategory[] = items.map((lt) => { - return { ...defaultLessonCategory, ...lt }; + const models: ListResult = await pb.collection(COL_VOCABULARIES).getList(1, 5, { + expand: 'cat_id', }); - setLessonCategoriesData(tempLessonTypes); + const { items, totalItems } = models; + + const tempVocabularies: Vocabulary[] = items.map((v) => { + return { ...defaultVocabulary, ...v }; + }); + + setLessonCategoriesData(tempVocabularies); setRecordCount(totalItems); - setF(tempLessonTypes); + setF(tempVocabularies); // console.log({ currentPage, f }); } catch (error) { - // logger.error(error); setShowError({ - // show: true, detail: JSON.stringify(error, null, 2), }); } finally { setShowLoading(false); } - - // pb.collection(COL_LESSON_CATEGORIES) - // .getList(currentPage, rowsPerPage, listOption) - // .then((lessonCategories: ListResult) => { - // // console.log(lessonTypes); - // const { items, page, perPage, totalItems, totalPages } = lessonCategories; - // const tempLessonCategories: LessonCategory[] = items.map((item) => { - // return { ...defaultLessonCategory, ...item }; - // }); - - // setLessonCategoriesData(tempLessonCategories); - // setRecordCount(totalItems); - // setF(tempLessonCategories); - // // console.log({ currentPage, f }); - // }) - // .catch((error) => { - // logger.error(error); - // setShowError({ - // // - // show: true, - // detail: JSON.stringify(error, null, 2), - // }); - // }) - // .finally(() => { - // setShowLoading(false); - // }); }; const [lastListOption, setLastListOption] = React.useState({}); @@ -156,11 +125,6 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { preFinalListOption = { ...preFinalListOption, sort: tempSortDir }; } setListOption(preFinalListOption); - // setListOption({ - // filter: tempFilter.join(' && '), - // sort: tempSortDir, - // // - // }); }, [visible, sortDir, name, type]); // return <>helloworld; @@ -199,7 +163,7 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { loading={isLoadingAddPage} onClick={(): void => { setIsLoadingAddPage(true); - router.push(paths.dashboard.lesson_categories.create); + router.push(paths.dashboard.vocabularies.create); }} startIcon={} variant="contained" @@ -209,22 +173,22 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { - + - - - - +
{JSON.stringify(f, null, 2)}
@@ -243,51 +207,51 @@ export default function Page({ searchParams }: PageProps): React.JSX.Element { // Sorting and filtering has to be done on the server. -function applySort(row: LessonCategory[], sortDir: 'asc' | 'desc' | undefined): LessonCategory[] { - return row.sort((a, b) => { - if (sortDir === 'asc') { - return a.createdAt.getTime() - b.createdAt.getTime(); - } +// function applySort(row: Vocabulary[], sortDir: 'asc' | 'desc' | undefined): Vocabulary[] { +// return row.sort((a, b) => { +// if (sortDir === 'asc') { +// return a.createdAt.getTime() - b.createdAt.getTime(); +// } - return b.createdAt.getTime() - a.createdAt.getTime(); - }); -} +// return b.createdAt.getTime() - a.createdAt.getTime(); +// }); +// } -function applyFilters(row: LessonCategory[], { email, phone, status, name, visible }: Filters): LessonCategory[] { - return row.filter((item) => { - if (email) { - if (!item.email?.toLowerCase().includes(email.toLowerCase())) { - return false; - } - } +// function applyFilters(row: Vocabulary[], { email, phone, status, name, visible }: Filters): Vocabulary[] { +// return row.filter((item) => { +// if (email) { +// if (!item.email?.toLowerCase().includes(email.toLowerCase())) { +// return false; +// } +// } - if (phone) { - if (!item.phone?.toLowerCase().includes(phone.toLowerCase())) { - return false; - } - } +// if (phone) { +// if (!item.phone?.toLowerCase().includes(phone.toLowerCase())) { +// return false; +// } +// } - if (status) { - if (item.status !== status) { - return false; - } - } +// if (status) { +// if (item.status !== status) { +// return false; +// } +// } - if (name) { - if (!item.name?.toLowerCase().includes(name.toLowerCase())) { - return false; - } - } +// if (name) { +// if (!item.name?.toLowerCase().includes(name.toLowerCase())) { +// return false; +// } +// } - if (visible) { - if (!item.visible?.toLowerCase().includes(visible.toLowerCase())) { - return false; - } - } +// if (visible) { +// if (!item.visible?.toLowerCase().includes(visible.toLowerCase())) { +// return false; +// } +// } - return true; - }); -} +// return true; +// }); +// } interface PageProps { searchParams: { diff --git a/002_source/cms/src/app/dashboard/vocabularies/view/[cat_id]/page.tsx b/002_source/cms/src/app/dashboard/vocabularies/view/[cat_id]/page.tsx index cc14c52..3b4f3d0 100644 --- a/002_source/cms/src/app/dashboard/vocabularies/view/[cat_id]/page.tsx +++ b/002_source/cms/src/app/dashboard/vocabularies/view/[cat_id]/page.tsx @@ -4,7 +4,7 @@ import * as React from 'react'; // import type { Metadata } from 'next'; import RouterLink from 'next/link'; import { useParams, useRouter } from 'next/navigation'; -import { COL_LESSON_CATEGORIES } from '@/constants'; +import { COL_VOCABULARIES } from '@/constants'; import Avatar from '@mui/material/Avatar'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; @@ -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'; @@ -39,14 +39,12 @@ import { PropertyItem } from '@/components/core/property-item'; import { PropertyList } from '@/components/core/property-list'; import { toast } from '@/components/core/toaster'; import ErrorDisplay from '@/components/dashboard/error'; -import { defaultLessonCategory } from '@/components/dashboard/lesson_category/_constants.ts'; -// import { defaultLessonCategory } from '@/components/dashboard/lesson_category/defaultLessonCategory'; -import { Notifications } from '@/components/dashboard/lesson_category/notifications'; -import { 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/lp_categories/type'; +import { defaultVocabulary } from '@/components/dashboard/vocabulary/_constants.ts'; +import { Notifications } from '@/components/dashboard/vocabulary/notifications'; +import { Payments } from '@/components/dashboard/vocabulary/payments'; +import type { Address } from '@/components/dashboard/vocabulary/shipping-address'; +import { ShippingAddress } from '@/components/dashboard/vocabulary/shipping-address'; +import type { Vocabulary } from '@/components/dashboard/vocabulary/type'; import FormLoading from '@/components/loading'; // export const metadata = { title: `Details | Customers | Dashboard | ${config.site.name}` } satisfies Metadata; @@ -60,18 +58,18 @@ export default function Page(): React.JSX.Element { const [showLoading, setShowLoading] = React.useState(true); const [showError, setShowError] = React.useState(false); // - const [showLessonCategory, setShowLessonCategory] = React.useState(defaultLessonCategory); + const [showLessonCategory, setShowLessonCategory] = React.useState(defaultVocabulary); function handleEditClick() { - router.push(paths.dashboard.lesson_categories.edit(showLessonCategory.id)); + router.push(paths.dashboard.vocabularies.edit(showLessonCategory.id)); } React.useEffect(() => { if (catId) { - pb.collection(COL_LESSON_CATEGORIES) + pb.collection(COL_VOCABULARIES) .getOne(catId) .then((model: RecordModel) => { - setShowLessonCategory({ ...defaultLessonCategory, ...model }); + setShowLessonCategory({ ...defaultVocabulary, ...model }); }) .catch((err) => { logger.error(err); @@ -111,7 +109,7 @@ export default function Page(): React.JSX.Element { @@ -119,8 +117,16 @@ export default function Page(): React.JSX.Element { {t('dashboard.lessonCategorys.list.title')} - - + +
- + {showLessonCategory.name} } + icon={ + + } label={showLessonCategory.visible} size="small" variant="outlined" /> - + {showLessonCategory.id}
-
- - + + } - title={t('basic-details', { ns: 'lesson_category' })} + title={t('basic-details')} /> } @@ -178,8 +205,17 @@ export default function Page(): React.JSX.Element { > {( [ - { key: 'Customer ID', value: }, - { key: 'Name', value: showLessonCategory.name }, + { + key: 'word', + value: ( + + ), + }, + { key: 'word_c', value: showLessonCategory.word_c }, { key: 'Pos', value: showLessonCategory.pos }, { key: 'Visible', @@ -195,9 +231,20 @@ export default function Page(): React.JSX.Element { { key: 'Quota', value: ( - - - + + + 50% @@ -206,7 +253,11 @@ export default function Page(): React.JSX.Element { ] satisfies { key: string; value: React.ReactNode }[] ).map( (item): React.JSX.Element => ( - + ) )} @@ -218,16 +269,22 @@ export default function Page(): React.JSX.Element { } - title={t('security', { ns: 'lesson_category' })} + title={t('security')} />
-
- + A deleted lesson category cannot be restored. All data will be permanently removed.
@@ -235,7 +292,10 @@ export default function Page(): React.JSX.Element {
- + }> + } @@ -291,11 +354,17 @@ export default function Page(): React.JSX.Element { } - title={t('billing-details', { ns: 'lesson_category' })} + title={t('billing-details')} /> - - } sx={{ '--PropertyItem-padding': '16px' }}> + + } + sx={{ '--PropertyItem-padding': '16px' }} + > {( [ { key: 'Credit card', value: '**** 4142' }, @@ -307,7 +376,11 @@ export default function Page(): React.JSX.Element { ] satisfies { key: string; value: React.ReactNode }[] ).map( (item): React.JSX.Element => ( - + ) )} @@ -317,7 +390,10 @@ export default function Page(): React.JSX.Element { }> + } @@ -326,10 +402,13 @@ export default function Page(): React.JSX.Element { } - title={t('shipping-addresses', { ns: 'lesson_category' })} + title={t('shipping-addresses')} /> - + {( [ { @@ -351,7 +430,11 @@ export default function Page(): React.JSX.Element { }, ] satisfies Address[] ).map((address) => ( - + ))} diff --git a/002_source/cms/src/components/dashboard/cr/categories/cr-category-edit-form.tsx b/002_source/cms/src/components/dashboard/cr/categories/cr-category-edit-form.tsx index 4424082..bca9e6d 100644 --- a/002_source/cms/src/components/dashboard/cr/categories/cr-category-edit-form.tsx +++ b/002_source/cms/src/components/dashboard/cr/categories/cr-category-edit-form.tsx @@ -127,7 +127,7 @@ export function CrCategoryEditForm(): React.JSX.Element { // TODO: remove below type: '', }; - + // try { const result = await pb.collection(COL_QUIZ_LP_CATEGORIES).update(catId, tempUpdate); logger.debug(result); diff --git a/002_source/cms/src/components/dashboard/layout/config.ts b/002_source/cms/src/components/dashboard/layout/config.ts index 735b955..d62368e 100644 --- a/002_source/cms/src/components/dashboard/layout/config.ts +++ b/002_source/cms/src/components/dashboard/layout/config.ts @@ -28,27 +28,27 @@ export const layoutConfig = { items: [ { key: 'lesson-types', - title: 'type', + title: 'lesson-types', icon: 'users', items: [ { key: 'lesson-types', - title: 'dashboard.lessonTypes.list', + title: 'lessonTypes.list', href: paths.dashboard.lesson_types.list, }, { key: 'lesson-categories', - title: 'dashboard.lessonCategories.list', + title: 'lessonCategories.list', href: paths.dashboard.lesson_categories.list, }, { key: 'vocabulary', - title: 'dashboard.vocabularies.list', + title: 'vocabularies.list', href: paths.dashboard.vocabularies.list, }, { key: 'connective', - title: 'dashboard.connectives.list', + title: 'connectives.list', href: paths.dashboard.connectives.list, }, ], diff --git a/002_source/cms/src/components/dashboard/lesson_category/type.d.ts b/002_source/cms/src/components/dashboard/lesson_category/type.d.ts index 4ea1ce5..a8c59c5 100644 --- a/002_source/cms/src/components/dashboard/lesson_category/type.d.ts +++ b/002_source/cms/src/components/dashboard/lesson_category/type.d.ts @@ -1,3 +1,5 @@ +// RULES: obsoleted +// please use `./cms/src/db/LessonCategories/type.d.ts` export interface LessonCategory { isEmpty?: boolean; // diff --git a/002_source/cms/src/components/dashboard/mf/categories/mf-category-edit-form.tsx b/002_source/cms/src/components/dashboard/mf/categories/mf-category-edit-form.tsx index 25b295e..a7b712e 100644 --- a/002_source/cms/src/components/dashboard/mf/categories/mf-category-edit-form.tsx +++ b/002_source/cms/src/components/dashboard/mf/categories/mf-category-edit-form.tsx @@ -127,7 +127,7 @@ export function MfCategoryEditForm(): React.JSX.Element { // TODO: remove below type: '', }; - + // try { const result = await pb.collection(COL_QUIZ_MF_CATEGORIES).update(catId, tempUpdate); logger.debug(result); diff --git a/002_source/cms/src/components/dashboard/student/type.d.tsx b/002_source/cms/src/components/dashboard/student/type.d.tsx index 41228a7..ed3c667 100644 --- a/002_source/cms/src/components/dashboard/student/type.d.tsx +++ b/002_source/cms/src/components/dashboard/student/type.d.tsx @@ -1,7 +1,9 @@ 'use client'; +// RULES: sorting direction for student lists export type SortDir = 'asc' | 'desc'; +// RULES: core student data structure export interface Student { id: string; name: string; @@ -14,6 +16,7 @@ export interface Student { updatedAt?: Date; } +// RULES: form data structure for creating new student export interface CreateFormProps { name: string; email: string; @@ -36,6 +39,7 @@ export interface CreateFormProps { // status?: 'pending' | 'active' | 'blocked'; } +// RULES: form data structure for editing existing student export interface EditFormProps { name: string; email: string; @@ -57,11 +61,14 @@ export interface EditFormProps { // quota?: number; // status?: 'pending' | 'active' | 'blocked'; } +// RULES: filter props for student search and filtering export interface CustomersFiltersProps { filters?: Filters; sortDir?: SortDir; fullData: Student[]; } + +// RULES: available filter options for student data export interface Filters { email?: string; phone?: string; diff --git a/002_source/cms/src/components/dashboard/teacher/type.d.tsx b/002_source/cms/src/components/dashboard/teacher/type.d.tsx index 3b84aab..5e6f638 100644 --- a/002_source/cms/src/components/dashboard/teacher/type.d.tsx +++ b/002_source/cms/src/components/dashboard/teacher/type.d.tsx @@ -1,7 +1,9 @@ 'use client'; +// RULES: sorting direction for teacher lists export type SortDir = 'asc' | 'desc'; +// RULES: core teacher data structure export interface Teacher { id: string; name: string; @@ -14,6 +16,7 @@ export interface Teacher { updatedAt?: Date; } +// RULES: form data structure for creating new teacher export interface CreateFormProps { name: string; email: string; @@ -36,6 +39,7 @@ export interface CreateFormProps { // status?: 'pending' | 'active' | 'blocked'; } +// RULES: form data structure for editing existing teacher export interface EditFormProps { name: string; email: string; @@ -57,6 +61,8 @@ export interface EditFormProps { // quota?: number; // status?: 'pending' | 'active' | 'blocked'; } + +// RULES: filter props for teacher search and filtering export interface CustomersFiltersProps { filters?: Filters; sortDir?: SortDir; diff --git a/002_source/cms/src/components/dashboard/vocabulary/_constants.ts b/002_source/cms/src/components/dashboard/vocabulary/_constants.ts index 1458199..a7cba1d 100644 --- a/002_source/cms/src/components/dashboard/vocabulary/_constants.ts +++ b/002_source/cms/src/components/dashboard/vocabulary/_constants.ts @@ -1,44 +1,40 @@ import { dayjs } from '@/lib/dayjs'; +import { Vocabulary, CreateForm } from './type'; -import { CreateForm, LessonCategory } from './type'; - -// import type { CreateForm, LessonCategory } from '../lp_categories/type'; - -export const defaultLessonCategory: LessonCategory = { - isEmpty: false, - id: 'default-id', - cat_name: 'default-category-name', - cat_image_url: undefined, - cat_image: undefined, - pos: 0, - visible: 'hidden', - lesson_id: 'default-lesson-id', - description: 'default-description', - remarks: 'default-remarks', - // - collectionId: '0000000000', - createdAt: dayjs('2099-01-01').toDate(), - // - name: '', - avatar: '', - email: '', - phone: '', - quota: 0, - status: 'NA', +export const defaultVocabulary: Vocabulary = { + id: 'default-vocabulary-id', + image: undefined, + sound: undefined, + word: '', + word_c: '', + sample_e: '', + sample_c: '', + cat_id: 'default-category-id', + category: 'default-category', + lesson_type_id: 'default-lesson-type-id', }; -export const LessonCategoryCreateFormDefault: CreateForm = { - name: '', - type: '', - pos: 1, - visible: 'visible', - description: '', - isActive: true, - order: 1, - imageUrl: '', +export const VocabularyCreateFormDefault: CreateForm = { + image: undefined, + sound: undefined, + word: '', + word_c: '', + sample_e: '', + sample_c: '', + cat_id: '', + category: '', + lesson_type_id: '', }; -export const emptyLessonCategory: LessonCategory = { - ...defaultLessonCategory, +export const emptyVocabulary: Vocabulary = { + ...defaultVocabulary, + id: '', + word: '', + word_c: '', + sample_e: '', + sample_c: '', + cat_id: '', + category: '', + lesson_type_id: '', isEmpty: true, }; 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 7f0ab5f..671b235 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 @@ -15,6 +15,7 @@ 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); @@ -44,33 +45,24 @@ export default function ConfirmDeleteModal({ transform: 'translate(-50%, -50%)', }; - function performDelete(id: string): Promise { - return pb - .collection(COL_LESSON_TYPES) - .delete(id) - .then(() => { - toast(t('dashboard.lessonTypes.delete.success')); - reloadRows(); - }) - .catch((err) => { - logger.error(err); - toast(t('dashboard.lessonTypes.delete.error')); - }) - .finally(() => {}); - } - function handleUserConfirmDelete(): void { if (idToDelete) { setIsDeleteing(true); - performDelete(idToDelete) + + // RULES: Vocabulary -> deleteVocabulary + deleteVocabulary(idToDelete) .then(() => { + reloadRows(); handleClose(); - setIsDeleteing(false); + toast(t('delete.success')); }) .catch((err) => { // console.error(err) logger.error(err); - toast(t('dashboard.lessonTypes.delete.error')); + toast(t('delete.error')); + }) + .finally(() => { + setIsDeleteing(false); }); } } @@ -86,19 +78,33 @@ export default function ConfirmDeleteModal({ - + {t('Delete Lesson Type ?')} - + {t('Are you sure you want to delete lesson type ?')} - - ({ - deselectAll: noop, - deselectOne: noop, - selectAll: noop, - selectOne: noop, - selected: new Set(), - selectedAny: false, - selectedAll: false, -}); - -interface LessonCategoriesSelectionProviderProps { - children: React.ReactNode; - lessonCategories: LessonCategory[]; -} - -export function LessonCategoriesSelectionProvider({ - children, - lessonCategories = [], -}: LessonCategoriesSelectionProviderProps): React.JSX.Element { - const customerIds = React.useMemo(() => lessonCategories.map((customer) => customer.id), [lessonCategories]); - const selection = useSelection(customerIds); - - return ( - - {children} - - ); -} - -export function useLessonCategoriesSelection(): LessonCategoriesSelectionContextValue { - return React.useContext(LessonCategoriesSelectionContext); -} diff --git a/002_source/cms/src/components/dashboard/vocabulary/lesson-category-edit-form.tsx b/002_source/cms/src/components/dashboard/vocabulary/lesson-category-edit-form.tsx deleted file mode 100644 index 2ec64e2..0000000 --- a/002_source/cms/src/components/dashboard/vocabulary/lesson-category-edit-form.tsx +++ /dev/null @@ -1,353 +0,0 @@ -'use client'; - -import * as React from 'react'; -import RouterLink from 'next/link'; -import { useParams, useRouter } from 'next/navigation'; -import { COL_LESSON_CATEGORIES, NS_LESSON_CATEGORY } from '@/constants'; -import { zodResolver } from '@hookform/resolvers/zod'; -import { LoadingButton } from '@mui/lab'; -import { Avatar, Divider, MenuItem } from '@mui/material'; -// import Avatar from '@mui/material/Avatar'; -import Box from '@mui/material/Box'; -import Button from '@mui/material/Button'; -import Card from '@mui/material/Card'; -import CardActions from '@mui/material/CardActions'; -import CardContent from '@mui/material/CardContent'; -// import Checkbox from '@mui/material/Checkbox'; - -import 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 type { RecordModel } from 'pocketbase'; -import { Controller, useForm } from 'react-hook-form'; -import { useTranslation } from 'react-i18next'; -import { z as zod } from 'zod'; - -import { paths } from '@/paths'; -import { dayjs } from '@/lib/dayjs'; -import { logger } from '@/lib/default-logger'; -import { fileToBase64 } from '@/lib/file-to-base64'; -import { pb } from '@/lib/pb'; -import { Option } from '@/components/core/option'; -import { TextEditor } from '@/components/core/text-editor/text-editor'; -import { toast } from '@/components/core/toaster'; -import FormLoading from '@/components/loading'; - -import ErrorDisplay from '../error'; -import { defaultLessonCategory } from './_constants'; -import type { EditFormProps, LessonCategory } from './type'; - -// TODO: review this -const schema = zod.object({ - cat_name: zod.string().min(1, 'name-is-required').max(255), - // - pos: zod.number().min(1, 'Phone is required').max(99), - visible: zod.string().max(255), - // - description: zod.string().optional(), - remarks: zod.string().optional(), -}); - -type Values = zod.infer; - -const defaultValues = { - cat_name: '', - // cat_image: undefined, - pos: 0, - visible: 'hidden', - // lesson_id: 'default-lesson-id', - description: 'default-description', - remarks: 'default-remarks', - // -} satisfies Values; - -export function LessonCategoryEditForm(): React.JSX.Element { - const router = useRouter(); - const { t } = useTranslation(['common', 'lesson_category']); - - const NS_DEFAULT = { ns: 'lesson_category' }; - - const { cat_id: catId } = useParams<{ cat_id: string }>(); - // - const [isUpdating, setIsUpdating] = React.useState(false); - const [showLoading, setShowLoading] = React.useState(false); - const [showError, setShowError] = React.useState(false); - - const { - control, - handleSubmit, - formState: { errors }, - setValue, - reset, - watch, - } = useForm({ defaultValues, resolver: zodResolver(schema) }); - - const onSubmit = React.useCallback(async (values: Values): Promise => { - setIsUpdating(true); - const tempUpdate: EditFormProps = { - cat_name: values.cat_name, - pos: values.pos, - visible: values.visible, - description: values.description, - remarks: values.remarks, - type: '', - }; - - pb.collection(COL_LESSON_CATEGORIES) - .update(catId, tempUpdate) - .then((res) => { - logger.debug(res); - toast.success(t('update.success', NS_DEFAULT)); - router.push(paths.dashboard.lesson_categories.list); - }) - .catch((err) => { - logger.error(err); - toast.error('Something went wrong!'); - }) - .finally(() => { - // - setIsUpdating(false); - }); - }, []); - - 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] - ); - - const [textDescription, setTextDescription] = React.useState('loading'); - const [textRemarks, setTextRemarks] = React.useState('loading'); - const handleLoad = React.useCallback( - (id: string) => { - setShowLoading(true); - pb.collection(COL_LESSON_CATEGORIES) - .getOne(id) - .then((model: RecordModel) => { - const temp: LessonCategory = { ...defaultLessonCategory, ...model }; - reset(temp); - setTextDescription(temp.description); - setTextRemarks(temp.remarks); - }) - .catch((err) => { - logger.error(err); - toast(t('list.error', NS_DEFAULT)); - }) - .finally(() => { - setShowLoading(false); - }); - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [catId] - ); - - React.useEffect(() => { - handleLoad(catId); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [catId]); - - if (showLoading) return ; - if (showError) - return ( - - ); - - return ( -
- - - } spacing={4}> - - {t('edit.basic-info', NS_DEFAULT)} - - - - - {/* - - // TODO: resume me - - - */} - - - {t('edit.avatar', NS_DEFAULT)} - {t('edit.avatarRequirements', NS_DEFAULT)} - - - - - - - ( - - {t('edit.name', NS_DEFAULT)} - - {errors.cat_name ? {errors.cat_name.message} : null} - - )} - /> - - - - ( - - {t('edit.position', NS_DEFAULT)} - { - field.onChange(parseInt(e.target.value)); - }} - type="number" - /> - - {errors.pos ? {errors.pos.message} : null} - - )} - /> - - - ( - - {t('edit.visible', NS_DEFAULT)} - - - {errors.visible ? {errors.visible.message} : null} - - )} - /> - - - - - - {t('create.detail-information', NS_DEFAULT)} - - - { - return ( - - - {t('create.description', NS_DEFAULT)} - - - { - field.onChange({ target: { value: editor.getHTML() } }); - }} - placeholder={t('edit.write-something', NS_DEFAULT)} - /> - - - ); - }} - /> - - - ( - - - {t('create.remarks', NS_DEFAULT)} - - - { - field.onChange({ target: { value: editor.getText() } }); - }} - hideToolbar - placeholder={t('edit.write-something', NS_DEFAULT)} - /> - - - )} - /> - - - - - - - - - - {t('edit.updateButton', NS_DEFAULT)} - - - -
- ); -} diff --git a/002_source/cms/src/components/dashboard/vocabulary/type.d copy.ts b/002_source/cms/src/components/dashboard/vocabulary/type.d copy.ts new file mode 100644 index 0000000..743ef8a --- /dev/null +++ b/002_source/cms/src/components/dashboard/vocabulary/type.d copy.ts @@ -0,0 +1,36 @@ +export interface Vocabulary { + id: string; + created?: string; + updated?: string; + image?: string; + sound?: string; + word?: string; + word_c?: string; + sample_e?: string; + sample_c?: string; + cat_id?: string; + category?: string; + lesson_type_id?: string; +} + +export interface CreateForm { + image?: string; + sound?: string; + word?: string; + word_c?: string; + sample_e?: string; + sample_c?: string; + cat_id?: string; + category?: string; + lesson_type_id?: string; +} + +export interface EditFormProps { + id: string; + defaultValues: Vocabulary; + onDone: () => void; +} + +export interface Helloworld { + helloworld: string; +} diff --git a/002_source/cms/src/components/dashboard/vocabulary/type.d.ts b/002_source/cms/src/components/dashboard/vocabulary/type.d.ts index 4ea1ce5..6880170 100644 --- a/002_source/cms/src/components/dashboard/vocabulary/type.d.ts +++ b/002_source/cms/src/components/dashboard/vocabulary/type.d.ts @@ -1,47 +1,60 @@ -export interface LessonCategory { - isEmpty?: boolean; - // +// RULES: +// should match the collection `Vocabularies` from `schema.dbml` +export interface Vocabulary { id: string; - collectionId: string; - // - cat_name: string; - cat_image_url?: string; - cat_image?: string; - pos: number; + created?: string; + updated?: string; + image?: string; + sound?: string; + word?: string; + word_c?: string; + sample_e?: string; + sample_c?: string; + cat_id: string; + category?: string; + lesson_type_id?: string; visible: string; - lesson_id: string; - description: string; - remarks: string; - createdAt: Date; - // - name: string; - avatar: string; - email: string; - phone: string; - quota: number; - status: 'pending' | 'active' | 'blocked' | 'NA'; + expand?: { + cat_id?: { + collectionId: string; + id: string; + cat_image: string; + cat_name: string; + // + }; + }; } +// RULES: for use with vocabulary-create-form.tsx +// when you update, please take a look into `vocabulary-create-form.tsx` export interface CreateForm { - name: string; - type: string; - pos: number; - visible: string; - description: string; - isActive: boolean; - order: number; - imageUrl: string; + image?: string; + sound?: string; + word?: string; + word_c?: string; + sample_e?: string; + sample_c?: string; + cat_id?: string; + category?: string; + lesson_type_id?: string; } +// RULES: for use with vocabulary-edit-form.tsx +// when you update, please take a look into `vocabulary-edit-form.tsx` export interface EditFormProps { - cat_name: string; - pos: number; - visible: string; - description?: string; - remarks?: string; - type: string; + image: File[] | null; + sound: string; + word: string; + word_c: string; + sample_e: string; + sample_c: string; + cat_id: string; + category: string; + lesson_type_id: string; } +// RULES: +// helloworld example, should not modify export interface Helloworld { helloworld: string; } diff --git a/002_source/cms/src/components/dashboard/vocabulary/lesson-categories-filters.tsx b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-filters.tsx similarity index 82% rename from 002_source/cms/src/components/dashboard/vocabulary/lesson-categories-filters.tsx rename to 002_source/cms/src/components/dashboard/vocabulary/vocabularies-filters.tsx index ec387a5..2ef4f61 100644 --- a/002_source/cms/src/components/dashboard/vocabulary/lesson-categories-filters.tsx +++ b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-filters.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import { useRouter } from 'next/navigation'; -import { COL_LESSON_CATEGORIES } from '@/constants'; import GetAllCount from '@/db/LessonCategories/GetAllCount'; import GetHiddenCount from '@/db/LessonCategories/GetHiddenCount'; import GetVisibleCount from '@/db/LessonCategories/GetVisibleCount'; @@ -20,13 +19,11 @@ import Typography from '@mui/material/Typography'; import { useTranslation } from 'react-i18next'; import { paths } from '@/paths'; -import { pb } from '@/lib/pb'; import { FilterButton, FilterPopover, useFilterContext } from '@/components/core/filter-button'; import { Option } from '@/components/core/option'; -// import { LessonCategory } from '../lp_categories/type'; -import { useLessonCategoriesSelection } from './lesson-categories-selection-context'; -import { LessonCategory } from './type'; +import { useVocabulariesSelection } from './vocabularies-selection-context'; +import type { Vocabulary } from './type'; export interface Filters { email?: string; @@ -39,17 +36,17 @@ export interface Filters { export type SortDir = 'asc' | 'desc'; -export interface LessonCategoriesFiltersProps { +export interface VocabulariesFiltersProps { filters?: Filters; sortDir?: SortDir; - fullData: LessonCategory[]; + fullData: Vocabulary[]; } -export function LessonCategoriesFilters({ +export function VocabulariesFilters({ filters = {}, sortDir = 'desc', fullData, -}: LessonCategoriesFiltersProps): React.JSX.Element { +}: VocabulariesFiltersProps): React.JSX.Element { const { t } = useTranslation(); const { email, phone, status, name, visible, type } = filters; @@ -59,16 +56,16 @@ export function LessonCategoriesFilters({ const router = useRouter(); - const selection = useLessonCategoriesSelection(); + const selection = useVocabulariesSelection(); function getVisible(): number { - return fullData.reduce((count, item: LessonCategory) => { + return fullData.reduce((count, item: Vocabulary) => { return item.visible === 'visible' ? count + 1 : count; }, 0); } function getHidden(): number { - return fullData.reduce((count, item: LessonCategory) => { + return fullData.reduce((count, item: Vocabulary) => { return item.visible === 'hidden' ? count + 1 : count; }, 0); } @@ -115,7 +112,7 @@ export function LessonCategoriesFilters({ searchParams.set('visible', newFilters.visible); } - router.push(`${paths.dashboard.lesson_categories.list}?${searchParams.toString()}`); + router.push(`${paths.dashboard.vocabularies.list}?${searchParams.toString()}`); }, [router] ); @@ -195,10 +192,21 @@ export function LessonCategoriesFilters({ return (
- + {tabs.map((tab) => ( } + icon={ + + } iconPosition="end" key={tab.value} label={tab.label} @@ -209,8 +217,16 @@ export function LessonCategoriesFilters({ ))} - - + + {t('Clear filters')} : null} {selection.selectedAny ? ( - - + + {selection.selected.size} {t('selected')} - ) : null} - @@ -268,7 +299,12 @@ function TypeFilterPopover(): React.JSX.Element { }, [initialValue]); return ( - + { @@ -304,7 +340,12 @@ function NameFilterPopover(): React.JSX.Element { }, [initialValue]); return ( - + { @@ -339,7 +380,12 @@ function EmailFilterPopover(): React.JSX.Element { }, [initialValue]); return ( - + { @@ -374,7 +420,12 @@ function PhoneFilterPopover(): React.JSX.Element { }, [initialValue]); return ( - + { diff --git a/002_source/cms/src/components/dashboard/vocabulary/lesson-categories-pagination.tsx b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-pagination.tsx similarity index 88% rename from 002_source/cms/src/components/dashboard/vocabulary/lesson-categories-pagination.tsx rename to 002_source/cms/src/components/dashboard/vocabulary/vocabularies-pagination.tsx index 7a344d5..b7256e4 100644 --- a/002_source/cms/src/components/dashboard/vocabulary/lesson-categories-pagination.tsx +++ b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-pagination.tsx @@ -10,7 +10,7 @@ function noop(): void { return undefined; } -interface LessonCategoriesPaginationProps { +interface VocabulariesPaginationProps { count: number; page: number; // @@ -19,14 +19,14 @@ interface LessonCategoriesPaginationProps { rowsPerPage: number; } -export function LessonCategoriesPagination({ +export function VocabulariesPagination({ count, page, // setPage, setRowsPerPage, rowsPerPage, -}: LessonCategoriesPaginationProps): React.JSX.Element { +}: 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) => { diff --git a/002_source/cms/src/components/dashboard/vocabulary/vocabularies-selection-context.tsx b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-selection-context.tsx new file mode 100644 index 0000000..ef1ddc3 --- /dev/null +++ b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-selection-context.tsx @@ -0,0 +1,46 @@ +'use client'; + +import * as React from 'react'; + +import { useSelection } from '@/hooks/use-selection'; +import type { Selection } from '@/hooks/use-selection'; + +import { Vocabulary } from './type'; + + +function noop(): void { + return undefined; +} + +export interface VocabulariesSelectionContextValue extends Selection {} + +export const VocabulariesSelectionContext = React.createContext({ + deselectAll: noop, + deselectOne: noop, + selectAll: noop, + selectOne: noop, + selected: new Set(), + selectedAny: false, + selectedAll: false, +}); + +interface VocabulariesSelectionProviderProps { + children: React.ReactNode; + lessonCategories: Vocabulary[]; +} + +export function VocabulariesSelectionProvider({ + children, + lessonCategories = [], +}: VocabulariesSelectionProviderProps): React.JSX.Element { + const customerIds = React.useMemo(() => lessonCategories.map((customer) => customer.id), [lessonCategories]); + const selection = useSelection(customerIds); + + return ( + {children} + ); +} + +export function useVocabulariesSelection(): VocabulariesSelectionContextValue { + return React.useContext(VocabulariesSelectionContext); +} diff --git a/002_source/cms/src/components/dashboard/vocabulary/lesson-categories-table.tsx b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-table.tsx similarity index 63% rename from 002_source/cms/src/components/dashboard/vocabulary/lesson-categories-table.tsx rename to 002_source/cms/src/components/dashboard/vocabulary/vocabularies-table.tsx index f90667a..d393bc5 100644 --- a/002_source/cms/src/components/dashboard/vocabulary/lesson-categories-table.tsx +++ b/002_source/cms/src/components/dashboard/vocabulary/vocabularies-table.tsx @@ -27,10 +27,18 @@ import { DataTable } from '@/components/core/data-table'; import type { ColumnDef } from '@/components/core/data-table'; import ConfirmDeleteModal from './confirm-delete-modal'; -import { useLessonCategoriesSelection } from './lesson-categories-selection-context'; -import type { LessonCategory } from './type'; +import { useVocabulariesSelection } from './vocabularies-selection-context'; +import type { Vocabulary } from './type'; +import { listLessonCategories } from '@/db/LessonCategories/listLessonCategories'; +import { LessonCategory } from '@/db/LessonCategories/type'; +import { Logger } from '@/lib/logger'; +import { logger } from '@/lib/default-logger'; +import getImageUrlFromFile from '@/lib/get-image-url-from-file.ts'; -function columns(handleDeleteClick: (testId: string) => void): ColumnDef[] { +function columns( + handleDeleteClick: (testId: string) => void, + lessonCategories: { id: string; label: string }[] +): ColumnDef[] { return [ { formatter: (row): React.JSX.Element => ( @@ -42,7 +50,7 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef @@ -58,12 +66,12 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef {' '}
- {row.cat_name} + {row.word} - slug: {row.cat_name} + slug: {row.word_c}
@@ -74,78 +82,39 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef ( - - - { + const { cat_name: catName } = row?.expand?.cat_id ?? { cat_name: '--' }; + + return ( + - {new Intl.NumberFormat('en-US', { style: 'percent', maximumFractionDigits: 2 }).format(row.quota / 100)} - - - ), + + {catName} + +
+ ); + }, // NOTE: please refer to translation.json here - name: 'word-count', + name: 'category', width: '100px', }, { 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: ( - - ), - }, - NA: { - label: 'NA', - icon: ( - - ), - }, - } as const; - const { label, icon } = mapping[row.status] ?? { label: 'Unknown', icon: null }; - return ( - + ); }, - name: 'Status', + name: 'visible', width: '150px', }, { @@ -165,13 +134,12 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef { handleDeleteClick(row.id); }} @@ -188,14 +156,14 @@ function columns(handleDeleteClick: (testId: string) => void): ColumnDef void; } -export function LessonCategoriesTable({ rows, reloadRows }: LessonCategoriesTableProps): React.JSX.Element { - const { t } = useTranslation(['lesson_category']); - const { deselectAll, deselectOne, selectAll, selectOne, selected } = useLessonCategoriesSelection(); +export function VocabulariesTable({ rows, reloadRows }: VocabulariesTableProps): React.JSX.Element { + const { t } = useTranslation(['vocabulary']); + const { deselectAll, deselectOne, selectAll, selectOne, selected } = useVocabulariesSelection(); const [idToDelete, setIdToDelete] = React.useState(''); const [open, setOpen] = React.useState(false); @@ -205,6 +173,20 @@ export function LessonCategoriesTable({ rows, reloadRows }: LessonCategoriesTabl setIdToDelete(testId); } + let [lessonCategories, setLessonCategories] = React.useState<{}>({}); + + async function tempFunc(): Promise { + try { + const tempCategories = await listLessonCategories(); + console.log(tempCategories); + } catch (error) { + logger.error(error); + } + } + React.useEffect(() => { + void tempFunc; + }, []); + return ( - + columns={columns(handleDeleteClick)} onDeselectAll={deselectAll} onDeselectOne={(_, row) => { diff --git a/002_source/cms/src/components/dashboard/vocabulary/lesson-category-create-form.tsx b/002_source/cms/src/components/dashboard/vocabulary/vocabulary-create-form.tsx similarity index 70% rename from 002_source/cms/src/components/dashboard/vocabulary/lesson-category-create-form.tsx rename to 002_source/cms/src/components/dashboard/vocabulary/vocabulary-create-form.tsx index 7744b52..1756dbc 100644 --- a/002_source/cms/src/components/dashboard/vocabulary/lesson-category-create-form.tsx +++ b/002_source/cms/src/components/dashboard/vocabulary/vocabulary-create-form.tsx @@ -3,23 +3,19 @@ import * as React from 'react'; import RouterLink from 'next/link'; import { useRouter } from 'next/navigation'; -import { COL_LESSON_CATEGORIES, NS_LESSON_CATEGORY } from '@/constants'; import { zodResolver } from '@hookform/resolvers/zod'; import { LoadingButton } from '@mui/lab'; -import { Avatar, Divider, MenuItem } from '@mui/material'; +import { Avatar, Divider } from '@mui/material'; // import Avatar from '@mui/material/Avatar'; import Box from '@mui/material/Box'; import Button from '@mui/material/Button'; import Card from '@mui/material/Card'; import CardActions from '@mui/material/CardActions'; import CardContent from '@mui/material/CardContent'; -import Checkbox from '@mui/material/Checkbox'; import 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'; @@ -32,7 +28,6 @@ import { z as zod } from 'zod'; import { paths } from '@/paths'; import { logger } from '@/lib/default-logger'; import { fileToBase64 } from '@/lib/file-to-base64'; -import { Option } from '@/components/core/option'; import { TextEditor } from '@/components/core/text-editor/text-editor'; import { toast } from '@/components/core/toaster'; @@ -71,12 +66,10 @@ const defaultValues = { currency: 'USD', } satisfies Values; -export function LessonCategoryCreateForm(): React.JSX.Element { +export function VocabularyCreateForm(): React.JSX.Element { const router = useRouter(); const { t } = useTranslation(['common', 'lesson_category']); - const NS_DEFAULT = { ns: 'lesson_category' }; - const [isCreating, setIsCreating] = React.useState(false); const { @@ -121,12 +114,22 @@ export function LessonCategoryCreateForm(): React.JSX.Element {
- } spacing={4}> + } + spacing={4} + > - {t('create.typeInformation', NS_DEFAULT)} - + {t('create.typeInformation')} + - + - - {t('create.avatar', NS_DEFAULT)} - {t('create.avatarRequirements', NS_DEFAULT)} + + {t('create.avatar')} + {t('create.avatarRequirements')} - + - + ( - - {t('create.name', NS_DEFAULT)} + + {t('create.name')} {errors.name ? {errors.name.message} : null} )} /> - + ( - + Email address - + {errors.email ? {errors.email.message} : null} )} /> - + ( - + Phone number {errors.phone ? {errors.phone.message} : null} @@ -206,12 +238,18 @@ export function LessonCategoryCreateForm(): React.JSX.Element { )} /> - + ( - + Company {errors.company ? {errors.company.message} : null} @@ -222,35 +260,56 @@ export function LessonCategoryCreateForm(): React.JSX.Element { - {t('create.detail-information', NS_DEFAULT)} - - + {t('create.detail-information')} + + ( - - {t('create.description', NS_DEFAULT)} + + {t('create.description')} - + )} /> - + ( - - {t('create.remarks', NS_DEFAULT)} + + {t('create.remarks')} - + )} @@ -261,12 +320,21 @@ export function LessonCategoryCreateForm(): React.JSX.Element { - - - {t('create.createButton', NS_DEFAULT)} + + {t('create.createButton')} 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 new file mode 100644 index 0000000..ee2e9b6 --- /dev/null +++ b/002_source/cms/src/components/dashboard/vocabulary/vocabulary-edit-form.tsx @@ -0,0 +1,462 @@ +'use client'; + +import * as React from 'react'; +import RouterLink from 'next/link'; +import { useParams, useRouter } from 'next/navigation'; +import { COL_VOCABULARIES } from '@/constants'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { LoadingButton } from '@mui/lab'; +import { Avatar, Divider, MenuItem } from '@mui/material'; +// import Avatar from '@mui/material/Avatar'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import Card from '@mui/material/Card'; +import CardActions from '@mui/material/CardActions'; +import CardContent from '@mui/material/CardContent'; + +import FormControl from '@mui/material/FormControl'; +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 type { RecordModel } from 'pocketbase'; +import { Controller, useForm } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; +import { z as zod } from 'zod'; + +import { paths } from '@/paths'; +import { dayjs } from '@/lib/dayjs'; +import { logger } from '@/lib/default-logger'; +import { base64ToFile, fileToBase64 } from '@/lib/file-to-base64'; +import { pb } from '@/lib/pb'; +import { Option } from '@/components/core/option'; +import { TextEditor } from '@/components/core/text-editor/text-editor'; +import { toast } from '@/components/core/toaster'; +import FormLoading from '@/components/loading'; + +import ErrorDisplay from '../error'; +import { defaultLessonCategory } from './_constants'; +import type { EditFormProps } from './type'; +import getVocabularyById from '@/db/Vocabularies/GetById'; +import getAllLessonCategories from '@/db/LessonCategories/GetAll'; +import { listLessonCategories } from '@/db/LessonCategories/listLessonCategories'; +import isDevelopment from '@/lib/check-is-development'; + +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().min(1, 'Lesson type ID is required'), + // 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(); + + const { cat_id: catId } = useParams<{ cat_id: 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 tempUpdate: EditFormProps = { + image: values.avatar ? [await base64ToFile(values.avatar)] : null, + sound: '', + word: values.word, + word_c: values.word_c, + sample_e: values.sample_e || '', + sample_c: values.sample_c || '', + cat_id: values.cat_id, + category: '', + lesson_type_id: '', + }; + // + try { + console.log({ tempUpdate }); + const result = await pb.collection(COL_VOCABULARIES).update(catId, tempUpdate); + logger.debug(result); + toast.success(t('edit.success')); + router.push(paths.dashboard.vocabularies.list); + } catch (error) { + logger.error(error); + toast.error(t('update.failed')); + } finally { + setIsUpdating(false); + } + }, + // t is not necessary here + // eslint-disable-next-line react-hooks/exhaustive-deps + [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] + ); + + // load existing data when user arrive + const loadExistingData = React.useCallback( + async (id: string) => { + try { + const result = await pb.collection(COL_VOCABULARIES).getOne(id); + reset({ ...defaultValues, ...result }); + + if (result.image !== '') { + const fetchResult = await fetch( + `http://127.0.0.1:8090/api/files/${result.collectionId}/${result.id}/${result.image}` + ); + + const blob = await fetchResult.blob(); + const url = await fileToBase64(blob); + + setValue('avatar', url); + } else { + setValue('avatar', ''); + } + } catch (error) { + logger.error(error); + toast(t('list.error')); + + setShowError({ show: true, detail: JSON.stringify(error, null, 2) }); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [catId] + ); + + let [categoriesOption, setCategoriesOption] = React.useState<{ value: string; label: string }[]>([]); + const loadCategories = React.useCallback(async () => { + try { + const categories = await listLessonCategories(); + + logger.debug(categories); + + setCategoriesOption( + categories.map((c) => { + return { label: c.cat_name || '??', value: c.id }; + }) + ); + } catch (error) { + logger.error(error); + toast.error(t('list.error')); + } + }, [catId]); + + React.useEffect(() => { + setShowLoading(true); + + void loadCategories(); + void loadExistingData(catId); + + setShowLoading(false); + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [catId]); + + if (showLoading) return ; + if (showError.show) + return ( + + ); + + return ( + + + + } + spacing={4} + > + + {t('edit.basic-info')} + + + + + + + + + + {t('edit.avatar')} + {t('edit.avatarRequirements')} + + + + + + + ( + + {t('edit.word')} + + {errors.word ? {errors.word.message} : null} + + )} + /> + + {/* */} + + ( + + {t('edit.word_c')} + + {errors.word_c ? {errors.word_c.message} : null} + + )} + /> + + {/* */} + + ( + + {t('edit.cat_id')} + + + )} + /> + + {/* */} + + ( + + {/* TODO: sound file selection is not implemented */} + {t('edit.sound_file')} - (Not implemented) + + {errors.sound ? {errors.sound.message} : null} + + )} + /> + + + + {/* */} + + {t('edit.sample-sentence')} + + + ( + + {t('edit.sample_e')} + + {errors.sample_e ? {errors.sample_e.message} : null} + + )} + /> + + + ( + + {t('edit.sample_c')} + + {errors.sample_c ? {errors.sample_c.message} : null} + + )} + /> + + + + {/* */} + + + + + + + 1{t('edit.updateButton')}2 + + + +
{JSON.stringify(errors, null, 2)}
+
+
+ + ); +} diff --git a/002_source/cms/src/constants.ts b/002_source/cms/src/constants.ts index ad738f6..d4ffcbd 100644 --- a/002_source/cms/src/constants.ts +++ b/002_source/cms/src/constants.ts @@ -23,11 +23,13 @@ const COL_CUSTOMERS = 'Customers'; const COL_NOTIFICATIONS = 'Notifications'; const COL_TEACHERS = 'Teachers'; const COL_STUDENTS = 'Students'; +const COL_VOCABULARIES = 'Vocabularies'; // FOR page display const NO_VALUE = 'NO_VALUE'; const NO_NUM = -Infinity; const NS_LESSON_CATEGORY = 'lesson_category'; +const NS_VOCABULARY = 'vocabulary'; export { COL_LESSON_TYPES, @@ -51,5 +53,7 @@ export { COL_NOTIFICATIONS, COL_TEACHERS, COL_STUDENTS, + COL_VOCABULARIES, + NS_VOCABULARY, // }; diff --git a/002_source/cms/src/db/LessonCategories/listLessonCategories.tsx b/002_source/cms/src/db/LessonCategories/listLessonCategories.tsx new file mode 100644 index 0000000..faa5f31 --- /dev/null +++ b/002_source/cms/src/db/LessonCategories/listLessonCategories.tsx @@ -0,0 +1,13 @@ +// +// RULES: +import { COL_LESSON_CATEGORIES } from '@/constants'; + +import { pb } from '@/lib/pb'; +import type { LessonCategory } from './type'; + +export async function listLessonCategories(): Promise { + const records = await pb.collection(COL_LESSON_CATEGORIES).getFullList({ + expand: 'cat_id', + }); + return records as unknown as LessonCategory[]; +} diff --git a/002_source/cms/src/db/LessonCategories/type.d.ts b/002_source/cms/src/db/LessonCategories/type.d.ts new file mode 100644 index 0000000..5504f4d --- /dev/null +++ b/002_source/cms/src/db/LessonCategories/type.d.ts @@ -0,0 +1,23 @@ +export interface LessonCategory { + isEmpty?: boolean; + // + id: string; + collectionId: string; + // + cat_name: string; + cat_image_url?: string; + cat_image?: string; + pos: number; + visible: string; + lesson_id: string; + description: string; + remarks: string; + createdAt: Date; + // + name: string; + avatar: string; + email: string; + phone: string; + quota: number; + status: 'pending' | 'active' | 'blocked' | 'NA'; +} diff --git a/002_source/cms/src/db/Notifications/GetNotificationByUserId.tsx b/002_source/cms/src/db/Notifications/GetNotificationByUserId.tsx index 1a69f8f..3271212 100644 --- a/002_source/cms/src/db/Notifications/GetNotificationByUserId.tsx +++ b/002_source/cms/src/db/Notifications/GetNotificationByUserId.tsx @@ -1,3 +1,5 @@ +// +// RULES: // api method for get notifications by user id import { pb } from '@/lib/pb'; import { COL_NOTIFICATIONS } from '@/constants'; diff --git a/002_source/cms/src/db/Vocabularies/Create.tsx b/002_source/cms/src/db/Vocabularies/Create.tsx new file mode 100644 index 0000000..6b475be --- /dev/null +++ b/002_source/cms/src/db/Vocabularies/Create.tsx @@ -0,0 +1,8 @@ +import { COL_VOCABULARIES } from '@/constants'; +import type { Vocabulary, VocabularyCreate } from './type'; + +import { pb } from '@/lib/pb'; + +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 new file mode 100644 index 0000000..39a001b --- /dev/null +++ b/002_source/cms/src/db/Vocabularies/Delete.tsx @@ -0,0 +1,6 @@ +import { COL_VOCABULARIES } from '@/constants'; +import { pb } from '@/lib/pb'; + +export default function deleteVocabulary(id: string): Promise { + return pb.collection(COL_VOCABULARIES).delete(id); +} diff --git a/002_source/cms/src/db/Vocabularies/GetAll.tsx b/002_source/cms/src/db/Vocabularies/GetAll.tsx new file mode 100644 index 0000000..f6c35a9 --- /dev/null +++ b/002_source/cms/src/db/Vocabularies/GetAll.tsx @@ -0,0 +1,8 @@ +import { COL_VOCABULARIES } from '@/constants'; +import type { Vocabularies } from './type'; + +import { pb } from '@/lib/pb'; + +export default function getAllVocabularies(): Promise { + return pb.collection(COL_VOCABULARIES).getFullList(); +} diff --git a/002_source/cms/src/db/Vocabularies/GetAllCount.tsx b/002_source/cms/src/db/Vocabularies/GetAllCount.tsx new file mode 100644 index 0000000..1f7f7bf --- /dev/null +++ b/002_source/cms/src/db/Vocabularies/GetAllCount.tsx @@ -0,0 +1,14 @@ +// RULES: +// error handled by caller +// contain definition to collection only + +import { COL_VOCABULARIES } from '@/constants'; + +import { pb } from '@/lib/pb'; + +export default function getAllVocabulariesCount(): Promise { + return pb + .collection(COL_VOCABULARIES) + .getList(1, 9999) + .then((res) => res.totalItems); +} diff --git a/002_source/cms/src/db/Vocabularies/GetById.tsx b/002_source/cms/src/db/Vocabularies/GetById.tsx new file mode 100644 index 0000000..defcf4d --- /dev/null +++ b/002_source/cms/src/db/Vocabularies/GetById.tsx @@ -0,0 +1,8 @@ +import { COL_VOCABULARIES } from '@/constants'; +import type { Vocabulary } from './type'; + +import { pb } from '@/lib/pb'; + +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 new file mode 100644 index 0000000..ea25f04 --- /dev/null +++ b/002_source/cms/src/db/Vocabularies/GetHiddenCount.tsx @@ -0,0 +1,9 @@ +import { COL_VOCABULARIES } from '@/constants'; +import { pb } from '@/lib/pb'; + +export default function getHiddenVocabulariesCount(): Promise { + return pb + .collection(COL_VOCABULARIES) + .getList(1, 9999, { filter: 'status = "hidden"' }) + .then((res) => res.totalItems); +} diff --git a/002_source/cms/src/db/Vocabularies/GetVisibleCount.tsx b/002_source/cms/src/db/Vocabularies/GetVisibleCount.tsx new file mode 100644 index 0000000..657b197 --- /dev/null +++ b/002_source/cms/src/db/Vocabularies/GetVisibleCount.tsx @@ -0,0 +1,9 @@ +import { COL_VOCABULARIES } from '@/constants'; +import { pb } from '@/lib/pb'; + +export default function getVisibleVocabulariesCount(): Promise { + return pb + .collection(COL_VOCABULARIES) + .getList(1, 9999, { filter: 'status = "visible"' }) + .then((res) => res.totalItems); +} diff --git a/002_source/cms/src/db/Vocabularies/Helloworld.tsx b/002_source/cms/src/db/Vocabularies/Helloworld.tsx new file mode 100644 index 0000000..2356119 --- /dev/null +++ b/002_source/cms/src/db/Vocabularies/Helloworld.tsx @@ -0,0 +1,5 @@ +function helloWorld(): string { + return 'helloworld'; +} + +export { helloWorld }; diff --git a/002_source/cms/src/db/Vocabularies/Update.tsx b/002_source/cms/src/db/Vocabularies/Update.tsx new file mode 100644 index 0000000..ac961b9 --- /dev/null +++ b/002_source/cms/src/db/Vocabularies/Update.tsx @@ -0,0 +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 { + return pb.collection(COL_VOCABULARIES).update(id, data); +} diff --git a/002_source/cms/src/db/Vocabularies/_GUIDELINES.md b/002_source/cms/src/db/Vocabularies/_GUIDELINES.md new file mode 100644 index 0000000..96b23fd --- /dev/null +++ b/002_source/cms/src/db/Vocabularies/_GUIDELINES.md @@ -0,0 +1,30 @@ +# GUIDELINES + +This folder contains drivers for `LessonCategory`/`LessonCategories` records using PocketBase: + +- create (Create.tsx) +- read (GetById.tsx) +- write (Update.tsx) +- count (GetAllCount.tsx) +- delete (Delete.tsx) +- list (GetAll.tsx) + +the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` + +## Assumption and Requirements + +- assume `pb` is located in `@/lib/pb` +- no need to handle error in this function, i'll handle it in the caller +- type information defined in `@/db/LessonCategories/type.d.tsx` + +simple template: + +```typescript +import { pb } from '@/lib/pb'; +import { COL_LESSON_CATEGORIES } from '@/constants'; + +export async function createLessonCategory(data: CreateFormProps) { + // ...content + // use direct return of pb.collection (e.g. return pb.collection(xxx)) +} +``` diff --git a/002_source/cms/src/db/Vocabularies/type.d.tsx b/002_source/cms/src/db/Vocabularies/type.d.tsx new file mode 100644 index 0000000..76258ef --- /dev/null +++ b/002_source/cms/src/db/Vocabularies/type.d.tsx @@ -0,0 +1,53 @@ +// RULES: interface for handling vocabulary record +export interface Vocabulary { + // + id: string; + collectionId: string; + // + word: string; + word_c: string; + sample_e: string; + sample_c: string; + cat_id: string; + category: string; + lesson_type_id: string; + image: File[]; + sound: File[]; +} + +// RULES: interface for handling create form +export interface CreateForm { + word: string; + word_c: string; + sample_e: string; + sample_c: string; + cat_id: string; + category: string; + lesson_type_id: string; + image: File[]; + sound: File[]; + isActive: boolean; + order: number; +} + +// RULES: interface for handling edit form +export interface EditFormProps { + id: string; + collectionId: string; + word: string; + word_c: string; + sample_e: string; + sample_c: string; + cat_id: string; + category: string; + lesson_type_id: string; + image: File[]; + sound: File[]; + isActive: boolean; + order: number; +} + +// RULES: helloworld self test +export interface Helloworld { + helloworld: string; +} diff --git a/002_source/cms/src/db/_repomix.md b/002_source/cms/src/db/_repomix.md deleted file mode 100644 index 297f887..0000000 --- a/002_source/cms/src/db/_repomix.md +++ /dev/null @@ -1,12508 +0,0 @@ -This file is a merged representation of the entire codebase, combined into a single document by Repomix. - -# File Summary - -## Purpose -This file contains a packed representation of the entire repository's contents. -It is designed to be easily consumable by AI systems for analysis, code review, -or other automated processes. - -## File Format -The content is organized as follows: -1. This summary section -2. Repository information -3. Directory structure -4. Multiple file entries, each consisting of: - a. A header with the file path (## File: path/to/file) - b. The full contents of the file in a code block - -## Usage Guidelines -- This file should be treated as read-only. Any changes should be made to the - original repository files, not this packed version. -- When processing this file, use the file path to distinguish - between different files in the repository. -- Be aware that this file may contain sensitive information. Handle it with - the same level of security as you would the original repository. - -## Notes -- Some files may have been excluded based on .gitignore rules and Repomix's configuration -- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files -- Files matching patterns in .gitignore are excluded -- Files matching default ignore patterns are excluded -- Files are sorted by Git change count (files with more changes are at the bottom) - -## Additional Info - -# Directory Structure -``` -_PROMPT/ - 1.MD - 2.MD - 3.MD - 4.md - temp.md -Customers/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetActiveCount.tsx - GetAll.tsx - GetAllCount.tsx - GetBlockedCount.tsx - GetById.tsx - GetPendingCount.tsx - Helloworld.tsx - Update.tsx -Events/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Update.tsx.draft -Helloworlds/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Helloworld.tsx.draft - Update.tsx.draft -LessonCategories/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Helloworld.tsx - Update.tsx -LessonTypes/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Helloworld.tsx - Update.tsx -Messages/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Update.tsx.draft -QuizCategories/ - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Helloworld.tsx.draft - Update.tsx.draft -QuizConnectives/ - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Helloworld.tsx.draft - Update.tsx.draft -QuizConnectivesCategories/ - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Helloworld.tsx.draft - Update.tsx.draft -QuizCRCategories/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Update.tsx -QuizCRQuestions/ - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx -QuizListenings/ - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - ListWithOption.tsx -QuizLPCategories/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Update.tsx -QuizLPQuestions/ - _GUIDELINES.md - _PROMPT.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Update.tsx -QuizMFCategories/ - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Update.tsx -Students/ - Create.tsx - Delete.tsx - GetActiveCount.tsx - GetAll.tsx - GetAllCount.tsx - GetBlockedCount.tsx - GetById.tsx - Update.tsx -Subscriptions/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Update.tsx.draft -Teachers/ - _GUIDELINES.md - Create.tsx - GetActiveCount.tsx - GetAll.tsx - GetAllCount.tsx - GetBlockedCount.tsx - GetById.tsx - GetPendingCount.tsx - Update.tsx -UserMetas/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx - GetById.tsx.draft - Update.tsx.draft -Users/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx - GetById.tsx.draft - Update.tsx.draft -DB_AI_GUIDELINE.MD -repomix-output.xml -schema.json -``` - -# Files - -## File: _PROMPT/1.MD -````markdown -Hi, please study the documentation below, -i will send you the task afterwards, - -please read and understand the documentation below and link up the ideas -reply `OK` when you done -no need to state me any other things, thanks - -1. `schema.dbml` - -- this describe the database schema in dbml format -- filepath: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/001_documentation/Requirements/REQ0006/schema.dbml` - -2. `schema.json` - -- this is the schema export in pocketbase format -- filepath: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/schema.json` - -3. `_AI_GUIDELINE`: - -- there are the markdown files that help you better understand the implementation -- directory: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/_AI_GUIDELINE` - -thanks - ---- - -# task - -clone from `LessonTypes` to `Customers` - -## steps - -1. read `tsx` files from `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/LessonTypes` -1. copy file to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/Customers` -1. modify the copied `tsx` files to suit `customer` fields -```` - -## File: _PROMPT/2.MD -````markdown -update `LpCategoryDefaultValue` -in file `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lp_categories/_constants.ts` - -thanks - -you can find the type def in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx` - -please help to draft code file: - -base_dir=`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db` - -using -`$base_dir/QuizListenings/GetHiddenCount.tsx`, -`$base_dir/QuizListenings/GetVisibleCount.tsx`, -`$base_dir/LessonTypes/GetHiddenCount.tsx`, -`$base_dir/LessonTypes/GetVisibleCount.tsx`, -as reference, - -look into the all directories under base_dir e.g. `QuizCategories`. -propergate `GetHiddenCount.tsx` and `GetVisibleCount.tsx` if missing, do the change to suit the collection. -use `.draft.tsx` instead when you write file - ---- - -rewrite `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/LessonCategories/GetAllCount.tsx` to match `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/UserMetas/GetAllCount.tsx` style - ---- - -style rewrite - -study -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/overview/summary/ActiveUserCount/index.tsx` -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/overview/summary/LessonCategoriesCount/index.tsx` - -and rewrite `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/overview/summary/LessonTypeCount/index.tsx` to match style above thanks -```` - -## File: _PROMPT/3.MD -````markdown -please draft with idea: - -``` -await pb -.collection(COL_LESSON_TYPES) -.getList(currentPage + 1, rowsPerPage, listOption); -``` - -for Listening Practice - -thanks - -I want you to clone -from `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/LessonTypes/GetVisibleCount.tsx` (source file) - -to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/QuizListenings/GetVisibleCount.tsx` (dest file) - -please extract , link up and remember the document properties -(e.g. types, functions, variables, constants, etc) -from source file -draft dest file - -update the variables and properties of dest file to reflect `listening practice categories`/`lp_categories` - ---- - -## task - -update `schema.dbml` to reflect `schema.json` - -## details - -Hi, -I have a pocketbase export json file: -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/pocketbase/pb_hooks/seed/schema.json` - -and a dbml file: -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/001_documentation/Requirements/REQ0006/schema.dbml` - -the collection name in pocketbase should be reflected by a table in dbml, - -## steps - -compare `schema.json` and `schema.dbml` -please keep `schema.json` remain unchanged -update `schema.dbml` to reflect `schema.json` -do check again when finished -```` - -## File: _PROMPT/4.md -````markdown ---- - -clone `GetVisibleCount.tsx` and `GetHiddenCount.tsx` from `LessonTypes` to `LessonCategories` and update it - -please draft `GetHiddenCount.tsx` for COL_LESSON_TYPES and `status = hidden` - -well done !, please proceed to another request - -working directory: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db` - -according information from `schema.json`, get the collection of `Students` - -pleaes clone the `tsx` files from `LessonTypes` and `LessonCategories` to `Students` and update the content - -when you draft coding, review file and append with `.tsx.draft` - ---- - -- this is part of react typescript project, with pocketbase -- `schema.dbml`, describe the collections(tables) -- folder `LessonCategories`, the correct references -- folder `LessonTypes`, the correct references -- you can find the `schema.dbml` and schema information from `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/001_documentation/Requirements/REQ0006` -- do not read root directory, assume it is a fresh copy of nextjs project is ok - -## instruction - -- break the questions into smaller parts -- review file append with `.draft`, see if the content aligned with the correct references -- read and understand `dbml` file -- lookup the every folder - -## tasks - -Thanks - ---- - -please take a look in `schema.dbml` and `schema.json`, -associate the collection from json file to the table in dbml file - -please modify the `schema.dbml` to align with `schema.json` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - ---- - -please revise - -please revise -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx` `interface LpCategory` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - -please modify `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lp_categories/_constants.tsx` - -to follow the type definition in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx`, the constant `defaultLpCategory` -```` - -## File: _PROMPT/temp.md -````markdown -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lp_categories/lp-categories-filters.tsx` - -this file is original for `lesson_category` model, -please modify it to fit `lp_category` (listening practice category) - -thanks -```` - -## File: Customers/_GUIDELINES.md -````markdown -# GUIDELINES - -This folder contains drivers for `Customer`/`Customers` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx, GetActiveCount.tsx, GetBlockedCount.tsx, GetPendingCount.tsx) -- misc (Helloworld.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/Customers/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; - -export async function createCustomer(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` -```` - -## File: Customers/Create.tsx -````typescript -// api method for crate customer record -// RULES: -// TBA -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; -import type { CreateFormProps } from '@/components/dashboard/customer/type.d'; -import type { RecordModel } from 'pocketbase'; - -export async function createCustomer(data: CreateFormProps): Promise { - return pb.collection(COL_CUSTOMERS).create(data); -} -```` - -## File: Customers/Delete.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; - -export async function deleteCustomer(id: string): Promise { - return pb.collection(COL_CUSTOMERS).delete(id); -} -```` - -## File: Customers/GetActiveCount.tsx -````typescript -import { COL_CUSTOMERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetActiveCount(): Promise { - const { totalItems: count } = await pb.collection(COL_CUSTOMERS).getList(1, 1, { - filter: 'status = "active"', - }); - return count; -} -```` - -## File: Customers/GetAll.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getAllCustomers(options = {}): Promise { - return pb.collection(COL_CUSTOMERS).getFullList(options); -} -```` - -## File: Customers/GetAllCount.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; - -export async function getAllCustomersCount(): Promise { - const result = await pb.collection(COL_CUSTOMERS).getList(1, 1); - return result.totalItems; -} -```` - -## File: Customers/GetBlockedCount.tsx -````typescript -import { COL_CUSTOMERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetBlockedCount(): Promise { - const { totalItems: count } = await pb.collection(COL_CUSTOMERS).getList(1, 1, { - filter: 'status = "blocked"', - }); - return count; -} -```` - -## File: Customers/GetById.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getCustomerById(id: string): Promise { - return pb.collection(COL_CUSTOMERS).getOne(id); -} -```` - -## File: Customers/GetPendingCount.tsx -````typescript -import { COL_CUSTOMERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetPendingCount(): Promise { - const { totalItems: count } = await pb.collection(COL_CUSTOMERS).getList(1, 1, { - filter: 'status = "pending"', - }); - return count; -} -```` - -## File: Customers/Helloworld.tsx -````typescript -export function helloCustomer() { - return 'Hello from Customers module!'; -} -```` - -## File: Customers/Update.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import type { EditFormProps } from '@/components/dashboard/customer/type.d'; - -export async function updateCustomer(id: string, data: Partial): Promise { - return pb.collection(COL_CUSTOMERS).update(id, data); -} -```` - -## File: Events/_GUIDELINES.md -````markdown -# GUIDELINES - -This folder contains drivers for `Event`/`Events` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Events/type.d.tsx` -- Event records require special handling for: - - Date/time validation - - Location data - - Attendee management - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createEvent(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection('Events')) -} -``` -```` - -## File: Events/Create.tsx.draft -```` -import { COL_EVENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/event/types'; - -export default function createEvent(data: CreateForm): Promise { - return pb.collection(COL_EVENTS).create(data); -} -```` - -## File: Events/Delete.tsx.draft -```` -import { COL_EVENTS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteEvent(id: string): Promise { - return pb.collection(COL_EVENTS).delete(id); -} -```` - -## File: Events/GetAll.tsx.draft -```` -import { COL_EVENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllEvents(): Promise { - return pb.collection(COL_EVENTS).getFullList({ - sort: 'event_time' // Sort by event time - }); -} -```` - -## File: Events/GetAllCount.tsx.draft -```` -import { COL_EVENTS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getAllEventsCount(startDate?: string, endDate?: string): Promise { - let filter = ''; - if (startDate && endDate) { - filter = `event_time >= "${startDate}" && event_time <= "${endDate}"`; - } else if (startDate) { - filter = `event_time >= "${startDate}"`; - } else if (endDate) { - filter = `event_time <= "${endDate}"`; - } - - const { totalItems: count } = await pb - .collection(COL_EVENTS) - .getList(1, 9999, { filter }); - return count; -} -```` - -## File: Events/GetById.tsx.draft -```` -import { COL_EVENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getEventById(id: string): Promise { - return pb.collection(COL_EVENTS).getOne(id); -} -```` - -## File: Events/GetHiddenCount.tsx.draft -```` -// REQ0006 -import { COL_EVENTS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_EVENTS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: Events/GetVisibleCount.tsx.draft -```` -// REQ0006 -import { COL_EVENTS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_EVENTS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: Events/Update.tsx.draft -```` -import { COL_EVENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { UpdateForm } from '@/components/dashboard/event/types'; - -export default function updateEvent(id: string, data: UpdateForm): Promise { - return pb.collection(COL_EVENTS).update(id, data); -} -```` - -## File: Helloworlds/_GUIDELINES.md -````markdown -# GUIDELINES - -This folder contains test drivers for `Helloworld` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function -- type information defined in `@/db/Helloworlds/type.d.tsx` -- This is a test collection - keep implementations simple - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createHelloworld(data: CreateFormProps) { - // Simple test implementation - return pb.collection('Helloworlds').create(data); -} -``` -```` - -## File: Helloworlds/Create.tsx.draft -```` -import { COL_HELLOWORLDS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/helloworld/types'; - -export default function createHelloworld(data: CreateForm): Promise { - return pb.collection(COL_HELLOWORLDS).create(data); -} -```` - -## File: Helloworlds/Delete.tsx.draft -```` -import { COL_HELLOWORLDS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default function deleteHelloworld(id: string): Promise { - return pb.collection(COL_HELLOWORLDS).delete(id); -} -```` - -## File: Helloworlds/GetAll.tsx.draft -```` -import { COL_HELLOWORLDS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllHelloworlds(): Promise { - return pb.collection(COL_HELLOWORLDS).getFullList(); -} -```` - -## File: Helloworlds/GetById.tsx.draft -```` -import { COL_HELLOWORLDS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getHelloworldById(id: string): Promise { - return pb.collection(COL_HELLOWORLDS).getOne(id); -} -```` - -## File: Helloworlds/GetHiddenCount.tsx.draft -```` -// REQ0006 -import { COL_HELLOWORLDS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_HELLOWORLDS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: Helloworlds/GetVisibleCount.tsx.draft -```` -// REQ0006 -import { COL_HELLOWORLDS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_HELLOWORLDS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: Helloworlds/Helloworld.tsx.draft -```` -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; -```` - -## File: Helloworlds/Update.tsx.draft -```` -import { COL_HELLOWORLDS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/helloworld/types'; - -export default function updateHelloworld(id: string, data: CreateForm): Promise { - return pb.collection(COL_HELLOWORLDS).update(id, data); -} -```` - -## File: LessonCategories/_GUIDELINES.md -````markdown -# GUIDELINES - -This folder contains drivers for `LessonCategory`/`LessonCategories` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/LessonCategories/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_LESSON_CATEGORIES } from '@/constants'; - -export async function createLessonCategory(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` -```` - -## File: LessonCategories/Create.tsx -````typescript -import { COL_LESSON_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/categories/type'; - -export default function createLessonCategory(data: CreateFormProps): Promise { - return pb.collection(COL_LESSON_CATEGORIES).create(data); -} -```` - -## File: LessonCategories/Delete.tsx -````typescript -import { COL_LESSON_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteLessonCategory(id: string): Promise { - return pb.collection(COL_LESSON_CATEGORIES).delete(id); -} -```` - -## File: LessonCategories/GetAll.tsx -````typescript -import { COL_LESSON_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllLessonCategories(): Promise { - return pb.collection(COL_LESSON_CATEGORIES).getFullList(); -} -```` - -## File: LessonCategories/GetAllCount.tsx -````typescript -// RULES: -// error handled by caller -// contain definition to collection only - -import { COL_LESSON_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function getAllLessonCategoriesCount(): Promise { - return pb - .collection(COL_LESSON_CATEGORIES) - .getList(1, 9999) - .then((res) => res.totalItems); -} -```` - -## File: LessonCategories/GetById.tsx -````typescript -import { COL_LESSON_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getLessonCategoryById(id: string): Promise { - return pb.collection(COL_LESSON_CATEGORIES).getOne(id); -} -```` - -## File: LessonCategories/GetHiddenCount.tsx -````typescript -// REQ0006 -import { COL_LESSON_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: LessonCategories/GetVisibleCount.tsx -````typescript -// REQ0006 -import { COL_LESSON_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: LessonCategories/Helloworld.tsx -````typescript -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; -```` - -## File: LessonCategories/Update.tsx -````typescript -import { COL_LESSON_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/categories/type'; - -export default function updateLessonCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_LESSON_CATEGORIES).update(id, data); -} -```` - -## File: LessonTypes/_GUIDELINES.md -````markdown -# GUIDELINES - -This folder contains drivers for `LessonType`/`LessonTypes` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/LessonTypes/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_LESSON_TYPES } from '@/constants'; - -export async function createLessonType(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` -```` - -## File: LessonTypes/Create.tsx -````typescript -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/lesson_type/lesson-type'; - -export default function createLessonType(data: CreateForm): Promise { - return pb.collection(COL_LESSON_TYPES).create(data); -} -```` - -## File: LessonTypes/Delete.tsx -````typescript -import { COL_LESSON_TYPES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteLessonType(id: string): Promise { - return pb.collection(COL_LESSON_TYPES).delete(id); -} -```` - -## File: LessonTypes/GetAll.tsx -````typescript -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllLessonTypes(): Promise { - return pb.collection(COL_LESSON_TYPES).getFullList(); -} -```` - -## File: LessonTypes/GetAllCount.tsx -````typescript -// REQ0006 -import { COL_LESSON_TYPES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_TYPES).getList(1, 9999, {}); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: LessonTypes/GetById.tsx -````typescript -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getLessonTypeById(id: string): Promise { - return pb.collection(COL_LESSON_TYPES).getOne(id); -} -```` - -## File: LessonTypes/GetHiddenCount.tsx -````typescript -// REQ0006 -import { COL_LESSON_TYPES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_TYPES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: LessonTypes/GetVisibleCount.tsx -````typescript -// REQ0006 -import { COL_LESSON_TYPES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_TYPES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: LessonTypes/Helloworld.tsx -````typescript -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; -```` - -## File: LessonTypes/Update.tsx -````typescript -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/lesson_type/lesson-type'; - -export default function updateLessonType(id: string, data: CreateForm): Promise { - return pb.collection(COL_LESSON_TYPES).update(id, data); -} -```` - -## File: Messages/_GUIDELINES.md -````markdown -# GUIDELINES - -This folder contains drivers for `Message`/`Messages` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Messages/type.d.tsx` -- Message records require special handling for: - - Sender/receiver validation - - Timestamp management - - Read status tracking - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createMessage(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection('Messages')) -} -``` -```` - -## File: Messages/Create.tsx.draft -```` -import { COL_MESSAGES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/message/types'; - -export default function createMessage(data: CreateForm): Promise { - return pb.collection(COL_MESSAGES).create(data); -} -```` - -## File: Messages/Delete.tsx.draft -```` -import { COL_MESSAGES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteMessage(id: string): Promise { - return pb.collection(COL_MESSAGES).delete(id); -} -```` - -## File: Messages/GetAll.tsx.draft -```` -import { COL_MESSAGES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllMessages(): Promise { - return pb.collection(COL_MESSAGES).getFullList({ - expand: 'user_id', // Expand related user data - sort: '-created' // Sort by most recent first - }); -} -```` - -## File: Messages/GetAllCount.tsx.draft -```` -import { COL_MESSAGES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getAllMessagesCount(status?: string): Promise { - const filter = status ? `status = "${status}"` : ''; - const { totalItems: count } = await pb - .collection(COL_MESSAGES) - .getList(1, 9999, { filter }); - return count; -} -```` - -## File: Messages/GetById.tsx.draft -```` -import { COL_MESSAGES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getMessageById(id: string): Promise { - return pb.collection(COL_MESSAGES).getOne(id, { - expand: 'user_id' // Expand related user data - }); -} -```` - -## File: Messages/GetHiddenCount.tsx.draft -```` -// REQ0006 -import { COL_MESSAGES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_MESSAGES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: Messages/GetVisibleCount.tsx.draft -```` -// REQ0006 -import { COL_MESSAGES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_MESSAGES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: Messages/Update.tsx.draft -```` -import { COL_MESSAGES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { UpdateForm } from '@/components/dashboard/message/types'; - -export default function updateMessage(id: string, data: UpdateForm): Promise { - return pb.collection(COL_MESSAGES).update(id, data); -} -```` - -## File: QuizCategories/Create.tsx.draft -```` -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface CreateForm { - // TODO: Add QuizCategories fields -} - -export default function createQuizCategory(data: CreateForm): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).create(data); -} -```` - -## File: QuizCategories/Delete.tsx.draft -```` -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizCategory(id: string): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).delete(id); -} -```` - -## File: QuizCategories/GetAll.tsx.draft -```` -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizCategories(): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).getFullList(); -} -```` - -## File: QuizCategories/GetById.tsx.draft -```` -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).getOne(id); -} -```` - -## File: QuizCategories/GetHiddenCount.tsx.draft -```` -// REQ0006 -import { COL_QUIZ_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizCategories/GetVisibleCount.tsx.draft -```` -// REQ0006 -import { COL_QUIZ_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizCategories/Helloworld.tsx.draft -```` -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; -```` - -## File: QuizCategories/Update.tsx.draft -```` -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface UpdateForm { - // TODO: Add QuizCategories fields -} - -export default function updateQuizCategory(id: string, data: UpdateForm): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).update(id, data); -} -```` - -## File: QuizConnectives/Create.tsx.draft -```` -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface CreateForm { - // TODO: Add QuizConnectives fields -} - -export default function createQuizConnective(data: CreateForm): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).create(data); -} -```` - -## File: QuizConnectives/Delete.tsx.draft -```` -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizConnective(id: string): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).delete(id); -} -```` - -## File: QuizConnectives/GetAll.tsx.draft -```` -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizConnectives(): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).getFullList(); -} -```` - -## File: QuizConnectives/GetById.tsx.draft -```` -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizConnectiveById(id: string): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).getOne(id); -} -```` - -## File: QuizConnectives/GetHiddenCount.tsx.draft -```` -// REQ0006 -import { COL_QUIZ_CONNECTIVES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CONNECTIVES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizConnectives/GetVisibleCount.tsx.draft -```` -// REQ0006 -import { COL_QUIZ_CONNECTIVES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CONNECTIVES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizConnectives/Helloworld.tsx.draft -```` -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; -```` - -## File: QuizConnectives/Update.tsx.draft -```` -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface UpdateForm { - // TODO: Add QuizConnectives fields -} - -export default function updateQuizConnective(id: string, data: UpdateForm): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).update(id, data); -} -```` - -## File: QuizConnectivesCategories/Create.tsx.draft -```` -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface CreateForm { - // TODO: Add QuizConnectivesCategories fields -} - -export default function createQuizConnectivesCategory(data: CreateForm): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).create(data); -} -```` - -## File: QuizConnectivesCategories/Delete.tsx.draft -```` -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizConnectivesCategory(id: string): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).delete(id); -} -```` - -## File: QuizConnectivesCategories/GetAll.tsx.draft -```` -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizConnectivesCategories(): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).getFullList(); -} -```` - -## File: QuizConnectivesCategories/GetById.tsx.draft -```` -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizConnectivesCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).getOne(id); -} -```` - -## File: QuizConnectivesCategories/GetHiddenCount.tsx.draft -```` -// REQ0006 -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb - .collection(COL_QUIZ_CONNECTIVES_CATEGORIES) - .getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizConnectivesCategories/GetVisibleCount.tsx.draft -```` -// REQ0006 -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb - .collection(COL_QUIZ_CONNECTIVES_CATEGORIES) - .getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizConnectivesCategories/Helloworld.tsx.draft -```` -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; -```` - -## File: QuizConnectivesCategories/Update.tsx.draft -```` -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface UpdateForm { - // TODO: Add QuizConnectivesCategories fields -} - -export default function updateQuizConnectivesCategory(id: string, data: UpdateForm): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).update(id, data); -} -```` - -## File: QuizCRCategories/_GUIDELINES.md -````markdown -# GUIDELINES - -This folder contains drivers for `QuizCRCategory`/`QuizCRCategories` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/QuizCRCategories/type.d.tsx` -- Quiz categories may require additional validation logic - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; - -export async function createQuizCRCategory(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` -```` - -## File: QuizCRCategories/Create.tsx -````typescript -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'; - -export default function createQuizCRCategory(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).create(data); -} -```` - -## File: QuizCRCategories/Delete.tsx -````typescript -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizCRCategories(id: string): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).delete(id); -} -```` - -## File: QuizCRCategories/GetAll.tsx -````typescript -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import { pb } from '@/lib/pb'; - -export default function getAllQuizCRCategories(): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).getFullList(); -} -```` - -## File: QuizCRCategories/GetAllCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_CR_CATEGORIES).getList(1, 9999, {}); - return count; -} -```` - -## File: QuizCRCategories/GetById.tsx -````typescript -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizCRCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).getOne(id); -} -```` - -## File: QuizCRCategories/GetHiddenCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizCRCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CR_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizCRCategories/GetVisibleCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizCRCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CR_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizCRCategories/Update.tsx -````typescript -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/cr/categories/type'; - -export default function updateQuizCRCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).update(id, data); -} -```` - -## File: QuizCRQuestions/Create.tsx -````typescript -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/cr/questions/type'; - -// interface CreateForm { -// // TODO: Add QuizCRQuestions fields -// } - -export default function createQuizCRQuestion(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_CR_QUESTIONS).create(data); -} -```` - -## File: QuizCRQuestions/Delete.tsx -````typescript -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizCRQuestions(id: string): Promise { - return pb.collection(COL_QUIZ_CR_QUESTIONS).delete(id); -} -```` - -## File: QuizCRQuestions/GetAll.tsx -````typescript -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizCRQuestions(): Promise { - return pb.collection(COL_QUIZ_CR_QUESTIONS).getFullList(); -} -```` - -## File: QuizCRQuestions/GetAllCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_CR_QUESTIONS).getList(1, 9999, {}); - return count; -} -```` - -## File: QuizCRQuestions/GetHiddenCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizCRQuestionsCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CR_QUESTIONS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizCRQuestions/GetVisibleCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizCRQuestionsCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CR_QUESTIONS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizListenings/Delete.tsx -````typescript -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizLPCategories(id: string): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).delete(id); -} -```` - -## File: QuizListenings/GetAll.tsx -````typescript -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizListenings(): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getFullList(); -} -```` - -## File: QuizListenings/GetAllCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, {}); - return count; -} -```` - -## File: QuizListenings/GetById.tsx -````typescript -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizListeningById(id: string): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getOne(id); -} -```` - -## File: QuizListenings/GetHiddenCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizListenings/GetVisibleCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizListenings/ListWithOption.tsx -````typescript -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { ListResult, RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface ListWithOptionParams { - currentPage: number; - rowsPerPage: number; - listOption?: { - filter?: string; - sort?: string; - expand?: string; - }; -} - -export default function listWithOption({ - currentPage, - rowsPerPage, - listOption = {}, -}: ListWithOptionParams): Promise> { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getList(currentPage + 1, rowsPerPage, listOption); -} -```` - -## File: QuizLPCategories/_GUIDELINES.md -````markdown -# GUIDELINES - -This folder contains drivers for `QuizLPCategory` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/QuizLPCategories/type.d.tsx` -- Quiz LP categories may require additional validation logic - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -export async function createQuizLPCategory(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(COL_QUIZ_LP_CATEGORIES)) -} -``` -```` - -## File: QuizLPCategories/Create.tsx -````typescript -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'; - -export default function createQuizLPCategory(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).create(data); -} -```` - -## File: QuizLPCategories/Delete.tsx -````typescript -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizLPCategories(id: string): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).delete(id); -} -```` - -## File: QuizLPCategories/GetAll.tsx -````typescript -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizLPCategories(): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getFullList(); -} -```` - -## File: QuizLPCategories/GetAllCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, {}); - return count; -} -```` - -## File: QuizLPCategories/GetById.tsx -````typescript -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizLPCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getOne(id); -} -```` - -## File: QuizLPCategories/GetHiddenCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizLPCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizLPCategories/GetVisibleCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizLPCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizLPCategories/Update.tsx -````typescript -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/categories/type'; - -export default function updateQuizLPCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).update(id, data); -} -```` - -## File: QuizLPQuestions/_GUIDELINES.md -````markdown -# GUIDELINES - -This folder contains drivers for `QuizLPQuestion` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/QuizLPQuestions/type.d.tsx` -- Quiz LP questions require special handling for: - - Answer validation - - Question type checking - - Category association - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -export async function createQuizLPQuestion(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(COL_QUIZ_LP_QUESTIONS)) -} -``` -```` - -## File: QuizLPQuestions/_PROMPT.md -````markdown -please help to review the `tsx` file in this folder -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/QuizLPQuestions` - -it was clone from -`LPCategories` -please help to modify to -`LPQuestions` - -please also help to modify the name of -`variables`, `constants`, `functions`, `classes`, components's name, paths - -the db fields structures between them are the same - -do not move the files -do not create directories -keep current folder structure is important - -thanks -```` - -## File: QuizLPQuestions/Create.tsx -````typescript -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/questions/type'; - -// interface CreateForm { -// // TODO: Add QuizLPQuestions fields -// } - -export default function createQuizLPQuestion(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_LP_QUESTIONS).create(data); -} -```` - -## File: QuizLPQuestions/Delete.tsx -````typescript -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizLPQuestions(id: string): Promise { - return pb.collection(COL_QUIZ_LP_QUESTIONS).delete(id); -} -```` - -## File: QuizLPQuestions/GetAll.tsx -````typescript -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizLPQuestions(): Promise { - return pb.collection(COL_QUIZ_LP_QUESTIONS).getFullList(); -} -```` - -## File: QuizLPQuestions/GetAllCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_LP_QUESTIONS).getList(1, 9999, {}); - return count; -} -```` - -## File: QuizLPQuestions/GetById.tsx -````typescript -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizLPQuestionById(id: string): Promise { - return pb.collection(COL_QUIZ_LP_QUESTIONS).getOne(id); -} -```` - -## File: QuizLPQuestions/GetHiddenCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizLPQuestionsCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_QUESTIONS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizLPQuestions/GetVisibleCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizLPQuestionsCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_QUESTIONS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizLPQuestions/Update.tsx -````typescript -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/categories/type'; - -export default function updateQuizLPCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).update(id, data); -} -```` - -## File: QuizMFCategories/Create.tsx -````typescript -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/mf/categories/type'; - -export default function createQuizMFCategory(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).create(data); -} -```` - -## File: QuizMFCategories/Delete.tsx -````typescript -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizMFCategories(id: string): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).delete(id); -} -```` - -## File: QuizMFCategories/GetAll.tsx -````typescript -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizMFCategories(): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).getFullList(); -} -```` - -## File: QuizMFCategories/GetAllCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_MF_CATEGORIES).getList(1, 9999, {}); - return count; -} -```` - -## File: QuizMFCategories/GetById.tsx -````typescript -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizMFCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).getOne(id); -} -```` - -## File: QuizMFCategories/GetHiddenCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizMFCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_MF_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizMFCategories/GetVisibleCount.tsx -````typescript -// REQ0006 -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizMFCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_MF_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: QuizMFCategories/Update.tsx -````typescript -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/mf/categories/type'; - -export default function updateQuizMFCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).update(id, data); -} -```` - -## File: Students/Create.tsx -````typescript -// api method for create student record -// RULES: -// TBA -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; -import type { CreateFormProps } from '@/components/dashboard/student/type.d'; -import type { RecordModel } from 'pocketbase'; - -export async function createStudent(data: CreateFormProps): Promise { - return pb.collection(COL_STUDENTS).create(data); -} -```` - -## File: Students/Delete.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; - -export async function deleteStudent(id: string): Promise { - return pb.collection(COL_STUDENTS).delete(id); -} -```` - -## File: Students/GetActiveCount.tsx -````typescript -import { COL_STUDENTS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetActiveCount(): Promise { - const { totalItems: count } = await pb.collection(COL_STUDENTS).getList(1, 1, { - filter: 'status = "active"', - }); - return count; -} -```` - -## File: Students/GetAll.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getAllStudents(options = {}): Promise { - return pb.collection(COL_STUDENTS).getFullList(options); -} -```` - -## File: Students/GetAllCount.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; - -export async function getAllStudentsCount(): Promise { - const result = await pb.collection(COL_STUDENTS).getList(1, 1); - return result.totalItems; -} -```` - -## File: Students/GetBlockedCount.tsx -````typescript -import { COL_STUDENTS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetBlockedCount(): Promise { - const { totalItems: count } = await pb.collection(COL_STUDENTS).getList(1, 1, { - filter: 'status = "blocked"', - }); - return count; -} -```` - -## File: Students/GetById.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getStudentById(id: string): Promise { - return pb.collection(COL_STUDENTS).getOne(id); -} -```` - -## File: Students/Update.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import type { EditFormProps } from '@/components/dashboard/student/type.d'; - -export async function updateStudent(id: string, data: Partial): Promise { - return pb.collection(COL_STUDENTS).update(id, data); -} -```` - -## File: Subscriptions/_GUIDELINES.md -````markdown -# GUIDELINES - -This folder contains drivers for `Subscription`/`Subscriptions` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Subscriptions/type.d.tsx` -- Subscription records require special handling for: - - Payment status validation - - Expiration date checks - - Auto-renewal logic - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createSubscription(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection('Subscriptions')) -} -``` -```` - -## File: Subscriptions/Create.tsx.draft -```` -import { COL_SUBSCRIPTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/subscription/types'; - -export default function createSubscription(data: CreateForm): Promise { - return pb.collection(COL_SUBSCRIPTIONS).create(data); -} -```` - -## File: Subscriptions/Delete.tsx.draft -```` -import { COL_SUBSCRIPTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteSubscription(id: string): Promise { - // TODO: Add validation for active subscriptions if needed - return pb.collection(COL_SUBSCRIPTIONS).delete(id); -} -```` - -## File: Subscriptions/GetAll.tsx.draft -```` -import { COL_SUBSCRIPTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllSubscriptions(): Promise { - return pb.collection(COL_SUBSCRIPTIONS).getFullList({ - expand: 'user_id,plan_id', // Expand related user and plan data - sort: '-created' // Sort by most recent first - }); -} -```` - -## File: Subscriptions/GetAllCount.tsx.draft -```` -import { COL_SUBSCRIPTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getAllSubscriptionsCount(status?: string): Promise { - const filter = status ? `status = "${status}"` : ''; - const { totalItems: count } = await pb - .collection(COL_SUBSCRIPTIONS) - .getList(1, 9999, { filter }); - return count; -} -```` - -## File: Subscriptions/GetById.tsx.draft -```` -import { COL_SUBSCRIPTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getSubscriptionById(id: string): Promise { - return pb.collection(COL_SUBSCRIPTIONS).getOne(id, { - expand: 'user_id,plan_id' // Expand related user and plan data - }); -} -```` - -## File: Subscriptions/GetHiddenCount.tsx.draft -```` -// REQ0006 -import { COL_SUBSCRIPTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_SUBSCRIPTIONS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: Subscriptions/GetVisibleCount.tsx.draft -```` -// REQ0006 -import { COL_SUBSCRIPTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_SUBSCRIPTIONS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} -```` - -## File: Subscriptions/Update.tsx.draft -```` -import { COL_SUBSCRIPTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { UpdateForm } from '@/components/dashboard/subscription/types'; - -export default function updateSubscription(id: string, data: UpdateForm): Promise { - return pb.collection(COL_SUBSCRIPTIONS).update(id, data); -} -```` - -## File: Teachers/_GUIDELINES.md -````markdown -# GUIDELINES - -This folder contains drivers for `Teacher`/`Teachers` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Teachers/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createTeacher(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection('Teachers')) -} -``` -```` - -## File: Teachers/Create.tsx -````typescript -// api method for create teacher record -// RULES: -// TBA -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; -import type { CreateFormProps } from '@/components/dashboard/teacher/type.d'; -import type { RecordModel } from 'pocketbase'; - -export async function createTeacher(data: CreateFormProps): Promise { - return pb.collection(COL_TEACHERS).create(data); -} -```` - -## File: Teachers/GetActiveCount.tsx -````typescript -import { COL_TEACHERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetActiveCount(): Promise { - const { totalItems: count } = await pb.collection(COL_TEACHERS).getList(1, 1, { - filter: 'status = "active"', - }); - return count; -} -```` - -## File: Teachers/GetAll.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getAllTeachers(options = {}): Promise { - return pb.collection(COL_TEACHERS).getFullList(options); -} -```` - -## File: Teachers/GetAllCount.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; - -export async function getAllTeachersCount(): Promise { - const result = await pb.collection(COL_TEACHERS).getList(1, 1); - return result.totalItems; -} -```` - -## File: Teachers/GetBlockedCount.tsx -````typescript -import { COL_TEACHERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetBlockedCount(): Promise { - const { totalItems: count } = await pb.collection(COL_TEACHERS).getList(1, 1, { - filter: 'status = "blocked"', - }); - return count; -} -```` - -## File: Teachers/GetById.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getTeacherById(id: string): Promise { - return pb.collection(COL_TEACHERS).getOne(id); -} -```` - -## File: Teachers/GetPendingCount.tsx -````typescript -import { COL_TEACHERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetPendingCount(): Promise { - const { totalItems: count } = await pb.collection(COL_TEACHERS).getList(1, 1, { - filter: 'status = "pending"', - }); - return count; -} -```` - -## File: Teachers/Update.tsx -````typescript -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import type { EditFormProps } from '@/components/dashboard/teacher/type.d'; - -export async function updateTeacher(id: string, data: Partial): Promise { - return pb.collection(COL_TEACHERS).update(id, data); -} -```` - -## File: UserMetas/_GUIDELINES.md -````markdown -# GUIDELINES - -This folder contains drivers for `UserMeta`/`UserMetas` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/UserMetas/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_USER_METAS } from '@/constants'; - -export async function createUserMeta(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` -```` - -## File: UserMetas/Create.tsx.draft -```` -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/lesson_type/types'; - -// import type { CreateForm } from '@/components/dashboard/lesson_type/interfaces.ts.del'; - -export default function createLessonType(data: CreateForm): Promise { - return pb.collection(COL_LESSON_TYPES).create(data); -} -```` - -## File: UserMetas/Delete.tsx.draft -```` -import { COL_USER_METAS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default function deleteUserMeta(id: string): Promise { - return pb.collection(COL_USER_METAS).delete(id); -} -```` - -## File: UserMetas/GetAll.tsx.draft -```` -import { COL_USER_METAS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import { pb } from '@/lib/pb'; - -export default function getAllUserMetas(): Promise { - return pb.collection(COL_USER_METAS).getFullList(); -} -```` - -## File: UserMetas/GetAllCount.tsx -````typescript -// RULES: -// error handled by caller -// contain definition to collection only - -import { COL_USER_METAS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function getAllUserMetasCount(): Promise { - return pb - .collection(COL_USER_METAS) - .getList(1, 9998) - .then((res) => res.totalItems); -} -```` - -## File: UserMetas/GetById.tsx.draft -```` -import { COL_USER_METAS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import { pb } from '@/lib/pb'; - -export default function getUserMetaById(id: string): Promise { - return pb.collection(COL_USER_METAS).getOne(id); -} -```` - -## File: UserMetas/Update.tsx.draft -```` -import { COL_USER_METAS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/user_meta/types'; - -export default function updateUserMeta(id: string, data: CreateForm): Promise { - return pb.collection(COL_USER_METAS).update(id, data); -} -```` - -## File: Users/_GUIDELINES.md -````markdown -# GUIDELINES - -This folder contains drivers for `User`/`Users` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Users/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_USERS } from '@/constants'; - -export async function createUser(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` -```` - -## File: Users/Create.tsx.draft -```` -import { COL_USERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/user/types'; - - -export default function createUser(data: CreateForm): Promise { - return pb.collection(COL_USERS).create(data); -} -```` - -## File: Users/Delete.tsx.draft -```` -import { COL_USERS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteUser(id: string): Promise { - return pb.collection(COL_USERS).delete(id); -} -```` - -## File: Users/GetAll.tsx.draft -```` -import { COL_USERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllUsers(): Promise { - return pb.collection(COL_USERS).getFullList(); -} -```` - -## File: Users/GetAllCount.tsx -````typescript -// REQ0006 -import { COL_USERS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - try { - const result = await pb.collection(`users`).getList(1, 9999, { filter: 'email != ""' }); - const { totalItems: count } = result; - return count; - } catch (error) { - console.error(error); - return -99; - } -} -```` - -## File: Users/GetById.tsx.draft -```` -import { COL_USERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getUserById(id: string): Promise { - return pb.collection(COL_USERS).getOne(id); -} -```` - -## File: Users/Update.tsx.draft -```` -import { COL_USERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/user/types'; - -export default function updateUser(id: string, data: CreateForm): Promise { - return pb.collection(COL_USERS).update(id, data); -} -```` - -## File: DB_AI_GUIDELINE.MD -````markdown -# AI GUIDELINE - -## getting started - -Imagine there is a software developer and a QA engineer to solve the problems together - -They will: - -no need to reply me what you are going on and your digest in this phase. -just reply me "OK" when done - -base_dir=`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project` - -- read `/001_documentation/Requirements/REQ0006/schema.dbml` -this is file in dbml syntax state the main database - -- read `/002_source/cms/src/db/schema.json` -this is the file of live pocketbase schema output - -- read `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/constants.ts` -this is the content of `@/constants` - -- look into the md files in folder `/002_source/cms/_AI_GUIDELINE` - -- read, remember and link up the ideas in file stated above, -i will tell them the task afterwards - ---- - -The software engineer will provide solutions, -while QA engineer will feedback the opinion. - -this is now not in debug phase, -so, no need to reply me what they are going on or their insight throught the prompt. -just reply me "OK" when done - ---- - -clone `GetVisibleCount.tsx` and `GetHiddenCount.tsx` from `LessonTypes` to `LessonCategories` and update it - -please draft `GetHiddenCount.tsx` for COL_LESSON_TYPES and `status = hidden` - -well done !, please proceed to another request - -working directory: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db` - -according information from `schema.json`, get the collection of `Students` - -pleaes clone the `tsx` files from `LessonTypes` and `LessonCategories` to `Students` and update the content - -when you draft coding, review file and append with `.tsx.draft` - ---- - -- this is part of react typescript project, with pocketbase -- `schema.dbml`, describe the collections(tables) -- folder `LessonCategories`, the correct references -- folder `LessonTypes`, the correct references -- you can find the `schema.dbml` and schema information from `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/001_documentation/Requirements/REQ0006` -- do not read root directory, assume it is a fresh copy of nextjs project is ok - -## instruction - -- break the questions into smaller parts -- review file append with `.draft`, see if the content aligned with the correct references -- read and understand `dbml` file -- lookup the every folder - -## tasks - -Thanks - - - ---- - - -please take a look in `schema.dbml` and `schema.json`, -associate the collection from json file to the table in dbml file - -please modify the `schema.dbml` to align with `schema.json` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - - ---- - -please revise - -please revise -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx` `interface LpCategory` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - - -please modify `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lp_categories/_constants.tsx` - -to follow the type definition in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx`, the constant `defaultLpCategory` - ---- - -the constants file (`@/constants`) was `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/constants.ts` - -please help to fix the `tsx` files in folder `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/QuizMFCategories`, -the `COL` constants is wrongly used, it should refer to `COL_QUIZ_MF_CATEGORIES`. thanks - - -please update the `COL_XXXX` TO COL_MF_CATEGORIES -```` - -## File: repomix-output.xml -````xml -This file is a merged representation of the entire codebase, combined into a single document by Repomix. - - -This section contains a summary of this file. - - -This file contains a packed representation of the entire repository's contents. -It is designed to be easily consumable by AI systems for analysis, code review, -or other automated processes. - - - -The content is organized as follows: -1. This summary section -2. Repository information -3. Directory structure -4. Repository files, each consisting of: - - File path as an attribute - - Full contents of the file - - - -- This file should be treated as read-only. Any changes should be made to the - original repository files, not this packed version. -- When processing this file, use the file path to distinguish - between different files in the repository. -- Be aware that this file may contain sensitive information. Handle it with - the same level of security as you would the original repository. - - - -- Some files may have been excluded based on .gitignore rules and Repomix's configuration -- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files -- Files matching patterns in .gitignore are excluded -- Files matching default ignore patterns are excluded -- Files are sorted by Git change count (files with more changes are at the bottom) - - - - - - - - - -_PROMPT/ - 1.MD - 2.MD - 3.MD - 4.md - temp.md -Customers/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetActiveCount.tsx - GetAll.tsx - GetAllCount.tsx - GetBlockedCount.tsx - GetById.tsx - GetPendingCount.tsx - Helloworld.tsx - Update.tsx -Events/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Update.tsx.draft -Helloworlds/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Helloworld.tsx.draft - Update.tsx.draft -LessonCategories/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Helloworld.tsx - Update.tsx -LessonTypes/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Helloworld.tsx - Update.tsx -Messages/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Update.tsx.draft -QuizCategories/ - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Helloworld.tsx.draft - Update.tsx.draft -QuizConnectives/ - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Helloworld.tsx.draft - Update.tsx.draft -QuizConnectivesCategories/ - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Helloworld.tsx.draft - Update.tsx.draft -QuizCRCategories/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Update.tsx -QuizCRQuestions/ - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx -QuizListenings/ - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - ListWithOption.tsx -QuizLPCategories/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Update.tsx -QuizLPQuestions/ - _GUIDELINES.md - _PROMPT.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Update.tsx -QuizMFCategories/ - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Update.tsx -Students/ - Create.tsx - Delete.tsx - GetActiveCount.tsx - GetAll.tsx - GetAllCount.tsx - GetBlockedCount.tsx - GetById.tsx - Update.tsx -Subscriptions/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Update.tsx.draft -Teachers/ - _GUIDELINES.md - Create.tsx - GetActiveCount.tsx - GetAll.tsx - GetAllCount.tsx - GetBlockedCount.tsx - GetById.tsx - GetPendingCount.tsx - Update.tsx -UserMetas/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx - GetById.tsx.draft - Update.tsx.draft -Users/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx - GetById.tsx.draft - Update.tsx.draft -DB_AI_GUIDELINE.MD -schema.json - - - -This section contains the contents of the repository's files. - - -Hi, please study the documentation below, -i will send you the task afterwards, - -please read and understand the documentation below and link up the ideas -reply `OK` when you done -no need to state me any other things, thanks - -1. `schema.dbml` - -- this describe the database schema in dbml format -- filepath: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/001_documentation/Requirements/REQ0006/schema.dbml` - -2. `schema.json` - -- this is the schema export in pocketbase format -- filepath: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/schema.json` - -3. `_AI_GUIDELINE`: - -- there are the markdown files that help you better understand the implementation -- directory: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/_AI_GUIDELINE` - -thanks - ---- - -# task - -clone from `LessonTypes` to `Customers` - -## steps - -1. read `tsx` files from `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/LessonTypes` -1. copy file to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/Customers` -1. modify the copied `tsx` files to suit `customer` fields - - - -update `LpCategoryDefaultValue` -in file `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lp_categories/_constants.ts` - -thanks - -you can find the type def in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx` - -please help to draft code file: - -base_dir=`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db` - -using -`$base_dir/QuizListenings/GetHiddenCount.tsx`, -`$base_dir/QuizListenings/GetVisibleCount.tsx`, -`$base_dir/LessonTypes/GetHiddenCount.tsx`, -`$base_dir/LessonTypes/GetVisibleCount.tsx`, -as reference, - -look into the all directories under base_dir e.g. `QuizCategories`. -propergate `GetHiddenCount.tsx` and `GetVisibleCount.tsx` if missing, do the change to suit the collection. -use `.draft.tsx` instead when you write file - ---- - -rewrite `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/LessonCategories/GetAllCount.tsx` to match `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/UserMetas/GetAllCount.tsx` style - ---- - -style rewrite - -study -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/overview/summary/ActiveUserCount/index.tsx` -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/overview/summary/LessonCategoriesCount/index.tsx` - -and rewrite `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/overview/summary/LessonTypeCount/index.tsx` to match style above thanks - - - -please draft with idea: - -``` -await pb -.collection(COL_LESSON_TYPES) -.getList(currentPage + 1, rowsPerPage, listOption); -``` - -for Listening Practice - -thanks - -I want you to clone -from `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/LessonTypes/GetVisibleCount.tsx` (source file) - -to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/QuizListenings/GetVisibleCount.tsx` (dest file) - -please extract , link up and remember the document properties -(e.g. types, functions, variables, constants, etc) -from source file -draft dest file - -update the variables and properties of dest file to reflect `listening practice categories`/`lp_categories` - ---- - -## task - -update `schema.dbml` to reflect `schema.json` - -## details - -Hi, -I have a pocketbase export json file: -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/pocketbase/pb_hooks/seed/schema.json` - -and a dbml file: -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/001_documentation/Requirements/REQ0006/schema.dbml` - -the collection name in pocketbase should be reflected by a table in dbml, - -## steps - -compare `schema.json` and `schema.dbml` -please keep `schema.json` remain unchanged -update `schema.dbml` to reflect `schema.json` -do check again when finished - - - ---- - -clone `GetVisibleCount.tsx` and `GetHiddenCount.tsx` from `LessonTypes` to `LessonCategories` and update it - -please draft `GetHiddenCount.tsx` for COL_LESSON_TYPES and `status = hidden` - -well done !, please proceed to another request - -working directory: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db` - -according information from `schema.json`, get the collection of `Students` - -pleaes clone the `tsx` files from `LessonTypes` and `LessonCategories` to `Students` and update the content - -when you draft coding, review file and append with `.tsx.draft` - ---- - -- this is part of react typescript project, with pocketbase -- `schema.dbml`, describe the collections(tables) -- folder `LessonCategories`, the correct references -- folder `LessonTypes`, the correct references -- you can find the `schema.dbml` and schema information from `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/001_documentation/Requirements/REQ0006` -- do not read root directory, assume it is a fresh copy of nextjs project is ok - -## instruction - -- break the questions into smaller parts -- review file append with `.draft`, see if the content aligned with the correct references -- read and understand `dbml` file -- lookup the every folder - -## tasks - -Thanks - ---- - -please take a look in `schema.dbml` and `schema.json`, -associate the collection from json file to the table in dbml file - -please modify the `schema.dbml` to align with `schema.json` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - ---- - -please revise - -please revise -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx` `interface LpCategory` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - -please modify `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lp_categories/_constants.tsx` - -to follow the type definition in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx`, the constant `defaultLpCategory` - - - -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lp_categories/lp-categories-filters.tsx` - -this file is original for `lesson_category` model, -please modify it to fit `lp_category` (listening practice category) - -thanks - - - -# GUIDELINES - -This folder contains drivers for `Customer`/`Customers` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx, GetActiveCount.tsx, GetBlockedCount.tsx, GetPendingCount.tsx) -- misc (Helloworld.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/Customers/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; - -export async function createCustomer(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` - - - -// api method for crate customer record -// RULES: -// TBA -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; -import type { CreateFormProps } from '@/components/dashboard/customer/type.d'; -import type { RecordModel } from 'pocketbase'; - -export async function createCustomer(data: CreateFormProps): Promise { - return pb.collection(COL_CUSTOMERS).create(data); -} - - - -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; - -export async function deleteCustomer(id: string): Promise { - return pb.collection(COL_CUSTOMERS).delete(id); -} - - - -import { COL_CUSTOMERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetActiveCount(): Promise { - const { totalItems: count } = await pb.collection(COL_CUSTOMERS).getList(1, 1, { - filter: 'status = "active"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getAllCustomers(options = {}): Promise { - return pb.collection(COL_CUSTOMERS).getFullList(options); -} - - - -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; - -export async function getAllCustomersCount(): Promise { - const result = await pb.collection(COL_CUSTOMERS).getList(1, 1); - return result.totalItems; -} - - - -import { COL_CUSTOMERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetBlockedCount(): Promise { - const { totalItems: count } = await pb.collection(COL_CUSTOMERS).getList(1, 1, { - filter: 'status = "blocked"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getCustomerById(id: string): Promise { - return pb.collection(COL_CUSTOMERS).getOne(id); -} - - - -import { COL_CUSTOMERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetPendingCount(): Promise { - const { totalItems: count } = await pb.collection(COL_CUSTOMERS).getList(1, 1, { - filter: 'status = "pending"', - }); - return count; -} - - - -export function helloCustomer() { - return 'Hello from Customers module!'; -} - - - -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import type { EditFormProps } from '@/components/dashboard/customer/type.d'; - -export async function updateCustomer(id: string, data: Partial): Promise { - return pb.collection(COL_CUSTOMERS).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `Event`/`Events` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Events/type.d.tsx` -- Event records require special handling for: - - Date/time validation - - Location data - - Attendee management - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createEvent(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection('Events')) -} -``` - - - -import { COL_EVENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/event/types'; - -export default function createEvent(data: CreateForm): Promise { - return pb.collection(COL_EVENTS).create(data); -} - - - -import { COL_EVENTS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteEvent(id: string): Promise { - return pb.collection(COL_EVENTS).delete(id); -} - - - -import { COL_EVENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllEvents(): Promise { - return pb.collection(COL_EVENTS).getFullList({ - sort: 'event_time' // Sort by event time - }); -} - - - -import { COL_EVENTS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getAllEventsCount(startDate?: string, endDate?: string): Promise { - let filter = ''; - if (startDate && endDate) { - filter = `event_time >= "${startDate}" && event_time <= "${endDate}"`; - } else if (startDate) { - filter = `event_time >= "${startDate}"`; - } else if (endDate) { - filter = `event_time <= "${endDate}"`; - } - - const { totalItems: count } = await pb - .collection(COL_EVENTS) - .getList(1, 9999, { filter }); - return count; -} - - - -import { COL_EVENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getEventById(id: string): Promise { - return pb.collection(COL_EVENTS).getOne(id); -} - - - -// REQ0006 -import { COL_EVENTS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_EVENTS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_EVENTS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_EVENTS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_EVENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { UpdateForm } from '@/components/dashboard/event/types'; - -export default function updateEvent(id: string, data: UpdateForm): Promise { - return pb.collection(COL_EVENTS).update(id, data); -} - - - -# GUIDELINES - -This folder contains test drivers for `Helloworld` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function -- type information defined in `@/db/Helloworlds/type.d.tsx` -- This is a test collection - keep implementations simple - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createHelloworld(data: CreateFormProps) { - // Simple test implementation - return pb.collection('Helloworlds').create(data); -} -``` - - - -import { COL_HELLOWORLDS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/helloworld/types'; - -export default function createHelloworld(data: CreateForm): Promise { - return pb.collection(COL_HELLOWORLDS).create(data); -} - - - -import { COL_HELLOWORLDS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default function deleteHelloworld(id: string): Promise { - return pb.collection(COL_HELLOWORLDS).delete(id); -} - - - -import { COL_HELLOWORLDS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllHelloworlds(): Promise { - return pb.collection(COL_HELLOWORLDS).getFullList(); -} - - - -import { COL_HELLOWORLDS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getHelloworldById(id: string): Promise { - return pb.collection(COL_HELLOWORLDS).getOne(id); -} - - - -// REQ0006 -import { COL_HELLOWORLDS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_HELLOWORLDS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_HELLOWORLDS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_HELLOWORLDS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; - - - -import { COL_HELLOWORLDS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/helloworld/types'; - -export default function updateHelloworld(id: string, data: CreateForm): Promise { - return pb.collection(COL_HELLOWORLDS).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `LessonCategory`/`LessonCategories` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/LessonCategories/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_LESSON_CATEGORIES } from '@/constants'; - -export async function createLessonCategory(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` - - - -import { COL_LESSON_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/categories/type'; - -export default function createLessonCategory(data: CreateFormProps): Promise { - return pb.collection(COL_LESSON_CATEGORIES).create(data); -} - - - -import { COL_LESSON_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteLessonCategory(id: string): Promise { - return pb.collection(COL_LESSON_CATEGORIES).delete(id); -} - - - -import { COL_LESSON_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllLessonCategories(): Promise { - return pb.collection(COL_LESSON_CATEGORIES).getFullList(); -} - - - -// RULES: -// error handled by caller -// contain definition to collection only - -import { COL_LESSON_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function getAllLessonCategoriesCount(): Promise { - return pb - .collection(COL_LESSON_CATEGORIES) - .getList(1, 9999) - .then((res) => res.totalItems); -} - - - -import { COL_LESSON_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getLessonCategoryById(id: string): Promise { - return pb.collection(COL_LESSON_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_LESSON_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_LESSON_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; - - - -import { COL_LESSON_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/categories/type'; - -export default function updateLessonCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_LESSON_CATEGORIES).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `LessonType`/`LessonTypes` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/LessonTypes/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_LESSON_TYPES } from '@/constants'; - -export async function createLessonType(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` - - - -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/lesson_type/lesson-type'; - -export default function createLessonType(data: CreateForm): Promise { - return pb.collection(COL_LESSON_TYPES).create(data); -} - - - -import { COL_LESSON_TYPES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteLessonType(id: string): Promise { - return pb.collection(COL_LESSON_TYPES).delete(id); -} - - - -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllLessonTypes(): Promise { - return pb.collection(COL_LESSON_TYPES).getFullList(); -} - - - -// REQ0006 -import { COL_LESSON_TYPES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_TYPES).getList(1, 9999, {}); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getLessonTypeById(id: string): Promise { - return pb.collection(COL_LESSON_TYPES).getOne(id); -} - - - -// REQ0006 -import { COL_LESSON_TYPES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_TYPES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_LESSON_TYPES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_TYPES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; - - - -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/lesson_type/lesson-type'; - -export default function updateLessonType(id: string, data: CreateForm): Promise { - return pb.collection(COL_LESSON_TYPES).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `Message`/`Messages` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Messages/type.d.tsx` -- Message records require special handling for: - - Sender/receiver validation - - Timestamp management - - Read status tracking - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createMessage(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection('Messages')) -} -``` - - - -import { COL_MESSAGES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/message/types'; - -export default function createMessage(data: CreateForm): Promise { - return pb.collection(COL_MESSAGES).create(data); -} - - - -import { COL_MESSAGES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteMessage(id: string): Promise { - return pb.collection(COL_MESSAGES).delete(id); -} - - - -import { COL_MESSAGES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllMessages(): Promise { - return pb.collection(COL_MESSAGES).getFullList({ - expand: 'user_id', // Expand related user data - sort: '-created' // Sort by most recent first - }); -} - - - -import { COL_MESSAGES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getAllMessagesCount(status?: string): Promise { - const filter = status ? `status = "${status}"` : ''; - const { totalItems: count } = await pb - .collection(COL_MESSAGES) - .getList(1, 9999, { filter }); - return count; -} - - - -import { COL_MESSAGES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getMessageById(id: string): Promise { - return pb.collection(COL_MESSAGES).getOne(id, { - expand: 'user_id' // Expand related user data - }); -} - - - -// REQ0006 -import { COL_MESSAGES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_MESSAGES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_MESSAGES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_MESSAGES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_MESSAGES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { UpdateForm } from '@/components/dashboard/message/types'; - -export default function updateMessage(id: string, data: UpdateForm): Promise { - return pb.collection(COL_MESSAGES).update(id, data); -} - - - -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface CreateForm { - // TODO: Add QuizCategories fields -} - -export default function createQuizCategory(data: CreateForm): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).create(data); -} - - - -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizCategory(id: string): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).delete(id); -} - - - -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizCategories(): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).getFullList(); -} - - - -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; - - - -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface UpdateForm { - // TODO: Add QuizCategories fields -} - -export default function updateQuizCategory(id: string, data: UpdateForm): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).update(id, data); -} - - - -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface CreateForm { - // TODO: Add QuizConnectives fields -} - -export default function createQuizConnective(data: CreateForm): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).create(data); -} - - - -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizConnective(id: string): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).delete(id); -} - - - -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizConnectives(): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).getFullList(); -} - - - -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizConnectiveById(id: string): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_CONNECTIVES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CONNECTIVES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_CONNECTIVES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CONNECTIVES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; - - - -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface UpdateForm { - // TODO: Add QuizConnectives fields -} - -export default function updateQuizConnective(id: string, data: UpdateForm): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).update(id, data); -} - - - -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface CreateForm { - // TODO: Add QuizConnectivesCategories fields -} - -export default function createQuizConnectivesCategory(data: CreateForm): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).create(data); -} - - - -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizConnectivesCategory(id: string): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).delete(id); -} - - - -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizConnectivesCategories(): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).getFullList(); -} - - - -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizConnectivesCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb - .collection(COL_QUIZ_CONNECTIVES_CATEGORIES) - .getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb - .collection(COL_QUIZ_CONNECTIVES_CATEGORIES) - .getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; - - - -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface UpdateForm { - // TODO: Add QuizConnectivesCategories fields -} - -export default function updateQuizConnectivesCategory(id: string, data: UpdateForm): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `QuizCRCategory`/`QuizCRCategories` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/QuizCRCategories/type.d.tsx` -- Quiz categories may require additional validation logic - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; - -export async function createQuizCRCategory(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` - - - -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'; - -export default function createQuizCRCategory(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).create(data); -} - - - -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizCRCategories(id: string): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).delete(id); -} - - - -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import { pb } from '@/lib/pb'; - -export default function getAllQuizCRCategories(): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).getFullList(); -} - - - -// REQ0006 -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_CR_CATEGORIES).getList(1, 9999, {}); - return count; -} - - - -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizCRCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizCRCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CR_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizCRCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CR_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/cr/categories/type'; - -export default function updateQuizCRCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).update(id, data); -} - - - -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/cr/questions/type'; - -// interface CreateForm { -// // TODO: Add QuizCRQuestions fields -// } - -export default function createQuizCRQuestion(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_CR_QUESTIONS).create(data); -} - - - -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizCRQuestions(id: string): Promise { - return pb.collection(COL_QUIZ_CR_QUESTIONS).delete(id); -} - - - -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizCRQuestions(): Promise { - return pb.collection(COL_QUIZ_CR_QUESTIONS).getFullList(); -} - - - -// REQ0006 -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_CR_QUESTIONS).getList(1, 9999, {}); - return count; -} - - - -// REQ0006 -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizCRQuestionsCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CR_QUESTIONS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizCRQuestionsCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CR_QUESTIONS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizLPCategories(id: string): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).delete(id); -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizListenings(): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getFullList(); -} - - - -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, {}); - return count; -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizListeningById(id: string): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { ListResult, RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface ListWithOptionParams { - currentPage: number; - rowsPerPage: number; - listOption?: { - filter?: string; - sort?: string; - expand?: string; - }; -} - -export default function listWithOption({ - currentPage, - rowsPerPage, - listOption = {}, -}: ListWithOptionParams): Promise> { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getList(currentPage + 1, rowsPerPage, listOption); -} - - - -# GUIDELINES - -This folder contains drivers for `QuizLPCategory` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/QuizLPCategories/type.d.tsx` -- Quiz LP categories may require additional validation logic - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -export async function createQuizLPCategory(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(COL_QUIZ_LP_CATEGORIES)) -} -``` - - - -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'; - -export default function createQuizLPCategory(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).create(data); -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizLPCategories(id: string): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).delete(id); -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizLPCategories(): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getFullList(); -} - - - -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, {}); - return count; -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizLPCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizLPCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizLPCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/categories/type'; - -export default function updateQuizLPCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `QuizLPQuestion` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/QuizLPQuestions/type.d.tsx` -- Quiz LP questions require special handling for: - - Answer validation - - Question type checking - - Category association - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -export async function createQuizLPQuestion(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(COL_QUIZ_LP_QUESTIONS)) -} -``` - - - -please help to review the `tsx` file in this folder -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/QuizLPQuestions` - -it was clone from -`LPCategories` -please help to modify to -`LPQuestions` - -please also help to modify the name of -`variables`, `constants`, `functions`, `classes`, components's name, paths - -the db fields structures between them are the same - -do not move the files -do not create directories -keep current folder structure is important - -thanks - - - -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/questions/type'; - -// interface CreateForm { -// // TODO: Add QuizLPQuestions fields -// } - -export default function createQuizLPQuestion(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_LP_QUESTIONS).create(data); -} - - - -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizLPQuestions(id: string): Promise { - return pb.collection(COL_QUIZ_LP_QUESTIONS).delete(id); -} - - - -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizLPQuestions(): Promise { - return pb.collection(COL_QUIZ_LP_QUESTIONS).getFullList(); -} - - - -// REQ0006 -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_LP_QUESTIONS).getList(1, 9999, {}); - return count; -} - - - -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizLPQuestionById(id: string): Promise { - return pb.collection(COL_QUIZ_LP_QUESTIONS).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizLPQuestionsCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_QUESTIONS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizLPQuestionsCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_QUESTIONS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/categories/type'; - -export default function updateQuizLPCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).update(id, data); -} - - - -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/mf/categories/type'; - -export default function createQuizMFCategory(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).create(data); -} - - - -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizMFCategories(id: string): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).delete(id); -} - - - -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizMFCategories(): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).getFullList(); -} - - - -// REQ0006 -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_MF_CATEGORIES).getList(1, 9999, {}); - return count; -} - - - -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizMFCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizMFCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_MF_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizMFCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_MF_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/mf/categories/type'; - -export default function updateQuizMFCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).update(id, data); -} - - - -// api method for create student record -// RULES: -// TBA -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; -import type { CreateFormProps } from '@/components/dashboard/student/type.d'; -import type { RecordModel } from 'pocketbase'; - -export async function createStudent(data: CreateFormProps): Promise { - return pb.collection(COL_STUDENTS).create(data); -} - - - -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; - -export async function deleteStudent(id: string): Promise { - return pb.collection(COL_STUDENTS).delete(id); -} - - - -import { COL_STUDENTS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetActiveCount(): Promise { - const { totalItems: count } = await pb.collection(COL_STUDENTS).getList(1, 1, { - filter: 'status = "active"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getAllStudents(options = {}): Promise { - return pb.collection(COL_STUDENTS).getFullList(options); -} - - - -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; - -export async function getAllStudentsCount(): Promise { - const result = await pb.collection(COL_STUDENTS).getList(1, 1); - return result.totalItems; -} - - - -import { COL_STUDENTS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetBlockedCount(): Promise { - const { totalItems: count } = await pb.collection(COL_STUDENTS).getList(1, 1, { - filter: 'status = "blocked"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getStudentById(id: string): Promise { - return pb.collection(COL_STUDENTS).getOne(id); -} - - - -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import type { EditFormProps } from '@/components/dashboard/student/type.d'; - -export async function updateStudent(id: string, data: Partial): Promise { - return pb.collection(COL_STUDENTS).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `Subscription`/`Subscriptions` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Subscriptions/type.d.tsx` -- Subscription records require special handling for: - - Payment status validation - - Expiration date checks - - Auto-renewal logic - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createSubscription(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection('Subscriptions')) -} -``` - - - -import { COL_SUBSCRIPTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/subscription/types'; - -export default function createSubscription(data: CreateForm): Promise { - return pb.collection(COL_SUBSCRIPTIONS).create(data); -} - - - -import { COL_SUBSCRIPTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteSubscription(id: string): Promise { - // TODO: Add validation for active subscriptions if needed - return pb.collection(COL_SUBSCRIPTIONS).delete(id); -} - - - -import { COL_SUBSCRIPTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllSubscriptions(): Promise { - return pb.collection(COL_SUBSCRIPTIONS).getFullList({ - expand: 'user_id,plan_id', // Expand related user and plan data - sort: '-created' // Sort by most recent first - }); -} - - - -import { COL_SUBSCRIPTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getAllSubscriptionsCount(status?: string): Promise { - const filter = status ? `status = "${status}"` : ''; - const { totalItems: count } = await pb - .collection(COL_SUBSCRIPTIONS) - .getList(1, 9999, { filter }); - return count; -} - - - -import { COL_SUBSCRIPTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getSubscriptionById(id: string): Promise { - return pb.collection(COL_SUBSCRIPTIONS).getOne(id, { - expand: 'user_id,plan_id' // Expand related user and plan data - }); -} - - - -// REQ0006 -import { COL_SUBSCRIPTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_SUBSCRIPTIONS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_SUBSCRIPTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_SUBSCRIPTIONS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_SUBSCRIPTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { UpdateForm } from '@/components/dashboard/subscription/types'; - -export default function updateSubscription(id: string, data: UpdateForm): Promise { - return pb.collection(COL_SUBSCRIPTIONS).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `Teacher`/`Teachers` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Teachers/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createTeacher(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection('Teachers')) -} -``` - - - -// api method for create teacher record -// RULES: -// TBA -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; -import type { CreateFormProps } from '@/components/dashboard/teacher/type.d'; -import type { RecordModel } from 'pocketbase'; - -export async function createTeacher(data: CreateFormProps): Promise { - return pb.collection(COL_TEACHERS).create(data); -} - - - -import { COL_TEACHERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetActiveCount(): Promise { - const { totalItems: count } = await pb.collection(COL_TEACHERS).getList(1, 1, { - filter: 'status = "active"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getAllTeachers(options = {}): Promise { - return pb.collection(COL_TEACHERS).getFullList(options); -} - - - -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; - -export async function getAllTeachersCount(): Promise { - const result = await pb.collection(COL_TEACHERS).getList(1, 1); - return result.totalItems; -} - - - -import { COL_TEACHERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetBlockedCount(): Promise { - const { totalItems: count } = await pb.collection(COL_TEACHERS).getList(1, 1, { - filter: 'status = "blocked"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getTeacherById(id: string): Promise { - return pb.collection(COL_TEACHERS).getOne(id); -} - - - -import { COL_TEACHERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetPendingCount(): Promise { - const { totalItems: count } = await pb.collection(COL_TEACHERS).getList(1, 1, { - filter: 'status = "pending"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import type { EditFormProps } from '@/components/dashboard/teacher/type.d'; - -export async function updateTeacher(id: string, data: Partial): Promise { - return pb.collection(COL_TEACHERS).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `UserMeta`/`UserMetas` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/UserMetas/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_USER_METAS } from '@/constants'; - -export async function createUserMeta(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` - - - -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/lesson_type/types'; - -// import type { CreateForm } from '@/components/dashboard/lesson_type/interfaces.ts.del'; - -export default function createLessonType(data: CreateForm): Promise { - return pb.collection(COL_LESSON_TYPES).create(data); -} - - - -import { COL_USER_METAS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default function deleteUserMeta(id: string): Promise { - return pb.collection(COL_USER_METAS).delete(id); -} - - - -import { COL_USER_METAS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import { pb } from '@/lib/pb'; - -export default function getAllUserMetas(): Promise { - return pb.collection(COL_USER_METAS).getFullList(); -} - - - -// RULES: -// error handled by caller -// contain definition to collection only - -import { COL_USER_METAS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function getAllUserMetasCount(): Promise { - return pb - .collection(COL_USER_METAS) - .getList(1, 9998) - .then((res) => res.totalItems); -} - - - -import { COL_USER_METAS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import { pb } from '@/lib/pb'; - -export default function getUserMetaById(id: string): Promise { - return pb.collection(COL_USER_METAS).getOne(id); -} - - - -import { COL_USER_METAS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/user_meta/types'; - -export default function updateUserMeta(id: string, data: CreateForm): Promise { - return pb.collection(COL_USER_METAS).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `User`/`Users` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Users/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_USERS } from '@/constants'; - -export async function createUser(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` - - - -import { COL_USERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/user/types'; - - -export default function createUser(data: CreateForm): Promise { - return pb.collection(COL_USERS).create(data); -} - - - -import { COL_USERS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteUser(id: string): Promise { - return pb.collection(COL_USERS).delete(id); -} - - - -import { COL_USERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllUsers(): Promise { - return pb.collection(COL_USERS).getFullList(); -} - - - -// REQ0006 -import { COL_USERS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - try { - const result = await pb.collection(`users`).getList(1, 9999, { filter: 'email != ""' }); - const { totalItems: count } = result; - return count; - } catch (error) { - console.error(error); - return -99; - } -} - - - -import { COL_USERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getUserById(id: string): Promise { - return pb.collection(COL_USERS).getOne(id); -} - - - -import { COL_USERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/user/types'; - -export default function updateUser(id: string, data: CreateForm): Promise { - return pb.collection(COL_USERS).update(id, data); -} - - - -# AI GUIDELINE - -## getting started - -Imagine there is a software developer and a QA engineer to solve the problems together - -They will: - -no need to reply me what you are going on and your digest in this phase. -just reply me "OK" when done - -base_dir=`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project` - -- read `/001_documentation/Requirements/REQ0006/schema.dbml` -this is file in dbml syntax state the main database - -- read `/002_source/cms/src/db/schema.json` -this is the file of live pocketbase schema output - -- read `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/constants.ts` -this is the content of `@/constants` - -- look into the md files in folder `/002_source/cms/_AI_GUIDELINE` - -- read, remember and link up the ideas in file stated above, -i will tell them the task afterwards - ---- - -The software engineer will provide solutions, -while QA engineer will feedback the opinion. - -this is now not in debug phase, -so, no need to reply me what they are going on or their insight throught the prompt. -just reply me "OK" when done - ---- - -clone `GetVisibleCount.tsx` and `GetHiddenCount.tsx` from `LessonTypes` to `LessonCategories` and update it - -please draft `GetHiddenCount.tsx` for COL_LESSON_TYPES and `status = hidden` - -well done !, please proceed to another request - -working directory: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db` - -according information from `schema.json`, get the collection of `Students` - -pleaes clone the `tsx` files from `LessonTypes` and `LessonCategories` to `Students` and update the content - -when you draft coding, review file and append with `.tsx.draft` - ---- - -- this is part of react typescript project, with pocketbase -- `schema.dbml`, describe the collections(tables) -- folder `LessonCategories`, the correct references -- folder `LessonTypes`, the correct references -- you can find the `schema.dbml` and schema information from `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/001_documentation/Requirements/REQ0006` -- do not read root directory, assume it is a fresh copy of nextjs project is ok - -## instruction - -- break the questions into smaller parts -- review file append with `.draft`, see if the content aligned with the correct references -- read and understand `dbml` file -- lookup the every folder - -## tasks - -Thanks - - - ---- - - -please take a look in `schema.dbml` and `schema.json`, -associate the collection from json file to the table in dbml file - -please modify the `schema.dbml` to align with `schema.json` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - - ---- - -please revise - -please revise -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx` `interface LpCategory` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - - -please modify `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lp_categories/_constants.tsx` - -to follow the type definition in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx`, the constant `defaultLpCategory` - ---- - -the constants file (`@/constants`) was `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/constants.ts` - -please help to fix the `tsx` files in folder `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/QuizMFCategories`, -the `COL` constants is wrongly used, it should refer to `COL_QUIZ_MF_CATEGORIES`. thanks - - -please update the `COL_XXXX` TO COL_MF_CATEGORIES - - - -[ - { - "id": "pbc_3142635823", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "_superusers", - "type": "auth", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "cost": 0, - "hidden": true, - "id": "password901924565", - "max": 0, - "min": 8, - "name": "password", - "pattern": "", - "presentable": false, - "required": true, - "system": true, - "type": "password" - }, - { - "autogeneratePattern": "[a-zA-Z0-9]{50}", - "hidden": true, - "id": "text2504183744", - "max": 60, - "min": 30, - "name": "tokenKey", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "exceptDomains": null, - "hidden": false, - "id": "email3885137012", - "name": "email", - "onlyDomains": null, - "presentable": false, - "required": true, - "system": true, - "type": "email" - }, - { - "hidden": false, - "id": "bool1547992806", - "name": "emailVisibility", - "presentable": false, - "required": false, - "system": true, - "type": "bool" - }, - { - "hidden": false, - "id": "bool256245529", - "name": "verified", - "presentable": false, - "required": false, - "system": true, - "type": "bool" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE UNIQUE INDEX `idx_tokenKey_pbc_3142635823` ON `_superusers` (`tokenKey`)", - "CREATE UNIQUE INDEX `idx_email_pbc_3142635823` ON `_superusers` (`email`) WHERE `email` != ''" - ], - "system": true, - "authRule": "", - "manageRule": null, - "authAlert": { - "enabled": true, - "emailTemplate": { - "subject": "Login from a new location", - "body": "

Hello,

\n

We noticed a login to your {APP_NAME} account from a new location.

\n

If this was you, you may disregard this email.

\n

If this wasn't you, you should immediately change your {APP_NAME} account password to revoke access from all other locations.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - "oauth2": { - "mappedFields": { - "id": "", - "name": "", - "username": "", - "avatarURL": "" - }, - "enabled": false - }, - "passwordAuth": { - "enabled": true, - "identityFields": [ - "email" - ] - }, - "mfa": { - "enabled": false, - "duration": 1800, - "rule": "" - }, - "otp": { - "enabled": false, - "duration": 180, - "length": 8, - "emailTemplate": { - "subject": "OTP for {APP_NAME}", - "body": "

Hello,

\n

Your one-time password is: {OTP}

\n

If you didn't ask for the one-time password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - "authToken": { - "duration": 86400 - }, - "passwordResetToken": { - "duration": 1800 - }, - "emailChangeToken": { - "duration": 1800 - }, - "verificationToken": { - "duration": 259200 - }, - "fileToken": { - "duration": 180 - }, - "verificationTemplate": { - "subject": "Verify your {APP_NAME} email", - "body": "

Hello,

\n

Thank you for joining us at {APP_NAME}.

\n

Click on the button below to verify your email address.

\n

\n Verify\n

\n

\n Thanks,
\n {APP_NAME} team\n

" - }, - "resetPasswordTemplate": { - "subject": "Reset your {APP_NAME} password", - "body": "

Hello,

\n

Click on the button below to reset your password.

\n

\n Reset password\n

\n

If you didn't ask to reset your password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - }, - "confirmEmailChangeTemplate": { - "subject": "Confirm your {APP_NAME} new email address", - "body": "

Hello,

\n

Click on the button below to confirm your new email address.

\n

\n Confirm new email\n

\n

If you didn't ask to change your email address, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - { - "id": "_pb_users_auth_", - "listRule": "id = @request.auth.id", - "viewRule": "id = @request.auth.id", - "createRule": "", - "updateRule": "id = @request.auth.id", - "deleteRule": "id = @request.auth.id", - "name": "users", - "type": "auth", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "cost": 0, - "hidden": true, - "id": "password901924565", - "max": 0, - "min": 8, - "name": "password", - "pattern": "", - "presentable": false, - "required": true, - "system": true, - "type": "password" - }, - { - "autogeneratePattern": "[a-zA-Z0-9]{50}", - "hidden": true, - "id": "text2504183744", - "max": 60, - "min": 30, - "name": "tokenKey", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "exceptDomains": null, - "hidden": false, - "id": "email3885137012", - "name": "email", - "onlyDomains": null, - "presentable": false, - "required": true, - "system": true, - "type": "email" - }, - { - "hidden": false, - "id": "bool1547992806", - "name": "emailVisibility", - "presentable": false, - "required": false, - "system": true, - "type": "bool" - }, - { - "hidden": false, - "id": "bool256245529", - "name": "verified", - "presentable": false, - "required": false, - "system": true, - "type": "bool" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1579384326", - "max": 255, - "min": 0, - "name": "name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file376926767", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [ - "image/jpeg", - "image/png", - "image/svg+xml", - "image/gif", - "image/webp" - ], - "name": "avatar", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": null, - "type": "file" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [ - "CREATE UNIQUE INDEX `idx_tokenKey__pb_users_auth_` ON `users` (`tokenKey`)", - "CREATE UNIQUE INDEX `idx_email__pb_users_auth_` ON `users` (`email`) WHERE `email` != ''" - ], - "system": false, - "authRule": "", - "manageRule": null, - "authAlert": { - "enabled": true, - "emailTemplate": { - "subject": "Login from a new location", - "body": "

Hello,

\n

We noticed a login to your {APP_NAME} account from a new location.

\n

If this was you, you may disregard this email.

\n

If this wasn't you, you should immediately change your {APP_NAME} account password to revoke access from all other locations.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - "oauth2": { - "mappedFields": { - "id": "", - "name": "name", - "username": "", - "avatarURL": "avatar" - }, - "enabled": false - }, - "passwordAuth": { - "enabled": true, - "identityFields": [ - "email" - ] - }, - "mfa": { - "enabled": false, - "duration": 1800, - "rule": "" - }, - "otp": { - "enabled": false, - "duration": 180, - "length": 8, - "emailTemplate": { - "subject": "OTP for {APP_NAME}", - "body": "

Hello,

\n

Your one-time password is: {OTP}

\n

If you didn't ask for the one-time password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - "authToken": { - "duration": 604800 - }, - "passwordResetToken": { - "duration": 1800 - }, - "emailChangeToken": { - "duration": 1800 - }, - "verificationToken": { - "duration": 259200 - }, - "fileToken": { - "duration": 180 - }, - "verificationTemplate": { - "subject": "Verify your {APP_NAME} email", - "body": "

Hello,

\n

Thank you for joining us at {APP_NAME}.

\n

Click on the button below to verify your email address.

\n

\n Verify\n

\n

\n Thanks,
\n {APP_NAME} team\n

" - }, - "resetPasswordTemplate": { - "subject": "Reset your {APP_NAME} password", - "body": "

Hello,

\n

Click on the button below to reset your password.

\n

\n Reset password\n

\n

If you didn't ask to reset your password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - }, - "confirmEmailChangeTemplate": { - "subject": "Confirm your {APP_NAME} new email address", - "body": "

Hello,

\n

Click on the button below to confirm your new email address.

\n

\n Confirm new email\n

\n

If you didn't ask to change your email address, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - { - "id": "pbc_1430376151", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "Categories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2034676914", - "max": 0, - "min": 0, - "name": "cat_image_url", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2739402623", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": true, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_2328411368", - "hidden": false, - "id": "relation3455582614", - "maxSelect": 1, - "minSelect": 0, - "name": "lesson_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1156222427", - "max": 0, - "min": 0, - "name": "remarks", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_108570809", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "Customers", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1579384326", - "max": 0, - "min": 0, - "name": "name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3885137012", - "max": 0, - "min": 0, - "name": "email", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1146066909", - "max": 0, - "min": 0, - "name": "phone", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "number1813778413", - "max": null, - "min": null, - "name": "quota", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2063623452", - "max": 0, - "min": 0, - "name": "status", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file507207115", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "avatar_file", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "cascadeDelete": false, - "collectionId": "_pb_users_auth_", - "hidden": false, - "id": "relation2809058197", - "maxSelect": 1, - "minSelect": 0, - "name": "user_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_1196309394", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "LessonsCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1137421714", - "max": 0, - "min": 0, - "name": "cat_image_url", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": true, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_2328411368", - "hidden": false, - "id": "relation3455582614", - "maxSelect": 1, - "minSelect": 0, - "name": "lesson_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "convertURLs": false, - "hidden": false, - "id": "editor1843675174", - "maxSize": 0, - "name": "description", - "presentable": false, - "required": false, - "system": false, - "type": "editor" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1156222427", - "max": 0, - "min": 0, - "name": "remarks", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_2328411368", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "LessonsTypes", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1579384326", - "max": 0, - "min": 0, - "name": "name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2363381545", - "max": 0, - "min": 0, - "name": "type", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": true, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "date1542800728", - "max": "", - "min": "", - "name": "field", - "presentable": false, - "required": false, - "system": false, - "type": "date" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_4061499106", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizCRCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_3141885671", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizCRQuestions", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2416551515", - "max": 0, - "min": 0, - "name": "question_fh", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2814132303", - "max": 0, - "min": 0, - "name": "question_sh", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1249130051", - "max": 0, - "min": 0, - "name": "modal_ans", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_4061499106", - "hidden": false, - "id": "relation1827623476", - "maxSelect": 1, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "json3493198471", - "maxSize": 0, - "name": "options", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_3571292172", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2034676914", - "max": 0, - "min": 0, - "name": "cat_image", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_96745150", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizConnectives", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2416551515", - "max": 0, - "min": 0, - "name": "question_fh", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2814132303", - "max": 0, - "min": 0, - "name": "question_sh", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1249130051", - "max": 0, - "min": 0, - "name": "modal_ans", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_342761728", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 999, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_342761728", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizConnectivesCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_3639453778", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizLPCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2560465762", - "max": 0, - "min": 0, - "name": "slug", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1156222427", - "max": 0, - "min": 0, - "name": "remarks", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "convertURLs": false, - "hidden": false, - "id": "editor1843675174", - "maxSize": 0, - "name": "description", - "presentable": false, - "required": false, - "system": false, - "type": "editor" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_742947356", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizLPQuestions", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file4170105732", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "sound", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_3639453778", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 1, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2560465762", - "max": 0, - "min": 0, - "name": "slug", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1156222427", - "max": 0, - "min": 0, - "name": "remarks", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "convertURLs": false, - "hidden": false, - "id": "editor1843675174", - "maxSize": 0, - "name": "description", - "presentable": false, - "required": false, - "system": false, - "type": "editor" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_2511066072", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizListenings", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "file4170105732", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "sound", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_3571292172", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 999, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_84667061", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizMFCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_3346420851", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizMFQuestions", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3690399444", - "max": 0, - "min": 0, - "name": "word_c", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_84667061", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 1, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file4170105732", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "sound", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_2936646783", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizMatchings", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3690399444", - "max": 0, - "min": 0, - "name": "word_c", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_3571292172", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 999, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_1305841361", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "UserMetas", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text4192936109", - "max": 0, - "min": 0, - "name": "helloworld", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "json3622966325", - "maxSize": 0, - "name": "meta", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "cascadeDelete": false, - "collectionId": "_pb_users_auth_", - "hidden": false, - "id": "relation2809058197", - "maxSelect": 1, - "minSelect": 0, - "name": "user_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2744374011", - "max": 0, - "min": 0, - "name": "state", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file376926767", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "avatar", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1466534506", - "max": 0, - "min": 0, - "name": "role", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_1638686383", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "Vocabularies", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "file3309110367", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "file4170105732", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "sound", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3690399444", - "max": 0, - "min": 0, - "name": "word_c", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text412313404", - "max": 0, - "min": 0, - "name": "sample_e", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text4059087369", - "max": 0, - "min": 0, - "name": "sample_c", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_1430376151", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 1, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text105650625", - "max": 0, - "min": 0, - "name": "category", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_2328411368", - "hidden": false, - "id": "relation808508980", - "maxSelect": 1, - "minSelect": 0, - "name": "lesson_type_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_4275539003", - "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "createRule": null, - "updateRule": null, - "deleteRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "name": "_authOrigins", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text455797646", - "max": 0, - "min": 0, - "name": "collectionRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text127846527", - "max": 0, - "min": 0, - "name": "recordRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text4228609354", - "max": 0, - "min": 0, - "name": "fingerprint", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE UNIQUE INDEX `idx_authOrigins_unique_pairs` ON `_authOrigins` (collectionRef, recordRef, fingerprint)" - ], - "system": true - }, - { - "id": "pbc_2281828961", - "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "createRule": null, - "updateRule": null, - "deleteRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "name": "_externalAuths", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text455797646", - "max": 0, - "min": 0, - "name": "collectionRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text127846527", - "max": 0, - "min": 0, - "name": "recordRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2462348188", - "max": 0, - "min": 0, - "name": "provider", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1044722854", - "max": 0, - "min": 0, - "name": "providerId", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE UNIQUE INDEX `idx_externalAuths_record_provider` ON `_externalAuths` (collectionRef, recordRef, provider)", - "CREATE UNIQUE INDEX `idx_externalAuths_collection_provider` ON `_externalAuths` (collectionRef, provider, providerId)" - ], - "system": true - }, - { - "id": "pbc_2279338944", - "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "_mfas", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text455797646", - "max": 0, - "min": 0, - "name": "collectionRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text127846527", - "max": 0, - "min": 0, - "name": "recordRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1582905952", - "max": 0, - "min": 0, - "name": "method", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE INDEX `idx_mfas_collectionRef_recordRef` ON `_mfas` (collectionRef,recordRef)" - ], - "system": true - }, - { - "id": "pbc_1638494021", - "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "_otps", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text455797646", - "max": 0, - "min": 0, - "name": "collectionRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text127846527", - "max": 0, - "min": 0, - "name": "recordRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "cost": 8, - "hidden": true, - "id": "password901924565", - "max": 0, - "min": 0, - "name": "password", - "pattern": "", - "presentable": false, - "required": true, - "system": true, - "type": "password" - }, - { - "autogeneratePattern": "", - "hidden": true, - "id": "text3866985172", - "max": 0, - "min": 0, - "name": "sentTo", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE INDEX `idx_otps_collectionRef_recordRef` ON `_otps` (collectionRef, recordRef)" - ], - "system": true - }, - { - "id": "pbc_1509025625", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "billingAddress", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1400097126", - "max": 0, - "min": 0, - "name": "country", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2744374011", - "max": 0, - "min": 0, - "name": "state", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text760939060", - "max": 0, - "min": 0, - "name": "city", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text4114525948", - "max": 0, - "min": 0, - "name": "zipCode", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3620973610", - "max": 0, - "min": 0, - "name": "line1", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1322974608", - "max": 0, - "min": 0, - "name": "line2", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_123408445", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "helloworlds", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text907060870", - "max": 0, - "min": 0, - "name": "hello", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_2109205374", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "t1", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text907060870", - "max": 0, - "min": 0, - "name": "hello", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "file2313559263", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "test_file", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - } - ], - "indexes": [], - "system": false - } -] -
- -
-```` - -## File: schema.json -````json -[ - { - "id": "pbc_3142635823", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "_superusers", - "type": "auth", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "cost": 0, - "hidden": true, - "id": "password901924565", - "max": 0, - "min": 8, - "name": "password", - "pattern": "", - "presentable": false, - "required": true, - "system": true, - "type": "password" - }, - { - "autogeneratePattern": "[a-zA-Z0-9]{50}", - "hidden": true, - "id": "text2504183744", - "max": 60, - "min": 30, - "name": "tokenKey", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "exceptDomains": null, - "hidden": false, - "id": "email3885137012", - "name": "email", - "onlyDomains": null, - "presentable": false, - "required": true, - "system": true, - "type": "email" - }, - { - "hidden": false, - "id": "bool1547992806", - "name": "emailVisibility", - "presentable": false, - "required": false, - "system": true, - "type": "bool" - }, - { - "hidden": false, - "id": "bool256245529", - "name": "verified", - "presentable": false, - "required": false, - "system": true, - "type": "bool" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE UNIQUE INDEX `idx_tokenKey_pbc_3142635823` ON `_superusers` (`tokenKey`)", - "CREATE UNIQUE INDEX `idx_email_pbc_3142635823` ON `_superusers` (`email`) WHERE `email` != ''" - ], - "system": true, - "authRule": "", - "manageRule": null, - "authAlert": { - "enabled": true, - "emailTemplate": { - "subject": "Login from a new location", - "body": "

Hello,

\n

We noticed a login to your {APP_NAME} account from a new location.

\n

If this was you, you may disregard this email.

\n

If this wasn't you, you should immediately change your {APP_NAME} account password to revoke access from all other locations.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - "oauth2": { - "mappedFields": { - "id": "", - "name": "", - "username": "", - "avatarURL": "" - }, - "enabled": false - }, - "passwordAuth": { - "enabled": true, - "identityFields": [ - "email" - ] - }, - "mfa": { - "enabled": false, - "duration": 1800, - "rule": "" - }, - "otp": { - "enabled": false, - "duration": 180, - "length": 8, - "emailTemplate": { - "subject": "OTP for {APP_NAME}", - "body": "

Hello,

\n

Your one-time password is: {OTP}

\n

If you didn't ask for the one-time password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - "authToken": { - "duration": 86400 - }, - "passwordResetToken": { - "duration": 1800 - }, - "emailChangeToken": { - "duration": 1800 - }, - "verificationToken": { - "duration": 259200 - }, - "fileToken": { - "duration": 180 - }, - "verificationTemplate": { - "subject": "Verify your {APP_NAME} email", - "body": "

Hello,

\n

Thank you for joining us at {APP_NAME}.

\n

Click on the button below to verify your email address.

\n

\n Verify\n

\n

\n Thanks,
\n {APP_NAME} team\n

" - }, - "resetPasswordTemplate": { - "subject": "Reset your {APP_NAME} password", - "body": "

Hello,

\n

Click on the button below to reset your password.

\n

\n Reset password\n

\n

If you didn't ask to reset your password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - }, - "confirmEmailChangeTemplate": { - "subject": "Confirm your {APP_NAME} new email address", - "body": "

Hello,

\n

Click on the button below to confirm your new email address.

\n

\n Confirm new email\n

\n

If you didn't ask to change your email address, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - { - "id": "_pb_users_auth_", - "listRule": "id = @request.auth.id", - "viewRule": "id = @request.auth.id", - "createRule": "", - "updateRule": "id = @request.auth.id", - "deleteRule": "id = @request.auth.id", - "name": "users", - "type": "auth", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "cost": 0, - "hidden": true, - "id": "password901924565", - "max": 0, - "min": 8, - "name": "password", - "pattern": "", - "presentable": false, - "required": true, - "system": true, - "type": "password" - }, - { - "autogeneratePattern": "[a-zA-Z0-9]{50}", - "hidden": true, - "id": "text2504183744", - "max": 60, - "min": 30, - "name": "tokenKey", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "exceptDomains": null, - "hidden": false, - "id": "email3885137012", - "name": "email", - "onlyDomains": null, - "presentable": false, - "required": true, - "system": true, - "type": "email" - }, - { - "hidden": false, - "id": "bool1547992806", - "name": "emailVisibility", - "presentable": false, - "required": false, - "system": true, - "type": "bool" - }, - { - "hidden": false, - "id": "bool256245529", - "name": "verified", - "presentable": false, - "required": false, - "system": true, - "type": "bool" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1579384326", - "max": 255, - "min": 0, - "name": "name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file376926767", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [ - "image/jpeg", - "image/png", - "image/svg+xml", - "image/gif", - "image/webp" - ], - "name": "avatar", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": null, - "type": "file" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [ - "CREATE UNIQUE INDEX `idx_tokenKey__pb_users_auth_` ON `users` (`tokenKey`)", - "CREATE UNIQUE INDEX `idx_email__pb_users_auth_` ON `users` (`email`) WHERE `email` != ''" - ], - "system": false, - "authRule": "", - "manageRule": null, - "authAlert": { - "enabled": true, - "emailTemplate": { - "subject": "Login from a new location", - "body": "

Hello,

\n

We noticed a login to your {APP_NAME} account from a new location.

\n

If this was you, you may disregard this email.

\n

If this wasn't you, you should immediately change your {APP_NAME} account password to revoke access from all other locations.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - "oauth2": { - "mappedFields": { - "id": "", - "name": "name", - "username": "", - "avatarURL": "avatar" - }, - "enabled": false - }, - "passwordAuth": { - "enabled": true, - "identityFields": [ - "email" - ] - }, - "mfa": { - "enabled": false, - "duration": 1800, - "rule": "" - }, - "otp": { - "enabled": false, - "duration": 180, - "length": 8, - "emailTemplate": { - "subject": "OTP for {APP_NAME}", - "body": "

Hello,

\n

Your one-time password is: {OTP}

\n

If you didn't ask for the one-time password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - "authToken": { - "duration": 604800 - }, - "passwordResetToken": { - "duration": 1800 - }, - "emailChangeToken": { - "duration": 1800 - }, - "verificationToken": { - "duration": 259200 - }, - "fileToken": { - "duration": 180 - }, - "verificationTemplate": { - "subject": "Verify your {APP_NAME} email", - "body": "

Hello,

\n

Thank you for joining us at {APP_NAME}.

\n

Click on the button below to verify your email address.

\n

\n Verify\n

\n

\n Thanks,
\n {APP_NAME} team\n

" - }, - "resetPasswordTemplate": { - "subject": "Reset your {APP_NAME} password", - "body": "

Hello,

\n

Click on the button below to reset your password.

\n

\n Reset password\n

\n

If you didn't ask to reset your password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - }, - "confirmEmailChangeTemplate": { - "subject": "Confirm your {APP_NAME} new email address", - "body": "

Hello,

\n

Click on the button below to confirm your new email address.

\n

\n Confirm new email\n

\n

If you didn't ask to change your email address, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - { - "id": "pbc_1430376151", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "Categories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2034676914", - "max": 0, - "min": 0, - "name": "cat_image_url", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2739402623", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": true, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_2328411368", - "hidden": false, - "id": "relation3455582614", - "maxSelect": 1, - "minSelect": 0, - "name": "lesson_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1156222427", - "max": 0, - "min": 0, - "name": "remarks", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_108570809", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "Customers", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1579384326", - "max": 0, - "min": 0, - "name": "name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3885137012", - "max": 0, - "min": 0, - "name": "email", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1146066909", - "max": 0, - "min": 0, - "name": "phone", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "number1813778413", - "max": null, - "min": null, - "name": "quota", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2063623452", - "max": 0, - "min": 0, - "name": "status", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file507207115", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "avatar_file", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "cascadeDelete": false, - "collectionId": "_pb_users_auth_", - "hidden": false, - "id": "relation2809058197", - "maxSelect": 1, - "minSelect": 0, - "name": "user_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_1196309394", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "LessonsCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1137421714", - "max": 0, - "min": 0, - "name": "cat_image_url", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": true, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_2328411368", - "hidden": false, - "id": "relation3455582614", - "maxSelect": 1, - "minSelect": 0, - "name": "lesson_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "convertURLs": false, - "hidden": false, - "id": "editor1843675174", - "maxSize": 0, - "name": "description", - "presentable": false, - "required": false, - "system": false, - "type": "editor" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1156222427", - "max": 0, - "min": 0, - "name": "remarks", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_2328411368", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "LessonsTypes", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1579384326", - "max": 0, - "min": 0, - "name": "name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2363381545", - "max": 0, - "min": 0, - "name": "type", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": true, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "date1542800728", - "max": "", - "min": "", - "name": "field", - "presentable": false, - "required": false, - "system": false, - "type": "date" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_4061499106", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizCRCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_3141885671", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizCRQuestions", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2416551515", - "max": 0, - "min": 0, - "name": "question_fh", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2814132303", - "max": 0, - "min": 0, - "name": "question_sh", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1249130051", - "max": 0, - "min": 0, - "name": "modal_ans", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_4061499106", - "hidden": false, - "id": "relation1827623476", - "maxSelect": 1, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "json3493198471", - "maxSize": 0, - "name": "options", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_3571292172", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2034676914", - "max": 0, - "min": 0, - "name": "cat_image", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_96745150", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizConnectives", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2416551515", - "max": 0, - "min": 0, - "name": "question_fh", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2814132303", - "max": 0, - "min": 0, - "name": "question_sh", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1249130051", - "max": 0, - "min": 0, - "name": "modal_ans", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_342761728", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 999, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_342761728", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizConnectivesCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_3639453778", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizLPCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2560465762", - "max": 0, - "min": 0, - "name": "slug", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1156222427", - "max": 0, - "min": 0, - "name": "remarks", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "convertURLs": false, - "hidden": false, - "id": "editor1843675174", - "maxSize": 0, - "name": "description", - "presentable": false, - "required": false, - "system": false, - "type": "editor" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_742947356", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizLPQuestions", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file4170105732", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "sound", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_3639453778", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 1, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2560465762", - "max": 0, - "min": 0, - "name": "slug", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1156222427", - "max": 0, - "min": 0, - "name": "remarks", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "convertURLs": false, - "hidden": false, - "id": "editor1843675174", - "maxSize": 0, - "name": "description", - "presentable": false, - "required": false, - "system": false, - "type": "editor" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_2511066072", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizListenings", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "file4170105732", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "sound", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_3571292172", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 999, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_84667061", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizMFCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_3346420851", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizMFQuestions", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3690399444", - "max": 0, - "min": 0, - "name": "word_c", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_84667061", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 1, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file4170105732", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "sound", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_2936646783", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizMatchings", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3690399444", - "max": 0, - "min": 0, - "name": "word_c", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_3571292172", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 999, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_1305841361", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "UserMetas", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text4192936109", - "max": 0, - "min": 0, - "name": "helloworld", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "json3622966325", - "maxSize": 0, - "name": "meta", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "cascadeDelete": false, - "collectionId": "_pb_users_auth_", - "hidden": false, - "id": "relation2809058197", - "maxSelect": 1, - "minSelect": 0, - "name": "user_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2744374011", - "max": 0, - "min": 0, - "name": "state", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file376926767", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "avatar", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1466534506", - "max": 0, - "min": 0, - "name": "role", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_1638686383", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "Vocabularies", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "file3309110367", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "file4170105732", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "sound", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3690399444", - "max": 0, - "min": 0, - "name": "word_c", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text412313404", - "max": 0, - "min": 0, - "name": "sample_e", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text4059087369", - "max": 0, - "min": 0, - "name": "sample_c", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_1430376151", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 1, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text105650625", - "max": 0, - "min": 0, - "name": "category", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_2328411368", - "hidden": false, - "id": "relation808508980", - "maxSelect": 1, - "minSelect": 0, - "name": "lesson_type_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_4275539003", - "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "createRule": null, - "updateRule": null, - "deleteRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "name": "_authOrigins", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text455797646", - "max": 0, - "min": 0, - "name": "collectionRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text127846527", - "max": 0, - "min": 0, - "name": "recordRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text4228609354", - "max": 0, - "min": 0, - "name": "fingerprint", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE UNIQUE INDEX `idx_authOrigins_unique_pairs` ON `_authOrigins` (collectionRef, recordRef, fingerprint)" - ], - "system": true - }, - { - "id": "pbc_2281828961", - "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "createRule": null, - "updateRule": null, - "deleteRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "name": "_externalAuths", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text455797646", - "max": 0, - "min": 0, - "name": "collectionRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text127846527", - "max": 0, - "min": 0, - "name": "recordRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2462348188", - "max": 0, - "min": 0, - "name": "provider", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1044722854", - "max": 0, - "min": 0, - "name": "providerId", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE UNIQUE INDEX `idx_externalAuths_record_provider` ON `_externalAuths` (collectionRef, recordRef, provider)", - "CREATE UNIQUE INDEX `idx_externalAuths_collection_provider` ON `_externalAuths` (collectionRef, provider, providerId)" - ], - "system": true - }, - { - "id": "pbc_2279338944", - "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "_mfas", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text455797646", - "max": 0, - "min": 0, - "name": "collectionRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text127846527", - "max": 0, - "min": 0, - "name": "recordRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1582905952", - "max": 0, - "min": 0, - "name": "method", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE INDEX `idx_mfas_collectionRef_recordRef` ON `_mfas` (collectionRef,recordRef)" - ], - "system": true - }, - { - "id": "pbc_1638494021", - "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "_otps", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text455797646", - "max": 0, - "min": 0, - "name": "collectionRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text127846527", - "max": 0, - "min": 0, - "name": "recordRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "cost": 8, - "hidden": true, - "id": "password901924565", - "max": 0, - "min": 0, - "name": "password", - "pattern": "", - "presentable": false, - "required": true, - "system": true, - "type": "password" - }, - { - "autogeneratePattern": "", - "hidden": true, - "id": "text3866985172", - "max": 0, - "min": 0, - "name": "sentTo", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE INDEX `idx_otps_collectionRef_recordRef` ON `_otps` (collectionRef, recordRef)" - ], - "system": true - }, - { - "id": "pbc_1509025625", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "billingAddress", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1400097126", - "max": 0, - "min": 0, - "name": "country", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2744374011", - "max": 0, - "min": 0, - "name": "state", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text760939060", - "max": 0, - "min": 0, - "name": "city", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text4114525948", - "max": 0, - "min": 0, - "name": "zipCode", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3620973610", - "max": 0, - "min": 0, - "name": "line1", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1322974608", - "max": 0, - "min": 0, - "name": "line2", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_123408445", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "helloworlds", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text907060870", - "max": 0, - "min": 0, - "name": "hello", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_2109205374", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "t1", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text907060870", - "max": 0, - "min": 0, - "name": "hello", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "file2313559263", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "test_file", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - } - ], - "indexes": [], - "system": false - } -] -```` diff --git a/002_source/cms/src/db/repomix-output.xml b/002_source/cms/src/db/repomix-output.xml deleted file mode 100644 index 12e51d0..0000000 --- a/002_source/cms/src/db/repomix-output.xml +++ /dev/null @@ -1,6168 +0,0 @@ -This file is a merged representation of the entire codebase, combined into a single document by Repomix. - - -This section contains a summary of this file. - - -This file contains a packed representation of the entire repository's contents. -It is designed to be easily consumable by AI systems for analysis, code review, -or other automated processes. - - - -The content is organized as follows: -1. This summary section -2. Repository information -3. Directory structure -4. Repository files, each consisting of: - - File path as an attribute - - Full contents of the file - - - -- This file should be treated as read-only. Any changes should be made to the - original repository files, not this packed version. -- When processing this file, use the file path to distinguish - between different files in the repository. -- Be aware that this file may contain sensitive information. Handle it with - the same level of security as you would the original repository. - - - -- Some files may have been excluded based on .gitignore rules and Repomix's configuration -- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files -- Files matching patterns in .gitignore are excluded -- Files matching default ignore patterns are excluded -- Files are sorted by Git change count (files with more changes are at the bottom) - - - - - - - - - -_PROMPT/ - 1.MD - 2.MD - 3.MD - 4.md - temp.md -Customers/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetActiveCount.tsx - GetAll.tsx - GetAllCount.tsx - GetBlockedCount.tsx - GetById.tsx - GetPendingCount.tsx - Helloworld.tsx - Update.tsx -Events/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Update.tsx.draft -Helloworlds/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Helloworld.tsx.draft - Update.tsx.draft -LessonCategories/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Helloworld.tsx - Update.tsx -LessonTypes/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Helloworld.tsx - Update.tsx -Messages/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Update.tsx.draft -QuizCategories/ - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Helloworld.tsx.draft - Update.tsx.draft -QuizConnectives/ - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Helloworld.tsx.draft - Update.tsx.draft -QuizConnectivesCategories/ - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Helloworld.tsx.draft - Update.tsx.draft -QuizCRCategories/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Update.tsx -QuizCRQuestions/ - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx -QuizListenings/ - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - ListWithOption.tsx -QuizLPCategories/ - _GUIDELINES.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Update.tsx -QuizLPQuestions/ - _GUIDELINES.md - _PROMPT.md - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Update.tsx -QuizMFCategories/ - Create.tsx - Delete.tsx - GetAll.tsx - GetAllCount.tsx - GetById.tsx - GetHiddenCount.tsx - GetVisibleCount.tsx - Update.tsx -Students/ - Create.tsx - Delete.tsx - GetActiveCount.tsx - GetAll.tsx - GetAllCount.tsx - GetBlockedCount.tsx - GetById.tsx - Update.tsx -Subscriptions/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx.draft - GetById.tsx.draft - GetHiddenCount.tsx.draft - GetVisibleCount.tsx.draft - Update.tsx.draft -Teachers/ - _GUIDELINES.md - Create.tsx - GetActiveCount.tsx - GetAll.tsx - GetAllCount.tsx - GetBlockedCount.tsx - GetById.tsx - GetPendingCount.tsx - Update.tsx -UserMetas/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx - GetById.tsx.draft - Update.tsx.draft -Users/ - _GUIDELINES.md - Create.tsx.draft - Delete.tsx.draft - GetAll.tsx.draft - GetAllCount.tsx - GetById.tsx.draft - Update.tsx.draft -DB_AI_GUIDELINE.MD -schema.json - - - -This section contains the contents of the repository's files. - - -Hi, please study the documentation below, -i will send you the task afterwards, - -please read and understand the documentation below and link up the ideas -reply `OK` when you done -no need to state me any other things, thanks - -1. `schema.dbml` - -- this describe the database schema in dbml format -- filepath: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/001_documentation/Requirements/REQ0006/schema.dbml` - -2. `schema.json` - -- this is the schema export in pocketbase format -- filepath: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/schema.json` - -3. `_AI_GUIDELINE`: - -- there are the markdown files that help you better understand the implementation -- directory: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/_AI_GUIDELINE` - -thanks - ---- - -# task - -clone from `LessonTypes` to `Customers` - -## steps - -1. read `tsx` files from `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/LessonTypes` -1. copy file to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/Customers` -1. modify the copied `tsx` files to suit `customer` fields - - - -update `LpCategoryDefaultValue` -in file `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lp_categories/_constants.ts` - -thanks - -you can find the type def in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx` - -please help to draft code file: - -base_dir=`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db` - -using -`$base_dir/QuizListenings/GetHiddenCount.tsx`, -`$base_dir/QuizListenings/GetVisibleCount.tsx`, -`$base_dir/LessonTypes/GetHiddenCount.tsx`, -`$base_dir/LessonTypes/GetVisibleCount.tsx`, -as reference, - -look into the all directories under base_dir e.g. `QuizCategories`. -propergate `GetHiddenCount.tsx` and `GetVisibleCount.tsx` if missing, do the change to suit the collection. -use `.draft.tsx` instead when you write file - ---- - -rewrite `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/LessonCategories/GetAllCount.tsx` to match `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/UserMetas/GetAllCount.tsx` style - ---- - -style rewrite - -study -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/overview/summary/ActiveUserCount/index.tsx` -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/overview/summary/LessonCategoriesCount/index.tsx` - -and rewrite `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/overview/summary/LessonTypeCount/index.tsx` to match style above thanks - - - -please draft with idea: - -``` -await pb -.collection(COL_LESSON_TYPES) -.getList(currentPage + 1, rowsPerPage, listOption); -``` - -for Listening Practice - -thanks - -I want you to clone -from `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/LessonTypes/GetVisibleCount.tsx` (source file) - -to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/QuizListenings/GetVisibleCount.tsx` (dest file) - -please extract , link up and remember the document properties -(e.g. types, functions, variables, constants, etc) -from source file -draft dest file - -update the variables and properties of dest file to reflect `listening practice categories`/`lp_categories` - ---- - -## task - -update `schema.dbml` to reflect `schema.json` - -## details - -Hi, -I have a pocketbase export json file: -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/pocketbase/pb_hooks/seed/schema.json` - -and a dbml file: -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/001_documentation/Requirements/REQ0006/schema.dbml` - -the collection name in pocketbase should be reflected by a table in dbml, - -## steps - -compare `schema.json` and `schema.dbml` -please keep `schema.json` remain unchanged -update `schema.dbml` to reflect `schema.json` -do check again when finished - - - ---- - -clone `GetVisibleCount.tsx` and `GetHiddenCount.tsx` from `LessonTypes` to `LessonCategories` and update it - -please draft `GetHiddenCount.tsx` for COL_LESSON_TYPES and `status = hidden` - -well done !, please proceed to another request - -working directory: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db` - -according information from `schema.json`, get the collection of `Students` - -pleaes clone the `tsx` files from `LessonTypes` and `LessonCategories` to `Students` and update the content - -when you draft coding, review file and append with `.tsx.draft` - ---- - -- this is part of react typescript project, with pocketbase -- `schema.dbml`, describe the collections(tables) -- folder `LessonCategories`, the correct references -- folder `LessonTypes`, the correct references -- you can find the `schema.dbml` and schema information from `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/001_documentation/Requirements/REQ0006` -- do not read root directory, assume it is a fresh copy of nextjs project is ok - -## instruction - -- break the questions into smaller parts -- review file append with `.draft`, see if the content aligned with the correct references -- read and understand `dbml` file -- lookup the every folder - -## tasks - -Thanks - ---- - -please take a look in `schema.dbml` and `schema.json`, -associate the collection from json file to the table in dbml file - -please modify the `schema.dbml` to align with `schema.json` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - ---- - -please revise - -please revise -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx` `interface LpCategory` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - -please modify `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lp_categories/_constants.tsx` - -to follow the type definition in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx`, the constant `defaultLpCategory` - - - -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lp_categories/lp-categories-filters.tsx` - -this file is original for `lesson_category` model, -please modify it to fit `lp_category` (listening practice category) - -thanks - - - -# GUIDELINES - -This folder contains drivers for `Customer`/`Customers` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx, GetActiveCount.tsx, GetBlockedCount.tsx, GetPendingCount.tsx) -- misc (Helloworld.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/Customers/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; - -export async function createCustomer(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` - - - -// api method for crate customer record -// RULES: -// TBA -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; -import type { CreateFormProps } from '@/components/dashboard/customer/type.d'; -import type { RecordModel } from 'pocketbase'; - -export async function createCustomer(data: CreateFormProps): Promise { - return pb.collection(COL_CUSTOMERS).create(data); -} - - - -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; - -export async function deleteCustomer(id: string): Promise { - return pb.collection(COL_CUSTOMERS).delete(id); -} - - - -import { COL_CUSTOMERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetActiveCount(): Promise { - const { totalItems: count } = await pb.collection(COL_CUSTOMERS).getList(1, 1, { - filter: 'status = "active"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getAllCustomers(options = {}): Promise { - return pb.collection(COL_CUSTOMERS).getFullList(options); -} - - - -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; - -export async function getAllCustomersCount(): Promise { - const result = await pb.collection(COL_CUSTOMERS).getList(1, 1); - return result.totalItems; -} - - - -import { COL_CUSTOMERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetBlockedCount(): Promise { - const { totalItems: count } = await pb.collection(COL_CUSTOMERS).getList(1, 1, { - filter: 'status = "blocked"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getCustomerById(id: string): Promise { - return pb.collection(COL_CUSTOMERS).getOne(id); -} - - - -import { COL_CUSTOMERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetPendingCount(): Promise { - const { totalItems: count } = await pb.collection(COL_CUSTOMERS).getList(1, 1, { - filter: 'status = "pending"', - }); - return count; -} - - - -export function helloCustomer() { - return 'Hello from Customers module!'; -} - - - -import { pb } from '@/lib/pb'; -import { COL_CUSTOMERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import type { EditFormProps } from '@/components/dashboard/customer/type.d'; - -export async function updateCustomer(id: string, data: Partial): Promise { - return pb.collection(COL_CUSTOMERS).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `Event`/`Events` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Events/type.d.tsx` -- Event records require special handling for: - - Date/time validation - - Location data - - Attendee management - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createEvent(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection('Events')) -} -``` - - - -import { COL_EVENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/event/types'; - -export default function createEvent(data: CreateForm): Promise { - return pb.collection(COL_EVENTS).create(data); -} - - - -import { COL_EVENTS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteEvent(id: string): Promise { - return pb.collection(COL_EVENTS).delete(id); -} - - - -import { COL_EVENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllEvents(): Promise { - return pb.collection(COL_EVENTS).getFullList({ - sort: 'event_time' // Sort by event time - }); -} - - - -import { COL_EVENTS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getAllEventsCount(startDate?: string, endDate?: string): Promise { - let filter = ''; - if (startDate && endDate) { - filter = `event_time >= "${startDate}" && event_time <= "${endDate}"`; - } else if (startDate) { - filter = `event_time >= "${startDate}"`; - } else if (endDate) { - filter = `event_time <= "${endDate}"`; - } - - const { totalItems: count } = await pb - .collection(COL_EVENTS) - .getList(1, 9999, { filter }); - return count; -} - - - -import { COL_EVENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getEventById(id: string): Promise { - return pb.collection(COL_EVENTS).getOne(id); -} - - - -// REQ0006 -import { COL_EVENTS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_EVENTS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_EVENTS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_EVENTS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_EVENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { UpdateForm } from '@/components/dashboard/event/types'; - -export default function updateEvent(id: string, data: UpdateForm): Promise { - return pb.collection(COL_EVENTS).update(id, data); -} - - - -# GUIDELINES - -This folder contains test drivers for `Helloworld` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function -- type information defined in `@/db/Helloworlds/type.d.tsx` -- This is a test collection - keep implementations simple - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createHelloworld(data: CreateFormProps) { - // Simple test implementation - return pb.collection('Helloworlds').create(data); -} -``` - - - -import { COL_HELLOWORLDS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/helloworld/types'; - -export default function createHelloworld(data: CreateForm): Promise { - return pb.collection(COL_HELLOWORLDS).create(data); -} - - - -import { COL_HELLOWORLDS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default function deleteHelloworld(id: string): Promise { - return pb.collection(COL_HELLOWORLDS).delete(id); -} - - - -import { COL_HELLOWORLDS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllHelloworlds(): Promise { - return pb.collection(COL_HELLOWORLDS).getFullList(); -} - - - -import { COL_HELLOWORLDS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getHelloworldById(id: string): Promise { - return pb.collection(COL_HELLOWORLDS).getOne(id); -} - - - -// REQ0006 -import { COL_HELLOWORLDS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_HELLOWORLDS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_HELLOWORLDS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_HELLOWORLDS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; - - - -import { COL_HELLOWORLDS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/helloworld/types'; - -export default function updateHelloworld(id: string, data: CreateForm): Promise { - return pb.collection(COL_HELLOWORLDS).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `LessonCategory`/`LessonCategories` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/LessonCategories/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_LESSON_CATEGORIES } from '@/constants'; - -export async function createLessonCategory(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` - - - -import { COL_LESSON_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/categories/type'; - -export default function createLessonCategory(data: CreateFormProps): Promise { - return pb.collection(COL_LESSON_CATEGORIES).create(data); -} - - - -import { COL_LESSON_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteLessonCategory(id: string): Promise { - return pb.collection(COL_LESSON_CATEGORIES).delete(id); -} - - - -import { COL_LESSON_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllLessonCategories(): Promise { - return pb.collection(COL_LESSON_CATEGORIES).getFullList(); -} - - - -// RULES: -// error handled by caller -// contain definition to collection only - -import { COL_LESSON_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function getAllLessonCategoriesCount(): Promise { - return pb - .collection(COL_LESSON_CATEGORIES) - .getList(1, 9999) - .then((res) => res.totalItems); -} - - - -import { COL_LESSON_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getLessonCategoryById(id: string): Promise { - return pb.collection(COL_LESSON_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_LESSON_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_LESSON_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; - - - -import { COL_LESSON_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/categories/type'; - -export default function updateLessonCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_LESSON_CATEGORIES).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `LessonType`/`LessonTypes` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/LessonTypes/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_LESSON_TYPES } from '@/constants'; - -export async function createLessonType(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` - - - -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/lesson_type/lesson-type'; - -export default function createLessonType(data: CreateForm): Promise { - return pb.collection(COL_LESSON_TYPES).create(data); -} - - - -import { COL_LESSON_TYPES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteLessonType(id: string): Promise { - return pb.collection(COL_LESSON_TYPES).delete(id); -} - - - -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllLessonTypes(): Promise { - return pb.collection(COL_LESSON_TYPES).getFullList(); -} - - - -// REQ0006 -import { COL_LESSON_TYPES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_TYPES).getList(1, 9999, {}); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getLessonTypeById(id: string): Promise { - return pb.collection(COL_LESSON_TYPES).getOne(id); -} - - - -// REQ0006 -import { COL_LESSON_TYPES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_TYPES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_LESSON_TYPES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_LESSON_TYPES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; - - - -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/lesson_type/lesson-type'; - -export default function updateLessonType(id: string, data: CreateForm): Promise { - return pb.collection(COL_LESSON_TYPES).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `Message`/`Messages` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Messages/type.d.tsx` -- Message records require special handling for: - - Sender/receiver validation - - Timestamp management - - Read status tracking - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createMessage(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection('Messages')) -} -``` - - - -import { COL_MESSAGES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/message/types'; - -export default function createMessage(data: CreateForm): Promise { - return pb.collection(COL_MESSAGES).create(data); -} - - - -import { COL_MESSAGES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteMessage(id: string): Promise { - return pb.collection(COL_MESSAGES).delete(id); -} - - - -import { COL_MESSAGES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllMessages(): Promise { - return pb.collection(COL_MESSAGES).getFullList({ - expand: 'user_id', // Expand related user data - sort: '-created' // Sort by most recent first - }); -} - - - -import { COL_MESSAGES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getAllMessagesCount(status?: string): Promise { - const filter = status ? `status = "${status}"` : ''; - const { totalItems: count } = await pb - .collection(COL_MESSAGES) - .getList(1, 9999, { filter }); - return count; -} - - - -import { COL_MESSAGES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getMessageById(id: string): Promise { - return pb.collection(COL_MESSAGES).getOne(id, { - expand: 'user_id' // Expand related user data - }); -} - - - -// REQ0006 -import { COL_MESSAGES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_MESSAGES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_MESSAGES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_MESSAGES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_MESSAGES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { UpdateForm } from '@/components/dashboard/message/types'; - -export default function updateMessage(id: string, data: UpdateForm): Promise { - return pb.collection(COL_MESSAGES).update(id, data); -} - - - -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface CreateForm { - // TODO: Add QuizCategories fields -} - -export default function createQuizCategory(data: CreateForm): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).create(data); -} - - - -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizCategory(id: string): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).delete(id); -} - - - -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizCategories(): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).getFullList(); -} - - - -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; - - - -import { COL_QUIZ_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface UpdateForm { - // TODO: Add QuizCategories fields -} - -export default function updateQuizCategory(id: string, data: UpdateForm): Promise { - return pb.collection(COL_QUIZ_CATEGORIES).update(id, data); -} - - - -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface CreateForm { - // TODO: Add QuizConnectives fields -} - -export default function createQuizConnective(data: CreateForm): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).create(data); -} - - - -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizConnective(id: string): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).delete(id); -} - - - -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizConnectives(): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).getFullList(); -} - - - -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizConnectiveById(id: string): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_CONNECTIVES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CONNECTIVES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_CONNECTIVES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CONNECTIVES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; - - - -import { COL_QUIZ_CONNECTIVES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface UpdateForm { - // TODO: Add QuizConnectives fields -} - -export default function updateQuizConnective(id: string, data: UpdateForm): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES).update(id, data); -} - - - -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface CreateForm { - // TODO: Add QuizConnectivesCategories fields -} - -export default function createQuizConnectivesCategory(data: CreateForm): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).create(data); -} - - - -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizConnectivesCategory(id: string): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).delete(id); -} - - - -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizConnectivesCategories(): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).getFullList(); -} - - - -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizConnectivesCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb - .collection(COL_QUIZ_CONNECTIVES_CATEGORIES) - .getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb - .collection(COL_QUIZ_CONNECTIVES_CATEGORIES) - .getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -function Helloworld(): string { - return 'helloworld'; -} - -export { Helloworld }; - - - -import { COL_QUIZ_CONNECTIVES_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface UpdateForm { - // TODO: Add QuizConnectivesCategories fields -} - -export default function updateQuizConnectivesCategory(id: string, data: UpdateForm): Promise { - return pb.collection(COL_QUIZ_CONNECTIVES_CATEGORIES).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `QuizCRCategory`/`QuizCRCategories` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/QuizCRCategories/type.d.tsx` -- Quiz categories may require additional validation logic - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; - -export async function createQuizCRCategory(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` - - - -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'; - -export default function createQuizCRCategory(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).create(data); -} - - - -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizCRCategories(id: string): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).delete(id); -} - - - -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import { pb } from '@/lib/pb'; - -export default function getAllQuizCRCategories(): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).getFullList(); -} - - - -// REQ0006 -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_CR_CATEGORIES).getList(1, 9999, {}); - return count; -} - - - -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizCRCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizCRCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CR_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizCRCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CR_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_QUIZ_CR_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/cr/categories/type'; - -export default function updateQuizCRCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_CR_CATEGORIES).update(id, data); -} - - - -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/cr/questions/type'; - -// interface CreateForm { -// // TODO: Add QuizCRQuestions fields -// } - -export default function createQuizCRQuestion(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_CR_QUESTIONS).create(data); -} - - - -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizCRQuestions(id: string): Promise { - return pb.collection(COL_QUIZ_CR_QUESTIONS).delete(id); -} - - - -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizCRQuestions(): Promise { - return pb.collection(COL_QUIZ_CR_QUESTIONS).getFullList(); -} - - - -// REQ0006 -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_CR_QUESTIONS).getList(1, 9999, {}); - return count; -} - - - -// REQ0006 -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizCRQuestionsCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CR_QUESTIONS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_CR_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizCRQuestionsCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_CR_QUESTIONS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizLPCategories(id: string): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).delete(id); -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizListenings(): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getFullList(); -} - - - -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, {}); - return count; -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizListeningById(id: string): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { ListResult, RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -interface ListWithOptionParams { - currentPage: number; - rowsPerPage: number; - listOption?: { - filter?: string; - sort?: string; - expand?: string; - }; -} - -export default function listWithOption({ - currentPage, - rowsPerPage, - listOption = {}, -}: ListWithOptionParams): Promise> { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getList(currentPage + 1, rowsPerPage, listOption); -} - - - -# GUIDELINES - -This folder contains drivers for `QuizLPCategory` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/QuizLPCategories/type.d.tsx` -- Quiz LP categories may require additional validation logic - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -export async function createQuizLPCategory(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(COL_QUIZ_LP_CATEGORIES)) -} -``` - - - -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'; - -export default function createQuizLPCategory(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).create(data); -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizLPCategories(id: string): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).delete(id); -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizLPCategories(): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getFullList(); -} - - - -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, {}); - return count; -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizLPCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizLPCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizLPCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/categories/type'; - -export default function updateQuizLPCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `QuizLPQuestion` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/QuizLPQuestions/type.d.tsx` -- Quiz LP questions require special handling for: - - Answer validation - - Question type checking - - Category association - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -export async function createQuizLPQuestion(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(COL_QUIZ_LP_QUESTIONS)) -} -``` - - - -please help to review the `tsx` file in this folder -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/QuizLPQuestions` - -it was clone from -`LPCategories` -please help to modify to -`LPQuestions` - -please also help to modify the name of -`variables`, `constants`, `functions`, `classes`, components's name, paths - -the db fields structures between them are the same - -do not move the files -do not create directories -keep current folder structure is important - -thanks - - - -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/questions/type'; - -// interface CreateForm { -// // TODO: Add QuizLPQuestions fields -// } - -export default function createQuizLPQuestion(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_LP_QUESTIONS).create(data); -} - - - -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizLPQuestions(id: string): Promise { - return pb.collection(COL_QUIZ_LP_QUESTIONS).delete(id); -} - - - -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizLPQuestions(): Promise { - return pb.collection(COL_QUIZ_LP_QUESTIONS).getFullList(); -} - - - -// REQ0006 -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_LP_QUESTIONS).getList(1, 9999, {}); - return count; -} - - - -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizLPQuestionById(id: string): Promise { - return pb.collection(COL_QUIZ_LP_QUESTIONS).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizLPQuestionsCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_QUESTIONS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_LP_QUESTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizLPQuestionsCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_LP_QUESTIONS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_QUIZ_LP_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/lp/categories/type'; - -export default function updateQuizLPCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_LP_CATEGORIES).update(id, data); -} - - - -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/mf/categories/type'; - -export default function createQuizMFCategory(data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).create(data); -} - - - -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteQuizMFCategories(id: string): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).delete(id); -} - - - -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllQuizMFCategories(): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).getFullList(); -} - - - -// REQ0006 -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - const { totalItems: count } = await pb.collection(COL_QUIZ_MF_CATEGORIES).getList(1, 9999, {}); - return count; -} - - - -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getQuizMFCategoryById(id: string): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).getOne(id); -} - - - -// REQ0006 -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getHiddenQuizMFCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_MF_CATEGORIES).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getVisibleQuizMFCategoriesCount(): Promise { - try { - const result = await pb.collection(COL_QUIZ_MF_CATEGORIES).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_QUIZ_MF_CATEGORIES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateFormProps } from '@/components/dashboard/mf/categories/type'; - -export default function updateQuizMFCategory(id: string, data: CreateFormProps): Promise { - return pb.collection(COL_QUIZ_MF_CATEGORIES).update(id, data); -} - - - -// api method for create student record -// RULES: -// TBA -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; -import type { CreateFormProps } from '@/components/dashboard/student/type.d'; -import type { RecordModel } from 'pocketbase'; - -export async function createStudent(data: CreateFormProps): Promise { - return pb.collection(COL_STUDENTS).create(data); -} - - - -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; - -export async function deleteStudent(id: string): Promise { - return pb.collection(COL_STUDENTS).delete(id); -} - - - -import { COL_STUDENTS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetActiveCount(): Promise { - const { totalItems: count } = await pb.collection(COL_STUDENTS).getList(1, 1, { - filter: 'status = "active"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getAllStudents(options = {}): Promise { - return pb.collection(COL_STUDENTS).getFullList(options); -} - - - -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; - -export async function getAllStudentsCount(): Promise { - const result = await pb.collection(COL_STUDENTS).getList(1, 1); - return result.totalItems; -} - - - -import { COL_STUDENTS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetBlockedCount(): Promise { - const { totalItems: count } = await pb.collection(COL_STUDENTS).getList(1, 1, { - filter: 'status = "blocked"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getStudentById(id: string): Promise { - return pb.collection(COL_STUDENTS).getOne(id); -} - - - -import { pb } from '@/lib/pb'; -import { COL_STUDENTS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import type { EditFormProps } from '@/components/dashboard/student/type.d'; - -export async function updateStudent(id: string, data: Partial): Promise { - return pb.collection(COL_STUDENTS).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `Subscription`/`Subscriptions` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Subscriptions/type.d.tsx` -- Subscription records require special handling for: - - Payment status validation - - Expiration date checks - - Auto-renewal logic - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createSubscription(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection('Subscriptions')) -} -``` - - - -import { COL_SUBSCRIPTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/subscription/types'; - -export default function createSubscription(data: CreateForm): Promise { - return pb.collection(COL_SUBSCRIPTIONS).create(data); -} - - - -import { COL_SUBSCRIPTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteSubscription(id: string): Promise { - // TODO: Add validation for active subscriptions if needed - return pb.collection(COL_SUBSCRIPTIONS).delete(id); -} - - - -import { COL_SUBSCRIPTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllSubscriptions(): Promise { - return pb.collection(COL_SUBSCRIPTIONS).getFullList({ - expand: 'user_id,plan_id', // Expand related user and plan data - sort: '-created' // Sort by most recent first - }); -} - - - -import { COL_SUBSCRIPTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function getAllSubscriptionsCount(status?: string): Promise { - const filter = status ? `status = "${status}"` : ''; - const { totalItems: count } = await pb - .collection(COL_SUBSCRIPTIONS) - .getList(1, 9999, { filter }); - return count; -} - - - -import { COL_SUBSCRIPTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getSubscriptionById(id: string): Promise { - return pb.collection(COL_SUBSCRIPTIONS).getOne(id, { - expand: 'user_id,plan_id' // Expand related user and plan data - }); -} - - - -// REQ0006 -import { COL_SUBSCRIPTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetHiddenCount(): Promise { - try { - const result = await pb.collection(COL_SUBSCRIPTIONS).getList(1, 9999, { filter: 'visible = "hidden"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -// REQ0006 -import { COL_SUBSCRIPTIONS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetVisibleCount(): Promise { - try { - const result = await pb.collection(COL_SUBSCRIPTIONS).getList(1, 9999, { filter: 'visible = "visible"' }); - const { totalItems: count } = result; - return count; - } catch (error) { - return 0; - } -} - - - -import { COL_SUBSCRIPTIONS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { UpdateForm } from '@/components/dashboard/subscription/types'; - -export default function updateSubscription(id: string, data: UpdateForm): Promise { - return pb.collection(COL_SUBSCRIPTIONS).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `Teacher`/`Teachers` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Teachers/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; - -export async function createTeacher(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection('Teachers')) -} -``` - - - -// api method for create teacher record -// RULES: -// TBA -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; -import type { CreateFormProps } from '@/components/dashboard/teacher/type.d'; -import type { RecordModel } from 'pocketbase'; - -export async function createTeacher(data: CreateFormProps): Promise { - return pb.collection(COL_TEACHERS).create(data); -} - - - -import { COL_TEACHERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetActiveCount(): Promise { - const { totalItems: count } = await pb.collection(COL_TEACHERS).getList(1, 1, { - filter: 'status = "active"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getAllTeachers(options = {}): Promise { - return pb.collection(COL_TEACHERS).getFullList(options); -} - - - -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; - -export async function getAllTeachersCount(): Promise { - const result = await pb.collection(COL_TEACHERS).getList(1, 1); - return result.totalItems; -} - - - -import { COL_TEACHERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetBlockedCount(): Promise { - const { totalItems: count } = await pb.collection(COL_TEACHERS).getList(1, 1, { - filter: 'status = "blocked"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; -import { RecordModel } from 'pocketbase'; - -export async function getTeacherById(id: string): Promise { - return pb.collection(COL_TEACHERS).getOne(id); -} - - - -import { COL_TEACHERS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default async function GetPendingCount(): Promise { - const { totalItems: count } = await pb.collection(COL_TEACHERS).getList(1, 1, { - filter: 'status = "pending"', - }); - return count; -} - - - -import { pb } from '@/lib/pb'; -import { COL_TEACHERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import type { EditFormProps } from '@/components/dashboard/teacher/type.d'; - -export async function updateTeacher(id: string, data: Partial): Promise { - return pb.collection(COL_TEACHERS).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `UserMeta`/`UserMetas` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/UserMetas/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_USER_METAS } from '@/constants'; - -export async function createUserMeta(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` - - - -import { COL_LESSON_TYPES } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/lesson_type/types'; - -// import type { CreateForm } from '@/components/dashboard/lesson_type/interfaces.ts.del'; - -export default function createLessonType(data: CreateForm): Promise { - return pb.collection(COL_LESSON_TYPES).create(data); -} - - - -import { COL_USER_METAS } from '@/constants'; -import { pb } from '@/lib/pb'; - -export default function deleteUserMeta(id: string): Promise { - return pb.collection(COL_USER_METAS).delete(id); -} - - - -import { COL_USER_METAS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import { pb } from '@/lib/pb'; - -export default function getAllUserMetas(): Promise { - return pb.collection(COL_USER_METAS).getFullList(); -} - - - -// RULES: -// error handled by caller -// contain definition to collection only - -import { COL_USER_METAS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function getAllUserMetasCount(): Promise { - return pb - .collection(COL_USER_METAS) - .getList(1, 9998) - .then((res) => res.totalItems); -} - - - -import { COL_USER_METAS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import { pb } from '@/lib/pb'; - -export default function getUserMetaById(id: string): Promise { - return pb.collection(COL_USER_METAS).getOne(id); -} - - - -import { COL_USER_METAS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/user_meta/types'; - -export default function updateUserMeta(id: string, data: CreateForm): Promise { - return pb.collection(COL_USER_METAS).update(id, data); -} - - - -# GUIDELINES - -This folder contains drivers for `User`/`Users` records using PocketBase: - -- create (Create.tsx) -- read (GetById.tsx) -- write (Update.tsx) -- count (GetAllCount.tsx) -- delete (Delete.tsx) -- list (GetAll.tsx) - -the `@` sign refer to `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src` - -## Assumption and Requirements - -- assume `pb` is located in `@/lib/pb` -- no need to handle error in this function, i'll handle it in the caller -- type information defined in `@/db/Users/type.d.tsx` - -simple template: - -```typescript -import { pb } from '@/lib/pb'; -import { COL_USERS } from '@/constants'; - -export async function createUser(data: CreateFormProps) { - // ...content - // use direct return of pb.collection (e.g. return pb.collection(xxx)) -} -``` - - - -import { COL_USERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/user/types'; - - -export default function createUser(data: CreateForm): Promise { - return pb.collection(COL_USERS).create(data); -} - - - -import { COL_USERS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default function deleteUser(id: string): Promise { - return pb.collection(COL_USERS).delete(id); -} - - - -import { COL_USERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getAllUsers(): Promise { - return pb.collection(COL_USERS).getFullList(); -} - - - -// REQ0006 -import { COL_USERS } from '@/constants'; - -import { pb } from '@/lib/pb'; - -export default async function GetAllCount(): Promise { - try { - const result = await pb.collection(`users`).getList(1, 9999, { filter: 'email != ""' }); - const { totalItems: count } = result; - return count; - } catch (error) { - console.error(error); - return -99; - } -} - - - -import { COL_USERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; - -export default function getUserById(id: string): Promise { - return pb.collection(COL_USERS).getOne(id); -} - - - -import { COL_USERS } from '@/constants'; -import type { RecordModel } from 'pocketbase'; - -import { pb } from '@/lib/pb'; -import type { CreateForm } from '@/components/dashboard/user/types'; - -export default function updateUser(id: string, data: CreateForm): Promise { - return pb.collection(COL_USERS).update(id, data); -} - - - -# AI GUIDELINE - -## getting started - -Imagine there is a software developer and a QA engineer to solve the problems together - -They will: - -no need to reply me what you are going on and your digest in this phase. -just reply me "OK" when done - -base_dir=`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project` - -- read `/001_documentation/Requirements/REQ0006/schema.dbml` -this is file in dbml syntax state the main database - -- read `/002_source/cms/src/db/schema.json` -this is the file of live pocketbase schema output - -- read `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/constants.ts` -this is the content of `@/constants` - -- look into the md files in folder `/002_source/cms/_AI_GUIDELINE` - -- read, remember and link up the ideas in file stated above, -i will tell them the task afterwards - ---- - -The software engineer will provide solutions, -while QA engineer will feedback the opinion. - -this is now not in debug phase, -so, no need to reply me what they are going on or their insight throught the prompt. -just reply me "OK" when done - ---- - -clone `GetVisibleCount.tsx` and `GetHiddenCount.tsx` from `LessonTypes` to `LessonCategories` and update it - -please draft `GetHiddenCount.tsx` for COL_LESSON_TYPES and `status = hidden` - -well done !, please proceed to another request - -working directory: `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db` - -according information from `schema.json`, get the collection of `Students` - -pleaes clone the `tsx` files from `LessonTypes` and `LessonCategories` to `Students` and update the content - -when you draft coding, review file and append with `.tsx.draft` - ---- - -- this is part of react typescript project, with pocketbase -- `schema.dbml`, describe the collections(tables) -- folder `LessonCategories`, the correct references -- folder `LessonTypes`, the correct references -- you can find the `schema.dbml` and schema information from `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/001_documentation/Requirements/REQ0006` -- do not read root directory, assume it is a fresh copy of nextjs project is ok - -## instruction - -- break the questions into smaller parts -- review file append with `.draft`, see if the content aligned with the correct references -- read and understand `dbml` file -- lookup the every folder - -## tasks - -Thanks - - - ---- - - -please take a look in `schema.dbml` and `schema.json`, -associate the collection from json file to the table in dbml file - -please modify the `schema.dbml` to align with `schema.json` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - - ---- - -please revise - -please revise -`/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx` `interface LpCategory` - -to the collection `QuizLPCategories` align the dbml file in the previous prompt - - -please modify `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/components/dashboard/lp_categories/_constants.tsx` - -to follow the type definition in `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/types/LpCategory.tsx`, the constant `defaultLpCategory` - ---- - -the constants file (`@/constants`) was `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/constants.ts` - -please help to fix the `tsx` files in folder `/home/logic/_wsl_workspace/001_github_ws/lettersoup-online-ws/lettersoup-online/project/002_source/cms/src/db/QuizMFCategories`, -the `COL` constants is wrongly used, it should refer to `COL_QUIZ_MF_CATEGORIES`. thanks - - -please update the `COL_XXXX` TO COL_MF_CATEGORIES - - - -[ - { - "id": "pbc_3142635823", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "_superusers", - "type": "auth", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "cost": 0, - "hidden": true, - "id": "password901924565", - "max": 0, - "min": 8, - "name": "password", - "pattern": "", - "presentable": false, - "required": true, - "system": true, - "type": "password" - }, - { - "autogeneratePattern": "[a-zA-Z0-9]{50}", - "hidden": true, - "id": "text2504183744", - "max": 60, - "min": 30, - "name": "tokenKey", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "exceptDomains": null, - "hidden": false, - "id": "email3885137012", - "name": "email", - "onlyDomains": null, - "presentable": false, - "required": true, - "system": true, - "type": "email" - }, - { - "hidden": false, - "id": "bool1547992806", - "name": "emailVisibility", - "presentable": false, - "required": false, - "system": true, - "type": "bool" - }, - { - "hidden": false, - "id": "bool256245529", - "name": "verified", - "presentable": false, - "required": false, - "system": true, - "type": "bool" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE UNIQUE INDEX `idx_tokenKey_pbc_3142635823` ON `_superusers` (`tokenKey`)", - "CREATE UNIQUE INDEX `idx_email_pbc_3142635823` ON `_superusers` (`email`) WHERE `email` != ''" - ], - "system": true, - "authRule": "", - "manageRule": null, - "authAlert": { - "enabled": true, - "emailTemplate": { - "subject": "Login from a new location", - "body": "

Hello,

\n

We noticed a login to your {APP_NAME} account from a new location.

\n

If this was you, you may disregard this email.

\n

If this wasn't you, you should immediately change your {APP_NAME} account password to revoke access from all other locations.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - "oauth2": { - "mappedFields": { - "id": "", - "name": "", - "username": "", - "avatarURL": "" - }, - "enabled": false - }, - "passwordAuth": { - "enabled": true, - "identityFields": [ - "email" - ] - }, - "mfa": { - "enabled": false, - "duration": 1800, - "rule": "" - }, - "otp": { - "enabled": false, - "duration": 180, - "length": 8, - "emailTemplate": { - "subject": "OTP for {APP_NAME}", - "body": "

Hello,

\n

Your one-time password is: {OTP}

\n

If you didn't ask for the one-time password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - "authToken": { - "duration": 86400 - }, - "passwordResetToken": { - "duration": 1800 - }, - "emailChangeToken": { - "duration": 1800 - }, - "verificationToken": { - "duration": 259200 - }, - "fileToken": { - "duration": 180 - }, - "verificationTemplate": { - "subject": "Verify your {APP_NAME} email", - "body": "

Hello,

\n

Thank you for joining us at {APP_NAME}.

\n

Click on the button below to verify your email address.

\n

\n Verify\n

\n

\n Thanks,
\n {APP_NAME} team\n

" - }, - "resetPasswordTemplate": { - "subject": "Reset your {APP_NAME} password", - "body": "

Hello,

\n

Click on the button below to reset your password.

\n

\n Reset password\n

\n

If you didn't ask to reset your password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - }, - "confirmEmailChangeTemplate": { - "subject": "Confirm your {APP_NAME} new email address", - "body": "

Hello,

\n

Click on the button below to confirm your new email address.

\n

\n Confirm new email\n

\n

If you didn't ask to change your email address, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - { - "id": "_pb_users_auth_", - "listRule": "id = @request.auth.id", - "viewRule": "id = @request.auth.id", - "createRule": "", - "updateRule": "id = @request.auth.id", - "deleteRule": "id = @request.auth.id", - "name": "users", - "type": "auth", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "cost": 0, - "hidden": true, - "id": "password901924565", - "max": 0, - "min": 8, - "name": "password", - "pattern": "", - "presentable": false, - "required": true, - "system": true, - "type": "password" - }, - { - "autogeneratePattern": "[a-zA-Z0-9]{50}", - "hidden": true, - "id": "text2504183744", - "max": 60, - "min": 30, - "name": "tokenKey", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "exceptDomains": null, - "hidden": false, - "id": "email3885137012", - "name": "email", - "onlyDomains": null, - "presentable": false, - "required": true, - "system": true, - "type": "email" - }, - { - "hidden": false, - "id": "bool1547992806", - "name": "emailVisibility", - "presentable": false, - "required": false, - "system": true, - "type": "bool" - }, - { - "hidden": false, - "id": "bool256245529", - "name": "verified", - "presentable": false, - "required": false, - "system": true, - "type": "bool" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1579384326", - "max": 255, - "min": 0, - "name": "name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file376926767", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [ - "image/jpeg", - "image/png", - "image/svg+xml", - "image/gif", - "image/webp" - ], - "name": "avatar", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": null, - "type": "file" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [ - "CREATE UNIQUE INDEX `idx_tokenKey__pb_users_auth_` ON `users` (`tokenKey`)", - "CREATE UNIQUE INDEX `idx_email__pb_users_auth_` ON `users` (`email`) WHERE `email` != ''" - ], - "system": false, - "authRule": "", - "manageRule": null, - "authAlert": { - "enabled": true, - "emailTemplate": { - "subject": "Login from a new location", - "body": "

Hello,

\n

We noticed a login to your {APP_NAME} account from a new location.

\n

If this was you, you may disregard this email.

\n

If this wasn't you, you should immediately change your {APP_NAME} account password to revoke access from all other locations.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - "oauth2": { - "mappedFields": { - "id": "", - "name": "name", - "username": "", - "avatarURL": "avatar" - }, - "enabled": false - }, - "passwordAuth": { - "enabled": true, - "identityFields": [ - "email" - ] - }, - "mfa": { - "enabled": false, - "duration": 1800, - "rule": "" - }, - "otp": { - "enabled": false, - "duration": 180, - "length": 8, - "emailTemplate": { - "subject": "OTP for {APP_NAME}", - "body": "

Hello,

\n

Your one-time password is: {OTP}

\n

If you didn't ask for the one-time password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - "authToken": { - "duration": 604800 - }, - "passwordResetToken": { - "duration": 1800 - }, - "emailChangeToken": { - "duration": 1800 - }, - "verificationToken": { - "duration": 259200 - }, - "fileToken": { - "duration": 180 - }, - "verificationTemplate": { - "subject": "Verify your {APP_NAME} email", - "body": "

Hello,

\n

Thank you for joining us at {APP_NAME}.

\n

Click on the button below to verify your email address.

\n

\n Verify\n

\n

\n Thanks,
\n {APP_NAME} team\n

" - }, - "resetPasswordTemplate": { - "subject": "Reset your {APP_NAME} password", - "body": "

Hello,

\n

Click on the button below to reset your password.

\n

\n Reset password\n

\n

If you didn't ask to reset your password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - }, - "confirmEmailChangeTemplate": { - "subject": "Confirm your {APP_NAME} new email address", - "body": "

Hello,

\n

Click on the button below to confirm your new email address.

\n

\n Confirm new email\n

\n

If you didn't ask to change your email address, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" - } - }, - { - "id": "pbc_1430376151", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "Categories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2034676914", - "max": 0, - "min": 0, - "name": "cat_image_url", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2739402623", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": true, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_2328411368", - "hidden": false, - "id": "relation3455582614", - "maxSelect": 1, - "minSelect": 0, - "name": "lesson_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1156222427", - "max": 0, - "min": 0, - "name": "remarks", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_108570809", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "Customers", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1579384326", - "max": 0, - "min": 0, - "name": "name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3885137012", - "max": 0, - "min": 0, - "name": "email", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1146066909", - "max": 0, - "min": 0, - "name": "phone", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "number1813778413", - "max": null, - "min": null, - "name": "quota", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2063623452", - "max": 0, - "min": 0, - "name": "status", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file507207115", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "avatar_file", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "cascadeDelete": false, - "collectionId": "_pb_users_auth_", - "hidden": false, - "id": "relation2809058197", - "maxSelect": 1, - "minSelect": 0, - "name": "user_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_1196309394", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "LessonsCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1137421714", - "max": 0, - "min": 0, - "name": "cat_image_url", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": true, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_2328411368", - "hidden": false, - "id": "relation3455582614", - "maxSelect": 1, - "minSelect": 0, - "name": "lesson_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "convertURLs": false, - "hidden": false, - "id": "editor1843675174", - "maxSize": 0, - "name": "description", - "presentable": false, - "required": false, - "system": false, - "type": "editor" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1156222427", - "max": 0, - "min": 0, - "name": "remarks", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_2328411368", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "LessonsTypes", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1579384326", - "max": 0, - "min": 0, - "name": "name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2363381545", - "max": 0, - "min": 0, - "name": "type", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": true, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "date1542800728", - "max": "", - "min": "", - "name": "field", - "presentable": false, - "required": false, - "system": false, - "type": "date" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_4061499106", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizCRCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_3141885671", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizCRQuestions", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2416551515", - "max": 0, - "min": 0, - "name": "question_fh", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2814132303", - "max": 0, - "min": 0, - "name": "question_sh", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1249130051", - "max": 0, - "min": 0, - "name": "modal_ans", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_4061499106", - "hidden": false, - "id": "relation1827623476", - "maxSelect": 1, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "json3493198471", - "maxSize": 0, - "name": "options", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_3571292172", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2034676914", - "max": 0, - "min": 0, - "name": "cat_image", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_96745150", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizConnectives", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2416551515", - "max": 0, - "min": 0, - "name": "question_fh", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2814132303", - "max": 0, - "min": 0, - "name": "question_sh", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1249130051", - "max": 0, - "min": 0, - "name": "modal_ans", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_342761728", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 999, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_342761728", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizConnectivesCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_3639453778", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizLPCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2560465762", - "max": 0, - "min": 0, - "name": "slug", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1156222427", - "max": 0, - "min": 0, - "name": "remarks", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "convertURLs": false, - "hidden": false, - "id": "editor1843675174", - "maxSize": 0, - "name": "description", - "presentable": false, - "required": false, - "system": false, - "type": "editor" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_742947356", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizLPQuestions", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file4170105732", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "sound", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_3639453778", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 1, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2560465762", - "max": 0, - "min": 0, - "name": "slug", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1156222427", - "max": 0, - "min": 0, - "name": "remarks", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "convertURLs": false, - "hidden": false, - "id": "editor1843675174", - "maxSize": 0, - "name": "description", - "presentable": false, - "required": false, - "system": false, - "type": "editor" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_2511066072", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizListenings", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "file4170105732", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "sound", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_3571292172", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 999, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_84667061", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizMFCategories", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1125157303", - "max": 0, - "min": 0, - "name": "cat_name", - "pattern": "", - "presentable": true, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "number2161764012", - "max": null, - "min": null, - "name": "pos", - "onlyInt": false, - "presentable": false, - "required": false, - "system": false, - "type": "number" - }, - { - "hidden": false, - "id": "json3915970527", - "maxSize": 0, - "name": "init_answer", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_3346420851", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "QuizMFQuestions", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3690399444", - "max": 0, - "min": 0, - "name": "word_c", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_84667061", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 1, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2058414169", - "max": 0, - "min": 0, - "name": "visible", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file4170105732", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "sound", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "file2034676914", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "cat_image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_2936646783", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "QuizMatchings", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3690399444", - "max": 0, - "min": 0, - "name": "word_c", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_3571292172", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 999, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_1305841361", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "UserMetas", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text4192936109", - "max": 0, - "min": 0, - "name": "helloworld", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "json3622966325", - "maxSize": 0, - "name": "meta", - "presentable": false, - "required": false, - "system": false, - "type": "json" - }, - { - "cascadeDelete": false, - "collectionId": "_pb_users_auth_", - "hidden": false, - "id": "relation2809058197", - "maxSelect": 1, - "minSelect": 0, - "name": "user_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2744374011", - "max": 0, - "min": 0, - "name": "state", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "file376926767", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "avatar", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1466534506", - "max": 0, - "min": 0, - "name": "role", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_1638686383", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "Vocabularies", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "file3309110367", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "image", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "hidden": false, - "id": "file4170105732", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "sound", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3287381265", - "max": 0, - "min": 0, - "name": "word", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3690399444", - "max": 0, - "min": 0, - "name": "word_c", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text412313404", - "max": 0, - "min": 0, - "name": "sample_e", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text4059087369", - "max": 0, - "min": 0, - "name": "sample_c", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_1430376151", - "hidden": false, - "id": "relation3870140739", - "maxSelect": 1, - "minSelect": 0, - "name": "cat_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text105650625", - "max": 0, - "min": 0, - "name": "category", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "cascadeDelete": false, - "collectionId": "pbc_2328411368", - "hidden": false, - "id": "relation808508980", - "maxSelect": 1, - "minSelect": 0, - "name": "lesson_type_id", - "presentable": false, - "required": false, - "system": false, - "type": "relation" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_4275539003", - "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "createRule": null, - "updateRule": null, - "deleteRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "name": "_authOrigins", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text455797646", - "max": 0, - "min": 0, - "name": "collectionRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text127846527", - "max": 0, - "min": 0, - "name": "recordRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text4228609354", - "max": 0, - "min": 0, - "name": "fingerprint", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE UNIQUE INDEX `idx_authOrigins_unique_pairs` ON `_authOrigins` (collectionRef, recordRef, fingerprint)" - ], - "system": true - }, - { - "id": "pbc_2281828961", - "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "createRule": null, - "updateRule": null, - "deleteRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "name": "_externalAuths", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text455797646", - "max": 0, - "min": 0, - "name": "collectionRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text127846527", - "max": 0, - "min": 0, - "name": "recordRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2462348188", - "max": 0, - "min": 0, - "name": "provider", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1044722854", - "max": 0, - "min": 0, - "name": "providerId", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE UNIQUE INDEX `idx_externalAuths_record_provider` ON `_externalAuths` (collectionRef, recordRef, provider)", - "CREATE UNIQUE INDEX `idx_externalAuths_collection_provider` ON `_externalAuths` (collectionRef, provider, providerId)" - ], - "system": true - }, - { - "id": "pbc_2279338944", - "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "_mfas", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text455797646", - "max": 0, - "min": 0, - "name": "collectionRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text127846527", - "max": 0, - "min": 0, - "name": "recordRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1582905952", - "max": 0, - "min": 0, - "name": "method", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE INDEX `idx_mfas_collectionRef_recordRef` ON `_mfas` (collectionRef,recordRef)" - ], - "system": true - }, - { - "id": "pbc_1638494021", - "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId", - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "_otps", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text455797646", - "max": 0, - "min": 0, - "name": "collectionRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text127846527", - "max": 0, - "min": 0, - "name": "recordRef", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": true, - "system": true, - "type": "text" - }, - { - "cost": 8, - "hidden": true, - "id": "password901924565", - "max": 0, - "min": 0, - "name": "password", - "pattern": "", - "presentable": false, - "required": true, - "system": true, - "type": "password" - }, - { - "autogeneratePattern": "", - "hidden": true, - "id": "text3866985172", - "max": 0, - "min": 0, - "name": "sentTo", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": true, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": true, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": true, - "type": "autodate" - } - ], - "indexes": [ - "CREATE INDEX `idx_otps_collectionRef_recordRef` ON `_otps` (collectionRef, recordRef)" - ], - "system": true - }, - { - "id": "pbc_1509025625", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "billingAddress", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1400097126", - "max": 0, - "min": 0, - "name": "country", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text2744374011", - "max": 0, - "min": 0, - "name": "state", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text760939060", - "max": 0, - "min": 0, - "name": "city", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text4114525948", - "max": 0, - "min": 0, - "name": "zipCode", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text3620973610", - "max": 0, - "min": 0, - "name": "line1", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text1322974608", - "max": 0, - "min": 0, - "name": "line2", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_123408445", - "listRule": "", - "viewRule": "", - "createRule": "", - "updateRule": "", - "deleteRule": "", - "name": "helloworlds", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text907060870", - "max": 0, - "min": 0, - "name": "hello", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - } - ], - "indexes": [], - "system": false - }, - { - "id": "pbc_2109205374", - "listRule": null, - "viewRule": null, - "createRule": null, - "updateRule": null, - "deleteRule": null, - "name": "t1", - "type": "base", - "fields": [ - { - "autogeneratePattern": "[a-z0-9]{15}", - "hidden": false, - "id": "text3208210256", - "max": 15, - "min": 15, - "name": "id", - "pattern": "^[a-z0-9]+$", - "presentable": false, - "primaryKey": true, - "required": true, - "system": true, - "type": "text" - }, - { - "autogeneratePattern": "", - "hidden": false, - "id": "text907060870", - "max": 0, - "min": 0, - "name": "hello", - "pattern": "", - "presentable": false, - "primaryKey": false, - "required": false, - "system": false, - "type": "text" - }, - { - "hidden": false, - "id": "autodate2990389176", - "name": "created", - "onCreate": true, - "onUpdate": false, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "autodate3332085495", - "name": "updated", - "onCreate": true, - "onUpdate": true, - "presentable": false, - "system": false, - "type": "autodate" - }, - { - "hidden": false, - "id": "file2313559263", - "maxSelect": 1, - "maxSize": 0, - "mimeTypes": [], - "name": "test_file", - "presentable": false, - "protected": false, - "required": false, - "system": false, - "thumbs": [], - "type": "file" - } - ], - "indexes": [], - "system": false - } -] -
- -
diff --git a/002_source/cms/src/lib/get-image-url-from-file.ts.ts b/002_source/cms/src/lib/get-image-url-from-file.ts.ts new file mode 100644 index 0000000..68f41a5 --- /dev/null +++ b/002_source/cms/src/lib/get-image-url-from-file.ts.ts @@ -0,0 +1,3 @@ +export default function getImageUrlFromFile(collectionId: string, id: string, catImage: string): string { + return `http://127.0.0.1:8090/api/files/${collectionId}/${id}/${catImage}`; +} diff --git a/002_source/cms/tsconfig.json b/002_source/cms/tsconfig.json index e6ca189..9c98697 100644 --- a/002_source/cms/tsconfig.json +++ b/002_source/cms/tsconfig.json @@ -20,13 +20,7 @@ "plugins": [{ "name": "next" }], "paths": { "@/*": ["./src/*"] } }, - "include": [ - "next-env.d.ts", - "**/*.ts", - "**/*.tsx", - ".next/types/**/*.ts" - // - ], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": [ "node_modules", ".next",