Fixed hydration errors
Moved some code to client only (it makes sense given the localstorage stuff)
This commit is contained in:
@@ -10,7 +10,10 @@ import DecadeLayout from './state/decennially/Layout.vue'
|
||||
import YearLayout from './state/yearly/Layout.vue'
|
||||
|
||||
const { currentConfig } = useCalendar()
|
||||
const { eventsLoaded, eventsAreLoading } = storeToRefs(useCalendarEvents())
|
||||
const { selectedDate, jumpToDate } = useCalendar()
|
||||
|
||||
const { fetchEvents } = useCalendarEvents()
|
||||
fetchEvents()
|
||||
|
||||
const currentViewComponent: ComputedRef<Component> = computed<Component>(() => {
|
||||
switch (currentConfig.viewType) {
|
||||
@@ -28,19 +31,18 @@ const currentViewComponent: ComputedRef<Component> = computed<Component>(() => {
|
||||
return CenturyLayout
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
jumpToDate(selectedDate)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-full grid grid-rows-[auto,1fr]">
|
||||
<CalendarMenu />
|
||||
|
||||
<template v-if="eventsAreLoading">
|
||||
<div>
|
||||
Loading
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="eventsLoaded">
|
||||
<component :is="currentViewComponent" v-if="eventsLoaded" />
|
||||
</template>
|
||||
<KeepAlive>
|
||||
<component :is="currentViewComponent" />
|
||||
</KeepAlive>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { getRelativeString } from '@/models/Date'
|
||||
import { useCalendar } from '@/stores/CalendarStore'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { computed } from 'vue'
|
||||
|
||||
@@ -15,10 +14,19 @@ const dateDifference = computed(() => getRelativeString(defaultDate, selectedDat
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1 class="text-2xl font-bold flex items-center gap-1">
|
||||
<PhMapPin size="26" weight="bold" /> {{ mainDateTitle }}
|
||||
</h1>
|
||||
<h2 class="text-lg italic opacity-75">
|
||||
{{ dateDifference }}
|
||||
</h2>
|
||||
<ClientOnly>
|
||||
<h1 class="text-2xl font-bold flex items-center gap-1">
|
||||
<PhMapPin size="26" weight="bold" /> {{ mainDateTitle }}
|
||||
</h1>
|
||||
<h2 class="text-lg italic opacity-75">
|
||||
{{ dateDifference }}
|
||||
</h2>
|
||||
|
||||
<template #fallback>
|
||||
<div class="grid gap-1">
|
||||
<UiSkeleton class="h-8 w-64" />
|
||||
<UiSkeleton class="h-6 w-28" />
|
||||
</div>
|
||||
</template>
|
||||
</ClientOnly>
|
||||
</template>
|
||||
|
||||
@@ -60,8 +60,16 @@ function handleGotoPreviousEventPage(position: 'next' | 'prev' = 'next') {
|
||||
|
||||
<template>
|
||||
<div class="flex gap-2">
|
||||
<div class="w-40 px-4 py-2 border-slate-700 border-x-[1px] border-t-[1px] rounded-t-sm">
|
||||
<span class="text-sm">{{ currentDate.currentDateTitle }}</span>
|
||||
<div class="grid items-end w-40 px-4 py-2 border-slate-700 border-x-[1px] border-t-[1px] rounded-t-sm text-sm">
|
||||
<ClientOnly>
|
||||
<span>{{ currentDate.currentDateTitle }}</span>
|
||||
|
||||
<template #fallback>
|
||||
<span class="inline-block">
|
||||
<UiSkeleton class="h-[19px] w-full rounded-sm" />
|
||||
</span>
|
||||
</template>
|
||||
</ClientOnly>
|
||||
</div>
|
||||
<div class="border-slate-700 border-x-[1px] border-t-[1px] rounded-t-sm">
|
||||
<UiTooltipProvider :delay-duration="250">
|
||||
|
||||
@@ -5,21 +5,30 @@ import { computed } from 'vue'
|
||||
|
||||
import { areDatesIdentical } from '@/models/Date'
|
||||
|
||||
const { defaultDate, selectedDate } = storeToRefs(useCalendar())
|
||||
const { defaultDate } = useCalendar()
|
||||
const { selectedDate } = storeToRefs(useCalendar())
|
||||
const { jumpToDefaultDate, getFormattedDateTitle } = useCalendar()
|
||||
|
||||
const defaultDateFormatted: string = getFormattedDateTitle(defaultDate.value, true)
|
||||
const defaultDateFormatted: string = getFormattedDateTitle(defaultDate, true)
|
||||
|
||||
const isDefaultDate: ComputedRef<boolean> = computed<boolean>(() => areDatesIdentical(selectedDate.value, defaultDate.value))
|
||||
const isDefaultDate: ComputedRef<boolean> = computed<boolean>(() => areDatesIdentical(selectedDate.value, defaultDate))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UiTooltipProvider :delay-duration="250">
|
||||
<UiTooltip>
|
||||
<UiTooltipTrigger as-child>
|
||||
<UiButton size="sm" :disabled="isDefaultDate" @click="jumpToDefaultDate">
|
||||
Aujourd'hui
|
||||
</UiButton>
|
||||
<ClientOnly>
|
||||
<UiButton size="sm" :disabled="isDefaultDate" @click="jumpToDefaultDate">
|
||||
Aujourd'hui
|
||||
</UiButton>
|
||||
|
||||
<template #fallback>
|
||||
<UiButton size="sm">
|
||||
Aujourd'hui
|
||||
</UiButton>
|
||||
</template>
|
||||
</ClientOnly>
|
||||
</UiTooltipTrigger>
|
||||
<UiTooltipContent>
|
||||
<p>{{ defaultDateFormatted }}</p>
|
||||
|
||||
@@ -201,7 +201,7 @@ whenever(keys.control_period, () => {
|
||||
const searchResultsRef = ref<HTMLElement | null>(null)
|
||||
const { y: searchResultsY } = useScroll(searchResultsRef)
|
||||
|
||||
watch(currentPage, () => {
|
||||
watch([currentPage, selectedEntity], () => {
|
||||
searchResultsY.value = 0
|
||||
})
|
||||
|
||||
|
||||
@@ -73,15 +73,17 @@ const eventsNotDisplayed = computed(
|
||||
class="relative z-10 group block w-full text-center cursor-pointer"
|
||||
@click="selectDate(date)"
|
||||
>
|
||||
<span
|
||||
class="inline-flex w-8 h-8 aspect-square items-center justify-center rounded-full border-2 border-transparent font-bold transition-colors group-hover:border-slate-800"
|
||||
:class="{
|
||||
'bg-slate-800': isDefaultDate && !isSelectedDate,
|
||||
'text-white bg-blue-500': isSelectedDate
|
||||
}"
|
||||
>
|
||||
{{ date.day }}
|
||||
</span>
|
||||
<ClientOnly>
|
||||
<span
|
||||
class="inline-flex w-8 h-8 aspect-square items-center justify-center rounded-full border-2 border-transparent font-bold transition-colors group-hover:border-slate-800"
|
||||
:class="{
|
||||
'bg-slate-800': isDefaultDate && !isSelectedDate,
|
||||
'text-white bg-blue-500': isSelectedDate
|
||||
}"
|
||||
>
|
||||
{{ date.day }}
|
||||
</span>
|
||||
</ClientOnly>
|
||||
</button>
|
||||
|
||||
<ul
|
||||
|
||||
14
components/ui/skeleton/Skeleton.vue
Normal file
14
components/ui/skeleton/Skeleton.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
interface SkeletonProps {
|
||||
class?: HTMLAttributes['class']
|
||||
}
|
||||
|
||||
const props = defineProps<SkeletonProps>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="cn('animate-pulse rounded-md bg-muted', props.class)" />
|
||||
</template>
|
||||
1
components/ui/skeleton/index.ts
Normal file
1
components/ui/skeleton/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as Skeleton } from './Skeleton.vue'
|
||||
Reference in New Issue
Block a user