Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { Metadata } from 'next'
import localFont from 'next/font/local'
import './globals.css'
import { ThemeProvider } from '@/components/providers/theme-provider'
import { Toaster } from '@/components/ui/toaster'

const geistSans = localFont({
src: './fonts/GeistVF.woff',
Expand All @@ -14,8 +16,8 @@ const geistMono = localFont({
})

export const metadata: Metadata = {
title: 'CodeGuide Starter Lite',
description: 'Starter kit from codeguide.dev',
title: 'Admin Dashboard - CodeGuide',
description: 'Modern admin dashboard built with Next.js, Tailwind CSS, and Radix UI',
}

export default function RootLayout({
Expand All @@ -24,8 +26,18 @@ export default function RootLayout({
children: React.ReactNode
}>) {
return (
<html lang="en">
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>{children}</body>
<html lang="en" suppressHydrationWarning>
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
{children}
<Toaster />
</ThemeProvider>
</body>
</html>
)
}
10 changes: 7 additions & 3 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
"use client"

import { Hero } from '@/components/ui/animated-hero'
import Image from 'next/image'
import { DashboardLayout } from '@/components/dashboard/layout'
import { DashboardOverview } from '@/components/dashboard/overview'

export default function Home() {
return <Hero />
return (
<DashboardLayout>
<DashboardOverview />
</DashboardLayout>
)
}
12 changes: 12 additions & 0 deletions app/settings/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"use client"

import { DashboardLayout } from '@/components/dashboard/layout'
import { SettingsPage } from '@/components/dashboard/settings'

export default function Settings() {
return (
<DashboardLayout>
<SettingsPage />
</DashboardLayout>
)
}
12 changes: 12 additions & 0 deletions app/users/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"use client"

import { DashboardLayout } from '@/components/dashboard/layout'
import { UserManagement } from '@/components/dashboard/user-management'

export default function UsersPage() {
return (
<DashboardLayout>
<UserManagement />
</DashboardLayout>
)
}
150 changes: 150 additions & 0 deletions components/dashboard/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
"use client"

import { useState } from 'react'
import {
Home,
Users,
Settings,
BarChart3,
FileText,
Menu,
Moon,
Sun,
Monitor
} from 'lucide-react'
import { useTheme } from 'next-themes'
import { Button } from '@/components/ui/button'
import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger
} from '@/components/ui/dropdown-menu'
import { cn } from '@/lib/utils'
import Image from 'next/image'

const navigation = [
{ name: 'Dashboard', href: '/', icon: Home, current: true },
{ name: 'Analytics', href: '/analytics', icon: BarChart3, current: false },
{ name: 'Users', href: '/users', icon: Users, current: false },
{ name: 'Reports', href: '/reports', icon: FileText, current: false },
{ name: 'Settings', href: '/settings', icon: Settings, current: false },
]

interface DashboardLayoutProps {
children: React.ReactNode
}

function ThemeToggle() {
const { setTheme } = useTheme()

return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon">
<Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => setTheme("light")}>
<Sun className="mr-2 h-4 w-4" />
<span>Light</span>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("dark")}>
<Moon className="mr-2 h-4 w-4" />
<span>Dark</span>
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setTheme("system")}>
<Monitor className="mr-2 h-4 w-4" />
<span>System</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)
}

function Sidebar() {
return (
<div className="flex h-full w-64 flex-col border-r bg-background">
{/* Logo */}
<div className="flex h-16 items-center gap-2 border-b px-6">
<Image src="/codeguide-logo.png" alt="CodeGuide" width={32} height={32} />
<span className="logo-text text-xl font-bold">CodeGuide</span>
</div>

{/* Navigation */}
<nav className="flex-1 space-y-1 px-3 py-4">
{navigation.map((item) => {
const Icon = item.icon
return (
<a
key={item.name}
href={item.href}
className={cn(
item.current
? 'bg-primary text-primary-foreground'
: 'text-muted-foreground hover:text-foreground hover:bg-muted',
'group flex items-center rounded-md px-3 py-2 text-sm font-medium transition-colors'
)}
>
<Icon className="mr-3 h-5 w-5" />
{item.name}
</a>
)
})}
</nav>
</div>
)
}

function MobileSidebar() {
const [open, setOpen] = useState(false)

return (
<Sheet open={open} onOpenChange={setOpen}>
<SheetTrigger asChild>
<Button variant="outline" size="icon" className="md:hidden">
<Menu className="h-5 w-5" />
<span className="sr-only">Open sidebar</span>
</Button>
</SheetTrigger>
<SheetContent side="left" className="w-64 p-0">
<Sidebar />
</SheetContent>
</Sheet>
)
}

export function DashboardLayout({ children }: DashboardLayoutProps) {
return (
<div className="flex h-screen bg-background">
{/* Desktop Sidebar */}
<div className="hidden md:flex">
<Sidebar />
</div>

{/* Main Content */}
<div className="flex flex-1 flex-col">
{/* Header */}
<header className="flex h-16 items-center justify-between border-b px-6">
<div className="flex items-center gap-4">
<MobileSidebar />
<h1 className="text-2xl font-semibold">Dashboard</h1>
</div>

<div className="flex items-center gap-4">
<ThemeToggle />
</div>
</header>

{/* Page Content */}
<main className="flex-1 overflow-auto p-6">
{children}
</main>
</div>
</div>
)
}
Loading