91 lines
3.3 KiB
TypeScript
91 lines
3.3 KiB
TypeScript
/* eslint-disable canonical/id-match */
|
||
/* eslint-disable react/jsx-no-bind */
|
||
'use client';
|
||
|
||
import { type SlotComponentProps } from '../types';
|
||
import { EditableTimeRangeForm, ReadonlyTimeRange } from '@/components/shared/time-range';
|
||
import { useSlotMutation, useSlotQuery } from '@/hooks/api/slots';
|
||
import { useScheduleStore } from '@/stores/schedule';
|
||
import { Enum_Order_State } from '@repo/graphql/types';
|
||
import { Button } from '@repo/ui/components/ui/button';
|
||
import { combineDateAndTimeToUTC, formatTime } from '@repo/utils/datetime-format';
|
||
import dayjs from 'dayjs';
|
||
import { PencilLine } from 'lucide-react';
|
||
import { useEffect } from 'react';
|
||
|
||
export function SlotTime(props: Readonly<SlotComponentProps>) {
|
||
const editMode = useScheduleStore((state) => state.editMode);
|
||
return editMode ? <SlotTimeEditForm {...props} /> : <SlotTimeReadonly {...props} />;
|
||
}
|
||
|
||
function SlotTimeEditForm({ documentId }: Readonly<SlotComponentProps>) {
|
||
const { editMode, endTime, resetTime, setEditMode, setEndTime, setStartTime, startTime } =
|
||
useScheduleStore((state) => state);
|
||
const { isPending: isMutationPending, mutate: updateSlot } = useSlotMutation({ documentId });
|
||
const { data: { slot } = {}, isPending: isQueryPending } = useSlotQuery({ documentId });
|
||
const isPending = isMutationPending || isQueryPending;
|
||
|
||
useEffect(() => {
|
||
if (editMode && slot?.datetime_start && slot?.datetime_end) {
|
||
setStartTime(formatTime(slot.datetime_start).user());
|
||
setEndTime(formatTime(slot.datetime_end).user());
|
||
}
|
||
}, [editMode, setEndTime, setStartTime, slot]);
|
||
|
||
function handleSubmit() {
|
||
if (!slot?.datetime_start) return;
|
||
const date = slot.datetime_start; // ISO-строка, год-месяц-день и время
|
||
const dateOnly = dayjs(date).format('YYYY-MM-DD'); // Получаем только дату
|
||
|
||
const newDatetimeStart = combineDateAndTimeToUTC(dateOnly, startTime);
|
||
const newDatetimeEnd = combineDateAndTimeToUTC(dateOnly, endTime);
|
||
updateSlot({
|
||
data: { datetime_end: newDatetimeEnd, datetime_start: newDatetimeStart },
|
||
});
|
||
resetTime();
|
||
setEditMode(false);
|
||
}
|
||
|
||
return (
|
||
<EditableTimeRangeForm disabled={isPending} onSubmit={handleSubmit}>
|
||
<Button className="rounded-full text-xs" disabled={isPending} onClick={handleSubmit}>
|
||
Сохранить
|
||
</Button>
|
||
</EditableTimeRangeForm>
|
||
);
|
||
}
|
||
|
||
const FORBIDDEN_ORDER_STATES: Enum_Order_State[] = [
|
||
Enum_Order_State.Scheduled,
|
||
Enum_Order_State.Approved,
|
||
Enum_Order_State.Completed,
|
||
Enum_Order_State.Cancelling,
|
||
];
|
||
|
||
function SlotTimeReadonly({ documentId }: Readonly<SlotComponentProps>) {
|
||
const setEditMode = useScheduleStore((state) => state.setEditMode);
|
||
const { data: { slot } = {} } = useSlotQuery({ documentId });
|
||
if (!slot) return null;
|
||
const disabledEdit = slot?.orders.some(
|
||
(order) => order?.state && FORBIDDEN_ORDER_STATES.includes(order?.state),
|
||
);
|
||
return (
|
||
<div className="flex items-center gap-2">
|
||
<ReadonlyTimeRange
|
||
className="text-3xl"
|
||
datetimeEnd={slot.datetime_end ?? ''}
|
||
datetimeStart={slot.datetime_start ?? ''}
|
||
/>
|
||
<Button
|
||
className="rounded-full text-xs"
|
||
disabled={disabledEdit}
|
||
onClick={() => setEditMode(true)}
|
||
size="icon"
|
||
variant="outline"
|
||
>
|
||
<PencilLine className="size-4" />
|
||
</Button>
|
||
</div>
|
||
);
|
||
}
|