diff --git a/frontend/components/sidebar/app-sidebar.tsx b/frontend/components/sidebar/app-sidebar.tsx index 5faacd1..c1a38cd 100644 --- a/frontend/components/sidebar/app-sidebar.tsx +++ b/frontend/components/sidebar/app-sidebar.tsx @@ -1,6 +1,7 @@ "use client"; import * as React from "react"; +import { useEffect, useState } from "react"; import { AudioWaveform, BookOpen, @@ -12,146 +13,85 @@ import { PieChart, Settings2, SquareTerminal, + User, } from "lucide-react"; import { NavMain } from "./nav-main"; -import { NavProjects } from "./nav-projects"; import { NavUser } from "./nav-user"; import { TeamSwitcher } from "./team-switcher"; import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader, SidebarRail } from "@/components/ui/sidebar"; -import { useEffect } from "react"; +import { NavCrops } from "./nav-crops"; import { fetchUserMe } from "@/api/user"; -const data = { - user: { - name: "shadcn", - email: "m@example.com", - avatar: "/avatars/avatar.webp", - }, - teams: [ - { - name: "Farm 1", - logo: GalleryVerticalEnd, - plan: "Hatyai", - }, - { - name: "Farm 2", - logo: AudioWaveform, - plan: "Songkla", - }, - { - name: "Farm 3", - logo: Command, - plan: "Layong", - }, - ], - navMain: [ - { - title: "Dashboard", - url: "#", - icon: SquareTerminal, - isActive: true, - items: [ - { - title: "Analytic", - url: "#", - }, - ], - }, - { - title: "AI Chatbot", - url: "#", - icon: Bot, - items: [ - { - title: "Main model", - url: "#", - }, - ], - }, - { - title: "Documentation", - url: "#", - icon: BookOpen, - items: [ - { - title: "Introduction", - url: "#", - }, - { - title: "Get Started", - url: "#", - }, - { - title: "Tutorials", - url: "#", - }, - { - title: "Changelog", - url: "#", - }, - ], - }, - { - title: "Settings", - url: "#", - icon: Settings2, - items: [ - { - title: "General", - url: "#", - }, - { - title: "Team", - url: "#", - }, - { - title: "Billing", - url: "#", - }, - { - title: "Limits", - url: "#", - }, - ], - }, - ], - projects: [ - { - name: "Crops 1", - url: "#", - icon: Frame, - }, - { - name: "Crops 2", - url: "#", - icon: PieChart, - }, - { - name: "Crops 3", - url: "#", - icon: Map, - }, - ], -}; +interface Team { + name: string; + logo: React.ComponentType; + plan: string; +} -export function AppSidebar({ ...props }: React.ComponentProps) { - const [user, setUser] = React.useState<{ name: string; email: string; avatar: string }>({ +import { LucideIcon } from "lucide-react"; + +interface NavItem { + title: string; + url: string; + icon: LucideIcon; +} + +interface SidebarConfig { + teams: Team[]; + navMain: NavItem[]; + crops: NavItem[]; +} + +interface AppSidebarProps extends React.ComponentProps { + config?: SidebarConfig; +} + +export function AppSidebar({ config, ...props }: AppSidebarProps) { + const defaultConfig: SidebarConfig = { + teams: [ + { name: "Farm 1", logo: GalleryVerticalEnd, plan: "Hatyai" }, + { name: "Farm 2", logo: AudioWaveform, plan: "Songkla" }, + { name: "Farm 3", logo: Command, plan: "Layong" }, + ], + navMain: [ + { title: "Farms", url: "/farms", icon: Map }, + { title: "Crops list", url: "/crops", icon: Frame }, + { title: "Inventory", url: "/inventory", icon: SquareTerminal }, + { title: "Marketplace Information", url: "/marketplace", icon: PieChart }, + { title: "Knowledge Hub", url: "/knowledge", icon: BookOpen }, + { title: "Users", url: "/users", icon: User }, + { title: "AI Chatbot", url: "/chatbot", icon: Bot }, + { title: "Settings", url: "/settings", icon: Settings2 }, + ], + // Define crops with dynamic URLs – replace [farmId] with your actual farm identifier as needed. + crops: [ + { title: "Crops 1", url: "/farms/[farmId]/crops/1", icon: Map }, + { title: "Crops 2", url: "/farms/[farmId]/crops/2", icon: Map }, + { title: "Crops 3", url: "/farms/[farmId]/crops/3", icon: Map }, + ], + }; + + // Allow external configuration override + const sidebarConfig = config || defaultConfig; + + const [user, setUser] = useState<{ name: string; email: string; avatar: string }>({ name: "", email: "", avatar: "/avatars/avatar.webp", }); - const [loading, setLoading] = React.useState(true); - const [error, setError] = React.useState(""); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(""); useEffect(() => { async function getUser() { try { const data = await fetchUserMe(); - let to_set = user; - to_set.name = data.user.UUID; - to_set.email = data.user.Email; - setUser(to_set); + setUser({ + name: data.user.UUID, + email: data.user.Email, + avatar: data.user.Avatar || "/avatars/avatar.webp", + }); } catch (err: any) { setError(err.message); } finally { @@ -164,11 +104,13 @@ export function AppSidebar({ ...props }: React.ComponentProps) { return ( - + - - + +
+ +
{loading ? "Loading..." : error ? error : } diff --git a/frontend/components/sidebar/nav-crops.tsx b/frontend/components/sidebar/nav-crops.tsx new file mode 100644 index 0000000..5bd9442 --- /dev/null +++ b/frontend/components/sidebar/nav-crops.tsx @@ -0,0 +1,41 @@ +"use client"; + +import { LucideIcon } from "lucide-react"; +import { + SidebarGroup, + SidebarGroupLabel, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, +} from "@/components/ui/sidebar"; + +interface CropItem { + title: string; + url: string; + icon: LucideIcon; +} + +interface NavCropsProps { + crops: CropItem[]; + title?: string; +} + +export function NavCrops({ crops, title = "Crops" }: NavCropsProps) { + return ( + + {title} + + {crops.map((crop) => ( + + + + + {crop.title} + + + + ))} + + + ); +} diff --git a/frontend/components/sidebar/nav-projects.tsx b/frontend/components/sidebar/nav-projects.tsx deleted file mode 100644 index 921c0d3..0000000 --- a/frontend/components/sidebar/nav-projects.tsx +++ /dev/null @@ -1,82 +0,0 @@ -"use client"; - -import { Folder, Forward, MoreHorizontal, Trash2, type LucideIcon } from "lucide-react"; - -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; -import { - SidebarGroup, - SidebarGroupLabel, - SidebarMenu, - SidebarMenuAction, - SidebarMenuButton, - SidebarMenuItem, - useSidebar, -} from "@/components/ui/sidebar"; - -export function NavProjects({ - projects, -}: { - projects: { - name: string; - url: string; - icon: LucideIcon; - }[]; -}) { - const { isMobile } = useSidebar(); - - return ( - - Projects - - {projects.map((item) => ( - - - - - {item.name} - - - - - - - More - - - - - - View Project - - - - Share Project - - - - - Delete Project - - - - - ))} - - - - More - - - - - ); -}