From 8c8a588dfc6334016899cdf53765570ad7a66d8e Mon Sep 17 00:00:00 2001 From: vchikalkin Date: Thu, 10 Apr 2025 11:37:27 +0300 Subject: [PATCH] context/order: split into files --- apps/web/context/order.tsx | 122 ----------------------------- apps/web/context/order/hooks.tsx | 19 +++++ apps/web/context/order/index.tsx | 52 ++++++++++++ apps/web/context/order/reducer.tsx | 36 +++++++++ apps/web/context/order/types.tsx | 30 +++++++ 5 files changed, 137 insertions(+), 122 deletions(-) delete mode 100644 apps/web/context/order.tsx create mode 100644 apps/web/context/order/hooks.tsx create mode 100644 apps/web/context/order/index.tsx create mode 100644 apps/web/context/order/reducer.tsx create mode 100644 apps/web/context/order/types.tsx diff --git a/apps/web/context/order.tsx b/apps/web/context/order.tsx deleted file mode 100644 index 2c5039d..0000000 --- a/apps/web/context/order.tsx +++ /dev/null @@ -1,122 +0,0 @@ -'use client'; -import { createContext, type PropsWithChildren, useMemo, useReducer, useState } from 'react'; - -type Action = { payload: Steps; type: 'SET_STEP' } | { type: 'NEXT_STEP' } | { type: 'PREV_STEP' }; - -type ContextType = { - clientId: null | string; - date: Date; - masterId: null | string; - nextStep: () => void; - prevStep: () => void; - serviceId: null | string; - setClientId: (clientId: null | string) => void; - setDate: (date: Date) => void; - setMasterId: (customerId: null | string) => void; - setServiceId: (serviceId: null | string) => void; - setStep: (step: Steps) => void; - setTime: (time: string) => void; - step: Steps; - time: null | string; -}; - -type State = { step: Steps }; -type Steps = 'client-select' | 'datetime-select' | 'master-select' | 'service-select' | 'success'; - -const stepsSequence: Steps[] = [ - 'master-select', - 'client-select', - 'service-select', - 'datetime-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 'PREV_STEP': { - const currentIndex = stepsSequence.indexOf(state.step); - const previousIndex = currentIndex - 1; - const previousStep = stepsSequence[previousIndex]; - - return previousStep ? { ...state, step: previousStep } : state; - } - - case 'SET_STEP': { - return { ...state, step: action.payload }; - } - - default: - return state; - } -} - -function useEntityState() { - const [entityId, setEntityId] = useState(null); - return { entityId, setEntityId }; -} - -function useStep() { - const [state, dispatch] = useReducer(stepsReducer, { step: 'master-select' }); - - const setStep = (payload: Steps) => dispatch({ payload, type: 'SET_STEP' }); - const nextStep = () => dispatch({ type: 'NEXT_STEP' }); - const previousStep = () => dispatch({ type: 'PREV_STEP' }); - - return { nextStep, prevStep: previousStep, setStep, ...state }; -} - -export const OrderContext = createContext({} as ContextType); - -export function OrderContextProvider({ children }: Readonly) { - const { entityId: masterId, setEntityId: setMasterId } = useEntityState(); - const { entityId: serviceId, setEntityId: setServiceId } = useEntityState(); - const { entityId: clientId, setEntityId: setClientId } = useEntityState(); - - const [date, setDate] = useState(new Date()); - const [time, setTime] = useState(null); - - const { nextStep, prevStep, setStep, step } = useStep(); - - const value = useMemo( - () => ({ - clientId, - date, - masterId, - nextStep, - prevStep, - serviceId, - setClientId, - setDate, - setMasterId, - setServiceId, - setStep, - setTime, - step, - time, - }), - [ - clientId, - date, - masterId, - nextStep, - prevStep, - serviceId, - setClientId, - setMasterId, - setServiceId, - setStep, - step, - time, - ], - ); - - return {children}; -} diff --git a/apps/web/context/order/hooks.tsx b/apps/web/context/order/hooks.tsx new file mode 100644 index 0000000..b98dbd8 --- /dev/null +++ b/apps/web/context/order/hooks.tsx @@ -0,0 +1,19 @@ +'use client'; +import { stepsReducer } from './reducer'; +import { type Steps } from './types'; +import { useReducer, useState } from 'react'; + +export function useEntityState() { + const [entityId, setEntityId] = useState(null); + return { entityId, setEntityId }; +} + +export function useStep() { + const [state, dispatch] = useReducer(stepsReducer, { step: 'master-select' }); + + const setStep = (payload: Steps) => dispatch({ payload, type: 'SET_STEP' }); + const nextStep = () => dispatch({ type: 'NEXT_STEP' }); + const previousStep = () => dispatch({ type: 'PREV_STEP' }); + + return { nextStep, prevStep: previousStep, setStep, ...state }; +} diff --git a/apps/web/context/order/index.tsx b/apps/web/context/order/index.tsx new file mode 100644 index 0000000..32d4414 --- /dev/null +++ b/apps/web/context/order/index.tsx @@ -0,0 +1,52 @@ +'use client'; +import { useEntityState, useStep } from './hooks'; +import { type ContextType } from './types'; +import { createContext, type PropsWithChildren, useMemo, useState } from 'react'; + +export const OrderContext = createContext({} as ContextType); + +export function OrderContextProvider({ children }: Readonly) { + const { entityId: masterId, setEntityId: setMasterId } = useEntityState(); + const { entityId: serviceId, setEntityId: setServiceId } = useEntityState(); + const { entityId: clientId, setEntityId: setClientId } = useEntityState(); + + const [date, setDate] = useState(new Date()); + const [time, setTime] = useState(null); + + const { nextStep, prevStep, setStep, step } = useStep(); + + const value = useMemo( + () => ({ + clientId, + date, + masterId, + nextStep, + prevStep, + serviceId, + setClientId, + setDate, + setMasterId, + setServiceId, + setStep, + setTime, + step, + time, + }), + [ + clientId, + date, + masterId, + nextStep, + prevStep, + serviceId, + setClientId, + setMasterId, + setServiceId, + setStep, + step, + time, + ], + ); + + return {children}; +} diff --git a/apps/web/context/order/reducer.tsx b/apps/web/context/order/reducer.tsx new file mode 100644 index 0000000..096cf2e --- /dev/null +++ b/apps/web/context/order/reducer.tsx @@ -0,0 +1,36 @@ +import { type Action, type State, type Steps } from './types'; + +const stepsSequence: Steps[] = [ + 'master-select', + 'client-select', + 'service-select', + 'datetime-select', + 'success', +]; + +export 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 'PREV_STEP': { + const currentIndex = stepsSequence.indexOf(state.step); + const previousIndex = currentIndex - 1; + const previousStep = stepsSequence[previousIndex]; + + return previousStep ? { ...state, step: previousStep } : state; + } + + case 'SET_STEP': { + return { ...state, step: action.payload }; + } + + default: + return state; + } +} diff --git a/apps/web/context/order/types.tsx b/apps/web/context/order/types.tsx new file mode 100644 index 0000000..7f1451d --- /dev/null +++ b/apps/web/context/order/types.tsx @@ -0,0 +1,30 @@ +export type Action = + | { payload: Steps; type: 'SET_STEP' } + | { type: 'NEXT_STEP' } + | { type: 'PREV_STEP' }; + +export type ContextType = { + clientId: null | string; + date: Date; + masterId: null | string; + nextStep: () => void; + prevStep: () => void; + serviceId: null | string; + setClientId: (clientId: null | string) => void; + setDate: (date: Date) => void; + setMasterId: (customerId: null | string) => void; + setServiceId: (serviceId: null | string) => void; + setStep: (step: Steps) => void; + setTime: (time: string) => void; + step: Steps; + time: null | string; +}; + +export type State = { step: Steps }; + +export type Steps = + | 'client-select' + | 'datetime-select' + | 'master-select' + | 'service-select' + | 'success';