diff --git a/src/app/deals/contexts/BoardsContext.tsx b/src/app/deals/contexts/BoardsContext.tsx index 61ee806..8bdbc90 100644 --- a/src/app/deals/contexts/BoardsContext.tsx +++ b/src/app/deals/contexts/BoardsContext.tsx @@ -1,10 +1,11 @@ "use client"; -import React, { createContext, FC, useContext, useState } from "react"; +import React, { useState } from "react"; import { useProjectsContext } from "@/app/deals/contexts/ProjectsContext"; -import { BoardSchema } from "@/lib/client"; import { BoardsCrud, useBoardsCrud } from "@/hooks/cruds/useBoardsCrud"; import useBoardsList from "@/hooks/lists/useBoardsList"; +import { BoardSchema } from "@/lib/client"; +import makeContext from "@/lib/contextFactory/contextFactory"; type BoardsContextState = { boards: BoardSchema[]; @@ -15,9 +16,7 @@ type BoardsContextState = { boardsCrud: BoardsCrud; }; -const BoardsContext = createContext(undefined); - -const useBoardsContextState = () => { +const useBoardsContextState = (): BoardsContextState => { const { selectedProject: project } = useProjectsContext(); const { boards, @@ -50,28 +49,5 @@ const useBoardsContextState = () => { }; }; -type BoardsContextProviderProps = { - children: React.ReactNode; -}; - -export const BoardsContextProvider: FC = ({ - children, -}) => { - const state = useBoardsContextState(); - - return ( - - {children} - - ); -}; - -export const useBoardsContext = () => { - const context = useContext(BoardsContext); - if (!context) { - throw new Error( - "useBoardsContext must be used within a BoardsContextProvider" - ); - } - return context; -}; +export const [BoardsContextProvider, useBoardsContext] = + makeContext(useBoardsContextState, "Boards"); diff --git a/src/app/deals/contexts/DealsContext.tsx b/src/app/deals/contexts/DealsContext.tsx index e0fc838..ae5fde5 100644 --- a/src/app/deals/contexts/DealsContext.tsx +++ b/src/app/deals/contexts/DealsContext.tsx @@ -1,11 +1,12 @@ "use client"; -import React, { createContext, FC, useContext } from "react"; +import React from "react"; import { useBoardsContext } from "@/app/deals/contexts/BoardsContext"; import { useStatusesContext } from "@/app/deals/contexts/StatusesContext"; import { DealsCrud, useDealsCrud } from "@/hooks/cruds/useDealsCrud"; import useDealsList from "@/hooks/lists/useDealsList"; import { DealSchema } from "@/lib/client"; +import makeContext from "@/lib/contextFactory/contextFactory"; type DealsContextState = { deals: DealSchema[]; @@ -14,16 +15,16 @@ type DealsContextState = { dealsCrud: DealsCrud; }; -const DealsContext = createContext(undefined); - -const useDealsContextState = () => { +const useDealsContextState = (): DealsContextState => { const { selectedBoard } = useBoardsContext(); const { statuses } = useStatusesContext(); const { deals, setDeals, refetch: refetchDeals, - } = useDealsList({ boardId: selectedBoard?.id }); + } = useDealsList({ + boardId: selectedBoard?.id, + }); const dealsCrud = useDealsCrud({ deals, @@ -33,34 +34,8 @@ const useDealsContextState = () => { statuses, }); - return { - deals, - setDeals, - refetchDeals, - dealsCrud, - }; + return { deals, setDeals, refetchDeals, dealsCrud }; }; -type DealsContextProviderProps = { - children: React.ReactNode; -}; - -export const DealsContextProvider: FC = ({ - children, -}) => { - const state = useDealsContextState(); - - return ( - {children} - ); -}; - -export const useDealsContext = () => { - const context = useContext(DealsContext); - if (!context) { - throw new Error( - "useDealsContext must be used within a DealsContextProvider" - ); - } - return context; -}; +export const [DealsContextProvider, useDealsContext] = + makeContext(useDealsContextState, "Deals"); diff --git a/src/app/deals/contexts/ProjectsContext.tsx b/src/app/deals/contexts/ProjectsContext.tsx index a4ba55e..c58391b 100644 --- a/src/app/deals/contexts/ProjectsContext.tsx +++ b/src/app/deals/contexts/ProjectsContext.tsx @@ -1,9 +1,10 @@ "use client"; -import React, { createContext, FC, useContext, useState } from "react"; +import React, { useState } from "react"; import { ProjectsCrud, useProjectsCrud } from "@/hooks/cruds/useProjectsCrud"; import useProjectsList from "@/hooks/lists/useProjectsList"; import { ProjectSchema } from "@/lib/client"; +import makeContext from "@/lib/contextFactory/contextFactory"; type ProjectsContextState = { selectedProject: ProjectSchema | null; @@ -13,11 +14,7 @@ type ProjectsContextState = { projectsCrud: ProjectsCrud; }; -const ProjectsContext = createContext( - undefined -); - -const useProjectsContextState = () => { +const useProjectsContextState = (): ProjectsContextState => { const { projects, setProjects, @@ -49,28 +46,5 @@ const useProjectsContextState = () => { }; }; -type ProjectsContextProviderProps = { - children: React.ReactNode; -}; - -export const ProjectsContextProvider: FC = ({ - children, -}) => { - const state = useProjectsContextState(); - - return ( - - {children} - - ); -}; - -export const useProjectsContext = () => { - const context = useContext(ProjectsContext); - if (!context) { - throw new Error( - "useProjectsContext must be used within a ProjectsContextProvider" - ); - } - return context; -}; +export const [ProjectsContextProvider, useProjectsContext] = + makeContext(useProjectsContextState, "Projects"); diff --git a/src/app/deals/contexts/StatusesContext.tsx b/src/app/deals/contexts/StatusesContext.tsx index f2fb736..8c52928 100644 --- a/src/app/deals/contexts/StatusesContext.tsx +++ b/src/app/deals/contexts/StatusesContext.tsx @@ -1,10 +1,11 @@ "use client"; -import React, { createContext, FC, useContext } from "react"; +import React from "react"; import { useBoardsContext } from "@/app/deals/contexts/BoardsContext"; import { StatusesCrud, useStatusesCrud } from "@/hooks/cruds/useStatusesCrud"; import useStatusesList from "@/hooks/lists/useStatusesList"; import { StatusSchema } from "@/lib/client"; +import makeContext from "@/lib/contextFactory/contextFactory"; type StatusesContextState = { statuses: StatusSchema[]; @@ -13,11 +14,7 @@ type StatusesContextState = { statusesCrud: StatusesCrud; }; -const StatusesContext = createContext( - undefined -); - -const useStatusesContextState = () => { +const useStatusesContextState = (): StatusesContextState => { const { selectedBoard } = useBoardsContext(); const { statuses, @@ -42,28 +39,5 @@ const useStatusesContextState = () => { }; }; -type StatusesContextProviderProps = { - children: React.ReactNode; -}; - -export const StatusesContextProvider: FC = ({ - children, -}) => { - const state = useStatusesContextState(); - - return ( - - {children} - - ); -}; - -export const useStatusesContext = () => { - const context = useContext(StatusesContext); - if (!context) { - throw new Error( - "useStatusesContext must be used within a StatusesContextProvider" - ); - } - return context; -}; +export const [StatusesContextProvider, useStatusesContext] = + makeContext(useStatusesContextState, "Statuses"); diff --git a/src/app/deals/drawers/BoardStatusesEditorDrawer/contexts/BoardStatusesContext.tsx b/src/app/deals/drawers/BoardStatusesEditorDrawer/contexts/BoardStatusesContext.tsx index f452120..221bd1d 100644 --- a/src/app/deals/drawers/BoardStatusesEditorDrawer/contexts/BoardStatusesContext.tsx +++ b/src/app/deals/drawers/BoardStatusesEditorDrawer/contexts/BoardStatusesContext.tsx @@ -1,9 +1,10 @@ "use client"; -import React, { createContext, FC, useContext } from "react"; +import React from "react"; import { StatusesCrud, useStatusesCrud } from "@/hooks/cruds/useStatusesCrud"; import useStatusesList from "@/hooks/lists/useStatusesList"; import { BoardSchema, StatusSchema } from "@/lib/client"; +import makeContext from "@/lib/contextFactory/contextFactory"; type BoardStatusesContextState = { board: BoardSchema; @@ -13,15 +14,13 @@ type BoardStatusesContextState = { statusesCrud: StatusesCrud; }; -const BoardStatusesContext = createContext< - BoardStatusesContextState | undefined ->(undefined); - type Props = { board: BoardSchema; }; -const useBoardStatusesContextState = ({ board }: Props) => { +const useBoardStatusesContextState = ({ + board, +}: Props): BoardStatusesContextState => { const { statuses, setStatuses, @@ -46,28 +45,8 @@ const useBoardStatusesContextState = ({ board }: Props) => { }; }; -type BoardStatusesContextProviderProps = { - children: React.ReactNode; -} & Props; - -export const BoardStatusesContextProvider: FC< - BoardStatusesContextProviderProps -> = ({ children, ...props }) => { - const state = useBoardStatusesContextState(props); - - return ( - - {children} - +export const [BoardStatusesContextProvider, useBoardStatusesContext] = + makeContext( + useBoardStatusesContextState, + "BoardStatuses" ); -}; - -export const useBoardStatusesContext = () => { - const context = useContext(BoardStatusesContext); - if (!context) { - throw new Error( - "useBoardStatusesContext must be used within a BoardStatusesContextProvider" - ); - } - return context; -}; diff --git a/src/app/deals/drawers/ProjectBoardsEditorDrawer/contexts/ProjectBoardsContext.tsx b/src/app/deals/drawers/ProjectBoardsEditorDrawer/contexts/ProjectBoardsContext.tsx index 7a49c06..788834b 100644 --- a/src/app/deals/drawers/ProjectBoardsEditorDrawer/contexts/ProjectBoardsContext.tsx +++ b/src/app/deals/drawers/ProjectBoardsEditorDrawer/contexts/ProjectBoardsContext.tsx @@ -1,9 +1,10 @@ "use client"; -import React, { createContext, FC, useContext } from "react"; +import React from "react"; import { BoardsCrud, useBoardsCrud } from "@/hooks/cruds/useBoardsCrud"; import useBoardsList from "@/hooks/lists/useBoardsList"; import { BoardSchema, ProjectSchema } from "@/lib/client"; +import makeContext from "@/lib/contextFactory/contextFactory"; type ProjectBoardsContextState = { boards: BoardSchema[]; @@ -13,10 +14,6 @@ type ProjectBoardsContextState = { boardsCrud: BoardsCrud; }; -const ProjectBoardsContext = createContext< - ProjectBoardsContextState | undefined ->(undefined); - type Props = { project: ProjectSchema; }; @@ -44,28 +41,8 @@ const useProjectBoardsContextState = ({ project }: Props) => { }; }; -type ProjectBoardsContextProviderProps = { - children: React.ReactNode; -} & Props; - -export const ProjectBoardsContextProvider: FC< - ProjectBoardsContextProviderProps -> = ({ children, ...props }) => { - const state = useProjectBoardsContextState(props); - - return ( - - {children} - +export const [ProjectBoardsContextProvider, useProjectBoardsContext] = + makeContext( + useProjectBoardsContextState, + "ProjectBoards" ); -}; - -export const useProjectBoardsContext = () => { - const context = useContext(ProjectBoardsContext); - if (!context) { - throw new Error( - "useProjectBoardsContext must be used within a ProjectBoardsContextProvider" - ); - } - return context; -}; diff --git a/src/lib/contextFactory/contextFactory.tsx b/src/lib/contextFactory/contextFactory.tsx new file mode 100644 index 0000000..1f5367f --- /dev/null +++ b/src/lib/contextFactory/contextFactory.tsx @@ -0,0 +1,31 @@ +"use client"; + +import React, { createContext, FC, PropsWithChildren, useContext } from "react"; + +export default function makeContext( + useValue: (args: HookArgs) => State, + displayName?: string +) { + const Context = createContext(undefined); + Context.displayName = displayName ?? "Custom"; + + const Provider: FC> = ({ + children, + ...hookArgs + }) => { + const value = useValue(hookArgs as HookArgs); + return {children}; + }; + + const useContextHook = () => { + const context = useContext(Context); + if (!context) { + throw new Error( + `${Context.displayName}Context must be used within ${Context.displayName}ContextProvider` + ); + } + return context; + }; + + return [Provider, useContextHook] as const; +}