added calendar and implemented bridge between small and big calendar
This commit is contained in:
@@ -4,11 +4,14 @@
|
||||
"": {
|
||||
"name": "nuxt-app",
|
||||
"dependencies": {
|
||||
"@iconify-json/lucide": "^1.2.42",
|
||||
"@internationalized/date": "^3.8.0",
|
||||
"@nuxt/eslint": "1.3.0",
|
||||
"@nuxt/test-utils": "3.18.0",
|
||||
"@nuxt/ui": "3.1.1",
|
||||
"@types/moment": "^2.13.0",
|
||||
"eslint": "^9.0.0",
|
||||
"moment": "^2.30.1",
|
||||
"nuxt": "^3.17.2",
|
||||
"nuxt-app": "file:",
|
||||
"typescript": "^5.6.3",
|
||||
@@ -192,6 +195,8 @@
|
||||
|
||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.2", "", {}, "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ=="],
|
||||
|
||||
"@iconify-json/lucide": ["@iconify-json/lucide@1.2.42", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-exkRygF4yd6e5q966TXJQc/b+MAu3iQb8LeExCjl2JoP4/RlpudkYpg1AIZVCVCjAiElDYmVJYDWiJXPLkFN/g=="],
|
||||
|
||||
"@iconify/collections": ["@iconify/collections@1.0.545", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-LQprSmX6Wp69insYYSHM6bj5ZF4gT4ZwoqX9UXdCxGxRMzRpaNzQZUZ++2kP0wnOg3lX2ocMla8ns8oRPzxO2g=="],
|
||||
|
||||
"@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="],
|
||||
@@ -468,6 +473,8 @@
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/moment": ["@types/moment@2.13.0", "", { "dependencies": { "moment": "*" } }, "sha512-DyuyYGpV6r+4Z1bUznLi/Y7HpGn4iQ4IVcGn8zrr1P4KotKLdH0sbK1TFR6RGyX6B+G8u83wCzL+bpawKU/hdQ=="],
|
||||
|
||||
"@types/node": ["@types/node@22.15.12", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-K0fpC/ZVeb8G9rm7bH7vI0KAec4XHEhBam616nVJCV51bKzJ6oA3luG4WdKoaztxe70QaNjS/xBmcDLmr4PiGw=="],
|
||||
|
||||
"@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="],
|
||||
@@ -1392,6 +1399,8 @@
|
||||
|
||||
"module-definition": ["module-definition@5.0.1", "", { "dependencies": { "ast-module-types": "^5.0.0", "node-source-walk": "^6.0.1" }, "bin": { "module-definition": "bin/cli.js" } }, "sha512-kvw3B4G19IXk+BOXnYq/D/VeO9qfHaapMeuS7w7sNUqmGaA6hywdFHMi+VWeR9wUScXM7XjoryTffCZ5B0/8IA=="],
|
||||
|
||||
"moment": ["moment@2.30.1", "", {}, "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how=="],
|
||||
|
||||
"mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
18
web/components/ui/MainContent.vue
Normal file
18
web/components/ui/MainContent.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import type { Moment } from 'moment';
|
||||
import Calendar from './calendar/Calendar.vue'
|
||||
import { Event } from '~/utils/event';
|
||||
import { UCard } from '#components';
|
||||
|
||||
const events = defineModel<Event[]>('events', { required: true })
|
||||
const date = defineModel<Moment>('date', { required: true })
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UCard class="flex grow" :ui="{ body: 'w-full h-full' }">
|
||||
<Calendar v-model:events="events" v-model:date="date"></Calendar>
|
||||
</UCard>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -2,13 +2,29 @@
|
||||
import { CalendarDate } from '@internationalized/date';
|
||||
import ListItem from './ListItem.vue';
|
||||
import Title1 from './Title1.vue';
|
||||
import type { DropdownMenuItem } from '@nuxt/ui';
|
||||
import type { Moment } from 'moment';
|
||||
import moment from 'moment';
|
||||
|
||||
const selectedDate = shallowRef(new CalendarDate(2024, 6, 29));
|
||||
|
||||
const dropDownItems = ref<DropDownMenuItems>([
|
||||
{label: "Profile", icon: "i-lucide-user"}
|
||||
const dropDownItems = ref<DropdownMenuItem[]>([
|
||||
{ label: "Profile", icon: "i-lucide-user" },
|
||||
{ label: "Settings", icon: "i-lucide-settings" }
|
||||
])
|
||||
|
||||
const date = defineModel<Moment>('date', { required: true })
|
||||
|
||||
const selectedDate = computed({
|
||||
get() {
|
||||
return new CalendarDate(date.value.year(), date.value.month() + 1, date.value.date())
|
||||
},
|
||||
set(value) {
|
||||
if (value === undefined) {
|
||||
return
|
||||
}
|
||||
date.value = moment(value.toString());
|
||||
}
|
||||
})
|
||||
|
||||
defineProps<{
|
||||
todos: string[]
|
||||
}>()
|
||||
@@ -17,35 +33,32 @@ defineProps<{
|
||||
|
||||
<template>
|
||||
<UCard class="flex w-64 h-full">
|
||||
<div class="flex flex-col h-full w-full">
|
||||
<header>
|
||||
<div class="flex flex-col h-full w-full gap-5">
|
||||
<header class="flex flex-col gap-2">
|
||||
<Title1>Calendar</Title1>
|
||||
<UCalendar v-model="selectedDate" />
|
||||
</header>
|
||||
<div class="flex flex-col grow justify-between">
|
||||
<div>
|
||||
<div class="flex flex-col gap-2">
|
||||
<Title1>Todos</Title1>
|
||||
<div class="flex gap-2 flex-col">
|
||||
<ListItem v-for="todo in todos">{{ todo }}</ListItem>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex">
|
||||
<UButton class="w-full flex justify-center">
|
||||
<UButton size="xl" class="w-full flex justify-center">
|
||||
+
|
||||
</UButton>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="pt-4">
|
||||
<UDropdownMenu
|
||||
:items="dropDownItems"
|
||||
:ui="{
|
||||
content: 'w-full'
|
||||
}"
|
||||
>
|
||||
<UButton class="flex gap-1 items-center">
|
||||
<UDropdownMenu :items="dropDownItems" size="xl" :ui="{
|
||||
content: 'w-60'
|
||||
}">
|
||||
<UButton variant="ghost" class="flex gap-1 items-center w-full text-text">
|
||||
<UAvatar src="https://github.com/benjamincanac.png" />
|
||||
Sebastian Peinbauer
|
||||
</Ubutton>
|
||||
</UButton>
|
||||
</UDropdownMenu>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -3,9 +3,10 @@ import { computed, ref } from 'vue';
|
||||
import CalendarHeader from './CalendarHeader.vue';
|
||||
import CalendarCollumn from './CalendarCollumn.vue';
|
||||
import moment, { type Moment } from 'moment';
|
||||
import { Event } from '~/utils/event';
|
||||
|
||||
const events = defineModel<Event[]>('events', { required: true })
|
||||
const date = ref(moment())
|
||||
const date = defineModel<Moment>('date', { required: true })
|
||||
const draggedEvent = ref<DraggedEvent | undefined>()
|
||||
|
||||
type Day = {
|
||||
@@ -18,7 +19,7 @@ const week = computed(() => {
|
||||
})
|
||||
|
||||
function pushEventWithCollisionUpdate(array: CollissionWrapper[], event: Event, collisions: CollissionWrapper[], collisionCount: number) {
|
||||
array.push({event: event, collisions: collisionCount })
|
||||
array.push({ event: event, collisions: collisionCount })
|
||||
|
||||
for (let collision of collisions) {
|
||||
collision.collisions = collisionCount
|
||||
@@ -105,8 +106,8 @@ function quickCreate(date: Moment, timespan: Timespan) {
|
||||
<div class="calendar flex flex-row w-full flex-1 items-stretch">
|
||||
<CalendarHeader :seperators="seperators" />
|
||||
|
||||
<CalendarCollumn v-for="day in days" :seperators="seperators" :day="day.date" :events="day.events" v-model:draggedEvent="draggedEvent"
|
||||
@quick-create="quickCreate" />
|
||||
<CalendarCollumn v-for="day in days" :seperators="seperators" :day="day.date" :events="day.events"
|
||||
v-model:draggedEvent="draggedEvent" @quick-create="quickCreate" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -92,13 +92,13 @@ function dragDrop(_: DragEvent) {
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col h-full grow">
|
||||
<div class="flex justify-center items-center flex-col bg-gray-600 h-18 text-white border-b-2 border-white">
|
||||
<div class="flex justify-center items-center flex-col h-18 border-b-2 border-text">
|
||||
<div>{{ props.day.format('dd').toUpperCase() }}</div>
|
||||
<div>{{ props.day.date() }}</div>
|
||||
</div>
|
||||
|
||||
<div id="col" ref="column" @mousedown="mousedown" @mouseup="mouseup" @mousemove="mouseover" @dragover="dragover"
|
||||
@dragend="dragDrop" class="bg-gray-600 text-white relative flex flex-col grow items-center">
|
||||
@dragend="dragDrop" class="relative flex flex-col grow items-center">
|
||||
<CalendarSeperator v-for="sep in seperators" :seperator="sep">
|
||||
<hr class="w-full">
|
||||
</CalendarSeperator>
|
||||
@@ -109,7 +109,8 @@ function dragDrop(_: DragEvent) {
|
||||
<CalendarEvent v-for="event in column" :event="event" :columnIndex="index" @move="eventMove" />
|
||||
</div>
|
||||
|
||||
<div v-if="draggedEvent !== undefined && draggedEvent.date.isSame(props.day)" class="absolute w-11/12 top-20 bg-black opacity-45 rounded-lg"
|
||||
<div v-if="draggedEvent !== undefined && draggedEvent.date.isSame(props.day)"
|
||||
class="absolute w-11/12 top-20 bg-black opacity-45 rounded-lg"
|
||||
:style="{ height: `${draggedEvent.height}px`, top: `${draggedEvent.top}px` }"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,10 +10,10 @@ defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col h-full grow">
|
||||
<div class="flex justify-center items-center bg-gray-600 h-18 text-white border-b-white border-b-2">vue-calendar
|
||||
<div class="flex flex-col h-full w-32">
|
||||
<div class="flex justify-center items-center h-18 border-b-text border-b-2">vue-calendar
|
||||
</div>
|
||||
<div class="calendar-legend bg-gray-600 text-white relative flex flex-col grow justify-evenly">
|
||||
<div class="calendar-legend relative flex flex-col grow justify-evenly">
|
||||
<CalendarSeperator v-for="sep in seperators" :seperator="sep">
|
||||
{{ sep.text }}
|
||||
</CalendarSeperator>
|
||||
|
||||
@@ -12,7 +12,8 @@ const relativePositionOf = function (time: Moment) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :style="{top: relativePositionOf(seperator.time)}" class="h-10 w-full flex justify-center items-center text-white border-white absolute -translate-y-1/2">
|
||||
<div :style="{ top: relativePositionOf(seperator.time) }"
|
||||
class="h-10 w-full flex justify-center items-center border-white absolute -translate-y-1/2">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -10,11 +10,14 @@
|
||||
"postinstall": "nuxt prepare"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify-json/lucide": "^1.2.42",
|
||||
"@internationalized/date": "^3.8.0",
|
||||
"@nuxt/eslint": "1.3.0",
|
||||
"@nuxt/test-utils": "3.18.0",
|
||||
"@nuxt/ui": "3.1.1",
|
||||
"@types/moment": "^2.13.0",
|
||||
"eslint": "^9.0.0",
|
||||
"moment": "^2.30.1",
|
||||
"nuxt": "^3.17.2",
|
||||
"nuxt-app": "file:",
|
||||
"typescript": "^5.6.3",
|
||||
|
||||
@@ -1,24 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import moment from 'moment';
|
||||
import MainContent from '~/components/ui/MainContent.vue';
|
||||
import Sidebar from '~/components/ui/Sidebar.vue';
|
||||
import Calendar from '~/components/ui/calendar/Calendar.vue'
|
||||
import moment, { type Moment } from 'moment';
|
||||
|
||||
const todos = ["Staistics", "Computer Graphics", "Webdev"]
|
||||
const events = ref([])
|
||||
const date = ref(moment())
|
||||
|
||||
onMounted(() => {
|
||||
date.value.subtract(10,"days")
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="h-screen w-screen p-4 flex flex-row gap-5">
|
||||
<Sidebar :todos="todos" />
|
||||
<div class="flex grow">
|
||||
<Calendar v-model:events="events" v-model:date="date"></Calendar>
|
||||
</div>
|
||||
<Sidebar :todos="todos" v-model:date="date" />
|
||||
<MainContent v-model:events="events" v-model:date="date" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -19,21 +19,10 @@ export type AnonymousEvent = {
|
||||
to: Moment
|
||||
}
|
||||
|
||||
export type SerializableEvent = {
|
||||
title: string,
|
||||
from: string,
|
||||
to: string
|
||||
}
|
||||
|
||||
export type EventWithCollisions = Event & {
|
||||
collisions: number
|
||||
}
|
||||
|
||||
export type EventDimensions = {
|
||||
from: number,
|
||||
to: number
|
||||
}
|
||||
|
||||
export function percentToPixelDimensions(dimensions: EventDimensions, totalHeight: number): EventDimensions {
|
||||
return {
|
||||
from: (dimensions.from / 100) * totalHeight,
|
||||
|
||||
Reference in New Issue
Block a user