order: add repeat button
This commit is contained in:
parent
1fb3b67d79
commit
9beee9902e
@ -1,12 +1,16 @@
|
||||
/* eslint-disable canonical/id-match */
|
||||
'use client';
|
||||
|
||||
import FloatingActionPanel from '../shared/action-panel';
|
||||
import { type OrderComponentProps } from './types';
|
||||
import { useIsMaster } from '@/hooks/api/customers';
|
||||
import { useOrderMutation, useOrderQuery } from '@/hooks/api/orders';
|
||||
import { usePushWithData } from '@/hooks/url';
|
||||
import { Enum_Order_State } from '@repo/graphql/types';
|
||||
|
||||
export function OrderButtons({ documentId }: Readonly<OrderComponentProps>) {
|
||||
const push = usePushWithData();
|
||||
|
||||
const isMaster = useIsMaster();
|
||||
|
||||
const { data: { order } = {} } = useOrderQuery({ documentId });
|
||||
@ -34,6 +38,10 @@ export function OrderButtons({ documentId }: Readonly<OrderComponentProps>) {
|
||||
}
|
||||
}
|
||||
|
||||
function handleOnRepeat() {
|
||||
push('/orders/add', order);
|
||||
}
|
||||
|
||||
return (
|
||||
<FloatingActionPanel
|
||||
isLoading={isPending}
|
||||
@ -49,6 +57,7 @@ export function OrderButtons({ documentId }: Readonly<OrderComponentProps>) {
|
||||
? undefined
|
||||
: () => handleApprove()
|
||||
}
|
||||
onRepeat={isCancelled || isCompleted ? handleOnRepeat : undefined}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -7,8 +7,10 @@ import { NextButton } from './next-button';
|
||||
import { ErrorPage, SuccessPage } from './result';
|
||||
import { ServiceSelect } from './service-select';
|
||||
import { SubmitButton } from './submit-button';
|
||||
import { useGetUrlData } from '@/hooks/url';
|
||||
import { OrderStoreProvider, useInitOrderStore, useOrderStore } from '@/stores/order';
|
||||
import { withContext } from '@/utils/context';
|
||||
import { type OrderFieldsFragment } from '@repo/graphql/types';
|
||||
import { LoadingSpinner } from '@repo/ui/components/ui/spinner';
|
||||
import { type JSX } from 'react';
|
||||
|
||||
@ -35,7 +37,9 @@ function getButtonComponent(step: string) {
|
||||
}
|
||||
|
||||
export const OrderForm = withContext(OrderStoreProvider)(function () {
|
||||
useInitOrderStore();
|
||||
const data = useGetUrlData<OrderFieldsFragment>();
|
||||
|
||||
useInitOrderStore(data);
|
||||
|
||||
const step = useOrderStore((store) => store.step);
|
||||
if (step === 'loading') return <LoadingSpinner />;
|
||||
|
||||
1
apps/web/hooks/url/index.ts
Normal file
1
apps/web/hooks/url/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './parameters';
|
||||
35
apps/web/hooks/url/parameters.ts
Normal file
35
apps/web/hooks/url/parameters.ts
Normal file
@ -0,0 +1,35 @@
|
||||
/* eslint-disable canonical/id-match */
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
'use client';
|
||||
|
||||
import { useRouter, useSearchParams } from 'next/navigation';
|
||||
|
||||
export function useGetUrlData<T>(): null | T {
|
||||
const searchParameters = useSearchParams();
|
||||
const data = searchParameters.get('_data_');
|
||||
|
||||
if (!data) return null;
|
||||
|
||||
try {
|
||||
const decoded = decodeURIComponent(atob(data));
|
||||
return JSON.parse(decoded) as T;
|
||||
} catch (error) {
|
||||
throw new Error('Failed to parse data parameters', { cause: error });
|
||||
}
|
||||
}
|
||||
|
||||
export function usePushWithData() {
|
||||
const router = useRouter();
|
||||
const searchParameters = useSearchParams();
|
||||
|
||||
return <T>(url: string, parameters: T) => {
|
||||
try {
|
||||
const base64 = btoa(encodeURIComponent(JSON.stringify(parameters)));
|
||||
const parameters_ = new URLSearchParams(searchParameters);
|
||||
parameters_.set('_data_', base64);
|
||||
router.push(`${url}?${parameters_.toString()}`);
|
||||
} catch (error) {
|
||||
throw new Error('Failed to serialize data parameters', { cause: error });
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1,8 +1,10 @@
|
||||
/* eslint-disable sonarjs/cognitive-complexity */
|
||||
'use client';
|
||||
import { useOrderStore } from './context';
|
||||
import { type Steps } from './types';
|
||||
import { useCustomerQuery, useIsMaster } from '@/hooks/api/customers';
|
||||
import { useEffect } from 'react';
|
||||
import { type OrderFieldsFragment } from '@repo/graphql/types';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
|
||||
const STEPS: Steps[] = [
|
||||
'master-select',
|
||||
@ -14,28 +16,63 @@ const STEPS: Steps[] = [
|
||||
export const MASTER_STEPS: Steps[] = STEPS.filter((step) => step !== 'master-select');
|
||||
export const CLIENT_STEPS: Steps[] = STEPS.filter((step) => step !== 'client-select');
|
||||
|
||||
export function useInitOrderStore() {
|
||||
export function useInitOrderStore(initData: null | OrderFieldsFragment) {
|
||||
const initialized = useRef(false);
|
||||
|
||||
const { data: { customer } = {} } = useCustomerQuery();
|
||||
const isMaster = useIsMaster();
|
||||
|
||||
const setMasterId = useOrderStore((store) => store.setMasterId);
|
||||
const setClientId = useOrderStore((store) => store.setClientId);
|
||||
const setServiceId = useOrderStore((store) => store.setServiceId);
|
||||
const setStep = useOrderStore((store) => store.setStep);
|
||||
const setStepsSequence = useOrderStore((store) => store._setStepSequence);
|
||||
const isMaster = useIsMaster();
|
||||
const step = useOrderStore((store) => store.step);
|
||||
|
||||
const setFirstStep = useCallback(() => {
|
||||
const steps = isMaster ? MASTER_STEPS : CLIENT_STEPS;
|
||||
setStepsSequence(steps);
|
||||
setStep(steps[0] as Steps);
|
||||
}, [isMaster, setStep, setStepsSequence]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isMaster && customer) {
|
||||
setMasterId(customer?.documentId);
|
||||
if (initialized.current || !customer || step !== 'loading') return;
|
||||
|
||||
if (initData) {
|
||||
const masterId = initData.slot?.master?.documentId;
|
||||
const clientId = initData.client?.documentId;
|
||||
const serviceId = initData.services[0]?.documentId;
|
||||
|
||||
if (masterId) setMasterId(masterId);
|
||||
if (clientId) setClientId(clientId);
|
||||
if (serviceId) setServiceId(serviceId);
|
||||
|
||||
if (masterId && clientId && serviceId) {
|
||||
setStep('datetime-select');
|
||||
} else {
|
||||
setFirstStep();
|
||||
}
|
||||
} else {
|
||||
if (isMaster) {
|
||||
setMasterId(customer.documentId);
|
||||
} else {
|
||||
setClientId(customer.documentId);
|
||||
}
|
||||
|
||||
setFirstStep();
|
||||
}
|
||||
|
||||
if (!isMaster && customer) {
|
||||
setClientId(customer?.documentId);
|
||||
}
|
||||
|
||||
const steps = isMaster ? MASTER_STEPS : CLIENT_STEPS;
|
||||
const initialStep = steps[0] as Steps;
|
||||
|
||||
setStepsSequence(steps);
|
||||
setStep(initialStep);
|
||||
}, [customer, isMaster, setClientId, setMasterId, setStep, setStepsSequence]);
|
||||
initialized.current = true;
|
||||
}, [
|
||||
customer,
|
||||
initData,
|
||||
isMaster,
|
||||
setClientId,
|
||||
setFirstStep,
|
||||
setMasterId,
|
||||
setServiceId,
|
||||
setStep,
|
||||
setStepsSequence,
|
||||
step,
|
||||
]);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user