feat(live-atc): manual flight entry on setup screen

Adds a "Manual flight" card alongside VATSIM and demo so a flight can
be entered by hand (callsign, dep, arr, optional aircraft/altitude)
without a VATSIM account. Feeds into the same scenario picker.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
itsrubberduck
2026-07-19 19:37:53 +02:00
parent a53442b1d1
commit 9eb670c0c4
3 changed files with 128 additions and 1 deletions

View File

@@ -1,4 +1,5 @@
<script setup lang="ts">
import { reactive, computed } from 'vue'
import SetupCard from '~/components/live-atc/SetupCard.vue'
defineProps<{
@@ -8,10 +9,36 @@ defineProps<{
const vatsimId = defineModel<string>('vatsimId', { required: true })
defineEmits<{
const emit = defineEmits<{
(e: 'load-flight-plans'): void
(e: 'start-demo'): void
(e: 'start-manual', plan: { callsign: string; dep: string; arr: string; aircraft: string; altitude: string }): void
}>()
const manual = reactive({
callsign: '',
dep: '',
arr: '',
aircraft: '',
altitude: '',
})
const manualValid = computed(() =>
manual.callsign.trim().length >= 2 &&
manual.dep.trim().length >= 3 &&
manual.arr.trim().length >= 3
)
const startManual = () => {
if (!manualValid.value) return
emit('start-manual', {
callsign: manual.callsign,
dep: manual.dep,
arr: manual.arr,
aircraft: manual.aircraft,
altitude: manual.altitude,
})
}
</script>
<template>
@@ -53,6 +80,85 @@ defineEmits<{
</div>
</SetupCard>
<!-- Manual flight entry -->
<SetupCard>
<div class="space-y-4">
<div>
<h2 class="text-lg font-semibold">Manual flight</h2>
<p class="text-sm text-[var(--t3)]">Enter a flight by hand no VATSIM account needed.</p>
</div>
<v-text-field
v-model="manual.callsign"
label="Callsign"
placeholder="DLH39A"
variant="outlined"
density="comfortable"
color="cyan"
prepend-inner-icon="mdi-radio-tower"
hide-details
@keyup.enter="startManual"
/>
<div class="grid grid-cols-2 gap-3">
<v-text-field
v-model="manual.dep"
label="From (ICAO)"
placeholder="EDDF"
variant="outlined"
density="comfortable"
color="cyan"
prepend-inner-icon="mdi-airplane-takeoff"
maxlength="4"
hide-details
@keyup.enter="startManual"
/>
<v-text-field
v-model="manual.arr"
label="To (ICAO)"
placeholder="EDDM"
variant="outlined"
density="comfortable"
color="cyan"
prepend-inner-icon="mdi-airplane-landing"
maxlength="4"
hide-details
@keyup.enter="startManual"
/>
</div>
<div class="grid grid-cols-2 gap-3">
<v-text-field
v-model="manual.aircraft"
label="Aircraft (opt.)"
placeholder="A320/L"
variant="outlined"
density="comfortable"
color="cyan"
prepend-inner-icon="mdi-airplane"
hide-details
/>
<v-text-field
v-model="manual.altitude"
label="Cruise ft (opt.)"
placeholder="36000"
variant="outlined"
density="comfortable"
color="cyan"
prepend-inner-icon="mdi-arrow-expand-vertical"
inputmode="numeric"
hide-details
/>
</div>
<v-btn
block
color="cyan"
variant="tonal"
:disabled="!manualValid"
@click="startManual"
>
Continue with this flight
</v-btn>
</div>
</SetupCard>
<!-- Demo Mode -->
<SetupCard>
<div class="space-y-4">

View File

@@ -713,6 +713,24 @@ export function useLiveAtcSession(
currentScreen.value = 'scenario'
}
/** Start from a manually entered flight instead of VATSIM / demo. */
const startManualFlight = (plan: {
callsign: string
dep: string
arr: string
aircraft?: string
altitude?: string
}) => {
selectedPlan.value = {
callsign: plan.callsign.trim().toUpperCase(),
aircraft: plan.aircraft?.trim().toUpperCase() || 'A320/L',
dep: plan.dep.trim().toUpperCase(),
arr: plan.arr.trim().toUpperCase(),
altitude: plan.altitude?.trim() || '36000',
}
currentScreen.value = 'scenario'
}
/** Launch a specific scenario with the current flight plan. */
const launchScenario = async (scenario: Scenario) => {
if (!selectedPlan.value) return
@@ -833,6 +851,7 @@ export function useLiveAtcSession(
loadFlightPlans,
startMonitoring,
startDemoFlight,
startManualFlight,
launchScenario,
flyAgain,
backToSetup,

View File

@@ -21,6 +21,7 @@
:error="error"
@load-flight-plans="loadFlightPlans"
@start-demo="startDemoFlight"
@start-manual="startManualFlight"
/>
<FlightSelectStep
@@ -603,6 +604,7 @@ const {
loadFlightPlans,
startMonitoring,
startDemoFlight,
startManualFlight,
launchScenario,
flyAgain,
backToSetup,