split next-button into two buttons

This commit is contained in:
vchikalkin 2025-05-09 17:56:53 +03:00
parent 1528cc25b8
commit 0ed90d5451
5 changed files with 68 additions and 54 deletions

View File

@ -1,4 +1,5 @@
'use client';
import { useOrderCreate } from '@/hooks/orders';
import { useOrderStore } from '@/stores/order';
import { Button } from '@repo/ui/components/ui/button';
@ -6,14 +7,18 @@ export function BackButton() {
const step = useOrderStore((store) => store.step);
const previousStep = useOrderStore((store) => store.prevStep);
function handleOnClick() {
previousStep();
}
const { isPending } = useOrderCreate();
if (['master-select', 'success'].includes(step)) return null;
return (
<Button className="w-full" onClick={() => handleOnClick()} type="button" variant="ghost">
<Button
className="w-full"
disabled={isPending}
onClick={previousStep}
type="button"
variant="ghost"
>
Назад
</Button>
);

View File

@ -1,58 +1,21 @@
/* eslint-disable sonarjs/no-duplicate-string */
'use client';
import { useOrderCreate } from '@/hooks/orders';
import { useOrderStore } from '@/stores/order';
import { Button } from '@repo/ui/components/ui/button';
import { useEffect } from 'react';
export function NextButton() {
const { clientId, date, nextStep, serviceId, setStep, slotId, step, time } = useOrderStore(
const { clientId, date, masterId, nextStep, serviceId, step, time } = useOrderStore(
(store) => store,
);
const disabled = useButtonDisabled();
const { isPending, isSuccess, mutate: createOrder } = useOrderCreate();
useEffect(() => {
if (isSuccess) setStep('success');
}, [isSuccess, setStep]);
function handleOnClick() {
if (step !== 'datetime-select') return nextStep();
if (!clientId || !date || !serviceId || !slotId || !time) return null;
return createOrder({ clientId, date, serviceId, slotId, time });
}
if (isPending) {
return (
<Button className="w-full" disabled type="button">
Загрузка...
</Button>
);
}
return (
<Button className="w-full" disabled={disabled} onClick={() => handleOnClick()} type="button">
{step === 'datetime-select' ? 'Завершить' : 'Далее'}
</Button>
);
}
function useButtonDisabled() {
const step = useOrderStore((state) => state.step);
const clientId = useOrderStore((state) => state.clientId);
const masterId = useOrderStore((state) => state.masterId);
const serviceId = useOrderStore((state) => state.serviceId);
const date = useOrderStore((state) => state.date);
const time = useOrderStore((state) => state.time);
return (
const isDisabled =
(step === 'master-select' && !masterId) ||
(step === 'client-select' && !clientId) ||
(step === 'service-select' && !serviceId) ||
(step === 'datetime-select' && (!date || !time))
(step === 'datetime-select' && (!date || !time));
return (
<Button className="w-full" disabled={isDisabled} onClick={nextStep} type="button">
Далее
</Button>
);
}

View File

@ -0,0 +1,35 @@
'use client';
import { useOrderCreate } from '@/hooks/orders';
import { useOrderStore } from '@/stores/order';
import { Button } from '@repo/ui/components/ui/button';
import { LoadingSpinner } from '@repo/ui/components/ui/spinner';
import { useEffect } from 'react';
export function SubmitButton() {
const { clientId, date, serviceId, setStep, slotId, time } = useOrderStore((store) => store);
const isDisabled = !clientId || !serviceId || !date || !time || !slotId;
const { isError, isPending, isSuccess, mutate: createOrder } = useOrderCreate();
const handleSubmit = () => {
if (isDisabled) return;
createOrder({ clientId, date, serviceId, slotId, time });
};
useEffect(() => {
if (isSuccess) setStep('success');
if (isError) setStep('error');
}, [isError, isSuccess, setStep]);
return (
<Button
className="w-full"
disabled={isPending || isDisabled}
onClick={handleSubmit}
type="button"
>
{isPending ? <LoadingSpinner /> : 'Завершить'}
</Button>
);
}

View File

@ -8,6 +8,7 @@ import {
NextButton,
ServiceSelect,
} from './components';
import { SubmitButton } from './components/submit-button';
import { OrderStoreProvider, useOrderStore } from '@/stores/order';
import { useInitOrderStore } from '@/stores/order/hooks';
import { withContext } from '@/utils/context';
@ -20,6 +21,19 @@ const STEP_COMPONENTS: Record<string, JSX.Element> = {
'service-select': <ServiceSelect />,
};
function getStepComponent(step: string) {
return STEP_COMPONENTS[step] ?? null;
}
const BUTTON_COMPONENTS: Record<string, JSX.Element> = {
'': <NextButton />,
'datetime-select': <SubmitButton />,
};
function getButtonComponent(step: string) {
return BUTTON_COMPONENTS[step] ?? <NextButton />;
}
export const OrderForm = withContext(OrderStoreProvider)(function () {
useInitOrderStore();
@ -30,13 +44,9 @@ export const OrderForm = withContext(OrderStoreProvider)(function () {
<div className="space-y-4 [&>*]:px-4">
{getStepComponent(step)}
<div className="space-y-2">
<NextButton />
{getButtonComponent(step)}
<BackButton />
</div>
</div>
);
});
function getStepComponent(step: string) {
return STEP_COMPONENTS[step] ?? null;
}

View File

@ -20,4 +20,5 @@ export const useOrderQuery = ({ documentId }: Props) =>
export const useOrderCreate = () =>
useMutation({
mutationFn: createOrder,
mutationKey: ['orders', 'create'],
});