Avatar do admina, pridani debrief informaci

This commit is contained in:
Michal Kváček
2024-01-20 22:08:49 +01:00
parent b0aa6b5628
commit 08a3cbf3d9
12 changed files with 145 additions and 74 deletions
+32 -19
View File
@@ -9,40 +9,53 @@ const year = ref(date.getFullYear());
<q-footer class="q-pa-lg q-mt-xl">
<div class="row justify-center">
<div class="col-4 text-center">
<q-img fit="contain" width="32px" src="/icons/favicon-32x32.png" />
<div class="col-xs-12 col-md-4 text-center q-py-lg" style="font-size: 130%">
<q-img fit="contain" width="32px" src="/icons/favicon-32x32.png"/>
<div class="text-h5">Polétání.cz</div>
Vytvořeno s &hearts; nejen pro létání.
Vytvořeno s <q-icon name="favorite" color="red"/> nejen pro létání.
</div>
<div class="col-2">
<div class="col-xs-6 col-md-2">
<q-list>
<q-item><router-link :to="{name: 'about'}">O projektu</router-link></q-item>
<q-item><router-link :to="{name: 'contact'}">Kontakt</router-link></q-item>
<q-item><router-link :to="{name: 'features'}">Funkce</router-link></q-item>
<q-item>
<router-link :to="{name: 'about'}">O projektu</router-link>
</q-item>
<q-item>
<router-link :to="{name: 'contact'}">Kontakt</router-link>
</q-item>
<q-item>
<router-link :to="{name: 'features'}">Funkce</router-link>
</q-item>
</q-list>
</div>
<div class="col-2">
<div class="col-xs-6 col-md-2">
<q-list>
<q-item><router-link :to="{name: 'login'}">Login</router-link></q-item>
<q-item><router-link :to="{name: 'registration'}">Registrace</router-link></q-item>
<q-item><router-link :to="{name: 'forgottenPassword'}">Zapomenuté heslo</router-link></q-item>
<q-item>
<router-link :to="{name: 'login'}">Login</router-link>
</q-item>
<q-item>
<router-link :to="{name: 'registration'}">Registrace</router-link>
</q-item>
<q-item>
<router-link :to="{name: 'forgottenPassword'}">Zapomenuté heslo</router-link>
</q-item>
</q-list>
</div>
<div class="col-2">
<div class="col-xs-12 col-md-2">
<q-list>
<q-item><router-link :to="{name: 'termsAndConditions'}">Podmínky použití</router-link></q-item>
<q-item><router-link :to="{name: 'personalInformation'}">Správa osobních údajů</router-link></q-item>
<q-item>
<router-link :to="{name: 'termsAndConditions'}">Podmínky použití</router-link>
</q-item>
<q-item>
<router-link :to="{name: 'personalInformation'}">Správa osobních údajů</router-link>
</q-item>
</q-list>
</div>
<!-- <div class="col">-->
<!-- &copy; 2023 Polétání.cz-->
<!-- </div>-->
</div>
<div class="row q-mt-lg">
<div class="col text-center">
&copy; {{ year }} Polétání.cz
</div>
&copy; {{ year }} Polétání.cz
</div>
</div>
</q-footer>
</template>
@@ -1,5 +1,5 @@
<script setup>
import {reactive, watch} from "vue";
import {reactive, ref, watch} from "vue";
import FormWrapper from "components/FormWrapper.vue";
import {setDefaultData} from "src/composables/form/formHandling";
import RichTextEditor from "components/inputs/RichTextEditor.vue";
@@ -19,16 +19,17 @@ const props = defineProps({
required: false,
},
isRequestPending: {
type: Boolean,
required: false,
default: false,
}
type: Boolean,
required: false,
default: false,
}
});
const formData = reactive({
name: "",
event: null,
description: "",
debriefingNotes: "",
urlSlug: "",
isPublic: null
})
@@ -46,12 +47,13 @@ watch(() => props.flight, (newVal) => {
}
}, {immediate: true});
const descriptionTab = ref("description");
</script>
<template>
<FormWrapper v-model="formData" :is-request-pending="props.isRequestPending">
<ComboboxInput :options="events" v-if="events" v-model="formData.event" label="Událost" v-bind="commonProps"/>
<q-input type="text" v-model="formData.name" label="Jméno letu" v-bind="commonProps" />
<q-input type="text" v-model="formData.name" label="Jméno letu" v-bind="commonProps"/>
<template v-if="loggedUser?.publicUsername">
<SlugInput
v-if="formData.isPublic"
@@ -63,6 +65,22 @@ watch(() => props.flight, (newVal) => {
/>
<q-checkbox v-model="formData.isPublic" label="Veřejný?"/>
</template>
<RichTextEditor v-model="formData.description" v-bind="commonProps" label="Popis letu, poznámky, ..."/>
<q-tabs v-model="descriptionTab" active-color="primary">
<q-tab name="description">Popis</q-tab>
<q-tab name="debriefing">Debriefing (soukromé poznámky)</q-tab>
</q-tabs>
<q-tab-panels v-model="descriptionTab">
<q-tab-panel name="description">
<RichTextEditor v-model="formData.description" v-bind="commonProps" height="30vh"/>
</q-tab-panel>
<q-tab-panel name="debriefing">
<RichTextEditor v-model="formData.debriefingNotes" v-bind="commonProps" height="20vh"/>
</q-tab-panel>
</q-tab-panels>
</FormWrapper>
</template>
-1
View File
@@ -46,7 +46,6 @@ const inputPrompt = () =>
const togglePublicVisibility = () => {
if (props.requireUrlSlug && !props.isPublic) {
inputPrompt().onOk((data) => {
console.log(data, urlSlugModel.value);
emits("changeVisibility", {isPublic: !props.isPublic, urlSlug: slugify(urlSlugModel.value)});
})
} else {
+8 -1
View File
@@ -56,5 +56,12 @@ const toolbar = [
</script>
<template>
<q-editor v-model="content" :definitions="definitions" :toolbar="toolbar" :height="height" :label="label" :rules="rules"/>
<q-editor
v-model="content"
:definitions="definitions"
:toolbar="toolbar"
:height="height"
v-bind="$attrs"
:rules="rules"
/>
</template>
@@ -6,8 +6,8 @@ import {randomInt} from "src/composables/random";
<template>
<q-breadcrumbs class="q-mx-md q-my-md">
<q-breadcrumbs-el> <q-skeleton :width="`${randomInt(30, 60)}px`" type="rect" /> </q-breadcrumbs-el>
<q-breadcrumbs-el> <q-skeleton :width="`${randomInt(40, 80)}px`" type="rect" /> </q-breadcrumbs-el>
<q-breadcrumbs-el> <q-skeleton :width="`${randomInt(100, 190)}px`" type="rect" /> </q-breadcrumbs-el>
<q-breadcrumbs-el> <q-skeleton :width="`${randomInt(200, 280)}px`" type="rect" /> </q-breadcrumbs-el>
</q-breadcrumbs>
+15 -17
View File
@@ -6,6 +6,8 @@ import {commonProps} from "src/composables/inputs";
import RichTextEditor from "components/inputs/RichTextEditor.vue";
import FormWrapper from "components/FormWrapper.vue";
import {setDefaultData} from "src/composables/form/formHandling";
import {slugify} from "src/composables/slugify";
import BasicInfoBanner from "components/banners/BasicInfoBanner.vue";
const props = defineProps({
user: {
@@ -13,12 +15,11 @@ const props = defineProps({
required: false,
default: null
},
isRequestPending: {
type: Boolean,
required: false,
default: false,
}
isRequestPending: {
type: Boolean,
required: false,
default: false,
}
})
const formData = reactive({
@@ -29,22 +30,19 @@ const formData = reactive({
watch(() => props.user, (newVal) => {
setDefaultData(formData, props.user)
}, {immediate: true});
watch(() => formData.publicUsername, (newVal) => {
formData.publicUsername = slugify(newVal);
}, {immediate: true})
</script>
<template>
<FormWrapper v-model="formData" :is-request-pending="props.isRequestPending">
<q-list>
<q-item v-if="user.publicUsername">
<router-link target="_blank" :to="{name: 'publicProfileDetail', params: {username: user.publicUsername}}">
@{{ user.publicUsername }}
</router-link>
</q-item>
<q-item v-else>
<q-icon name="" color="red"/>
Nastav si veřejné uživatelské jméno pro zpřístupnění profilu a sdílení záznamů s ostatními
</q-item>
</q-list>
<BasicInfoBanner style="padding: 0 !important" v-if="formData.publicUsername === ''">
Nastav si veřejné uživatelské jméno pro zpřístupnění profilu a sdílení záznamů s ostatními
</BasicInfoBanner>
<q-input v-model="formData.name" label="Jméno" v-bind="commonProps"/>
<q-input
+6
View File
@@ -6,3 +6,9 @@
margin-left: auto;
margin-right: auto;
}
.q-tab-panel {
@media (max-width: $breakpoint-sm) {
padding: 0;
}
}
+13 -11
View File
@@ -103,21 +103,23 @@ ${FRAGMENT_WEATHER_FULL_INFO}
export const FRAGMENT_FLIGHT_FULL_PRIVATE_INFO = gql`
fragment flightFullPrivateInfo on Flight {
...flightFullInfo
debriefingNotes
photos {
...photoFullInfo
...photoFullInfo
pointOfInterest {
id
name
}
copilots {
id
name
}
pointOfInterest {
id
name
}
copilots {
id
name
}
}
}
${FRAGMENT_FLIGHT_FULL_INFO}
${FRAGMENT_PHOTO_FULL_INFO}
`;
`;
+34 -2
View File
@@ -25,8 +25,39 @@
show-if-above
bordered
>
<q-img class="absolute-top" v-if="!isQueryRunning && user" :src="user.titleImageUrl" style="height: 150px"/>
<q-spinner v-else/>
<q-img
fit="cover"
class="absolute-top"
v-if="!isQueryRunning && user"
:src="user.titleImageUrl"
style="height: 150px"
>
<div class="bg-transparent absolute-bottom-right" v-if="user.publicUsername !== ''">
<router-link
v-if="user.avatarImageUrl"
target="_blank"
:to="{name: 'publicProfileDetail', params: {username: user.publicUsername}}"
>
<AvatarFromPhoto
class="shadow-9"
:size="40"
:src="user.avatarImageUrl"
/>
</router-link>
<q-btn
v-else
color="blue-1"
text-color="blue-9"
target="_blank"
:to="{name: 'publicProfileDetail', params: {username: user.publicUsername}}"
>
@{{ user.publicUsername }}
</q-btn>
</div>
</q-img>
<div class="absolute-top text-center bg-grey-2" style="padding-top: 40px; height: 150px;" v-else>
<q-spinner size="64px" color="grey-5"/>
</div>
<q-scroll-area style="height: calc(100% - 150px); margin-top: 150px; border-right: 1px solid #ddd">
<SidebarNavigation/>
@@ -66,6 +97,7 @@ import {successObject} from "src/composables/dialog";
import SidebarNavigation from "components/navigation/SidebarNavigation.vue";
import TopMenuButton from "components/navigation/TopMenuButton.vue";
import {metaData} from "src/composables/meta";
import AvatarFromPhoto from "components/avatars/AvatarFromPhoto.vue";
const $q = useQuasar();
const $router = useRouter();
+3 -8
View File
@@ -1,27 +1,23 @@
<script setup>
import {useRoute, useRouter} from "vue-router";
import {computed, onMounted, ref} from "vue";
import {useLoggedUserStore} from "stores/LoggedUser";
import {useAuthStore} from "stores/Auth";
const $route = useRoute();
const $router = useRouter();
const url = computed(() => $route.query.url || '/moje');
const showLoginInfo = ref(false);
onMounted(() => {
console.log(useAuthStore().getAccessToken());
useAuthStore().refreshAccessToken().then(() => {
$router.push($route.query.url)
$router.push(url.value)
}).catch(e => {
$router.push({name: "login"})
});
setTimeout(() => showLoginInfo.value = true, 1000);
setTimeout(() => $router.push(url), 10000);
setTimeout(() => $router.push(url.value), 10000);
});
</script>
@@ -29,7 +25,7 @@ onMounted(() => {
<template>
<div class="row justify-center">
<div class="col-4">
<div class="col-sm-12 col-4">
<transition
v-if="showLoginInfo"
appear
@@ -42,7 +38,6 @@ onMounted(() => {
<br>
<p class="q-my-lg">
Probíhá přihlašování. Za okamžik dojde k přesměrování. Pokud se tak nestane, klikni na tlačítko
</p>
</q-card-section>
<q-card-actions>
@@ -107,6 +107,12 @@ const togglePublicVisibility = (variables) => toggleVisibility({
<q-separator/>
<article class="q-my-lg" v-html="flight.debriefingNotes"/>
<BasicInfoBanner v-if="flight.debriegingNotes === ''">
Nezapomeň si poznamenat důležité informace pro debriefing. Tyto poznámky slouží jen pro tebe.
</BasicInfoBanner>
<q-separator/>
<ContentCardEditButton
:to="{name: 'flightEdit', params: {id: flightId, step: 'photos'}}"
label="Upravit fotografie"
+1 -6
View File
@@ -1,12 +1,9 @@
<script>
import {usePilotsStore} from "stores/Pilots";
import {useAppStore} from "stores/App";
export default {
preFetch({store, currentRoute}) {
return usePilotsStore(store).fetchPublicPilotDetail(currentRoute.params.username).catch(e => {
useAppStore().appStatus = 404;
});
return usePilotsStore(store).fetchPublicPilotDetail(currentRoute.params.username).catch(e => {});
},
}
</script>
@@ -16,8 +13,6 @@ import {storeToRefs} from "pinia";
import PilotProfileCard from "components/profile/PilotProfileCard.vue";
import PublicProfileSkeleton from "components/profile/skeletons/PublicProfileSkeleton.vue";
console.log("pilot profile wrapper");
const {pilot, isQueryRunning: pilotLoading} = storeToRefs(usePilotsStore());
</script>