feat(batch-1): multi-role sidebar, video display, certificate layout, upload progress, counselor access
- 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]
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import { ROLE_HOME_ROUTES } from '@/enums'
|
||||
|
||||
// Read by the WordPress site (madresebanoo.ir) to show/hide its "account"
|
||||
// button and link it to the right dashboard, without ever seeing a real
|
||||
// auth token. Must stay in sync with whatever the WP/Elementor side expects
|
||||
// — see the implementation report for the exact contract.
|
||||
const COOKIE_NAME = 'mb_auth_status'
|
||||
const ROOT_DOMAIN = 'madresebanoo.ir'
|
||||
|
||||
const isOnRootDomain = () => {
|
||||
const host = window.location.hostname
|
||||
return host === ROOT_DOMAIN || host.endsWith(`.${ROOT_DOMAIN}`)
|
||||
}
|
||||
|
||||
const cookieAttributes = () => {
|
||||
const attrs = ['Path=/', 'SameSite=Lax']
|
||||
// A Domain=.madresebanoo.ir cookie is only accepted by the browser when the
|
||||
// current page is actually on that domain (prod). On local dev
|
||||
// (127.0.0.1/localhost) we fall back to a host-only cookie so the sync
|
||||
// logic is still exercised, instead of silently failing to set anything.
|
||||
if (isOnRootDomain()) attrs.push(`Domain=.${ROOT_DOMAIN}`)
|
||||
// Secure cookies are dropped by the browser on plain http, which local dev
|
||||
// serves over. Only require it where it can actually work (prod, https).
|
||||
if (window.location.protocol === 'https:') attrs.push('Secure')
|
||||
return attrs
|
||||
}
|
||||
|
||||
const writeCookie = (value, { expire = false } = {}) => {
|
||||
const attrs = cookieAttributes()
|
||||
attrs.push(expire ? 'Max-Age=0' : '') // no Max-Age on set = session cookie
|
||||
// This cookie must be readable by a separate WordPress site with plain JS
|
||||
// (no httpOnly), and needs Domain/SameSite attributes the CookieStore API
|
||||
// doesn't uniformly support yet — document.cookie is the correct tool here.
|
||||
// eslint-disable-next-line unicorn/no-document-cookie
|
||||
document.cookie = [`${COOKIE_NAME}=${value}`, ...attrs].filter(Boolean).join('; ')
|
||||
}
|
||||
|
||||
const dashboardPathFor = async (role) => {
|
||||
try {
|
||||
const { default: router } = await import('@/router')
|
||||
const routeName = ROLE_HOME_ROUTES[role] || 'student-dashboard'
|
||||
return router.resolve({ name: routeName }).path
|
||||
} catch {
|
||||
return '/dashboard'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets mb_auth_status to a non-sensitive JSON blob describing display state
|
||||
* only: `{ loggedIn: true, dashboardPath }`. Never put the access token,
|
||||
* password, or any credential in this cookie.
|
||||
*/
|
||||
export const syncAuthStatusCookie = async (role) => {
|
||||
const dashboardPath = await dashboardPathFor(role)
|
||||
const value = encodeURIComponent(JSON.stringify({ loggedIn: true, dashboardPath }))
|
||||
writeCookie(value)
|
||||
}
|
||||
|
||||
export const clearAuthStatusCookie = () => {
|
||||
writeCookie('', { expire: true })
|
||||
}
|
||||
Reference in New Issue
Block a user