aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web/app
diff options
context:
space:
mode:
Diffstat (limited to 'apps/web/app')
-rw-r--r--apps/web/app/admin/layout.tsx63
-rw-r--r--apps/web/app/dashboard/layout.tsx89
-rw-r--r--apps/web/app/settings/layout.tsx86
3 files changed, 170 insertions, 68 deletions
diff --git a/apps/web/app/admin/layout.tsx b/apps/web/app/admin/layout.tsx
index 0d876736..7b20b7ad 100644
--- a/apps/web/app/admin/layout.tsx
+++ b/apps/web/app/admin/layout.tsx
@@ -1,11 +1,41 @@
import { redirect } from "next/navigation";
import { AdminCard } from "@/components/admin/AdminCard";
import { AdminNotices } from "@/components/admin/AdminNotices";
-import MobileAdminSidebar from "@/components/admin/sidebar/MobileSidebar";
-import AdminSidebar from "@/components/admin/sidebar/Sidebar";
-import Header from "@/components/dashboard/header/Header";
-import { Separator } from "@/components/ui/separator";
+import MobileSidebar from "@/components/shared/sidebar/MobileSidebar";
+import Sidebar from "@/components/shared/sidebar/Sidebar";
+import SidebarLayout from "@/components/shared/sidebar/SidebarLayout";
import { getServerAuthSession } from "@/server/auth";
+import { TFunction } from "i18next";
+import { Activity, ArrowLeft, Settings, Users } from "lucide-react";
+
+const adminSidebarItems = (
+ t: TFunction,
+): {
+ name: string;
+ icon: JSX.Element;
+ path: string;
+}[] => [
+ {
+ name: t("settings.back_to_app"),
+ icon: <ArrowLeft size={18} />,
+ path: "/dashboard/bookmarks",
+ },
+ {
+ name: t("admin.server_stats.server_stats"),
+ icon: <Activity size={18} />,
+ path: "/admin/overview",
+ },
+ {
+ name: t("admin.users_list.users_list"),
+ icon: <Users size={18} />,
+ path: "/admin/users",
+ },
+ {
+ name: t("common.actions"),
+ icon: <Settings size={18} />,
+ path: "/admin/actions",
+ },
+];
export default async function AdminLayout({
children,
@@ -18,23 +48,14 @@ export default async function AdminLayout({
}
return (
- <div>
- <Header />
- <div className="flex min-h-[calc(100vh-64px)] w-screen flex-col sm:h-[calc(100vh-64px)] sm:flex-row">
- <div className="hidden flex-none sm:flex">
- <AdminSidebar />
- </div>
- <main className="flex-1 bg-muted sm:overflow-y-auto">
- <div className="block w-full sm:hidden">
- <MobileAdminSidebar />
- <Separator />
- </div>
- <div className="min-h-30 container flex flex-col gap-1 p-4">
- <AdminNotices />
- <AdminCard>{children}</AdminCard>
- </div>
- </main>
+ <SidebarLayout
+ sidebar={<Sidebar items={adminSidebarItems} />}
+ mobileSidebar={<MobileSidebar items={adminSidebarItems} />}
+ >
+ <div className="flex flex-col gap-1">
+ <AdminNotices />
+ <AdminCard>{children}</AdminCard>
</div>
- </div>
+ </SidebarLayout>
);
}
diff --git a/apps/web/app/dashboard/layout.tsx b/apps/web/app/dashboard/layout.tsx
index cbd51245..17a7c144 100644
--- a/apps/web/app/dashboard/layout.tsx
+++ b/apps/web/app/dashboard/layout.tsx
@@ -1,9 +1,13 @@
-import Header from "@/components/dashboard/header/Header";
-import MobileSidebar from "@/components/dashboard/sidebar/ModileSidebar";
-import Sidebar from "@/components/dashboard/sidebar/Sidebar";
-import DemoModeBanner from "@/components/DemoModeBanner";
+import { redirect } from "next/navigation";
+import AllLists from "@/components/dashboard/sidebar/AllLists";
+import MobileSidebar from "@/components/shared/sidebar/MobileSidebar";
+import Sidebar from "@/components/shared/sidebar/Sidebar";
+import SidebarLayout from "@/components/shared/sidebar/SidebarLayout";
import { Separator } from "@/components/ui/separator";
-import ValidAccountCheck from "@/components/utils/ValidAccountCheck";
+import { api } from "@/server/api/client";
+import { getServerAuthSession } from "@/server/auth";
+import { TFunction } from "i18next";
+import { Archive, Highlighter, Home, Search, Tag } from "lucide-react";
import serverConfig from "@hoarder/shared/config";
@@ -14,24 +18,63 @@ export default async function Dashboard({
children: React.ReactNode;
modal: React.ReactNode;
}>) {
+ const session = await getServerAuthSession();
+ if (!session) {
+ redirect("/");
+ }
+
+ const lists = await api.lists.list();
+
+ const items = (t: TFunction) =>
+ [
+ {
+ name: t("common.home"),
+ icon: <Home size={18} />,
+ path: "/dashboard/bookmarks",
+ },
+ serverConfig.meilisearch
+ ? [
+ {
+ name: t("common.search"),
+ icon: <Search size={18} />,
+ path: "/dashboard/search",
+ },
+ ]
+ : [],
+ {
+ name: t("common.tags"),
+ icon: <Tag size={18} />,
+ path: "/dashboard/tags",
+ },
+ {
+ name: t("common.highlights"),
+ icon: <Highlighter size={18} />,
+ path: "/dashboard/highlights",
+ },
+ {
+ name: t("common.archive"),
+ icon: <Archive size={18} />,
+ path: "/dashboard/archive",
+ },
+ ].flat();
+
return (
- <div>
- <Header />
- <div className="flex min-h-[calc(100vh-64px)] w-screen flex-col sm:h-[calc(100vh-64px)] sm:flex-row">
- <ValidAccountCheck />
- <div className="hidden flex-none sm:flex">
- <Sidebar />
- </div>
- <main className="flex-1 bg-muted sm:overflow-y-auto">
- {serverConfig.demoMode && <DemoModeBanner />}
- <div className="block w-full sm:hidden">
- <MobileSidebar />
- <Separator />
- </div>
- {modal}
- <div className="min-h-30 container p-4">{children}</div>
- </main>
- </div>
- </div>
+ <SidebarLayout
+ sidebar={
+ <Sidebar
+ items={items}
+ extraSections={
+ <>
+ <Separator />
+ <AllLists initialData={lists} />
+ </>
+ }
+ />
+ }
+ mobileSidebar={<MobileSidebar items={items} />}
+ modal={modal}
+ >
+ {children}
+ </SidebarLayout>
);
}
diff --git a/apps/web/app/settings/layout.tsx b/apps/web/app/settings/layout.tsx
index 0ab6c624..bbff68a9 100644
--- a/apps/web/app/settings/layout.tsx
+++ b/apps/web/app/settings/layout.tsx
@@ -1,11 +1,60 @@
-import Header from "@/components/dashboard/header/Header";
-import DemoModeBanner from "@/components/DemoModeBanner";
-import MobileSidebar from "@/components/settings/sidebar/ModileSidebar";
-import Sidebar from "@/components/settings/sidebar/Sidebar";
-import { Separator } from "@/components/ui/separator";
-import ValidAccountCheck from "@/components/utils/ValidAccountCheck";
+import MobileSidebar from "@/components/shared/sidebar/MobileSidebar";
+import Sidebar from "@/components/shared/sidebar/Sidebar";
+import SidebarLayout from "@/components/shared/sidebar/SidebarLayout";
+import { TFunction } from "i18next";
+import {
+ ArrowLeft,
+ Download,
+ KeyRound,
+ Link,
+ Rss,
+ Sparkles,
+ User,
+} from "lucide-react";
-import serverConfig from "@hoarder/shared/config";
+const settingsSidebarItems = (
+ t: TFunction,
+): {
+ name: string;
+ icon: JSX.Element;
+ path: string;
+}[] => [
+ {
+ name: t("settings.back_to_app"),
+ icon: <ArrowLeft size={18} />,
+ path: "/dashboard/bookmarks",
+ },
+ {
+ name: t("settings.info.user_info"),
+ icon: <User size={18} />,
+ path: "/settings/info",
+ },
+ {
+ name: t("settings.ai.ai_settings"),
+ icon: <Sparkles size={18} />,
+ path: "/settings/ai",
+ },
+ {
+ name: t("settings.feeds.rss_subscriptions"),
+ icon: <Rss size={18} />,
+ path: "/settings/feeds",
+ },
+ {
+ name: t("settings.import.import_export"),
+ icon: <Download size={18} />,
+ path: "/settings/import",
+ },
+ {
+ name: t("settings.api_keys.api_keys"),
+ icon: <KeyRound size={18} />,
+ path: "/settings/api-keys",
+ },
+ {
+ name: t("settings.broken_links.broken_links"),
+ icon: <Link size={18} />,
+ path: "/settings/broken-links",
+ },
+];
export default async function SettingsLayout({
children,
@@ -13,22 +62,11 @@ export default async function SettingsLayout({
children: React.ReactNode;
}>) {
return (
- <div>
- <Header />
- <div className="flex min-h-[calc(100vh-64px)] w-screen flex-col sm:h-[calc(100vh-64px)] sm:flex-row">
- <ValidAccountCheck />
- <div className="hidden flex-none sm:flex">
- <Sidebar />
- </div>
- <main className="flex-1 bg-muted sm:overflow-y-auto">
- {serverConfig.demoMode && <DemoModeBanner />}
- <div className="block w-full sm:hidden">
- <MobileSidebar />
- <Separator />
- </div>
- <div className="min-h-30 container p-4">{children}</div>
- </main>
- </div>
- </div>
+ <SidebarLayout
+ sidebar={<Sidebar items={settingsSidebarItems} />}
+ mobileSidebar={<MobileSidebar items={settingsSidebarItems} />}
+ >
+ {children}
+ </SidebarLayout>
);
}