Vylepseni SSR, pridani meta informaci, zatim dost WIP
This commit is contained in:
+17
-15
@@ -2,26 +2,28 @@
|
|||||||
FROM node:20-alpine as develop-stage
|
FROM node:20-alpine as develop-stage
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY package*.json ./
|
RUN yarn global add @quasar/cli
|
||||||
RUN yarn global add @quasar/cli && yarn --production=false
|
|
||||||
|
COPY package.json yarn.lock ./
|
||||||
|
RUN yarn --production=false
|
||||||
|
RUN npx update-browserslist-db@latest
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# build stage
|
# build stage
|
||||||
FROM develop-stage as build-stage
|
FROM develop-stage as build-stage
|
||||||
|
|
||||||
#ARG API_URL
|
|
||||||
#ENV VUE_API_URL $API_URL
|
|
||||||
|
|
||||||
RUN yarn --production=false
|
|
||||||
RUN quasar build -m ssr
|
RUN quasar build -m ssr
|
||||||
|
|
||||||
# production stage
|
FROM node:20-alpine as production-stage
|
||||||
#FROM nginx:1.25-alpine as production-stage
|
|
||||||
#COPY conf/nginx.conf /etc/nginx/nginx.conf
|
|
||||||
#COPY --from=build-stage /app/dist/spa /app/html
|
|
||||||
#EXPOSE 80
|
|
||||||
#
|
|
||||||
#CMD ["nginx", "-g", "daemon off;"]
|
|
||||||
|
|
||||||
FROM keymetrics/pm2:latest-alpine as production-stage
|
ENV NODE_ENV production
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY process.yml /app
|
||||||
|
COPY --from=build-stage /app/dict/ssr/package.json /app
|
||||||
|
RUN yarn global add pm2 && yarn && yarn cache clean
|
||||||
|
|
||||||
|
COPY --from=build-stage /app/dist/ssr /app
|
||||||
|
|
||||||
|
CMD ["pm2-runtime", "/app/process.yml"]
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
version: "3.3"
|
version: "3.4"
|
||||||
services:
|
services:
|
||||||
poletani-app:
|
poletani-app:
|
||||||
image: "docker.kvacek.cz/poletani/app:latest"
|
image: "docker.kvacek.cz/poletani/app:latest"
|
||||||
|
# build:
|
||||||
|
# context: .
|
||||||
|
# dockerfile: Dockerfile
|
||||||
|
# target: "production-stage"
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- 9000:80
|
# - 9000:80
|
||||||
|
- 9000:3000
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ services:
|
|||||||
## command: ls -l /app
|
## command: ls -l /app
|
||||||
|
|
||||||
app:
|
app:
|
||||||
|
network_mode: host
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
target: "develop-stage"
|
target: "develop-stage"
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title><%= productName %></title>
|
|
||||||
|
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="description" content="<%= productDescription %>">
|
|
||||||
<meta name="format-detection" content="telephone=no">
|
<meta name="format-detection" content="telephone=no">
|
||||||
<meta name="msapplication-tap-highlight" content="no">
|
<meta name="msapplication-tap-highlight" content="no">
|
||||||
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>">
|
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>">
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
apps:
|
||||||
|
- name: poletani
|
||||||
|
script: /app/index.js
|
||||||
|
exec_mode: cluster
|
||||||
|
instances: 3
|
||||||
+3
-3
@@ -23,7 +23,7 @@ module.exports = configure(function (ctx) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// https://v2.quasar.dev/quasar-cli/prefetch-feature
|
// https://v2.quasar.dev/quasar-cli/prefetch-feature
|
||||||
// preFetch: true,
|
preFetch: true,
|
||||||
|
|
||||||
// app boot file (/poletani/boot)
|
// app boot file (/poletani/boot)
|
||||||
// --> boot files are part of "main.js"
|
// --> boot files are part of "main.js"
|
||||||
@@ -56,7 +56,7 @@ module.exports = configure(function (ctx) {
|
|||||||
build: {
|
build: {
|
||||||
target: {
|
target: {
|
||||||
browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
|
browser: ['es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1'],
|
||||||
node: 'node18'
|
node: 'node20'
|
||||||
},
|
},
|
||||||
|
|
||||||
env: {
|
env: {
|
||||||
@@ -76,7 +76,7 @@ module.exports = configure(function (ctx) {
|
|||||||
// env: {},
|
// env: {},
|
||||||
// rawDefine: {}
|
// rawDefine: {}
|
||||||
// ignorePublicFolder: true,
|
// ignorePublicFolder: true,
|
||||||
// minify: false,
|
minify: true,
|
||||||
// polyfillModulePreload: true,
|
// polyfillModulePreload: true,
|
||||||
// distDir
|
// distDir
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import {useAppStore} from "stores/App";
|
|||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
|
|
||||||
const layoutComponent = computed(() => {
|
const layoutComponent = computed(() => {
|
||||||
if (!route.meta) return null;
|
if (!route.meta) return null;
|
||||||
return route.meta.layout;
|
return route.meta.layout;
|
||||||
|
|||||||
+5
-9
@@ -1,4 +1,3 @@
|
|||||||
// import {boot} from "quasar/wrappers";
|
|
||||||
import {ApolloClient, ApolloLink, fromPromise, InMemoryCache} from '@apollo/client/core'
|
import {ApolloClient, ApolloLink, fromPromise, InMemoryCache} from '@apollo/client/core'
|
||||||
import {createUploadLink} from 'apollo-upload-client';
|
import {createUploadLink} from 'apollo-upload-client';
|
||||||
import {onError} from "@apollo/client/link/error";
|
import {onError} from "@apollo/client/link/error";
|
||||||
@@ -8,6 +7,8 @@ import {Notify} from "quasar";
|
|||||||
import {errorObject, warningObject} from "src/composables/dialog";
|
import {errorObject, warningObject} from "src/composables/dialog";
|
||||||
|
|
||||||
const handleRefreshToken = (store, forward, operation) => {
|
const handleRefreshToken = (store, forward, operation) => {
|
||||||
|
if (!operation._refreshUnauthorizedUser) return;
|
||||||
|
|
||||||
return fromPromise(useUserStore(store).refreshAccessToken()
|
return fromPromise(useUserStore(store).refreshAccessToken()
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
Notify.create(warningObject("Tvoje přihlášení vypřešlo. Přihlaš se prosím znovu."));
|
Notify.create(warningObject("Tvoje přihlášení vypřešlo. Přihlaš se prosím znovu."));
|
||||||
@@ -18,7 +19,8 @@ const handleRefreshToken = (store, forward, operation) => {
|
|||||||
const oldHeaders = operation.getContext().headers;
|
const oldHeaders = operation.getContext().headers;
|
||||||
operation.setContext({
|
operation.setContext({
|
||||||
headers: {
|
headers: {
|
||||||
...oldHeaders, authorization: `Bearer ${accessToken}`,
|
...oldHeaders,
|
||||||
|
authorization: `Bearer ${accessToken}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -27,8 +29,6 @@ const handleRefreshToken = (store, forward, operation) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const apolloWrapper = {};
|
export const apolloWrapper = {};
|
||||||
export default (({store}) => {
|
export default (({store}) => {
|
||||||
const uploadLink = createUploadLink({
|
const uploadLink = createUploadLink({
|
||||||
@@ -64,14 +64,9 @@ export default (({store}) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const apolloClient = new ApolloClient({
|
const apolloClient = new ApolloClient({
|
||||||
link: ApolloLink.from([authLink, errorLink, uploadLink]), cache: new InMemoryCache(), connectToDevTools: true,
|
link: ApolloLink.from([authLink, errorLink, uploadLink]), cache: new InMemoryCache(), connectToDevTools: true,
|
||||||
});
|
});
|
||||||
// const apolloProvider = createApolloProvider({
|
|
||||||
// defaultClient: apolloClient,
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
apolloWrapper.query = (query, variables = {}) => {
|
apolloWrapper.query = (query, variables = {}) => {
|
||||||
return apolloClient.query({
|
return apolloClient.query({
|
||||||
@@ -79,6 +74,7 @@ export default (({store}) => {
|
|||||||
})
|
})
|
||||||
.then((response) => response)
|
.then((response) => response)
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
if (!err.toString().includes("401") && !err.toString().includes("Not authorized"))
|
||||||
console.error("Error during query: ", err)
|
console.error("Error during query: ", err)
|
||||||
return err;
|
return err;
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
export const metaData = ({title, description, keywords, image}) => {
|
||||||
|
return {
|
||||||
|
title: title || "",
|
||||||
|
titleTemplate(title) {
|
||||||
|
return title !== '' ? `${title} - Polétání.cz` : 'Polétání.cz'
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
description: {name: "description", content: description || ""},
|
||||||
|
keywords: {name: "keywords", content: (keywords || []).join(", ")},
|
||||||
|
ogImage: image ? {property: "og:image", content: image} : undefined,
|
||||||
|
ogTitle: {
|
||||||
|
property: "og:title",
|
||||||
|
content: title,
|
||||||
|
template(ogTitle) {
|
||||||
|
return (!ogTitle || ogTitle === '') ? "Polétání.cz" : `${ogTitle} - Polétání.cz`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const commonKeywords = ["zápisník", "létání", "ultralight", "letectví", "fotogalerie", "výlet", "vyhlídkový let", "navigační let"];
|
||||||
@@ -13,7 +13,6 @@ export const croppedArea = ref(null);
|
|||||||
export const selectedAspectRatio = ref(null);
|
export const selectedAspectRatio = ref(null);
|
||||||
|
|
||||||
watch(() => selectedAspectRatio.value, (newVal) => {
|
watch(() => selectedAspectRatio.value, (newVal) => {
|
||||||
console.log(newVal);
|
|
||||||
cropper.setAspectRatio(newVal);
|
cropper.setAspectRatio(newVal);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {ref} from "vue";
|
|||||||
|
|
||||||
export const compare = ref(false);
|
export const compare = ref(false);
|
||||||
|
|
||||||
export const splitterWidth = ref(750); // TODO: doresit onresize a zmenu velikosti
|
export const splitterWidth = ref(750);
|
||||||
export const splitter = ref(50);
|
export const splitter = ref(50);
|
||||||
export const onResize = (info) => {
|
export const onResize = (info) => {
|
||||||
splitterWidth.value = info.width < 750 ? info.width : 750;
|
splitterWidth.value = info.width < 750 ? info.width : 750;
|
||||||
|
|||||||
@@ -25,7 +25,6 @@
|
|||||||
show-if-above
|
show-if-above
|
||||||
bordered
|
bordered
|
||||||
>
|
>
|
||||||
|
|
||||||
<q-img class="absolute-top" v-if="!isQueryRunning && user" :src="user.titleImageUrl" style="height: 150px"/>
|
<q-img class="absolute-top" v-if="!isQueryRunning && user" :src="user.titleImageUrl" style="height: 150px"/>
|
||||||
<q-spinner v-else/>
|
<q-spinner v-else/>
|
||||||
|
|
||||||
@@ -44,14 +43,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {onBeforeMount, onMounted, ref} from 'vue'
|
import {onMounted, ref} from 'vue'
|
||||||
import NavigationButton from "components/navigation/NavigationButton.vue";
|
|
||||||
import {useUserStore} from "stores/User";
|
import {useUserStore} from "stores/User";
|
||||||
import {storeToRefs} from "pinia";
|
import {storeToRefs} from "pinia";
|
||||||
import BreadcrumbsNavigation from "components/navigation/BreadcrumbsNavigation.vue";
|
import BreadcrumbsNavigation from "components/navigation/BreadcrumbsNavigation.vue";
|
||||||
import {useAppStore} from "stores/App";
|
import {useAppStore} from "stores/App";
|
||||||
import {useMeta, useQuasar} from "quasar";
|
import {useQuasar} from "quasar";
|
||||||
import AvatarFromPhoto from "components/avatars/AvatarFromPhoto.vue";
|
|
||||||
import {useRouter} from "vue-router";
|
import {useRouter} from "vue-router";
|
||||||
import {successObject} from "src/composables/dialog";
|
import {successObject} from "src/composables/dialog";
|
||||||
import SidebarNavigation from "components/navigation/SidebarNavigation.vue";
|
import SidebarNavigation from "components/navigation/SidebarNavigation.vue";
|
||||||
@@ -61,17 +58,14 @@ const $q = useQuasar();
|
|||||||
const $router = useRouter();
|
const $router = useRouter();
|
||||||
|
|
||||||
const {pageTitle, breadcrumbs} = storeToRefs(useAppStore());
|
const {pageTitle, breadcrumbs} = storeToRefs(useAppStore());
|
||||||
useMeta(() => ({
|
|
||||||
title: pageTitle.value !== '' ? `${pageTitle.value} - Polétání.cz` : 'Polétání.cz'
|
|
||||||
}));
|
|
||||||
|
|
||||||
const leftDrawerOpen = ref(false)
|
const leftDrawerOpen = ref(false)
|
||||||
const toggleLeftDrawer = () => {
|
const toggleLeftDrawer = () => {
|
||||||
leftDrawerOpen.value = !leftDrawerOpen.value
|
leftDrawerOpen.value = !leftDrawerOpen.value
|
||||||
};
|
};
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onMounted(() => {
|
||||||
useUserStore().fetchLoggedUserDetail();
|
useUserStore().fetchLoggedUserDetail({refresh: true});
|
||||||
})
|
})
|
||||||
const {isQueryRunning, user} = storeToRefs(useUserStore());
|
const {isQueryRunning, user} = storeToRefs(useUserStore());
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<q-header>
|
<q-header>
|
||||||
<q-toolbar>
|
<q-toolbar>
|
||||||
<q-toolbar-title>
|
<q-toolbar-title>
|
||||||
{{ pageTitle }}
|
{{ pageTitle || "Polétání.cz" }}
|
||||||
</q-toolbar-title>
|
</q-toolbar-title>
|
||||||
|
|
||||||
<template v-if="loggedUser && loggedUser.id">
|
<template v-if="loggedUser && loggedUser.id">
|
||||||
@@ -35,24 +35,18 @@ import {storeToRefs} from "pinia";
|
|||||||
import {useUserStore} from "stores/User";
|
import {useUserStore} from "stores/User";
|
||||||
import {onMounted} from "vue";
|
import {onMounted} from "vue";
|
||||||
import {useAppStore} from "stores/App";
|
import {useAppStore} from "stores/App";
|
||||||
import {useMeta} from "quasar";
|
|
||||||
import BreadcrumbsNavigation from "components/navigation/BreadcrumbsNavigation.vue";
|
import BreadcrumbsNavigation from "components/navigation/BreadcrumbsNavigation.vue";
|
||||||
import AvatarFromPhoto from "components/avatars/AvatarFromPhoto.vue";
|
import AvatarFromPhoto from "components/avatars/AvatarFromPhoto.vue";
|
||||||
import {useRoute} from "vue-router";
|
|
||||||
|
|
||||||
const {pageTitle, breadcrumbs} = storeToRefs(useAppStore());
|
const {pageTitle, breadcrumbs} = storeToRefs(useAppStore());
|
||||||
const loggedUser = storeToRefs(useUserStore()).user;
|
const loggedUser = storeToRefs(useUserStore()).user;
|
||||||
|
|
||||||
useMeta(() => ({
|
|
||||||
title: pageTitle.value !== '' ? `${pageTitle.value} - Polétání.cz` : 'Polétání.cz'
|
|
||||||
}));
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
useUserStore().fetchLoggedUserDetail();
|
useUserStore().fetchLoggedUserDetail({refresh: false});
|
||||||
|
|
||||||
if (loggedUser || useUserStore().hasAccessToken()) {
|
if (loggedUser || useUserStore().hasAccessToken()) {
|
||||||
// poll once per 5 minutes to keep access token active
|
// poll once per 5 minutes to keep access token active
|
||||||
setInterval(useUserStore().fetchLoggedUserDetail, 5*60*1000);
|
setInterval(() => useUserStore().fetchLoggedUserDetail({refresh: false}), 5 * 60 * 1000);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -8,14 +8,16 @@ import {useAppStore} from "stores/App";
|
|||||||
import BasicInfoBanner from "components/banners/BasicInfoBanner.vue";
|
import BasicInfoBanner from "components/banners/BasicInfoBanner.vue";
|
||||||
import {useFlightsStore} from "stores/Flights";
|
import {useFlightsStore} from "stores/Flights";
|
||||||
import {storeToRefs} from "pinia";
|
import {storeToRefs} from "pinia";
|
||||||
|
import {useMeta} from "quasar";
|
||||||
|
import {metaData} from "src/composables/meta";
|
||||||
|
|
||||||
const $q = useQuasar();
|
const $q = useQuasar();
|
||||||
|
|
||||||
useAppStore().setPageTitle("Moje lety")
|
useMeta(() => metaData({
|
||||||
onMounted(() => {
|
title: "Moje lety"
|
||||||
useFlightsStore().fetch();
|
}));
|
||||||
})
|
|
||||||
|
|
||||||
|
useFlightsStore().fetch();
|
||||||
const {flights, isQueryRunning} = storeToRefs(useFlightsStore());
|
const {flights, isQueryRunning} = storeToRefs(useFlightsStore());
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
</script>
|
import {useMeta} from "quasar";
|
||||||
|
import {commonKeywords, metaData} from "src/composables/meta";
|
||||||
|
|
||||||
|
useMeta(() => metaData({
|
||||||
|
title: "",
|
||||||
|
description: "Polétání.cz je aplikace na ukládání a sdílení fotografií a tras z vyhlídkových letů.",
|
||||||
|
keywords: [...commonKeywords]
|
||||||
|
}));
|
||||||
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<q-layout view="lHh Lpr lFf" style="background: url('hp/bg.jpg'); background-size: cover;">
|
<q-layout view="lHh Lpr lFf" data-style="background: url('hp/bg.jpg'); background-size: cover;">
|
||||||
|
|
||||||
<q-header class="bg-semi-transparent text-black" elevated>
|
<q-header class="bg-semi-transparent text-black" elevated>
|
||||||
<q-toolbar>
|
<q-toolbar>
|
||||||
@@ -24,7 +31,7 @@
|
|||||||
|
|
||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
<div class="info-box bg-semi-transparent q-mx-lg q-py-lg q-px-lg rounded-borders">
|
<div class="info-box bg-semi-transparent q-mx-lg q-py-lg q-px-lg rounded-borders">
|
||||||
<div class="text-h3 text-center">Pochlub se polétáním</div>
|
<div class="text-h3 text-center">Fotogalerie ze vzduchu</div>
|
||||||
|
|
||||||
<q-timeline color="primary" class="q-my-lg">
|
<q-timeline color="primary" class="q-my-lg">
|
||||||
<q-timeline-entry title="Zaznamenej si let">
|
<q-timeline-entry title="Zaznamenej si let">
|
||||||
@@ -60,7 +67,7 @@
|
|||||||
</q-timeline>
|
</q-timeline>
|
||||||
|
|
||||||
<div class="text-center q-my-lg">
|
<div class="text-center q-my-lg">
|
||||||
<q-btn size="xl" :to="{name: 'registration'}" rounded color="secondary">Založit profil</q-btn>
|
<q-btn size="xl" :to="{name: 'registration'}" rounded color="secondary">Založit účet</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
<script setup>
|
<script>
|
||||||
import {useRoute} from "vue-router";
|
|
||||||
import PublicProfileSkeleton from "components/profile/PublicProfileSkeleton.vue";
|
|
||||||
import {storeToRefs} from "pinia";
|
|
||||||
import {useUserStore} from "stores/User";
|
import {useUserStore} from "stores/User";
|
||||||
import PilotProfileCard from "components/profile/PilotProfileCard.vue";
|
|
||||||
import {onMounted} from "vue";
|
|
||||||
|
|
||||||
const loggedUser = storeToRefs(useUserStore()).user;
|
export default {
|
||||||
const username = useRoute().params.username;
|
preFetch({currentRoute}) {
|
||||||
|
return useUserStore().fetchPublicUserDetail(currentRoute.params.username);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {storeToRefs} from "pinia";
|
||||||
|
import PilotProfileCard from "components/profile/PilotProfileCard.vue";
|
||||||
|
import PublicProfileSkeleton from "components/profile/PublicProfileSkeleton.vue";
|
||||||
|
|
||||||
const {publicUser: pilot, isQueryRunning: pilotLoading} = storeToRefs(useUserStore());
|
const {publicUser: pilot, isQueryRunning: pilotLoading} = storeToRefs(useUserStore());
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
useUserStore().fetchPublicUserDetail(username);
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-md-8">
|
<div class="col-12 col-md-8">
|
||||||
<router-view :logged-user="loggedUser" :username="username"/>
|
<router-view :pilot="pilot"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-4">
|
<div class="col-12 col-md-4">
|
||||||
<PublicProfileSkeleton v-if="pilotLoading || !pilot"/>
|
<PublicProfileSkeleton v-if="pilotLoading && !pilot"/>
|
||||||
<PilotProfileCard v-else :pilot="pilot"/>
|
<PilotProfileCard v-else :pilot="pilot"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
<script setup>
|
|
||||||
import {useAircraftsStore} from "stores/Aircrafts";
|
|
||||||
import {onMounted} from "vue";
|
|
||||||
import {storeToRefs} from "pinia";
|
|
||||||
|
|
||||||
const {aircraft, isQueryRunning, aircrafts} = storeToRefs(useAircraftsStore());
|
|
||||||
onMounted(() => {
|
|
||||||
useAircraftsStore().fetch();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<template>
|
|
||||||
|
|
||||||
<q-spinner v-if="isQueryRunning" />
|
|
||||||
letadlo: {{ aircrafts }}
|
|
||||||
</template>
|
|
||||||
@@ -1,55 +1,45 @@
|
|||||||
|
<script>
|
||||||
|
import {useCopilotsStore} from "stores/Copilots";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
preFetch({currentRoute}) {
|
||||||
|
return useCopilotsStore().fetchDetail(currentRoute.params.id, currentRoute.params.username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {useRoute} from "vue-router";
|
|
||||||
import {onMounted} from "vue";
|
|
||||||
import FlightsList from "components/flights/FlightsList.vue";
|
import FlightsList from "components/flights/FlightsList.vue";
|
||||||
import {useAppStore} from "stores/App";
|
import {useAppStore} from "stores/App";
|
||||||
import BasicListSkeleton from "components/basicSkeletons/BasicListSkeleton.vue";
|
import BasicListSkeleton from "components/basicSkeletons/BasicListSkeleton.vue";
|
||||||
import {useUserStore} from "stores/User";
|
|
||||||
import {useCopilotsStore} from "stores/Copilots";
|
|
||||||
import {storeToRefs} from "pinia";
|
import {storeToRefs} from "pinia";
|
||||||
|
|
||||||
const $route = useRoute();
|
|
||||||
const copilotId = parseInt($route.params.id);
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
loggedUser: {
|
pilot: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
|
|
||||||
username: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const {copilot, isQueryRunning} = storeToRefs(useCopilotsStore());
|
const {copilot, isQueryRunning} = storeToRefs(useCopilotsStore());
|
||||||
const {publicUser, isQueryRunning: isPilotQueryRunning} = storeToRefs(useUserStore());
|
|
||||||
|
|
||||||
onMounted(() => {
|
useAppStore().setPageTitle(`${pilot.name} + ${copilot.value.name}`);
|
||||||
Promise.all([
|
|
||||||
useUserStore().fetchPublicUserDetail(props.username),
|
|
||||||
useCopilotsStore().fetchDetail(copilotId, props.username)
|
|
||||||
]).then(() => {
|
|
||||||
useAppStore().setPageTitle(`${publicUser.value.name} + ${copilot.value.name}`);
|
|
||||||
useAppStore().setBreadcrumbs([
|
useAppStore().setBreadcrumbs([
|
||||||
{to: {name: 'homepage'}, label: "Polétání.cz"},
|
{to: {name: 'homepage'}, label: "Polétání.cz"},
|
||||||
{to: {name: "publicProfileDetail", params: {username: props.username}}, label: `@${props.username}`},
|
{to: {name: "publicProfileDetail", params: {username: props.username}}, label: `@${props.username}`},
|
||||||
{label: publicUser.value.name}
|
{label: props.pilot.name}
|
||||||
]);
|
]);
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<BasicListSkeleton v-if="isQueryRunning || isPilotQueryRunning || !copilot" class="q-mb-md"/>
|
<BasicListSkeleton v-if="isQueryRunning || !copilot" class="q-mb-md"/>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<h3>Společné lety</h3>
|
<h3>Společné lety</h3>
|
||||||
<FlightsList
|
<FlightsList
|
||||||
:items="copilot.flights"
|
:items="copilot.flights"
|
||||||
:route-detail="{name: 'publicFlightDetail', params: {username: username}}"
|
:route-detail="{name: 'publicFlightDetail', params: {username: pilot.publicUsername}}"
|
||||||
class="q-mb-md"
|
class="q-mb-md"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
|
<script>
|
||||||
|
import {useEventsStore} from "stores/Events";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
preFetch({currentRoute}) {
|
||||||
|
return useEventsStore().fetchDetail(currentRoute.params.id, currentRoute.params.username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {onMounted, watch} from "vue";
|
import {watch} from "vue";
|
||||||
import {useRoute} from "vue-router";
|
import {useRoute} from "vue-router";
|
||||||
import {useAppStore} from "stores/App";
|
import {useAppStore} from "stores/App";
|
||||||
import EventDetailSkeleton from "components/event/EventDetailSkeleton.vue";
|
import EventDetailSkeleton from "components/event/EventDetailSkeleton.vue";
|
||||||
import {FORMAT_DATE, formatDatetime} from "src/composables/datetimeUtils";
|
import {FORMAT_DATE, formatDatetime} from "src/composables/datetimeUtils";
|
||||||
import FlightsList from "components/flights/FlightsList.vue";
|
import FlightsList from "components/flights/FlightsList.vue";
|
||||||
import {useEventsStore} from "stores/Events";
|
|
||||||
import {useUserStore} from "stores/User";
|
|
||||||
import {storeToRefs} from "pinia";
|
import {storeToRefs} from "pinia";
|
||||||
|
|
||||||
const routeParams = useRoute().params;
|
const routeParams = useRoute().params;
|
||||||
onMounted(() => {
|
|
||||||
useEventsStore().fetchDetail(routeParams.id, routeParams.username);
|
|
||||||
useUserStore().fetchPublicUserDetail(routeParams.username);
|
|
||||||
})
|
|
||||||
|
|
||||||
const {isQueryRunning, event} = storeToRefs(useEventsStore());
|
const {isQueryRunning, event} = storeToRefs(useEventsStore());
|
||||||
|
|
||||||
@@ -26,7 +30,6 @@ watch(() => event.value, (newVal) => {
|
|||||||
{label: newVal.name}
|
{label: newVal.name}
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -1,43 +1,39 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import FlightsListSkeleton from "components/flights/FlightsListSkeleton.vue";
|
import FlightsListSkeleton from "components/flights/FlightsListSkeleton.vue";
|
||||||
import EventsList from "components/event/EventsList.vue";
|
import EventsList from "components/event/EventsList.vue";
|
||||||
import {onMounted, watch} from "vue";
|
|
||||||
import PublicFlightEventSwitcher from "components/navigation/PublicFlightEventSwitcher.vue";
|
import PublicFlightEventSwitcher from "components/navigation/PublicFlightEventSwitcher.vue";
|
||||||
import {useAppStore} from "stores/App";
|
import {useAppStore} from "stores/App";
|
||||||
import {useEventsStore} from "stores/Events";
|
import {useEventsStore} from "stores/Events";
|
||||||
import {storeToRefs} from "pinia";
|
import {storeToRefs} from "pinia";
|
||||||
|
import {useMeta} from "quasar";
|
||||||
|
import {commonKeywords, metaData} from "src/composables/meta";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
loggedUser: {
|
pilot: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: false
|
|
||||||
},
|
|
||||||
username: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(() => props.username, () => {
|
useMeta(() => metaData({
|
||||||
}, {immediate: true});
|
title: `${props.pilot.publicUsername} - Události`,
|
||||||
|
keywords: [...commonKeywords, "pilot"],
|
||||||
|
description: "Detail pilota na poletani.cz",
|
||||||
|
}));
|
||||||
|
|
||||||
onMounted(() => {
|
useAppStore().setPageTitle(`${props.pilot.publicUsername}`);
|
||||||
// const eventNameFormatted = eventName(newVal);
|
|
||||||
useAppStore().setPageTitle(`${props.username}`);
|
|
||||||
useAppStore().setBreadcrumbs([
|
useAppStore().setBreadcrumbs([
|
||||||
{to: {name: 'homepage'}, label: "Polétání.cz"},
|
{to: {name: 'homepage'}, label: "Polétání.cz"},
|
||||||
{to: {name: "publicProfileDetail", params: {username: props.username}}, label: `@${props.username}`},
|
{to: {name: "publicProfileDetail", params: {username: props.pilot.publicUsername}}, label: `@${props.pilot.publicUsername}`},
|
||||||
{label: "Události"}
|
{label: "Události"}
|
||||||
]);
|
]);
|
||||||
useEventsStore().fetch(props.username);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
useEventsStore().fetch(props.pilot.publicUsername);
|
||||||
const {isQueryRunning, events} = storeToRefs(useEventsStore());
|
const {isQueryRunning, events} = storeToRefs(useEventsStore());
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<PublicFlightEventSwitcher :username="username"/>
|
<PublicFlightEventSwitcher :username="pilot.publicUsername"/>
|
||||||
|
|
||||||
<FlightsListSkeleton v-if="isQueryRunning"/>
|
<FlightsListSkeleton v-if="isQueryRunning"/>
|
||||||
|
|
||||||
@@ -48,7 +44,7 @@ const {isQueryRunning, events} = storeToRefs(useEventsStore());
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<EventsList
|
<EventsList
|
||||||
:items="events"
|
:items="events"
|
||||||
:route-detail="{name: 'publicEventDetail', params: {username: username}}"
|
:route-detail="{name: 'publicEventDetail', params: {username: pilot.publicUsername}}"
|
||||||
class="q-mb-md"
|
class="q-mb-md"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,29 +1,45 @@
|
|||||||
|
<script>
|
||||||
|
import {useFlightsStore} from "stores/Flights";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
preFetch({currentRoute}) {
|
||||||
|
return useFlightsStore().fetchDetail(currentRoute.params.id, currentRoute.params.username)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
<script setup>
|
<script setup>
|
||||||
import {onMounted, watch} from "vue";
|
|
||||||
import {useRoute} from "vue-router";
|
|
||||||
import FlightTrackMap from "components/flights/FlightTrackMap.vue";
|
import FlightTrackMap from "components/flights/FlightTrackMap.vue";
|
||||||
import FlightBasicInfo from "components/flights/FlightBasicInfo.vue";
|
import FlightBasicInfo from "components/flights/FlightBasicInfo.vue";
|
||||||
import {useAppStore} from "stores/App";
|
import {useAppStore} from "stores/App";
|
||||||
import FlightDetailSkeleton from "components/flights/FlightDetailSkeleton.vue";
|
import FlightDetailSkeleton from "components/flights/FlightDetailSkeleton.vue";
|
||||||
import PhotoGallery from "components/photos/PhotoGallery.vue";
|
import PhotoGallery from "components/photos/PhotoGallery.vue";
|
||||||
import {storeToRefs} from "pinia";
|
import {storeToRefs} from "pinia";
|
||||||
import {useFlightsStore} from "stores/Flights";
|
|
||||||
import {flightName} from "src/composables/flight";
|
import {flightName} from "src/composables/flight";
|
||||||
|
import {useRoute} from "vue-router";
|
||||||
|
import {useUserStore} from "stores/User";
|
||||||
|
import {useMeta} from "quasar";
|
||||||
|
import {metaData} from "src/composables/meta";
|
||||||
|
|
||||||
|
const {isQueryRunning, flight} = storeToRefs(useFlightsStore());
|
||||||
const routeParams = useRoute().params;
|
const routeParams = useRoute().params;
|
||||||
onMounted(() => {
|
|
||||||
useFlightsStore().fetchDetail(routeParams.id, routeParams.username).then(f => {
|
const pilot = storeToRefs(useUserStore()).publicUser;
|
||||||
const flightNameFormatted = flightName(f);
|
|
||||||
|
const flightNameFormatted = flightName(flight.value);
|
||||||
useAppStore().setPageTitle(flightNameFormatted);
|
useAppStore().setPageTitle(flightNameFormatted);
|
||||||
useAppStore().setBreadcrumbs([
|
useAppStore().setBreadcrumbs([
|
||||||
{to: {name: 'homepage'}, label: "Polétání.cz"},
|
{to: {name: 'homepage'}, label: "Polétání.cz"},
|
||||||
{to: {name: "publicProfileDetail", params: {username: routeParams.username}}, label: `@${routeParams.username}`},
|
{to: {name: "publicProfileDetail", params: {username: routeParams.username}}, label: `@${routeParams.username}`},
|
||||||
{label: flightNameFormatted}
|
{label: flightNameFormatted}
|
||||||
]);
|
]);
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
const {isQueryRunning, flight} = storeToRefs(useFlightsStore());
|
useMeta(() => metaData({
|
||||||
|
title: `${flightNameFormatted} - ${pilot.value.name}`,
|
||||||
|
keywords: ["let", "výlet", "letadlo", pilot.value.name, flight.value.aircraft.callSign],
|
||||||
|
description: flight.description,
|
||||||
|
image: flight.coverPhoto?.url
|
||||||
|
}
|
||||||
|
))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -55,8 +71,6 @@ const {isQueryRunning, flight} = storeToRefs(useFlightsStore());
|
|||||||
<FlightTrackMap :flight="flight"/>
|
<FlightTrackMap :flight="flight"/>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
</q-card>
|
</q-card>
|
||||||
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -2,42 +2,40 @@
|
|||||||
import FlightsListSkeleton from "components/flights/FlightsListSkeleton.vue";
|
import FlightsListSkeleton from "components/flights/FlightsListSkeleton.vue";
|
||||||
import FlightsList from "components/flights/FlightsList.vue";
|
import FlightsList from "components/flights/FlightsList.vue";
|
||||||
import PublicFlightEventSwitcher from "components/navigation/PublicFlightEventSwitcher.vue";
|
import PublicFlightEventSwitcher from "components/navigation/PublicFlightEventSwitcher.vue";
|
||||||
import {onMounted} from "vue";
|
|
||||||
import {useAppStore} from "stores/App";
|
import {useAppStore} from "stores/App";
|
||||||
import {useUserStore} from "stores/User";
|
|
||||||
import {useFlightsStore} from "stores/Flights";
|
import {useFlightsStore} from "stores/Flights";
|
||||||
import {storeToRefs} from "pinia";
|
import {storeToRefs} from "pinia";
|
||||||
|
import {commonKeywords, metaData} from "src/composables/meta";
|
||||||
|
import {useMeta} from "quasar";
|
||||||
|
import {useUserStore} from "stores/User";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
loggedUser: {
|
pilot: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: false
|
required: true,
|
||||||
},
|
|
||||||
|
|
||||||
username: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
useMeta(() => metaData({
|
||||||
useUserStore().fetchPublicUserDetail(props.username).then(user => {
|
title: `${props.pilot.publicUsername} - Lety`,
|
||||||
useAppStore().setPageTitle(user.publicUsername);
|
keywords: [...commonKeywords, "pilot", props.pilot.publicUsername, props.pilot.name],
|
||||||
|
description: `Výlety publikované pilotem ${props.pilot.name}. ${props.pilot.publicUsername}: ${props.pilot.description}`,
|
||||||
|
image: props.pilot.titleImageUrl
|
||||||
|
}));
|
||||||
|
|
||||||
|
useAppStore().setPageTitle(props.pilot.publicUsername);
|
||||||
useAppStore().setBreadcrumbs([
|
useAppStore().setBreadcrumbs([
|
||||||
{to: {name: 'homepage'}, label: "Polétání.cz"},
|
{to: {name: 'homepage'}, label: "Polétání.cz"},
|
||||||
{label: `@${user.publicUsername}`},
|
{label: `@${props.pilot.publicUsername}`},
|
||||||
])
|
])
|
||||||
})
|
|
||||||
|
|
||||||
useFlightsStore().fetch(props.username);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
useFlightsStore().fetch(props.pilot.publicUsername);
|
||||||
const {flights, isQueryRunning: areFlightsLoading} = storeToRefs(useFlightsStore());
|
const {flights, isQueryRunning: areFlightsLoading} = storeToRefs(useFlightsStore());
|
||||||
const {publicUser: pilot} = storeToRefs(useUserStore());
|
const loggedUser = storeToRefs(useUserStore()).user;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<PublicFlightEventSwitcher :username="username" />
|
<PublicFlightEventSwitcher :username="pilot?.publicUsername"/>
|
||||||
|
|
||||||
<FlightsListSkeleton v-if="areFlightsLoading"/>
|
<FlightsListSkeleton v-if="areFlightsLoading"/>
|
||||||
|
|
||||||
@@ -48,8 +46,8 @@ const {publicUser: pilot} = storeToRefs(useUserStore());
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<FlightsList
|
<FlightsList
|
||||||
:items="flights"
|
:items="flights"
|
||||||
:displayVisibilityInfo="loggedUser.id === pilot.id"
|
:displayVisibilityInfo="loggedUser?.id === pilot?.id"
|
||||||
:route-detail="{name: 'publicFlightDetail', params: {username: username}}"
|
:route-detail="{name: 'publicFlightDetail', params: {username: pilot?.publicUsername}}"
|
||||||
class="q-mb-md"
|
class="q-mb-md"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import PlainLayout from "layouts/PlainLayout.vue";
|
import PlainLayout from "layouts/PlainLayout.vue";
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{path: '/test', name: "test", component: () => import('pages/public/TestPage.vue'), meta: {layout: PlainLayout}},
|
|
||||||
{path: '/login', name: "login", component: () => import('pages/public/LoginPage.vue'), meta: {layout: PlainLayout}},
|
{path: '/login', name: "login", component: () => import('pages/public/LoginPage.vue'), meta: {layout: PlainLayout}},
|
||||||
{path: '/registrace', name: "registration", component: () => import('pages/public/RegisterPage.vue'), meta: {layout: PlainLayout}},
|
{path: '/registrace', name: "registration", component: () => import('pages/public/RegisterPage.vue'), meta: {layout: PlainLayout}},
|
||||||
{path: '/zapomenute-heslo', name: "forgottenPassword", component: () => import('pages/public/RegisterPage.vue'), meta: {layout: PlainLayout}},
|
{path: '/zapomenute-heslo', name: "forgottenPassword", component: () => import('pages/public/RegisterPage.vue'), meta: {layout: PlainLayout}},
|
||||||
|
|||||||
+4
-3
@@ -7,9 +7,9 @@ export const useAppStore = defineStore('App', () => {
|
|||||||
const appStatus = ref(200); // TODO: toto nejspis nebude potreba!
|
const appStatus = ref(200); // TODO: toto nejspis nebude potreba!
|
||||||
|
|
||||||
const resetAfterRouteChange = () => {
|
const resetAfterRouteChange = () => {
|
||||||
setPageTitle("");
|
pageTitle.value = null;
|
||||||
setBreadcrumbs([]);
|
|
||||||
appStatus.value = 200;
|
appStatus.value = 200;
|
||||||
|
breadcrumbs.value = []
|
||||||
};
|
};
|
||||||
|
|
||||||
const setPageTitle = (value) => {
|
const setPageTitle = (value) => {
|
||||||
@@ -22,6 +22,7 @@ export const useAppStore = defineStore('App', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pageTitle, breadcrumbs, appStatus, resetAfterRouteChange, setPageTitle, setBreadcrumbs
|
pageTitle, breadcrumbs, appStatus,
|
||||||
|
resetAfterRouteChange, setPageTitle, setBreadcrumbs
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ export const useEventsStore = defineStore('Events', () => {
|
|||||||
const isMutationRunning = ref(false);
|
const isMutationRunning = ref(false);
|
||||||
const isQueryRunning = ref(false);
|
const isQueryRunning = ref(false);
|
||||||
|
|
||||||
const fetchDetail = (id) => {
|
const fetchDetail = (id, username) => {
|
||||||
return query({
|
return query({
|
||||||
isQueryRunning,
|
isQueryRunning,
|
||||||
query: EVENT_DETAIL,
|
query: EVENT_DETAIL,
|
||||||
variables: {id},
|
variables: {id, username},
|
||||||
}).then(item => event.value = item);
|
}).then(item => event.value = item);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import {FLIGHT_DETAIL, FLIGHTS_LIST} from "src/graphql/queries/flights";
|
|||||||
import {EDIT_FLIGHT, CREATE_FLIGHT, DELETE_FLIGHT} from "src/graphql/mutations/flight";
|
import {EDIT_FLIGHT, CREATE_FLIGHT, DELETE_FLIGHT} from "src/graphql/mutations/flight";
|
||||||
import {deleteFromItems, mutate, query, updateInItems} from "stores/helpers";
|
import {deleteFromItems, mutate, query, updateInItems} from "stores/helpers";
|
||||||
import {ref} from "vue";
|
import {ref} from "vue";
|
||||||
import {DELETE_AIRCRAFT} from "src/graphql/mutations/aircrafts";
|
|
||||||
|
|
||||||
export const useFlightsStore = defineStore('Flights', () => {
|
export const useFlightsStore = defineStore('Flights', () => {
|
||||||
const flight = ref(null);
|
const flight = ref(null);
|
||||||
@@ -58,57 +57,7 @@ export const useFlightsStore = defineStore('Flights', () => {
|
|||||||
}).then(item => deleteFromItems(flights.value, 'id', item))
|
}).then(item => deleteFromItems(flights.value, 'id', item))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
flight, flights, isMutationRunning, isQueryRunning, fetchDetail, fetch, create, update, destroy
|
flight, flights, isMutationRunning, isQueryRunning, fetchDetail, fetch, create, update, destroy
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// actions: {
|
|
||||||
// create(formData) {
|
|
||||||
// delete formData['id'];
|
|
||||||
// return apolloWrapper.mutate(CREATE_FLIGHT, {input: formData}).then(({data}) => {
|
|
||||||
// const flightId = data.createFlight.id;
|
|
||||||
//
|
|
||||||
// // pitomy ohack kvuli tomu, ze se mi nedari dostat z API rovnou informace o nove vytvorenem letadle
|
|
||||||
// this.fetchDetail(flightId).then(flight => {
|
|
||||||
// this.items.push(flight);
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// return data.createFlight;
|
|
||||||
// })
|
|
||||||
// },
|
|
||||||
// update(id, formData) {
|
|
||||||
// this.isMutationRunning = true;
|
|
||||||
// return apolloWrapper.mutate(EDIT_FLIGHT, {id: id, input: formData}).then(({data}) => {
|
|
||||||
// const flight = data.editFlight;
|
|
||||||
// updateInItems(this.items, "id", flight);
|
|
||||||
//
|
|
||||||
// return flight;
|
|
||||||
// }).finally(() => this.isMutationRunning = false);
|
|
||||||
// },
|
|
||||||
// fetchDetail(id, username = null) {
|
|
||||||
// if (typeof id !== "number") {
|
|
||||||
// id = parseInt(id);
|
|
||||||
// }
|
|
||||||
// return apolloWrapper.query(FLIGHT_DETAIL, {id, username}).then(result => result.data.flight);
|
|
||||||
// },
|
|
||||||
// fetch(username = null) {
|
|
||||||
// return apolloWrapper
|
|
||||||
// .query(FLIGHTS_LIST, {username})
|
|
||||||
// .then((resp) => {
|
|
||||||
// const data = resp.data;
|
|
||||||
// this.items = data.flights;
|
|
||||||
// return data.flights;
|
|
||||||
// }).catch(err => console.log(err));
|
|
||||||
// },
|
|
||||||
// delete(id) {
|
|
||||||
// return apolloWrapper.mutate(DELETE_FLIGHT, {id}).then(({data}) => {
|
|
||||||
//
|
|
||||||
// const idx = this.items.indexOf(this.items.find(f => f.id === id));
|
|
||||||
// this.items.splice(idx, 1);
|
|
||||||
//
|
|
||||||
// return data.deleteFlight;
|
|
||||||
// })
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
});
|
});
|
||||||
|
|||||||
+5
-2
@@ -12,9 +12,10 @@ export const useUserStore = defineStore('LoggedUser', () => {
|
|||||||
const isMutationRunning = ref(false);
|
const isMutationRunning = ref(false);
|
||||||
const isRefreshing = ref(false);
|
const isRefreshing = ref(false);
|
||||||
|
|
||||||
const fetchLoggedUserDetail = () => query({
|
const fetchLoggedUserDetail = ({refresh}) => query({
|
||||||
isQueryRunning,
|
isQueryRunning,
|
||||||
query: LOGGED_USER_DETAIL
|
query: LOGGED_USER_DETAIL,
|
||||||
|
refreshUnauthorized: refresh || false,
|
||||||
}).then(item => {
|
}).then(item => {
|
||||||
user.value = item;
|
user.value = item;
|
||||||
return item;
|
return item;
|
||||||
@@ -67,6 +68,8 @@ export const useUserStore = defineStore('LoggedUser', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getAccessToken = () => {
|
const getAccessToken = () => {
|
||||||
|
if (typeof localStorage === 'undefined') return null;
|
||||||
|
|
||||||
const tokenValidity = localStorage.getItem("accessTokenValidity");
|
const tokenValidity = localStorage.getItem("accessTokenValidity");
|
||||||
const now = new Date().getTime() / 1000;
|
const now = new Date().getTime() / 1000;
|
||||||
|
|
||||||
|
|||||||
@@ -17,15 +17,22 @@ export const deleteFromItems = (items, key, value) => {
|
|||||||
items.splice(idx, 1);
|
items.splice(idx, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const query = ({isQueryRunning, query, variables}) => {
|
export const query = ({isQueryRunning, query, variables, refreshUnauthorized}) => {
|
||||||
if (variables && variables.id) {
|
if (variables && variables.id) {
|
||||||
variables.id = parseInt(variables.id);
|
variables.id = parseInt(variables.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query._refreshUnauthorizedUser = refreshUnauthorized;
|
||||||
|
|
||||||
isQueryRunning.value = true;
|
isQueryRunning.value = true;
|
||||||
const queryName = query.definitions[0].selectionSet.selections[0].name.value;
|
const queryName = query.definitions[0].selectionSet.selections[0].name.value;
|
||||||
return apolloWrapper.query(query, variables)
|
return apolloWrapper.query(query, variables)
|
||||||
.then((result) => result.data[queryName])
|
.then((result) => {
|
||||||
|
if (!result || result.error || !result.data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return result.data[queryName]
|
||||||
|
})
|
||||||
.finally(() => isQueryRunning.value = false);
|
.finally(() => isQueryRunning.value = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user