);
-}
+}
\ No newline at end of file
diff --git a/apps/web/src/components/layout/main-layout.tsx b/apps/web/src/components/layout/main-layout.tsx
index c4cfb03..6ec3a1e 100644
--- a/apps/web/src/components/layout/main-layout.tsx
+++ b/apps/web/src/components/layout/main-layout.tsx
@@ -1,17 +1,60 @@
-import { ReactNode } from "react";
-import { Navbar } from "./navbar";
+import { ReactNode, useState } from "react";
import { Footer } from "./footer";
+import { Sidebar } from "./sidebar";
+import { MobileNav } from "./mobile-nav";
+import { Leaf, Menu } from "lucide-react";
type Props = { children: ReactNode };
export function MainLayout({ children }: Props) {
+ const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
+
return (
-
-
-
- {children}
-
-
+
+ {/* Sidebar Desktop */}
+
+
+ {/* Main Content */}
+
+ {/* Header Mobile */}
+
+
+
+
+
+
+
ZeaVis Edu
+
+ Smart AI for Corn Disease Detection
+
+
+
+
+
+
+
+ {/* Mobile Navigation */}
+
setMobileMenuOpen(false)}
+ />
+
+ {/* Page Content */}
+
+
+ {children}
+
+
+
+ {/* Footer */}
+
+
);
}
diff --git a/apps/web/src/components/layout/mobile-nav.tsx b/apps/web/src/components/layout/mobile-nav.tsx
index 4262154..504d402 100644
--- a/apps/web/src/components/layout/mobile-nav.tsx
+++ b/apps/web/src/components/layout/mobile-nav.tsx
@@ -1,47 +1,55 @@
import { createPortal } from "react-dom";
import { Link, useLocation } from "react-router-dom";
-import { X, Leaf } from "lucide-react";
+import {
+ X,
+ Leaf,
+ LogOut,
+ LayoutDashboard,
+ Scan,
+ Activity,
+ BookOpen,
+ UserCheck,
+ ChartBar,
+} from "lucide-react";
type Props = {
open: boolean;
onClose: () => void;
};
+// Daftar menu disamakan persis dengan sidebar.tsx
const NAV_ITEMS = [
- { path: "/dashboard", label: "Dashboard" },
- { path: "/scan", label: "Scan Tanaman" },
- { path: "/diagnoses", label: "Diagnosa" },
- { path: "/catalog", label: "Pustaka", altPath: "/library" },
- { path: "/expert/reviews", label: "Review" },
- { path: "/telemetry", label: "Telemetry" },
+ { path: "/dashboard", label: "Dashboard", icon: LayoutDashboard },
+ { path: "/scan", label: "Scan Daun", icon: Scan },
+ { path: "/diagnoses", label: "Diagnosa", icon: Activity },
+ { path: "/catalog", label: "Pustaka", icon: BookOpen, altPath: "/library" },
+ { path: "/expert/reviews", label: "Tinjauan Pakar", icon: UserCheck },
+ { path: "/telemetry", label: "Telemetry", icon: ChartBar },
];
export function MobileNav({ open, onClose }: Props) {
const location = useLocation();
-
const isActive = (path: string) => location.pathname === path;
const navContent = (
{/* Backdrop */}
- {/* Panel */}
+ {/* Menu */}
- {/* Header */}
+ {/* Header Menu Mobile */}
@@ -50,42 +58,57 @@ export function MobileNav({ open, onClose }: Props) {
-
ZeaVis Edu
-
+
ZeaVis Edu
+
Smart AI for Corn Disease Detection
- {/* Nav items */}
-
);
diff --git a/apps/web/src/components/layout/navbar.tsx b/apps/web/src/components/layout/navbar.tsx
deleted file mode 100644
index 26e1db1..0000000
--- a/apps/web/src/components/layout/navbar.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import { useState } from "react";
-import { Link, useLocation } from "react-router-dom";
-import { Leaf, Menu } from "lucide-react";
-import { MobileNav } from "./mobile-nav";
-
-export function Navbar() {
- const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
- const location = useLocation();
- //
-
- const isActive = (path: string) => location.pathname === path;
-
- const navLinkClassName = (active: boolean) =>
- [
- "inline-flex items-center rounded-full px-4 py-2 text-[16px] font-medium transition-colors",
- active
- ? "bg-[#48A111] text-white shadow-sm"
- : "text-white/85 hover:bg-white/10 hover:text-white",
- ].join(" ");
-
- return (
-
-
-
-
-
-
-
-
-
-
ZeaVis Edu
-
- Smart AI for Corn Disease Detection
-
-
-
-
-
-
- Dashboard
-
-
- Scan Tanaman
-
-
- Diagnosa
-
-
- Pustaka
-
-
- Review
-
-
- Telemetry
-
-
-
-
-
-
setMobileMenuOpen(false)}
- />
-
-
- );
-}
diff --git a/apps/web/src/components/layout/sidebar.tsx b/apps/web/src/components/layout/sidebar.tsx
new file mode 100644
index 0000000..0a53a54
--- /dev/null
+++ b/apps/web/src/components/layout/sidebar.tsx
@@ -0,0 +1,139 @@
+import { useState } from "react";
+import { Link, useLocation } from "react-router-dom";
+import {
+ Leaf,
+ LogOut,
+ Menu,
+ ChevronLeft,
+ LayoutDashboard,
+ Scan,
+ Activity,
+ BookOpen,
+ UserCheck,
+ ChartBar,
+} from "lucide-react";
+import { MobileNav } from "./mobile-nav";
+
+const NAV_ITEMS = [
+ { path: "/dashboard", label: "Dashboard", icon: LayoutDashboard },
+ { path: "/scan", label: "Pindai Daun", icon: Scan },
+ { path: "/diagnoses", label: "Diagnosa", icon: Activity },
+ { path: "/catalog", label: "Pustaka", icon: BookOpen, altPath: "/library" },
+ { path: "/expert/reviews", label: "Tinjauan Pakar", icon: UserCheck },
+ { path: "/telemetry", label: "Telemetry", icon: ChartBar },
+];
+
+export function Sidebar() {
+ const location = useLocation();
+ const [isSidebarOpen, setIsSidebarOpen] = useState(true);
+ const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
+
+ const isActive = (path: string, altPath?: string) => {
+ if (path === "/dashboard" || path === "/scan") {
+ return location.pathname === path;
+ }
+ return (
+ location.pathname.startsWith(path) ||
+ (altPath && location.pathname.startsWith(altPath))
+ );
+ };
+
+ return (
+
+ );
+}