mirror of
https://github.com/open-reception/appointment-booking-software.git
synced 2026-08-17 21:25:52 +02:00
Fix calendar implementation issues
This commit is contained in:
@@ -126,7 +126,7 @@
|
||||
|
||||
<div class="relative flex w-full flex-col">
|
||||
{#if isWeekView && items}
|
||||
{@const isSelected = selectedDate.toString() === items[0]?.date}
|
||||
{@const isSelected = selectedDate.toString() === day.toString()}
|
||||
{@const isToday = toCalendarDate(day).toString() === today(getLocalTimeZone()).toString()}
|
||||
<Text
|
||||
style="xs"
|
||||
@@ -136,7 +136,10 @@
|
||||
isToday && "rounded-sm border-2 border-red-500/50 px-1",
|
||||
)}
|
||||
>
|
||||
{toDisplayDateTime(day.toDate(getLocalTimeZone()), { weekday: "short" })}
|
||||
{toDisplayDateTime(day.toDate(getLocalTimeZone()), {
|
||||
day: "numeric",
|
||||
weekday: "short",
|
||||
})}
|
||||
</Text>
|
||||
<Separator
|
||||
orientation="vertical"
|
||||
|
||||
@@ -2,18 +2,23 @@
|
||||
import { m } from "$i18n/messages";
|
||||
import { getLocale } from "$i18n/runtime";
|
||||
import { Button, buttonVariants } from "$lib/components/ui/button";
|
||||
import { CalendarDate, getLocalTimeZone, today } from "@internationalized/date";
|
||||
import {
|
||||
CalendarDate,
|
||||
getLocalTimeZone,
|
||||
isWeekend,
|
||||
today,
|
||||
type DateValue,
|
||||
} from "@internationalized/date";
|
||||
import { ChevronLeft, ChevronRight } from "@lucide/svelte";
|
||||
import * as Popover from "$lib/components/ui/popover/index.js";
|
||||
import { cn } from "$lib/utils";
|
||||
import CalendarMonth from "./CalendarMonth.svelte";
|
||||
import type { TAppointmentFilter } from "$lib/types/calendar";
|
||||
import type { OnChangeFn } from "vaul-svelte";
|
||||
import type { CalendarView } from "../types";
|
||||
|
||||
let {
|
||||
selectedDate = $bindable(),
|
||||
view,
|
||||
view = $bindable(),
|
||||
shownAppointments,
|
||||
shownChannels,
|
||||
shownAgents,
|
||||
@@ -50,8 +55,11 @@
|
||||
selectedDate = today(getLocalTimeZone());
|
||||
};
|
||||
|
||||
const onSelectDay: OnChangeFn<unknown> = () => {
|
||||
const onSelectDay = (v: DateValue | undefined) => {
|
||||
open = false;
|
||||
if (view === "week-workdays" && v && isWeekend(v, getLocale())) {
|
||||
view = "week";
|
||||
}
|
||||
};
|
||||
|
||||
const getISOWeek = (date: CalendarDate): { week: number; year: number } => {
|
||||
@@ -76,7 +84,7 @@
|
||||
<div
|
||||
class="flex flex-col items-start justify-between gap-2 min-[500px]:flex-row min-[500px]:items-center"
|
||||
>
|
||||
<div class="-ml-1 flex w-87.5 items-center justify-between gap-5">
|
||||
<div class={cn("-ml-1 flex items-center justify-between gap-5", isWeekView ? "w-60" : "w-75")}>
|
||||
<Button size="sm" variant="ghost" class="h-6 p-1!" onclick={prev}>
|
||||
<ChevronLeft />
|
||||
</Button>
|
||||
|
||||
@@ -17,14 +17,12 @@
|
||||
latestEndHour,
|
||||
scale = $bindable(),
|
||||
isLoading,
|
||||
isWeekView,
|
||||
}: {
|
||||
day: CalendarDate;
|
||||
earliestStartHour: number;
|
||||
latestEndHour: number;
|
||||
scale: number;
|
||||
isLoading: boolean;
|
||||
isWeekView?: boolean;
|
||||
} = $props();
|
||||
|
||||
const hourSize = $derived(60 * scale);
|
||||
@@ -73,15 +71,13 @@
|
||||
class="relative z-0 flex w-full items-start justify-between transition-all duration-200 select-none"
|
||||
style:height={`${hourSize}px`}
|
||||
>
|
||||
{#if !isWeekView}
|
||||
<Text style="xs" class="text-muted-foreground -mt-2 w-16 shrink-0">
|
||||
{Intl.DateTimeFormat(getLocale(), {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
timeZone: getLocalTimeZone().toString(),
|
||||
}).format(toCalendarDateTime(day).set({ hour }).toDate(getLocalTimeZone()))}
|
||||
</Text>
|
||||
{/if}
|
||||
<Text style="xs" class="text-muted-foreground -mt-2 w-16 shrink-0">
|
||||
{Intl.DateTimeFormat(getLocale(), {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
timeZone: getLocalTimeZone().toString(),
|
||||
}).format(toCalendarDateTime(day).set({ hour }).toDate(getLocalTimeZone()))}
|
||||
</Text>
|
||||
<Separator class="bg-muted-foreground -z-10 -ml-0.5 h-px w-auto! grow" />
|
||||
<Separator class="bg-secondary absolute top-1/2 right-0 left-16 h-px w-auto!" />
|
||||
</div>
|
||||
|
||||
@@ -66,13 +66,6 @@
|
||||
});
|
||||
let scale = $state(page.data.calendarZoom);
|
||||
|
||||
$effect(() => {
|
||||
const getMonth = (x: string | undefined) => (x ? new Date(x).getMonth() + 1 : undefined);
|
||||
if (!calendar || getMonth(calendar?.period.startDate) !== getMonth(selectedDate.toString())) {
|
||||
updateCalendar();
|
||||
}
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
if (calendar && history.state["sveltekit:states"]?.appointmentId) {
|
||||
// Wait 100ms to ensure that the calendar items are rendered
|
||||
@@ -96,21 +89,24 @@
|
||||
"date" in page.state &&
|
||||
"appointmentId" in page.state
|
||||
) {
|
||||
shownAppointments = "all";
|
||||
|
||||
// navigate to date
|
||||
const date = convertDate(page.state.date as string);
|
||||
if (date.toString() !== selectedDate.toString()) {
|
||||
selectedDate = date;
|
||||
replaceState("", { appointmentId: page.state.appointmentId });
|
||||
} else {
|
||||
if (calendar) {
|
||||
openAppointmentById(
|
||||
calendar,
|
||||
channels,
|
||||
history.state["sveltekit:states"].appointmentId,
|
||||
() => {
|
||||
replaceState("", {});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// open appointment
|
||||
if (calendar) {
|
||||
openAppointmentById(
|
||||
calendar,
|
||||
channels,
|
||||
history.state["sveltekit:states"].appointmentId,
|
||||
() => {
|
||||
replaceState("", {});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -142,7 +138,7 @@
|
||||
|
||||
<SidebarLayout breakcrumbs={[{ label: m["nav.calendar"](), href: ROUTES.DASHBOARD.CALENDAR }]}>
|
||||
<div class="flex flex-col gap-10">
|
||||
<CalendarHeader bind:selectedDate {view} {shownAppointments} {shownAgents} {shownChannels} />
|
||||
<CalendarHeader bind:selectedDate bind:view {shownAppointments} {shownAgents} {shownChannels} />
|
||||
<div
|
||||
class="flex transition-all duration-200"
|
||||
style:min-height={`${(hours.to * 30 + 60) * scale}px`}
|
||||
|
||||
Reference in New Issue
Block a user