Added sidebar to left side of calendar view

This commit is contained in:
Alexis
2024-04-29 21:09:46 +02:00
parent ffaf54bccd
commit 5adc7db425
16 changed files with 242 additions and 108 deletions

View File

@@ -2,7 +2,7 @@
import { useDark } from '@vueuse/core'
import { RouterView } from 'vue-router'
const dark = useDark()
useDark()
</script>
<template>

View File

@@ -0,0 +1,24 @@
<script lang="ts" setup>
import { getRelativeString } from '@/models/Date'
import { useCalendar } from '@/stores/CalendarStore'
import { storeToRefs } from 'pinia'
import { computed } from 'vue'
import { PhMapPin } from '@phosphor-icons/vue'
const { defaultDate, getFormattedDateTitle } = useCalendar()
const { selectedDate } = storeToRefs(useCalendar())
const mainDateTitle = computed(() => getFormattedDateTitle(selectedDate.value, true))
const dateDifference = computed(() => getRelativeString(defaultDate, selectedDate.value))
</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>
</template>

View File

@@ -1,60 +1,43 @@
<script lang="ts" setup>
import { getRelativeString } from '@/models/Date'
import { useCalendar } from '@/stores/CalendarStore'
import { storeToRefs } from 'pinia'
import { computed } from 'vue'
import { PhMapPin } from '@phosphor-icons/vue'
import CalendarMenuNav from './CalendarMenuNav.vue'
import CalendarMenuToday from './CalendarMenuToday.vue'
import CalendarSwitch from './CalendarSwitch.vue'
import CalendarCurrentDate from './CalendarCurrentDate.vue'
import CalendarSearch from './search/CalendarSearch.vue'
const { defaultDate, getFormattedDateTitle, currentDate } = useCalendar()
const { selectedDate } = storeToRefs(useCalendar())
const mainDateTitle = computed(() => getFormattedDateTitle(selectedDate.value, true))
const dateDifference = computed(() => getRelativeString(defaultDate, selectedDate.value))
const { currentDate } = useCalendar()
</script>
<template>
<header class="border-slate-700 border-b-[1px]">
<div class="pt-4 container">
<div class="grid md:grid-cols-12 items-center">
<div class="md:col-span-9">
<div class="flex items-center gap-6">
<menu class="flex items-center gap-2">
<li>
<CalendarSwitch />
</li>
<li>
<CalendarMenuToday />
</li>
<li>
<CalendarMenuNav />
</li>
</menu>
<div>
<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>
</div>
</div>
</div>
<div class="md:col-span-3 flex justify-end">
<header class="pt-4 border-slate-700 border-b-[1px]">
<div class="px-6 flex justify-between">
<menu class="flex items-center gap-2">
<li class="flex items-center">
<CalendarMenuToday />
</li>
<li>
<CalendarMenuNav />
</li>
<li class="ml-6">
<CalendarCurrentDate />
</li>
</menu>
<menu class="flex items-center gap-2">
<li>
<CalendarSearch />
</div>
</div>
</li>
<li>
<CalendarSwitch />
</li>
</menu>
</div>
<div class="container">
<div class="flex">
<div class="px-4 py-2 border-slate-700 border-x-[1px] border-t-[1px] rounded-t-sm">
<span class="text-sm">{{ currentDate.currentDateTitle }}</span>
</div>
<div class="ml-12 flex">
<div class="px-4 py-2 border-slate-700 border-x-[1px] border-t-[1px] rounded-t-sm">
<span class="text-sm">{{ currentDate.currentDateTitle }}</span>
</div>
</div>
</header>

View File

@@ -0,0 +1,23 @@
<script lang="ts" setup>
import { PhList, PhHouse } from '@phosphor-icons/vue'
import Button from '../ui/button/Button.vue'
</script>
<template>
<nav class="w-16 py-6 border-r-[1px] border-l-slate-500 grid justify-center">
<menu>
<li class="mb-12">
<Button variant="ghost" size="icon" @click="console.log" class="rounded-full">
<PhList size="27" />
</Button>
</li>
<li>
<Button variant="ghost" size="icon" class="rounded-full" as-child>
<RouterLink to="/">
<PhHouse size="24" weight="fill" />
</RouterLink>
</Button>
</li>
</menu>
</nav>
</template>

View File

@@ -0,0 +1,29 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
import { RouterLink } from 'vue-router'
const props = defineProps<{
class?: HTMLAttributes['class']
link?: string
}>()
</script>
<template>
<div
:class="
cn('rounded-lg border bg-card text-card-foreground shadow-sm transition-all', props.class, {
'relative outline outline-2 outline-offset-4 outline-transparent hover:bg-sky-950 hover:-translate-y-[.2rem] focus-within:outline-sky-900':
props.link
})
"
>
<slot />
<RouterLink
v-if="props.link"
:to="props.link"
class="absolute inset-0 focus-visible:outline-none"
/>
</div>
</template>

View File

@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<template>
<div :class="cn('p-6 pt-0 text-muted-foreground', props.class)">
<slot />
</div>
</template>

View File

@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<template>
<p :class="cn('text-sm text-muted-foreground mt-1', props.class)">
<slot />
</p>
</template>

View File

@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<template>
<div :class="cn('flex items-center p-6 pt-0', props.class)">
<slot />
</div>
</template>

View File

@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<template>
<div :class="cn('flex flex-col gap-y-1.5 px-6 pt-6 pb-3', props.class)">
<slot />
</div>
</template>

View File

@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>
<template>
<h3 :class="cn('text-2xl font-semibold leading-none tracking-tight', props.class)">
<slot />
</h3>
</template>

View File

@@ -0,0 +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'

View File

@@ -1,13 +1,19 @@
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import HomePage from '@/views/HomePage.vue'
import CalendarPage from '@/views/CalendarPage.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView
name: 'accueil',
component: HomePage
},
{
path: '/calendrier',
name: 'calendrier',
component: CalendarPage
}
]
})

View File

@@ -93,17 +93,6 @@ export const useCalendar = defineStore('calendar', () => {
}
})
// Assign default values if no params exist in URL
if (!params.day || typeof params.day === 'object' || !isInt(params.day)) {
params.day = defaultDay.toString()
}
if (!params.month || typeof params.month === 'object' || !isDigit(params.month)) {
params.month = defaultMonth.toString()
}
if (!params.year || typeof params.year === 'object' || !isSignedInt(params.year)) {
params.year = defaultYear.toString()
}
const currentDay = computed<number>(() => {
return Number(params.day)
})
@@ -191,6 +180,19 @@ export const useCalendar = defineStore('calendar', () => {
}
})
function validateUrlParams(): void {
// Assign default values if no params exist in URL
if (!params.day || typeof params.day === 'object' || !isInt(params.day)) {
params.day = defaultDate.value.day.toString()
}
if (!params.month || typeof params.month === 'object' || !isDigit(params.month)) {
params.month = defaultDate.value.month.toString()
}
if (!params.year || typeof params.year === 'object' || !isSignedInt(params.year)) {
params.year = defaultDate.value.year.toString()
}
}
/**
* Moves the current date forward one month
*/
@@ -396,6 +398,7 @@ export const useCalendar = defineStore('calendar', () => {
selectedDate,
selectDate,
params,
validateUrlParams,
getPeriodOfYear,
incrementMonth,
decrementMonth,

View File

@@ -0,0 +1,17 @@
<script lang="ts" setup>
import { useCalendar } from '@/stores/CalendarStore'
import Calendar from '@/components/calendar/Calendar.vue'
import Sidebar from '@/components/calendar/Sidebar.vue'
const { validateUrlParams } = useCalendar()
validateUrlParams()
</script>
<template>
<main class="h-full grid grid-cols-[auto_1fr]">
<Sidebar />
<Calendar />
</main>
</template>

22
src/views/HomePage.vue Normal file
View File

@@ -0,0 +1,22 @@
<script setup lang="ts">
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
</script>
<template>
<main class="h-full grid place-items-center" v-once>
<Card class="w-1/3 min-w-72" link="/calendrier">
<CardHeader>
<CardTitle>Calendrier</CardTitle>
<CardDescription>
<Badge class="mix-blend-luminosity font-bold bg-gray-600" variant="secondary">
chronologie
</Badge>
</CardDescription>
</CardHeader>
<CardContent>
Chronologie complète de Léïm, rassemblant les évènements et personnages clés du monde
</CardContent>
</Card>
</main>
</template>

View File

@@ -1,49 +0,0 @@
<script lang="ts" setup>
import Calendar from '@/components/calendar/Calendar.vue'
</script>
<template>
<main class="h-full">
<Calendar />
<!-- <pre>
{{ currentDate }}
</pre>
<div class="grid gap-2">
<div class="flex gap-2">
<button class="bg-slate-800 py-2 px-4 rounded-sm" @click="incrementMonth()">Month +</button>
<button class="bg-slate-800 py-2 px-4 rounded-sm" @click="decrementMonth()">Month -</button>
</div>
<div class="flex gap-2">
<button class="bg-slate-800 py-2 px-4 rounded-sm" @click="incrementYear()">Year +</button>
<button class="bg-slate-800 py-2 px-4 rounded-sm" @click="decrementYear()">Year -</button>
</div>
<div class="flex gap-2">
<button class="bg-slate-800 py-2 px-4 rounded-sm" @click="incrementYear(100)">
Century +
</button>
<button class="bg-slate-800 py-2 px-4 rounded-sm" @click="decrementYear(100)">
Century -
</button>
</div>
<div class="flex gap-2">
<button class="bg-slate-800 py-2 px-4 rounded-sm" @click="incrementYear(1000)">
Millenia +
</button>
<button class="bg-slate-800 py-2 px-4 rounded-sm" @click="decrementYear(1000)">
Millenia -
</button>
</div>
<div class="flex gap-2">
<input class="bg-slate-900" type="number" v-model="monthTarget" />
<button class="bg-slate-800 py-2 px-4 rounded-sm" @click="setMonth(monthTarget)">
Set Month
</button>
</div>
</div>
<pre>
Current events:
{{ currentEvents }}
</pre> -->
</main>
</template>