feat(order-form): implement date selection with event highlighting and monthly view for available time slots

This commit is contained in:
vchikalkin 2025-07-16 13:27:41 +03:00
parent 5e517def3d
commit 307997d67f
2 changed files with 42 additions and 3 deletions

View File

@ -6,12 +6,40 @@ import { Button } from '@repo/ui/components/ui/button';
import { Calendar } from '@repo/ui/components/ui/calendar';
import { formatDate } from '@repo/utils/datetime-format';
import dayjs from 'dayjs';
import { useState } from 'react';
export function DateSelect() {
const selectedDate = useOrderStore((store) => store.date);
const setDate = useOrderStore((store) => store.setDate);
const setTime = useOrderStore((store) => store.setTime);
const setSlot = useOrderStore((store) => store.setSlotId);
const masterId = useOrderStore((store) => store.masterId);
const serviceId = useOrderStore((store) => store.serviceId);
const [currentMonthDate, setCurrentMonthDate] = useState(new Date());
const { data: { slots } = {} } = useAvailableTimeSlotsQuery(
{
filters: {
date: {
gte: dayjs(currentMonthDate).startOf('month').format('YYYY-MM-DD'),
lte: dayjs(currentMonthDate).endOf('month').format('YYYY-MM-DD'),
},
master: {
documentId: {
eq: masterId,
},
},
},
},
{
service: {
documentId: {
eq: serviceId,
},
},
},
);
return (
<Calendar
@ -20,6 +48,15 @@ export function DateSelect() {
return dayjs().isAfter(dayjs(date), 'day');
}}
mode="single"
modifiers={{
hasEvent: (date) => {
return slots?.some((slot) => dayjs(slot?.date).isSame(date, 'day')) || false;
},
}}
modifiersClassNames={{
hasEvent: 'border-primary border-2 rounded-xl',
}}
onMonthChange={(date) => setCurrentMonthDate(date)}
onSelect={(date) => {
if (date) setDate(date);
setTime(null);

View File

@ -50,6 +50,8 @@ export class SlotsService extends BaseService {
variables: VariablesOf<typeof GQL.GetSlotsDocument>,
context: { service: GQL.ServiceFiltersInput },
) {
if (!variables.filters?.date) throw new Error('Missing date');
const { query } = await getClientWithToken();
const getSlotsResult = await query({
@ -76,10 +78,10 @@ export class SlotsService extends BaseService {
const serviceDuration = getMinutes(service.duration);
const openedSlots = getSlotsResult.data.slots;
const slots = getSlotsResult.data.slots;
const times: Array<{ slotId: string; time: string }> = [];
for (const slot of openedSlots) {
for (const slot of slots) {
if (!slot?.time_start || !slot?.time_end) continue;
let startTime = dayjs(`${slot.date} ${slot.time_start}`);
@ -107,7 +109,7 @@ export class SlotsService extends BaseService {
}
}
return { times };
return { slots, times };
}
async getSlot(variables: VariablesOf<typeof GQL.GetSlotDocument>) {