Fixed hydration errors

Moved some code to client only (it makes sense given the localstorage stuff)
This commit is contained in:
Alexis
2024-05-13 16:06:57 +02:00
parent b49b570fe2
commit df14fad98a
10 changed files with 82 additions and 39 deletions

View File

@@ -10,7 +10,10 @@ import DecadeLayout from './state/decennially/Layout.vue'
import YearLayout from './state/yearly/Layout.vue' import YearLayout from './state/yearly/Layout.vue'
const { currentConfig } = useCalendar() const { currentConfig } = useCalendar()
const { eventsLoaded, eventsAreLoading } = storeToRefs(useCalendarEvents()) const { selectedDate, jumpToDate } = useCalendar()
const { fetchEvents } = useCalendarEvents()
fetchEvents()
const currentViewComponent: ComputedRef<Component> = computed<Component>(() => { const currentViewComponent: ComputedRef<Component> = computed<Component>(() => {
switch (currentConfig.viewType) { switch (currentConfig.viewType) {
@@ -28,19 +31,18 @@ const currentViewComponent: ComputedRef<Component> = computed<Component>(() => {
return CenturyLayout return CenturyLayout
} }
}) })
onMounted(() => {
jumpToDate(selectedDate)
})
</script> </script>
<template> <template>
<div class="h-full grid grid-rows-[auto,1fr]"> <div class="h-full grid grid-rows-[auto,1fr]">
<CalendarMenu /> <CalendarMenu />
<template v-if="eventsAreLoading"> <KeepAlive>
<div> <component :is="currentViewComponent" />
Loading </KeepAlive>
</div>
</template>
<template v-else-if="eventsLoaded">
<component :is="currentViewComponent" v-if="eventsLoaded" />
</template>
</div> </div>
</template> </template>

View File

@@ -1,6 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { getRelativeString } from '@/models/Date' import { getRelativeString } from '@/models/Date'
import { useCalendar } from '@/stores/CalendarStore'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { computed } from 'vue' import { computed } from 'vue'
@@ -15,10 +14,19 @@ const dateDifference = computed(() => getRelativeString(defaultDate, selectedDat
</script> </script>
<template> <template>
<h1 class="text-2xl font-bold flex items-center gap-1"> <ClientOnly>
<PhMapPin size="26" weight="bold" /> {{ mainDateTitle }} <h1 class="text-2xl font-bold flex items-center gap-1">
</h1> <PhMapPin size="26" weight="bold" /> {{ mainDateTitle }}
<h2 class="text-lg italic opacity-75"> </h1>
{{ dateDifference }} <h2 class="text-lg italic opacity-75">
</h2> {{ 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> </template>

View File

@@ -60,8 +60,16 @@ function handleGotoPreviousEventPage(position: 'next' | 'prev' = 'next') {
<template> <template>
<div class="flex gap-2"> <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"> <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">
<span class="text-sm">{{ currentDate.currentDateTitle }}</span> <ClientOnly>
<span>{{ currentDate.currentDateTitle }}</span>
<template #fallback>
<span class="inline-block">
<UiSkeleton class="h-[19px] w-full rounded-sm" />
</span>
</template>
</ClientOnly>
</div> </div>
<div class="border-slate-700 border-x-[1px] border-t-[1px] rounded-t-sm"> <div class="border-slate-700 border-x-[1px] border-t-[1px] rounded-t-sm">
<UiTooltipProvider :delay-duration="250"> <UiTooltipProvider :delay-duration="250">

View File

@@ -5,21 +5,30 @@ import { computed } from 'vue'
import { areDatesIdentical } from '@/models/Date' import { areDatesIdentical } from '@/models/Date'
const { defaultDate, selectedDate } = storeToRefs(useCalendar()) const { defaultDate } = useCalendar()
const { selectedDate } = storeToRefs(useCalendar())
const { jumpToDefaultDate, getFormattedDateTitle } = 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> </script>
<template> <template>
<UiTooltipProvider :delay-duration="250"> <UiTooltipProvider :delay-duration="250">
<UiTooltip> <UiTooltip>
<UiTooltipTrigger as-child> <UiTooltipTrigger as-child>
<UiButton size="sm" :disabled="isDefaultDate" @click="jumpToDefaultDate"> <ClientOnly>
Aujourd'hui <UiButton size="sm" :disabled="isDefaultDate" @click="jumpToDefaultDate">
</UiButton> Aujourd'hui
</UiButton>
<template #fallback>
<UiButton size="sm">
Aujourd'hui
</UiButton>
</template>
</ClientOnly>
</UiTooltipTrigger> </UiTooltipTrigger>
<UiTooltipContent> <UiTooltipContent>
<p>{{ defaultDateFormatted }}</p> <p>{{ defaultDateFormatted }}</p>

View File

@@ -201,7 +201,7 @@ whenever(keys.control_period, () => {
const searchResultsRef = ref<HTMLElement | null>(null) const searchResultsRef = ref<HTMLElement | null>(null)
const { y: searchResultsY } = useScroll(searchResultsRef) const { y: searchResultsY } = useScroll(searchResultsRef)
watch(currentPage, () => { watch([currentPage, selectedEntity], () => {
searchResultsY.value = 0 searchResultsY.value = 0
}) })

View File

@@ -73,15 +73,17 @@ const eventsNotDisplayed = computed(
class="relative z-10 group block w-full text-center cursor-pointer" class="relative z-10 group block w-full text-center cursor-pointer"
@click="selectDate(date)" @click="selectDate(date)"
> >
<span <ClientOnly>
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" <span
:class="{ 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"
'bg-slate-800': isDefaultDate && !isSelectedDate, :class="{
'text-white bg-blue-500': isSelectedDate 'bg-slate-800': isDefaultDate && !isSelectedDate,
}" 'text-white bg-blue-500': isSelectedDate
> }"
{{ date.day }} >
</span> {{ date.day }}
</span>
</ClientOnly>
</button> </button>
<ul <ul

View 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>

View File

@@ -0,0 +1 @@
export { default as Skeleton } from './Skeleton.vue'

View File

@@ -7,8 +7,8 @@ import {
type LeimPeriod, type LeimPeriod,
type LeimPeriodShort type LeimPeriodShort
} from '@/models/Date' } from '@/models/Date'
import { useSessionStorage, useUrlSearchParams } from '@vueuse/core' import { useLocalStorage, useUrlSearchParams } from '@vueuse/core'
import { defineStore } from 'pinia' import { defineStore, skipHydrate } from 'pinia'
import { computed, ref, type ComputedRef, type Ref } from 'vue' import { computed, ref, type ComputedRef, type Ref } from 'vue'
type CalendarViewType = 'month' | 'year' | 'decade' | 'century' type CalendarViewType = 'month' | 'year' | 'decade' | 'century'
@@ -161,7 +161,7 @@ export const useCalendar = defineStore('calendar', () => {
} }
}) })
const selectedDate = useSessionStorage<LeimDate>('selected-date', currentLeimDate.value, { deep: true }) const selectedDate = useLocalStorage<LeimDate>('selected-date', currentLeimDate.value, { deep: true })
/** /**
* Check whether the current viewType is active * Check whether the current viewType is active
@@ -393,7 +393,7 @@ export const useCalendar = defineStore('calendar', () => {
currentDate, currentDate,
currentLeimDate, currentLeimDate,
defaultDate, defaultDate,
selectedDate, selectedDate: skipHydrate(selectedDate),
selectDate, selectDate,
params, params,
getPeriodOfYear, getPeriodOfYear,

View File

@@ -38,7 +38,6 @@ export const useCalendarEvents = defineStore('calendar-events', () => {
eventsAreLoading.value = false eventsAreLoading.value = false
} }
} }
fetchEvents()
/** /**
* Determines if the event can appear in the front end * Determines if the event can appear in the front end