mirror of
https://github.com/OpenSquawk/OpenSquawk
synced 2026-08-09 19:16:02 +08:00
Add previous navigation and mission lesson toggle
This commit is contained in:
@@ -694,7 +694,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else class="module-content">
|
<div v-else class="module-content">
|
||||||
<div class="module-overview">
|
<div
|
||||||
|
class="module-overview"
|
||||||
|
:class="{
|
||||||
|
'is-expanded': moduleOverviewHoldOpen,
|
||||||
|
'is-active': moduleOverviewIsOpen
|
||||||
|
}"
|
||||||
|
@mouseenter="handleModuleOverviewHover(true)"
|
||||||
|
@mouseleave="handleModuleOverviewHover(false)"
|
||||||
|
@focusin="handleModuleOverviewFocusIn"
|
||||||
|
@focusout="handleModuleOverviewFocusOut"
|
||||||
|
>
|
||||||
<div v-if="current" class="module-overview-header">
|
<div v-if="current" class="module-overview-header">
|
||||||
<div class="module-overview-meta">
|
<div class="module-overview-meta">
|
||||||
<div>
|
<div>
|
||||||
@@ -703,22 +713,34 @@
|
|||||||
<h3 class="module-overview-title">{{ current.title }}</h3>
|
<h3 class="module-overview-title">{{ current.title }}</h3>
|
||||||
<p class="module-overview-sub">{{ current.subtitle }}</p>
|
<p class="module-overview-sub">{{ current.subtitle }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="module-overview-tools">
|
||||||
class="module-overview-progress"
|
<button
|
||||||
role="progressbar"
|
class="module-overview-toggle"
|
||||||
aria-label="Mission progress"
|
type="button"
|
||||||
:aria-valuenow="pct(current.id)"
|
@click="toggleModuleOverview"
|
||||||
aria-valuemin="0"
|
:aria-expanded="moduleOverviewIsOpen ? 'true' : 'false'"
|
||||||
aria-valuemax="100"
|
:aria-controls="moduleOverviewTrackId"
|
||||||
>
|
>
|
||||||
<span class="module-overview-progress-label">Progress</span>
|
<span class="module-overview-toggle-label">Mission lessons</span>
|
||||||
<div class="module-overview-progress-bar">
|
<v-icon size="16" class="module-overview-toggle-icon">mdi-chevron-down</v-icon>
|
||||||
<div class="module-overview-progress-fill" :style="{ width: pct(current.id) + '%' }"></div>
|
</button>
|
||||||
|
<div
|
||||||
|
class="module-overview-progress"
|
||||||
|
role="progressbar"
|
||||||
|
aria-label="Mission progress"
|
||||||
|
:aria-valuenow="pct(current.id)"
|
||||||
|
aria-valuemin="0"
|
||||||
|
aria-valuemax="100"
|
||||||
|
>
|
||||||
|
<span class="module-overview-progress-label">Progress</span>
|
||||||
|
<div class="module-overview-progress-bar">
|
||||||
|
<div class="module-overview-progress-fill" :style="{ width: pct(current.id) + '%' }"></div>
|
||||||
|
</div>
|
||||||
|
<span class="module-overview-progress-meta">{{ doneCount(current.id) }}/{{ current.lessons.length }} lessons</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="module-overview-progress-meta">{{ doneCount(current.id) }}/{{ current.lessons.length }} lessons</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="lesson-track" ref="lessonTrack">
|
<div class="lesson-track" ref="lessonTrack" :id="moduleOverviewTrackId">
|
||||||
<div class="lesson-grid">
|
<div class="lesson-grid">
|
||||||
<button
|
<button
|
||||||
v-for="l in current.lessons"
|
v-for="l in current.lessons"
|
||||||
@@ -977,6 +999,15 @@
|
|||||||
<div v-else class="lesson-actions-hint">
|
<div v-else class="lesson-actions-hint">
|
||||||
Last lesson in this mission.
|
Last lesson in this mission.
|
||||||
</div>
|
</div>
|
||||||
|
<button
|
||||||
|
class="btn ghost lesson-actions-prev"
|
||||||
|
type="button"
|
||||||
|
:disabled="!hasPreviousAction"
|
||||||
|
@click="goToPreviousLesson"
|
||||||
|
>
|
||||||
|
<v-icon size="18">mdi-arrow-left</v-icon>
|
||||||
|
{{ previousActionLabel }}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="lesson-actions-buttons">
|
<div class="lesson-actions-buttons">
|
||||||
<button class="btn soft" type="button" @click="repeatLesson">
|
<button class="btn soft" type="button" @click="repeatLesson">
|
||||||
@@ -1292,6 +1323,13 @@ const flightPlanError = ref<string | null>(null)
|
|||||||
const simbriefForm = reactive({ userId: '', loading: false })
|
const simbriefForm = reactive({ userId: '', loading: false })
|
||||||
const simbriefPlanMeta = ref<{ callsign: string; route: string } | null>(null)
|
const simbriefPlanMeta = ref<{ callsign: string; route: string } | null>(null)
|
||||||
const lessonTrack = ref<HTMLElement | null>(null)
|
const lessonTrack = ref<HTMLElement | null>(null)
|
||||||
|
const moduleOverviewExpanded = ref(false)
|
||||||
|
const moduleOverviewHovering = ref(false)
|
||||||
|
const moduleOverviewFocusWithin = ref(false)
|
||||||
|
const isHoverCapable = ref(false)
|
||||||
|
const moduleOverviewTrackId = computed(() => current.value ? `module-${current.value.id}-lesson-track` : 'module-lesson-track')
|
||||||
|
const moduleOverviewHoldOpen = computed(() => !isHoverCapable.value || moduleOverviewExpanded.value)
|
||||||
|
const moduleOverviewIsOpen = computed(() => moduleOverviewHoldOpen.value || moduleOverviewHovering.value || moduleOverviewFocusWithin.value)
|
||||||
type ManualSection = 'departure' | 'arrival' | 'procedures'
|
type ManualSection = 'departure' | 'arrival' | 'procedures'
|
||||||
const manualSectionsOpen = reactive<Record<ManualSection, boolean>>({
|
const manualSectionsOpen = reactive<Record<ManualSection, boolean>>({
|
||||||
departure: false,
|
departure: false,
|
||||||
@@ -2237,6 +2275,46 @@ const showSettings = ref(false)
|
|||||||
const api = useApi()
|
const api = useApi()
|
||||||
|
|
||||||
const isClient = typeof window !== 'undefined'
|
const isClient = typeof window !== 'undefined'
|
||||||
|
let hoverCapabilityCleanup: (() => void) | null = null
|
||||||
|
|
||||||
|
function resetModuleOverviewExpansion() {
|
||||||
|
moduleOverviewHovering.value = false
|
||||||
|
moduleOverviewFocusWithin.value = false
|
||||||
|
moduleOverviewExpanded.value = !isHoverCapable.value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (import.meta.client) {
|
||||||
|
const mediaQuery = window.matchMedia('(hover: hover)')
|
||||||
|
const applyHoverCapability = (matches: boolean) => {
|
||||||
|
isHoverCapable.value = matches
|
||||||
|
resetModuleOverviewExpansion()
|
||||||
|
}
|
||||||
|
applyHoverCapability(mediaQuery.matches)
|
||||||
|
const handleHoverCapabilityChange = (event: MediaQueryListEvent) => {
|
||||||
|
applyHoverCapability(event.matches)
|
||||||
|
}
|
||||||
|
if (typeof mediaQuery.addEventListener === 'function') {
|
||||||
|
mediaQuery.addEventListener('change', handleHoverCapabilityChange)
|
||||||
|
hoverCapabilityCleanup = () => {
|
||||||
|
mediaQuery.removeEventListener('change', handleHoverCapabilityChange)
|
||||||
|
}
|
||||||
|
} else if (typeof mediaQuery.addListener === 'function') {
|
||||||
|
mediaQuery.addListener(handleHoverCapabilityChange)
|
||||||
|
hoverCapabilityCleanup = () => {
|
||||||
|
mediaQuery.removeListener(handleHoverCapabilityChange)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch([panel, moduleStage], ([panelValue, stage]) => {
|
||||||
|
if (panelValue !== 'module' || stage !== 'lessons') {
|
||||||
|
resetModuleOverviewExpansion()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(() => current.value?.id, () => {
|
||||||
|
resetModuleOverviewExpansion()
|
||||||
|
})
|
||||||
|
}
|
||||||
const defaultCfg = createDefaultLearnConfig()
|
const defaultCfg = createDefaultLearnConfig()
|
||||||
const cfg = ref<LearnConfig>({...defaultCfg})
|
const cfg = ref<LearnConfig>({...defaultCfg})
|
||||||
audioReveal.value = !cfg.value.audioChallenge
|
audioReveal.value = !cfg.value.audioChallenge
|
||||||
@@ -2431,6 +2509,10 @@ if (isClient) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
|
if (hoverCapabilityCleanup) {
|
||||||
|
hoverCapabilityCleanup()
|
||||||
|
hoverCapabilityCleanup = null
|
||||||
|
}
|
||||||
if (persistTimer) {
|
if (persistTimer) {
|
||||||
clearTimeout(persistTimer)
|
clearTimeout(persistTimer)
|
||||||
persistTimer = null
|
persistTimer = null
|
||||||
@@ -2551,6 +2633,20 @@ const nextLessonMeta = computed(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const prevLessonMeta = computed(() => {
|
||||||
|
if (!current.value || !activeLesson.value) return null
|
||||||
|
const lessons = current.value.lessons
|
||||||
|
const activeId = activeLesson.value.id
|
||||||
|
const idx = lessons.findIndex(lesson => lesson.id === activeId)
|
||||||
|
if (idx <= 0) return null
|
||||||
|
const previousLesson = lessons[idx - 1]
|
||||||
|
return {
|
||||||
|
lesson: previousLesson,
|
||||||
|
position: idx,
|
||||||
|
total: lessons.length
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const nextMissionMeta = computed(() => {
|
const nextMissionMeta = computed(() => {
|
||||||
if (!current.value) return null
|
if (!current.value) return null
|
||||||
const currentIndex = modules.value.findIndex(module => module.id === current.value?.id)
|
const currentIndex = modules.value.findIndex(module => module.id === current.value?.id)
|
||||||
@@ -2569,12 +2665,37 @@ const nextMissionMeta = computed(() => {
|
|||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const prevMissionMeta = computed(() => {
|
||||||
|
if (!current.value) return null
|
||||||
|
const currentIndex = modules.value.findIndex(module => module.id === current.value?.id)
|
||||||
|
if (currentIndex <= 0) return null
|
||||||
|
for (let idx = currentIndex - 1; idx >= 0; idx--) {
|
||||||
|
const module = modules.value[idx]
|
||||||
|
if (isModuleUnlocked(module.id)) {
|
||||||
|
return {
|
||||||
|
module,
|
||||||
|
position: idx + 1,
|
||||||
|
total: modules.value.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
|
||||||
const nextActionLabel = computed(() => {
|
const nextActionLabel = computed(() => {
|
||||||
if (nextLessonMeta.value) return 'Next lesson'
|
if (nextLessonMeta.value) return 'Next lesson'
|
||||||
if (nextMissionMeta.value) return 'Next mission'
|
if (nextMissionMeta.value) return 'Next mission'
|
||||||
return 'Next lesson'
|
return 'Next lesson'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const previousActionLabel = computed(() => {
|
||||||
|
if (prevLessonMeta.value) return 'Previous lesson'
|
||||||
|
if (prevMissionMeta.value) return 'Previous module'
|
||||||
|
return 'Previous lesson'
|
||||||
|
})
|
||||||
|
|
||||||
|
const hasPreviousAction = computed(() => Boolean(prevLessonMeta.value || prevMissionMeta.value))
|
||||||
|
|
||||||
watch(activeLesson, lesson => {
|
watch(activeLesson, lesson => {
|
||||||
if (lesson) {
|
if (lesson) {
|
||||||
if (moduleStage.value === 'lessons') {
|
if (moduleStage.value === 'lessons') {
|
||||||
@@ -2650,10 +2771,62 @@ function rollScenario(clear = false) {
|
|||||||
queueAutoSay()
|
queueAutoSay()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleModuleOverview() {
|
||||||
|
if (!isHoverCapable.value) return
|
||||||
|
moduleOverviewExpanded.value = !moduleOverviewExpanded.value
|
||||||
|
if (moduleOverviewExpanded.value) {
|
||||||
|
moduleOverviewHovering.value = false
|
||||||
|
void nextTick(() => {
|
||||||
|
const activeId = activeLesson.value?.id
|
||||||
|
const selector = activeId ? `[data-lesson='${activeId}']` : 'button.lesson'
|
||||||
|
const target = lessonTrack.value?.querySelector<HTMLElement>(selector)
|
||||||
|
target?.focus()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
moduleOverviewHovering.value = false
|
||||||
|
moduleOverviewFocusWithin.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleModuleOverviewHover(state: boolean) {
|
||||||
|
if (!isHoverCapable.value) return
|
||||||
|
moduleOverviewHovering.value = state
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleModuleOverviewFocusIn(event: FocusEvent) {
|
||||||
|
if (!isHoverCapable.value) return
|
||||||
|
const target = event.target as HTMLElement | null
|
||||||
|
if (target?.classList?.contains('module-overview-toggle') && !moduleOverviewExpanded.value) {
|
||||||
|
moduleOverviewFocusWithin.value = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
moduleOverviewFocusWithin.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleModuleOverviewFocusOut(event: FocusEvent) {
|
||||||
|
if (!isHoverCapable.value) return
|
||||||
|
const currentTarget = event.currentTarget as HTMLElement | null
|
||||||
|
const related = event.relatedTarget as Node | null
|
||||||
|
if (currentTarget && related && currentTarget.contains(related)) return
|
||||||
|
moduleOverviewFocusWithin.value = false
|
||||||
|
}
|
||||||
|
|
||||||
function repeatLesson() {
|
function repeatLesson() {
|
||||||
rollScenario(true)
|
rollScenario(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function goToPreviousLesson() {
|
||||||
|
const meta = prevLessonMeta.value
|
||||||
|
if (meta) {
|
||||||
|
activeLesson.value = meta.lesson
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const previousMission = prevMissionMeta.value
|
||||||
|
if (previousMission) {
|
||||||
|
quickContinue(previousMission.module.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function goToNextLesson() {
|
function goToNextLesson() {
|
||||||
const meta = nextLessonMeta.value
|
const meta = nextLessonMeta.value
|
||||||
if (meta) {
|
if (meta) {
|
||||||
@@ -4280,9 +4453,15 @@ onMounted(() => {
|
|||||||
background:
|
background:
|
||||||
radial-gradient(420px 260px at -10% -20%, color-mix(in srgb, var(--accent) 22%, transparent), transparent 70%),
|
radial-gradient(420px 260px at -10% -20%, color-mix(in srgb, var(--accent) 22%, transparent), transparent 70%),
|
||||||
linear-gradient(150deg, color-mix(in srgb, var(--bg2) 82%, transparent), color-mix(in srgb, var(--text) 6%, transparent));
|
linear-gradient(150deg, color-mix(in srgb, var(--bg2) 82%, transparent), color-mix(in srgb, var(--text) 6%, transparent));
|
||||||
gap: 28px;
|
--module-overview-gap: 28px;
|
||||||
|
--lesson-track-max-height: 400px;
|
||||||
|
--lesson-track-opacity: 1;
|
||||||
|
--lesson-track-pointer-events: auto;
|
||||||
|
--lesson-track-padding-bottom: 12px;
|
||||||
|
--lesson-track-offset: 0px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
gap: var(--module-overview-gap);
|
||||||
border-radius: 28px;
|
border-radius: 28px;
|
||||||
isolation: isolate;
|
isolation: isolate;
|
||||||
}
|
}
|
||||||
@@ -4328,6 +4507,50 @@ onMounted(() => {
|
|||||||
max-width: 520px;
|
max-width: 520px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.module-overview-tools {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
|
gap: 14px;
|
||||||
|
min-width: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-overview-toggle {
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 6px 16px;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
|
||||||
|
background: color-mix(in srgb, var(--bg2) 82%, transparent);
|
||||||
|
color: color-mix(in srgb, var(--t3) 30%, white 5%);
|
||||||
|
font-size: 12px;
|
||||||
|
letter-spacing: .08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background .2s ease, color .2s ease, border-color .2s ease, box-shadow .2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-overview-toggle:hover {
|
||||||
|
background: color-mix(in srgb, var(--accent) 18%, transparent);
|
||||||
|
color: color-mix(in srgb, var(--accent) 85%, white 10%);
|
||||||
|
border-color: color-mix(in srgb, var(--accent) 42%, transparent);
|
||||||
|
box-shadow: 0 10px 24px rgba(2, 6, 23, .35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-overview-toggle:focus-visible {
|
||||||
|
outline: 2px solid color-mix(in srgb, var(--accent) 72%, white 12%);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-overview-toggle-label {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-overview-toggle-icon {
|
||||||
|
transition: transform .25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
.module-overview-chip {
|
.module-overview-chip {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -4393,6 +4616,17 @@ onMounted(() => {
|
|||||||
color: color-mix(in srgb, var(--t3) 70%, transparent);
|
color: color-mix(in srgb, var(--t3) 70%, transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.module-overview.is-active .module-overview-toggle {
|
||||||
|
background: color-mix(in srgb, var(--accent) 18%, transparent);
|
||||||
|
color: color-mix(in srgb, var(--accent) 85%, white 10%);
|
||||||
|
border-color: color-mix(in srgb, var(--accent) 42%, transparent);
|
||||||
|
box-shadow: 0 10px 24px rgba(2, 6, 23, .35);
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-overview.is-active .module-overview-toggle-icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
.module-detail {
|
.module-detail {
|
||||||
border-color: color-mix(in srgb, var(--text) 22%, transparent);
|
border-color: color-mix(in srgb, var(--text) 22%, transparent);
|
||||||
background: linear-gradient(160deg, color-mix(in srgb, var(--text) 6%, transparent) 0%, color-mix(in srgb, var(--bg2) 70%, transparent) 100%);
|
background: linear-gradient(160deg, color-mix(in srgb, var(--text) 6%, transparent) 0%, color-mix(in srgb, var(--bg2) 70%, transparent) 100%);
|
||||||
@@ -4407,7 +4641,8 @@ onMounted(() => {
|
|||||||
|
|
||||||
.lesson-track {
|
.lesson-track {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding-bottom: 12px;
|
overflow-y: hidden;
|
||||||
|
padding-bottom: var(--lesson-track-padding-bottom, 12px);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding-left: 6px;
|
padding-left: 6px;
|
||||||
padding-right: 6px;
|
padding-right: 6px;
|
||||||
@@ -4415,6 +4650,37 @@ onMounted(() => {
|
|||||||
mask-image: linear-gradient(to right, transparent, rgba(0, 0, 0, .9) 20%, rgba(0, 0, 0, .9) 80%, transparent);
|
mask-image: linear-gradient(to right, transparent, rgba(0, 0, 0, .9) 20%, rgba(0, 0, 0, .9) 80%, transparent);
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
max-height: var(--lesson-track-max-height, 400px);
|
||||||
|
opacity: var(--lesson-track-opacity, 1);
|
||||||
|
pointer-events: var(--lesson-track-pointer-events, auto);
|
||||||
|
transform: translateY(var(--lesson-track-offset, 0px));
|
||||||
|
transition: max-height .3s ease, opacity .3s ease, padding-bottom .3s ease, transform .3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (hover: hover) {
|
||||||
|
.module-overview {
|
||||||
|
--module-overview-gap: 18px;
|
||||||
|
--lesson-track-max-height: 0px;
|
||||||
|
--lesson-track-opacity: 0;
|
||||||
|
--lesson-track-pointer-events: none;
|
||||||
|
--lesson-track-padding-bottom: 0px;
|
||||||
|
--lesson-track-offset: -12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-overview-toggle {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.module-overview:hover,
|
||||||
|
.module-overview:focus-within,
|
||||||
|
.module-overview.is-expanded {
|
||||||
|
--module-overview-gap: 28px;
|
||||||
|
--lesson-track-max-height: 400px;
|
||||||
|
--lesson-track-opacity: 1;
|
||||||
|
--lesson-track-pointer-events: auto;
|
||||||
|
--lesson-track-padding-bottom: 12px;
|
||||||
|
--lesson-track-offset: 0px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.lesson-grid {
|
.lesson-grid {
|
||||||
@@ -4824,6 +5090,12 @@ onMounted(() => {
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lesson-actions-prev {
|
||||||
|
align-self: flex-start;
|
||||||
|
min-width: 150px;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.lesson-actions-buttons .btn {
|
.lesson-actions-buttons .btn {
|
||||||
min-width: 150px;
|
min-width: 150px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
Reference in New Issue
Block a user