"use client"; import { signOut } from "@/app/login/actions"; import { ColorModeSync } from "@/components/theme/color-mode-sync"; import type { ColorMode } from "@/lib/color-mode"; import { Button, Card, CardContent, Typography, } from "poyraz-ui/atoms"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, toast, } from "poyraz-ui/molecules"; import { SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarHeader, SidebarMenu, SidebarMenuItem, SidebarPanel, SidebarProvider, SidebarTrigger, SidebarUserProfile, useSidebar, } from "poyraz-ui/organisms"; import { ChevronUp, LogOut, Settings } from "lucide-react"; import type { LucideIcon } from "lucide-react"; import Image from "next/image"; import Link from "next/link"; import { usePathname, useRouter } from "next/navigation"; import { useTransition } from "react"; export type AppShellNavItem = { title: string; href?: string; icon?: LucideIcon; }; export type AppShellNavGroup = { title: string; items: AppShellNavItem[]; }; export type AppShellBranding = { applicationName: string; organizationName: string | null; lightLogoUrl: string | null; darkLogoUrl: string | null; }; type ShellUser = { email: string; displayName: string; shortName: string; avatarUrl: string | null; }; type AppShellProps = { branding: AppShellBranding; children: React.ReactNode; homeHref: string; labels?: AppShellLabels; navGroups: AppShellNavGroup[]; settingsHref: string; user: ShellUser; progress?: number; colorMode?: ColorMode; }; export type AppShellLabels = { skipToContent: string; homeAriaLabel: string; mobileMenuAriaLabel: string; mobileMenuTooltip: string; logoAlt: string; progressTitle: string; progressValue: string; progressAriaLabel: string; accountMenuAriaLabel: string; settings: string; signOut: string; signingOut: string; signOutError: string; }; export function AppShell({ branding, children, homeHref, labels = defaultAppShellLabels, navGroups, settingsHref, user, progress, colorMode, }: AppShellProps) { const pathname = usePathname(); const sidebarProps = { branding, homeHref, labels, navGroups, pathname, progress, settingsHref, user }; return ( {colorMode ? : null}
{labels.skipToContent}
{children}
); } const defaultAppShellLabels: AppShellLabels = { skipToContent: "Ana içeriğe geç", homeAriaLabel: "Ana sayfa", mobileMenuAriaLabel: "Ana menüyü aç veya kapat", mobileMenuTooltip: "Menü", logoAlt: "Logo", progressTitle: "Proje ilerlemesi", progressValue: "%{progress} tamamlandı", progressAriaLabel: "Proje ilerlemesi", accountMenuAriaLabel: "{name} için hesap menüsünü aç", settings: "Ayarlar", signOut: "Çıkış yap", signingOut: "Çıkış yapılıyor", signOutError: "Çıkış yapılamadı. Lütfen tekrar deneyin.", }; type SidebarCompositionProps = { branding: AppShellBranding; homeHref: string; labels: AppShellLabels; navGroups: AppShellNavGroup[]; pathname: string; progress?: number; settingsHref: string; user: ShellUser; }; function DesktopSidebar(props: SidebarCompositionProps) { return ( ); } function MobileSidebar(props: SidebarCompositionProps) { return (
{props.labels.mobileMenuTooltip}
); } function SidebarComposition({ branding, homeHref, labels, navGroups, pathname, progress, settingsHref, user, }: SidebarCompositionProps) { return ( <> {typeof progress === "number" ? : null} ); } function SidebarNavigation({ homeHref, navGroups, pathname, }: Pick) { const { setMobileOpen, variant } = useSidebar(); return navGroups.map((group) => ( {group.title} {group.items.map((item) => { const active = item.href === homeHref ? pathname === homeHref : item.href ? pathname === item.href || pathname.startsWith(`${item.href}/`) : false; const Icon = item.icon; return ( ); })} )); } function WorkspaceLogo({ branding, compact = false, }: { branding: AppShellBranding; compact?: boolean; }) { const lightLogoUrl = branding.lightLogoUrl ?? branding.darkLogoUrl ?? "/logo/blackLogoLong.png"; const darkLogoUrl = branding.darkLogoUrl ?? branding.lightLogoUrl ?? "/logo/lightLogoLong.png"; const imageClassName = compact ? "max-h-8 w-auto max-w-full object-contain" : "max-h-12 w-auto max-w-full object-contain"; return ( {branding.applicationName} {branding.applicationName} ); } function ProgressSummary({ labels, progress }: { labels: AppShellLabels; progress: number }) { const normalizedProgress = Math.max(0, Math.min(100, progress)); const progressValue = labels.progressValue.replace("{progress}", String(normalizedProgress)); return ( {labels.progressTitle}
{progressValue}
); } function AccountMenu({ labels, user, settingsHref }: { labels: AppShellLabels; user: ShellUser; settingsHref: string }) { const router = useRouter(); const [isSigningOut, startSignOutTransition] = useTransition(); function handleSignOut() { startSignOutTransition(async () => { try { const result = await signOut(); router.replace(result.redirectTo); router.refresh(); } catch { toast.error(labels.signOutError); } }); } return ( {user.displayName} {user.email} ); }