Add dynamic breadcrumbs to Header via React Context
Replace hardcoded "Coffee Project / Projects" with a BreadcrumbsContext that each page registers into via useBreadcrumbs(). The Header reads breadcrumb items dynamically, renders links for items with href, and makes "Coffee Project" clickable to open the navigation drawer. Also removes the unused currentScreenName from Redux appState. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import { Provider as ReduxProvider } from "react-redux"
|
||||
|
||||
import { store } from "@shared/store"
|
||||
|
||||
import { BreadcrumbsProvider } from "./BreadcrumbsContext"
|
||||
import { QueryClientProvider } from "./QueryClientProvider"
|
||||
import { UserSync } from "./UserSync"
|
||||
|
||||
@@ -19,9 +20,11 @@ export const AppProviders = ({
|
||||
<ReduxProvider store={store}>
|
||||
<QueryClientProvider>
|
||||
<UserSync />
|
||||
<Theme accentColor="violet" grayColor="slate" radius="medium">
|
||||
{children}
|
||||
</Theme>
|
||||
<BreadcrumbsProvider>
|
||||
<Theme accentColor="iris" grayColor="slate" radius="medium" scaling="100%">
|
||||
{children}
|
||||
</Theme>
|
||||
</BreadcrumbsProvider>
|
||||
</QueryClientProvider>
|
||||
</ReduxProvider>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
"use client"
|
||||
|
||||
import {
|
||||
createContext,
|
||||
type JSX,
|
||||
type ReactNode,
|
||||
useContext,
|
||||
useEffect,
|
||||
useState,
|
||||
} from "react"
|
||||
|
||||
export interface BreadcrumbItem {
|
||||
label: string
|
||||
href?: string
|
||||
}
|
||||
|
||||
interface BreadcrumbsContextValue {
|
||||
items: BreadcrumbItem[]
|
||||
setItems: (items: BreadcrumbItem[]) => void
|
||||
}
|
||||
|
||||
const BreadcrumbsContext = createContext<BreadcrumbsContextValue>({
|
||||
items: [],
|
||||
setItems: () => {},
|
||||
})
|
||||
|
||||
export const BreadcrumbsProvider = ({
|
||||
children,
|
||||
}: {
|
||||
children: ReactNode
|
||||
}): JSX.Element => {
|
||||
const [items, setItems] = useState<BreadcrumbItem[]>([])
|
||||
|
||||
return (
|
||||
<BreadcrumbsContext.Provider value={{ items, setItems }}>
|
||||
{children}
|
||||
</BreadcrumbsContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useBreadcrumbs = (items: BreadcrumbItem[]): void => {
|
||||
const { setItems } = useContext(BreadcrumbsContext)
|
||||
|
||||
useEffect(() => {
|
||||
setItems(items)
|
||||
return () => setItems([])
|
||||
}, [JSON.stringify(items)])
|
||||
}
|
||||
|
||||
export const useBreadcrumbItems = (): BreadcrumbItem[] => {
|
||||
return useContext(BreadcrumbsContext).items
|
||||
}
|
||||
@@ -1,25 +1,18 @@
|
||||
import type { PayloadAction } from "@reduxjs/toolkit"
|
||||
|
||||
import { createSlice } from "@reduxjs/toolkit"
|
||||
|
||||
import { AppState } from "./types"
|
||||
|
||||
const initialState: AppState = {
|
||||
currentScreenName: "",
|
||||
}
|
||||
const initialState: AppState = {}
|
||||
|
||||
const appStateSlice = createSlice({
|
||||
name: "appState",
|
||||
initialState,
|
||||
reducers: {
|
||||
setCurrentScreenName(state, action: PayloadAction<string>) {
|
||||
state.currentScreenName = action.payload
|
||||
},
|
||||
resetAppState(state) {
|
||||
state.currentScreenName = initialState.currentScreenName
|
||||
resetAppState() {
|
||||
return initialState
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export const { resetAppState, setCurrentScreenName } = appStateSlice.actions
|
||||
export const { resetAppState } = appStateSlice.actions
|
||||
export const appStateReducer = appStateSlice.reducer
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
export interface AppState {
|
||||
currentScreenName: string
|
||||
}
|
||||
export interface AppState {}
|
||||
|
||||
Reference in New Issue
Block a user