Zobrazeni linku na event u detailu letu

This commit is contained in:
Michal Kváček
2024-02-26 09:45:23 +01:00
parent 1a5c8f09bf
commit 92678ec829
7 changed files with 74 additions and 25 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ services:
- ./src-ssr:/app/src-ssr - ./src-ssr:/app/src-ssr
- ./public:/app/public - ./public:/app/public
# - ./node_modules:/app/node_modules:delegated # - ./node_modules:/app/node_modules:delegated
command: quasar dev # -m ssr command: quasar dev -m ssr
environment: environment:
API_URL: "http://127.0.0.1:8000" API_URL: "http://127.0.0.1:8000"
@@ -21,6 +21,11 @@ const props = defineProps({
type: Object, type: Object,
required: false, required: false,
default: null default: null
},
eventDetailRoute: {
type: Object,
required: false,
default: null
} }
}) })
</script> </script>
@@ -122,6 +127,18 @@ const props = defineProps({
{{ minutesToHumanReadable(flight.durationMinCalculated) }} {{ minutesToHumanReadable(flight.durationMinCalculated) }}
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item v-if="flight.event && flight.event.isPublic">
<q-item-section avatar>
<q-icon name="event"/>
</q-item-section>
<q-item-section>
<router-link :to="eventDetailRoute">
{{ flight.event.name }}
</router-link>
</q-item-section>
</q-item>
<q-item v-if="flight.copilots?.length > 0"> <q-item v-if="flight.copilots?.length > 0">
<q-list> <q-list>
<q-item v-for="copilot in flight.copilots" :key="copilot.id"> <q-item v-for="copilot in flight.copilots" :key="copilot.id">
+9
View File
@@ -16,6 +16,15 @@ export const aircraftKeywords = (aircraft) => {
return [aircraft.organization?.name, aircraft.callSign, aircraft.manufacturer, aircraft.model] return [aircraft.organization?.name, aircraft.callSign, aircraft.manufacturer, aircraft.model]
}; };
export const flightEventKeywords = (event) => {
if (!event) return [];
return [event.name];
}
export const flightKeywords = (flight) => {
return ["let", "výlet", "letadlo"]
}
export const metaData = ({title, description, keywords, image, index = true}) => { export const metaData = ({title, description, keywords, image, index = true}) => {
const filteredKeywords = (keywords || []).filter(kw => !!kw); const filteredKeywords = (keywords || []).filter(kw => !!kw);
const filteredDescription = stripHtml(description); const filteredDescription = stripHtml(description);
+2
View File
@@ -60,6 +60,8 @@ fragment flightFullInfo on Flight {
event { event {
id id
isPublic
urlSlug
name name
} }
+12 -10
View File
@@ -94,6 +94,7 @@ const togglePublicVisibility = (variables) => toggleVisibility({
<FlightBasicInfo <FlightBasicInfo
:flight="flight" :flight="flight"
:poi-detail-route="{name: 'poiDetail'}" :poi-detail-route="{name: 'poiDetail'}"
:event-detail-route="{name: 'eventDetail', params: {id: flight.event.id}}"
:aircraft-detail-route="{name: 'aircraftDetail'}" :aircraft-detail-route="{name: 'aircraftDetail'}"
:copilot-detail-route="{name: 'copilotDetail'}" :copilot-detail-route="{name: 'copilotDetail'}"
/> />
@@ -108,7 +109,7 @@ const togglePublicVisibility = (variables) => toggleVisibility({
<q-separator/> <q-separator/>
<article class="q-my-lg" v-html="flight.debriefingNotes"/> <article class="q-my-lg" v-html="flight.debriefingNotes"/>
<BasicInfoBanner v-if="flight.debriegingNotes === ''"> <BasicInfoBanner v-if="flight.debriefingNotes === ''">
Nezapomeň si poznamenat důležité informace pro debriefing. Tyto poznámky slouží jen pro tebe. Nezapomeň si poznamenat důležité informace pro debriefing. Tyto poznámky slouží jen pro tebe.
</BasicInfoBanner> </BasicInfoBanner>
<q-separator/> <q-separator/>
@@ -123,10 +124,9 @@ const togglePublicVisibility = (variables) => toggleVisibility({
> >
U tohoto letu nemáš nahrané žádné fotografie. U tohoto letu nemáš nahrané žádné fotografie.
</BasicInfoBanner> </BasicInfoBanner>
<PhotoGallery <q-no-ssr v-else>
v-else <PhotoGallery :photos="flight.photos"/>
:photos="flight.photos" </q-no-ssr>
/>
<q-separator/> <q-separator/>
@@ -140,11 +140,13 @@ const togglePublicVisibility = (variables) => toggleVisibility({
> >
Nemáš nastavenou žádnou trasu. Nemáš nastavenou žádnou trasu.
</BasicInfoBanner> </BasicInfoBanner>
<FlightTrackMap
v-else <q-no-ssr v-else>
:flight="flight" <FlightTrackMap
:photos="flight.photos" :flight="flight"
/> :photos="flight.photos"
/>
</q-no-ssr>
</q-card-section> </q-card-section>
</template> </template>
</ContentCard> </ContentCard>
+8 -7
View File
@@ -15,31 +15,31 @@ const help = {
}, },
"organizace": { "organizace": {
title: "Co jsou to organizace?", title: "Co jsou to organizace?",
content: "Organizace slouží ke sdílení letadel, např. v rámci aeroklubu. " content: "Organizace slouží ke sdílení letadel, např. v rámci aeroklubu (nebo jiného provozovatele)."
}, },
"udalosti": { "udalosti": {
title: "Co jsou to události?", title: "Co jsou to události?",
content: "" content: "<p>Události slouží pro sloučení souvisejících letů. Letecké soustředění, výcvik, vícedenní výlet...</p>"
}, },
"uvodni-fotografie": { "uvodni-fotografie": {
title: "K čemu potřebuji úvodní fotografii?", title: "K čemu potřebuji úvodní fotografii?",
content: "" content: "Úvodní fotografie slouží k upoutání pozornosti nejen v prostředí Polétání.cz ale i na sociálních sítích. Pokud pošleš odkaz"
}, },
"url": { "url": {
title: "Proč k veřejným datům musím uvádět URL část?", title: "Proč k veřejným datům musím uvádět URL část?",
content: "" content: "Protože všechna veřejná data potřebují unikátní adresu, na které budou k dispozici ostatním uživatelům internetu. Zadáním vlastní URL adresy si můžeš vytvořit přehledné a čitelné adresy, které se snáze pamatují."
}, },
"poi": { "poi": {
title: "Jak funguje databáze zajímavých míst?", title: "Jak funguje databáze zajímavých míst?",
content: "" content: "Každý uživatel Polétání.cz může zveřejnit nějaké zajímavé místo na mapě. Toto místo pak mohou ostatní použít pro plánování svých letů, organizaci fotek u svých výletů. Všechna tato data se zobrazují na veřejné stránce s detailem tohoto zvoleného místa a mohou tak sloužit i jako inspirace pro ostatní."
}, },
"editor-fotek": { "editor-fotek": {
title: "Co umí editor fotek?", title: "Co umí editor fotek?",
content: "" content: "Polétání.cz ti dovoluje provádět základní úpravy tvých fotek."
}, },
"debriefing": { "debriefing": {
title: "Co jsou poznámky k debriefingu?", title: "Co jsou poznámky k debriefingu?",
content: "Prostě soukromé poznámky. Vidíš je jen ty." content: "Prostě soukromé poznámky. Vidíš je jen ty. Můžeš si sem poznamenat co bylo dobře, co nebylo úplně ok. Nezapomeň, že debriefing je součást každého letu a pomáhá při zlepšování schopností pilotů!"
}, },
"verejny-profil": { "verejny-profil": {
title: "Musím mít veřejný profil?", title: "Musím mít veřejný profil?",
@@ -50,6 +50,7 @@ const help = {
const opened = ref({}); const opened = ref({});
onMounted(() => { onMounted(() => {
opened.value[$route.query.h] = true; opened.value[$route.query.h] = true;
}) })
useAppStore().setPageTitle("Nápověda"); useAppStore().setPageTitle("Nápověda");
@@ -19,9 +19,10 @@ import PhotoGallery from "components/photos/PhotoGallery.vue";
import {storeToRefs} from "pinia"; import {storeToRefs} from "pinia";
import {flightName} from "src/composables/flight"; import {flightName} from "src/composables/flight";
import {useMeta} from "quasar"; import {useMeta} from "quasar";
import {aircraftKeywords, metaData} from "src/composables/meta"; import {aircraftKeywords, flightEventKeywords, flightKeywords, metaData} from "src/composables/meta";
import ContentCard from "components/ContentCard.vue"; import ContentCard from "components/ContentCard.vue";
import {usePhotosStore} from "stores/Photos"; import {usePhotosStore} from "stores/Photos";
import {computed} from "vue";
const {isQueryRunning, flight} = storeToRefs(useFlightsStore()); const {isQueryRunning, flight} = storeToRefs(useFlightsStore());
@@ -37,15 +38,32 @@ const {isQueryRunning: arePhotosLoading, photos: flightPhotos} = storeToRefs(use
const flightNameFormatted = flightName(flight.value); const flightNameFormatted = flightName(flight.value);
useAppStore().setPageTitle(flightNameFormatted); useAppStore().setPageTitle(flightNameFormatted);
useAppStore().setBreadcrumbs([
const event = computed(() => flight.value.event);
const breadcrumbs = [
{to: {name: 'homepage'}, label: "Polétání.cz"}, {to: {name: 'homepage'}, label: "Polétání.cz"},
{to: {name: "publicProfileDetail", params: {username: props.pilot.publicUsername}}, label: `@${props.pilot.publicUsername}`}, {to: {name: "publicProfileDetail", params: {username: props.pilot.publicUsername}}, label: `@${props.pilot.publicUsername}`},
{label: flightNameFormatted} ]
]); if (event.value && event.value.isPublic) {
breadcrumbs.push({to: {name: 'publicEventsList', username: props.pilot.publicUsername}, label: "Události"});
breadcrumbs.push({
to: {
name: 'publicEventDetail',
params: {eventSlug: event.value.urlSlug, username: props.pilot.publicUsername}
}, label: event.value.name
});
}
breadcrumbs.push({label: flightNameFormatted})
useAppStore().setBreadcrumbs(breadcrumbs);
useMeta(() => metaData({ useMeta(() => metaData({
title: `${flightNameFormatted} - ${props.pilot.name}`, title: `${flightNameFormatted} - ${props.pilot.name}`,
keywords: ["let", "výlet", "letadlo", props.pilot.name, ...aircraftKeywords(flight.value.aircraft)], keywords: [
...flightKeywords(flight.value),
props.pilot.name,
...aircraftKeywords(flight.value.aircraft),
...flightEventKeywords(event.value)
],
description: flight.value.description, description: flight.value.description,
image: flight.value.titlePhoto?.url image: flight.value.titlePhoto?.url
} }
@@ -63,6 +81,7 @@ useMeta(() => metaData({
:flight="flight" :flight="flight"
:poi-detail-route="{name: 'publicPOIDetail'}" :poi-detail-route="{name: 'publicPOIDetail'}"
:aircraft-detail-route="{name: 'publicAircraftDetail'}" :aircraft-detail-route="{name: 'publicAircraftDetail'}"
:event-detail-route="event.isPublic ? {name: 'publicEventDetail', params: {username: pilot.publicUsername, eventSlug: event.urlSlug}} : null"
:copilot-detail-route="{name: 'publicCopilotDetail', params: {username: pilot.publicUsername}}" :copilot-detail-route="{name: 'publicCopilotDetail', params: {username: pilot.publicUsername}}"
/> />
@@ -71,9 +90,8 @@ useMeta(() => metaData({
<q-no-ssr> <q-no-ssr>
<q-inner-loading v-if="arePhotosLoading"/> <q-inner-loading v-if="arePhotosLoading"/>
<PhotoGallery :photos="flightPhotos" v-else/> <PhotoGallery :photos="flightPhotos" v-else/>
<FlightTrackMap :key="flight.id" :flight="flight" :photos="flightPhotos"/>
</q-no-ssr> </q-no-ssr>
<FlightTrackMap :key="flight.id" :flight="flight" :photos="flightPhotos"/>
</q-card-section> </q-card-section>
</template> </template>
</ContentCard> </ContentCard>