mirror of
https://github.com/OpenSquawk/OpenSquawk
synced 2026-08-01 22:26:04 +08:00
Add feedback page and gate classroom behind orientation
This commit is contained in:
10
app/middleware/require-classroom-intro.ts
Normal file
10
app/middleware/require-classroom-intro.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import {CLASSROOM_INTRO_STORAGE_KEY} from '~~/shared/constants/storage'
|
||||
|
||||
export default defineNuxtRouteMiddleware(() => {
|
||||
if (process.server) return
|
||||
|
||||
const introComplete = localStorage.getItem(CLASSROOM_INTRO_STORAGE_KEY) === 'true'
|
||||
if (!introComplete) {
|
||||
return navigateTo('/classroom-introduction')
|
||||
}
|
||||
})
|
||||
@@ -13,7 +13,7 @@
|
||||
<p class="text-sm text-white/60">Guided preflight briefing</p>
|
||||
</div>
|
||||
</div>
|
||||
<NuxtLink to="/classroom" class="btn primary">
|
||||
<NuxtLink to="/classroom" class="btn primary" @click="handleClassroomEntry">
|
||||
Enter Classroom hub
|
||||
<v-icon icon="mdi-launch" size="18" class="text-[#061318]" />
|
||||
</NuxtLink>
|
||||
@@ -167,7 +167,7 @@
|
||||
<v-icon icon="mdi-gesture-tap-button" size="18" class="text-[#061318]" />
|
||||
Start guided tour
|
||||
</button>
|
||||
<NuxtLink to="/classroom" class="btn ghost">
|
||||
<NuxtLink to="/classroom" class="btn ghost" @click="handleClassroomEntry">
|
||||
Skip to Classroom
|
||||
<v-icon icon="mdi-arrow-right" size="16" />
|
||||
</NuxtLink>
|
||||
@@ -382,10 +382,10 @@
|
||||
Next stop
|
||||
<v-icon icon="mdi-arrow-right" size="18" class="text-[#061318]" />
|
||||
</button>
|
||||
<NuxtLink v-else to="/classroom" class="btn primary">
|
||||
<NuxtLink v-else to="/classroom" class="btn primary" @click="handleClassroomEntry">
|
||||
Enter Classroom hub
|
||||
<v-icon icon="mdi-launch" size="18" class="text-[#061318]" />
|
||||
</NuxtLink>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -403,6 +403,7 @@
|
||||
import { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue'
|
||||
import { useHead } from '#imports'
|
||||
import { useApi } from '~/composables/useApi'
|
||||
import { CLASSROOM_INTRO_STORAGE_KEY } from '~~/shared/constants/storage'
|
||||
import type { PizzicatoLite } from '~~/shared/utils/pizzicatoLite'
|
||||
import { loadPizzicatoLite } from '~~/shared/utils/pizzicatoLite'
|
||||
import { clampReadability, createNoiseGenerators, getReadabilityProfile } from '~~/shared/utils/radioEffects'
|
||||
@@ -420,6 +421,8 @@ interface StageStop {
|
||||
voiceLine: string
|
||||
}
|
||||
|
||||
definePageMeta({ middleware: 'require-auth' })
|
||||
|
||||
useHead({ title: 'Classroom orientation • OpenSquawk' })
|
||||
|
||||
const stages: StageStop[] = [
|
||||
@@ -497,6 +500,15 @@ const stages: StageStop[] = [
|
||||
|
||||
const api = useApi()
|
||||
|
||||
function markClassroomIntroComplete() {
|
||||
if (typeof window === 'undefined') return
|
||||
localStorage.setItem(CLASSROOM_INTRO_STORAGE_KEY, 'true')
|
||||
}
|
||||
|
||||
function handleClassroomEntry() {
|
||||
markClassroomIntroComplete()
|
||||
}
|
||||
|
||||
const voiceMode = ref<VoiceMode>('text')
|
||||
const radioLevel = ref(3)
|
||||
const hasCompletedRadioCheck = ref(false)
|
||||
|
||||
@@ -122,6 +122,10 @@
|
||||
</div>
|
||||
|
||||
<div class="hud-right">
|
||||
<NuxtLink class="btn ghost" to="/feedback" title="Share feedback or ideas">
|
||||
<v-icon size="18">mdi-message-draw</v-icon>
|
||||
Feedback
|
||||
</NuxtLink>
|
||||
|
||||
<!-- ATC Einstellungen -->
|
||||
<button class="btn ghost" @click="showSettings=true" title="Settings">
|
||||
@@ -1165,6 +1169,8 @@
|
||||
<div v-else class="container footer-container">
|
||||
<div class="footer-meta">
|
||||
<span class="muted small">© 2025 OpenSquawk. All rights reserved.</span>
|
||||
<span aria-hidden="true" class="muted small">·</span>
|
||||
<NuxtLink to="/feedback" class="link small">Feedback & ideas</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -1278,7 +1284,7 @@ import {loadPizzicatoLite} from '~~/shared/utils/pizzicatoLite'
|
||||
import type {PizzicatoLite} from '~~/shared/utils/pizzicatoLite'
|
||||
import {createNoiseGenerators, getReadabilityProfile} from '~~/shared/utils/radioEffects'
|
||||
|
||||
definePageMeta({middleware: 'require-auth'})
|
||||
definePageMeta({middleware: ['require-auth', 'require-classroom-intro']})
|
||||
|
||||
type Objective = {
|
||||
id: string
|
||||
|
||||
1
shared/constants/storage.ts
Normal file
1
shared/constants/storage.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const CLASSROOM_INTRO_STORAGE_KEY = 'os_classroom_intro_completed'
|
||||
Reference in New Issue
Block a user