81 lines
2.2 KiB
TypeScript
81 lines
2.2 KiB
TypeScript
'use client';
|
|
import { createContext, type PropsWithChildren, useMemo, useReducer, useState } from 'react';
|
|
|
|
type Action = { payload: Steps; type: 'SET_STEP' } | { type: 'NEXT_STEP' };
|
|
|
|
type ContextType = {
|
|
customerId: null | string;
|
|
nextStep: () => void;
|
|
orderId: null | string;
|
|
setCustomerId: (customerId: string) => void;
|
|
setOrderId: (orderId: string) => void;
|
|
setStep: (step: Steps) => void;
|
|
step: Steps;
|
|
};
|
|
|
|
type State = { step: Steps };
|
|
type Steps = 'customer-select' | 'service-select' | 'success' | 'time-select';
|
|
|
|
const stepsSequence: Steps[] = ['customer-select', 'service-select', 'time-select', 'success'];
|
|
|
|
function stepsReducer(state: State, action: Action): State {
|
|
switch (action.type) {
|
|
case 'NEXT_STEP': {
|
|
const currentIndex = stepsSequence.indexOf(state.step);
|
|
const nextIndex = currentIndex + 1;
|
|
const nextStep = stepsSequence[nextIndex];
|
|
|
|
return nextStep ? { ...state, step: nextStep } : state;
|
|
}
|
|
|
|
case 'SET_STEP': {
|
|
return { ...state, step: action.payload };
|
|
}
|
|
|
|
default:
|
|
return state;
|
|
}
|
|
}
|
|
|
|
function useCustomerState() {
|
|
const [customerId, setCustomerId] = useState<null | string>(null);
|
|
return { customerId, setCustomerId };
|
|
}
|
|
|
|
function useOrderState() {
|
|
const [orderId, setOrderId] = useState<null | string>(null);
|
|
return { orderId, setOrderId };
|
|
}
|
|
|
|
function useStep() {
|
|
const [state, dispatch] = useReducer(stepsReducer, { step: 'customer-select' });
|
|
|
|
const setStep = (payload: Steps) => dispatch({ payload, type: 'SET_STEP' });
|
|
const nextStep = () => dispatch({ type: 'NEXT_STEP' });
|
|
|
|
return { nextStep, setStep, ...state };
|
|
}
|
|
|
|
export const OrderContext = createContext<ContextType>({} as ContextType);
|
|
|
|
export function OrderContextProvider({ children }: Readonly<PropsWithChildren>) {
|
|
const { customerId, setCustomerId } = useCustomerState();
|
|
const { orderId, setOrderId } = useOrderState();
|
|
const { nextStep, setStep, step } = useStep();
|
|
|
|
const value = useMemo(
|
|
() => ({
|
|
customerId,
|
|
nextStep,
|
|
orderId,
|
|
setCustomerId,
|
|
setOrderId,
|
|
setStep,
|
|
step,
|
|
}),
|
|
[customerId, nextStep, orderId, setCustomerId, setOrderId, setStep, step],
|
|
);
|
|
|
|
return <OrderContext.Provider value={value}>{children}</OrderContext.Provider>;
|
|
}
|