ConfirmModal mounts once at the app root, so its Teleport anchor in
<body> is created before page-level modals like TermDetailsModal.
With an identical z-index, later-mounted modals ended up stacking on
top of it, hiding the confirmation prompt (e.g. confirming the new
remove-student-from-term action). Adds a configurable zIndex prop to
BasicModal and gives ConfirmModal a higher value so it always shows
on top regardless of mount order.
The mutation/API plumbing already existed (useRemoveAdminTermStudentMutation)
but no UI ever called it. Adds a delete action to each row in the term
details modal's seminarians list, with a confirmation prompt.
The submit button only disabled after Vue re-rendered on mutation
pending state, leaving a window where a fast double-click fired
onSubmit twice — creating two exam rows, with the losing request
usually failing to attach its questions (an "empty" duplicate exam).
When a user has both student and missionary roles, common items
(dashboard, education, ticket) appeared twice. Added dedupeKey to
each item; buildMergedMenuItems now skips items whose key was already
added by an earlier role — the primary role's version always wins.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Admin can view, issue, and delete certificates. Student certificate
query now normalises the response shape (works with both paginated
and non-paginated API responses).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
UsersTable now shows all role labels joined (not just the first role),
and its CSS badge class is based on the primary role. UserFormPage
uses a multi-select for roles instead of a single-select, and the
form validation requires at least one role. TermItem layout fix for
inactive badge alignment.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Copyright.vue / AuthCopyright.vue: change link from mugweb.ir to madresebanoo.ir
- SelectField.vue: add min-width:0 to prevent flex overflow in narrow layouts
- useRedirectAfterLogin: check roles array (multi-role support) instead of single role
- StudentRegisterPage: show block reason when user's status is blocked
- http.js: only clear session on 401 if a token already existed (login
form 401 should not trigger logout); clear via authStore so WordPress
cookie is also cleaned up
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The list query returned the raw paginated payload unmapped, so
current/ended filtering and pagination metadata didn't work; align it
with the same coverUrl fallback the detail query already used.
Admin CRUD page for service types, plus wiring the student "request
service" form's category select to the real list instead of a
hardcoded pair of options.
The admin course form sent a stray upload id (imageId/uploadId) that
didn't match any field the API accepts; the API expects cover_media_id
with the media id returned from the upload endpoint. Also switch course
displays to the coverUrl field the API actually returns.
SessionFormPage now passes { formData, onUploadProgress } to mutateAsync
for progress tracking. Update uploadMediaMutationFn to destructure the
object and forward onUploadProgress to apiUploadMedia; update apiUploadMedia
to accept and pass the callback to axios.
[batch-1-hotfix]
- roleMenuItems.js: merged menu builder that unions items from all user roles
(student + missionary, student + counselor, etc.) additively
- auth store: expose `roles` array in addition to singular `role`; wire in
WordPress auth-status cookie sync so the public site can show/hide the
account button
- router guards: use roles.includes() instead of role === for multi-role access
- layouts (Student/Counselor/Missionary): delegate menuItems to
buildMergedMenuItems so dual-role users see sections from both roles
- StudentSessionDetailsPage: contentKind now returns 'video' (not 'link')
when session.videoUrl is set; adds embed iframe branch for online sessions
- CertificateItem.vue: fix CSS order/alignment for desktop + mobile layout
- StudentCertificatesPage.vue: map backend payload fields to component props
with Jalaali date formatting
- SessionFormPage: upload progress bar (%) during video uploads; embed_code
textarea for online sessions (frontend-only; dormant until batch-2 backend
migration is deployed)
- wp-sync/auth-status-cookie.js: cookie helper for WordPress login-state sync
[batch-1-low-risk]