New portal feature apps/portal/src/app/features/exam-attempt/, following
the repo's existing folder convention (pages/<Page>/index.tsx, components/,
types/, hooks/ — matches the payments feature's hooks/ precedent):
- types/exam-attempt.ts — response/local-state shapes
- hooks/useExamAttempt.ts — all API orchestration: load (registration +
attempt), start/resume, per-question autosave (immediate on MCQ select,
debounced+flushed-on-navigation for essay text), local countdown seeded
from the server's serverTime/remainingSeconds, submit, and resync from
the server whenever a write is refused as expired/already-submitted
- components/ExamInstructions, ExamTimer, ExamQuestionNav,
ExamQuestionDisplay, ExamCompletion — one concern per file, not a single
page dump
- pages/ExamAttemptPage — thin view layer over the hook
Flow: /exams (existing) gets a 'Take exam' action on eligible registration
rows → /exams/:examId/take, which shows instructions before an attempt
exists, the live exam screen while IN_PROGRESS, and a no-score completion
screen once SUBMITTED/EXPIRED (never fabricates a result — grading
doesn't exist yet).
Security note: RequirePermission on the route and disabled inputs after
local timeout are UI conveniences only. Every save/submit is independently
re-checked by the backend's ownership + applyExpiry() on each call: a
client that skipped the UI entirely and hit the API directly would be
bound by exactly the same rules.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Added RequirePermission component to manage access based on user permissions.
- Integrated permission checks in MySeaRecordsPage, SeafarerRegistrationPage, VesselRegistrationPage, WaiverPage, and PortalLayout.
- Updated router to enforce permissions for specific routes.
- Introduced PORTAL_PERMISSIONS and LICENSE_PERMISSIONS constants for consistent permission management.
- Enhanced usePermissions hook to fetch permissions from the server and determine access rights.
- Refactored UI components to conditionally render based on user permissions, improving security and user experience.
Resolved by unifying on the lib/data AdvancedTable (PR #10) as the canonical
table component: kept its API plus teammate i18n/feature work, kept the
folder-per-table structure (index.tsx + columns.tsx + actions.tsx) across all
27 tables, removed the parallel lib/table implementation, and fixed
pre-existing compile breaks in ExamDetailPage/QuestionAssigner/RecordResultModal.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(waiver): implement waiver page with application tracking and letter download feature
feat(ui): introduce AdvancedTable component for enhanced table functionality across the application
chore: update package-lock.json to remove unnecessary dependencies
- Added useLocalized hook to provide a stable function for retrieving bilingual values based on the current language.
- Updated various components across the portal and backoffice to utilize the new useLocalized hook for consistent bilingual label rendering.
- Refactored localized function in licensing.helpers to handle empty Amharic strings correctly.
- Enhanced localization handling in LicenseApplicationPage, ProfilePage, and other components to ensure proper language switching.
- Added `useDateDisplayer` hook and `dateDisplayer` function to format dates consistently based on the user's language.
- Updated multiple components and pages in both backoffice and portal applications to utilize the new date display functionality, ensuring proper formatting for dates in lists, tables, and detail views.
- Introduced Ethiopian date formatting for Amharic language support.
- Refactored date handling in components such as ExamAppealsPage, ResultPage, SeafarerRegistryPage, and others to improve localization and user experience.
- Added a new CSS module for MyApplicationsPage to style the segmented tab bar and clickable tiles.
- Implemented tab navigation for applications, licences, and apply sections, improving user experience.
- Introduced filtering options for applications, including search, status, and date range.
- Enhanced the display of application and licence information with new components and improved layout.
- Updated translations for the new features in both Amharic and English.
fix(layouts): import baseApi in BackofficeLayout and PortalLayout for API state management
refactor(auth): remove clearCurrentProfile call on logout and improve cookie removal logic
chore(auth-storage): enhance cookie management with secure and sameSite attributes, and streamline cleanup process
- Implement saveMyAddress mutation for updating user addresses.
- Enhance address validation schema with additional fields.
- Add error handling for location loading in LocationPicker.
- Update translations for loading errors in English and Amharic.
- Introduce phone number validation for Ethiopian formats.
- Refactor AddressFormContent to accommodate new address structure.