refactor components & folders structure

This commit is contained in:
vchikalkin 2025-02-08 19:57:41 +03:00
parent dfda8a1579
commit 5f990d7286
10 changed files with 128 additions and 104 deletions

View File

@ -1,59 +0,0 @@
/* eslint-disable canonical/id-match */
'use client';
import { ScheduleSlotsContext } from '@/context/schedule-slots';
import { useSlotAdd } from '@/hooks/slots';
import { combineDateTime } from '@/utils/date';
import { Enum_Slot_State } from '@repo/graphql/types';
import { Button } from '@repo/ui/components/ui/button';
import { Input } from '@repo/ui/components/ui/input';
import { PlusSquare } from 'lucide-react';
import { type FormEvent, use, useState } from 'react';
export function AddSlotForm() {
const [startTime, setStartTime] = useState('');
const [endTime, setEndTime] = useState('');
const { selectedDate } = use(ScheduleSlotsContext);
const { isPending, mutate } = useSlotAdd();
const handleSubmit = (event: FormEvent) => {
event.preventDefault();
mutate({
dateend: combineDateTime(selectedDate, endTime).toISOString(),
datestart: combineDateTime(selectedDate, startTime).toISOString(),
state: Enum_Slot_State.Open,
});
setStartTime('');
setEndTime('');
};
return (
<form className="grid grid-cols-[1fr_1fr_auto] gap-2" onSubmit={handleSubmit}>
<div className="flex-1">
<Input
disabled={isPending}
id="start-time"
onChange={(event) => setStartTime(event.target.value)}
required
type="time"
value={startTime}
/>
</div>
<div className="flex-1">
<Input
disabled={isPending}
id="end-time"
onChange={(event) => setEndTime(event.target.value)}
required
type="time"
value={endTime}
/>
</div>
<Button type="submit">
<PlusSquare className="size-4" />
</Button>
</form>
);
}

View File

@ -0,0 +1,43 @@
/* eslint-disable canonical/id-match */
'use client';
import { Context, ContextProvider } from '../context';
import { AddTimePair } from './time-pair';
import { ScheduleSlotsContext } from '@/context/schedule-slots';
import { useSlotAdd } from '@/hooks/slots';
import { withContext } from '@/utils/context';
import { combineDateTime } from '@/utils/date';
import { Enum_Slot_State } from '@repo/graphql/types';
import { Button } from '@repo/ui/components/ui/button';
import { PlusSquare } from 'lucide-react';
import { type FormEvent, use } from 'react';
export const AddSlotForm = withContext(ContextProvider)(function () {
const { endTime, setEndTime, setStartTime, startTime } = use(Context);
const { selectedDate } = use(ScheduleSlotsContext);
const { mutate: addSlot } = useSlotAdd();
const handleSubmit = (event: FormEvent) => {
event.preventDefault();
if (startTime && endTime) {
addSlot({
dateend: combineDateTime(selectedDate, endTime).toISOString(),
datestart: combineDateTime(selectedDate, startTime).toISOString(),
state: Enum_Slot_State.Open,
});
setStartTime('');
setEndTime('');
}
};
return (
<form className="grid grid-cols-[1fr_1fr_auto] items-center gap-2" onSubmit={handleSubmit}>
<AddTimePair />
<Button type="submit">
<PlusSquare className="size-4" />
</Button>
</form>
);
});

View File

@ -1,15 +1,16 @@
'use client';
import { EditableTimePair, ReadonlyTimePair } from '.';
import { Context } from '../context';
import { Context, ContextProvider } from '../context';
import { type Props } from '../types';
import { EditableTimePair, ReadonlyTimePair } from './time-pair';
import { ScheduleSlotsContext } from '@/context/schedule-slots';
import { useSlotMutation, useSlotQuery } from '@/hooks/slots';
import { withContext } from '@/utils/context';
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<Props>) {
export const EditSlotForm = withContext(ContextProvider)(function (props: Readonly<Props>) {
const { documentId } = props;
const { editMode, endTime, setEditMode, setEndTime, setStartTime, startTime } = use(Context);
@ -17,12 +18,12 @@ export function Form(props: Readonly<Props>) {
const { selectedDate } = use(ScheduleSlotsContext);
const { isLoading: isLoadingSlotQuery } = useSlotQuery({ documentId });
const { isPending: isPendingSlotMutation, mutate } = useSlotMutation({ documentId });
const { isPending: isPendingSlotMutation, mutate: mutateSlot } = useSlotMutation({ documentId });
const handleSubmit = (event: FormEvent) => {
event.preventDefault();
if (startTime && endTime) {
mutate({
mutateSlot({
data: {
dateend: combineDateTime(selectedDate, endTime).toISOString(),
datestart: combineDateTime(selectedDate, startTime).toISOString(),
@ -52,4 +53,4 @@ export function Form(props: Readonly<Props>) {
</Button>
</form>
);
}
});

View File

@ -1,12 +1,31 @@
'use client';
import { Context } from '../context';
import { Context, type ContextType } from '../context';
import { type Props } from '../types';
import { useSlotQuery } from '@/hooks/slots';
import { useSlotAdd, 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';
type TimePairProps = Pick<ContextType, 'endTime' | 'setEndTime' | 'setStartTime' | 'startTime'> & {
readonly disabled?: boolean;
};
export function AddTimePair() {
const { endTime, setEndTime, setStartTime, startTime } = use(Context);
const { isPending } = useSlotAdd();
return (
<TimeInputPair
disabled={isPending}
endTime={endTime}
setEndTime={setEndTime}
setStartTime={setStartTime}
startTime={startTime}
/>
);
}
export function EditableTimePair({ documentId }: Readonly<Props>) {
const { editMode, endTime, setEndTime, setStartTime, startTime } = use(Context);
const { data } = useSlotQuery({ documentId });
@ -19,26 +38,12 @@ export function EditableTimePair({ documentId }: Readonly<Props>) {
}, [data?.slot?.dateend, data?.slot?.datestart, editMode, setEndTime, setStartTime]);
return (
<>
<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>
</>
<TimeInputPair
endTime={endTime}
setEndTime={setEndTime}
setStartTime={setStartTime}
startTime={startTime}
/>
);
}
@ -54,3 +59,36 @@ export function ReadonlyTimePair({ documentId }: Readonly<Props>) {
</>
);
}
function TimeInputPair({
disabled = false,
endTime,
setEndTime,
setStartTime,
startTime,
}: TimePairProps) {
return (
<>
<div className="flex-1">
<Input
disabled={disabled}
id="start-time"
onChange={(event) => setStartTime?.(event.target.value)}
required
type="time"
value={startTime}
/>
</div>
<div className="flex-1">
<Input
disabled={disabled}
id="end-time"
onChange={(event) => setEndTime?.(event.target.value)}
required
type="time"
value={endTime}
/>
</div>
</>
);
}

View File

@ -1,7 +1,7 @@
'use client';
import { createContext, type PropsWithChildren, useMemo, useState } from 'react';
type ContextType = {
export type ContextType = {
editMode: boolean;
endTime: string;
setEditMode: (value: boolean) => void;

View File

@ -1,2 +0,0 @@
export * from './form';
export * from './time-pair';

View File

@ -1,12 +0,0 @@
'use client';
import { Form } from './components';
import { ContextProvider } from './context';
import { type Props } from './types';
export function EditSlotForm(props: Readonly<Props>) {
return (
<ContextProvider>
<Form {...props} />
</ContextProvider>
);
}

View File

@ -1,6 +1,6 @@
'use client';
import { AddSlotForm } from './add-slot-form';
import { EditSlotForm } from './edit-slot-form';
import { AddSlotForm } from './components/add-slot-form';
import { EditSlotForm } from './components/edit-slot-form';
import { useSlots } from '@/hooks/slots';
import { Loader } from 'lucide-react';

View File

@ -0,0 +1,15 @@
import { type ComponentType, type JSX } from 'react';
type ContextProvider = <T extends object>(props: T) => JSX.Element;
export function withContext<T extends object>(ContextProvider: ContextProvider) {
return function <P extends T>(Component: ComponentType<P>) {
return (props: P) => {
return (
<ContextProvider {...props}>
<Component {...props} />
</ContextProvider>
);
};
};
}