Added sidebar to left side of calendar view
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { useDark } from '@vueuse/core'
|
||||
import { RouterView } from 'vue-router'
|
||||
|
||||
const dark = useDark()
|
||||
useDark()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
24
src/components/calendar/CalendarCurrentDate.vue
Normal file
24
src/components/calendar/CalendarCurrentDate.vue
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
23
src/components/calendar/Sidebar.vue
Normal file
23
src/components/calendar/Sidebar.vue
Normal 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>
|
||||
29
src/components/ui/card/Card.vue
Normal file
29
src/components/ui/card/Card.vue
Normal 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>
|
||||
14
src/components/ui/card/CardContent.vue
Normal file
14
src/components/ui/card/CardContent.vue
Normal 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>
|
||||
14
src/components/ui/card/CardDescription.vue
Normal file
14
src/components/ui/card/CardDescription.vue
Normal 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>
|
||||
14
src/components/ui/card/CardFooter.vue
Normal file
14
src/components/ui/card/CardFooter.vue
Normal 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>
|
||||
14
src/components/ui/card/CardHeader.vue
Normal file
14
src/components/ui/card/CardHeader.vue
Normal 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>
|
||||
14
src/components/ui/card/CardTitle.vue
Normal file
14
src/components/ui/card/CardTitle.vue
Normal 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>
|
||||
6
src/components/ui/card/index.ts
Normal file
6
src/components/ui/card/index.ts
Normal 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'
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
@@ -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,
|
||||
|
||||
17
src/views/CalendarPage.vue
Normal file
17
src/views/CalendarPage.vue
Normal 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
22
src/views/HomePage.vue
Normal 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>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user