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>
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.
- 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]