From 0f3bcea322fd5c5df4dc09337da73797aebdaab6 Mon Sep 17 00:00:00 2001 From: mewdev Date: Thu, 9 Jan 2025 14:14:56 +0100 Subject: [PATCH] wip: migrated from mockup counter store to questions store, update components and layout accordingly --- apps/web/app/abc/[currentQuestion]/page.tsx | 37 +++++++----- apps/web/app/abc/components/counter.tsx | 4 +- apps/web/app/abc/layout.tsx | 9 ++- apps/web/app/abc/page.tsx | 36 ------------ .../abc/providers/counterStoreProvider.tsx | 43 -------------- apps/web/app/abc/providers/storeProvider.tsx | 57 +++++++++++++++++++ apps/web/app/abc/store.ts | 21 +------ apps/web/app/abc/utils/urlUpdater.tsx | 4 +- 8 files changed, 90 insertions(+), 121 deletions(-) delete mode 100644 apps/web/app/abc/providers/counterStoreProvider.tsx create mode 100644 apps/web/app/abc/providers/storeProvider.tsx diff --git a/apps/web/app/abc/[currentQuestion]/page.tsx b/apps/web/app/abc/[currentQuestion]/page.tsx index 7a3d53e..01a540d 100644 --- a/apps/web/app/abc/[currentQuestion]/page.tsx +++ b/apps/web/app/abc/[currentQuestion]/page.tsx @@ -1,24 +1,18 @@ "use client"; -import { useCounterStore } from "../providers/counterStoreProvider"; - -type Question = { - id: string; - title: string; - statement: string; - detail: string; - tags: string[]; -}; +import { useQuestionsStore } from "../providers/storeProvider"; export default function Page() { - const questions = useCounterStore((state) => state.questions); - const currentQuestion = useCounterStore((state) => state.currentQuestion); - const prevQuestion = useCounterStore((state) => state.prevQuestion); - const skipQuestion = useCounterStore((state) => state.skipQuestion); + const questions = useQuestionsStore((state) => state.questions); + const collection = useQuestionsStore((state) => state.collection); + const currentQuestion = useQuestionsStore((state) => state.currentQuestion); + const prevQuestion = useQuestionsStore((state) => state.prevQuestion); + const skipQuestion = useQuestionsStore((state) => state.skipQuestion); return ( -
-
+
+
+

Questions

{questions?.map((question: string, index) => { if (currentQuestion === index + 1) { return ( @@ -29,6 +23,19 @@ export default function Page() { } })}
+
+

Collection

+ {collection?.map((item: string, index) => { + if (currentQuestion === index + 1) { + return ( +
+ {item} +
+ ); + } + })} +
+
diff --git a/apps/web/app/abc/components/counter.tsx b/apps/web/app/abc/components/counter.tsx index 1369e1f..45f1ede 100644 --- a/apps/web/app/abc/components/counter.tsx +++ b/apps/web/app/abc/components/counter.tsx @@ -1,9 +1,9 @@ "use client"; -import { useCounterStore } from "../providers/counterStoreProvider"; +import { useQuestionsStore } from "../providers/storeProvider"; export default function Counter() { - const { count, incrementCount, decrementCount } = useCounterStore( + const { count, incrementCount, decrementCount } = useQuestionsStore( (state) => state, ); diff --git a/apps/web/app/abc/layout.tsx b/apps/web/app/abc/layout.tsx index c496ddf..ce58b3a 100644 --- a/apps/web/app/abc/layout.tsx +++ b/apps/web/app/abc/layout.tsx @@ -1,21 +1,24 @@ import "../globals.css"; import "@repo/design-system/styles"; import "@repo/design-system/themes/theme-default"; -import { CounterStoreProvider } from "./providers/counterStoreProvider"; +import { StoreProvider } from "./providers/storeProvider"; import UrlUpdater from "./utils/urlUpdater"; +const collection = ["Collection 1", "Collection 2", "Collection 3"]; + export default async function RootLayout({ children, }: { children: React.ReactNode; }) { + console.log(collection); return ( - + {children} - + ); } diff --git a/apps/web/app/abc/page.tsx b/apps/web/app/abc/page.tsx index 25fc3e6..2048056 100644 --- a/apps/web/app/abc/page.tsx +++ b/apps/web/app/abc/page.tsx @@ -1,42 +1,6 @@ "use client"; -import { useEffect, useState } from "react"; -import { useCounterStore } from "./providers/counterStoreProvider"; - -type Question = { - id: string; - title: string; - statement: string; - detail: string; - tags: string[]; -}; - export default function Page() { - // const [isLoading, setIsLoading] = useState(true); - const questions = useCounterStore((state) => state.questions); - const currentQuestion = useCounterStore((state) => state.currentQuestion); - const prevQuestion = useCounterStore((state) => state.prevQuestion); - const skipQuestion = useCounterStore((state) => state.skipQuestion); - // const [questions, setQuestions] = useState([]); - - // useEffect(() => { - // // make a generic fn - // async function fetchQuestions() { - // const res = await fetch( - // "https://www.volebnikalkulacka.cz/data/instance/volebnikalkulacka.cz/krajske-2024/10-jihomoravsky/questions.json", - // ); - // const data = await res.json(); - // setQuestions(data); - // setIsLoading(false); - // } - // fetchQuestions(); - // }, []); - - // loading ui - // if (isLoading) { - // return

Data is Loading

; - // } - // loaded ui return (
Needs redirect
diff --git a/apps/web/app/abc/providers/counterStoreProvider.tsx b/apps/web/app/abc/providers/counterStoreProvider.tsx deleted file mode 100644 index 948f2dc..0000000 --- a/apps/web/app/abc/providers/counterStoreProvider.tsx +++ /dev/null @@ -1,43 +0,0 @@ -"use client"; - -import { type ReactNode, createContext, useRef, useContext } from "react"; -import { useStore } from "zustand"; - -import { type CounterStore, createCounterStore } from "../store"; - -export type CounterStoreApi = ReturnType; - -export const CounterStoreContext = createContext( - undefined, -); - -export interface CounterStoreProviderProps { - children: ReactNode; -} - -export const CounterStoreProvider = ({ - children, -}: CounterStoreProviderProps) => { - const storeRef = useRef(); - if (!storeRef.current) { - storeRef.current = createCounterStore(); - } - - return ( - - {children} - - ); -}; - -export const useCounterStore = ( - selector: (store: CounterStore) => T, -): T => { - const counterStoreContext = useContext(CounterStoreContext); - - if (!counterStoreContext) { - throw new Error(`useCounterStore must be used within CounterStoreProvider`); - } - - return useStore(counterStoreContext, selector); -}; diff --git a/apps/web/app/abc/providers/storeProvider.tsx b/apps/web/app/abc/providers/storeProvider.tsx new file mode 100644 index 0000000..3dd8f89 --- /dev/null +++ b/apps/web/app/abc/providers/storeProvider.tsx @@ -0,0 +1,57 @@ +"use client"; + +import { type ReactNode, createContext, useRef, useContext } from "react"; +import { type StoreApi, createStore, useStore } from "zustand"; + +type Store = { + count: number; + questions: string[]; + currentQuestion: number; + collection: string[]; + decrementCount: () => void; + incrementCount: () => void; + prevQuestion: () => void; + skipQuestion: () => void; +}; + +export const StoreContext = createContext | undefined>( + undefined, +); + +// update to props with children +export interface StoreProviderProps { + children: ReactNode; + collection: string[]; +} + +export const StoreProvider = ({ children, collection }: StoreProviderProps) => { + const storeRef = useRef | undefined>(); + if (!storeRef.current) { + storeRef.current = createStore((set) => ({ + collection, + count: 1, + questions: ["Item 1", "Item 2", "Item 3"], + currentQuestion: 1, + decrementCount: () => set((state) => ({ count: state.count - 1 })), + incrementCount: () => set((state) => ({ count: state.count + 1 })), + prevQuestion: () => + set((state) => ({ currentQuestion: state.currentQuestion - 1 })), + skipQuestion: () => + set((state) => ({ currentQuestion: state.currentQuestion + 1 })), + })); + } + + return ( + + {children} + + ); +}; + +export function useQuestionsStore(selector: (state: Store) => U): U { + const store = useContext(StoreContext); + if (!store) { + throw new Error("Missing StoreProvider"); + } + return useStore(store, selector); +} diff --git a/apps/web/app/abc/store.ts b/apps/web/app/abc/store.ts index 194e67b..b107dfd 100644 --- a/apps/web/app/abc/store.ts +++ b/apps/web/app/abc/store.ts @@ -4,6 +4,7 @@ export type CounterState = { count: number; questions: string[]; currentQuestion: number; + collection: string[]; }; export type CounterActions = { @@ -14,23 +15,3 @@ export type CounterActions = { }; export type CounterStore = CounterState & CounterActions; - -export const defaultInitState: CounterState = { - count: 0, - questions: ["Item 1", "Item 2", "Item 3"], - currentQuestion: 1, -}; - -export const createCounterStore = ( - initState: CounterState = defaultInitState, -) => { - return createStore()((set) => ({ - ...initState, - decrementCount: () => set((state) => ({ count: state.count - 1 })), - incrementCount: () => set((state) => ({ count: state.count + 1 })), - prevQuestion: () => - set((state) => ({ currentQuestion: state.currentQuestion - 1 })), - skipQuestion: () => - set((state) => ({ currentQuestion: state.currentQuestion + 1 })), - })); -}; diff --git a/apps/web/app/abc/utils/urlUpdater.tsx b/apps/web/app/abc/utils/urlUpdater.tsx index 63a6dc8..cc6e335 100644 --- a/apps/web/app/abc/utils/urlUpdater.tsx +++ b/apps/web/app/abc/utils/urlUpdater.tsx @@ -1,13 +1,13 @@ "use client"; import { useEffect } from "react"; -import { useCounterStore } from "../providers/counterStoreProvider"; +import { useQuestionsStore } from "../providers/storeProvider"; type Props = { children: React.ReactNode; }; export default function UrlUpdater({ children }: Props) { - const currentQuestion = useCounterStore((state) => state.currentQuestion); + const currentQuestion = useQuestionsStore((state) => state.currentQuestion); useEffect(() => { // change url