frontend: run lint

Signed-off-by: Nicolas Froger <nicolas@kektus.xyz>
This commit is contained in:
Nicolas Froger 2024-07-27 02:10:59 +02:00
commit 2647ac244d
No known key found for this signature in database
61 changed files with 426 additions and 592 deletions

View file

@ -1,134 +0,0 @@
[
{
"id": 4,
"date": "2022-07-01T22:20:43.000Z",
"location": {
"lat": 48.93071193154141,
"lon": 2.1544736306563346,
"city": "Sartrouville",
"country": "France"
},
"description": "je suis en train de me prendre en photo dans la rue",
"assets": [
"https://www.kektus.fr/img/DSC09764.jpg"
]
},
{
"id": 5,
"date": "2023-12-28T23:18:43.511Z",
"location": {
"lat": 45.8307086344589862,
"lon": -1.107245822424634,
"city": "Marennes-Hiers-Brouage",
"country": "France"
},
"description": "ce mec est très dangereux",
"assets": [
"https://www.kektus.fr/img/DSC00671.jpg"
]
},
{
"id": 6,
"date": "2024-07-21T18:25:43.511Z",
"location": {
"lat": 45.98963904301394,
"lon": -1.3010006132332887,
"city": "Saint-Georges-d'Oléron",
"country": "France"
},
"description": "ceci est une **plage** avec un très long texte.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque et viverra lacus, vitae ultrices urna. Nunc purus nulla, iaculis at turpis ac, pretium vestibulum odio. Nullam posuere, magna nec ornare interdum, purus sem malesuada lectus, eget mattis lacus turpis et diam. Quisque orci sapien, elementum vitae pretium a, varius vitae ante. Morbi elementum elementum dignissim. Nulla venenatis est et velit pharetra eleifend. Nunc eu eros et augue convallis laoreet feugiat nec purus.\n\n Nunc mi justo, tempus sed aliquet ac, vulputate non sem. Phasellus vel massa aliquam, dapibus neque vitae, convallis odio. Duis in massa bibendum, lacinia arcu vitae, varius enim. Aenean posuere hendrerit neque vel rhoncus. Morbi rutrum nunc vitae fringilla luctus. Phasellus sapien risus, tincidunt in finibus non, mattis ut est. Fusce vehicula efficitur nisi a ultricies. Mauris cursus ut sem vitae fringilla.",
"assets": [
"https://www.kektus.fr/img/DSC00684.jpg",
"https://www.kektus.fr/img/DSC00723.jpg",
"https://www.kektus.fr/img/DSC00739.jpg"
]
},
{
"id": 7,
"date": "2022-07-01T22:20:43.000Z",
"location": {
"lat": 48.93071193154141,
"lon": 2.1544736306563346,
"city": "Sartrouville",
"country": "France"
},
"description": "je suis en train de me prendre en photo dans la rue",
"assets": [
"https://www.kektus.fr/img/DSC09764.jpg"
]
},
{
"id": 8,
"date": "2023-12-28T23:18:43.511Z",
"location": {
"lat": 45.8307086344589862,
"lon": -1.107245822424634,
"city": "Marennes-Hiers-Brouage",
"country": "France"
},
"description": "ce mec est très dangereux",
"assets": [
"https://www.kektus.fr/img/DSC00671.jpg"
]
},
{
"id": 9,
"date": "2024-07-21T18:25:43.511Z",
"location": {
"lat": 45.98963904301394,
"lon": -1.3010006132332887,
"city": "Saint-Georges-d'Oléron",
"country": "France"
},
"description": "ceci est une **plage** avec un très long texte.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque et viverra lacus, vitae ultrices urna. Nunc purus nulla, iaculis at turpis ac, pretium vestibulum odio. Nullam posuere, magna nec ornare interdum, purus sem malesuada lectus, eget mattis lacus turpis et diam. Quisque orci sapien, elementum vitae pretium a, varius vitae ante. Morbi elementum elementum dignissim. Nulla venenatis est et velit pharetra eleifend. Nunc eu eros et augue convallis laoreet feugiat nec purus.\n\n Nunc mi justo, tempus sed aliquet ac, vulputate non sem. Phasellus vel massa aliquam, dapibus neque vitae, convallis odio. Duis in massa bibendum, lacinia arcu vitae, varius enim. Aenean posuere hendrerit neque vel rhoncus. Morbi rutrum nunc vitae fringilla luctus. Phasellus sapien risus, tincidunt in finibus non, mattis ut est. Fusce vehicula efficitur nisi a ultricies. Mauris cursus ut sem vitae fringilla.",
"assets": [
"https://www.kektus.fr/img/DSC00684.jpg",
"https://www.kektus.fr/img/DSC00723.jpg",
"https://www.kektus.fr/img/DSC00739.jpg"
]
},
{
"id": 10,
"date": "2022-07-01T22:20:43.000Z",
"location": {
"lat": 48.93071193154141,
"lon": 2.1544736306563346,
"city": "Sartrouville",
"country": "France"
},
"description": "je suis en train de me prendre en photo dans la rue",
"assets": [
"https://www.kektus.fr/img/DSC09764.jpg"
]
},
{
"id": 11,
"date": "2023-12-28T23:18:43.511Z",
"location": {
"lat": 45.8307086344589862,
"lon": -1.107245822424634,
"city": "Marennes-Hiers-Brouage",
"country": "France"
},
"description": "ce mec est très dangereux",
"assets": [
"https://www.kektus.fr/img/DSC00671.jpg"
]
},
{
"id": 12,
"date": "2024-07-21T18:25:43.511Z",
"location": {
"lat": 45.98963904301394,
"lon": -1.3010006132332887,
"city": "Saint-Georges-d'Oléron",
"country": "France"
},
"description": "ceci est une **plage** avec un très long texte.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque et viverra lacus, vitae ultrices urna. Nunc purus nulla, iaculis at turpis ac, pretium vestibulum odio. Nullam posuere, magna nec ornare interdum, purus sem malesuada lectus, eget mattis lacus turpis et diam. Quisque orci sapien, elementum vitae pretium a, varius vitae ante. Morbi elementum elementum dignissim. Nulla venenatis est et velit pharetra eleifend. Nunc eu eros et augue convallis laoreet feugiat nec purus.\n\n Nunc mi justo, tempus sed aliquet ac, vulputate non sem. Phasellus vel massa aliquam, dapibus neque vitae, convallis odio. Duis in massa bibendum, lacinia arcu vitae, varius enim. Aenean posuere hendrerit neque vel rhoncus. Morbi rutrum nunc vitae fringilla luctus. Phasellus sapien risus, tincidunt in finibus non, mattis ut est. Fusce vehicula efficitur nisi a ultricies. Mauris cursus ut sem vitae fringilla.",
"assets": [
"https://www.kektus.fr/img/DSC00684.jpg",
"https://www.kektus.fr/img/DSC00723.jpg",
"https://www.kektus.fr/img/DSC00739.jpg"
]
}
]

View file

@ -9,12 +9,16 @@ const appVersion = ref(import.meta.env.VITE_APP_VERSION)
<template>
<div class="fixed w-full top-0 z-50 flex items-center backdrop-blur-md bg-black/10 gap-2 px-3">
<a href="https://www.kektus.fr"
><h1 id="kektus" class="font-bold select-none mx-3 my-3 text-2xl hover:text-3xl transition-all duration-300">
kektus</h1></a
><h1
id="kektus"
class="font-bold select-none mx-3 my-3 text-2xl hover:text-3xl transition-all duration-300"
>
kektus
</h1></a
>
<h1 class="font-light text-lg my-2 mr-3">carnet de voyage été 2024</h1>
<div class="flex-grow"></div>
<RouterLink :to="{name: 'home'}">
<RouterLink :to="{ name: 'home' }">
<div class="p-2 bg-black/10 hover:bg-black/20 transition-colors duration-300 rounded-lg">
<Images size="20" />
</div>
@ -26,8 +30,11 @@ const appVersion = ref(import.meta.env.VITE_APP_VERSION)
</RouterLink>
</div>
<RouterView />
<p class="fixed right-0 bottom-0 z-50 p-1 font-extralight text-sm"><a
href="https://gitlab.kektus.xyz/kektus/services/summer2024" target="_blank">v{{ appVersion }}</a></p>
<p class="fixed right-0 bottom-0 z-50 p-1 font-extralight text-sm">
<a href="https://gitlab.kektus.xyz/kektus/services/summer2024" target="_blank"
>v{{ appVersion }}</a
>
</p>
</template>
<style scoped></style>

View file

@ -2,20 +2,20 @@
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap');
body {
font-family: 'Raleway', sans-serif;
font-family: 'Raleway', sans-serif;
}
#kektus {
font-family: 'Montserrat', sans-serif;
font-family: 'Montserrat', sans-serif;
}
.ol-zoom {
top: 120px !important;
left: .5em;
top: 120px !important;
left: 0.5em;
}
@media screen and (min-width: 500px) {
.ol-zoom {
top: 70px !important;
}
}
.ol-zoom {
top: 70px !important;
}
}

View file

@ -10,7 +10,7 @@ const countdownInterval = setInterval(() => {
const now = new Date().getTime()
const distance = countdownDate - now
if (distance < 0) {
countdownDisplay.value = 'c\'est parti !'
countdownDisplay.value = "c'est parti !"
clearInterval(countdownInterval)
return
}
@ -20,18 +20,20 @@ const countdownInterval = setInterval(() => {
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60))
const seconds = Math.floor((distance % (1000 * 60)) / 1000)
countdownDisplay.value = `${days} jour` + (days > 1 ? 's' : '') +
` ${hours} heure` + (hours > 1 ? 's' : '') +
` ${minutes} minute` + (minutes > 1 ? 's' : '') +
` ${seconds} seconde` + (seconds > 1 ? 's' : '')
countdownDisplay.value =
`${days} jour` +
(days > 1 ? 's' : '') +
` ${hours} heure` +
(hours > 1 ? 's' : '') +
` ${minutes} minute` +
(minutes > 1 ? 's' : '') +
` ${seconds} seconde` +
(seconds > 1 ? 's' : '')
}, 1000)
</script>
<template>
<p :class="props.class">{{ countdownDisplay }}</p>
</template>
<style scoped>
</style>
<style scoped></style>

View file

@ -14,42 +14,42 @@ const postActionBtn = ref(null)
function postDataToggle() {
if (postDataVisible.value) {
for (const data of postData.value) {
data.classList.remove('backdrop-blur-sm');
data.classList.remove('bg-gray-400/10');
data.classList.add('bg-gray-400/0');
data.classList.remove('backdrop-blur-sm')
data.classList.remove('bg-gray-400/10')
data.classList.add('bg-gray-400/0')
}
for (const title of postDataTitle.value) {
title.classList.add("opacity-0");
title.classList.add('opacity-0')
}
for (const desc of postDataDescription.value) {
desc.classList.add("opacity-0");
desc.classList.remove("scrollable-element");
desc.classList.add('opacity-0')
desc.classList.remove('scrollable-element')
}
for (const btn of postActionBtn.value) {
btn.classList.remove("top-0");
btn.classList.remove("right-0");
btn.classList.add("left-0");
btn.classList.add("bottom-0");
btn.classList.remove('top-0')
btn.classList.remove('right-0')
btn.classList.add('left-0')
btn.classList.add('bottom-0')
}
postDataVisible.value = false
} else {
for (const data of postData.value) {
data.classList.add('backdrop-blur-sm');
data.classList.add('bg-gray-400/10');
data.classList.remove('bg-gray-400/0');
data.classList.add('backdrop-blur-sm')
data.classList.add('bg-gray-400/10')
data.classList.remove('bg-gray-400/0')
}
for (const title of postDataTitle.value) {
title.classList.remove("opacity-0");
title.classList.remove('opacity-0')
}
for (const desc of postDataDescription.value) {
desc.classList.remove("opacity-0");
desc.classList.add("scrollable-element");
desc.classList.remove('opacity-0')
desc.classList.add('scrollable-element')
}
for (const btn of postActionBtn.value) {
btn.classList.add("top-0");
btn.classList.add("right-0");
btn.classList.remove("left-0");
btn.classList.remove("bottom-0");
btn.classList.add('top-0')
btn.classList.add('right-0')
btn.classList.remove('left-0')
btn.classList.remove('bottom-0')
}
postDataVisible.value = true
}
@ -83,5 +83,4 @@ function postDataToggle() {
</div>
</template>
<style scoped>
</style>
<style scoped></style>

View file

@ -1,11 +1,11 @@
<script setup>
import { alertVariants } from ".";
import { cn } from "@/lib/utils";
import { alertVariants } from '.'
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
variant: { type: null, required: false },
});
variant: { type: null, required: false }
})
</script>
<template>

View file

@ -1,9 +1,9 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>

View file

@ -1,9 +1,9 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>

View file

@ -1,21 +1,21 @@
import { cva } from "class-variance-authority";
import { cva } from 'class-variance-authority'
export { default as Alert } from "./Alert.vue";
export { default as AlertTitle } from "./AlertTitle.vue";
export { default as AlertDescription } from "./AlertDescription.vue";
export { default as Alert } from './Alert.vue'
export { default as AlertTitle } from './AlertTitle.vue'
export { default as AlertDescription } from './AlertDescription.vue'
export const alertVariants = cva(
"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground',
{
variants: {
variant: {
default: "bg-background text-foreground",
default: 'bg-background text-foreground',
destructive:
"border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
},
'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive'
}
},
defaultVariants: {
variant: "default",
},
},
);
variant: 'default'
}
}
)

View file

@ -1,20 +1,13 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>
<div
:class="
cn(
'rounded-lg border bg-card text-card-foreground shadow-sm',
props.class,
)
"
>
<div :class="cn('rounded-lg border bg-card text-card-foreground shadow-sm', props.class)">
<slot />
</div>
</template>

View file

@ -1,9 +1,9 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>

View file

@ -1,9 +1,9 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>

View file

@ -1,9 +1,9 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>

View file

@ -1,9 +1,9 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>

View file

@ -1,17 +1,13 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>
<h3
:class="
cn('text-2xl font-semibold leading-none tracking-tight', props.class)
"
>
<h3 :class="cn('text-2xl font-semibold leading-none tracking-tight', props.class)">
<slot />
</h3>
</template>

View file

@ -1,6 +1,6 @@
export { default as Card } from "./Card.vue";
export { default as CardHeader } from "./CardHeader.vue";
export { default as CardTitle } from "./CardTitle.vue";
export { default as CardDescription } from "./CardDescription.vue";
export { default as CardContent } from "./CardContent.vue";
export { default as CardFooter } from "./CardFooter.vue";
export { default as Card } from './Card.vue'
export { default as CardHeader } from './CardHeader.vue'
export { default as CardTitle } from './CardTitle.vue'
export { default as CardDescription } from './CardDescription.vue'
export { default as CardContent } from './CardContent.vue'
export { default as CardFooter } from './CardFooter.vue'

View file

@ -1,34 +1,34 @@
<script setup>
import { useProvideCarousel } from "./useCarousel";
import { cn } from "@/lib/utils";
import { useProvideCarousel } from './useCarousel'
import { cn } from '@/lib/utils'
const props = defineProps({
opts: { type: null, required: false },
plugins: { type: null, required: false },
orientation: { type: String, required: false, default: "horizontal" },
class: { type: null, required: false },
});
orientation: { type: String, required: false, default: 'horizontal' },
class: { type: null, required: false }
})
const emits = defineEmits(["init-api"]);
const emits = defineEmits(['init-api'])
const carouselArgs = useProvideCarousel(props, emits);
const carouselArgs = useProvideCarousel(props, emits)
defineExpose(carouselArgs);
defineExpose(carouselArgs)
function onKeyDown(event) {
const prevKey = props.orientation === "vertical" ? "ArrowUp" : "ArrowLeft";
const nextKey = props.orientation === "vertical" ? "ArrowDown" : "ArrowRight";
const prevKey = props.orientation === 'vertical' ? 'ArrowUp' : 'ArrowLeft'
const nextKey = props.orientation === 'vertical' ? 'ArrowDown' : 'ArrowRight'
if (event.key === prevKey) {
event.preventDefault();
carouselArgs.scrollPrev();
event.preventDefault()
carouselArgs.scrollPrev()
return;
return
}
if (event.key === nextKey) {
event.preventDefault();
carouselArgs.scrollNext();
event.preventDefault()
carouselArgs.scrollNext()
}
}
</script>

View file

@ -1,28 +1,22 @@
<script setup>
import { useCarousel } from "./useCarousel";
import { cn } from "@/lib/utils";
import { useCarousel } from './useCarousel'
import { cn } from '@/lib/utils'
defineOptions({
inheritAttrs: false,
});
inheritAttrs: false
})
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
const { carouselRef, orientation } = useCarousel();
const { carouselRef, orientation } = useCarousel()
</script>
<template>
<div ref="carouselRef" class="overflow-hidden">
<div
:class="
cn(
'flex',
orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col',
props.class,
)
"
:class="cn('flex', orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col', props.class)"
v-bind="$attrs"
>
<slot />

View file

@ -1,12 +1,12 @@
<script setup>
import { useCarousel } from "./useCarousel";
import { cn } from "@/lib/utils";
import { useCarousel } from './useCarousel'
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
const { orientation } = useCarousel();
const { orientation } = useCarousel()
</script>
<template>
@ -17,7 +17,7 @@ const { orientation } = useCarousel();
cn(
'min-w-0 shrink-0 grow-0 basis-full',
orientation === 'horizontal' ? 'pl-4' : 'pt-4',
props.class,
props.class
)
"
>

View file

@ -1,14 +1,14 @@
<script setup>
import { ArrowRight } from "lucide-vue-next";
import { useCarousel } from "./useCarousel";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { ArrowRight } from 'lucide-vue-next'
import { useCarousel } from './useCarousel'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
const { orientation, canScrollNext, scrollNext } = useCarousel();
const { orientation, canScrollNext, scrollNext } = useCarousel()
</script>
<template>
@ -20,7 +20,7 @@ const { orientation, canScrollNext, scrollNext } = useCarousel();
orientation === 'horizontal'
? '-right-12 top-1/2 -translate-y-1/2'
: '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',
props.class,
props.class
)
"
variant="outline"

View file

@ -1,14 +1,14 @@
<script setup>
import { ArrowLeft } from "lucide-vue-next";
import { useCarousel } from "./useCarousel";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { ArrowLeft } from 'lucide-vue-next'
import { useCarousel } from './useCarousel'
import { cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
const { orientation, canScrollPrev, scrollPrev } = useCarousel();
const { orientation, canScrollPrev, scrollPrev } = useCarousel()
</script>
<template>
@ -20,7 +20,7 @@ const { orientation, canScrollPrev, scrollPrev } = useCarousel();
orientation === 'horizontal'
? '-left-12 top-1/2 -translate-y-1/2'
: '-top-12 left-1/2 -translate-x-1/2 rotate-90',
props.class,
props.class
)
"
variant="outline"

View file

@ -1,6 +1,6 @@
export { default as Carousel } from "./Carousel.vue";
export { default as CarouselContent } from "./CarouselContent.vue";
export { default as CarouselItem } from "./CarouselItem.vue";
export { default as CarouselPrevious } from "./CarouselPrevious.vue";
export { default as CarouselNext } from "./CarouselNext.vue";
export { useCarousel } from "./useCarousel";
export { default as Carousel } from './Carousel.vue'
export { default as CarouselContent } from './CarouselContent.vue'
export { default as CarouselItem } from './CarouselItem.vue'
export { default as CarouselPrevious } from './CarouselPrevious.vue'
export { default as CarouselNext } from './CarouselNext.vue'
export { useCarousel } from './useCarousel'

View file

@ -1 +1 @@
export {};
export {}

View file

@ -1,41 +1,41 @@
import { createInjectionState } from "@vueuse/core";
import emblaCarouselVue from "embla-carousel-vue";
import { onMounted, ref } from "vue";
import { createInjectionState } from '@vueuse/core'
import emblaCarouselVue from 'embla-carousel-vue'
import { onMounted, ref } from 'vue'
const [useProvideCarousel, useInjectCarousel] = createInjectionState(
({ opts, orientation, plugins }, emits) => {
const [emblaNode, emblaApi] = emblaCarouselVue(
{
...opts,
axis: orientation === "horizontal" ? "x" : "y",
axis: orientation === 'horizontal' ? 'x' : 'y'
},
plugins,
);
plugins
)
function scrollPrev() {
emblaApi.value?.scrollPrev();
emblaApi.value?.scrollPrev()
}
function scrollNext() {
emblaApi.value?.scrollNext();
emblaApi.value?.scrollNext()
}
const canScrollNext = ref(false);
const canScrollPrev = ref(false);
const canScrollNext = ref(false)
const canScrollPrev = ref(false)
function onSelect(api) {
canScrollNext.value = api?.canScrollNext() || false;
canScrollPrev.value = api?.canScrollPrev() || false;
canScrollNext.value = api?.canScrollNext() || false
canScrollPrev.value = api?.canScrollPrev() || false
}
onMounted(() => {
if (!emblaApi.value) return;
if (!emblaApi.value) return
emblaApi.value?.on("init", onSelect);
emblaApi.value?.on("reInit", onSelect);
emblaApi.value?.on("select", onSelect);
emblaApi.value?.on('init', onSelect)
emblaApi.value?.on('reInit', onSelect)
emblaApi.value?.on('select', onSelect)
emits("init-api", emblaApi.value);
});
emits('init-api', emblaApi.value)
})
return {
carouselRef: emblaNode,
@ -44,18 +44,17 @@ const [useProvideCarousel, useInjectCarousel] = createInjectionState(
canScrollNext,
scrollPrev,
scrollNext,
orientation,
};
},
);
orientation
}
}
)
function useCarousel() {
const carouselState = useInjectCarousel();
const carouselState = useInjectCarousel()
if (!carouselState)
throw new Error("useCarousel must be used within a <Carousel />");
if (!carouselState) throw new Error('useCarousel must be used within a <Carousel />')
return carouselState;
return carouselState
}
export { useCarousel, useProvideCarousel };
export { useCarousel, useProvideCarousel }

View file

@ -1,16 +1,14 @@
<script setup>
import { Slot } from "radix-vue";
import { useFormField } from "./useFormField";
import { Slot } from 'radix-vue'
import { useFormField } from './useFormField'
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
const { error, formItemId, formDescriptionId, formMessageId } = useFormField()
</script>
<template>
<Slot
:id="formItemId"
:aria-describedby="
!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`
"
:aria-describedby="!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`"
:aria-invalid="!!error"
>
<slot />

View file

@ -1,19 +1,16 @@
<script setup>
import { useFormField } from "./useFormField";
import { cn } from "@/lib/utils";
import { useFormField } from './useFormField'
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
const { formDescriptionId } = useFormField();
const { formDescriptionId } = useFormField()
</script>
<template>
<p
:id="formDescriptionId"
:class="cn('text-sm text-muted-foreground', props.class)"
>
<p :id="formDescriptionId" :class="cn('text-sm text-muted-foreground', props.class)">
<slot />
</p>
</template>

View file

@ -1,15 +1,15 @@
<script setup>
import { provide } from "vue";
import { useId } from "radix-vue";
import { FORM_ITEM_INJECTION_KEY } from "./injectionKeys";
import { cn } from "@/lib/utils";
import { provide } from 'vue'
import { useId } from 'radix-vue'
import { FORM_ITEM_INJECTION_KEY } from './injectionKeys'
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
const id = useId();
provide(FORM_ITEM_INJECTION_KEY, id);
const id = useId()
provide(FORM_ITEM_INJECTION_KEY, id)
</script>
<template>

View file

@ -1,23 +1,20 @@
<script setup>
import { useFormField } from "./useFormField";
import { cn } from "@/lib/utils";
import { Label } from "@/components/ui/label";
import { useFormField } from './useFormField'
import { cn } from '@/lib/utils'
import { Label } from '@/components/ui/label'
const props = defineProps({
for: { type: String, required: false },
asChild: { type: Boolean, required: false },
as: { type: null, required: false },
class: { type: null, required: false },
});
class: { type: null, required: false }
})
const { error, formItemId } = useFormField();
const { error, formItemId } = useFormField()
</script>
<template>
<Label
:class="cn(error && 'text-destructive', props.class)"
:for="formItemId"
>
<Label :class="cn(error && 'text-destructive', props.class)" :for="formItemId">
<slot />
</Label>
</template>

View file

@ -1,9 +1,9 @@
<script setup>
import { ErrorMessage } from "vee-validate";
import { toValue } from "vue";
import { useFormField } from "./useFormField";
import { ErrorMessage } from 'vee-validate'
import { toValue } from 'vue'
import { useFormField } from './useFormField'
const { name, formMessageId } = useFormField();
const { name, formMessageId } = useFormField()
</script>
<template>

View file

@ -1,7 +1,7 @@
export { Form, Field as FormField } from "vee-validate";
export { default as FormItem } from "./FormItem.vue";
export { default as FormLabel } from "./FormLabel.vue";
export { default as FormControl } from "./FormControl.vue";
export { default as FormMessage } from "./FormMessage.vue";
export { default as FormDescription } from "./FormDescription.vue";
export { FORM_ITEM_INJECTION_KEY } from "./injectionKeys";
export { Form, Field as FormField } from 'vee-validate'
export { default as FormItem } from './FormItem.vue'
export { default as FormLabel } from './FormLabel.vue'
export { default as FormControl } from './FormControl.vue'
export { default as FormMessage } from './FormMessage.vue'
export { default as FormDescription } from './FormDescription.vue'
export { FORM_ITEM_INJECTION_KEY } from './injectionKeys'

View file

@ -1 +1 @@
export const FORM_ITEM_INJECTION_KEY = Symbol();
export const FORM_ITEM_INJECTION_KEY = Symbol()

View file

@ -3,27 +3,26 @@ import {
useFieldError,
useIsFieldDirty,
useIsFieldTouched,
useIsFieldValid,
} from "vee-validate";
import { inject } from "vue";
import { FORM_ITEM_INJECTION_KEY } from "./injectionKeys";
useIsFieldValid
} from 'vee-validate'
import { inject } from 'vue'
import { FORM_ITEM_INJECTION_KEY } from './injectionKeys'
export function useFormField() {
const fieldContext = inject(FieldContextKey);
const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY);
const fieldContext = inject(FieldContextKey)
const fieldItemContext = inject(FORM_ITEM_INJECTION_KEY)
if (!fieldContext)
throw new Error("useFormField should be used within <FormField>");
if (!fieldContext) throw new Error('useFormField should be used within <FormField>')
const { name } = fieldContext;
const id = fieldItemContext;
const { name } = fieldContext
const id = fieldItemContext
const fieldState = {
valid: useIsFieldValid(name),
isDirty: useIsFieldDirty(name),
isTouched: useIsFieldTouched(name),
error: useFieldError(name),
};
error: useFieldError(name)
}
return {
id,
@ -31,6 +30,6 @@ export function useFormField() {
formItemId: `${id}-form-item`,
formDescriptionId: `${id}-form-item-description`,
formMessageId: `${id}-form-item-message`,
...fieldState,
};
...fieldState
}
}

View file

@ -1,19 +1,19 @@
<script setup>
import { useVModel } from "@vueuse/core";
import { cn } from "@/lib/utils";
import { useVModel } from '@vueuse/core'
import { cn } from '@/lib/utils'
const props = defineProps({
defaultValue: { type: [String, Number], required: false },
modelValue: { type: [String, Number], required: false },
class: { type: null, required: false },
});
class: { type: null, required: false }
})
const emits = defineEmits(["update:modelValue"]);
const emits = defineEmits(['update:modelValue'])
const modelValue = useVModel(props, "modelValue", emits, {
const modelValue = useVModel(props, 'modelValue', emits, {
passive: true,
defaultValue: props.defaultValue,
});
defaultValue: props.defaultValue
})
</script>
<template>
@ -22,7 +22,7 @@ const modelValue = useVModel(props, "modelValue", emits, {
:class="
cn(
'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
props.class,
props.class
)
"
/>

View file

@ -1 +1 @@
export { default as Input } from "./Input.vue";
export { default as Input } from './Input.vue'

View file

@ -1,20 +1,20 @@
<script setup>
import { computed } from "vue";
import { Label } from "radix-vue";
import { cn } from "@/lib/utils";
import { computed } from 'vue'
import { Label } from 'radix-vue'
import { cn } from '@/lib/utils'
const props = defineProps({
for: { type: String, required: false },
asChild: { type: Boolean, required: false },
as: { type: null, required: false },
class: { type: null, required: false },
});
class: { type: null, required: false }
})
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;
const { class: _, ...delegated } = props
return delegated;
});
return delegated
})
</script>
<template>
@ -23,7 +23,7 @@ const delegatedProps = computed(() => {
:class="
cn(
'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70',
props.class,
props.class
)
"
>

View file

@ -1 +1 @@
export { default as Label } from "./Label.vue";
export { default as Label } from './Label.vue'

View file

@ -1,9 +1,9 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>

View file

@ -1,9 +1,9 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>

View file

@ -1,9 +1,9 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>

View file

@ -1,15 +1,13 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>
<td
:class="cn('p-4 align-middle [&:has([role=checkbox])]:pr-0', props.class)"
>
<td :class="cn('p-4 align-middle [&:has([role=checkbox])]:pr-0', props.class)">
<slot />
</td>
</template>

View file

@ -1,29 +1,25 @@
<script setup>
import { computed } from "vue";
import TableRow from "./TableRow.vue";
import TableCell from "./TableCell.vue";
import { cn } from "@/lib/utils";
import { computed } from 'vue'
import TableRow from './TableRow.vue'
import TableCell from './TableCell.vue'
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
colspan: { type: Number, required: false, default: 1 },
});
colspan: { type: Number, required: false, default: 1 }
})
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;
const { class: _, ...delegated } = props
return delegated;
});
return delegated
})
</script>
<template>
<TableRow>
<TableCell
:class="
cn(
'p-4 whitespace-nowrap align-middle text-sm text-foreground',
props.class
)"
:class="cn('p-4 whitespace-nowrap align-middle text-sm text-foreground', props.class)"
v-bind="delegatedProps"
>
<div class="flex items-center justify-center py-10">

View file

@ -1,17 +1,13 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>
<tfoot
:class="
cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', props.class)
"
>
<tfoot :class="cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', props.class)">
<slot />
</tfoot>
</template>

View file

@ -1,9 +1,9 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>
@ -11,7 +11,7 @@ const props = defineProps({
:class="
cn(
'h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0',
props.class,
props.class
)
"
>

View file

@ -1,9 +1,9 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>

View file

@ -1,18 +1,15 @@
<script setup>
import { cn } from "@/lib/utils";
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
});
class: { type: null, required: false }
})
</script>
<template>
<tr
:class="
cn(
'border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
props.class,
)
cn('border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted', props.class)
"
>
<slot />

View file

@ -1,9 +1,9 @@
export { default as Table } from "./Table.vue";
export { default as TableBody } from "./TableBody.vue";
export { default as TableCell } from "./TableCell.vue";
export { default as TableHead } from "./TableHead.vue";
export { default as TableHeader } from "./TableHeader.vue";
export { default as TableFooter } from "./TableFooter.vue";
export { default as TableRow } from "./TableRow.vue";
export { default as TableCaption } from "./TableCaption.vue";
export { default as TableEmpty } from "./TableEmpty.vue";
export { default as Table } from './Table.vue'
export { default as TableBody } from './TableBody.vue'
export { default as TableCell } from './TableCell.vue'
export { default as TableHead } from './TableHead.vue'
export { default as TableHeader } from './TableHeader.vue'
export { default as TableFooter } from './TableFooter.vue'
export { default as TableRow } from './TableRow.vue'
export { default as TableCaption } from './TableCaption.vue'
export { default as TableEmpty } from './TableEmpty.vue'

View file

@ -1,19 +1,19 @@
<script setup>
import { useVModel } from "@vueuse/core";
import { cn } from "@/lib/utils";
import { useVModel } from '@vueuse/core'
import { cn } from '@/lib/utils'
const props = defineProps({
class: { type: null, required: false },
defaultValue: { type: [String, Number], required: false },
modelValue: { type: [String, Number], required: false },
});
modelValue: { type: [String, Number], required: false }
})
const emits = defineEmits(["update:modelValue"]);
const emits = defineEmits(['update:modelValue'])
const modelValue = useVModel(props, "modelValue", emits, {
const modelValue = useVModel(props, 'modelValue', emits, {
passive: true,
defaultValue: props.defaultValue,
});
defaultValue: props.defaultValue
})
</script>
<template>
@ -22,7 +22,7 @@ const modelValue = useVModel(props, "modelValue", emits, {
:class="
cn(
'flex min-h-20 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
props.class,
props.class
)
"
/>

View file

@ -1 +1 @@
export { default as Textarea } from "./Textarea.vue";
export { default as Textarea } from './Textarea.vue'

View file

@ -1,5 +1,5 @@
<script setup>
import { TooltipRoot, useForwardPropsEmits } from "radix-vue";
import { TooltipRoot, useForwardPropsEmits } from 'radix-vue'
const props = defineProps({
defaultOpen: { type: Boolean, required: false },
@ -8,11 +8,11 @@ const props = defineProps({
disableHoverableContent: { type: Boolean, required: false },
disableClosingTrigger: { type: Boolean, required: false },
disabled: { type: Boolean, required: false },
ignoreNonKeyboardFocus: { type: Boolean, required: false },
});
const emits = defineEmits(["update:open"]);
ignoreNonKeyboardFocus: { type: Boolean, required: false }
})
const emits = defineEmits(['update:open'])
const forwarded = useForwardPropsEmits(props, emits);
const forwarded = useForwardPropsEmits(props, emits)
</script>
<template>

View file

@ -1,11 +1,11 @@
<script setup>
import { computed } from "vue";
import { TooltipContent, TooltipPortal, useForwardPropsEmits } from "radix-vue";
import { cn } from "@/lib/utils";
import { computed } from 'vue'
import { TooltipContent, TooltipPortal, useForwardPropsEmits } from 'radix-vue'
import { cn } from '@/lib/utils'
defineOptions({
inheritAttrs: false,
});
inheritAttrs: false
})
const props = defineProps({
forceMount: { type: Boolean, required: false },
@ -22,18 +22,18 @@ const props = defineProps({
arrowPadding: { type: Number, required: false },
sticky: { type: String, required: false },
hideWhenDetached: { type: Boolean, required: false },
class: { type: null, required: false },
});
class: { type: null, required: false }
})
const emits = defineEmits(["escapeKeyDown", "pointerDownOutside"]);
const emits = defineEmits(['escapeKeyDown', 'pointerDownOutside'])
const delegatedProps = computed(() => {
const { class: _, ...delegated } = props;
const { class: _, ...delegated } = props
return delegated;
});
return delegated
})
const forwarded = useForwardPropsEmits(delegatedProps, emits);
const forwarded = useForwardPropsEmits(delegatedProps, emits)
</script>
<template>
@ -43,7 +43,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
:class="
cn(
'z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
props.class,
props.class
)
"
>

View file

@ -1,5 +1,5 @@
<script setup>
import { TooltipProvider } from "radix-vue";
import { TooltipProvider } from 'radix-vue'
const props = defineProps({
delayDuration: { type: Number, required: false },
@ -7,8 +7,8 @@ const props = defineProps({
disableHoverableContent: { type: Boolean, required: false },
disableClosingTrigger: { type: Boolean, required: false },
disabled: { type: Boolean, required: false },
ignoreNonKeyboardFocus: { type: Boolean, required: false },
});
ignoreNonKeyboardFocus: { type: Boolean, required: false }
})
</script>
<template>

View file

@ -1,10 +1,10 @@
<script setup>
import { TooltipTrigger } from "radix-vue";
import { TooltipTrigger } from 'radix-vue'
const props = defineProps({
asChild: { type: Boolean, required: false },
as: { type: null, required: false },
});
as: { type: null, required: false }
})
</script>
<template>

View file

@ -1,4 +1,4 @@
export { default as Tooltip } from "./Tooltip.vue";
export { default as TooltipContent } from "./TooltipContent.vue";
export { default as TooltipTrigger } from "./TooltipTrigger.vue";
export { default as TooltipProvider } from "./TooltipProvider.vue";
export { default as Tooltip } from './Tooltip.vue'
export { default as TooltipContent } from './TooltipContent.vue'
export { default as TooltipTrigger } from './TooltipTrigger.vue'
export { default as TooltipProvider } from './TooltipProvider.vue'

View file

@ -9,14 +9,14 @@ import VueFullPage from 'vue-fullpage.js'
import App from './App.vue'
import router from './router'
import "vue3-openlayers/styles.css";
import OpenLayersMap from "vue3-openlayers";
import 'vue3-openlayers/styles.css'
import OpenLayersMap from 'vue3-openlayers'
const app = createApp(App)
app.use(VueFullPage)
app.use(createPinia())
app.use(router)
app.use(OpenLayersMap);
app.use(OpenLayersMap)
app.mount('#app')

View file

@ -2,41 +2,39 @@ import { defineStore } from 'pinia'
import { ref } from 'vue'
import { API_BASE_URL } from '@/config.js'
export const useAuthStore = defineStore("auth", () => {
const adminToken = ref("");
const isAuth = ref(false);
const error = ref(false);
export const useAuthStore = defineStore('auth', () => {
const adminToken = ref('')
const isAuth = ref(false)
const error = ref(false)
function login(token) {
adminToken.value = "";
isAuth.value = false;
error.value = false;
adminToken.value = ''
isAuth.value = false
error.value = false
return fetch(API_BASE_URL + "/admin/auth/check", {
return fetch(API_BASE_URL + '/admin/auth/check', {
headers: {
"X-admin-token": token
'X-admin-token': token
}
}).then(resp => {
}).then((resp) => {
if (resp.ok) {
adminToken.value = token;
isAuth.value = true;
localStorage.setItem("kektus-summer-admin-token", token)
adminToken.value = token
isAuth.value = true
localStorage.setItem('kektus-summer-admin-token', token)
} else {
error.value = true;
error.value = true
}
})
}
function checkFromLocalStorage() {
const storedToken = localStorage.getItem("kektus-summer-admin-token")
const storedToken = localStorage.getItem('kektus-summer-admin-token')
if (storedToken) {
return login(storedToken)
}
return Promise.resolve();
return Promise.resolve()
}
return { adminToken, login, checkFromLocalStorage, isAuth, error }
})
})

View file

@ -1,5 +1,4 @@
<script setup>
import { Button } from '@/components/ui/button/index.js'
import { CirclePlus, Pencil, Trash, MapPin } from 'lucide-vue-next'
import { useAdminPostsStore } from '@/stores/adminPosts.js'
@ -72,6 +71,4 @@ onMounted(() => {
</div>
</template>
<style scoped>
</style>
<style scoped></style>

View file

@ -8,7 +8,14 @@ import { Label } from '@/components/ui/label/index.js'
import { toTypedSchema } from '@vee-validate/zod'
import { z } from 'zod'
import { onMounted, onUnmounted, ref } from 'vue'
import { AlertCircle, ArrowLeft, ArrowRight, CircleCheckBig, CirclePlus, RefreshCcw } from 'lucide-vue-next'
import {
AlertCircle,
ArrowLeft,
ArrowRight,
CircleCheckBig,
CirclePlus,
RefreshCcw
} from 'lucide-vue-next'
import {
Carousel,
CarouselContent,

View file

@ -1,5 +1,4 @@
<script setup>
import { useAuthStore } from '@/stores/auth.js'
import { toTypedSchema } from '@vee-validate/zod'
import { z } from 'zod'
@ -14,15 +13,17 @@ import router from '@/router/index.js'
import { useRoute } from 'vue-router'
const authStore = useAuthStore()
const nextView = useRoute().query.redirect;
const nextView = useRoute().query.redirect
onMounted(() => {
authStore.checkFromLocalStorage().then(onLogin);
authStore.checkFromLocalStorage().then(onLogin)
})
const formSchema = toTypedSchema(z.object({
token: z.string().min(1)
}))
const formSchema = toTypedSchema(
z.object({
token: z.string().min(1)
})
)
const form = useForm({
validationSchema: formSchema
})
@ -32,16 +33,14 @@ const onSubmit = form.handleSubmit((values) => {
})
function onLogin() {
if (!authStore.isAuth)
return;
if (!authStore.isAuth) return
if (nextView) {
router.push(nextView);
router.push(nextView)
} else {
router.push({name: "admin"});
router.push({ name: 'admin' })
}
}
</script>
<template>
@ -57,7 +56,6 @@ function onLogin() {
<AlertDescription>Token invalide</AlertDescription>
</Alert>
<div id="form-container" ref="formContainer">
<form id="login-form" class="space-y-6" @submit="onSubmit">
<FormField v-slot="{ componentField }" name="token">
@ -68,15 +66,11 @@ function onLogin() {
</FormControl>
</FormItem>
</FormField>
<Button class="mt-6 w-full" type="submit">
Login
</Button>
<Button class="mt-6 w-full" type="submit"> Login </Button>
</form>
</div>
</div>
</div>
</template>
<style scoped>
</style>
<style scoped></style>

View file

@ -1,9 +1,13 @@
<script setup>
import { usePostsStore } from '@/stores/posts.js'
import { computed, onMounted, ref } from 'vue'
import { Camera, Goal, MapPin } from 'lucide-vue-next'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip/index.js'
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger
} from '@/components/ui/tooltip/index.js'
import { useLocationStore } from '@/stores/location.js'
import { fromLonLat } from 'ol/proj.js'
@ -39,16 +43,8 @@ const goalLocations = ref([
<template>
<div class="fixed h-full w-full">
<ol-map
:loadTilesWhileAnimating="true"
:loadTilesWhileInteracting="true"
class="h-full w-full"
>
<ol-view
ref="view"
:zoom="3.6"
:center="[ 652293.6169027708, 6425265.202945196 ]"
/>
<ol-map :loadTilesWhileAnimating="true" :loadTilesWhileInteracting="true" class="h-full w-full">
<ol-view ref="view" :zoom="3.6" :center="[652293.6169027708, 6425265.202945196]" />
<ol-tile-layer>
<ol-source-osm />
@ -56,16 +52,18 @@ const goalLocations = ref([
<ol-scaleline-control />
<ol-overlay
v-for="post in postStore.posts" :key="post.id"
v-for="post in postStore.posts"
:key="post.id"
:position="post.projectedCoordinates"
:autoPan="true"
>
<TooltipProvider>
<Tooltip :default-open="true">
<TooltipTrigger as-child>
<RouterLink :to="{ name: 'home', hash: '#post-' + post.id}">
<RouterLink :to="{ name: 'home', hash: '#post-' + post.id }">
<div
class="-translate-x-1/2 -translate-y-1/2 p-1 rounded-lg bg-indigo-950 hover:bg-indigo-900 transition-colors duration-200">
class="-translate-x-1/2 -translate-y-1/2 p-1 rounded-lg bg-indigo-950 hover:bg-indigo-900 transition-colors duration-200"
>
<Camera size="16" />
</div>
</RouterLink>
@ -85,7 +83,8 @@ const goalLocations = ref([
<Tooltip :default-open="true">
<TooltipTrigger as-child>
<div
class="-translate-x-1/2 -translate-y-1/2 p-1 rounded-lg bg-rose-950 hover:bg-rose-900 transition-colors duration-200">
class="-translate-x-1/2 -translate-y-1/2 p-1 rounded-lg bg-rose-950 hover:bg-rose-900 transition-colors duration-200"
>
<MapPin size="16" />
</div>
</TooltipTrigger>
@ -97,7 +96,8 @@ const goalLocations = ref([
</ol-overlay>
<ol-overlay
v-for="loc in goalLocations" :key="loc.name"
v-for="loc in goalLocations"
:key="loc.name"
:position="loc.coords"
:autoPan="true"
>
@ -105,7 +105,8 @@ const goalLocations = ref([
<Tooltip>
<TooltipTrigger as-child>
<div
class="-translate-x-1/2 -translate-y-1/2 p-1 rounded-lg bg-emerald-800 hover:bg-emerald-700 transition-colors duration-200">
class="-translate-x-1/2 -translate-y-1/2 p-1 rounded-lg bg-emerald-800 hover:bg-emerald-700 transition-colors duration-200"
>
<Goal size="16" />
</div>
</TooltipTrigger>
@ -119,15 +120,9 @@ const goalLocations = ref([
<ol-vector-layer v-if="postsLinesCoordinates.length > 1">
<ol-source-vector>
<ol-feature ref="profileFeatureRef">
<ol-geom-line-string
:coordinates="postsLinesCoordinates"
></ol-geom-line-string>
<ol-geom-line-string :coordinates="postsLinesCoordinates"></ol-geom-line-string>
<ol-style>
<ol-style-stroke
color="white"
width="5"
:lineDash="[15, 15]"
></ol-style-stroke>
<ol-style-stroke color="white" width="5" :lineDash="[15, 15]"></ol-style-stroke>
</ol-style>
</ol-feature>
</ol-source-vector>
@ -136,5 +131,4 @@ const goalLocations = ref([
</div>
</template>
<style scoped>
</style>
<style scoped></style>

View file

@ -32,8 +32,7 @@ instance it still finds a way to be alive and break when changing views????
*/
async function initFullpage() {
if (fullPageInit)
return
if (fullPageInit) return
fullpageKey.value += 5
fullpageEnable.value = true
@ -41,7 +40,9 @@ async function initFullpage() {
try {
fullpage.value.init()
} catch (e) {
console.log('failed to reload fullpage.js because it sucks with vue, reloading page as last resort')
console.log(
'failed to reload fullpage.js because it sucks with vue, reloading page as last resort'
)
window.location.reload()
return
}
@ -57,7 +58,10 @@ onMounted(() => {
onBeforeUnmount(async () => {
console.log('caught post view unmount')
if (typeof window.fullpage_api !== 'undefined' && typeof window.fullpage_api.destroy !== 'undefined') {
if (
typeof window.fullpage_api !== 'undefined' &&
typeof window.fullpage_api.destroy !== 'undefined'
) {
window.fullpage_api.destroy('all')
}
fullpageKey.value++
@ -100,11 +104,18 @@ function onLeave(origin, destination, direction, trigger) {
class="col-start-1 col-span-full row-start-1 max-h-52 h-fit mt-28 sm:mt-16 lg:m-0 lg:col-start-5 lg:col-span-1 lg:row-start-3 lg:row-span-1 pointer-events-auto overflow-y-scroll transition-opacity duration-1000 opacity-0"
ref="menu"
>
<li :data-menuanchor="'post-' + post.id" v-for="post in postsStore.posts" :key="post.id"
class="m-2 backdrop-blur-sm rounded-lg bg-black/10 hover:bg-gray-500/10 transition-colors duration-200"
ref="menuItems">
<a :href="'#post-' + post.id"
class="block text-right px-4 py-3 transition-all duration-300">{{ post.formatedDate }}</a>
<li
:data-menuanchor="'post-' + post.id"
v-for="post in postsStore.posts"
:key="post.id"
class="m-2 backdrop-blur-sm rounded-lg bg-black/10 hover:bg-gray-500/10 transition-colors duration-200"
ref="menuItems"
>
<a
:href="'#post-' + post.id"
class="block text-right px-4 py-3 transition-all duration-300"
>{{ post.formatedDate }}</a
>
</li>
</ul>
</div>
@ -123,7 +134,6 @@ function onLeave(origin, destination, direction, trigger) {
</template>
<style scoped>
#menu li.active,
#menu li.active:hover {
background-color: rgba(255, 255, 255, 0.1);

View file

@ -13,10 +13,12 @@ import { API_BASE_URL } from '@/config.js'
const authStore = useAuthStore()
const formSchema = toTypedSchema(z.object({
latitude: z.number(),
longitude: z.number()
}))
const formSchema = toTypedSchema(
z.object({
latitude: z.number(),
longitude: z.number()
})
)
const form = useForm({
validationSchema: formSchema
})
@ -33,8 +35,7 @@ const formStatus = ref({
})
const onSubmit = form.handleSubmit(async (values) => {
if (!authStore.isAuth)
return
if (!authStore.isAuth) return
console.log('Envoi de la localisation...')
formContainer.value.classList.add('hidden')
@ -55,7 +56,8 @@ const onSubmit = form.handleSubmit(async (values) => {
console.log('POST post API failed: ' + response.statusText + '\n\n' + response.body)
formStatus.value.sending = false
formStatus.value.error = true
formStatus.value.errorMsg = 'Une erreur est survenue lors de l\'envoi du poste : ' + response.statusText
formStatus.value.errorMsg =
"Une erreur est survenue lors de l'envoi du poste : " + response.statusText
formContainer.value.classList.remove('hidden')
return
}
@ -79,7 +81,6 @@ onUnmounted(() => {
navigator.geolocation.clearWatch(geoWatchId)
}
})
</script>
<template>
@ -133,5 +134,4 @@ onUnmounted(() => {
</div>
</template>
<style scoped>
</style>
<style scoped></style>