INIT commit
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
<script setup>
|
||||
import {useUserStore} from "stores/User";
|
||||
|
||||
const loggedUser = useUserStore().user
|
||||
</script>
|
||||
|
||||
<template>
|
||||
Profile page
|
||||
|
||||
{{ loggedUser }}
|
||||
</template>
|
||||
@@ -0,0 +1,74 @@
|
||||
<script setup>
|
||||
import {computed, onMounted, reactive, ref} from "vue";
|
||||
import {useAircraftsStore} from "stores/Aircrafts";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import {storeToRefs} from "pinia";
|
||||
import {useQuasar} from "quasar";
|
||||
|
||||
const aircraftStore = useAircraftsStore();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
||||
const aircraftId = computed(() => parseInt(route.params.id));
|
||||
let loading = ref(false);
|
||||
let aircraft = reactive({});
|
||||
onMounted(() => {
|
||||
loading.value = true;
|
||||
aircraftStore.fetchDetail(aircraftId.value)
|
||||
.then(respAircraft => aircraft = respAircraft)
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
})
|
||||
|
||||
const $q = useQuasar();
|
||||
const confirmDelete = (id) => {
|
||||
$q.dialog({
|
||||
title: 'Potvrzení',
|
||||
message: 'Opravdu chceš smazat toto letadlo?',
|
||||
cancel: true,
|
||||
persistent: true
|
||||
}).onOk(() => {
|
||||
aircraftStore.delete(id).then(() => {
|
||||
router.push({name: "aircrafts"});
|
||||
$q.notify({message: "Letadlo uspesne odstraneno", position: "top", color: "positive"});
|
||||
});
|
||||
})
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-skeleton v-if="loading && aircraft"/>
|
||||
<template v-else>
|
||||
<q-breadcrumbs>
|
||||
<q-breadcrumbs-el :to="{name: 'aircrafts'}">Letadla</q-breadcrumbs-el>
|
||||
<q-breadcrumbs-el>{{ aircraft.name }}</q-breadcrumbs-el>
|
||||
</q-breadcrumbs>
|
||||
|
||||
<h1>{{ aircraft.name }}</h1>
|
||||
|
||||
<q-list>
|
||||
<q-item>
|
||||
Výrobce: {{ aircraft.manufacturer }}
|
||||
</q-item>
|
||||
|
||||
<q-item>
|
||||
Model: {{ aircraft.model }}
|
||||
</q-item>
|
||||
|
||||
</q-list>
|
||||
<q-btn :to='{name: "aircraftEdit", params: {id: aircraft.id}}'>Edit {{ aircraft.id }}</q-btn>
|
||||
<q-btn @click="confirmDelete(aircraft.id)">Delete</q-btn>
|
||||
|
||||
<!-- <h2>Limits</h2>-->
|
||||
<!-- Wind: {{ aircraft.limits.wind.frontKt }}/{{ aircraft.limits.wind.sideKt }} kt-->
|
||||
<!-- Neprekrocitelna rychlost: {{ aircraft.limits.speed.vmax }}-->
|
||||
<!-- Cestovni rychlost:-->
|
||||
<!-- Maximalni rychlost s klapkami:-->
|
||||
<!-- Padova rychlost bez klapek:-->
|
||||
<!-- Padova rychlost s klapkami (plne vysunute):-->
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
</template>
|
||||
@@ -0,0 +1,34 @@
|
||||
<script setup>
|
||||
import {useFlightsStore} from "stores/Flights";
|
||||
import {useRoute} from "vue-router";
|
||||
import {computed, onMounted} from "vue";
|
||||
import {minutesToHumanReadable} from "src/composables/timeUtils";
|
||||
|
||||
const flightsStore = useFlightsStore();
|
||||
const route = useRoute();
|
||||
|
||||
onMounted(() => {
|
||||
flightsStore.fetchDetail(route.params.id);
|
||||
})
|
||||
|
||||
const flight = computed(() => flightsStore.getDetail(route.params.id) || {});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{flight.takeOffLocation}} - {{flight.landingLocation}}</h1>
|
||||
|
||||
<q-icon name="calendar">{{flight.date}}</q-icon>
|
||||
<q-icon name="weather">
|
||||
Clouds: few
|
||||
Wind: 220/12kt
|
||||
Temp: 12°C
|
||||
</q-icon>
|
||||
|
||||
Track: {{ flight.turnPoints }}
|
||||
|
||||
{{ minutesToHumanReadable(flight.flightDurationMinutes) }}
|
||||
|
||||
<q-page-sticky location="bottom-right" :offset="[30, 30]">
|
||||
<q-fab color="primary" icon="edit" label="Edit" @click="$router.push({name: 'flightEdit', params:{id: flight.id}})"/>
|
||||
</q-page-sticky>
|
||||
</template>
|
||||
@@ -0,0 +1,24 @@
|
||||
<script setup>
|
||||
import {usePointsOfInterestStore} from "stores/PointsOfInterest";
|
||||
import {computed, onMounted} from "vue";
|
||||
import {useRoute} from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const poiId = route.params.id;
|
||||
const poiStore = usePointsOfInterestStore();
|
||||
|
||||
onMounted(() => {
|
||||
poiStore.fetchDetail(poiId);
|
||||
})
|
||||
|
||||
const poi = computed(() => poiStore.getDetail(poiId));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ poi.name }}</h1>
|
||||
|
||||
|
||||
<q-page-sticky position="bottom-right" :offset="[30, 30]">
|
||||
<q-fab icon="edit" label="Edit"/>
|
||||
</q-page-sticky>
|
||||
</template>
|
||||
@@ -0,0 +1,40 @@
|
||||
<script setup>
|
||||
import {useSecondPilotsStore} from "stores/SecondPilots";
|
||||
import {useRoute} from "vue-router";
|
||||
import {useFlightsStore} from "stores/Flights";
|
||||
import {computed, onMounted} from "vue";
|
||||
import {storeToRefs} from "pinia";
|
||||
import {minutesToHumanReadable} from "src/composables/timeUtils";
|
||||
|
||||
const secondPilotStore = useSecondPilotsStore();
|
||||
const flightsStore = useFlightsStore();
|
||||
const route = useRoute();
|
||||
|
||||
onMounted(() => {
|
||||
flightsStore.fetch();
|
||||
})
|
||||
|
||||
const secondPilot = {id: 1, name: "Franta Karel"};
|
||||
const flights = storeToRefs(flightsStore).items;
|
||||
|
||||
const commonFlights = computed(() => flights.value.filter(f => f.secondPilot.id === secondPilot.id))
|
||||
|
||||
const totalFlightTime = computed(() => {
|
||||
return commonFlights.value.reduce((acc, flight) => acc + flight.flightDurationMinutes, 0);
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-breadcrumbs>
|
||||
<q-breadcrumbs-el :to="{name: 'pilots'}">Pilots</q-breadcrumbs-el>
|
||||
<q-breadcrumbs-el>{{secondPilot.name}}</q-breadcrumbs-el>
|
||||
</q-breadcrumbs>
|
||||
|
||||
<h1>{{secondPilot.name}}</h1>
|
||||
|
||||
Flights:
|
||||
{{ commonFlights }}
|
||||
|
||||
Total time together: {{minutesToHumanReadable(totalFlightTime)}}
|
||||
|
||||
</template>
|
||||
@@ -0,0 +1,47 @@
|
||||
<script setup>
|
||||
import AircraftForm from "components/aircrafts/AircraftForm.vue";
|
||||
import {useAircraftsStore} from "stores/Aircrafts";
|
||||
import {useRoute, useRouter} from "vue-router";
|
||||
import {useQuasar} from "quasar";
|
||||
import {onMounted, reactive, ref} from "vue";
|
||||
|
||||
|
||||
let isRequestPending = ref(false);
|
||||
const $q = useQuasar();
|
||||
const router = useRouter();
|
||||
|
||||
const aircraftId = parseInt(useRoute().params.id);
|
||||
|
||||
const handleSave = (formData) => {
|
||||
isRequestPending.value = true;
|
||||
useAircraftsStore().update(aircraftId, formData).then(() => {
|
||||
$q.notify({message: "Letadlo uspesne upraveno", position: "top", color: "positive"});
|
||||
|
||||
router.push({name: "aircrafts"});
|
||||
}).finally(() => {
|
||||
isRequestPending.value = true;
|
||||
})
|
||||
}
|
||||
|
||||
let loadedAircraft = ref(null);
|
||||
onMounted(() => {
|
||||
useAircraftsStore().fetchDetail(aircraftId).then((data) => {
|
||||
console.log("data ", data);
|
||||
loadedAircraft.value = data;
|
||||
|
||||
} ).catch(err => {
|
||||
console.error(err);
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-skeleton v-if="!loadedAircraft" />
|
||||
<template v-if="loadedAircraft">
|
||||
<h1>Editace letadla {{ loadedAircraft.name}}</h1>
|
||||
|
||||
loaded aircraft: {{ loadedAircraft }}
|
||||
|
||||
<AircraftForm @save="handleSave" :default-values="loadedAircraft" :is-request-pending="isRequestPending"/>
|
||||
</template>
|
||||
</template>
|
||||
@@ -0,0 +1,7 @@
|
||||
<script setup>
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
flight edit
|
||||
</template>
|
||||
@@ -0,0 +1,196 @@
|
||||
<script setup>
|
||||
import {computed, onMounted, reactive, ref, watch} from "vue";
|
||||
import LocationInput from "components/inputs/LocationInput.vue";
|
||||
import {useAircraftsStore} from "stores/Aircrafts";
|
||||
import {useFlightsStore} from "stores/Flights";
|
||||
import {useRouter} from "vue-router";
|
||||
import {usePointsOfInterestStore} from "stores/PointsOfInterest";
|
||||
import {storeToRefs} from "pinia";
|
||||
import {isRequired} from "src/composables/form/rules";
|
||||
import {useMeta} from "quasar";
|
||||
import TabsStepper from "components/TabsStepper.vue";
|
||||
|
||||
const aircraftsStore = useAircraftsStore();
|
||||
const poiStore = usePointsOfInterestStore();
|
||||
const flightsStore = useFlightsStore();
|
||||
|
||||
useMeta({title: "New flight"});
|
||||
onMounted(() => {
|
||||
aircraftsStore.fetch();
|
||||
poiStore.fetch();
|
||||
flightsStore.fetch();
|
||||
});
|
||||
|
||||
|
||||
const rules = {
|
||||
aircraft: [isRequired],
|
||||
takeOffLocation: [isRequired],
|
||||
LandingLocation: [isRequired],
|
||||
}
|
||||
|
||||
const aircrafts = storeToRefs(aircraftsStore).items;
|
||||
const locations = storeToRefs(poiStore).items;
|
||||
|
||||
const turnPointsCount = ref(1);
|
||||
const formData = reactive({
|
||||
aircraftId: null,
|
||||
takeOffLocation: null,
|
||||
landingLocation: null,
|
||||
turnPoints: [],
|
||||
solo: true,
|
||||
secondPilot: "",
|
||||
instructor: false,
|
||||
picTime: 0,
|
||||
date: new Date(),
|
||||
takeOffTime: "",
|
||||
landingTime: "",
|
||||
flightDurationMinutes: 0,
|
||||
landings: 1,
|
||||
note: ""
|
||||
})
|
||||
const formSteps = ["aircraft", "basic", "track", "copilot", "photos", "notes"]
|
||||
const formStep = ref(formSteps[0]);
|
||||
|
||||
// watch(() => formData.takeOffLocation, (newVal) => {
|
||||
// if (!formData.landingLocation) {
|
||||
// formData.landingLocation = locations.value.find(l => l.id === newVal);
|
||||
// }
|
||||
// })
|
||||
|
||||
const router = useRouter();
|
||||
const saveForm = () => {
|
||||
flightsStore.create(this.formData).then(() => {
|
||||
router.push({name: "myFlights"});
|
||||
});
|
||||
}
|
||||
|
||||
const basicInfoFilled = computed(() => {
|
||||
return formData.aircraftId && formData.takeOffLocation && formData.landingLocation && formData.date && formData.flightDurationMinutes > 0
|
||||
})
|
||||
|
||||
const removeTurnPoint = (idx) => {
|
||||
formData.turnPoints.splice(idx, 1);
|
||||
turnPointsCount.value--;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<q-breadcrumbs>
|
||||
<q-breadcrumbs-el :to="{name: 'myFlights'}">My Flights</q-breadcrumbs-el>
|
||||
<q-breadcrumbs-el>Add new</q-breadcrumbs-el>
|
||||
</q-breadcrumbs>
|
||||
|
||||
<!-- {{ formData }}-->
|
||||
|
||||
<q-form @submit.prevent="saveForm" class="q-my-lg">
|
||||
<q-tabs
|
||||
v-model="formStep"
|
||||
outside-arrows
|
||||
mobile-arrows
|
||||
left-icon="chevron_left"
|
||||
right-icon="chevron_right"
|
||||
active-color="primary"
|
||||
class="q-mb-lg"
|
||||
>
|
||||
<q-tab name="aircraft" icon="flight" label="Aircraft"/>
|
||||
<q-tab name="basic" icon="flight_takeoff" label="Basic"/>
|
||||
<q-tab name="track" icon="route" label="Route"/>
|
||||
<q-tab name="copilot" icon="person_add" label="Copilot"/>
|
||||
<q-tab name="photos" icon="add_a_photo" label="Photos"/>
|
||||
<q-tab name="notes" icon="edit_note" label="Notes"/>
|
||||
</q-tabs>
|
||||
|
||||
<q-tab-panels v-model="formStep" animated>
|
||||
<q-tab-panel name="aircraft">
|
||||
<q-select
|
||||
v-model="formData.aircraftId"
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
emit-value
|
||||
map-options
|
||||
:rules="rules.aircraft"
|
||||
:options="aircrafts"
|
||||
label="Aircraft"
|
||||
>
|
||||
<template #prepend>
|
||||
<q-icon name="flight"></q-icon>
|
||||
</template>
|
||||
</q-select>
|
||||
|
||||
<TabsStepper v-model="formStep" next-step="basic"/>
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="basic">
|
||||
<q-input type="date" v-model="formData.date" label="Date"/>
|
||||
<q-input type="time" v-model="formData.time" label="Take-off time"/>
|
||||
<LocationInput label="Take-off location" :rules="rules.takeOffLocation" :locations="locations" v-model="formData.takeOffLocation" prepend-icon="flight_takeoff"/>
|
||||
<LocationInput label="Landing location" :rules="rules.landingLocation" :locations="locations" v-model="formData.landingLocation" prepend-icon="flight_land"/>
|
||||
<q-input v-model="formData.landings" label="Landings" type="number" min="1"/>
|
||||
<q-input v-model="formData.flightDurationMinutes" min=0 label="Flight duration (minutes)" type="number"/>
|
||||
|
||||
<TabsStepper v-model="formStep" previous-step="aircraft" next-step="track"/>
|
||||
</q-tab-panel>
|
||||
|
||||
<q-tab-panel name="track">
|
||||
<template v-for="i in turnPointsCount" :key="`${i}-${turnPointsCount}`">
|
||||
<LocationInput label="Turn point" :locations="locations" v-model="formData.turnPoints[i-1]">
|
||||
<template #append v-if="i > 1">
|
||||
<q-btn @click="removeTurnPoint(i - 1)">-</q-btn>
|
||||
</template>
|
||||
</LocationInput>
|
||||
</template>
|
||||
<q-btn @click="turnPointsCount++">
|
||||
Add turn point
|
||||
</q-btn>
|
||||
|
||||
<q-uploader
|
||||
label="Upload GPX track"
|
||||
url="http://localhost:4444/upload"
|
||||
class="q-mx-sm"
|
||||
style="width: 100%"
|
||||
auto-upload
|
||||
color="secondary"
|
||||
/>
|
||||
|
||||
<TabsStepper v-model="formStep" previous-step="basic" next-step="copilot"/>
|
||||
</q-tab-panel>
|
||||
|
||||
<q-tab-panel name="copilot">
|
||||
<q-btn-toggle spread no-caps v-model="formData.solo" toggle-color="primary" :options="[{label: 'Solo flight', value: true}, {label: 'Flight with someone', value: false}]"/>
|
||||
|
||||
<div v-if="!formData.solo">
|
||||
<q-input type="text" v-model="formData.secondPilot" label="Second pilot"/>
|
||||
<q-checkbox v-model="formData.instructor" v-if="formData.secondPilot !== ''" label="Instructor"/>
|
||||
<q-input v-model="formData.picTime" label="PIC time"/>
|
||||
</div>
|
||||
|
||||
<TabsStepper v-model="formStep" previous-step="track" next-step="photos"/>
|
||||
</q-tab-panel>
|
||||
|
||||
<q-tab-panel name="photos">
|
||||
<q-uploader
|
||||
label="Upload photos"
|
||||
url="http://localhost:4444/upload"
|
||||
multiple
|
||||
auto-upload
|
||||
style="width: 100%;"
|
||||
color="secondary"
|
||||
/>
|
||||
|
||||
<TabsStepper v-model="formStep" previous-step="copilot" next-step="notes"/>
|
||||
</q-tab-panel>
|
||||
|
||||
<q-tab-panel name="notes">
|
||||
<q-editor v-model="formData.note" height="60vh" label="Notes"/>
|
||||
|
||||
<TabsStepper v-model="formStep" previous-step="photos"/>
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
|
||||
<q-page-sticky expand position="bottom" :offset="[10, 10]" v-if="basicInfoFilled">
|
||||
<div>
|
||||
<q-btn type="submit" size="lg" class="full-width" color="primary" icon="save" label="Save flight"/>
|
||||
</div>
|
||||
</q-page-sticky>
|
||||
</q-form>
|
||||
</template>
|
||||
@@ -0,0 +1,27 @@
|
||||
<script setup>
|
||||
import AircraftForm from "components/aircrafts/AircraftForm.vue";
|
||||
import {useAircraftsStore} from "stores/Aircrafts";
|
||||
import {useRouter} from "vue-router";
|
||||
import {useQuasar} from "quasar";
|
||||
import {ref} from "vue";
|
||||
|
||||
let isRequestPending = ref(false);
|
||||
const $q = useQuasar();
|
||||
const router = useRouter();
|
||||
const handleSave = (formData) => {
|
||||
isRequestPending.value = true;
|
||||
useAircraftsStore().create(formData).then(() => {
|
||||
$q.notify({message: "Letadlo úspěšně vytvořeno", position: "top", color: "positive"});
|
||||
|
||||
router.push({name: "aircrafts"});
|
||||
}).finally(() => {
|
||||
isRequestPending.value = true;
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- <h1>Nové letadlo</h1>-->
|
||||
|
||||
<AircraftForm @save="handleSave" :is-request-pending="isRequestPending"/>
|
||||
</template>
|
||||
@@ -0,0 +1,40 @@
|
||||
<script setup>
|
||||
import {useAircraftsStore} from "stores/Aircrafts";
|
||||
import {computed, onMounted, ref} from "vue";
|
||||
import {storeToRefs} from "pinia";
|
||||
import AircraftsList from "components/aircrafts/AircraftsList.vue";
|
||||
import AddFAB from "components/AddFAB.vue";
|
||||
|
||||
const aircraftStore = useAircraftsStore();
|
||||
const aircrafts = storeToRefs(aircraftStore).items;
|
||||
const aircraftsComputed = computed(() => aircraftStore.items);
|
||||
|
||||
const refetch = () => {
|
||||
loading.value = true
|
||||
aircraftStore.fetch().then(data => console.log("data", data)).finally(() => {
|
||||
console.log("after fetch");
|
||||
loading.value = false
|
||||
});
|
||||
}
|
||||
|
||||
let loading = ref(false);
|
||||
onMounted(() => {
|
||||
refetch();
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-skeleton v-if="loading">Loading (sem pridat skeleton)</q-skeleton>
|
||||
|
||||
<AircraftsList :items="aircrafts" v-if="!loading"/>
|
||||
|
||||
<q-btn @click="refetch()">Fetch</q-btn>
|
||||
|
||||
{{ aircrafts }}
|
||||
<br>
|
||||
{{ aircraftsComputed }}
|
||||
<br>
|
||||
{{ aircraftStore.items }}
|
||||
|
||||
<AddFAB :router-link="{name: 'addAircraft'}"/>
|
||||
</template>
|
||||
@@ -0,0 +1,76 @@
|
||||
<script setup>
|
||||
import {computed, onMounted} from "vue";
|
||||
import {useFlightsStore} from "stores/Flights";
|
||||
import {minutesToHumanReadable} from "src/composables/timeUtils";
|
||||
import {useMeta, useQuasar} from "quasar";
|
||||
|
||||
useMeta({title: "Moje lety"});
|
||||
|
||||
const flightsStore = useFlightsStore();
|
||||
onMounted(() => {
|
||||
flightsStore.fetch();
|
||||
})
|
||||
const totalFlightTime = computed(() => {
|
||||
return flightsStore.items.reduce((acc, flight) => acc + flight.flightDurationMinutes, 0);
|
||||
})
|
||||
|
||||
const $q = useQuasar();
|
||||
const deleteFlight = (flightId) => {
|
||||
$q.dialog({
|
||||
title: 'Potvrzení',
|
||||
message: 'Opravdu chceš smazat tento let?',
|
||||
cancel: true,
|
||||
persistent: true
|
||||
}).onOk(() => {
|
||||
flightsStore.deleteItem(flightId);
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-4 col-lg-3" v-for="flight of flightsStore.items" :key="flight">
|
||||
|
||||
<q-card class="q-my-sm q-mx-sm">
|
||||
<q-img :src="flight.titlePhotoUrl" v-if="flight.titlePhotoUrl">
|
||||
<div class="absolute-bottom text-center text-h6">
|
||||
<router-link :to="{name: 'flightDetail', params:{id: flight.id}}" class="text-white">
|
||||
{{ flight.takeOffLocation }} - {{ flight.landingLocation }}
|
||||
</router-link>
|
||||
</div>
|
||||
</q-img>
|
||||
<q-card-section>
|
||||
<div class="text-h6" v-if="!flight.titlePhotoUrl">
|
||||
<router-link :to="{name: 'flightDetail', params:{id: flight.id}}">
|
||||
{{ flight.takeOffLocation }} - {{ flight.landingLocation }}
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="text-subtitle2">{{ minutesToHumanReadable(flight.flightDurationMinutes) }}</div>
|
||||
<div class="text-secondary">
|
||||
<q-icon name="today"/>
|
||||
{{ flight.date }}
|
||||
</div>
|
||||
<div class="text-secondary">
|
||||
<q-icon name="plane"/>
|
||||
{{ flight.aircraft.name }}
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator/>
|
||||
|
||||
<q-card-actions align="right">
|
||||
<!-- <q-btn flat icon="visibility"></q-btn>-->
|
||||
<!-- <q-btn flat icon="edit" :to="{name: 'flightEdit', params:{id: flight.id}}"></q-btn>-->
|
||||
<q-btn flat icon="delete" color="red" @click="deleteFlight(flight.id)"></q-btn>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
Total: {{ minutesToHumanReadable(totalFlightTime) }}
|
||||
|
||||
<q-page-sticky location="bottom" :offset="[30, 30]">
|
||||
<q-fab icon="add" color="primary" label="Add flight" @click="$router.push({name: 'addFlight'})"/>
|
||||
</q-page-sticky>
|
||||
</template>
|
||||
@@ -0,0 +1,31 @@
|
||||
<script setup>
|
||||
import {usePointsOfInterestStore} from "stores/PointsOfInterest";
|
||||
import {computed, onMounted, ref} from "vue";
|
||||
import {storeToRefs} from "pinia";
|
||||
|
||||
const poiStore = usePointsOfInterestStore();
|
||||
|
||||
onMounted(() => {
|
||||
poiStore.fetch();
|
||||
})
|
||||
|
||||
const pointsOfInterest = computed(() => poiStore.groupByTypes);
|
||||
const availableTypes = computed(() => Object.keys(pointsOfInterest.value));
|
||||
</script>
|
||||
|
||||
<template>
|
||||
{{ pointsOfInterest }}
|
||||
<div v-for="type of availableTypes" :key="type">
|
||||
<h2>{{ poiStore.pointTypeName(type) }}</h2>
|
||||
|
||||
<q-list bordered separator>
|
||||
<q-item clickable v-ripple v-for="poi of pointsOfInterest[type]" :key="poi">
|
||||
<q-item-section>
|
||||
<router-link :to="{name: 'poiDetail', params: {id: poi.id}}">
|
||||
{{ poi.name }}
|
||||
</router-link>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,29 @@
|
||||
<script setup>
|
||||
import {storeToRefs} from "pinia";
|
||||
import {useSecondPilotsStore} from "stores/SecondPilots";
|
||||
import {onMounted} from "vue";
|
||||
|
||||
const pilotsStore = useSecondPilotsStore();
|
||||
|
||||
onMounted(() => {
|
||||
pilotsStore.fetch();
|
||||
})
|
||||
|
||||
const secondPilots = storeToRefs(pilotsStore).items;
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-list bordered separator>
|
||||
<q-item clickable v-ripple v-for="pilot of secondPilots" :key="pilot">
|
||||
<q-item-label>
|
||||
<router-link :to="{name: 'pilotDetail', params: {id: pilot.id }}">
|
||||
{{ pilot.name }}
|
||||
</router-link>
|
||||
</q-item-label>
|
||||
<q-item-section>
|
||||
section
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</template>
|
||||
Reference in New Issue
Block a user