Compare commits

...

23 Commits

Author SHA1 Message Date
cf0ec8bd64 ``update Change logout behavior back to route navigation after sign-out instead of full page reload `` 2025-05-17 10:02:35 +00:00
59cdf7257b ```
update Implement standardized documentation for all database modules, including purpose, rules, and requirements for each CRUD operation; refactor existing comments to follow new documentation standard
```
2025-05-17 10:02:05 +00:00
b8309596be update example for ai, 2025-05-17 11:20:33 +08:00
688e102f2c ``delete Remove database schema definitions and hidden field count retrieval functionality`` 2025-05-17 09:41:36 +08:00
4d57d0a5f3 ``update Change logout behavior from route navigation to full page reload after sign-out `` 2025-05-16 23:41:22 +08:00
720838f137 Merge branch 'develop/ionic_mobile/i18n/trunk' into develop/ionic_mobile/login-flow/trunk 2025-05-16 23:38:56 +08:00
c92ac33ade ```
replace setting tab button with conditional rendering based on user authentication status, showing avatar if available
```
2025-05-16 23:37:39 +08:00
72e478937d ``update Add QR code generation feature with dynamic sizing and styling, implement screen-width-based conditional rendering, update i18n translations, and adjust context providers structure`` 2025-05-16 22:51:33 +08:00
62d8519da5 ``delete Remove i18n configuration file and English translation resources; likely replaced by a JSON-based or externalized translation management approach`` 2025-05-16 22:50:24 +08:00
8d746f3aa9 ``update Refactor navigation URLs by replacing hardcoded LESSON_LINK with Paths.LESSON_LINK across App, RouteConfig, and multiple components; remove redundant LESSON_LINK from constants`` 2025-05-16 22:00:04 +08:00
69b2ef59e5 ``update Upgrade dependencies including i18next, react-i18next, eslint, and testing-library; adjust peer dependencies and add new ESLint plugins`` 2025-05-16 21:59:52 +08:00
f9c0deb2e9 ``add Add CMS project code-workspace file to define multi-root workspace including documentation and AI workspace directories`` 2025-05-16 21:57:52 +08:00
47760fa7b2 ``add Add code-workspace files for documentation, ionic_mobile, and test projects to define multi-root workspace configurations`` 2025-05-16 21:57:41 +08:00
83bd86cc9b ``update Add .env.example file with PocketBase URL configuration for development environment `` 2025-05-16 17:47:33 +08:00
49189a532e ```
update Add development environment configuration, I18n support, route adjustments, and various hooks refactoring
```
2025-05-16 17:47:05 +08:00
6b917c9fb9 ``update Add error constant for empty PocketBase URL and validate it during app initialization `` 2025-05-16 15:56:56 +08:00
aa834a43c9 ``update Add platform-specific back button for Android, replace header layout, use LoadingSpinner, and refactor imports in Lesson page component`` 2025-05-16 15:56:46 +08:00
1775d8c5a3 ``update Remove unused components, imports, and refactor file URL generation in WordPage component`` 2025-05-16 15:56:24 +08:00
779062e247 ``update Replace getStudentAvatar with getStudentAvatarUrl for avatar URL generation in student profile`` 2025-05-16 15:56:19 +08:00
60df47fb8d ``update Extract PocketBase URL to constant and refactor related functions to use it for dynamic file URL generation`` 2025-05-16 15:55:47 +08:00
c87357ff24 ``update Remove unused import path suffix and comment out unused useRequireAuth hook`` 2025-05-16 15:55:30 +08:00
34a7ff7ac9 ``refactor Rename LoadingScreen component to LoadingSpinner and refactor structure for better reusability`` 2025-05-16 15:55:07 +08:00
3556e77a7c ```
add Implement custom sign-out functionality with loading state and error handling
```
2025-05-16 13:26:17 +08:00
194 changed files with 3022 additions and 4762 deletions

View File

@@ -2,7 +2,11 @@
import * as React from 'react';
import { useRouter } from 'next/navigation';
import { LoadingButton } from '@mui/lab';
import { Button } from '@mui/material';
import MenuItem from '@mui/material/MenuItem';
import { SignOut as SignOutIcon } from '@phosphor-icons/react/dist/ssr/SignOut';
import { useTranslation } from 'react-i18next';
import { authClient } from '@/lib/auth/custom/client';
import { logger } from '@/lib/default-logger';
@@ -10,39 +14,44 @@ import { useUser } from '@/hooks/use-user';
import { toast } from '@/components/core/toaster';
export function CustomSignOut(): React.JSX.Element {
const { t } = useTranslation('sign_in');
const { checkSession } = useUser();
const [buttonShowLoading, setButtonShowLoading] = React.useState<boolean>(false);
const router = useRouter();
const handleSignOut = React.useCallback(async (): Promise<void> => {
setButtonShowLoading(true);
try {
const { error } = await authClient.signOut();
if (error) {
logger.error('Sign out error', error);
toast.error('Something went wrong, unable to sign out');
toast.error(t('something-went-wrong-unable-to-sign-out'));
return;
}
// Refresh the auth state
await checkSession?.();
// UserProvider, for this case, will not refresh the router and we need to do it manually
router.refresh();
// After refresh, AuthGuard will handle the redirect
} catch (err) {
logger.error('Sign out error', err);
toast.error('Something went wrong, unable to sign out');
toast.error(t('something-went-wrong-unable-to-sign-out'));
}
}, [checkSession, router]);
}, [checkSession, router, t]);
return (
<MenuItem
component="div"
<LoadingButton
onClick={handleSignOut}
sx={{ justifyContent: 'center' }}
sx={{ width: '100%' }}
variant="text"
disabled={buttonShowLoading}
loading={buttonShowLoading}
startIcon={<SignOutIcon />}
color="secondary"
>
Sign out
</MenuItem>
{t('sign-out')}
</LoadingButton>
);
}

View File

@@ -16,15 +16,15 @@ import { User as UserIcon } from '@phosphor-icons/react/dist/ssr/User';
import type { User } from '@/types/user';
import { config } from '@/config';
import { paths } from '@/paths';
import { authClient } from '@/lib/auth/custom/client';
import { AuthStrategy } from '@/lib/auth/strategy';
import { logger } from '@/lib/default-logger';
import { Auth0SignOut } from './auth0-sign-out';
import { CognitoSignOut } from './cognito-sign-out';
import { CustomSignOut } from './custom-sign-out';
import { FirebaseSignOut } from './firebase-sign-out';
import { SupabaseSignOut } from './supabase-sign-out';
import { authClient } from '@/lib/auth/custom/client';
import { logger } from '@/lib/default-logger';
const defaultUser = {
id: 'USR-000',
@@ -55,7 +55,8 @@ export function UserPopover({ anchorEl, onClose, open }: UserPopoverProps): Reac
void loadUserMeta();
}, []);
if (!userMeta) return <>loading</>;
// NOTE: delay when userMeta is null, used for sign-out
if (!userMeta) return <></>;
return (
<Popover

View File

@@ -66,6 +66,7 @@ export function SideNav({ color = 'evident', items = [] }: SideNavProps): React.
spacing={2}
sx={{ p: 2 }}
>
{/* NOTE: hide logo
<div>
<Box
component={RouterLink}
@@ -79,6 +80,7 @@ export function SideNav({ color = 'evident', items = [] }: SideNavProps): React.
/>
</Box>
</div>
*/}
<WorkspacesSwitch />
</Stack>
<Box

View File

@@ -1,6 +1,11 @@
// api method for crate customer record
// PURPOSE:
// Create new customer record
// REQ0006
//
// RULES:
// TBA
// error handled by caller
// contain definition to collection only
//
import { pb } from '@/lib/pb';
import { COL_CUSTOMERS } from '@/constants';
import type { CreateFormProps } from '@/components/dashboard/customer/type.d';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Delete customer record
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { pb } from '@/lib/pb';
import { COL_CUSTOMERS } from '@/constants';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Get count of active customers
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { COL_USER_METAS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Get all customer records
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { pb } from '@/lib/pb';
import { COL_CUSTOMERS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Get total count of all customers
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { pb } from '@/lib/pb';
import { COL_CUSTOMERS } from '@/constants';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Get count of blocked customers
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { COL_USER_METAS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Get customer record by ID
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { pb } from '@/lib/pb';
import { COL_CUSTOMERS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Get count of pending customers
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { COL_USER_METAS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Sample hello world function
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
export function helloCustomer(): string {
return 'Hello from Customers module!';
}

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Update customer information
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { pb } from '@/lib/pb';
import { COL_CUSTOMERS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,11 @@
// PURPOSE:
// Create new lesson category in the database
//
// RULES:
// 1. Must provide data matching CreateFormProps type
// 2. Uses PocketBase collection API
// 3. Returns Promise<RecordModel>
import { COL_LESSON_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,11 @@
// PURPOSE:
// Delete specified lesson category from database
//
// RULES:
// 1. Must provide valid category ID
// 2. Uses PocketBase collection API
// 3. Returns Promise<boolean> indicating deletion success
import { COL_LESSON_CATEGORIES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,11 @@
// PURPOSE:
// Retrieve all lesson categories from database
//
// RULES:
// 1. Uses PocketBase getFullList API
// 2. Returns Promise<RecordModel[]> with all categories
// 3. Accepts no parameters
import { COL_LESSON_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,6 +1,11 @@
// PURPOSE:
// Get total count of all lesson categories
//
// RULES:
// error handled by caller
// contain definition to collection only
// 1. Uses PocketBase getList API
// 2. Returns Promise<number> representing total count
// 3. Errors handled by caller
// 4. Contains collection definition only
import { COL_LESSON_CATEGORIES } from '@/constants';

View File

@@ -1,3 +1,11 @@
// PURPOSE:
// Retrieve single lesson category by ID
//
// RULES:
// 1. Must provide valid category ID
// 2. Uses PocketBase getOne API
// 3. Returns Promise<RecordModel> with requested category
import { COL_LESSON_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,4 +1,13 @@
// PURPOSE:
// Get count of lesson categories marked as hidden
// REQ0006
//
// RULES:
// 1. Uses PocketBase getList API with visible="hidden" filter
// 2. Returns Promise<number> with count of hidden categories
// 3. Maximum 9999 records returned
// 4. Returns 0 on error
import { COL_LESSON_CATEGORIES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,4 +1,13 @@
// PURPOSE:
// Get count of lesson categories marked as visible
// REQ0006
//
// RULES:
// 1. Uses PocketBase getList API with visible="visible" filter
// 2. Returns Promise<number> with count of visible categories
// 3. Maximum 9999 records returned
// 4. Returns 0 on error
import { COL_LESSON_CATEGORIES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,10 @@
// PURPOSE:
// Example/test function that returns "helloworld" string
//
// RULES:
// 1. Takes no parameters
// 2. Always returns fixed string "helloworld"
function Helloworld(): string {
return 'helloworld';
}

View File

@@ -1,5 +1,10 @@
// PURPOSE:
// List all lesson categories with expanded relations
//
// RULES:
// 1. Uses PocketBase getFullList API
// 2. Expands cat_id relations
// 3. Returns Promise<LessonCategory[]> with all categories
import { COL_LESSON_CATEGORIES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,11 @@
// PURPOSE:
// Update existing lesson category with new data
//
// RULES:
// 1. Requires valid category ID and update data
// 2. Uses PocketBase collection update API
// 3. Returns Promise<RecordModel> with updated category
import { COL_LESSON_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,13 @@
//
// PURPOSE:
// Create new lesson type in PocketBase
//
// RULES:
// - Must validate using CreateForm type
// - Uses COL_LESSON_TYPES collection
// - Returns Promise with created record
//
import { COL_LESSON_TYPES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,7 +1,25 @@
//
// PURPOSE:
// Delete lesson type record from PocketBase
//
// RULES:
// - Calls pb.collection().delete()
// - Returns Promise<{success: boolean, error?: string}>
// - Basic error handling
//
import { COL_LESSON_TYPES } from '@/constants';
import { pb } from '@/lib/pb';
export default function deleteLessonType(id: string): Promise<boolean> {
return pb.collection(COL_LESSON_TYPES).delete(id);
export default async function deleteLessonType(id: string): Promise<{success: boolean, error?: string}> {
try {
await pb.collection(COL_LESSON_TYPES).delete(id);
return { success: true };
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error'
};
}
}

View File

@@ -1,3 +1,12 @@
//
// PURPOSE:
// Get all lesson type records from PocketBase
//
// RULES:
// - Uses pb.collection().getFullList()
// - Returns Promise<RecordModel[]>
// - No pagination or filtering implemented
//
import { COL_LESSON_TYPES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,4 +1,13 @@
//
// PURPOSE:
// Get total count of lesson types from PocketBase
// REQ0006
//
// RULES:
// - Uses pb.collection().getList() with large page size
// - Returns Promise<number> with total count
// - No filter support implemented
//
import { COL_LESSON_TYPES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,12 @@
//
// PURPOSE:
// Get lesson type by ID from PocketBase
//
// RULES:
// - Simply calls pb.collection().getOne()
// - Returns Promise<RecordModel>
// - Throws error if record not found
//
import { COL_LESSON_TYPES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,4 +1,14 @@
//
// PURPOSE:
// Get count of hidden lesson types
// REQ0006
//
// RULES:
// - Must clearly define "hidden" status
// - Must cache results
// - Must return accurate count
//
import { COL_LESSON_TYPES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,4 +1,15 @@
//
// PURPOSE:
// Get count of visible lesson types from PocketBase
// REQ0006
//
// RULES:
// - Uses filter: visible = "visible"
// - Returns Promise<number> with count
// - Returns 0 on error
// - No caching implemented
//
import { COL_LESSON_TYPES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,13 @@
//
// PURPOSE:
// Example/test file
//
// RULES:
// - For development/testing only
// - Should not contain business logic
// - Can be modified/deleted anytime
//
function Helloworld(): string {
return 'helloworld';
}

View File

@@ -1,3 +1,13 @@
//
// PURPOSE:
// Update lesson type in PocketBase
//
// RULES:
// - Simply calls pb.collection().update()
// - Uses CreateForm type for validation
// - Returns Promise<RecordModel>
// - No additional validation or logging
//
import { COL_LESSON_TYPES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,6 +1,11 @@
// api method for create notification record
// PURPOSE:
// Create new notification record
//
// RULES:
// TBA
// 1. Uses COL_NOTIFICATIONS collection
// 2. Requires NotificationFormProps type data
// 3. Returns Promise<RecordModel> with created record
// 4. Errors handled by caller
import { pb } from '@/lib/pb';
import { COL_NOTIFICATIONS } from '@/constants';
import type { NotificationFormProps } from '@/components/dashboard/notification/type.d';

View File

@@ -1,6 +1,11 @@
// api method for delete notification record
// PURPOSE:
// Delete notification record by ID
//
// RULES:
// TBA
// 1. Uses COL_NOTIFICATIONS collection
// 2. Requires valid notification ID string
// 3. Returns Promise<boolean> indicating success
// 4. Errors handled by caller
import { pb } from '@/lib/pb';
import { COL_NOTIFICATIONS } from '@/constants';

View File

@@ -1,3 +1,11 @@
// PURPOSE:
// Count active notification records
//
// RULES:
// 1. Uses COL_CUSTOMERS collection
// 2. Filters records with status="active"
// 3. Returns Promise<number> with count
// 4. Errors handled by caller
import { COL_CUSTOMERS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,6 +1,12 @@
// api method for get all notification records
// PURPOSE:
// Get all notification records
//
// RULES:
// TBA
// 1. Uses COL_NOTIFICATIONS collection
// 2. Returns Promise<RecordModel[]> with all records
// 3. Accepts optional options parameter
// 4. Uses getFullList API
// 5. Errors handled by caller
import { pb } from '@/lib/pb';
import { COL_NOTIFICATIONS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Get total count of notification records
//
// RULES:
// 1. Uses COL_NOTIFICATIONS collection
// 2. Returns Promise<number> with total count
// 3. Uses getList API
// 4. Errors handled by caller
//
import { pb } from '@/lib/pb';
import { COL_CUSTOMERS } from '@/constants';

View File

@@ -1,3 +1,11 @@
// PURPOSE:
// Count blocked notification records
//
// RULES:
// 1. Uses COL_CUSTOMERS collection
// 2. Filters records with status="blocked"
// 3. Returns Promise<number> with count
// 4. Errors handled by caller
import { COL_CUSTOMERS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,6 +1,12 @@
// api method for get notification by id
// PURPOSE:
// - Provides functionality to retrieve a single notification by ID
// - Returns complete notification details for specified ID
//
// RULES:
// TBA
// - Must validate input ID format
// - Should handle cases where notification is not found
// - Must respect data privacy and only return authorized fields
// - Should optimize query performance for single record retrieval
import { pb } from '@/lib/pb';
import { COL_NOTIFICATIONS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,6 +1,12 @@
// PURPOSE:
// Get notifications for specific user ID
//
// RULES:
// api method for get notifications by user id
// 1. Uses COL_NOTIFICATIONS collection
// 2. Requires valid user ID string
// 3. Returns Promise<Notification[]> with user's notifications
// 4. Expands author and to_user_id relations
// 5. Sorts by created date (newest first)
import { COL_NOTIFICATIONS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,11 @@
// PURPOSE:
// Count pending customer notifications
//
// RULES:
// 1. Uses COL_CUSTOMERS collection
// 2. Filters records with status="pending"
// 3. Returns Promise<number> with count
// 4. Errors handled by caller
import { COL_CUSTOMERS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,6 +1,13 @@
// PURPOSE:
// Get all unread notifications for specified user ID
//
// RULES:
// api method for get notifications by user id
// 1. Uses COL_NOTIFICATIONS collection
// 2. Filters by to_user_id and read=false status
// 3. Expands author and to_user_id relations
// 4. Sorts by created date (newest first)
// 5. Returns Promise<Notification[]>
// 6. Disables caching for real-time results
import { COL_NOTIFICATIONS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,10 @@
// PURPOSE:
// Example/Test component for notifications
//
// RULES:
// 1. Returns fixed string for testing
// 2. Not used in production
// 3. Follows project coding standards
export function helloCustomer(): string {
return 'Hello from Customers module!';
}

View File

@@ -1,6 +1,12 @@
// api method for update notification record
// PURPOSE:
// Update notification record
//
// RULES:
// TBA
// 1. Uses COL_NOTIFICATIONS collection
// 2. Requires valid notification ID string
// 3. Accepts Partial<NotificationFormProps> update data
// 4. Returns Promise<RecordModel> with updated record
// 5. Errors handled by caller
import { pb } from '@/lib/pb';
import { COL_NOTIFICATIONS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,6 +1,12 @@
// api method for update notification record
// PURPOSE:
// Mark single notification as read
//
// RULES:
// TBA
// 1. Uses COL_NOTIFICATIONS collection
// 2. Requires valid notification ID string
// 3. Updates read status to true
// 4. Returns Promise<RecordModel> with updated record
// 5. Errors handled by caller
import { COL_NOTIFICATIONS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Create new Quiz CR Category record
//
// RULES:
// 1. Uses COL_QUIZ_CR_CATEGORIES collection
// 2. Requires CreateFormProps type data
// 3. Returns Promise<RecordModel> with created record
// 4. Errors handled by caller
// 5. Uses pb.collection().create()
import { COL_QUIZ_CR_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Delete Quiz CR Category record
//
// RULES:
// 1. Uses COL_QUIZ_CR_CATEGORIES collection
// 2. Requires valid record ID string
// 3. Returns Promise<boolean> indicating success
// 4. Errors handled by caller
// 5. Uses pb.collection().delete()
import { COL_QUIZ_CR_CATEGORIES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Get all Quiz CR Category records
//
// RULES:
// 1. Uses COL_QUIZ_CR_CATEGORIES collection
// 2. Returns Promise<RecordModel[]> with all records
// 3. Accepts no parameters
// 4. Uses getFullList API
// 5. Errors handled by caller
import { COL_QUIZ_CR_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Get total count of Quiz CR Category records
//
// RULES:
// 1. Uses COL_QUIZ_CR_CATEGORIES collection
// 2. Returns Promise<number> with total count
// 3. Limits to first 9999 records
// 4. Errors handled by caller
// 5. Uses getList API
// REQ0006
import { COL_QUIZ_CR_CATEGORIES } from '@/constants';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Get Quiz CR Category record by ID
//
// RULES:
// 1. Uses COL_QUIZ_CR_CATEGORIES collection
// 2. Requires valid record ID string
// 3. Returns Promise<RecordModel> with requested record
// 4. Errors handled by caller
// 5. Uses getOne API
import { COL_QUIZ_CR_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Get count of hidden Quiz CR Category records
//
// RULES:
// 1. Uses COL_QUIZ_CR_CATEGORIES collection
// 2. Filters records with visible="hidden"
// 3. Returns Promise<number> with count
// 4. Limits to first 9999 records
// 5. Returns 0 on error
// REQ0006
import { COL_QUIZ_CR_CATEGORIES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// Get count of visible Quiz CR Category records
//
// RULES:
// 1. Uses COL_QUIZ_CR_CATEGORIES collection
// 2. Filters records with visible="visible"
// 3. Returns Promise<number> with count
// 4. Limits to first 9999 records
// 5. Returns 0 on error
// REQ0006
import { COL_QUIZ_CR_CATEGORIES } from '@/constants';

View File

@@ -1,3 +1,13 @@
// PURPOSE:
// Update Quiz CR Category record
//
// RULES:
// 1. Uses COL_QUIZ_CR_CATEGORIES collection
// 2. Requires valid record ID string
// 3. Accepts CreateFormProps update data
// 4. Returns Promise<RecordModel> with updated record
// 5. Errors handled by caller
// 6. Uses pb.collection().update()
import { COL_QUIZ_CR_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,13 @@
//
// PURPOSE:
// Create new QuizCRQuestions record
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { COL_QUIZ_CR_QUESTIONS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,13 @@
//
// PURPOSE:
// Delete specified QuizCRQuestions record
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { COL_QUIZ_CR_QUESTIONS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,13 @@
//
// PURPOSE:
// Get all QuizCRQuestions records
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { COL_QUIZ_CR_QUESTIONS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,4 +1,13 @@
//
// PURPOSE:
// Get total count of all QuizCRQuestions records
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { COL_QUIZ_CR_QUESTIONS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,4 +1,13 @@
//
// PURPOSE:
// Get count of hidden QuizCRQuestions records
// REQ0006
//
// RULES:
// returns 0 on error
// contain definition to collection only
//
import { COL_QUIZ_CR_QUESTIONS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,4 +1,13 @@
//
// PURPOSE:
// Get count of visible QuizCRQuestions records
// REQ0006
//
// RULES:
// returns 0 on error
// contain definition to collection only
//
import { COL_QUIZ_CR_QUESTIONS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,11 @@
// PURPOSE: Create new Quiz LP category record
//
// RULES:
// - Errors are handled by the caller
// - Uses pb.collection directly
// - Type definitions are in type.d.tsx
// - May require additional validation logic
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,11 @@
// PURPOSE: Delete specified Quiz LP category record
//
// RULES:
// - Errors are handled by the caller
// - Uses pb.collection directly
// - Type definitions are in type.d.tsx
// - May require additional validation logic
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,11 @@
// PURPOSE: Retrieve all Quiz LP category records
//
// RULES:
// - Errors are handled by the caller
// - Uses pb.collection directly
// - Type definitions are in type.d.tsx
// - May require additional filtering logic
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,11 @@
// PURPOSE: Get total count of Quiz LP category records
//
// RULES:
// - Errors are handled by the caller
// - Uses pb.collection directly
// - Type definitions are in type.d.tsx
// - Includes all records (both visible and hidden)
// REQ0006
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';

View File

@@ -1,3 +1,11 @@
// PURPOSE: Retrieve single Quiz LP category record by ID
//
// RULES:
// - Errors are handled by the caller
// - Uses pb.collection directly
// - Type definitions are in type.d.tsx
// - Returns null if record not found
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,11 @@
// PURPOSE: Get count of hidden Quiz LP category records
//
// RULES:
// - Errors are handled by the caller
// - Uses pb.collection directly
// - Type definitions are in type.d.tsx
// - Only counts records marked as hidden
// REQ0006
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';

View File

@@ -1,3 +1,11 @@
// PURPOSE: Get count of visible Quiz LP category records
//
// RULES:
// - Errors are handled by the caller
// - Uses pb.collection directly
// - Type definitions are in type.d.tsx
// - Only counts records marked as visible
// REQ0006
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';

View File

@@ -1,3 +1,11 @@
// PURPOSE: Update existing Quiz LP category record
//
// RULES:
// - Errors are handled by the caller
// - Uses pb.collection directly
// - Type definitions are in type.d.tsx
// - May require additional validation logic
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,13 @@
//
// PURPOSE:
// Create new QuizLPQuestions record
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { COL_QUIZ_LP_QUESTIONS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,13 @@
//
// PURPOSE:
// Get all QuizLPQuestions records
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { COL_QUIZ_LP_QUESTIONS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,4 +1,13 @@
//
// PURPOSE:
// Get total count of all QuizLPQuestions records
// REQ0006
//
// RULES:
// returns 0 on error
// contain definition to collection only
//
import { COL_QUIZ_LP_QUESTIONS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,13 @@
//
// PURPOSE:
// Get specific QuizLPQuestions record by ID
// REQ0006
//
// RULES:
// error handled by caller
// contain definition to collection only
//
import { COL_QUIZ_LP_QUESTIONS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,4 +1,13 @@
//
// PURPOSE:
// Get count of visible QuizLPQuestions records
// REQ0006
//
// RULES:
// returns 0 on error
// contain definition to collection only
//
import { COL_QUIZ_LP_QUESTIONS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,8 @@
// PURPOSE: Delete a QuizListening record by ID
// RULES:
// - Requires a valid QuizListening ID as parameter
// - Returns Promise<boolean> indicating success/failure
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,8 @@
// PURPOSE: Get all QuizListening records
// RULES:
// - Returns Promise with array of QuizListening records
// - No parameters required
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,8 @@
// PURPOSE: Get total count of QuizListening records
// RULES:
// - Returns Promise with total count number
// - No parameters required
// REQ0006
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';

View File

@@ -1,3 +1,8 @@
// PURPOSE: Get a single QuizListening record by ID
// RULES:
// - Requires a valid QuizListening ID as parameter
// - Returns Promise with QuizListening record or null if not found
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,4 +1,10 @@
// PURPOSE:
// Get count of hidden QuizListening records
// REQ0006
// RULES:
// - Returns Promise with count of hidden records
// - No parameters required
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,4 +1,11 @@
// PURPOSE:
// Get count of visible QuizListening records
// REQ0006
//
// RULES:
// - Returns Promise with count of visible records
// - No parameters required
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,11 @@
// PURPOSE:
// Get paginated QuizListening records with filtering/sorting options
//
// RULES:
// - Requires currentPage and rowsPerPage parameters
// - Optional listOption parameter for filtering/sorting
// - Returns Promise with paginated ListResult
import { COL_QUIZ_LP_CATEGORIES } from '@/constants';
import type { ListResult, RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,13 @@
// PURPOSE:
// - Creates a new Quiz Multiple-Factor Category record in PocketBase
// - Handles the creation of category records for quiz multi-factor system
//
// RULES:
// - Uses pb.collection().create() without error handling (errors handled by caller)
// - Requires valid CreateFormProps as input
// - Returns Promise<RecordModel> with created record
// - Collection ID defined in COL_QUIZ_MF_CATEGORIES constant
//
import { COL_QUIZ_MF_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// - Deletes a Quiz Multiple-Factor Category record from PocketBase
// - Handles removal of category records from quiz multi-factor system
//
// RULES:
// - Uses pb.collection().delete() without error handling (errors handled by caller)
// - Requires valid record ID as input
// - Returns Promise<boolean> indicating deletion success
// - Collection ID defined in COL_QUIZ_MF_CATEGORIES constant
import { COL_QUIZ_MF_CATEGORIES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// - Retrieves all Quiz Multiple-Factor Category records from PocketBase
// - Used for listing all available categories in quiz multi-factor system
//
// RULES:
// - Uses pb.collection().getFullList() without error handling
// - Returns Promise<RecordModel[]> with all category records
// - Collection ID defined in COL_QUIZ_MF_CATEGORIES constant
// - No filtering parameters required
import { COL_QUIZ_MF_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,4 +1,14 @@
// PURPOSE:
// - Counts all Quiz Multiple-Factor Category records in PocketBase
// - Provides total count of categories for quiz multi-factor system
// REQ0006
//
// RULES:
// - Uses pb.collection().getList() with large page size to count all records
// - Returns Promise<number> with total count
// - Collection ID defined in COL_QUIZ_MF_CATEGORIES constant
// - No filtering parameters applied
//
import { COL_QUIZ_MF_CATEGORIES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,13 @@
// PURPOSE:
// - Retrieves a single Quiz Multiple-Factor Category record by ID from PocketBase
// - Used when detailed information about a specific category is needed
//
// RULES:
// - Uses pb.collection().getOne() to fetch single record
// - Requires valid record ID as input
// - Returns Promise<RecordModel> with the category data
// - Collection ID defined in COL_QUIZ_MF_CATEGORIES constant
import { COL_QUIZ_MF_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,4 +1,13 @@
// PURPOSE:
// - Counts hidden Quiz Multiple-Factor Category records in PocketBase
// - Provides count of hidden categories for quiz multi-factor system
// REQ0006
//
// RULES:
// - Uses pb.collection().getList() with filter for hidden records
// - Returns Promise<number> with count of hidden records
// - Includes error handling (returns 0 on error)
// - Collection ID defined in COL_QUIZ_MF_CATEGORIES constant
import { COL_QUIZ_MF_CATEGORIES } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// - Counts visible Quiz Multiple-Factor Category records in PocketBase
// - Provides count of visible categories for quiz multi-factor system
//
// RULES:
// - Uses pb.collection().getList() with filter for visible records
// - Returns Promise<number> with count of visible records
// - Includes error handling (returns 0 on error)
// - Collection ID defined in COL_QUIZ_MF_CATEGORIES constant
// REQ0006
import { COL_QUIZ_MF_CATEGORIES } from '@/constants';

View File

@@ -1,3 +1,12 @@
// PURPOSE:
// - Updates an existing Quiz Multiple-Factor Category record in PocketBase
// - Handles modifications to category records in quiz multi-factor system
//
// RULES:
// - Uses pb.collection().update() without error handling (errors handled by caller)
// - Requires valid record ID and CreateFormProps as input
// - Returns Promise<RecordModel> with updated record
// - Collection ID defined in COL_QUIZ_MF_CATEGORIES constant
import { COL_QUIZ_MF_CATEGORIES } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,6 +1,13 @@
// api method for crate student record
//
// PURPOSE:
// Create a new student record in the database
//
// RULES:
// TBA
// 1. Uses PocketBase collection COL_USER_METAS
// 2. Input data must conform to CreateFormProps type
// 3. Returns Promise<RecordModel> from PocketBase
// 4. Automatically sets role to 'student'
//
import { COL_USER_METAS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,14 @@
//
// PURPOSE:
// Delete a student record from the database by ID
//
// RULES:
// 1. Uses PocketBase collection COL_USER_METAS
// 2. Requires valid student ID as input
// 3. Returns Promise<boolean> indicating deletion success
// 4. Does not verify if record exists before deletion
//
import { COL_USER_METAS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,14 @@
//
// PURPOSE:
// Count active student records in the database
//
// RULES:
// 1. Uses PocketBase collection COL_USER_METAS with role='student'
// 2. Only counts records with status='active'
// 3. Returns Promise<number> with the count
// 4. Uses PocketBase's getList with filter
//
import { COL_USER_METAS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,3 +1,14 @@
//
// PURPOSE:
// Retrieve all student records from the database
//
// RULES:
// 1. Uses PocketBase collection COL_STUDENTS
// 2. Returns Promise<RecordModel[]> with full list of students
// 3. Accepts optional query parameters via options object
// 4. Uses PocketBase's getFullList method
//
import { pb } from '@/lib/pb';
import { COL_STUDENTS } from '@/constants';
import type { RecordModel } from 'pocketbase';

View File

@@ -1,3 +1,14 @@
//
// PURPOSE:
// Count all student records in the database
//
// RULES:
// 1. Uses PocketBase collection COL_USER_METAS with role='student'
// 2. Returns Promise<number> with total count
// 3. Uses PocketBase's getList with minimal page size for counting
// 4. Includes all statuses (active, pending, blocked)
//
import { pb } from '@/lib/pb';
import { COL_USER_METAS } from '@/constants';

View File

@@ -1,3 +1,14 @@
//
// PURPOSE:
// Count blocked student records in the database
//
// RULES:
// 1. Uses PocketBase collection COL_USER_METAS with role='student'
// 2. Only counts records with status='blocked'
// 3. Returns Promise<number> with the count
// 4. Uses PocketBase's getList with filter
//
import { COL_USER_METAS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,4 +1,12 @@
// src/db/Students/GetById.tsx
//
// PURPOSE:
// Retrieve a single student record by ID from the database
//
// RULES:
// 1. Uses PocketBase collection COL_USER_METAS
// 2. Requires valid student record ID
// 3. Returns Promise<Student> with expanded billingAddress and helloworld
// 4. Transforms DBStudent to Student type
//
import { COL_USER_METAS } from '@/constants';

View File

@@ -1,3 +1,14 @@
//
// PURPOSE:
// Count pending student records in the database
//
// RULES:
// 1. Uses PocketBase collection COL_USER_METAS with role='student'
// 2. Only counts records with status='pending'
// 3. Returns Promise<number> with the count
// 4. Uses PocketBase's getList with filter
//
import { COL_USER_METAS } from '@/constants';
import { pb } from '@/lib/pb';

View File

@@ -1,7 +1,12 @@
// src/db/Students/Helloworld.tsx
// RULES:
// T.B.A.
//
export function helloCustomer(): string {
return 'Hello from Customers module!';
// PURPOSE:
// Provide a simple greeting function for students module
//
// RULES:
// 1. Returns a fixed greeting string
// 2. Outputs 'Hello from Students module!'
//
export function helloStudent(): string {
return 'Hello from Students module!';
}

View File

@@ -1,8 +1,18 @@
// PURPOSE:
// Update student record in database
//
// RULES:
// 1. Uses COL_USER_METAS collection with role='student'
// 2. Requires valid student ID string
// 3. Accepts Partial<EditFormProps> update data
// 4. Returns Promise<RecordModel> with updated record
// 5. Throws error if update fails
import { pb } from '@/lib/pb';
import { COL_CUSTOMERS } from '@/constants';
import { COL_USER_METAS } from '@/constants';
import type { RecordModel } from 'pocketbase';
import type { EditFormProps } from '@/components/dashboard/customer/type.d';
export async function updateCustomer(id: string, data: Partial<EditFormProps>): Promise<RecordModel> {
return pb.collection(COL_CUSTOMERS).update(id, data);
return pb.collection(COL_USER_METAS).update(id, data);
}

Some files were not shown because too many files have changed in this diff Show More