diff --git a/web/bun.lock b/web/bun.lock index f92b2ab..11fa3fc 100644 --- a/web/bun.lock +++ b/web/bun.lock @@ -10,8 +10,10 @@ "@nuxt/test-utils": "3.18.0", "@nuxt/ui": "3.1.1", "@nuxtjs/color-mode": "3.5.2", + "@types/luxon": "^3.6.2", "@types/moment": "^2.13.0", "eslint": "^9.0.0", + "luxon": "^3.6.1", "moment": "^2.30.1", "nuxt": "^3.17.2", "nuxt-app": "file:", @@ -474,6 +476,8 @@ "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + "@types/luxon": ["@types/luxon@3.6.2", "", {}, "sha512-R/BdP7OxEMc44l2Ex5lSXHoIXTB2JLNa3y2QISIbr58U/YcsffyQrYW//hZSdrfxrjRZj3GcUoxMPGdO8gSYuw=="], + "@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=="], diff --git a/web/components/ui/MainContent.vue b/web/components/ui/MainContent.vue index d7da085..97253b2 100644 --- a/web/components/ui/MainContent.vue +++ b/web/components/ui/MainContent.vue @@ -1,11 +1,11 @@ diff --git a/web/components/ui/Sidebar.vue b/web/components/ui/Sidebar.vue index 30435b1..6528c42 100644 --- a/web/components/ui/Sidebar.vue +++ b/web/components/ui/Sidebar.vue @@ -3,8 +3,7 @@ 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'; +import { DateTime } from 'luxon'; const colorMode = useColorMode(); const currentTheme = ref<'dark' | 'system' | 'light'>(colorMode.preference as 'dark' | 'system' | 'light'); @@ -56,17 +55,17 @@ const dropDownItems = computed(() => [ ] ]) -const date = defineModel('date', { required: true }) +const date = defineModel('date', { required: true }) const selectedDate = computed({ get() { - return new CalendarDate(date.value.year(), date.value.month() + 1, date.value.date()) + return new CalendarDate(date.value.year, date.value.month, date.value.day) }, set(value) { if (value === undefined) { return } - date.value = moment(value.toString()); + date.value = DateTime.fromISO(value.toString()); } }) diff --git a/web/components/ui/calendar/Calendar.vue b/web/components/ui/calendar/Calendar.vue index a3b8b62..7117753 100644 --- a/web/components/ui/calendar/Calendar.vue +++ b/web/components/ui/calendar/Calendar.vue @@ -2,20 +2,20 @@ 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'; +import { DateTime } from 'luxon'; const events = defineModel('events', { required: true }) -const date = defineModel('date', { required: true }) +const date = defineModel('date', { required: true }) const draggedEvent = ref() type Day = { - date: Moment + date: DateTime events: CollissionWrapper[][] } const week = computed(() => { - return moment(date.value).startOf('isoWeek') + return date.value.startOf('week') }) function pushEventWithCollisionUpdate(array: CollissionWrapper[], event: Event, collisions: CollissionWrapper[], collisionCount: number) { @@ -28,8 +28,9 @@ function pushEventWithCollisionUpdate(array: CollissionWrapper[], event: Event, const days = computed(() => { return [1, 2, 3, 4, 5, 6, 7].map((i) => { + const currentDate = date.value.startOf('week').plus({ day: i - 1 }) const filteredEvents = events.value.filter( - (event) => event.from >= moment(week.value).weekday(i).startOf('day') && event.to <= moment(week.value).weekday(i).endOf('day') + (event) => event.from >= currentDate.startOf('day') && event.to <= currentDate.endOf('day') ) const sortedEvents = filteredEvents.sort((a, b) => a.from.valueOf() - b.from.valueOf()) @@ -62,7 +63,7 @@ const days = computed(() => { } return { - date: moment(week.value).weekday(i), + date: currentDate, events: columns } }) @@ -72,17 +73,22 @@ const emits = defineEmits<{ (e: 'create', timespan: Event): void }>() +const hour = (num: number) => { + return DateTime.now().startOf('day').plus({ hours: num }) +} + const seperators = ref([ - { text: '3 AM', time: moment().hour(3) }, - { text: '6 AM', time: moment().hour(6) }, - { text: '9 AM', time: moment().hour(9) }, - { text: '12 PM', time: moment().hour(12) }, - { text: '3 PM', time: moment().hour(15) }, - { text: '6 PM', time: moment().hour(18) }, - { text: '9 PM', time: moment().hour(21) }, + { text: '3 AM', time: hour(3) }, + { text: '6 AM', time: hour(6) }, + { text: '9 AM', time: hour(9) }, + { text: '12 PM', time: hour(12) }, + { text: '3 PM', time: hour(15) }, + { text: '6 PM', time: hour(18) }, + { text: '9 PM', time: hour(21) }, ]) -function quickCreate(date: Moment, timespan: Timespan) { + +function quickCreate(date: DateTime, timespan: Timespan) { const eventTitle = prompt("Event title") if (eventTitle === null) { @@ -91,8 +97,8 @@ function quickCreate(date: Moment, timespan: Timespan) { const newEvent: Event = new Event( eventTitle, - moment(date).startOf('day').minutes(timespan.from * 24 * 60), - moment(date).startOf('day').minutes(timespan.to * 24 * 60) + date.startOf('day').plus({ minutes: timespan.from * 24 * 60 }), + date.startOf('day').plus({ minutes: timespan.to * 24 * 60 }) ) emits('create', newEvent) diff --git a/web/components/ui/calendar/CalendarCollumn.vue b/web/components/ui/calendar/CalendarCollumn.vue index 740fc26..558c7bf 100644 --- a/web/components/ui/calendar/CalendarCollumn.vue +++ b/web/components/ui/calendar/CalendarCollumn.vue @@ -1,19 +1,18 @@ diff --git a/web/package.json b/web/package.json index 75f330b..70aeae8 100644 --- a/web/package.json +++ b/web/package.json @@ -16,8 +16,10 @@ "@nuxt/test-utils": "3.18.0", "@nuxt/ui": "3.1.1", "@nuxtjs/color-mode": "3.5.2", + "@types/luxon": "^3.6.2", "@types/moment": "^2.13.0", "eslint": "^9.0.0", + "luxon": "^3.6.1", "moment": "^2.30.1", "nuxt": "^3.17.2", "nuxt-app": "file:", diff --git a/web/pages/index.vue b/web/pages/index.vue index 9ef4719..f6bd1a0 100644 --- a/web/pages/index.vue +++ b/web/pages/index.vue @@ -1,11 +1,11 @@ diff --git a/web/utils/event.ts b/web/utils/event.ts index 4d4b1a8..d0ac1f7 100644 --- a/web/utils/event.ts +++ b/web/utils/event.ts @@ -1,20 +1,19 @@ -import type { Moment } from "moment" -import moment from "moment" +import { DateTime } from "luxon" export class Event { private static readonly MINUTES_IN_DAY = 24 * 60 constructor( public readonly title: string, - public from: Moment, - public to: Moment + public from: DateTime, + public to: DateTime ) { } getPercentDimensions(): EventDimensions { - const start_of_day = moment(this.from).startOf('day') - const from_percentage = this.from.diff(start_of_day, 'minutes') / Event.MINUTES_IN_DAY - const to_percentage = this.to.diff(start_of_day, 'minutes') / Event.MINUTES_IN_DAY + const start_of_day = this.from.startOf('day') + const from_percentage = (this.from.diff(start_of_day, 'minutes').minutes) / Event.MINUTES_IN_DAY + const to_percentage = (this.to.diff(start_of_day, 'minutes').minutes) / Event.MINUTES_IN_DAY return { from: from_percentage * 100, to: to_percentage * 100 @@ -34,18 +33,18 @@ export class Event { } static fromSerializable(event: SerializableEvent) { - return new Event(event.title, moment(event.from), moment(event.to)) + return new Event(event.title, DateTime.fromISO(event.from), DateTime.fromISO(event.to)) } - static fromPercentDimensions(title: string, dimensions: EventDimensions, date: Moment): Event { + static fromPercentDimensions(title: string, dimensions: EventDimensions, date: DateTime): Event { return new Event( title, - moment(date).startOf('day').minutes((dimensions.from / 100) * Event.MINUTES_IN_DAY), - moment(date).startOf('day').minutes((dimensions.to / 100) * Event.MINUTES_IN_DAY) + date.startOf('day').plus({ minutes: (dimensions.from / 100) * Event.MINUTES_IN_DAY }), + date.startOf('day').plus({ minutes: (dimensions.to / 100) * Event.MINUTES_IN_DAY }) ) } - static fromPixelDimensions(title: string, dimensions: EventDimensions, height: number, date: Moment): Event { + static fromPixelDimensions(title: string, dimensions: EventDimensions, height: number, date: DateTime): Event { const percentDimensions: EventDimensions = { from: dimensions.from * 100 / height, to: dimensions.to * 100 / height @@ -84,8 +83,8 @@ export class Event { toSerializable(): SerializableEvent { return { title: this.title, - from: this.from.toISOString(), - to: this.to.toISOString() + from: this.from.toISO() ?? '', + to: this.to.toISO() ?? '' } } @@ -101,7 +100,7 @@ export class Event { const offset = mouseY - pixelDimensions.from return { - date: moment(this.from).startOf('day'), + date: this.from.startOf('day'), top: pixelDimensions.from, height: pixelDimensions.to - pixelDimensions.from, target: this, @@ -118,8 +117,8 @@ export type EventDimensions = { export type SimpleEvent = { title: string, - from: Moment, - to: Moment + from: DateTime, + to: DateTime } export type SerializableEvent = { @@ -134,7 +133,7 @@ export type CollissionWrapper = { } export type DraggedEvent = { - date: Moment, + date: DateTime, top: number, height: number, target: Event, diff --git a/web/utils/lib.ts b/web/utils/lib.ts index ab530bb..5622d51 100644 --- a/web/utils/lib.ts +++ b/web/utils/lib.ts @@ -1,8 +1,8 @@ -import type { Moment } from "moment" +import type { DateTime } from "luxon" export type Seperator = { text: string, - time: Moment + time: DateTime } export type Timespan = { @@ -15,8 +15,8 @@ export type Event = AnonymousEvent & { } export type AnonymousEvent = { - from: Moment, - to: Moment + from: DateTime, + to: DateTime } export type EventWithCollisions = Event & {