Added sidebar to left side of calendar view
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
import { useDark } from '@vueuse/core'
|
import { useDark } from '@vueuse/core'
|
||||||
import { RouterView } from 'vue-router'
|
import { RouterView } from 'vue-router'
|
||||||
|
|
||||||
const dark = useDark()
|
useDark()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<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>
|
<script lang="ts" setup>
|
||||||
import { getRelativeString } from '@/models/Date'
|
|
||||||
import { useCalendar } from '@/stores/CalendarStore'
|
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 CalendarMenuNav from './CalendarMenuNav.vue'
|
||||||
import CalendarMenuToday from './CalendarMenuToday.vue'
|
import CalendarMenuToday from './CalendarMenuToday.vue'
|
||||||
import CalendarSwitch from './CalendarSwitch.vue'
|
import CalendarSwitch from './CalendarSwitch.vue'
|
||||||
|
import CalendarCurrentDate from './CalendarCurrentDate.vue'
|
||||||
|
|
||||||
import CalendarSearch from './search/CalendarSearch.vue'
|
import CalendarSearch from './search/CalendarSearch.vue'
|
||||||
|
|
||||||
const { defaultDate, getFormattedDateTitle, currentDate } = useCalendar()
|
const { currentDate } = useCalendar()
|
||||||
const { selectedDate } = storeToRefs(useCalendar())
|
|
||||||
|
|
||||||
const mainDateTitle = computed(() => getFormattedDateTitle(selectedDate.value, true))
|
|
||||||
|
|
||||||
const dateDifference = computed(() => getRelativeString(defaultDate, selectedDate.value))
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<header class="border-slate-700 border-b-[1px]">
|
<header class="pt-4 border-slate-700 border-b-[1px]">
|
||||||
<div class="pt-4 container">
|
<div class="px-6 flex justify-between">
|
||||||
<div class="grid md:grid-cols-12 items-center">
|
<menu class="flex items-center gap-2">
|
||||||
<div class="md:col-span-9">
|
<li class="flex items-center">
|
||||||
<div class="flex items-center gap-6">
|
<CalendarMenuToday />
|
||||||
<menu class="flex items-center gap-2">
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<CalendarSwitch />
|
<CalendarMenuNav />
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li class="ml-6">
|
||||||
<CalendarMenuToday />
|
<CalendarCurrentDate />
|
||||||
</li>
|
</li>
|
||||||
<li>
|
</menu>
|
||||||
<CalendarMenuNav />
|
|
||||||
</li>
|
<menu class="flex items-center gap-2">
|
||||||
</menu>
|
<li>
|
||||||
<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">
|
|
||||||
<CalendarSearch />
|
<CalendarSearch />
|
||||||
</div>
|
</li>
|
||||||
</div>
|
<li>
|
||||||
|
<CalendarSwitch />
|
||||||
|
</li>
|
||||||
|
</menu>
|
||||||
</div>
|
</div>
|
||||||
<div class="container">
|
<div class="ml-12 flex">
|
||||||
<div class="flex">
|
<div class="px-4 py-2 border-slate-700 border-x-[1px] border-t-[1px] rounded-t-sm">
|
||||||
<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>
|
||||||
<span class="text-sm">{{ currentDate.currentDateTitle }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</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 { 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({
|
const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
routes: [
|
routes: [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
name: 'home',
|
name: 'accueil',
|
||||||
component: HomeView
|
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>(() => {
|
const currentDay = computed<number>(() => {
|
||||||
return Number(params.day)
|
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
|
* Moves the current date forward one month
|
||||||
*/
|
*/
|
||||||
@@ -396,6 +398,7 @@ export const useCalendar = defineStore('calendar', () => {
|
|||||||
selectedDate,
|
selectedDate,
|
||||||
selectDate,
|
selectDate,
|
||||||
params,
|
params,
|
||||||
|
validateUrlParams,
|
||||||
getPeriodOfYear,
|
getPeriodOfYear,
|
||||||
incrementMonth,
|
incrementMonth,
|
||||||
decrementMonth,
|
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