File size: 2,093 Bytes
c2ea5ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import React, {
  createContext,
  useContext,
  useReducer,
  ReactNode,
  useMemo,
} from "react";
import { ModalState, ModalConfig } from "@/types";

interface ModalContextType {
  modalState: ModalState;
  openModal: (
    type: ModalState["type"],
    title: string,
    data?: any,
    config?: ModalConfig
  ) => void;
  closeModal: () => void;
}

type ModalAction =
  | {
      type: "OPEN_MODAL";
      payload: {
        modalType: ModalState["type"];
        title: string;
        data?: any;
        config?: ModalConfig;
      };
    }
  | { type: "CLOSE_MODAL" };

const initialState: ModalState = {
  isOpen: false,
  type: null,
  title: "",
  data: undefined,
  config: undefined,
};

function modalReducer(state: ModalState, action: ModalAction): ModalState {
  switch (action.type) {
    case "OPEN_MODAL":
      return {
        isOpen: true,
        type: action.payload.modalType,
        title: action.payload.title,
        data: action.payload.data,
        config: action.payload.config,
      };
    case "CLOSE_MODAL":
      return {
        ...initialState,
      };
    default:
      return state;
  }
}

const ModalContext = createContext<ModalContextType | undefined>(undefined);

export function ModalProvider({ children }: { children: ReactNode }) {
  const [modalState, dispatch] = useReducer(modalReducer, initialState);

  const actions = useMemo(
    () => ({
      openModal: (
        type: ModalState["type"],
        title: string,
        data?: any,
        config?: ModalConfig
      ) => {
        dispatch({
          type: "OPEN_MODAL",
          payload: { modalType: type, title, data, config },
        });
      },
      closeModal: () => {
        dispatch({ type: "CLOSE_MODAL" });
      },
    }),
    []
  );

  return (
    <ModalContext.Provider value={{ modalState, ...actions }}>
      {children}
    </ModalContext.Provider>
  );
}

export function useModal() {
  const context = useContext(ModalContext);
  if (context === undefined) {
    throw new Error("useModal must be used within a ModalProvider");
  }
  return context;
}