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:
@@ -37,12 +37,23 @@
|
||||
<SvgIcon name="warning" :size="22" color="#b8b8b8" class="ssd__text-icon" />
|
||||
<p class="ssd__text-body">{{ session.text }}</p>
|
||||
</div>
|
||||
<div v-else-if="contentKind === 'embed'" class="ssd__embed">
|
||||
<iframe
|
||||
class="ssd__embed-frame"
|
||||
:srcdoc="session.embedCode"
|
||||
sandbox="allow-scripts allow-popups allow-forms allow-presentation"
|
||||
allow="autoplay; fullscreen; picture-in-picture"
|
||||
allowfullscreen
|
||||
loading="lazy"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="contentKind === 'link'" class="ssd__link">
|
||||
<div class="ssd__link__box">
|
||||
<span>https://link</span>
|
||||
<span>{{ session?.link || 'لینکی ثبت نشده است' }}</span>
|
||||
<SvgIcon name="link" :size="22" class="ssd__link-icon" />
|
||||
</div>
|
||||
<BaseButton text="ورود به جلسه " custom-class="ssd__link-btn">
|
||||
<BaseButton text="ورود به جلسه " custom-class="ssd__link-btn" @click="openSessionLink">
|
||||
<template #appendIcon>
|
||||
<SvgIcon name="arrow-left" :size="18" color="#fff" />
|
||||
</template>
|
||||
@@ -129,13 +140,17 @@ const homework = computed(() => (homeworksData.value?.data ?? [])[0] ?? null)
|
||||
const contentKind = computed(() => {
|
||||
const s = session.value
|
||||
if (!s) return ''
|
||||
if (s.type === 'online') return 'link'
|
||||
if (s.videoUrl) return 'link'
|
||||
if (s.type === 'online') return s.embedCode?.trim() ? 'embed' : 'link'
|
||||
if (s.videoUrl) return 'video'
|
||||
if (s.audioUrl) return 'audio'
|
||||
if (s.text) return 'text'
|
||||
return ''
|
||||
})
|
||||
|
||||
const openSessionLink = () => {
|
||||
if (session.value?.link) window.open(session.value.link, '_blank', 'noopener,noreferrer')
|
||||
}
|
||||
|
||||
const homeworkAudio = ref(null)
|
||||
const homeworkImage = ref(null)
|
||||
const errors = reactive({ audio: '', image: '' })
|
||||
@@ -260,6 +275,18 @@ const onSubmit = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
&__embed {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__embed-frame {
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
border: 0;
|
||||
border-radius: 1rem;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
&__link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user