Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions resources/js/components/entries/calendar/Calendar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Month from './Month.vue';
import Week from './Week.vue';
import { Listing, StatusIndicator } from '@/components/ui';
import DateFormatter from '@/components/DateFormatter.js';
import { getWeekDates, getCurrentDateRange } from './calendar.js';
import { getWeekDates, getCurrentDateRange, getEntryDate } from './calendar.js';
import { Link } from '@inertiajs/vue3';
import { ToggleGroup, ToggleItem, Button, Popover, Label, Select, Heading } from '@ui';
import { preferences } from '@api';
Expand Down Expand Up @@ -122,8 +122,7 @@ const selectedDateEntries = computed(() => {
const dateStr = selectedDate.value.toString();

return entries.value.filter(entry => {
const entryDate = new Date(entry.date?.date || entry.date);
return entryDate.toISOString().split('T')[0] === dateStr;
return getEntryDate(entry).toString().split('T')[0] === dateStr;
});
});

Expand Down
6 changes: 2 additions & 4 deletions resources/js/components/entries/calendar/Month.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import { CalendarCell, CalendarCellTrigger, CalendarGrid, CalendarGridBody, Cale
import CalendarEntry from './MonthEntry.vue';
import CreateEntryButton from '../CreateEntryButton.vue';
import { Button } from '@ui';
import { isToday, getCreateUrlDateParam } from './calendar.js';
import { isToday, getCreateUrlDateParam, getEntryDate } from './calendar.js';
import DateFormatter from '@/components/DateFormatter.js';
import { parseAbsoluteToLocal } from '@internationalized/date';

const props = defineProps({
weekDays: { type: Array, required: true },
Expand All @@ -32,8 +31,7 @@ const isCurrentDay = (dayIndex) => {
const getEntriesForDate = (date) => {
const dateStr = date.toString();
return props.entries.filter(entry => {
const entryDate = parseAbsoluteToLocal(entry.date?.date || entry.date);
return entryDate.toString().split('T')[0] === dateStr;
return getEntryDate(entry).toString().split('T')[0] === dateStr;
});
};

Expand Down
7 changes: 6 additions & 1 deletion resources/js/components/entries/calendar/MonthEntry.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ const entryClasses = computed(() => ({
'border-purple-500 hover:bg-purple-50 dark:hover:bg-purple-900': props.entry.status === 'scheduled'
}));

const time = computed(() => DateFormatter.format(props.entry.date?.date || props.entry.date, 'time'))
const time = computed(() => {
if (props.entry.date?.format_has_time === false) return null;

return DateFormatter.format(props.entry.date?.date || props.entry.date, 'time');
});
</script>

<template>
Expand All @@ -25,6 +29,7 @@ const time = computed(() => DateFormatter.format(props.entry.date?.date || props
>
<span class="line-clamp-2" v-text="entry.title" />
<span
v-if="time"
class="hidden @4xl:block text-2xs text-gray-400 dark:text-gray-400 group-hover/entry:dark:text-gray-300"
v-text="time"
/>
Expand Down
7 changes: 3 additions & 4 deletions resources/js/components/entries/calendar/Week.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { Button } from '@ui';
import {
isToday,
getCreateUrlDateParam,
getEntryDate,
} from './calendar.js';
import DateFormatter from '@/components/DateFormatter.js';
import { parseAbsoluteToLocal } from '@internationalized/date';

const props = defineProps({
weekDates: { type: Array, required: true },
Expand All @@ -27,12 +27,11 @@ const visibleHours = Array.from({ length: 24 }, (_, i) => i);
function getEntriesForHour(date, hour) {
const dateStr = date.toString();
return props.entries.filter(entry => {
const entryDate = parseAbsoluteToLocal(entry.date?.date || entry.date);
const entryDate = getEntryDate(entry);
const entryDateStr = entryDate.toString().split('T')[0];
if (entryDateStr !== dateStr) return false;

const entryHour = entryDate.hour;
return entryHour === hour;
return (entryDate.hour ?? 0) === hour;
});
}

Expand Down
9 changes: 8 additions & 1 deletion resources/js/components/entries/calendar/calendar.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { CalendarDate, CalendarDateTime, fromDate, getLocalTimeZone, startOfWeek, endOfWeek } from '@internationalized/date';
import { CalendarDate, CalendarDateTime, fromDate, getLocalTimeZone, parseAbsoluteToLocal, parseDate, startOfWeek, endOfWeek } from '@internationalized/date';
import DateFormatter from '@/components/DateFormatter.js';

export function getEntryDate(entry) {
const date = entry.date?.date || entry.date;

// Fields using a format without a time save a plain date string, which can't be parsed as an absolute datetime.
return date.includes('T') ? parseAbsoluteToLocal(date) : parseDate(date);
}

export function getWeekDates(currentDate) {
if (!currentDate) {
throw new Error('getWeekDates called with undefined currentDate');
Expand Down
19 changes: 19 additions & 0 deletions resources/js/tests/components/entries/calendar.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { expect, test } from 'vitest';
import { getEntryDate } from '@/components/entries/calendar/calendar.js';

test('it parses datetime values', () => {
const date = getEntryDate({ date: { date: '2026-08-24T12:30:00.000Z', format_has_time: true } });

expect(date.toString().split('T')[0]).toBe('2026-08-24');
});

test('it parses date-only values', () => {
const date = getEntryDate({ date: { date: '2026-08-24', format_has_time: false } });

expect(date.toString()).toBe('2026-08-24');
});

test('it parses values that are plain strings', () => {
expect(getEntryDate({ date: '2026-08-24T12:30:00.000Z' }).toString().split('T')[0]).toBe('2026-08-24');
expect(getEntryDate({ date: '2026-08-24' }).toString()).toBe('2026-08-24');
});
Loading