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:
@@ -1,12 +1,21 @@
|
||||
"use client"
|
||||
|
||||
import type { components } from "@shared/api/__generated__/openapi.types"
|
||||
import type { JSX } from "react"
|
||||
|
||||
import { PlusIcon } from "lucide-react"
|
||||
import { FunctionComponent, useState } from "react"
|
||||
|
||||
import { useRouter } from "next/navigation"
|
||||
|
||||
import { ProjectCard } from "@entities/ProjectCard"
|
||||
import { CreateProjectModal } from "@features/CreateProjectModal"
|
||||
import { useBreadcrumbs } from "@shared/context/BreadcrumbsContext"
|
||||
import {
|
||||
CreateProjectModal,
|
||||
DeleteProjectModal,
|
||||
EditProjectModal,
|
||||
RenameProjectModal,
|
||||
} from "@features/project"
|
||||
import api from "@shared/api"
|
||||
import { Button } from "@shared/ui"
|
||||
import { StaticLoader } from "@shared/ui/Loader"
|
||||
@@ -14,13 +23,18 @@ import { ProjectsHeader } from "@widgets/Projects/ProjectsHeader"
|
||||
|
||||
import { IProjectsPageProps } from "./ProjectsPage.d"
|
||||
import styles from "./ProjectsPage.module.scss"
|
||||
import { useRouter } from "next/navigation"
|
||||
|
||||
type ProjectRead = components["schemas"]["ProjectRead"]
|
||||
|
||||
export const ProjectsPage: FunctionComponent<
|
||||
IProjectsPageProps
|
||||
> = (): JSX.Element => {
|
||||
const router = useRouter();
|
||||
useBreadcrumbs([{ label: "Projects", href: "/projects" }])
|
||||
const router = useRouter()
|
||||
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false)
|
||||
const [editProject, setEditProject] = useState<ProjectRead | null>(null)
|
||||
const [renameProject, setRenameProject] = useState<ProjectRead | null>(null)
|
||||
const [deleteProject, setDeleteProject] = useState<ProjectRead | null>(null)
|
||||
|
||||
const {
|
||||
data: projects,
|
||||
@@ -57,6 +71,45 @@ export const ProjectsPage: FunctionComponent<
|
||||
}}
|
||||
/>
|
||||
|
||||
{editProject && (
|
||||
<EditProjectModal
|
||||
open
|
||||
onOpenChange={(open) => {
|
||||
if (!open) setEditProject(null)
|
||||
}}
|
||||
project={editProject}
|
||||
onUpdated={async () => {
|
||||
await refetchProjects()
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{renameProject && (
|
||||
<RenameProjectModal
|
||||
open
|
||||
onOpenChange={(open) => {
|
||||
if (!open) setRenameProject(null)
|
||||
}}
|
||||
project={renameProject}
|
||||
onRenamed={async () => {
|
||||
await refetchProjects()
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{deleteProject && (
|
||||
<DeleteProjectModal
|
||||
open
|
||||
onOpenChange={(open) => {
|
||||
if (!open) setDeleteProject(null)
|
||||
}}
|
||||
project={deleteProject}
|
||||
onDeleted={async () => {
|
||||
await refetchProjects()
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<ProjectsHeader />
|
||||
|
||||
<div className={styles.projectList}>
|
||||
@@ -64,12 +117,14 @@ export const ProjectsPage: FunctionComponent<
|
||||
<ProjectCard
|
||||
key={project.id}
|
||||
project={project}
|
||||
// Mock random progress for demo since API doesn't provide it yet
|
||||
progress={project.status === "PROCESSING" ? 45 : 0}
|
||||
currentAction={
|
||||
project.status === "PROCESSING" ? "Rendering" : undefined
|
||||
}
|
||||
onClick={() => router.push(`/projects/${project.id}`)}
|
||||
onEdit={() => setEditProject(project)}
|
||||
onRename={() => setRenameProject(project)}
|
||||
onDelete={() => setDeleteProject(project)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user