Commit Graph

232 Commits

Author SHA1 Message Date
estifanos
4d87d41e55 feat: add PdfPreviewModal component and integrate into DocumentsTab for centralized PDF viewing 2026-08-19 08:48:50 +00:00
Nati
f97eb68e25 Major 2026-08-19 08:35:28 +00:00
estifanos
58f9dd7668 UI Fixes 2026-08-19 08:32:44 +00:00
Estifo77
c377ddf74a Merge branch 'WorkflowChange' of https://github.com/Tria-plc/emaui into estif-branch-1 2026-08-19 10:23:33 +03:00
nati14575
130082dcc4 Refactor LicenseApplicationPage and RequireSeafarerProfile components
- Updated imports for better readability in LicenseApplicationPage.
- Introduced legacy profile sources for backward compatibility in LicenseApplicationPage.
- Enhanced user profile handling by utilizing accountUser in LicenseApplicationPage.
- Improved application state management in LicenseApplicationPage to include accountUser.
- Refactored RequireSeafarerProfile to check for existing applications and handle navigation accordingly.
- Cleaned up navigation items in PortalLayout for better readability and maintainability.
2026-08-19 09:42:23 +03:00
Nati
d44977cbf3 Remove obsolete test artifacts and error context files for seafarer registration tests 2026-08-19 05:14:43 +00:00
Nati
99eb55c366 feat: enhance location handling and localization; improve fallback mechanisms and unify type definitions 2026-08-18 14:44:24 +00:00
mihretue
59bb8cefb9 fix(exam): stop print margins doubling up, fitting far fewer questions per page
body had its own 40px padding + max-width:800px for the on-screen preview
tab, which stacked with @page's own margin once actual printing kicked in
— the preview tab never shows @page at all, so it looked like one
continuous page while the real printed output wasted ~150px+ of page
height per side and was capped to 800px wide regardless of the physical
page width. In @media print specifically: padding:0, max-width:none —
@page's margin is the only inset that should apply once printing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 12:59:08 +00:00
mihretue
20b7de2310 fix(exam): pin print footer to the bottom of every page
Footer was just the last thing in document flow, so on a short paper it
landed mid-page instead of at the bottom. position:fixed in @media print
(the standard trick for a repeating page footer) plus a matching @page
bottom margin so it never overlaps the last question's text.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 12:12:00 +00:00
mihretue
cb3f945a2a fix(exam): cap cutting point input at 100 for Percentage evaluation
Matches the new backend rule. Field caps at 100 and shows a hint the
moment Percentage is selected, instead of letting you type 150 and only
finding out later.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 12:02:45 +00:00
mihretue
df9db6a36e feat(question): add CHOICE options inline while creating, not after
Create a CHOICE question and the options fields were hidden behind a
'save first' message — had to save, then reopen via Edit, to actually add
options. Added an inline options editor (local state, same bilingual
fields/correct-checkbox as the existing edit-mode one) directly in the
create form. On submit: create the question, then immediately call
setOptions with the drafted options using the new question's id — one
action from the user's point of view, two API calls under the hood.
Edit mode is unchanged, still uses the existing QuestionOptionsEditor
against the real question id.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 12:00:15 +00:00
mihretue
ae3af7777e fix(exam,result,question): kebab-icon action menus, status change as a picker
Two follow-ups on the dropdown-actions pass:
- All four action menus (exams, results, questions, candidates panel) now
  trigger off a plain three-dot icon button instead of a text 'Actions'
  button with a chevron.
- Exam status change no longer lists all six statuses flat in the dropdown
  (bad UX, looked like six always-visible options). 'Status' is now one
  menu item that opens a small picker modal (current status + a Select +
  Update) rather than the full edit form.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 11:46:16 +00:00
mihretue
80db201676 fix(exam,result): collapse row actions into a dropdown menu everywhere
Same treatment as the questions table, applied consistently: exams list,
exam results list, and the exam-detail candidates panel all now show a
single Actions button opening a dropdown instead of a row of inline
buttons/icons. Also fixes the exams list's action column header, which was
rendering the literal untranslated key ('exam.columns.actions') — missing
a fallback string, same pattern already used elsewhere in this file.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 11:40:13 +00:00
mihretue
3ca5c342c3 fix(question): collapse row actions into a dropdown menu
Matches the exams table's action pattern — a single Actions button opening
a menu, instead of a row of inline buttons/icons that got crowded once a
question had submit/approve/reject/retire/edit/delete all applicable at
once.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 11:32:42 +00:00
estifanos
cb19928bde UI fixes 2026-08-18 10:41:44 +00:00
estifanos
5897e73442 feat: add status filtering and display to medical and sea service verification queues 2026-08-18 10:37:57 +00:00
estifanos
de0dcbfbe8 feat: add workflow profiles to restrict status filtering and sync queue counts by license type 2026-08-18 10:07:22 +00:00
estifanos
2d91092a6b refactor: remove VesselRegistrationHeadDashboardPage and associated navigation links 2026-08-18 09:54:13 +00:00
estifanos
7e19ce9cc9 Revert "mock data for test"
This reverts commit 02b9c73caf.
2026-08-18 09:38:54 +00:00
estifanos
02b9c73caf mock data for test 2026-08-18 09:35:47 +00:00
estifanos
2b95454b4b feat: implement interactive vessel registration reporting page with filters, charts, and data tables 2026-08-18 08:57:51 +00:00
estifanos
1dc82d943a feat: update document review progress tooltip with detailed counts and formatting 2026-08-18 07:46:51 +00:00
estifanos
3d508acc41 feat: implement 18+ age validation, enforce document review completion for approvals, and refactor DecisionBar UI 2026-08-18 07:43:48 +00:00
Estifo77
6a717eb761 Merge branch 'WorkflowChange' of https://github.com/Tria-plc/emaui into estif-branch-1 2026-08-18 09:56:16 +03:00
mihretue
f0443b84b1 fix(exam): lock the exam form to CHOICE when administration is Online
Matches the new backend rule (online_exam_requires_choice_form) — picking
Online in the exam form now auto-sets Form to Choice and disables that
field with an explanatory hint, instead of letting the user pick Essay
and only finding out at save time.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 17:20:16 +00:00
Nati
c7bd69eecb fix(seafarer): route registration through the application wizard
/seafarer-registration had a page of its own that wrote the profile directly
and created no application at all. A "submitted" registration was therefore
never reviewed, never approved and never numbered — there was nothing for an
officer to open. The shared wizard, the review queue and the approval side
effects all already existed; only the route pointed away from them.

The page is deleted rather than repaired. It was a second wizard maintained
alongside the config-driven one, and the seed already describes every step it
was hand-rolling — including the physical characteristics and medical details
added this release, which it would not have known about. /seafarer-registration
now redirects, so navigation, deep links and the profile gate keep working.

Also adds Configuration -> Number Formats, for the shape of generated seafarer,
seaman book and BTC numbers. The sample is rendered by the server rather than
formatted here, so the preview cannot drift from what an approval will actually
generate, and asking for one never consumes a number.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 14:48:26 +00:00
mihretue
8239d7ebe2 feat(exam,result): quick status action, per-row publish
Two UX gaps found in testing:

- Exams list: changing status (e.g. PENDING -> ACTIVE) required opening the
  full Edit modal for a one-field change. Added a status menu (teal toggle
  icon) directly in the row actions, calling PUT /exams/:id with just
  {status} — the backend DTO was already PartialType, nothing to change
  there.
- Exam Results: publishing required first picking the exam in a page-level
  filter to un-grey the header Publish button — not discoverable, and an
  extra step disconnected from the row you actually care about. Added a
  Publish action directly on any APPROVED result's row, confirm-gated since
  it publishes every approved result for that exam (not just the one row)
  and notifies every candidate. The header filter+button still works too,
  for publishing a batch at once.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 12:20:21 +00:00
mihretue
83d309248d feat(exam): regrade action + stop inviting a re-take on a finished exam
Two fixes surfaced by actual candidate-flow testing:

- Portal 'My registrations' always showed 'Take exam' regardless of whether
  the candidate had already finished — clicking it just hit
  attempt_already_submitted server-side. The registrations/mine response
  now carries the attempt's status; the row shows a Completed/Time expired
  badge once finished, or 'Resume exam' while still in progress, and only
  invites a fresh start when there's genuinely nothing yet.
- Backoffice candidates panel: a Regrade button next to a SUBMITTED/EXPIRED
  sitting, calling the new POST /exam-attempts/:id/regrade — the officer's
  path to the same staff-triggered regrade, no SQL needed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 12:00:45 +00:00
mihretue
e97e12d979 Merge remote-tracking branch 'origin/certficate' into feature/exam-attempt-domain 2026-08-17 11:19:17 +00:00
Estifo77
84e3500352 Merge branch 'certficate' of https://github.com/Tria-plc/emaui into estif-branch-1 2026-08-17 13:16:22 +03:00
mihretue
4a7d36369f fix(exam): print real MCQ options, evaluation-method-aware cutting point check
Print showed blank A/B/C/D fill-in lines for every CHOICE question instead
of the real options — the detail page never fetched option data at all
(GET /exams/:id?i=questions, no nested options), and the print template
hardcoded the blanks regardless. Now requests
?i=questions,questions.options and prints the real option text, falling
back to blank lines only when a question genuinely has none on record.

Also fixed the print-time cutting-point guard: it compared raw point sum
to cutting point regardless of evaluationMethod, wrongly blocking valid
low-point-sum PERCENTAGE papers from printing. Now branches the same way
RecordResultModal's grading preview already does, and surfaces the
matching backend validation error (paper_cannot_reach_cutting_point) added
server-side for the same reason.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 09:43:09 +00:00
mihretue
4f692c6bcf fix(exam): stop Create/Update Exam form from silently failing to submit
Three bugs compounded into a button that looked unwired:

- cuttingPoint carried a native HTML required attribute while sitting on
  the hidden Settings tab (Mantine keeps inactive tab panels mounted with
  display:none). The browser blocked form submission entirely, silently
  - no toast, no error, nothing. Replaced required with withAsterisk and
  moved validation into JS.
- Manual required-field validation never checked type/form/adminMethod/
  evalMethod/cuttingPoint at all, so even without the native block above
  a half-filled Settings tab would silently no-op. Validation now covers
  every required field on both tabs and switches to whichever tab has
  the problem.
- Filling only the English Direction field (leaving Amharic blank) passed
  frontend validation but the backend hard-rejects it, producing a 400
  with a confusing error. Frontend now requires both-or-neither, matching
  the same rule already applied to MCQ options.

Also translates the previously hardcoded validation message in both
locales.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 08:48:32 +00:00
mihretue
84ff644ebb fix(question): show both language fields for MCQ options
Options editor used a single toggle-based bilingual field (BilingualInput)
that swapped English/Amharic in place via a tiny, easy-to-miss button.
Authors were filling English only and never noticing Amharic was empty.

- QuestionOptionsEditor: show separate always-visible English/Amharic
  TextInputs per option instead of the toggle field.
- BilingualInput (shared): for other callers still using the toggle,
  add a tooltip and a red dot indicator when the hidden language is
  empty, so the gap is visible without switching.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 08:26:21 +00:00
estifanos
2341f90107 fix: redirect to home instead of login on auth failure in backoffice and portal stores 2026-08-17 07:09:36 +00:00
estifanos
4a33347853 refactor: redirect to root path instead of login page on logout in Backoffice and Portal layouts 2026-08-17 07:05:28 +00:00
nati14575
c698f381b9 fix(api): update BASE_API_URL to use localhost:3000 for consistency 2026-08-17 09:58:51 +03:00
fitse-yotor
fa7eb3dc5f feat(backoffice): restore Mengestab's seafarer register and wire it up
The approved single-page register -- with the detail modal that shows a
seafarer's full standing -- had been replaced by a three-file grid that
carried no profile view. That is why the seafarer profile appeared
missing from the backoffice entirely.

Restores his page and points it at /seafarer-registry. The list is
served whole and filtered in the browser: the filters are instant facets
over a page-sized list, and a round trip per keystroke would make the
search feel slower than the data it searches.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 07:15:08 +03:00
fitse-yotor
f294f67ced fix(portal,backoffice): six reported issues in registration and the designer
Seafarer and vessel registration were filtered out of the operations
step by `requiresOperatorMode !== false`, so someone registering as a
seafarer or vessel owner landed on an onboarding screen that did not
describe them. Both now appear, grouped apart from the company modes:
declaring "I am a seafarer" is a different kind of statement from "my
company forwards freight".

The designer's preview was gated on the Handlebars source alone, which a
canvas layout does not have until the server compiles it on save -- so
the button was dead for exactly the designs the canvas exists for.

Editing looked broken rather than deliberately read-only: every seeded
template is PUBLISHED, and a published design is immutable because
certificates were issued from it. Says so, and offers the new-version
action that is the way forward.

Reviewing officers saw company, capital and staff tabs on seafarer
certificate applications, because PRESENTATION is keyed by the generic
licence keys and the fifty-odd rank-specific CoC/CoP keys fell through
to the company default. Matched by prefix instead, so a certificate
configured tomorrow gets the right presentation without a code change.

Seaman book and BTC are wired to the newly seeded licence types and no
longer marked "soon".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 22:21:00 +03:00
fitse-yotor
c58a727a96 Merge branch 'feature/seaman' of https://github.com/Tria-plc/emaui into certficate 2026-08-15 12:44:39 +03:00
fitse-yotor
0ac75669d4 feat: add ExamStageActions component for exam fee handling
- Implemented ExamStageActions component to manage actions related to exam booking and payment based on application status.
- Added mock-base-query for development, providing a partial mock backend for various API endpoints.
- Introduced mock-data for simulating responses in the mock-base-query, covering profiles, vessels, applications, licenses, exams, and notifications.
2026-08-15 11:51:14 +03:00
Estifo77
fc2730f60b loader roleout on backoffice 2026-08-15 11:33:28 +03:00
Estifo77
6330c9ea55 applying loader on pages 2026-08-15 11:25:30 +03:00
estifanos
51cf0fbd17 UI landing page route fix 2026-08-15 07:02:37 +00:00
estifanos
f31e75c3de feat: implement PageLoader component and register maritime loader as the default theme loader 2026-08-14 11:35:34 +00:00
estifanos
7c79f4d644 feat: implement useAuthToken hook for consistent auth token retrieval across components.comment from nati 2026-08-14 09:27:37 +00:00
estifanos
e0b3a4887a feat: add internationalization support for auth components and pages, including translations for Amharic and English 2026-08-14 07:54:30 +00:00
estifanos
d6b813b697 feat: add landing page copy and styles for English and Amharic versions
- Introduced `landing-copy.ts` containing text for the public landing page, supporting both English and Amharic languages.
- Added `landing.css` for styling the landing page, ensuring scoped styles to prevent conflicts with other app styles.
- Implemented smooth scrolling and animations for a better user experience.
2026-08-14 07:20:42 +00:00
mihretue
14b5bb83f9 feat(question): MCQ options authoring editor (Phase 2 domain foundation)
Backend now supports MCQ options + a separate answer-key table
(PUT /questions/:id/options). Frontend side of that, authoring only —
no candidate exam-taking UI.

- Question type gains options?: QuestionOption[] (no correctness field —
  the API never returns one, matching the backend's split-table design)
- New question-api hooks: getQuestionWithOptions, setQuestionOptions
- New QuestionOptionsEditor component (separate file, not inlined into
  QuestionPage) — add/remove/reorder options, mark correct, bilingual text
- Wired into the question edit form, shown only for an existing CHOICE
  question (options attach to an id, matching the backend's replace
  endpoint)
- en/am i18n strings for the new editor

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 19:28:03 +00:00
mihretue
d98d6a71fe fix(result): gate record/save buttons behind RECORD_EXAM_RESULT
Record Result (POST /results) and the detail-modal Save (PUT /results/:id)
had no RequirePermission gate, unlike every other action on this page —
both routes are backend-guarded (RECORD_EXAM_RESULT, or
RECORD_EXAM_RESULT|MODERATE_EXAM_RESULT for the update), the buttons just
never mirrored it client-side.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 17:17:14 +00:00
Nati
6852fc86c6 feat: implement permission-based access control across various pages and components
- 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.
2026-08-13 12:58:11 +00:00