import clsx from "clsx" import React, { ReactNode, useReducer } from "react" import Button from "../../fundamentals/button" import Modal, { ModalProps } from "../../molecules/modal" import LayeredModal, { ILayeredModalContext } from "./layered-modal" enum SteppedActions { ENABLENEXTPAGE, DISABLENEXTPAGE, GOTONEXTPAGE, GOTOPREVIOUSPAGE, SETPAGE, SUBMIT, RESET, } type ISteppedContext = { currentStep: number nextStepEnabled: boolean enableNextPage: () => void disableNextPage: () => void goToNextPage: () => void goToPreviousPage: () => void submit: () => void reset: () => void setPage: (page: number) => void } const defaultContext: ISteppedContext = { currentStep: 0, nextStepEnabled: true, enableNextPage: () => {}, disableNextPage: () => {}, goToNextPage: () => {}, goToPreviousPage: () => {}, submit: () => {}, reset: () => {}, setPage: (page) => {}, } export const SteppedContext = React.createContext(defaultContext) const reducer = (state, action) => { switch (action.type) { case SteppedActions.ENABLENEXTPAGE: { return { ...state, nextStepEnabled: true } } case SteppedActions.DISABLENEXTPAGE: { return { ...state, nextStepEnabled: false } } case SteppedActions.GOTONEXTPAGE: { return { ...state, currentStep: state.currentStep + 1 } } case SteppedActions.GOTOPREVIOUSPAGE: { return { ...state, currentStep: Math.max(0, state.currentStep - 1) } } case SteppedActions.SETPAGE: { return { ...state, currentStep: action.payload > 0 ? action.payload : state.currentStep, } } case SteppedActions.SUBMIT: { return { ...state } } case SteppedActions.RESET: { return { ...state, currentStep: 0, nextStepEnabled: true } } } } type SteppedProps = { context: ISteppedContext title: string onSubmit: () => void lastScreenIsSummary?: boolean steps: ReactNode[] layeredContext?: ILayeredModalContext } & ModalProps export const SteppedProvider = ({ children }) => { const [state, dispatch] = useReducer(reducer, defaultContext) return ( { dispatch({ type: SteppedActions.ENABLENEXTPAGE }) }, disableNextPage: () => { dispatch({ type: SteppedActions.DISABLENEXTPAGE }) }, goToNextPage: () => { dispatch({ type: SteppedActions.GOTONEXTPAGE }) }, goToPreviousPage: () => { dispatch({ type: SteppedActions.GOTOPREVIOUSPAGE }) }, submit: () => { dispatch({ type: SteppedActions.SUBMIT }) }, setPage: (page: number) => { dispatch({ type: SteppedActions.SETPAGE, payload: page }) }, reset: () => { dispatch({ type: SteppedActions.RESET }) }, }} > {children} ) } const SteppedModal: React.FC = ({ context, steps, layeredContext, title, onSubmit, lastScreenIsSummary = false, handleClose, isLargeModal = true, }) => { const resetAndClose = () => { context.reset() handleClose() } const resetAndSubmit = () => { onSubmit() } return (

{title}

{!lastScreenIsSummary || (lastScreenIsSummary && context.currentStep !== steps.length - 1 && (
{`Step ${ context.currentStep + 1 } of ${steps.length}`} {steps.map((_, i) => ( context.currentStep, "bg-violet-60": context.currentStep >= i, }, { "outline-violet-20 outline outline-4": context.currentStep === i, } )} /> ))}
))}
{steps[context.currentStep]}
) } const ModalElement = ({ layeredContext, handleClose, isLargeModal = true, children, }) => layeredContext ? ( {children} ) : ( {children} ) export default SteppedModal