97 lines
3.0 KiB
TypeScript
97 lines
3.0 KiB
TypeScript
'use client';
|
|
import { ScheduleSlotsContext } from '@/context/schedule-slots';
|
|
import { useSlotMutation, useSlotQuery } from '@/hooks/slots';
|
|
import { combineDateTime, getTimeString } from '@/utils/date';
|
|
import { type SlotFieldsFragment } from '@repo/graphql/types';
|
|
import { Button } from '@repo/ui/components/ui/button';
|
|
import { Input } from '@repo/ui/components/ui/input';
|
|
import { Loader, Pencil, Save } from 'lucide-react';
|
|
import { type FormEvent, use, useEffect, useState } from 'react';
|
|
|
|
type Props = Pick<SlotFieldsFragment, 'documentId'>;
|
|
|
|
type TimeTextProps = { readonly date: Date };
|
|
|
|
export function EditSlotForm({ documentId }: Readonly<Props>) {
|
|
const [editMode, setEditMode] = useState(false);
|
|
|
|
const [startTime, setStartTime] = useState('');
|
|
const [endTime, setEndTime] = useState('');
|
|
|
|
const { selectedDate } = use(ScheduleSlotsContext);
|
|
|
|
const { data, isLoading: isLoadingSlotQuery } = useSlotQuery({ documentId });
|
|
const { isPending: isPendingSlotMutation, mutate } = useSlotMutation({ documentId });
|
|
|
|
const handleSubmit = (event: FormEvent) => {
|
|
event.preventDefault();
|
|
if (startTime && endTime) {
|
|
mutate({
|
|
data: {
|
|
dateend: combineDateTime(selectedDate, endTime).toISOString(),
|
|
datestart: combineDateTime(selectedDate, startTime).toISOString(),
|
|
},
|
|
documentId,
|
|
});
|
|
setStartTime('');
|
|
setEndTime('');
|
|
}
|
|
|
|
setEditMode(false);
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (editMode) {
|
|
setStartTime(getTimeString(data?.slot?.datestart));
|
|
setEndTime(getTimeString(data?.slot?.dateend));
|
|
}
|
|
}, [data?.slot?.dateend, data?.slot?.datestart, editMode]);
|
|
|
|
return (
|
|
<form className="grid grid-cols-[auto_1fr_1fr_auto] items-center gap-2" onSubmit={handleSubmit}>
|
|
<span className="text-base font-bold">•</span>
|
|
{editMode ? (
|
|
<>
|
|
<div className="flex-1">
|
|
<Input
|
|
id="start-time"
|
|
onChange={(event) => setStartTime(event.target.value)}
|
|
required
|
|
type="time"
|
|
value={startTime}
|
|
/>
|
|
</div>
|
|
<div className="flex-1">
|
|
<Input
|
|
id="end-time"
|
|
onChange={(event) => setEndTime(event.target.value)}
|
|
required
|
|
type="time"
|
|
value={endTime}
|
|
/>
|
|
</div>
|
|
</>
|
|
) : (
|
|
<>
|
|
<TimeText date={data?.slot?.datestart} />
|
|
<TimeText date={data?.slot?.dateend} />
|
|
</>
|
|
)}
|
|
|
|
<Button
|
|
disabled={isLoadingSlotQuery || isPendingSlotMutation}
|
|
onClick={editMode ? undefined : () => setEditMode(true)}
|
|
type={editMode ? 'submit' : 'button'}
|
|
>
|
|
{editMode ? <Save className="size-4" /> : <Pencil className="size-4" />}
|
|
</Button>
|
|
</form>
|
|
);
|
|
}
|
|
|
|
function TimeText({ date }: TimeTextProps) {
|
|
if (!date) return <Loader className="animate-spin" />;
|
|
|
|
return <span className="p-1 text-lg font-bold">{getTimeString(date)}</span>;
|
|
}
|