267 lines
8.3 KiB
TypeScript
267 lines
8.3 KiB
TypeScript
![]() |
"use client"
|
||
|
import Link from "next/link"
|
||
|
import { usePathname } from "next/navigation"
|
||
|
import {
|
||
|
BarChart3,
|
||
|
FileText,
|
||
|
Home,
|
||
|
LightbulbIcon,
|
||
|
LogOut,
|
||
|
MessageSquare,
|
||
|
Settings,
|
||
|
User,
|
||
|
VoteIcon,
|
||
|
Info,
|
||
|
ExternalLink,
|
||
|
History,
|
||
|
Bell,
|
||
|
Twitter,
|
||
|
Github,
|
||
|
Linkedin,
|
||
|
ClipboardList,
|
||
|
ShieldCheck,
|
||
|
ShieldAlert,
|
||
|
} from "lucide-react"
|
||
|
import {
|
||
|
Sidebar,
|
||
|
SidebarContent,
|
||
|
SidebarFooter,
|
||
|
SidebarGroup,
|
||
|
SidebarGroupContent,
|
||
|
SidebarGroupLabel,
|
||
|
SidebarHeader,
|
||
|
SidebarMenu,
|
||
|
SidebarMenuButton,
|
||
|
SidebarMenuItem,
|
||
|
SidebarSeparator,
|
||
|
SidebarTrigger,
|
||
|
} from "@/components/ui/sidebar"
|
||
|
import { Avatar, AvatarFallback } from "@/components/ui/avatar"
|
||
|
import { ConnectWalletButton } from "@/components/connect-wallet-button"
|
||
|
import { useWalletStore } from "@/lib/wallet-store"
|
||
|
import {
|
||
|
DropdownMenu,
|
||
|
DropdownMenuContent,
|
||
|
DropdownMenuItem,
|
||
|
DropdownMenuLabel,
|
||
|
DropdownMenuSeparator,
|
||
|
DropdownMenuTrigger,
|
||
|
} from "@/components/ui/dropdown-menu"
|
||
|
import { Button } from "@/components/ui/button"
|
||
|
|
||
|
export function AppSidebar() {
|
||
|
const pathname = usePathname()
|
||
|
const { walletConnected, walletAddress, username, isVerified, disconnectWallet } = useWalletStore()
|
||
|
|
||
|
const isActive = (path: string) => {
|
||
|
if (path === '/') {
|
||
|
return pathname === path
|
||
|
}
|
||
|
return pathname?.startsWith(path)
|
||
|
}
|
||
|
|
||
|
const mainNavItems = [
|
||
|
{
|
||
|
title: "Home",
|
||
|
icon: Home,
|
||
|
href: "/",
|
||
|
},
|
||
|
{
|
||
|
title: "Issues",
|
||
|
icon: ClipboardList,
|
||
|
href: "/issues",
|
||
|
},
|
||
|
{
|
||
|
title: "Submit Perspective",
|
||
|
icon: MessageSquare,
|
||
|
href: "/submit",
|
||
|
},
|
||
|
{
|
||
|
title: "Insights Dashboard",
|
||
|
icon: LightbulbIcon,
|
||
|
href: "/insights",
|
||
|
},
|
||
|
{
|
||
|
title: "Contributions",
|
||
|
icon: VoteIcon,
|
||
|
href: "/contributions",
|
||
|
},
|
||
|
{
|
||
|
title: "Resolutions",
|
||
|
icon: FileText,
|
||
|
href: "/resolutions",
|
||
|
},
|
||
|
{
|
||
|
title: "About",
|
||
|
icon: Info,
|
||
|
href: "/about",
|
||
|
},
|
||
|
]
|
||
|
|
||
|
const userNavItems = [
|
||
|
{
|
||
|
title: "Profile",
|
||
|
icon: User,
|
||
|
href: "/profile",
|
||
|
},
|
||
|
{
|
||
|
title: "Settings",
|
||
|
icon: Settings,
|
||
|
href: "/settings",
|
||
|
},
|
||
|
]
|
||
|
|
||
|
return (
|
||
|
<Sidebar variant="inset">
|
||
|
<SidebarHeader className="flex flex-col gap-2 p-4">
|
||
|
<div className="flex items-center gap-2">
|
||
|
<Link href="/" className="flex items-center gap-2">
|
||
|
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-primary text-primary-foreground">
|
||
|
<BarChart3 className="h-4 w-4" />
|
||
|
</div>
|
||
|
<span className="text-lg font-bold">VoxPop</span>
|
||
|
</Link>
|
||
|
<SidebarTrigger className="ml-auto" />
|
||
|
</div>
|
||
|
<div className="mt-2">
|
||
|
{walletConnected ? (
|
||
|
<div className="rounded-md border p-3">
|
||
|
<div className="flex items-center gap-2">
|
||
|
<Avatar className="h-8 w-8">
|
||
|
<AvatarFallback>{username?.[0] || "V"}</AvatarFallback>
|
||
|
</Avatar>
|
||
|
<div className="flex flex-col overflow-hidden">
|
||
|
<div className="flex items-center gap-1">
|
||
|
<span className="truncate font-medium">{username || "VoxPop User"}</span>
|
||
|
{isVerified ? (
|
||
|
<ShieldCheck className="h-4 w-4 text-green-500" title="Verified User" />
|
||
|
) : (
|
||
|
<ShieldAlert className="h-4 w-4 text-amber-500" title="Unverified User" />
|
||
|
)}
|
||
|
</div>
|
||
|
<span className="truncate text-xs text-muted-foreground">{walletAddress}</span>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div className="mt-1">
|
||
|
<Link
|
||
|
href="/settings"
|
||
|
className="text-xs text-primary hover:underline inline-flex items-center"
|
||
|
>
|
||
|
{isVerified ?
|
||
|
"Verified User (Full Access)" :
|
||
|
"Unverified User (Limited Access)"
|
||
|
}
|
||
|
<Settings className="ml-1 h-3 w-3" />
|
||
|
</Link>
|
||
|
</div>
|
||
|
|
||
|
<div className="mt-3 flex flex-wrap gap-2">
|
||
|
<Button variant="outline" size="sm" className="h-7 w-7 p-0" asChild>
|
||
|
<Link href="/profile/social">
|
||
|
<Twitter className="h-3.5 w-3.5" />
|
||
|
<span className="sr-only">Twitter</span>
|
||
|
</Link>
|
||
|
</Button>
|
||
|
<Button variant="outline" size="sm" className="h-7 w-7 p-0" asChild>
|
||
|
<Link href="/profile/social">
|
||
|
<Github className="h-3.5 w-3.5" />
|
||
|
<span className="sr-only">Github</span>
|
||
|
</Link>
|
||
|
</Button>
|
||
|
<Button variant="outline" size="sm" className="h-7 w-7 p-0" asChild>
|
||
|
<Link href="/profile/social">
|
||
|
<Linkedin className="h-3.5 w-3.5" />
|
||
|
<span className="sr-only">LinkedIn</span>
|
||
|
</Link>
|
||
|
</Button>
|
||
|
<DropdownMenu>
|
||
|
<DropdownMenuTrigger asChild>
|
||
|
<Button variant="outline" size="sm" className="ml-auto h-7">
|
||
|
<span className="sr-only">More options</span>
|
||
|
<ExternalLink className="h-3.5 w-3.5" />
|
||
|
</Button>
|
||
|
</DropdownMenuTrigger>
|
||
|
<DropdownMenuContent align="end">
|
||
|
<DropdownMenuLabel>Account</DropdownMenuLabel>
|
||
|
<DropdownMenuItem asChild>
|
||
|
<Link href="/profile/transactions">
|
||
|
<History className="mr-2 h-4 w-4" />
|
||
|
Transaction History
|
||
|
</Link>
|
||
|
</DropdownMenuItem>
|
||
|
<DropdownMenuItem asChild>
|
||
|
<Link href="/profile/notifications">
|
||
|
<Bell className="mr-2 h-4 w-4" />
|
||
|
Notifications
|
||
|
</Link>
|
||
|
</DropdownMenuItem>
|
||
|
<DropdownMenuSeparator />
|
||
|
<DropdownMenuItem onClick={disconnectWallet} className="text-destructive focus:text-destructive">
|
||
|
<LogOut className="mr-2 h-4 w-4" />
|
||
|
Disconnect
|
||
|
</DropdownMenuItem>
|
||
|
</DropdownMenuContent>
|
||
|
</DropdownMenu>
|
||
|
</div>
|
||
|
</div>
|
||
|
) : (
|
||
|
<ConnectWalletButton />
|
||
|
)}
|
||
|
</div>
|
||
|
</SidebarHeader>
|
||
|
<SidebarSeparator />
|
||
|
<SidebarContent>
|
||
|
<SidebarGroup>
|
||
|
<SidebarGroupLabel>Navigation</SidebarGroupLabel>
|
||
|
<SidebarGroupContent>
|
||
|
<SidebarMenu>
|
||
|
{mainNavItems.map((item) => (
|
||
|
<SidebarMenuItem key={item.href}>
|
||
|
<SidebarMenuButton asChild isActive={isActive(item.href)} tooltip={item.title}>
|
||
|
<Link href={item.href}>
|
||
|
<item.icon className="h-4 w-4" />
|
||
|
<span>{item.title}</span>
|
||
|
</Link>
|
||
|
</SidebarMenuButton>
|
||
|
</SidebarMenuItem>
|
||
|
))}
|
||
|
</SidebarMenu>
|
||
|
</SidebarGroupContent>
|
||
|
</SidebarGroup>
|
||
|
<SidebarSeparator />
|
||
|
<SidebarGroup>
|
||
|
<SidebarGroupLabel>User</SidebarGroupLabel>
|
||
|
<SidebarGroupContent>
|
||
|
<SidebarMenu>
|
||
|
{userNavItems.map((item) => (
|
||
|
<SidebarMenuItem key={item.href}>
|
||
|
<SidebarMenuButton asChild isActive={isActive(item.href)} tooltip={item.title}>
|
||
|
<Link href={item.href}>
|
||
|
<item.icon className="h-4 w-4" />
|
||
|
<span>{item.title}</span>
|
||
|
</Link>
|
||
|
</SidebarMenuButton>
|
||
|
</SidebarMenuItem>
|
||
|
))}
|
||
|
</SidebarMenu>
|
||
|
</SidebarGroupContent>
|
||
|
</SidebarGroup>
|
||
|
</SidebarContent>
|
||
|
{walletConnected && (
|
||
|
<SidebarFooter>
|
||
|
<SidebarMenu>
|
||
|
<SidebarMenuItem>
|
||
|
<SidebarMenuButton onClick={disconnectWallet}>
|
||
|
<LogOut className="mr-2 h-4 w-4" />
|
||
|
<span>Disconnect</span>
|
||
|
</SidebarMenuButton>
|
||
|
</SidebarMenuItem>
|
||
|
</SidebarMenu>
|
||
|
</SidebarFooter>
|
||
|
)}
|
||
|
</Sidebar>
|
||
|
)
|
||
|
}
|
||
|
|