diff --git a/docker-compose.yml b/docker-compose.yml
index 60b69c7..7fb378f 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,27 +1,27 @@
services:
-
- db:
- image: mariadb:10.11
- ports:
- - 3306:3306
- environment:
- - MYSQL_USER=root
- - MYSQL_DATABASE=ull_tracker
- - MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=true
- volumes:
- - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
- - db-data:/var/lib/mysql:rw
- api:
- build:
- context: ../api
- ports:
- - 8000:8000
- volumes:
- - ../api:/app
- environment:
- TZ: "Europe/Prague"
-# command: ls -l /app
+#
+# db:
+# image: mariadb:10.11
+# ports:
+# - 3306:3306
+# environment:
+# - MYSQL_USER=root
+# - MYSQL_DATABASE=ull_tracker
+# - MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=true
+# volumes:
+# - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
+# - db-data:/var/lib/mysql:rw
+# api:
+# build:
+# context: ../api
+# ports:
+# - 8000:8000
+# volumes:
+# - ../api:/app
+# environment:
+# TZ: "Europe/Prague"
+## command: ls -l /app
app:
build:
diff --git a/quasar.config.js b/quasar.config.js
index 2d1d769..edca8f8 100644
--- a/quasar.config.js
+++ b/quasar.config.js
@@ -90,7 +90,7 @@ module.exports = configure(function (/* ctx */) {
// Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer
devServer: {
// https: true
- open: true // opens browser window automatically
+ open: false // opens browser window automatically
},
// https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework
diff --git a/src/boot/axios.js b/src/boot/axios.js
index cc9d1c2..9de9913 100644
--- a/src/boot/axios.js
+++ b/src/boot/axios.js
@@ -19,7 +19,7 @@ api.interceptors.request.use((config) => {
config.headers['Authorization'] = `Bearer ${token}`
}
- if (config.url === '/refresh') {
+ if (['/refresh', '/login'].includes(config.url)) {
delete config.headers['Authorization'];
}
@@ -31,11 +31,9 @@ api.interceptors.response.use((response) => {
return response
}, async function (error) {
const originalRequest = error.config;
- if (error.response.status === 401 && !originalRequest._retry) {
- originalRequest._retry = true;
+ if (error.response.status === 401 && !['/refresh', '/login'].includes(originalRequest.url)) {
const newToken = await useUserStore().refreshAccessToken().catch(err => {
console.error(err);
- useRouter().push({to: "login"});
return Promise.reject("Logged out");
})
api.defaults.headers.common['Authorization'] = 'Bearer ' + newToken;
diff --git a/src/components/aircrafts/AircraftsListSkeleton.vue b/src/components/BasicListSkeleton.vue
similarity index 56%
rename from src/components/aircrafts/AircraftsListSkeleton.vue
rename to src/components/BasicListSkeleton.vue
index 908841d..995e781 100644
--- a/src/components/aircrafts/AircraftsListSkeleton.vue
+++ b/src/components/BasicListSkeleton.vue
@@ -1,10 +1,24 @@
-
+
diff --git a/src/components/FormWrapper.vue b/src/components/FormWrapper.vue
index a9bb9a6..fe6c61d 100644
--- a/src/components/FormWrapper.vue
+++ b/src/components/FormWrapper.vue
@@ -42,22 +42,23 @@ const fullwidthBtn = computed(() => $q.screen.width <= $q.screen.sizes.md);
-
+
+
+ {{ props.saveButton.label }}
-
- {{ props.saveButton.label }}
-
-
- Loading...
-
-
+
+ Loading...
+
+
+
diff --git a/src/components/aircrafts/AircraftForm.vue b/src/components/aircrafts/AircraftForm.vue
index e1c0e24..9ccbdd2 100644
--- a/src/components/aircrafts/AircraftForm.vue
+++ b/src/components/aircrafts/AircraftForm.vue
@@ -4,12 +4,14 @@ import {onMounted, reactive} from "vue";
import FormWrapper from "components/FormWrapper.vue";
import {setDefaultData} from "src/composables/form/formHandling";
import {defaultValues, isRequestPending} from "src/composables/form/props";
-import {isRequired} from "src/composables/form/rules";
+import {isRequired, maxLength, minLength} from "src/composables/form/rules";
+import {commonProps} from "src/composables/inputs";
const formData = reactive({
id: null,
callSign: "",
model: "",
+ seats: null,
manufacturer: "",
description: "",
photo: null,
@@ -23,8 +25,13 @@ const props = defineProps({
const rules = {
callSign: [
- v => isRequired(v)
+ isRequired,
+ minLength(4),
+ maxLength(8)
],
+ seats: [
+ isNumber
+ ]
};
onMounted(() => {
@@ -35,14 +42,49 @@ onMounted(() => {
-
-
-
-
+
+
- {{ props.defaultValues.photoUrl }}
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/copilots/CopilotListSkeleton.vue b/src/components/copilots/CopilotListSkeleton.vue
deleted file mode 100644
index f4ab8d8..0000000
--- a/src/components/copilots/CopilotListSkeleton.vue
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/components/flights/FlightsList.vue b/src/components/flights/FlightsList.vue
index 49fe9c3..4bbeca7 100644
--- a/src/components/flights/FlightsList.vue
+++ b/src/components/flights/FlightsList.vue
@@ -23,7 +23,7 @@ const props = defineProps({
-
+
-
-
-
-
- POI list skeleton
-
diff --git a/src/composables/form/rules.js b/src/composables/form/rules.js
index 4eae70b..6267231 100644
--- a/src/composables/form/rules.js
+++ b/src/composables/form/rules.js
@@ -1 +1,20 @@
-export const isRequired = (v) => !!v || "Required"
+export const isRequired = (val) => !!val || "Toto pole je povinné";
+export const isValidEmail = (email) => {
+ const patternEmail = /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,10})+$/;
+ return !!patternEmail.test(email) || "Tento e-mail není platný";
+};
+export const minLength = (length) => (val) => val.length >= length || `Zadej alespoň ${length} znaky`
+export const maxLength = (length) => (val) => val.length < length || `Zadej maximálně ${length} znaků`
+
+
+export const isEmptyArray = () => (val) => {
+ return (val && val.length !== 0) || "Select item, please";
+};
+
+export const isNumber = () => (val) => {
+ return !isNaN(val) || "Only numbers are allowed";
+};
+
+export const hasNoWhitespace = () => (val) => {
+ return /^\S*$/.test(val) || "Don't use whitespaces";
+};
diff --git a/src/layouts/ProfileLayout.vue b/src/layouts/ProfileLayout.vue
index f53e47d..9d5a044 100644
--- a/src/layouts/ProfileLayout.vue
+++ b/src/layouts/ProfileLayout.vue
@@ -15,23 +15,23 @@
{{ pageTitle || "Polétání.cz" }}
-
-
-
+
+
+
-
-
-
- Osobní nastavení
-
+
+
+
+ Osobní nastavení
+
-
- Odhlásit
-
+
+ Odhlásit
+
-
-
-
+
+
+
@@ -57,9 +57,11 @@
-
+
-
+
+
+
@@ -126,9 +128,9 @@ const $q = useQuasar();
const $router = useRouter();
const logout = () => {
-useUserStore().logout().then(() => {
- $q.notify(successObject("Odhlášení bylo úspěšné"));
- $router.push({name: "homepage"});
-})
+ useUserStore().logout().then(() => {
+ $q.notify(successObject("Odhlášení bylo úspěšné"));
+ $router.push({name: "homepage"});
+ })
}
diff --git a/src/pages/profile/forms/EditAircraftPage.vue b/src/pages/profile/forms/EditAircraftPage.vue
index 2151212..f537ecb 100644
--- a/src/pages/profile/forms/EditAircraftPage.vue
+++ b/src/pages/profile/forms/EditAircraftPage.vue
@@ -40,10 +40,14 @@ onMounted(() => {
-
+
+
+
+
+
+
diff --git a/src/pages/profile/forms/NewAircraftsPage.vue b/src/pages/profile/forms/NewAircraftsPage.vue
index 1debaf1..76853e8 100644
--- a/src/pages/profile/forms/NewAircraftsPage.vue
+++ b/src/pages/profile/forms/NewAircraftsPage.vue
@@ -3,8 +3,9 @@ import AircraftForm from "components/aircrafts/AircraftForm.vue";
import {useAircraftsStore} from "stores/Aircrafts";
import {useRouter} from "vue-router";
import {useQuasar} from "quasar";
-import {onMounted, ref} from "vue";
+import {ref} from "vue";
import {useAppStore} from "stores/App";
+import {successObject} from "src/composables/dialog";
let isRequestPending = ref(false);
const $q = useQuasar();
@@ -12,24 +13,25 @@ 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"});
-
+ $q.notify(successObject("Letadlo úspěšně vytvořeno"));
router.push({name: "aircrafts"});
}).finally(() => {
- isRequestPending.value = true;
+ isRequestPending.value = false;
})
}
-onMounted(() => {
- useAppStore().setPageTitle("Nové letadlo");
- useAppStore().setBreadcrumbs([
- {to: {name: "aircrafts"}, label: "Letadla"},
- {label: "Nové"}
- ]);
-});
+useAppStore().setPageTitle("Nové letadlo");
+useAppStore().setBreadcrumbs([
+ {to: {name: "aircrafts"}, label: "Letadla"},
+ {label: "Nové"}
+]);
-
+
+
+
+
+
diff --git a/src/pages/profile/lists/AircraftsPage.vue b/src/pages/profile/lists/AircraftsPage.vue
index 2335309..70a17a8 100644
--- a/src/pages/profile/lists/AircraftsPage.vue
+++ b/src/pages/profile/lists/AircraftsPage.vue
@@ -1,19 +1,34 @@
-
+
-
+
+
+
+
+
+ Aktuálně nemáš přidané žádné letadlo.
+
+
+
+
+
+
+
diff --git a/src/pages/profile/lists/CopilotsPage.vue b/src/pages/profile/lists/CopilotsPage.vue
index de982ed..c56bc47 100644
--- a/src/pages/profile/lists/CopilotsPage.vue
+++ b/src/pages/profile/lists/CopilotsPage.vue
@@ -1,10 +1,11 @@
-
+
+
+
+
+
+
+
+ Zatím tu není nikdo. Přidej si let s někým nebo kopilota vytvoř ručně tu.
+
+
+
+
+
+
+
-
-
-
diff --git a/src/pages/profile/lists/FlightsPage.vue b/src/pages/profile/lists/FlightsPage.vue
index f23cb30..0d39569 100644
--- a/src/pages/profile/lists/FlightsPage.vue
+++ b/src/pages/profile/lists/FlightsPage.vue
@@ -30,7 +30,7 @@ onMounted(() => {
-
+
diff --git a/src/pages/profile/lists/PointsOfInterestPage.vue b/src/pages/profile/lists/PointsOfInterestPage.vue
index 7d5ce9f..ea2742f 100644
--- a/src/pages/profile/lists/PointsOfInterestPage.vue
+++ b/src/pages/profile/lists/PointsOfInterestPage.vue
@@ -1,10 +1,10 @@
-
+
-
+
+
+
+
+
+ Nemáš tu uložené žádné zajímavé místo. Přidej si let, nastav si tam ručně trasu a jednotlivé body se zobrazí
+ i v tomto seznamu.
+
+
+
+
+
-
+
+
+
diff --git a/src/pages/public/RegisterPage.vue b/src/pages/public/RegisterPage.vue
index a1fd890..2831ea7 100644
--- a/src/pages/public/RegisterPage.vue
+++ b/src/pages/public/RegisterPage.vue
@@ -1,61 +1,74 @@
-
+
Registrace
-
-
+
+
-
+
-
+
@@ -63,7 +76,13 @@ const registerUser = () => {
-
+
Zpět na login