From 409110a8fa5de81cf5ee338f327e42b56286d102 Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Tue, 8 Aug 2023 18:03:13 +0200 Subject: [PATCH] Refactor StarredContext module structure --- .../(contextStarred)/StarredContext.ts | 7 +++ .../(contextStarred)/StarredContextData.ts | 9 +++ .../(contextStarred)/StarredProvider.tsx | 40 +++++++++++++ .../[lang]/(layout)/(contextStarred)/index.ts | 4 ++ .../(contextStarred)/useStarredConsumer.ts | 16 ++++++ .../app/[lang]/(layout)/StarredManager.tsx | 57 ------------------- .../app/[lang]/(page)/StarredBoardsPanel.tsx | 4 +- .../app/[lang]/board/[board]/BoardHeader.tsx | 4 +- todoblue/src/app/[lang]/layout.tsx | 6 +- 9 files changed, 83 insertions(+), 64 deletions(-) create mode 100644 todoblue/src/app/[lang]/(layout)/(contextStarred)/StarredContext.ts create mode 100644 todoblue/src/app/[lang]/(layout)/(contextStarred)/StarredContextData.ts create mode 100644 todoblue/src/app/[lang]/(layout)/(contextStarred)/StarredProvider.tsx create mode 100644 todoblue/src/app/[lang]/(layout)/(contextStarred)/index.ts create mode 100644 todoblue/src/app/[lang]/(layout)/(contextStarred)/useStarredConsumer.ts delete mode 100644 todoblue/src/app/[lang]/(layout)/StarredManager.tsx diff --git a/todoblue/src/app/[lang]/(layout)/(contextStarred)/StarredContext.ts b/todoblue/src/app/[lang]/(layout)/(contextStarred)/StarredContext.ts new file mode 100644 index 0000000..aa61e8d --- /dev/null +++ b/todoblue/src/app/[lang]/(layout)/(contextStarred)/StarredContext.ts @@ -0,0 +1,7 @@ +"use client"; + +import {StarredContextData} from "@/app/[lang]/(layout)/(contextStarred)/StarredContextData" +import {createContext} from "react" + + +export const StarredContext = createContext(null) diff --git a/todoblue/src/app/[lang]/(layout)/(contextStarred)/StarredContextData.ts b/todoblue/src/app/[lang]/(layout)/(contextStarred)/StarredContextData.ts new file mode 100644 index 0000000..53c4761 --- /dev/null +++ b/todoblue/src/app/[lang]/(layout)/(contextStarred)/StarredContextData.ts @@ -0,0 +1,9 @@ +import {Dispatch, SetStateAction} from "react" + + +export interface StarredContextData { + starred: string[], + setStarred: Dispatch> + addStarred: (key: string) => void, + removeStarred: (key: string) => void, +} diff --git a/todoblue/src/app/[lang]/(layout)/(contextStarred)/StarredProvider.tsx b/todoblue/src/app/[lang]/(layout)/(contextStarred)/StarredProvider.tsx new file mode 100644 index 0000000..a83a1cc --- /dev/null +++ b/todoblue/src/app/[lang]/(layout)/(contextStarred)/StarredProvider.tsx @@ -0,0 +1,40 @@ +"use client"; + +import {StarredContext} from "@/app/[lang]/(layout)/(contextStarred)/StarredContext" +import {ReactNode, useCallback} from "react" +import useLocalStorage from "use-local-storage" + + +export function StarredProvider({children}: {children: ReactNode}) { + const [starred, setStarred] = useLocalStorage("TODOBLUE_STARRED", []) + + const addStarred = useCallback((value: string) => { + setStarred(prev => { + if(!prev) { + return [value] + } + else { + return [...prev, value] + } + }) + }, []) + + const removeStarred = useCallback((value: string) => { + setStarred(prev => { + if(!prev) { + return [] + } + else { + const result = [...prev] + result.splice(result.indexOf(value), 1) + return result + } + }) + }, []) + + return ( + + {children} + + ) +} diff --git a/todoblue/src/app/[lang]/(layout)/(contextStarred)/index.ts b/todoblue/src/app/[lang]/(layout)/(contextStarred)/index.ts new file mode 100644 index 0000000..7a72fa6 --- /dev/null +++ b/todoblue/src/app/[lang]/(layout)/(contextStarred)/index.ts @@ -0,0 +1,4 @@ +export {StarredProvider} from "./StarredProvider" +export {useStarredConsumer} from "./useStarredConsumer" + +export type {StarredContextData} from "./StarredContextData" diff --git a/todoblue/src/app/[lang]/(layout)/(contextStarred)/useStarredConsumer.ts b/todoblue/src/app/[lang]/(layout)/(contextStarred)/useStarredConsumer.ts new file mode 100644 index 0000000..5315bfa --- /dev/null +++ b/todoblue/src/app/[lang]/(layout)/(contextStarred)/useStarredConsumer.ts @@ -0,0 +1,16 @@ +"use client"; + +import {StarredContext} from "@/app/[lang]/(layout)/(contextStarred)/StarredContext" +import {StarredContextData} from "@/app/[lang]/(layout)/(contextStarred)/StarredContextData" +import {useContext} from "react" + + +export function useStarredConsumer(): StarredContextData { + const context = useContext(StarredContext) + + if(context === null) { + throw new Error("useStarContext used outside a StarredContext.") + } + + return context +} diff --git a/todoblue/src/app/[lang]/(layout)/StarredManager.tsx b/todoblue/src/app/[lang]/(layout)/StarredManager.tsx deleted file mode 100644 index 84f114b..0000000 --- a/todoblue/src/app/[lang]/(layout)/StarredManager.tsx +++ /dev/null @@ -1,57 +0,0 @@ -"use client"; - -import {createContext, Dispatch, ReactNode, SetStateAction, useCallback, useContext} from "react" -import useLocalStorage from "use-local-storage" - -export interface StarContextData { - starred: string[], - setStarred: Dispatch> - addStarred: (key: string) => void, - removeStarred: (key: string) => void, -} - -const StarContext = createContext(null) - -export function StarredManager({children}: {children: ReactNode}) { - const [starred, setStarred] = useLocalStorage("TODOBLUE_STARRED", []) - - const addStarred = useCallback((value: string) => { - setStarred(prev => { - if(!prev) { - return [value] - } - else { - return [...prev, value] - } - }) - }, []) - - const removeStarred = useCallback((value: string) => { - setStarred(prev => { - if(!prev) { - return [] - } - else { - const result = [...prev] - result.splice(result.indexOf(value), 1) - return result - } - }) - }, []) - - return ( - - {children} - - ) -} - -export function useManagedStarred(): StarContextData { - const context = useContext(StarContext) - - if(context === null) { - throw new Error("useStarContext used outside a StarContext.") - } - - return context -} diff --git a/todoblue/src/app/[lang]/(page)/StarredBoardsPanel.tsx b/todoblue/src/app/[lang]/(page)/StarredBoardsPanel.tsx index a65df6b..0506751 100644 --- a/todoblue/src/app/[lang]/(page)/StarredBoardsPanel.tsx +++ b/todoblue/src/app/[lang]/(page)/StarredBoardsPanel.tsx @@ -1,7 +1,7 @@ "use client"; import {useClientTranslation} from "@/app/(i18n)/client" -import {useManagedStarred} from "@/app/[lang]/(layout)/StarredManager" +import {useStarredConsumer} from "@/app/[lang]/(layout)/(contextStarred)/StarredProvider" import {faStar} from "@fortawesome/free-solid-svg-icons" import {FontAwesomeIcon} from "@fortawesome/react-fontawesome" import cn from "classnames" @@ -12,7 +12,7 @@ import {useEffect, useState} from "react" export function StarredBoardsPanel({lng}: {lng: string}) { const {t} = useClientTranslation(lng, "root") const [isClient, setIsClient] = useState(null); - const {starred} = useManagedStarred() + const {starred} = useStarredConsumer() useEffect(() => setIsClient(true), []) diff --git a/todoblue/src/app/[lang]/board/[board]/BoardHeader.tsx b/todoblue/src/app/[lang]/board/[board]/BoardHeader.tsx index 9c9407d..4bfdba0 100644 --- a/todoblue/src/app/[lang]/board/[board]/BoardHeader.tsx +++ b/todoblue/src/app/[lang]/board/[board]/BoardHeader.tsx @@ -1,4 +1,4 @@ -import {useManagedStarred} from "@/app/[lang]/(layout)/StarredManager" +import {useStarredConsumer} from "../../(layout)/(contextStarred)" import {useRouter} from "next/navigation" import {ReactNode, useCallback} from "react" import style from "./BoardHeader.module.css" @@ -98,7 +98,7 @@ function HomeButton() { function StarButton() { const {name} = useManagedBoard() - const {starred, addStarred, removeStarred} = useManagedStarred() + const {starred, addStarred, removeStarred} = useStarredConsumer() const isStarred = starred.indexOf(name) >= 0 const toggleStarred = useCallback(() => isStarred ? removeStarred(name) : addStarred(name), [name, isStarred, addStarred, removeStarred]) diff --git a/todoblue/src/app/[lang]/layout.tsx b/todoblue/src/app/[lang]/layout.tsx index 23411e4..afe4a4e 100644 --- a/todoblue/src/app/[lang]/layout.tsx +++ b/todoblue/src/app/[lang]/layout.tsx @@ -2,7 +2,7 @@ import "./layout.css"; import {Body} from "@/app/[lang]/(layout)/Body" -import {StarredManager} from "@/app/[lang]/(layout)/StarredManager" +import {StarredProvider} from "@/app/[lang]/(layout)/(contextStarred)/StarredProvider" import type {Metadata as NextMetadata} from "next" import {default as React, ReactNode} from "react" @@ -25,9 +25,9 @@ export default function layout({children}: { children: ReactNode }) { return ( - + {children} - + )