Homepage, verejna cast, vetsi sada uprav a oprav
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
routeAdd: {
|
||||
type: Object,
|
||||
required: false
|
||||
},
|
||||
labelAdd: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: "Přidat"
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="q-pa-md q-gutter-sm">
|
||||
<q-banner class="bg-light-blue text-white">
|
||||
<template v-slot:avatar>
|
||||
<q-icon name="info"/>
|
||||
</template>
|
||||
<slot/>
|
||||
|
||||
<template v-slot:action v-if="routeAdd">
|
||||
<q-btn flat color="white" :to="routeAdd" :label="labelAdd"/>
|
||||
</template>
|
||||
</q-banner>
|
||||
</div>
|
||||
</template>
|
||||
@@ -47,7 +47,7 @@ const fullwidthBtn = computed(() => $q.screen.width <= $q.screen.sizes.md);
|
||||
color="primary"
|
||||
type="submit"
|
||||
size="lg"
|
||||
:class="{'q-my-lg': true, 'q-mx-lg': true, 'btn--fullwidth': fullwidthBtn}"
|
||||
:class="{'q-my-lg': true, 'q-mx-lg': !fullwidthBtn, 'btn--fullwidth': fullwidthBtn}"
|
||||
v-if="saveButton"
|
||||
:icon="props.saveButton.icon"
|
||||
:loading="props.isRequestPending"
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<script setup>
|
||||
|
||||
import {randomInt} from "src/composables/random";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-item>
|
||||
<q-item-section avatar>
|
||||
<q-skeleton type="QAvatar" size="30px"/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-skeleton type="text" :width="randomInt(50, 100)+'px'"/>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
@@ -1,10 +1,9 @@
|
||||
<script setup>
|
||||
|
||||
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, maxLength, minLength} from "src/composables/form/rules";
|
||||
import {isNumber, isRequired, maxLength, minLength} from "src/composables/form/rules";
|
||||
import {commonProps} from "src/composables/inputs";
|
||||
|
||||
const formData = reactive({
|
||||
@@ -24,14 +23,8 @@ const props = defineProps({
|
||||
});
|
||||
|
||||
const rules = {
|
||||
callSign: [
|
||||
isRequired,
|
||||
minLength(4),
|
||||
maxLength(8)
|
||||
],
|
||||
seats: [
|
||||
isNumber
|
||||
]
|
||||
callSign: [isRequired, minLength(4), maxLength(8)],
|
||||
seats: [isRequired, isNumber]
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
@@ -41,7 +34,7 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FormWrapper v-model="formData" :is-request-pending="isRequestPending">
|
||||
<FormWrapper v-model="formData" :is-request-pending="props.isRequestPending">
|
||||
<q-img :src="props.defaultValues.photoUrl" v-if="props.defaultValues.photoUrl"/>
|
||||
|
||||
<q-input
|
||||
@@ -67,8 +60,8 @@ onMounted(() => {
|
||||
|
||||
<q-input
|
||||
type="number"
|
||||
v-model="formData.seats"
|
||||
label="Počet míst"
|
||||
v-model.number="formData.seats"
|
||||
label="Počet míst (včetně pilota)"
|
||||
min="1"
|
||||
:rules="rules.seats"
|
||||
v-bind="commonProps"
|
||||
|
||||
@@ -7,6 +7,11 @@ const props = defineProps({
|
||||
flight: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
showCopilots: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@@ -70,16 +75,20 @@ const props = defineProps({
|
||||
{{ minutesToHumanReadable(flight.durationMinCalculated) }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item v-if="flight.copilot">
|
||||
<q-item-section avatar>
|
||||
<q-icon name="people"/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
Link jen pro prihlasene!
|
||||
<router-link :to="{name: 'copilotDetail', params: {id: flight.copilot.id}}">
|
||||
{{ flight.copilot.name }}
|
||||
</router-link>
|
||||
</q-item-section>
|
||||
<q-item v-if="flight.copilots?.length > 0">
|
||||
<q-list>
|
||||
<q-item v-for="copilot in flight.copilots" :key="copilot.id">
|
||||
<q-item-section avatar>
|
||||
<q-icon name="people"/>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<router-link :to="{name: 'copilotDetail', params: {id: copilot.id}}">
|
||||
{{ copilot.name }}
|
||||
</router-link>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-item>
|
||||
|
||||
</q-list>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,37 @@
|
||||
<script setup>
|
||||
import {randomInt} from "src/composables/random";
|
||||
import ListItemSkeleton from "components/ListItemSkeleton.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
skeleton
|
||||
<q-card class="flight-detail-card">
|
||||
<q-skeleton animation="fade" height="400px" square/>
|
||||
|
||||
<q-card-section>
|
||||
<q-list bordered separator>
|
||||
|
||||
<ListItemSkeleton/>
|
||||
<ListItemSkeleton/>
|
||||
|
||||
<q-item>
|
||||
<q-list>
|
||||
<ListItemSkeleton v-for="i in randomInt(2, 5)" :key="i"/>
|
||||
</q-list>
|
||||
</q-item>
|
||||
|
||||
<ListItemSkeleton/>
|
||||
<ListItemSkeleton/>
|
||||
|
||||
</q-list>
|
||||
|
||||
<article class="q-my-lg">
|
||||
<q-skeleton
|
||||
v-for="i in randomInt(5,8)" :key="i"
|
||||
type="text" :width="randomInt(90, 100)+'%'"
|
||||
/>
|
||||
</article>
|
||||
|
||||
<q-skeleton height="400px" square class="q-mt-lg"/>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup>
|
||||
import {onMounted, reactive, ref, watch} from "vue";
|
||||
import FormWrapper from "components/FormWrapper.vue";
|
||||
import {setDefaultData} from "src/composables/form/formHandling";
|
||||
import ComboboxInput from "components/inputs/ComboboxInput.vue";
|
||||
import {commonProps} from "src/composables/inputs";
|
||||
|
||||
const props = defineProps({
|
||||
flight: {
|
||||
@@ -16,28 +16,27 @@ const props = defineProps({
|
||||
});
|
||||
|
||||
const formData = reactive({
|
||||
copilot: null,
|
||||
copilots: [],
|
||||
})
|
||||
|
||||
const solo = ref(true);
|
||||
const solo = ref(false);
|
||||
watch(() => solo.value, (newVal) => {
|
||||
if (!newVal) {
|
||||
formData.copilot = null;
|
||||
formData.copilots = [];
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
if (props.flight) {
|
||||
setDefaultData(formData, props.flight);
|
||||
solo.value = !formData.copilot;
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => props.flight, (newVal) => {
|
||||
if (newVal) {
|
||||
formData.copilots = newVal.copilots.map(copilot => ({id: copilot.id, name: copilot.name}));
|
||||
solo.value = formData.copilots.length === 0;
|
||||
}
|
||||
}, {deep: true, immediate: true});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FormWrapper v-model="formData">
|
||||
|
||||
<q-btn-toggle
|
||||
spread
|
||||
no-caps
|
||||
@@ -48,14 +47,13 @@ onMounted(() => {
|
||||
|
||||
<div v-if="!solo">
|
||||
<ComboboxInput
|
||||
class="q-my-lg"
|
||||
outlined
|
||||
standout
|
||||
v-for="i in flight.aircraft.seats - 1"
|
||||
:key="i"
|
||||
v-bind="commonProps"
|
||||
:options="copilots"
|
||||
v-model="formData.copilot"
|
||||
:key="formData.copilot"
|
||||
v-model="formData.copilots[i-1]"
|
||||
:clearable="true"
|
||||
label="Druhy pilot"
|
||||
:label="i === 1 ? 'Kopilot' : 'Pasažér'"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ const filterFn = (val, update, abort) => {
|
||||
:v-bind="$attrs"
|
||||
>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item v-if="inputValue">
|
||||
<q-item-section avatar>
|
||||
<q-avatar text-color="green" size="32px" icon="add" />
|
||||
</q-item-section>
|
||||
|
||||
@@ -27,6 +27,7 @@ watch(
|
||||
map.fitBounds(bounds);
|
||||
}
|
||||
);
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -64,47 +64,48 @@ const showExtra = ref(false);
|
||||
@keyup.right="nextPhoto"
|
||||
>
|
||||
<q-card-section>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="text-center">
|
||||
<inner-image-zoom move-type="pan" :zoomScale="0.75" :hide-hint="true" :src="photo.url"/>
|
||||
</div>
|
||||
|
||||
<q-btn
|
||||
class="absolute all-pointer-events"
|
||||
round
|
||||
flat
|
||||
icon="info"
|
||||
:text-color="showExtra ? 'primary' : 'white'"
|
||||
style="background: rgba(0, 0, 0, 0.25); top: 8px; right: 8px"
|
||||
@click="showExtra = !showExtra"
|
||||
/>
|
||||
<q-btn
|
||||
class="absolute all-pointer-events"
|
||||
style="background: rgba(0, 0, 0, 0.25); top: 50%; left: 8px;"
|
||||
@click="prevPhoto"
|
||||
v-if="photoIndex > 0"
|
||||
icon="chevron_left"
|
||||
text-color="white"
|
||||
flat
|
||||
rounded
|
||||
>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
class="absolute all-pointer-events"
|
||||
style="background: rgba(0, 0, 0, 0.25); top: 50%; right: 8px;"
|
||||
@click="nextPhoto"
|
||||
v-if="photoIndex < photos.length - 1"
|
||||
icon-right="chevron_right"
|
||||
text-color="white"
|
||||
flat
|
||||
rounded
|
||||
>
|
||||
</q-btn>
|
||||
<strong v-if="photo.name !== ''">{{ photo.name }}</strong>
|
||||
<p v-if="photo.description !== ''">{{ photo.description }}</p>
|
||||
<div class="relative-position">
|
||||
<div class="text-center">
|
||||
<inner-image-zoom move-type="pan" :zoomScale="0.75" :hide-hint="true" :src="photo.url"/>
|
||||
</div>
|
||||
|
||||
<q-btn
|
||||
class="absolute all-pointer-events"
|
||||
round
|
||||
flat
|
||||
icon="info"
|
||||
:text-color="showExtra ? 'primary' : 'white'"
|
||||
style="background: rgba(0, 0, 0, 0.25); top: 8px; right: 8px"
|
||||
@click="showExtra = !showExtra"
|
||||
/>
|
||||
<q-btn
|
||||
class="absolute all-pointer-events"
|
||||
style="background: rgba(0, 0, 0, 0.25); top: 50%; left: 8px;"
|
||||
@click="prevPhoto"
|
||||
v-if="photoIndex > 0"
|
||||
icon="chevron_left"
|
||||
text-color="white"
|
||||
flat
|
||||
rounded
|
||||
>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
class="absolute all-pointer-events"
|
||||
style="background: rgba(0, 0, 0, 0.25); top: 50%; right: 8px;"
|
||||
@click="nextPhoto"
|
||||
v-if="photoIndex < photos.length - 1"
|
||||
icon-right="chevron_right"
|
||||
text-color="white"
|
||||
flat
|
||||
rounded
|
||||
>
|
||||
</q-btn>
|
||||
<strong v-if="photo.name !== ''">{{ photo.name }}</strong>
|
||||
<p v-if="photo.description !== ''">{{ photo.description }}</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-12 q-my-md" v-if="showExtra">
|
||||
<EmbeddedMap
|
||||
v-if="photo.gpsLatitude && photo.gpsLongitude"
|
||||
@@ -150,7 +151,6 @@ const showExtra = ref(false);
|
||||
<style>
|
||||
.iiz {
|
||||
width: 100%;
|
||||
height: 90vh;
|
||||
}
|
||||
|
||||
.iiz__img {
|
||||
|
||||
@@ -3,6 +3,7 @@ import {computed, ref} from "vue";
|
||||
import {setDefaultData} from "src/composables/form/formHandling";
|
||||
import DialogWrapper from "components/DialogWrapper.vue";
|
||||
import FormWrapper from "components/FormWrapper.vue";
|
||||
import {commonProps} from "src/composables/inputs";
|
||||
|
||||
const props = defineProps({
|
||||
photo: {
|
||||
@@ -32,8 +33,10 @@ const setup = (() => {
|
||||
|
||||
<q-card-section>
|
||||
<FormWrapper :save-button="false">
|
||||
<q-input v-model="formData.name" label="Název"/>
|
||||
<q-input type="textarea" v-model="formData.description" label="Popis"/>
|
||||
<q-input v-model="formData.name" label="Název" v-bind="commonProps"/>
|
||||
<q-input type="textarea" v-model="formData.description" label="Popis" v-bind="commonProps"/>
|
||||
|
||||
{{ locations }}
|
||||
|
||||
<q-select
|
||||
:options="locations"
|
||||
@@ -41,11 +44,12 @@ const setup = (() => {
|
||||
option-value="id"
|
||||
emit-value
|
||||
map-options
|
||||
v-bind="commonProps"
|
||||
v-model="formData.pointOfInterestId"
|
||||
label="POI"
|
||||
/>
|
||||
|
||||
<q-checkbox v-model="formData.isFlightCover" label="Úvodní fotografie k letu?" />
|
||||
<q-checkbox v-model="formData.isFlightCover" label="Úvodní fotografie k letu?"/>
|
||||
</FormWrapper>
|
||||
</q-card-section>
|
||||
</DialogWrapper>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<script setup>
|
||||
import {user as pilot} from "src/composables/objects/user";
|
||||
import {FORMAT_DATE, formatDatetime} from "src/composables/datetimeUtils";
|
||||
import AvatarFromPhoto from "components/AvatarFromPhoto.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-card flat style="margin: 0 auto; max-width: 400px">
|
||||
<q-img :src="pilot.titleImageUrl" v-if="pilot.titleImageUrl"/>
|
||||
<q-card-section>
|
||||
<div class="text-center" :style="`margin-top: ${pilot.titleImageUrl ? '-100' : '0'}px`">
|
||||
<AvatarFromPhoto :size="150" :src="pilot.avatarImageUrl" v-if="pilot.avatarImageUrl" class="q-mb-sm"/>
|
||||
<div class="text-h3">{{ pilot.name }}</div>
|
||||
<div class="text-subtitle1 text-weight-thin">
|
||||
Registrován: {{ formatDatetime(pilot.createdAt, FORMAT_DATE) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="q-my-lg" v-html="pilot.description"/>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
@@ -4,6 +4,7 @@ import {commonProps} from "src/composables/inputs";
|
||||
import {reactive, watch} from "vue";
|
||||
import {setDefaultData} from "src/composables/form/formHandling";
|
||||
import AvatarFromPhoto from "components/AvatarFromPhoto.vue";
|
||||
import {user as pilot} from "src/composables/objects/user";
|
||||
|
||||
const props = defineProps({
|
||||
user: {
|
||||
@@ -27,7 +28,7 @@ watch(() => props.user, (newVal) => {
|
||||
<FormWrapper v-model="formData">
|
||||
|
||||
<div class="text-center">
|
||||
<AvatarFromPhoto :size="200" :src="user.avatarImageUrl" />
|
||||
<AvatarFromPhoto :size="200" :src="user.avatarImageUrl" v-if="user.avatarImageUrl" />
|
||||
</div>
|
||||
|
||||
<q-file
|
||||
|
||||
@@ -26,19 +26,21 @@ watch(() => props.user, (newVal) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<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>
|
||||
|
||||
<FormWrapper v-model="formData">
|
||||
<q-input v-model="formData.name" label="Jméno" v-bind="commonProps"/>
|
||||
|
||||
<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>
|
||||
|
||||
<q-input v-model="formData.name" label="Jméno" v-bind="commonProps"/>
|
||||
<q-input
|
||||
v-model="formData.publicUsername"
|
||||
label="Veřejné uživatelské jméno"
|
||||
@@ -46,6 +48,6 @@ watch(() => props.user, (newVal) => {
|
||||
v-bind="commonProps"
|
||||
/>
|
||||
|
||||
<RichTextEditor v-model="formData.description" label="Veřejný podpis" />
|
||||
<RichTextEditor v-model="formData.description" label="Veřejný podpis"/>
|
||||
</FormWrapper>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<script setup> </script>
|
||||
|
||||
<template>Skeleton</template>
|
||||
Reference in New Issue
Block a user