Zaklad ssr
This commit is contained in:
+27
-25
@@ -2,6 +2,7 @@ import {boot} from 'quasar/wrappers'
|
||||
import axios from 'axios'
|
||||
import {useUserStore} from "stores/User";
|
||||
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: process.env.API_URL,
|
||||
withCredentials: true,
|
||||
@@ -12,37 +13,38 @@ const api = axios.create({
|
||||
},
|
||||
})
|
||||
|
||||
api.interceptors.request.use((config) => {
|
||||
const token = useUserStore().getAccessToken();
|
||||
if (token) {
|
||||
config.headers['Authorization'] = `Bearer ${token}`
|
||||
}
|
||||
export default boot(({app, store}) => {
|
||||
|
||||
if (['/refresh', '/login'].includes(config.url)) {
|
||||
delete config.headers['Authorization'];
|
||||
}
|
||||
api.interceptors.request.use((config) => {
|
||||
const token = useUserStore(store).getAccessToken();
|
||||
if (token) {
|
||||
config.headers['Authorization'] = `Bearer ${token}`
|
||||
}
|
||||
|
||||
return config;
|
||||
})
|
||||
if (['/refresh', '/login'].includes(config.url)) {
|
||||
delete config.headers['Authorization'];
|
||||
}
|
||||
|
||||
return config;
|
||||
})
|
||||
|
||||
// Response interceptor for API calls
|
||||
api.interceptors.response.use((response) => {
|
||||
return response
|
||||
}, async function (error) {
|
||||
const originalRequest = error.config;
|
||||
if (error.response.status === 401 && !['/refresh', '/login'].includes(originalRequest.url)) {
|
||||
const newToken = await useUserStore().refreshAccessToken().catch(err => {
|
||||
console.error(err);
|
||||
return Promise.reject("Logged out");
|
||||
})
|
||||
api.defaults.headers.common['Authorization'] = 'Bearer ' + newToken;
|
||||
return api(originalRequest);
|
||||
}
|
||||
return Promise.reject(error);
|
||||
});
|
||||
api.interceptors.response.use((response) => {
|
||||
return response
|
||||
}, async function (error) {
|
||||
const originalRequest = error.config;
|
||||
if (error.response.status === 401 && !['/refresh', '/login'].includes(originalRequest.url)) {
|
||||
const newToken = await useUserStore(store).refreshAccessToken().catch(err => {
|
||||
console.error(err);
|
||||
return Promise.reject("Logged out");
|
||||
})
|
||||
api.defaults.headers.common['Authorization'] = 'Bearer ' + newToken;
|
||||
return api(originalRequest);
|
||||
}
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
|
||||
export default boot(({app}) => {
|
||||
// for use inside Vue files (Options API) through this.$axios and this.$api
|
||||
|
||||
// app.config.globalProperties.$axios = axios
|
||||
|
||||
@@ -13,7 +13,7 @@ import BasicTextSkeleton from "components/basicSkeletons/BasicTextSkeleton.vue";
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section class="q-my-md">
|
||||
<BasicTextSkeleton :paragraphs="1" :lines="randomInt(1, 3)"/>
|
||||
<BasicTextSkeleton :paragraphs="1" :lines="2"/>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup>
|
||||
import {randomInt} from "src/composables/random";
|
||||
import {onBeforeMount, onMounted, ref} from "vue";
|
||||
|
||||
const props = defineProps({
|
||||
itemsCountMin: {
|
||||
@@ -12,13 +13,18 @@ const props = defineProps({
|
||||
required:false,
|
||||
default: 5
|
||||
}
|
||||
});
|
||||
|
||||
const items = ref(0);
|
||||
onMounted(() => {
|
||||
items.value = randomInt(props.itemsCountMin, props.itemsCountMax);
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-list bordered separator>
|
||||
<q-item v-ripple v-for="i in randomInt(itemsCountMin, itemsCountMax)" :key="i">
|
||||
<q-item v-ripple v-for="i in items" :key="i">
|
||||
<q-item-section avatar>
|
||||
<q-skeleton type="QAvatar" />
|
||||
</q-item-section>
|
||||
|
||||
@@ -26,7 +26,7 @@ import BasicTextSkeleton from "components/basicSkeletons/BasicTextSkeleton.vue";
|
||||
</q-list>
|
||||
|
||||
<article class="q-my-lg">
|
||||
<BasicTextSkeleton :lines="randomInt(2, 5)" :paragraphs="randomInt(1, 2)" />
|
||||
<BasicTextSkeleton :lines="7" :paragraphs="2" />
|
||||
</article>
|
||||
|
||||
<q-skeleton height="400px" square class="q-mt-lg"/>
|
||||
|
||||
@@ -4,7 +4,7 @@ import {randomInt} from "src/composables/random";
|
||||
|
||||
<template>
|
||||
<q-list bordered separator class="q-mx-md q-my-md">
|
||||
<q-item v-for="i in randomInt(5, 10)" :key="i" ripple>
|
||||
<q-item v-for="i in 10" :key="i" ripple>
|
||||
<q-item-section avatar>
|
||||
<q-avatar size="100px">
|
||||
<q-skeleton type="QAvatar" size="100px"></q-skeleton>
|
||||
@@ -12,7 +12,6 @@ import {randomInt} from "src/composables/random";
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-skeleton :width="randomInt(30,50)+'%'"/>
|
||||
|
||||
<q-skeleton type="text" :width="randomInt(10,15)+'%'"/>
|
||||
<q-skeleton type="text" :width="randomInt(5,10)+'%'"/>
|
||||
<q-skeleton type="text" width="8%"/>
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
<script setup>
|
||||
import {onMounted, onUnmounted, ref} from "vue";
|
||||
import PhotoSwipeLightbox from "photoswipe/lightbox";
|
||||
import {onMounted, onUnmounted} from "vue";
|
||||
import 'photoswipe/style.css';
|
||||
import "photoswipe-dynamic-caption-plugin/photoswipe-dynamic-caption-plugin.css";
|
||||
import PhotoSwipeDynamicCaption from "photoswipe-dynamic-caption-plugin";
|
||||
import MapWithMarkers from "components/map/MapWithMarkers.vue";
|
||||
import {formatDatetime} from "src/composables/datetimeUtils";
|
||||
import EmbeddedMap from "components/map/EmbeddedMap.vue";
|
||||
import {roundWithPrecision} from "../../composables/utils";
|
||||
import PhotoSwipeDynamicCaption from "../../../node_modules/photoswipe-dynamic-caption-plugin/photoswipe-dynamic-caption-plugin.esm";
|
||||
import PhotoCaption from "components/photos/PhotoCaption.vue";
|
||||
import PhotoSwipeLightbox from "../../../node_modules/photoswipe/dist/photoswipe-lightbox.esm"
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
@@ -25,7 +21,6 @@ const props = defineProps({
|
||||
|
||||
let $lightbox = null;
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
if (!$lightbox) {
|
||||
$lightbox = new PhotoSwipeLightbox({
|
||||
|
||||
@@ -6,12 +6,12 @@ import BasicTextSkeleton from "components/basicSkeletons/BasicTextSkeleton.vue";
|
||||
<template>
|
||||
<div>
|
||||
|
||||
<BasicTextSkeleton :lines="randomInt(4, 8)" />
|
||||
<BasicTextSkeleton :lines="4" />
|
||||
|
||||
<q-skeleton type="rect" width="100%" class="q-my-lg" height="400px"/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-4 col-md-4 col-lg-3" v-for="i in randomInt(3, 10)" :key="i">
|
||||
<div class="col-12 col-sm-4 col-md-4 col-lg-3" v-for="i in 6" :key="i">
|
||||
<q-card class="q-my-sm q-mx-sm">
|
||||
<q-skeleton type="rect" width="100%" height="200px"/>
|
||||
</q-card>
|
||||
|
||||
@@ -15,7 +15,7 @@ import {randomInt} from "src/composables/random";
|
||||
<q-skeleton class="inline-block" type="text" height="40px" :width="`${randomInt(60, 90)}%`"/>
|
||||
</div>
|
||||
<div class="q-mt-lg">
|
||||
<BasicTextSkeleton :lines="randomInt(1, 5)" :paragraphs="1"/>
|
||||
<BasicTextSkeleton :lines="3" :paragraphs="1"/>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
|
||||
+17
-17
@@ -3,23 +3,23 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {storeToRefs} from "pinia";
|
||||
import {useUserStore} from "stores/User";
|
||||
import {onMounted} from "vue";
|
||||
import {useAppStore} from "stores/App";
|
||||
import {useMeta} from "quasar";
|
||||
// import {storeToRefs} from "pinia";
|
||||
// import {useUserStore} from "stores/User";
|
||||
// import {onMounted} from "vue";
|
||||
// import {useAppStore} from "stores/App";
|
||||
// import {useMeta} from "quasar";
|
||||
|
||||
const {pageTitle} = storeToRefs(useAppStore());
|
||||
const loggedUser = storeToRefs(useUserStore()).user;
|
||||
|
||||
useMeta(() => ({
|
||||
title: pageTitle.value !== '' ? `${pageTitle.value} - Polétání.cz` : 'Polétání.cz'
|
||||
}));
|
||||
|
||||
onMounted(() => {
|
||||
if (useUserStore().getAccessToken()) {
|
||||
useUserStore().fetchLoggedUserDetail();
|
||||
}
|
||||
})
|
||||
// const {pageTitle} = storeToRefs(useAppStore());
|
||||
const loggedUser = null;//storeToRefs(useUserStore()).user;
|
||||
//
|
||||
// useMeta(() => ({
|
||||
// title: pageTitle.value !== '' ? `${pageTitle.value} - Polétání.cz` : 'Polétání.cz'
|
||||
// }));
|
||||
//
|
||||
// onMounted(() => {
|
||||
// if (useUserStore().getAccessToken()) {
|
||||
// useUserStore().fetchLoggedUserDetail();
|
||||
// }
|
||||
// })
|
||||
|
||||
</script>
|
||||
|
||||
@@ -43,7 +43,7 @@ watch(() => [adjustment.value, croppedAreaForPreview.value], debounce(() => {
|
||||
const savePhotoAdjustment = (photoId) => {
|
||||
const adjustmentInput = {...adjustment.value};
|
||||
|
||||
if (croppedArea.value.left !== null) {
|
||||
if (croppedArea.value && croppedArea.value.left !== null) {
|
||||
adjustmentInput.crop = {...croppedArea.value}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<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>
|
||||
+2
-11
@@ -3,16 +3,7 @@ import {createRouter, createMemoryHistory, createWebHistory, createWebHashHistor
|
||||
import routes from './routes'
|
||||
import {useAppStore} from "stores/App";
|
||||
|
||||
/*
|
||||
* If not building with SSR mode, you can
|
||||
* directly export the Router instantiation;
|
||||
*
|
||||
* The function below can be async too; either use
|
||||
* async/await or return a Promise which resolves
|
||||
* with the Router instance.
|
||||
*/
|
||||
|
||||
export default route(function (/* { store, ssrContext } */) {
|
||||
export default route(function ({ store }) {
|
||||
const createHistory = process.env.SERVER
|
||||
? createMemoryHistory
|
||||
: (process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory)
|
||||
@@ -29,7 +20,7 @@ export default route(function (/* { store, ssrContext } */) {
|
||||
|
||||
Router.afterEach(async (to, from) => {
|
||||
if (from.name !== to.name) {
|
||||
useAppStore().resetAfterRouteChange();
|
||||
useAppStore(store).resetAfterRouteChange();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import PlainLayout from "layouts/PlainLayout.vue";
|
||||
|
||||
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: '/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}},
|
||||
@@ -68,10 +69,10 @@ const routes = [
|
||||
|
||||
// Always leave this as last one,
|
||||
// but you can also remove it
|
||||
{
|
||||
path: '/:catchAll(.*)*',
|
||||
component: () => import('pages/ErrorNotFound.vue')
|
||||
}
|
||||
// {
|
||||
// path: '/:catchAll(.*)*',
|
||||
// component: () => import('pages/ErrorNotFound.vue')
|
||||
// }
|
||||
]
|
||||
|
||||
export default routes
|
||||
|
||||
Reference in New Issue
Block a user