-
+
-
+
@@ -50,16 +42,7 @@ const deleteFlight = (flightId) => {
{{ flight.aircraft.callSign }}
-
-
-
-
-
-
-
-
- Total: {{ minutesToHumanReadable(totalFlightTime) }}
diff --git a/src/components/flights/form/FlightFormPhotos.vue b/src/components/flights/form/FlightFormPhotos.vue
index de566cb..1c8fd1a 100644
--- a/src/components/flights/form/FlightFormPhotos.vue
+++ b/src/components/flights/form/FlightFormPhotos.vue
@@ -1,6 +1,7 @@
-
-
+
+
diff --git a/src/components/inputs/MapGPSInput.vue b/src/components/inputs/MapGPSInput.vue
index 5690584..7727e76 100644
--- a/src/components/inputs/MapGPSInput.vue
+++ b/src/components/inputs/MapGPSInput.vue
@@ -1,5 +1,67 @@
-
+
- Tu bude mapa s GPS pointerem
+
+
+
diff --git a/src/components/poi/POIEditForm.vue b/src/components/poi/POIEditForm.vue
index 686df71..54cc916 100644
--- a/src/components/poi/POIEditForm.vue
+++ b/src/components/poi/POIEditForm.vue
@@ -1,8 +1,10 @@
-
-
+
+
+
+
+
+
+
+
+
+
-
diff --git a/src/components/poi/POIList.vue b/src/components/poi/POIList.vue
index 7f5daf9..d57a77e 100644
--- a/src/components/poi/POIList.vue
+++ b/src/components/poi/POIList.vue
@@ -1,6 +1,4 @@
diff --git a/src/pages/profile/details/AircraftDetailPage.vue b/src/pages/profile/details/AircraftDetailPage.vue
index 0bb9a80..3716bc5 100644
--- a/src/pages/profile/details/AircraftDetailPage.vue
+++ b/src/pages/profile/details/AircraftDetailPage.vue
@@ -39,11 +39,11 @@ watch(aircraft, (newVal) => {
- {{ aircraft.callSign }}
-
+
-
+
+
Výrobce: {{ aircraft.manufacturer }}
@@ -53,7 +53,16 @@ watch(aircraft, (newVal) => {
- Delete
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/profile/details/CopilotDetailPage.vue b/src/pages/profile/details/CopilotDetailPage.vue
index 92304b7..1981d55 100644
--- a/src/pages/profile/details/CopilotDetailPage.vue
+++ b/src/pages/profile/details/CopilotDetailPage.vue
@@ -1,22 +1,21 @@
@@ -24,16 +23,12 @@ const totalFlightTime = computed(() => {
-
- Pilots
- {{ copilot.name }}
-
+ Společné lety
+
+ Zatím žádné společné lety
+
+
- {{ copilot.name }}
-
- Flights:
- {{ commonFlights }}
-
- Total time together: {{ minutesToHumanReadable(totalFlightTime) }}
+
diff --git a/src/pages/profile/details/FlightDetailPage.vue b/src/pages/profile/details/FlightDetailPage.vue
index e46c845..c9287ed 100644
--- a/src/pages/profile/details/FlightDetailPage.vue
+++ b/src/pages/profile/details/FlightDetailPage.vue
@@ -1,6 +1,6 @@
-
+
{
-
+
-
- -
- {{ poi.pointOfInterest.name }}
-
-
+
-
-
+
+
+
diff --git a/src/pages/profile/details/PointOfInterestDetailPage.vue b/src/pages/profile/details/PointOfInterestDetailPage.vue
index 386748d..1615709 100644
--- a/src/pages/profile/details/PointOfInterestDetailPage.vue
+++ b/src/pages/profile/details/PointOfInterestDetailPage.vue
@@ -4,11 +4,19 @@ import {useRoute} from "vue-router";
import POIDetailSkeleton from "components/poi/POIDetailSkeleton.vue";
import FAB from "components/FAB.vue";
import {fetchPoi, loading, poi} from "src/composables/objects/poi";
-import {flight} from "src/composables/objects/flight";
import PhotosList from "components/photos/PhotosList.vue";
+import {useAppStore} from "stores/App";
+import MapWithMarker from "components/MapWithMarkers.vue";
onMounted(() => {
- fetchPoi(useRoute().params.id);
+ fetchPoi(useRoute().params.id).then(() => {
+ useAppStore().setPageTitle(`${poi.value.name}`);
+ useAppStore().setBreadcrumbs([
+ {to: {name: "poi"}, label: "Zajímavá místa"},
+ {label: poi.value.name},
+ ])
+ });
+
})
@@ -16,7 +24,13 @@ onMounted(() => {
- {{ poi.name }}
+
+
-import {useCopilotsStore} from "stores/Copilots";
+import {onMounted} from "vue";
+import {loading, copilot, fetchCopilot} from "src/composables/objects/copilot";
+import {useAppStore} from "stores/App";
+import CopilotEditSkeleton from "components/copilots/CopilotEditSkeleton.vue";
+import CopilotEditForm from "components/copilots/CopilotEditForm.vue";
import {useRoute} from "vue-router";
-import {useFlightsStore} from "stores/Flights";
-import {computed, onMounted} from "vue";
-import {storeToRefs} from "pinia";
-import {minutesToHumanReadable} from "src/composables/datetimeUtils";
-const secondPilotStore = useCopilotsStore();
-const flightsStore = useFlightsStore();
-const route = useRoute();
+const copilotId = parseInt(useRoute().params.id);
onMounted(() => {
- flightsStore.fetch();
-})
+ fetchCopilot(copilotId).then(() => {
+ useAppStore().setPageTitle(`${copilot.value.name} - editace`);
+ useAppStore().setBreadcrumbs([
+ {to: {name: "pilots"}, label: "Kopiloti"},
+ {to: {name: "pilotDetail", params: {id: copilotId}}, label: copilot.value.name},
+ {label: "Editace"}
+ ])
+ })
+});
-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);
-})
+
+
+
- Editace copilota
diff --git a/src/pages/profile/forms/EditFlightPage.vue b/src/pages/profile/forms/EditFlightPage.vue
index 020f5ba..61335ca 100644
--- a/src/pages/profile/forms/EditFlightPage.vue
+++ b/src/pages/profile/forms/EditFlightPage.vue
@@ -97,7 +97,7 @@ const openPhotoEdit = (photo) => {
-
+
@@ -133,17 +133,18 @@ const openPhotoEdit = (photo) => {
+
+
+
+
-
-
-
diff --git a/src/pages/profile/forms/EditPointOfInterestPage.vue b/src/pages/profile/forms/EditPointOfInterestPage.vue
index b63c658..c699569 100644
--- a/src/pages/profile/forms/EditPointOfInterestPage.vue
+++ b/src/pages/profile/forms/EditPointOfInterestPage.vue
@@ -5,23 +5,33 @@ import {onMounted} from "vue";
import {useRoute} from "vue-router";
import POIEditForm from "components/poi/POIEditForm.vue";
import {usePointsOfInterestStore} from "stores/PointsOfInterest";
+import {useAppStore} from "stores/App";
+import {useQuasar} from "quasar";
+import {successObject} from "src/composables/dialog";
const poiId = parseInt(useRoute().params.id);
onMounted(() => {
- fetchPoi(poiId)
+ fetchPoi(poiId).then(() => {
+ useAppStore().setPageTitle(`${poi.value.name} - editace`);
+ useAppStore().setBreadcrumbs([
+ {to: {name: "poi"}, label: "Zajímavá místa"},
+ {to: {name: "poiDetail", params: {id: poiId}}, label: poi.value.name},
+ {label: "Editace"},
+ ]);
+ });
})
+const $q = useQuasar();
const handleSave = (data) => {
usePointsOfInterestStore().update(poiId, data).then(respData => {
- console.log(respData);
+ $q.notify(successObject("Úspěšně uloženo"));
});
}
-
-
+
diff --git a/src/pages/profile/lists/AircraftsPage.vue b/src/pages/profile/lists/AircraftsPage.vue
index d806a14..2335309 100644
--- a/src/pages/profile/lists/AircraftsPage.vue
+++ b/src/pages/profile/lists/AircraftsPage.vue
@@ -13,7 +13,7 @@ onMounted(() => {
-
+
diff --git a/src/pages/profile/lists/SecondPilotPage.vue b/src/pages/profile/lists/CopilotsPage.vue
similarity index 58%
rename from src/pages/profile/lists/SecondPilotPage.vue
rename to src/pages/profile/lists/CopilotsPage.vue
index 2014837..de982ed 100644
--- a/src/pages/profile/lists/SecondPilotPage.vue
+++ b/src/pages/profile/lists/CopilotsPage.vue
@@ -4,17 +4,19 @@ import CopilotListSkeleton from "components/copilots/CopilotListSkeleton.vue";
import {fetchCopilots, loading, copilots} from "src/composables/objects/copilot";
import CopilotsList from "components/copilots/CopilotsList.vue";
import FAB from "components/FAB.vue";
+import {useAppStore} from "stores/App";
onMounted(() => {
fetchCopilots();
+ useAppStore().setPageTitle("Spolucestující");
})
-
-
-
-
-
+
+
+
+
+
diff --git a/src/pages/profile/lists/FlightsPage.vue b/src/pages/profile/lists/FlightsPage.vue
index 73b5ea2..f23cb30 100644
--- a/src/pages/profile/lists/FlightsPage.vue
+++ b/src/pages/profile/lists/FlightsPage.vue
@@ -19,7 +19,7 @@ onMounted(() => {
-
+
diff --git a/src/pages/profile/lists/PointsOfInterestPage.vue b/src/pages/profile/lists/PointsOfInterestPage.vue
index e2b6513..7d5ce9f 100644
--- a/src/pages/profile/lists/PointsOfInterestPage.vue
+++ b/src/pages/profile/lists/PointsOfInterestPage.vue
@@ -16,7 +16,7 @@ useAppStore().setPageTitle("Zajímavá místa")
-
+
diff --git a/src/router/index.js b/src/router/index.js
index 630dc23..5131356 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -1,7 +1,6 @@
-import { route } from 'quasar/wrappers'
-import { createRouter, createMemoryHistory, createWebHistory, createWebHashHistory } from 'vue-router'
+import {route} from 'quasar/wrappers'
+import {createRouter, createMemoryHistory, createWebHistory, createWebHashHistory} from 'vue-router'
import routes from './routes'
-import {useUserStore} from "stores/User";
import {useAppStore} from "stores/App";
/*
@@ -19,7 +18,7 @@ export default route(function (/* { store, ssrContext } */) {
: (process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory)
const Router = createRouter({
- scrollBehavior: () => ({ left: 0, top: 0 }),
+ scrollBehavior: () => ({left: 0, top: 0}),
routes,
// Leave this as is and make changes in quasar.conf.js instead!
@@ -28,25 +27,9 @@ export default route(function (/* { store, ssrContext } */) {
history: createHistory(process.env.VUE_ROUTER_BASE)
})
- Router.beforeEach(async (to) => {
- if (to.meta?.protected) {
- const userStore = useUserStore();
- // const $q = useQuasar();
-
- useAppStore().resetAfterRouteChange();
-
- userStore.setupCredentials().then(()=>{
- if (!userStore.user.id) {
- // console.log("neni prihlaseny")
- // $q.notify("No access token, login again!");
- Router.push({name: "login"});
- }
- }).catch(e => {
- // console.error("Error in router: ", e);
- });
-
- }
- })
+ Router.afterEach(async (to) => {
+ useAppStore().resetAfterRouteChange();
+ });
return Router
})
diff --git a/src/router/routes.js b/src/router/routes.js
index 49f2303..2b9e709 100644
--- a/src/router/routes.js
+++ b/src/router/routes.js
@@ -25,10 +25,10 @@ const routes = [
{path: 'poi/add', name: "addPOI", component: () => import('pages/profile/forms/NewPointOfInterestPage.vue')},
{path: 'poi/:id', name: "poiDetail", component: () => import('pages/profile/details/PointOfInterestDetailPage.vue')},
{path: 'poi/:id/edit', name: "poiEdit", component: () => import('pages/profile/forms/EditPointOfInterestPage.vue')},
- {path: 'pilots', name: "pilots", component: () => import('pages/profile/lists/SecondPilotPage.vue')},
+ {path: 'pilots', name: "pilots", component: () => import('pages/profile/lists/CopilotsPage.vue')},
{path: 'pilots/add', name: "addPilots", component: () => import('pages/profile/forms/NewCopilotPage.vue')},
{path: 'pilots/:id', name: "pilotDetail", component: () => import('pages/profile/details/CopilotDetailPage.vue')},
- {path: 'pilots/:id/edit', name: "pilotEdit", component: () => import('pages/profile/details/EditCopilotPage.vue')},
+ {path: 'pilots/:id/edit', name: "pilotEdit", component: () => import('pages/profile/forms/EditCopilotPage.vue')},
{path: 'aircrafts', name: "aircrafts", component: () => import('pages/profile/lists/AircraftsPage.vue')},
{path: 'aircrafts/new', name: "addAircraft", component: () => import('pages/profile/forms/NewAircraftsPage.vue')},
{path: 'aircrafts/:id', name: "aircraftDetail", component: () => import('pages/profile/details/AircraftDetailPage.vue')},
diff --git a/src/stores/App.js b/src/stores/App.js
index 2d3f2b2..bd8a5fe 100644
--- a/src/stores/App.js
+++ b/src/stores/App.js
@@ -1,5 +1,4 @@
import {defineStore} from 'pinia'
-import {useMeta} from "quasar";
export const useAppStore = defineStore('App', {
state: () => ({
@@ -13,10 +12,6 @@ export const useAppStore = defineStore('App', {
},
setPageTitle(pageTitle) {
this.pageTitle = pageTitle;
- useMeta({title: pageTitle !== '' ? `${pageTitle} - Polétání.cz` : 'Polétání.cz'});
-
-
- console.log("setPageTitle:", pageTitle);
},
setBreadcrumbs(breadcrumbs) {
this.breadcrumbs = breadcrumbs;
diff --git a/src/stores/User.js b/src/stores/User.js
index f7f06be..190ce4f 100644
--- a/src/stores/User.js
+++ b/src/stores/User.js
@@ -4,31 +4,42 @@ import {api} from "boot/axios";
export const useUserStore = defineStore('LoggedUser', {
state: () => ({
user: {},
- accessToken: null
}),
+
actions: {
-
- setAccessToken(token) {
- console.log(token);
- if (token) {
- localStorage.setItem("accessToken", token);
- }
- this.accessToken = localStorage.getItem("accessToken");
+ setTokens({access_token, access_token_validity}) {
+ const now = new Date().getTime() / 1000;
+ localStorage.setItem("accessToken", access_token);
+ localStorage.setItem("accessTokenValidity", now + access_token_validity);
},
+
getAccessToken() {
- if (!this.accessToken) {
- this.setAccessToken();
+ const tokenValidity = localStorage.getItem("accessTokenValidity");
+ const now = new Date().getTime() / 1000;
+
+ if (tokenValidity < now) {
+ localStorage.removeItem("accessToken");
+ localStorage.removeItem("accessTokenValidity");
}
- return this.accessToken;
+ return localStorage.getItem(`accessToken`);
},
- async setupCredentials() {
- // TODO: aktualne se vola s kazdym prechodem mezi routami, to je urcite zbytecne!
- await api.get("/me").then(({data}) => {
+ setupCredentials() {
+ return api.get("/me").then(({data}) => {
this.user = data;
- }).catch(e => {
- console.log(e);
+ return this.user;
+ }).catch(async ({response}) => {
+ console.log(response);
+
+ return response;
+ });
+ },
+
+ async refreshAccessToken() {
+ return api.post("/refresh").then(({data}) => {
+ this.setTokens(data);
+ return data.access_token;
});
},
@@ -40,25 +51,15 @@ export const useUserStore = defineStore('LoggedUser', {
},
async login(formData) {
-
- return api.post("/login", formData).then(response => {
- const data = response.data;
- console.log("data", data);
- this.setAccessToken(data.access_token);
+ return api.post("/login", formData).then(({data}) => {
+ this.setTokens(data);
this.user = data.user;
})
-
- // console.log("login", username, password);
- // Object.assign(this.user, {
- // id: 1,
- // email: "michal@kvacek.cz",
- // name: "Michal K.",
- // accessToken: "abcdef",
- // avatarImageUrl: "https://via.placeholder.com/50x50"
- // });
},
logout() {
Object.assign(this.user, {});
+ localStorage.removeItem("accessToken");
+ localStorage.removeItem("accessTokenValidity");
}
}
})
diff --git a/yarn.lock b/yarn.lock
index decc76c..7711308 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -63,6 +63,21 @@
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.36.0.tgz#9837f768c03a1e4a30bd304a64fb8844f0e72efe"
integrity sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==
+"@googlemaps/js-api-loader@^1.12.11":
+ version "1.16.2"
+ resolved "https://registry.yarnpkg.com/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz#3fe748e21243f8e8322c677a5525c569ae9cdbe9"
+ integrity sha512-psGw5u0QM6humao48Hn4lrChOM2/rA43ZCm3tKK9qQsEj1/VzqkCqnvGfEOshDbBQflydfaRovbKwZMF4AyqbA==
+ dependencies:
+ fast-deep-equal "^3.1.3"
+
+"@googlemaps/markerclusterer@^2.0.6":
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/@googlemaps/markerclusterer/-/markerclusterer-2.4.0.tgz#52ede8a186f264468d7100b4c27d2a866956af6f"
+ integrity sha512-yjHrqaaYMzclbPERoCP/6r2w+wJfTCW/+Wblr7eJ4dyQcRFeOxZ8bsdoqvsyj1UbgNt91ly2aiww8h0uDOD6zw==
+ dependencies:
+ fast-deep-equal "^3.1.3"
+ supercluster "^8.0.1"
+
"@graphql-typed-document-node/core@^3.1.1":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861"
@@ -1911,6 +1926,11 @@ jsonfile@^6.0.1:
optionalDependencies:
graceful-fs "^4.1.6"
+kdbush@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-4.0.2.tgz#2f7b7246328b4657dd122b6c7f025fbc2c868e39"
+ integrity sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==
+
kind-of@^6.0.2:
version "6.0.3"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
@@ -2086,11 +2106,6 @@ minimist@^1.2.6:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
-moment@^2.29.4:
- version "2.29.4"
- resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
- integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
-
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -2737,6 +2752,13 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
+supercluster@^8.0.1:
+ version "8.0.1"
+ resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-8.0.1.tgz#9946ba123538e9e9ab15de472531f604e7372df5"
+ integrity sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==
+ dependencies:
+ kdbush "^4.0.2"
+
supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
@@ -2939,6 +2961,15 @@ vue-router@^4.1.6:
dependencies:
"@vue/devtools-api" "^6.4.5"
+vue3-google-map@^0.15.0:
+ version "0.15.0"
+ resolved "https://registry.yarnpkg.com/vue3-google-map/-/vue3-google-map-0.15.0.tgz#83d996c23934ae06cd6d3e158fc2dd46ca7a18e1"
+ integrity sha512-Y0fyBa9feS3mFIsYnCdqGr2TQWtRAhs0Q2vTmrhD/kzyY9z7lqd5p8ZM+Axw7xsaUXP+NvvIdIP4TianIOubkQ==
+ dependencies:
+ "@googlemaps/js-api-loader" "^1.12.11"
+ "@googlemaps/markerclusterer" "^2.0.6"
+ fast-deep-equal "^3.1.3"
+
vue@^3.2.47:
version "3.2.47"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.47.tgz#3eb736cbc606fc87038dbba6a154707c8a34cff0"