diff --git a/apps/web/components/schedule/time-slots/edit-slot-form.tsx b/apps/web/components/schedule/time-slots/edit-slot-form.tsx deleted file mode 100644 index 6338123..0000000 --- a/apps/web/components/schedule/time-slots/edit-slot-form.tsx +++ /dev/null @@ -1,96 +0,0 @@ -'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; - -type TimeTextProps = { readonly date: Date }; - -export function EditSlotForm({ documentId }: Readonly) { - 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 ( -
- - {editMode ? ( - <> -
- setStartTime(event.target.value)} - required - type="time" - value={startTime} - /> -
-
- setEndTime(event.target.value)} - required - type="time" - value={endTime} - /> -
- - ) : ( - <> - - - - )} - - - - ); -} - -function TimeText({ date }: TimeTextProps) { - if (!date) return ; - - return {getTimeString(date)}; -} diff --git a/apps/web/components/schedule/time-slots/edit-slot-form/components/form.tsx b/apps/web/components/schedule/time-slots/edit-slot-form/components/form.tsx new file mode 100644 index 0000000..e8bc85c --- /dev/null +++ b/apps/web/components/schedule/time-slots/edit-slot-form/components/form.tsx @@ -0,0 +1,55 @@ +'use client'; +import { EditableTimePair, ReadonlyTimePair } from '../components'; +import { Context } from '../context'; +import { type Props } from '../types'; +import { ScheduleSlotsContext } from '@/context/schedule-slots'; +import { useSlotMutation, useSlotQuery } from '@/hooks/slots'; +import { combineDateTime } from '@/utils/date'; +import { Button } from '@repo/ui/components/ui/button'; +import { Pencil, Save } from 'lucide-react'; +import { type FormEvent, use } from 'react'; + +export function Form(props: Readonly) { + const { documentId } = props; + + const { editMode, endTime, setEditMode, setEndTime, setStartTime, startTime } = use(Context); + + const { selectedDate } = use(ScheduleSlotsContext); + + const { 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); + }; + + const TimePair = editMode ? EditableTimePair : ReadonlyTimePair; + + return ( +
+ + + + + + ); +} diff --git a/apps/web/components/schedule/time-slots/edit-slot-form/components/index.ts b/apps/web/components/schedule/time-slots/edit-slot-form/components/index.ts new file mode 100644 index 0000000..d5e178e --- /dev/null +++ b/apps/web/components/schedule/time-slots/edit-slot-form/components/index.ts @@ -0,0 +1,2 @@ +export * from './form'; +export * from './time-pair'; diff --git a/apps/web/components/schedule/time-slots/edit-slot-form/components/time-pair.tsx b/apps/web/components/schedule/time-slots/edit-slot-form/components/time-pair.tsx new file mode 100644 index 0000000..50b4551 --- /dev/null +++ b/apps/web/components/schedule/time-slots/edit-slot-form/components/time-pair.tsx @@ -0,0 +1,56 @@ +'use client'; +import { Context } from '../context'; +import { type Props } from '../types'; +import { useSlotQuery } from '@/hooks/slots'; +import { getTimeString } from '@/utils/date'; +import { Input } from '@repo/ui/components/ui/input'; +import { Loader } from 'lucide-react'; +import { use, useEffect } from 'react'; + +export function EditableTimePair({ documentId }: Readonly) { + const { editMode, endTime, setEndTime, setStartTime, startTime } = use(Context); + const { data } = useSlotQuery({ documentId }); + + useEffect(() => { + if (editMode) { + setStartTime(getTimeString(data?.slot?.datestart)); + setEndTime(getTimeString(data?.slot?.dateend)); + } + }, [data?.slot?.dateend, data?.slot?.datestart, editMode, setEndTime, setStartTime]); + + return ( + <> +
+ setStartTime(event.target.value)} + required + type="time" + value={startTime} + /> +
+
+ setEndTime(event.target.value)} + required + type="time" + value={endTime} + /> +
+ + ); +} + +export function ReadonlyTimePair({ documentId }: Readonly) { + const { data } = useSlotQuery({ documentId }); + + if (!data) return ; + + return ( + <> + {getTimeString(data?.slot?.datestart)} + {getTimeString(data?.slot?.dateend)} + + ); +} diff --git a/apps/web/components/schedule/time-slots/edit-slot-form/context.tsx b/apps/web/components/schedule/time-slots/edit-slot-form/context.tsx new file mode 100644 index 0000000..f1a0242 --- /dev/null +++ b/apps/web/components/schedule/time-slots/edit-slot-form/context.tsx @@ -0,0 +1,31 @@ +'use client'; +import { createContext, type PropsWithChildren, useMemo, useState } from 'react'; + +type ContextType = { + editMode: boolean; + endTime: string; + setEditMode: (value: boolean) => void; + setEndTime: (value: string) => void; + setStartTime: (value: string) => void; + startTime: string; +}; +export const Context = createContext({} as ContextType); + +export function ContextProvider({ children }: Readonly) { + const [editMode, setEditMode] = useState(false); + const [startTime, setStartTime] = useState(''); + const [endTime, setEndTime] = useState(''); + + const value = useMemo(() => { + return { + editMode, + endTime, + setEditMode, + setEndTime, + setStartTime, + startTime, + }; + }, [editMode, endTime, setEditMode, startTime]); + + return {children}; +} diff --git a/apps/web/components/schedule/time-slots/edit-slot-form/index.tsx b/apps/web/components/schedule/time-slots/edit-slot-form/index.tsx new file mode 100644 index 0000000..b76e233 --- /dev/null +++ b/apps/web/components/schedule/time-slots/edit-slot-form/index.tsx @@ -0,0 +1,12 @@ +'use client'; +import { Form } from './components'; +import { ContextProvider } from './context'; +import { type Props } from './types'; + +export function EditSlotForm(props: Readonly) { + return ( + +
+ + ); +} diff --git a/apps/web/components/schedule/time-slots/edit-slot-form/types.tsx b/apps/web/components/schedule/time-slots/edit-slot-form/types.tsx new file mode 100644 index 0000000..6945600 --- /dev/null +++ b/apps/web/components/schedule/time-slots/edit-slot-form/types.tsx @@ -0,0 +1,4 @@ +'use client'; +import { type SlotFieldsFragment } from '@repo/graphql/types'; + +export type Props = Pick;