diff --git a/app/client/components/app-breadcrumb.tsx b/app/client/components/app-breadcrumb.tsx index 6f602f62..d419708a 100644 --- a/app/client/components/app-breadcrumb.tsx +++ b/app/client/components/app-breadcrumb.tsx @@ -1,4 +1,4 @@ -import { Link, useMatches, type UIMatch } from "react-router"; +import { useMatches, Link } from "@tanstack/react-router"; import { Breadcrumb, BreadcrumbItem, @@ -13,25 +13,22 @@ export interface BreadcrumbItemData { href?: string; } -interface RouteHandle { - breadcrumb?: (match: UIMatch) => BreadcrumbItemData[] | null; -} +type BreadcrumbFunction = (match: ReturnType[number]) => BreadcrumbItemData[] | null; export function AppBreadcrumb() { const matches = useMatches(); - // Find the last match with a breadcrumb handler const lastMatchWithBreadcrumb = [...matches].reverse().find((match) => { - const handle = match.handle as RouteHandle | undefined; - return handle?.breadcrumb; + const breadcrumbFn = match.staticData?.breadcrumb as BreadcrumbFunction | undefined; + return breadcrumbFn; }); if (!lastMatchWithBreadcrumb) { return null; } - const handle = lastMatchWithBreadcrumb.handle as RouteHandle; - const breadcrumbs = handle.breadcrumb?.(lastMatchWithBreadcrumb); + const breadcrumbFn = lastMatchWithBreadcrumb.staticData?.breadcrumb as BreadcrumbFunction; + const breadcrumbs = breadcrumbFn?.(lastMatchWithBreadcrumb); if (!breadcrumbs || breadcrumbs.length === 0) { return null; diff --git a/app/client/components/layout.tsx b/app/client/components/layout.tsx index 8a0551db..e0ee8a14 100644 --- a/app/client/components/layout.tsx +++ b/app/client/components/layout.tsx @@ -8,6 +8,7 @@ import { AppSidebar } from "./app-sidebar"; import { authClient } from "../lib/auth-client"; import { DevPanelListener } from "./dev-panel-listener"; import { Outlet, useNavigate } from "@tanstack/react-router"; +import { AppBreadcrumb } from "./app-breadcrumb"; type Props = { loaderData: AppContext; @@ -37,7 +38,7 @@ export function Layout({ loaderData }: Props) {
- {/* */} +
{loaderData.user && (
diff --git a/app/client/modules/backups/routes/backup-details.tsx b/app/client/modules/backups/routes/backup-details.tsx index bdbb1bd6..e5bd557d 100644 --- a/app/client/modules/backups/routes/backup-details.tsx +++ b/app/client/modules/backups/routes/backup-details.tsx @@ -40,12 +40,6 @@ import type { } from "~/client/lib/types"; import { useNavigate } from "@tanstack/react-router"; -// export const handle = { -// breadcrumb: (match: Route.MetaArgs) => { -// const data = match.loaderData; -// return [{ label: "Backups", href: "/backups" }, { label: data.schedule.name }]; -// }, -// }; type Props = { loaderData: { schedule: BackupSchedule; diff --git a/app/client/modules/backups/routes/backups.tsx b/app/client/modules/backups/routes/backups.tsx index 48bf7feb..8e26597b 100644 --- a/app/client/modules/backups/routes/backups.tsx +++ b/app/client/modules/backups/routes/backups.tsx @@ -23,10 +23,6 @@ import { SortableCard } from "~/client/components/sortable-card"; import { BackupCard } from "../components/backup-card"; import { Link } from "@tanstack/react-router"; -export const handle = { - breadcrumb: () => [{ label: "Backups" }], -}; - export const clientLoader = async () => { const jobs = await listBackupSchedules(); if (jobs.data) return jobs.data; diff --git a/app/client/modules/backups/routes/create-backup.tsx b/app/client/modules/backups/routes/create-backup.tsx index ecd5364c..8b205d37 100644 --- a/app/client/modules/backups/routes/create-backup.tsx +++ b/app/client/modules/backups/routes/create-backup.tsx @@ -16,10 +16,6 @@ import { getCronExpression } from "~/utils/utils"; import { CreateScheduleForm, type BackupScheduleFormValues } from "../components/create-schedule-form"; import { Link, useNavigate } from "@tanstack/react-router"; -// export const handle = { -// breadcrumb: () => [{ label: "Backups", href: "/backups" }, { label: "Create" }], -// }; - export function CreateBackupPage() { const navigate = useNavigate(); const formId = useId(); diff --git a/app/client/modules/notifications/routes/create-notification.tsx b/app/client/modules/notifications/routes/create-notification.tsx index b70b8281..a84b7488 100644 --- a/app/client/modules/notifications/routes/create-notification.tsx +++ b/app/client/modules/notifications/routes/create-notification.tsx @@ -10,10 +10,6 @@ import { Alert, AlertDescription } from "~/client/components/ui/alert"; import { CreateNotificationForm, type NotificationFormValues } from "../components/create-notification-form"; import { useNavigate } from "@tanstack/react-router"; -export const handle = { - breadcrumb: () => [{ label: "Notifications", href: "/notifications" }, { label: "Create" }], -}; - export function CreateNotificationPage() { const navigate = useNavigate(); const formId = useId(); diff --git a/app/client/modules/notifications/routes/notification-details.tsx b/app/client/modules/notifications/routes/notification-details.tsx index 3be93971..150694f7 100644 --- a/app/client/modules/notifications/routes/notification-details.tsx +++ b/app/client/modules/notifications/routes/notification-details.tsx @@ -26,13 +26,6 @@ import { Alert, AlertDescription } from "~/client/components/ui/alert"; import { CreateNotificationForm, type NotificationFormValues } from "../components/create-notification-form"; import { useNavigate } from "@tanstack/react-router"; -// export const handle = { -// breadcrumb: (match: Route.MetaArgs) => [ -// { label: "Notifications", href: "/notifications" }, -// { label: match.params.id }, -// ], -// }; - export function NotificationDetailsPage({ notificationId }: { notificationId: string }) { const navigate = useNavigate(); const formId = useId(); diff --git a/app/client/modules/notifications/routes/notifications.tsx b/app/client/modules/notifications/routes/notifications.tsx index 94824195..03f9c19c 100644 --- a/app/client/modules/notifications/routes/notifications.tsx +++ b/app/client/modules/notifications/routes/notifications.tsx @@ -11,10 +11,6 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "~ import { listNotificationDestinationsOptions } from "~/client/api-client/@tanstack/react-query.gen"; import { useNavigate } from "@tanstack/react-router"; -export const handle = { - breadcrumb: () => [{ label: "Notifications" }], -}; - export function NotificationsPage() { const [searchQuery, setSearchQuery] = useState(""); const [typeFilter, setTypeFilter] = useState(""); diff --git a/app/client/modules/repositories/routes/create-repository.tsx b/app/client/modules/repositories/routes/create-repository.tsx index 85ed1429..db450a63 100644 --- a/app/client/modules/repositories/routes/create-repository.tsx +++ b/app/client/modules/repositories/routes/create-repository.tsx @@ -13,10 +13,6 @@ import { parseError } from "~/client/lib/errors"; import { Alert, AlertDescription } from "~/client/components/ui/alert"; import { useNavigate } from "@tanstack/react-router"; -export const handle = { - breadcrumb: () => [{ label: "Repositories", href: "/repositories" }, { label: "Create" }], -}; - export function CreateRepositoryPage() { const navigate = useNavigate(); const formId = useId(); diff --git a/app/client/modules/repositories/routes/repositories.tsx b/app/client/modules/repositories/routes/repositories.tsx index 49a323d2..22927c4d 100644 --- a/app/client/modules/repositories/routes/repositories.tsx +++ b/app/client/modules/repositories/routes/repositories.tsx @@ -12,10 +12,6 @@ import { cn } from "~/client/lib/utils"; import { EmptyState } from "~/client/components/empty-state"; import { useNavigate } from "@tanstack/react-router"; -export const handle = { - breadcrumb: () => [{ label: "Repositories" }], -}; - export function RepositoriesPage() { const [searchQuery, setSearchQuery] = useState(""); const [statusFilter, setStatusFilter] = useState(""); diff --git a/app/client/modules/repositories/routes/repository-details.tsx b/app/client/modules/repositories/routes/repository-details.tsx index 5d691a31..b7e14f2d 100644 --- a/app/client/modules/repositories/routes/repository-details.tsx +++ b/app/client/modules/repositories/routes/repository-details.tsx @@ -6,13 +6,6 @@ import { RepositoryInfoTabContent } from "../tabs/info"; import { RepositorySnapshotsTabContent } from "../tabs/snapshots"; import { useNavigate, useSearch } from "@tanstack/react-router"; -// export const handle = { -// breadcrumb: (match: Route.MetaArgs) => [ -// { label: "Repositories", href: "/repositories" }, -// { label: match.loaderData?.name || match.params.id }, -// ], -// }; - export default function RepositoryDetailsPage({ repositoryId }: { repositoryId: string }) { const queryClient = useQueryClient(); diff --git a/app/client/modules/repositories/routes/restore-snapshot.tsx b/app/client/modules/repositories/routes/restore-snapshot.tsx index 2351c04c..8bad0ec0 100644 --- a/app/client/modules/repositories/routes/restore-snapshot.tsx +++ b/app/client/modules/repositories/routes/restore-snapshot.tsx @@ -1,15 +1,6 @@ import { RestoreForm } from "~/client/components/restore-form"; import type { Repository, Snapshot } from "~/client/lib/types"; -// export const handle = { -// breadcrumb: (match: Route.MetaArgs) => [ -// { label: "Repositories", href: "/repositories" }, -// { label: match.loaderData?.repository.name || match.params.id, href: `/repositories/${match.params.id}` }, -// { label: match.params.snapshotId, href: `/repositories/${match.params.id}/${match.params.snapshotId}` }, -// { label: "Restore" }, -// ], -// }; - type Props = { snapshot: Snapshot; repository: Repository; diff --git a/app/client/modules/repositories/routes/snapshot-details.tsx b/app/client/modules/repositories/routes/snapshot-details.tsx index 28721f16..2da8b140 100644 --- a/app/client/modules/repositories/routes/snapshot-details.tsx +++ b/app/client/modules/repositories/routes/snapshot-details.tsx @@ -12,14 +12,6 @@ import { useState } from "react"; import { Database } from "lucide-react"; import { Link, useParams } from "@tanstack/react-router"; -// export const handle = { -// breadcrumb: (match: Route.MetaArgs) => [ -// { label: "Repositories", href: "/repositories" }, -// { label: match.loaderData?.repository.name || match.params.id, href: `/repositories/${match.params.id}` }, -// { label: match.params.snapshotId }, -// ], -// }; - export const SnapshotError = () => { const { repoId } = useParams({ from: "/(dashboard)/repositories/$repoId/$snapshotId" }); diff --git a/app/client/modules/settings/routes/settings.tsx b/app/client/modules/settings/routes/settings.tsx index 5109a746..85f272fb 100644 --- a/app/client/modules/settings/routes/settings.tsx +++ b/app/client/modules/settings/routes/settings.tsx @@ -28,10 +28,6 @@ import { TwoFactorSection } from "../components/two-factor-section"; import { UserManagement } from "../components/user-management"; import { useNavigate, useSearch } from "@tanstack/react-router"; -export const handle = { - breadcrumb: () => [{ label: "Settings" }], -}; - type Props = { appContext: AppContext; }; diff --git a/app/client/modules/volumes/routes/create-volume.tsx b/app/client/modules/volumes/routes/create-volume.tsx index be98f491..a6bb98c2 100644 --- a/app/client/modules/volumes/routes/create-volume.tsx +++ b/app/client/modules/volumes/routes/create-volume.tsx @@ -10,10 +10,6 @@ import { parseError } from "~/client/lib/errors"; import { Alert, AlertDescription } from "~/client/components/ui/alert"; import { useNavigate } from "@tanstack/react-router"; -export const handle = { - breadcrumb: () => [{ label: "Volumes", href: "/volumes" }, { label: "Create" }], -}; - export function CreateVolumePage() { const navigate = useNavigate(); const formId = useId(); diff --git a/app/client/modules/volumes/routes/volume-details.tsx b/app/client/modules/volumes/routes/volume-details.tsx index 4d4f1527..d703086e 100644 --- a/app/client/modules/volumes/routes/volume-details.tsx +++ b/app/client/modules/volumes/routes/volume-details.tsx @@ -31,10 +31,6 @@ import { } from "~/client/api-client/@tanstack/react-query.gen"; import { useNavigate } from "@tanstack/react-router"; -export const handle = { - breadcrumb: (match: Route.MetaArgs) => [{ label: "Volumes", href: "/volumes" }, { label: match.params.id }], -}; - const getVolumeStatusVariant = (status: VolumeStatus): "success" | "neutral" | "error" | "warning" => { const statusMap = { mounted: "success" as const, diff --git a/app/client/modules/volumes/routes/volumes.tsx b/app/client/modules/volumes/routes/volumes.tsx index 87aaf2e5..e6a6aeef 100644 --- a/app/client/modules/volumes/routes/volumes.tsx +++ b/app/client/modules/volumes/routes/volumes.tsx @@ -23,10 +23,6 @@ const getVolumeStatusVariant = (status: VolumeStatus): "success" | "neutral" | " return statusMap[status]; }; -export const handle = { - breadcrumb: () => [{ label: "Volumes" }], -}; - export function VolumesPage() { const [searchQuery, setSearchQuery] = useState(""); const [statusFilter, setStatusFilter] = useState(""); diff --git a/app/client/routes/root.tsx b/app/client/routes/root.tsx deleted file mode 100644 index 8e9b4486..00000000 --- a/app/client/routes/root.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { redirect } from "react-router"; - -export const clientLoader = async () => { - return redirect("/volumes"); -}; - -export const loader = async () => { - return redirect("/volumes"); -}; diff --git a/app/context.ts b/app/context.ts index ac56c242..6e5f4be4 100644 --- a/app/context.ts +++ b/app/context.ts @@ -1,5 +1,3 @@ -import { createContext } from "react-router"; - type User = { id: string; email: string; @@ -13,8 +11,3 @@ export type AppContext = { user: User | null; hasUsers: boolean; }; - -export const appContext = createContext({ - user: null, - hasUsers: false, -}); diff --git a/app/root.tsx b/app/root.tsx deleted file mode 100644 index 2bb3ac81..00000000 --- a/app/root.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { MutationCache, QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration } from "react-router"; - -import type { Route } from "./+types/root"; -import "./app.css"; -import { Toaster } from "./client/components/ui/sonner"; -import { useServerEvents } from "./client/hooks/use-server-events"; -import { client } from "./client/api-client/client.gen"; - -client.setConfig({ - baseUrl: "/", -}); - -export const links: Route.LinksFunction = () => [ - { rel: "preconnect", href: "https://fonts.googleapis.com" }, - { - rel: "preconnect", - href: "https://fonts.gstatic.com", - crossOrigin: "anonymous", - }, - { - rel: "stylesheet", - href: "https://fonts.googleapis.com/css2?family=Google+Sans+Code:ital,wght@0,300..800;1,300..800&display=swap", - }, -]; - -const queryClient = new QueryClient({ - mutationCache: new MutationCache({ - onSuccess: () => { - void queryClient.invalidateQueries(); - }, - onError: (error) => { - console.error("Mutation error:", error); - void queryClient.invalidateQueries(); - }, - }), -}); - -export function Layout({ children }: { children: React.ReactNode }) { - return ( - - - - - - - - - - - - - - - - {children} - - - - - - - ); -} - -export default function App() { - useServerEvents(); - - return ; -} - -export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) { - let message = "Oops!"; - let details = "An unexpected error occurred."; - let stack: string | undefined; - - if (isRouteErrorResponse(error)) { - message = error.status === 404 ? "404" : "Error"; - details = error.status === 404 ? "The requested page could not be found." : error.statusText || details; - } else if (import.meta.env.DEV && error && error instanceof Error) { - details = error.message; - stack = error.stack; - } - - return ( -
-

{message}

-

{details}

- {stack && ( -
-					{stack}
-				
- )} -
- ); -} diff --git a/app/router.tsx b/app/router.tsx index 73d11cf6..6a18beb2 100644 --- a/app/router.tsx +++ b/app/router.tsx @@ -3,6 +3,7 @@ import { setupRouterSsrQueryIntegration } from "@tanstack/react-router-ssr-query import { routeTree } from "./routeTree.gen"; import { MutationCache, QueryClient } from "@tanstack/react-query"; import { client } from "./client/api-client/client.gen"; +import type { BreadcrumbItemData } from "./client/components/app-breadcrumb"; client.setConfig({ baseUrl: "/", @@ -45,4 +46,7 @@ declare module "@tanstack/react-router" { interface Register { router: ReturnType; } + interface StaticDataRouteOption { + breadcrumb?: (match: any) => BreadcrumbItemData[] | null; + } } diff --git a/app/routes/(dashboard)/backups/$backupId.$snapshotId.restore.tsx b/app/routes/(dashboard)/backups/$backupId.$snapshotId.restore.tsx index ac0f3b60..126c5791 100644 --- a/app/routes/(dashboard)/backups/$backupId.$snapshotId.restore.tsx +++ b/app/routes/(dashboard)/backups/$backupId.$snapshotId.restore.tsx @@ -19,7 +19,15 @@ export const Route = createFileRoute("/(dashboard)/backups/$backupId/$snapshotId context.queryClient.ensureQueryData({ ...getRepositoryOptions({ path: { id: schedule.data?.repositoryId } }) }), ]); - return { snapshot, repository }; + return { snapshot, repository, schedule: schedule.data }; + }, + staticData: { + breadcrumb: (match) => [ + { label: "Backup Jobs", href: "/backups" }, + { label: match.loaderData?.schedule?.name || "Job", href: `/backups/${match.params.backupId}` }, + { label: match.params.snapshotId }, + { label: "Restore" }, + ], }, }); diff --git a/app/routes/(dashboard)/backups/$scheduleId.tsx b/app/routes/(dashboard)/backups/$scheduleId.tsx index 0edbcfd3..0ffb6d76 100644 --- a/app/routes/(dashboard)/backups/$scheduleId.tsx +++ b/app/routes/(dashboard)/backups/$scheduleId.tsx @@ -28,6 +28,12 @@ export const Route = createFileRoute("/(dashboard)/backups/$scheduleId")({ return { schedule, notifs, repos, scheduleNotifs, mirrors }; }, + staticData: { + breadcrumb: (match) => [ + { label: "Backup Jobs", href: "/backups" }, + { label: match.loaderData?.schedule.name || "Job Details" }, + ], + }, head: ({ loaderData }) => ({ meta: [ { title: `Zerobyte - ${loaderData?.schedule.name || "Backup Job Details"}` }, diff --git a/app/routes/(dashboard)/backups/create.tsx b/app/routes/(dashboard)/backups/create.tsx index d6c3281d..6a540871 100644 --- a/app/routes/(dashboard)/backups/create.tsx +++ b/app/routes/(dashboard)/backups/create.tsx @@ -9,6 +9,12 @@ export const Route = createFileRoute("/(dashboard)/backups/create")({ context.queryClient.ensureQueryData({ ...listRepositoriesOptions() }), ]); }, + staticData: { + breadcrumb: () => [ + { label: "Backup Jobs", href: "/backups" }, + { label: "Create" }, + ], + }, component: RouteComponent, }); diff --git a/app/routes/(dashboard)/backups/index.tsx b/app/routes/(dashboard)/backups/index.tsx index 0f9a502d..c4cba64a 100644 --- a/app/routes/(dashboard)/backups/index.tsx +++ b/app/routes/(dashboard)/backups/index.tsx @@ -9,6 +9,9 @@ export const Route = createFileRoute("/(dashboard)/backups/")({ ...listBackupSchedulesOptions(), }); }, + staticData: { + breadcrumb: () => [{ label: "Backup Jobs" }], + }, head: () => ({ meta: [ { title: "Zerobyte - Backup Jobs" }, diff --git a/app/routes/(dashboard)/notifications/$notificationId.tsx b/app/routes/(dashboard)/notifications/$notificationId.tsx index f1d5c685..91f34911 100644 --- a/app/routes/(dashboard)/notifications/$notificationId.tsx +++ b/app/routes/(dashboard)/notifications/$notificationId.tsx @@ -11,6 +11,12 @@ export const Route = createFileRoute("/(dashboard)/notifications/$notificationId return res; }, + staticData: { + breadcrumb: (match) => [ + { label: "Notifications", href: "/notifications" }, + { label: match.loaderData?.name || "Notification Details" }, + ], + }, head: ({ loaderData }) => ({ meta: [ { title: `Zerobyte - ${loaderData?.name}` }, diff --git a/app/routes/(dashboard)/notifications/create.tsx b/app/routes/(dashboard)/notifications/create.tsx index d7169551..b69b0800 100644 --- a/app/routes/(dashboard)/notifications/create.tsx +++ b/app/routes/(dashboard)/notifications/create.tsx @@ -3,6 +3,12 @@ import { CreateNotificationPage } from "~/client/modules/notifications/routes/cr export const Route = createFileRoute("/(dashboard)/notifications/create")({ component: RouteComponent, + staticData: { + breadcrumb: () => [ + { label: "Notifications", href: "/notifications" }, + { label: "Create" }, + ], + }, head: () => ({ meta: [ { title: "Zerobyte - Create Notification" }, diff --git a/app/routes/(dashboard)/notifications/index.tsx b/app/routes/(dashboard)/notifications/index.tsx index b4e20c08..2761f22d 100644 --- a/app/routes/(dashboard)/notifications/index.tsx +++ b/app/routes/(dashboard)/notifications/index.tsx @@ -7,6 +7,9 @@ export const Route = createFileRoute("/(dashboard)/notifications/")({ loader: async ({ context }) => { await context.queryClient.ensureQueryData({ ...listNotificationDestinationsOptions() }); }, + staticData: { + breadcrumb: () => [{ label: "Notifications" }], + }, head: () => ({ meta: [ { title: "Zerobyte - Notifications" }, diff --git a/app/routes/(dashboard)/repositories/$repoId.$snapId.restore.tsx b/app/routes/(dashboard)/repositories/$repoId.$snapId.restore.tsx index c3d18e8a..702c7267 100644 --- a/app/routes/(dashboard)/repositories/$repoId.$snapId.restore.tsx +++ b/app/routes/(dashboard)/repositories/$repoId.$snapId.restore.tsx @@ -15,6 +15,14 @@ export const Route = createFileRoute("/(dashboard)/repositories/$repoId/$snapId/ return { snapshot, repository }; }, + staticData: { + breadcrumb: (match) => [ + { label: "Repositories", href: "/repositories" }, + { label: match.loaderData?.repository?.name || "Repository", href: `/repositories/${match.params.repoId}` }, + { label: match.params.snapId, href: `/repositories/${match.params.repoId}/${match.params.snapId}` }, + { label: "Restore" }, + ], + }, head: ({ params }) => ({ meta: [ { title: `Zerobyte - Restore Snapshot ${params.snapId}` }, diff --git a/app/routes/(dashboard)/repositories/$repoId.$snapshotId.tsx b/app/routes/(dashboard)/repositories/$repoId.$snapshotId.tsx index 21542f24..77dbd620 100644 --- a/app/routes/(dashboard)/repositories/$repoId.$snapshotId.tsx +++ b/app/routes/(dashboard)/repositories/$repoId.$snapshotId.tsx @@ -10,7 +10,7 @@ export const Route = createFileRoute("/(dashboard)/repositories/$repoId/$snapsho component: RouteComponent, errorComponent: (e) =>
{e.error.message}
, loader: async ({ params, context }) => { - await context.queryClient.ensureQueryData({ + const res = await context.queryClient.ensureQueryData({ ...getRepositoryOptions({ path: { id: params.repoId } }), }); @@ -25,6 +25,15 @@ export const Route = createFileRoute("/(dashboard)/repositories/$repoId/$snapsho query: { path: "/" }, }), }); + + return res; + }, + staticData: { + breadcrumb: (match) => [ + { label: "Repositories", href: "/repositories" }, + { label: match.loaderData?.name || "Repository", href: `/repositories/${match.params.repoId}` }, + { label: match.params.snapshotId }, + ], }, head: ({ params }) => ({ meta: [ diff --git a/app/routes/(dashboard)/repositories/$repositoryId.tsx b/app/routes/(dashboard)/repositories/$repositoryId.tsx index 93dc8450..50a6a606 100644 --- a/app/routes/(dashboard)/repositories/$repositoryId.tsx +++ b/app/routes/(dashboard)/repositories/$repositoryId.tsx @@ -25,6 +25,12 @@ export const Route = createFileRoute("/(dashboard)/repositories/$repositoryId")( return res; }, validateSearch: type({ tab: "string?" }), + staticData: { + breadcrumb: (match) => [ + { label: "Repositories", href: "/repositories" }, + { label: match.loaderData?.name || "Repository Details" }, + ], + }, head: ({ loaderData }) => ({ meta: [ { title: `Zerobyte - ${loaderData?.name}` }, diff --git a/app/routes/(dashboard)/repositories/create.tsx b/app/routes/(dashboard)/repositories/create.tsx index 619ad0bc..32d88460 100644 --- a/app/routes/(dashboard)/repositories/create.tsx +++ b/app/routes/(dashboard)/repositories/create.tsx @@ -3,6 +3,12 @@ import { CreateRepositoryPage } from "~/client/modules/repositories/routes/creat export const Route = createFileRoute("/(dashboard)/repositories/create")({ component: RouteComponent, + staticData: { + breadcrumb: () => [ + { label: "Repositories", href: "/repositories" }, + { label: "Create" }, + ], + }, head: () => ({ meta: [ { title: "Zerobyte - Create Repository" }, diff --git a/app/routes/(dashboard)/repositories/index.tsx b/app/routes/(dashboard)/repositories/index.tsx index f78591f5..1aa94679 100644 --- a/app/routes/(dashboard)/repositories/index.tsx +++ b/app/routes/(dashboard)/repositories/index.tsx @@ -10,6 +10,9 @@ export const Route = createFileRoute("/(dashboard)/repositories/")({ }); }, errorComponent: (e) =>
{e.error.message}
, + staticData: { + breadcrumb: () => [{ label: "Repositories" }], + }, head: () => ({ meta: [ { title: "Zerobyte - Repositories" }, diff --git a/app/routes/(dashboard)/settings/index.tsx b/app/routes/(dashboard)/settings/index.tsx index d2284fae..b76fc716 100644 --- a/app/routes/(dashboard)/settings/index.tsx +++ b/app/routes/(dashboard)/settings/index.tsx @@ -11,6 +11,9 @@ export const Route = createFileRoute("/(dashboard)/settings/")({ const authContext = await fetchUser(); return authContext as AppContext; }, + staticData: { + breadcrumb: () => [{ label: "Settings" }], + }, }); function RouteComponent() { diff --git a/app/routes/(dashboard)/volumes/$volumeId.tsx b/app/routes/(dashboard)/volumes/$volumeId.tsx index 7e97269e..85444649 100644 --- a/app/routes/(dashboard)/volumes/$volumeId.tsx +++ b/app/routes/(dashboard)/volumes/$volumeId.tsx @@ -14,6 +14,12 @@ export const Route = createFileRoute("/(dashboard)/volumes/$volumeId")({ return res; }, validateSearch: type({ tab: "string?" }), + staticData: { + breadcrumb: (match) => [ + { label: "Volumes", href: "/volumes" }, + { label: match.loaderData?.volume.name || "Volume Details" }, + ], + }, head: ({ loaderData }) => ({ meta: [ { title: `Zerobyte - ${loaderData?.volume.name}` }, diff --git a/app/routes/(dashboard)/volumes/create.tsx b/app/routes/(dashboard)/volumes/create.tsx index bf703647..80f58942 100644 --- a/app/routes/(dashboard)/volumes/create.tsx +++ b/app/routes/(dashboard)/volumes/create.tsx @@ -3,6 +3,9 @@ import { CreateVolumePage } from "~/client/modules/volumes/routes/create-volume" export const Route = createFileRoute("/(dashboard)/volumes/create")({ component: RouteComponent, + staticData: { + breadcrumb: () => [{ label: "Volumes", href: "/volumes" }, { label: "Create" }], + }, head: () => ({ meta: [ { title: "Zerobyte - Create Volume" }, diff --git a/app/routes/(dashboard)/volumes/index.tsx b/app/routes/(dashboard)/volumes/index.tsx index 5fb24041..9066c9a3 100644 --- a/app/routes/(dashboard)/volumes/index.tsx +++ b/app/routes/(dashboard)/volumes/index.tsx @@ -8,6 +8,9 @@ export const Route = createFileRoute("/(dashboard)/volumes/")({ loader: async ({ context }) => { await context.queryClient.ensureQueryData(listVolumesOptions()); }, + staticData: { + breadcrumb: () => [{ label: "Volumes" }], + }, head: () => ({ meta: [ { title: "Zerobyte - Volumes" },