From 8be6160f4f09507c113c38f574eeccf9d00cd6eb Mon Sep 17 00:00:00 2001 From: wsameer Date: Sat, 9 Aug 2025 10:26:22 -0400 Subject: [PATCH 1/3] fix: lag in sidebar collapse --- .../js/components/sidebar/app-sidebar.tsx | 175 ++++++++++++++++++ resources/js/components/sidebar/nav-main.tsx | 69 +++++++ .../js/components/sidebar/nav-projects.tsx | 83 +++++++++ resources/js/components/sidebar/nav-user.tsx | 103 +++++++++++ .../js/components/sidebar/team-switcher.tsx | 89 +++++++++ resources/js/pages/dashboard/page.tsx | 46 +++++ start/routes.ts | 2 +- 7 files changed, 566 insertions(+), 1 deletion(-) create mode 100644 resources/js/components/sidebar/app-sidebar.tsx create mode 100644 resources/js/components/sidebar/nav-main.tsx create mode 100644 resources/js/components/sidebar/nav-projects.tsx create mode 100644 resources/js/components/sidebar/nav-user.tsx create mode 100644 resources/js/components/sidebar/team-switcher.tsx create mode 100644 resources/js/pages/dashboard/page.tsx diff --git a/resources/js/components/sidebar/app-sidebar.tsx b/resources/js/components/sidebar/app-sidebar.tsx new file mode 100644 index 0000000..00f993c --- /dev/null +++ b/resources/js/components/sidebar/app-sidebar.tsx @@ -0,0 +1,175 @@ +'use client' + +import * as React from 'react' +import { + AudioWaveform, + BookOpen, + Bot, + Command, + Frame, + GalleryVerticalEnd, + Map, + PieChart, + Settings2, + SquareTerminal, +} from 'lucide-react' + +import { + Sidebar, + SidebarContent, + SidebarFooter, + SidebarHeader, + SidebarRail, +} from '@/components/ui/sidebar' +import { TeamSwitcher } from './team-switcher' +import { NavMain } from './nav-main' +import { NavProjects } from './nav-projects' +import { NavUser } from './nav-user' + +// This is sample data. +const data = { + user: { + name: 'shadcn', + email: 'm@example.com', + avatar: '/avatars/shadcn.jpg', + }, + teams: [ + { + name: 'Acme Inc', + logo: GalleryVerticalEnd, + plan: 'Enterprise', + }, + { + name: 'Acme Corp.', + logo: AudioWaveform, + plan: 'Startup', + }, + { + name: 'Evil Corp.', + logo: Command, + plan: 'Free', + }, + ], + navMain: [ + { + title: 'Playground', + url: '#', + icon: SquareTerminal, + isActive: true, + items: [ + { + title: 'History', + url: '#', + }, + { + title: 'Starred', + url: '#', + }, + { + title: 'Settings', + url: '#', + }, + ], + }, + { + title: 'Models', + url: '#', + icon: Bot, + items: [ + { + title: 'Genesis', + url: '#', + }, + { + title: 'Explorer', + url: '#', + }, + { + title: 'Quantum', + 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: 'Design Engineering', + url: '#', + icon: Frame, + }, + { + name: 'Sales & Marketing', + url: '#', + icon: PieChart, + }, + { + name: 'Travel', + url: '#', + icon: Map, + }, + ], +} + +export function AppSidebar({ ...props }: React.ComponentProps) { + return ( + + + + + + + + + + + + + + ) +} diff --git a/resources/js/components/sidebar/nav-main.tsx b/resources/js/components/sidebar/nav-main.tsx new file mode 100644 index 0000000..26221a8 --- /dev/null +++ b/resources/js/components/sidebar/nav-main.tsx @@ -0,0 +1,69 @@ +'use client' + +import { ChevronRight, type LucideIcon } from 'lucide-react' + +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible' +import { + SidebarGroup, + SidebarGroupLabel, + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + SidebarMenuSub, + SidebarMenuSubButton, + SidebarMenuSubItem, +} from '@/components/ui/sidebar' + +export function NavMain({ + items, +}: { + items: { + title: string + url: string + icon?: LucideIcon + isActive?: boolean + items?: { + title: string + url: string + }[] + }[] +}) { + return ( + + Platform + + {items.map((item) => ( + + + + + {item.icon && } + {item.title} + + + + + + {item.items?.map((subItem) => ( + + + + {subItem.title} + + + + ))} + + + + + ))} + + + ) +} diff --git a/resources/js/components/sidebar/nav-projects.tsx b/resources/js/components/sidebar/nav-projects.tsx new file mode 100644 index 0000000..a9ae813 --- /dev/null +++ b/resources/js/components/sidebar/nav-projects.tsx @@ -0,0 +1,83 @@ +'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 + + + + + ) +} diff --git a/resources/js/components/sidebar/nav-user.tsx b/resources/js/components/sidebar/nav-user.tsx new file mode 100644 index 0000000..5069580 --- /dev/null +++ b/resources/js/components/sidebar/nav-user.tsx @@ -0,0 +1,103 @@ +'use client' + +import { BadgeCheck, Bell, ChevronsUpDown, CreditCard, LogOut, Sparkles } from 'lucide-react' + +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuGroup, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu' +import { + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from '@/components/ui/sidebar' + +export function NavUser({ + user, +}: { + user: { + name: string + email: string + avatar: string + } +}) { + const { isMobile } = useSidebar() + + return ( + + + + + + + + CN + +
+ {user.name} + {user.email} +
+ +
+
+ + +
+ + + CN + +
+ {user.name} + {user.email} +
+
+
+ + + + + Upgrade to Pro + + + + + + + Account + + + + Billing + + + + Notifications + + + + + + Log out + +
+
+
+
+ ) +} diff --git a/resources/js/components/sidebar/team-switcher.tsx b/resources/js/components/sidebar/team-switcher.tsx new file mode 100644 index 0000000..1034b34 --- /dev/null +++ b/resources/js/components/sidebar/team-switcher.tsx @@ -0,0 +1,89 @@ +'use client' + +import * as React from 'react' +import { ChevronsUpDown, Plus } from 'lucide-react' + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu' +import { + SidebarMenu, + SidebarMenuButton, + SidebarMenuItem, + useSidebar, +} from '@/components/ui/sidebar' + +export function TeamSwitcher({ + teams, +}: { + teams: { + name: string + logo: React.ElementType + plan: string + }[] +}) { + const { isMobile } = useSidebar() + const [activeTeam, setActiveTeam] = React.useState(teams[0]) + + if (!activeTeam) { + return null + } + + return ( + + + + + +
+ +
+
+ {activeTeam.name} + {activeTeam.plan} +
+ +
+
+ + Teams + {teams.map((team, index) => ( + setActiveTeam(team)} + className="gap-2 p-2" + > +
+ +
+ {team.name} + ⌘{index + 1} +
+ ))} + + +
+ +
+
Add team
+
+
+
+
+
+ ) +} diff --git a/resources/js/pages/dashboard/page.tsx b/resources/js/pages/dashboard/page.tsx new file mode 100644 index 0000000..398aac6 --- /dev/null +++ b/resources/js/pages/dashboard/page.tsx @@ -0,0 +1,46 @@ +import { AppSidebar } from '@/components/sidebar/app-sidebar' +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from '@/components/ui/breadcrumb' +import { Separator } from '@/components/ui/separator' +import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar' + +export default function Page() { + return ( + + + +
+
+ + + + + + Building Your Application + + + + Data Fetching + + + +
+
+
+
+
+
+
+
+
+
+ + + ) +} diff --git a/start/routes.ts b/start/routes.ts index 5ae78cf..e92b03a 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -30,8 +30,8 @@ router .as('auth-routes') .prefix('api/auth') -router.on('/dashboard').renderInertia('dashboard').use(middleware.auth()).as('dashboard') router.on('/settings').renderInertia('settings').use(middleware.auth()).as('settings') +router.on('/dashboard').renderInertia('dashboard/page').use(middleware.auth()).as('dashboard') router .group(() => { From bf9a88cbfff5572383416fcaeac5defeb574e59a Mon Sep 17 00:00:00 2001 From: wsameer Date: Sat, 9 Aug 2025 13:19:07 -0400 Subject: [PATCH 2/3] updated sidebar and added more menu --- .../js/components/layout/page-layout.tsx | 15 +- .../js/components/navigation/app-sidebar.tsx | 85 -------- .../js/components/navigation/nav-main.tsx | 34 --- .../js/components/navigation/nav-projects.tsx | 81 -------- .../js/components/navigation/nav-user.tsx | 109 ---------- .../app-sidebar-header.tsx | 0 .../js/components/sidebar/app-sidebar.tsx | 194 +++++------------- resources/js/components/sidebar/nav-main.tsx | 73 +++---- .../js/components/sidebar/nav-projects.tsx | 83 -------- .../{navigation => sidebar}/nav-secondary.tsx | 2 - resources/js/components/sidebar/nav-user.tsx | 92 +++++---- .../js/components/sidebar/team-switcher.tsx | 99 ++------- resources/js/components/ui/dialog.tsx | 2 - resources/js/components/ui/label.tsx | 2 - resources/js/components/ui/toggle.tsx | 2 - resources/js/components/ui/tooltip.tsx | 2 - resources/js/pages/dashboard.tsx | 14 +- resources/js/pages/dashboard/page.tsx | 46 ----- resources/js/pages/settings.tsx | 5 +- resources/js/types/index.d.ts | 1 + start/routes.ts | 2 +- 21 files changed, 156 insertions(+), 787 deletions(-) delete mode 100644 resources/js/components/navigation/app-sidebar.tsx delete mode 100644 resources/js/components/navigation/nav-main.tsx delete mode 100644 resources/js/components/navigation/nav-projects.tsx delete mode 100644 resources/js/components/navigation/nav-user.tsx rename resources/js/components/{navigation => sidebar}/app-sidebar-header.tsx (100%) delete mode 100644 resources/js/components/sidebar/nav-projects.tsx rename resources/js/components/{navigation => sidebar}/nav-secondary.tsx (96%) delete mode 100644 resources/js/pages/dashboard/page.tsx diff --git a/resources/js/components/layout/page-layout.tsx b/resources/js/components/layout/page-layout.tsx index 57f35c0..90e0cda 100644 --- a/resources/js/components/layout/page-layout.tsx +++ b/resources/js/components/layout/page-layout.tsx @@ -1,23 +1,24 @@ -import { usePage } from '@inertiajs/react' +import { Head, usePage } from '@inertiajs/react' import { type PropsWithChildren } from 'react' import { type SharedProps, type BreadcrumbItem as BreadcrumbItemType } from '@/types' - -import { AppContent } from '../common/app-content' -import { AppSidebar } from '../navigation/app-sidebar' -import { AppSidebarHeader } from '../navigation/app-sidebar-header' import { SidebarProvider } from '../ui/sidebar' +import { AppSidebar } from '../sidebar/app-sidebar' +import { AppSidebarHeader } from '../sidebar/app-sidebar-header' +import { AppContent } from '../common/app-content' export const PageLayout = ({ children, + pageTitle, breadcrumbs = [], -}: PropsWithChildren & { breadcrumbs?: BreadcrumbItemType[] }) => { +}: PropsWithChildren & { pageTitle: string; breadcrumbs?: BreadcrumbItemType[] }) => { const isOpen = usePage().props.sidebarOpen return ( - + + {children} diff --git a/resources/js/components/navigation/app-sidebar.tsx b/resources/js/components/navigation/app-sidebar.tsx deleted file mode 100644 index 8f0e7b7..0000000 --- a/resources/js/components/navigation/app-sidebar.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { BookOpenIcon, GithubIcon, Settings2Icon, SquareTerminal } from 'lucide-react' -import * as React from 'react' - -import { - Sidebar, - SidebarContent, - SidebarFooter, - SidebarHeader, - SidebarMenu, - SidebarMenuButton, - SidebarMenuItem, - SidebarRail, -} from '@/components/ui/sidebar' -import { type NavItem } from '@/types' -import { Link } from '@inertiajs/react' -import { AppLogo } from '../common/app-logo' -import { NavMain } from './nav-main' -import { NavSecondary } from './nav-secondary' -import { NavUser } from './nav-user' - -// This is sample data. -const mainNavItems: NavItem[] = [ - { - title: 'Dashboard', - href: '/dashboard', // needs to match path.url for it to be active based on the page you are on - icon: SquareTerminal, - }, - { - title: 'Settings', - href: '/settings', - icon: Settings2Icon, - }, -] - -const secondaryNavItems: NavItem[] = [ - { - title: 'Documentation', - href: 'https://wsameer.github.io/adonisjs-react-starter-kit/intro.html', - icon: BookOpenIcon, - }, - { - title: 'Repository', - href: 'https://wsameer.github.io/adonisjs-react-starter-kit/', - icon: GithubIcon, - }, -] - -export function AppSidebar({ ...props }: React.ComponentProps) { - return ( - - - - - - -
- -
-
- App name - Enterprise -
- -
-
-
-
- - - - - - - - - - - -
- ) -} diff --git a/resources/js/components/navigation/nav-main.tsx b/resources/js/components/navigation/nav-main.tsx deleted file mode 100644 index 948064b..0000000 --- a/resources/js/components/navigation/nav-main.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { - SidebarGroup, - SidebarGroupLabel, - SidebarMenu, - SidebarMenuButton, - SidebarMenuItem, -} from '@/components/ui/sidebar' -import { type SharedProps, type NavItem } from '@/types' -import { Link, usePage } from '@inertiajs/react' - -export function NavMain({ items = [] }: { items: NavItem[] }) { - const page = usePage() - return ( - - Platform - - {items.map((item) => ( - - - - {item.icon && } - {item.title} - - - - ))} - - - ) -} diff --git a/resources/js/components/navigation/nav-projects.tsx b/resources/js/components/navigation/nav-projects.tsx deleted file mode 100644 index d21c4f7..0000000 --- a/resources/js/components/navigation/nav-projects.tsx +++ /dev/null @@ -1,81 +0,0 @@ -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 - - - - - ) -} diff --git a/resources/js/components/navigation/nav-user.tsx b/resources/js/components/navigation/nav-user.tsx deleted file mode 100644 index 8190c42..0000000 --- a/resources/js/components/navigation/nav-user.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import { ChevronsUpDown, LogOut } from 'lucide-react' - -import { Avatar, AvatarFallback } from '@/components/ui/avatar' -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from '@/components/ui/dropdown-menu' -import { - SidebarMenu, - SidebarMenuButton, - SidebarMenuItem, - useSidebar, -} from '@/components/ui/sidebar' -import { useMobileNavigation } from '@/hooks/use-mobile-navigations' -import { type SharedProps } from '@/types' -import { Link, router, usePage } from '@inertiajs/react' - -const getInitials = (fullName: string): string => { - const names = fullName.trim().split(' ') - - if (names.length === 0) return '' - if (names.length === 1) return names[0].charAt(0).toUpperCase() - - const firstInitial = names[0].charAt(0) - const lastInitial = names[names.length - 1].charAt(0) - - return `${firstInitial}${lastInitial}`.toUpperCase() -} - -export const NavUser = () => { - const { props } = usePage() - const { auth, user } = props - - const { state } = useSidebar() - const { isMobile } = useSidebar() - - const cleanup = useMobileNavigation() - const handleLogout = () => { - cleanup() - router.flushAll() - } - - if (!auth || !user) { - return null - } - - return ( - - - - - - - {/* */} - - {getInitials(user?.name ?? '')} - - -
- {user.name} - {user.email} -
- -
-
- - -
- - {/* */} - CN - -
- {user.name} - {user.email} -
-
-
- - - - - Log out - - -
-
-
-
- ) -} diff --git a/resources/js/components/navigation/app-sidebar-header.tsx b/resources/js/components/sidebar/app-sidebar-header.tsx similarity index 100% rename from resources/js/components/navigation/app-sidebar-header.tsx rename to resources/js/components/sidebar/app-sidebar-header.tsx diff --git a/resources/js/components/sidebar/app-sidebar.tsx b/resources/js/components/sidebar/app-sidebar.tsx index 00f993c..be84b12 100644 --- a/resources/js/components/sidebar/app-sidebar.tsx +++ b/resources/js/components/sidebar/app-sidebar.tsx @@ -1,16 +1,10 @@ -'use client' - import * as React from 'react' import { - AudioWaveform, - BookOpen, - Bot, - Command, - Frame, - GalleryVerticalEnd, - Map, - PieChart, - Settings2, + BookOpenIcon, + GithubIcon, + LifeBuoy, + SendIcon, + Settings2Icon, SquareTerminal, } from 'lucide-react' @@ -23,151 +17,65 @@ import { } from '@/components/ui/sidebar' import { TeamSwitcher } from './team-switcher' import { NavMain } from './nav-main' -import { NavProjects } from './nav-projects' +import { NavSecondary } from './nav-secondary' import { NavUser } from './nav-user' +import { type NavItem } from '@/types' // This is sample data. -const data = { - user: { - name: 'shadcn', - email: 'm@example.com', - avatar: '/avatars/shadcn.jpg', +const mainNavItems: NavItem[] = [ + { + title: 'Dashboard', + href: '/dashboard', // needs to match path.url for it to be active based on the page you are on + icon: SquareTerminal, + type: 'internal', }, - teams: [ - { - name: 'Acme Inc', - logo: GalleryVerticalEnd, - plan: 'Enterprise', - }, - { - name: 'Acme Corp.', - logo: AudioWaveform, - plan: 'Startup', - }, - { - name: 'Evil Corp.', - logo: Command, - plan: 'Free', - }, - ], - navMain: [ - { - title: 'Playground', - url: '#', - icon: SquareTerminal, - isActive: true, - items: [ - { - title: 'History', - url: '#', - }, - { - title: 'Starred', - url: '#', - }, - { - title: 'Settings', - url: '#', - }, - ], - }, - { - title: 'Models', - url: '#', - icon: Bot, - items: [ - { - title: 'Genesis', - url: '#', - }, - { - title: 'Explorer', - url: '#', - }, - { - title: 'Quantum', - 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: 'Design Engineering', - url: '#', - icon: Frame, - }, - { - name: 'Sales & Marketing', - url: '#', - icon: PieChart, - }, - { - name: 'Travel', - url: '#', - icon: Map, - }, - ], -} + { + title: 'Settings', + href: '/settings', + icon: Settings2Icon, + type: 'internal', + }, + { + title: 'Documentation', + href: 'https://wsameer.github.io/adonisjs-react-starter-kit/intro.html', + icon: BookOpenIcon, + type: 'external', + }, + { + title: 'Repository', + href: 'https://github.com/wsameer/adonisjs-react-starter-kit', + icon: GithubIcon, + type: 'external', + }, +] + +const secondaryNavItems: NavItem[] = [ + { + title: 'Support', + href: 'https://github.com/wsameer/adonisjs-react-starter-kit/issues/new', + icon: LifeBuoy, + type: 'external', + }, + { + title: 'Feedback', + href: 'mailto:someone@example.com', + icon: SendIcon, + type: 'external', + }, +] export function AppSidebar({ ...props }: React.ComponentProps) { return ( - + - - + + - + diff --git a/resources/js/components/sidebar/nav-main.tsx b/resources/js/components/sidebar/nav-main.tsx index 26221a8..64bce9b 100644 --- a/resources/js/components/sidebar/nav-main.tsx +++ b/resources/js/components/sidebar/nav-main.tsx @@ -1,67 +1,40 @@ -'use client' - -import { ChevronRight, type LucideIcon } from 'lucide-react' - -import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible' import { SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuButton, SidebarMenuItem, - SidebarMenuSub, - SidebarMenuSubButton, - SidebarMenuSubItem, } from '@/components/ui/sidebar' +import { type SharedProps, type NavItem } from '@/types' +import { Link, usePage } from '@inertiajs/react' +import { Icon } from '../common/icon' -export function NavMain({ - items, -}: { - items: { - title: string - url: string - icon?: LucideIcon - isActive?: boolean - items?: { - title: string - url: string - }[] - }[] -}) { +export function NavMain({ items }: { items: NavItem[] }) { + const page = usePage() return ( Platform {items.map((item) => ( - - - - - {item.icon && } + + + {item.type === 'internal' ? ( + + {item.icon && } + {item.title} + + ) : ( + + {item.icon && } {item.title} - - - - - - {item.items?.map((subItem) => ( - - - - {subItem.title} - - - - ))} - - - - + + )} + + ))} diff --git a/resources/js/components/sidebar/nav-projects.tsx b/resources/js/components/sidebar/nav-projects.tsx deleted file mode 100644 index a9ae813..0000000 --- a/resources/js/components/sidebar/nav-projects.tsx +++ /dev/null @@ -1,83 +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 - - - - - ) -} diff --git a/resources/js/components/navigation/nav-secondary.tsx b/resources/js/components/sidebar/nav-secondary.tsx similarity index 96% rename from resources/js/components/navigation/nav-secondary.tsx rename to resources/js/components/sidebar/nav-secondary.tsx index 60c4a88..bccc64b 100644 --- a/resources/js/components/navigation/nav-secondary.tsx +++ b/resources/js/components/sidebar/nav-secondary.tsx @@ -1,5 +1,3 @@ -import * as React from 'react' - import { SidebarGroup, SidebarGroupContent, diff --git a/resources/js/components/sidebar/nav-user.tsx b/resources/js/components/sidebar/nav-user.tsx index 5069580..8190c42 100644 --- a/resources/js/components/sidebar/nav-user.tsx +++ b/resources/js/components/sidebar/nav-user.tsx @@ -1,12 +1,9 @@ -'use client' +import { ChevronsUpDown, LogOut } from 'lucide-react' -import { BadgeCheck, Bell, ChevronsUpDown, CreditCard, LogOut, Sparkles } from 'lucide-react' - -import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' +import { Avatar, AvatarFallback } from '@/components/ui/avatar' import { DropdownMenu, DropdownMenuContent, - DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, @@ -18,18 +15,39 @@ import { SidebarMenuItem, useSidebar, } from '@/components/ui/sidebar' +import { useMobileNavigation } from '@/hooks/use-mobile-navigations' +import { type SharedProps } from '@/types' +import { Link, router, usePage } from '@inertiajs/react' -export function NavUser({ - user, -}: { - user: { - name: string - email: string - avatar: string - } -}) { +const getInitials = (fullName: string): string => { + const names = fullName.trim().split(' ') + + if (names.length === 0) return '' + if (names.length === 1) return names[0].charAt(0).toUpperCase() + + const firstInitial = names[0].charAt(0) + const lastInitial = names[names.length - 1].charAt(0) + + return `${firstInitial}${lastInitial}`.toUpperCase() +} + +export const NavUser = () => { + const { props } = usePage() + const { auth, user } = props + + const { state } = useSidebar() const { isMobile } = useSidebar() + const cleanup = useMobileNavigation() + const handleLogout = () => { + cleanup() + router.flushAll() + } + + if (!auth || !user) { + return null + } + return ( @@ -40,8 +58,10 @@ export function NavUser({ className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground" > - - CN + {/* */} + + {getInitials(user?.name ?? '')} +
{user.name} @@ -52,14 +72,14 @@ export function NavUser({
- + {/* */} CN
@@ -69,31 +89,17 @@ export function NavUser({
- - - - Upgrade to Pro - - - - - - - Account - - - - Billing - - - - Notifications - - - - - - Log out + + + + Log out + diff --git a/resources/js/components/sidebar/team-switcher.tsx b/resources/js/components/sidebar/team-switcher.tsx index 1034b34..fb42e13 100644 --- a/resources/js/components/sidebar/team-switcher.tsx +++ b/resources/js/components/sidebar/team-switcher.tsx @@ -1,88 +1,27 @@ -'use client' +import { GalleryVerticalEnd } from 'lucide-react' -import * as React from 'react' -import { ChevronsUpDown, Plus } from 'lucide-react' - -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuShortcut, - DropdownMenuTrigger, -} from '@/components/ui/dropdown-menu' -import { - SidebarMenu, - SidebarMenuButton, - SidebarMenuItem, - useSidebar, -} from '@/components/ui/sidebar' - -export function TeamSwitcher({ - teams, -}: { - teams: { - name: string - logo: React.ElementType - plan: string - }[] -}) { - const { isMobile } = useSidebar() - const [activeTeam, setActiveTeam] = React.useState(teams[0]) - - if (!activeTeam) { - return null - } +import { SidebarMenu, SidebarMenuButton, SidebarMenuItem } from '@/components/ui/sidebar' +import { Link } from '@inertiajs/react' +export function TeamSwitcher() { return ( - - - -
- -
-
- {activeTeam.name} - {activeTeam.plan} -
- -
-
- - Teams - {teams.map((team, index) => ( - setActiveTeam(team)} - className="gap-2 p-2" - > -
- -
- {team.name} - ⌘{index + 1} -
- ))} - - -
- -
-
Add team
-
-
-
+ + +
+ +
+
+ App Name + Enterprise +
+ +
) diff --git a/resources/js/components/ui/dialog.tsx b/resources/js/components/ui/dialog.tsx index 4a676bc..c0e54d9 100644 --- a/resources/js/components/ui/dialog.tsx +++ b/resources/js/components/ui/dialog.tsx @@ -1,5 +1,3 @@ -'use client' - import * as React from 'react' import * as DialogPrimitive from '@radix-ui/react-dialog' import { XIcon } from 'lucide-react' diff --git a/resources/js/components/ui/label.tsx b/resources/js/components/ui/label.tsx index 0f0939b..d7b4512 100644 --- a/resources/js/components/ui/label.tsx +++ b/resources/js/components/ui/label.tsx @@ -1,5 +1,3 @@ -'use client' - import * as React from 'react' import * as LabelPrimitive from '@radix-ui/react-label' diff --git a/resources/js/components/ui/toggle.tsx b/resources/js/components/ui/toggle.tsx index 973d7be..a41018c 100644 --- a/resources/js/components/ui/toggle.tsx +++ b/resources/js/components/ui/toggle.tsx @@ -1,5 +1,3 @@ -'use client' - import * as React from 'react' import * as TogglePrimitive from '@radix-ui/react-toggle' import { cva, type VariantProps } from 'class-variance-authority' diff --git a/resources/js/components/ui/tooltip.tsx b/resources/js/components/ui/tooltip.tsx index faffc58..d051219 100644 --- a/resources/js/components/ui/tooltip.tsx +++ b/resources/js/components/ui/tooltip.tsx @@ -1,5 +1,3 @@ -'use client' - import * as React from 'react' import * as TooltipPrimitive from '@radix-ui/react-tooltip' diff --git a/resources/js/pages/dashboard.tsx b/resources/js/pages/dashboard.tsx index 33926eb..80e82a3 100644 --- a/resources/js/pages/dashboard.tsx +++ b/resources/js/pages/dashboard.tsx @@ -1,8 +1,5 @@ -import { LOGIN_ROUTE } from '@/app/routes' import { PageLayout } from '@/components/layout/page-layout' import { type BreadcrumbItem } from '@/types' -import { type PageProps } from '@adonisjs/inertia/types' -import { Head, router } from '@inertiajs/react' const breadcrumbs: BreadcrumbItem[] = [ { id: 1, title: 'Building Your Application', href: '#' }, @@ -13,14 +10,9 @@ const breadcrumbs: BreadcrumbItem[] = [ }, ] -const Dashboard = ({ auth }: PageProps) => { - if (!auth) { - router.push({ url: LOGIN_ROUTE }) - } - +export default function Dashboard() { return ( - - +
@@ -32,5 +24,3 @@ const Dashboard = ({ auth }: PageProps) => { ) } - -export default Dashboard diff --git a/resources/js/pages/dashboard/page.tsx b/resources/js/pages/dashboard/page.tsx deleted file mode 100644 index 398aac6..0000000 --- a/resources/js/pages/dashboard/page.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { AppSidebar } from '@/components/sidebar/app-sidebar' -import { - Breadcrumb, - BreadcrumbItem, - BreadcrumbLink, - BreadcrumbList, - BreadcrumbPage, - BreadcrumbSeparator, -} from '@/components/ui/breadcrumb' -import { Separator } from '@/components/ui/separator' -import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar' - -export default function Page() { - return ( - - - -
-
- - - - - - Building Your Application - - - - Data Fetching - - - -
-
-
-
-
-
-
-
-
-
- - - ) -} diff --git a/resources/js/pages/settings.tsx b/resources/js/pages/settings.tsx index b3c1157..3e5765c 100644 --- a/resources/js/pages/settings.tsx +++ b/resources/js/pages/settings.tsx @@ -1,7 +1,7 @@ import { LOGIN_ROUTE } from '@/app/routes' import { PageLayout } from '@/components/layout/page-layout' import { type BreadcrumbItem, type PageProps } from '@/types' -import { Head, router } from '@inertiajs/react' +import { router } from '@inertiajs/react' const breadcrumbs: BreadcrumbItem[] = [ { id: 1, title: 'Building Your Application', href: '#' }, @@ -18,8 +18,7 @@ export const Settings = ({ auth }: PageProps) => { } return ( - - +
Settings
) diff --git a/resources/js/types/index.d.ts b/resources/js/types/index.d.ts index 935d444..45dd085 100644 --- a/resources/js/types/index.d.ts +++ b/resources/js/types/index.d.ts @@ -18,5 +18,6 @@ export interface NavItem { title: string href: string icon?: LucideIcon | null + type: 'internal' | 'external' isActive?: boolean } diff --git a/start/routes.ts b/start/routes.ts index e92b03a..299d0c9 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -31,7 +31,7 @@ router .prefix('api/auth') router.on('/settings').renderInertia('settings').use(middleware.auth()).as('settings') -router.on('/dashboard').renderInertia('dashboard/page').use(middleware.auth()).as('dashboard') +router.on('/dashboard').renderInertia('dashboard').use(middleware.auth()).as('dashboard') router .group(() => { From 2a6b988df04001fb1b27510490fe4ea142e2e233 Mon Sep 17 00:00:00 2001 From: wsameer Date: Sat, 9 Aug 2025 13:30:23 -0400 Subject: [PATCH 3/3] first steps for settings --- resources/js/pages/settings/profile-settings.tsx | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 resources/js/pages/settings/profile-settings.tsx diff --git a/resources/js/pages/settings/profile-settings.tsx b/resources/js/pages/settings/profile-settings.tsx new file mode 100644 index 0000000..e69de29