From 4bdddaa7e753f7e6cab6fb6fe073bcb53458f9da Mon Sep 17 00:00:00 2001 From: Pierre Wessman <4029607+pierrewessman@users.noreply.github.com> Date: Fri, 12 Dec 2025 12:50:10 +0100 Subject: [PATCH] pravatar --- CLAUDE.md | 159 ++++++++++++++++++++++++++++++++- components/layout/user-nav.tsx | 2 +- lib/mock-data.ts | 12 +-- 3 files changed, 163 insertions(+), 10 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 0fa3355..306a73d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,5 +1,158 @@ -# Development Notes +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Package Manager -- **Use pnpm** for all package management operations -- Do NOT use npm - always use pnpm +- **Always use pnpm** for all package management operations +- Do NOT use npm or yarn - this project exclusively uses pnpm + +## Development Commands + +```bash +# Install dependencies +pnpm install + +# Start development server (http://localhost:3000) +pnpm run dev + +# Create production build +pnpm run build + +# Start production server +pnpm start + +# Run linter +pnpm run lint +``` + +## Tech Stack & Key Libraries + +- **Next.js 14** with App Router (not Pages Router) +- **TypeScript** with strict mode enabled +- **Tailwind CSS v4** with custom theme configuration +- **shadcn/ui** components (New York style variant) +- **Chart.js** via react-chartjs-2 for data visualization +- **next-themes** for dark/light theme management +- **Lucide React** for icons + +## Architecture Overview + +### Provider Hierarchy +The app uses nested providers in this order (outer to inner): +1. `ThemeProvider` - Manages dark/light theme state +2. `SidebarProvider` - Manages sidebar state (open/collapsed) + +Both wrap all page content in [app/layout.tsx](app/layout.tsx:1). + +### Layout Structure +The dashboard uses a sidebar + inset layout pattern: +- `` - Collapsible navigation sidebar +- `` - Main content area containing: + - `
` - Top header with search and theme toggle + - Page content (dashboard components) + +This structure is defined in [app/page.tsx](app/page.tsx:1). + +### Data Flow +- All dashboard data comes from `getDashboardData()` in [lib/mock-data.ts](lib/mock-data.ts) +- Data types are defined in [types/dashboard.ts](types/dashboard.ts:1) +- Data is fetched at the page level and passed down as props + +### Component Organization + +``` +components/ +├── ui/ # shadcn/ui components (auto-generated, don't edit manually) +├── layout/ # Layout components (sidebar, header, nav) +├── dashboard/ # Dashboard-specific components (cards, tables, tabs) +├── charts/ # Chart wrapper components +└── theme-provider.tsx +``` + +### Theming System + +The app uses a CSS variable-based theming system: +- **Colors**: Defined using OKLCH color space in [app/globals.css](app/globals.css:1) +- **Variants**: Light mode (`:root`) and dark mode (`.dark` class) +- **Theme switching**: Managed by `next-themes` via the `ThemeProvider` +- **Chart colors**: Dynamic colors that respond to theme changes via `getChartColors()` in [lib/chart-config.ts](lib/chart-config.ts:1) + +To modify theme colors, edit the CSS variables in `app/globals.css` under `:root` (light) and `.dark` (dark theme). + +### Path Aliases + +TypeScript path alias `@/*` maps to the root directory: +```typescript +import { cn } from "@/lib/utils" +import { Button } from "@/components/ui/button" +``` + +Configured in [tsconfig.json](tsconfig.json:21). + +### Chart.js Configuration + +- Chart.js is globally registered in [lib/chart-config.ts](lib/chart-config.ts:1) +- Import this file before using any chart components +- Charts automatically adapt colors based on current theme +- Use `getChartColors(theme)` to get theme-aware color palette + +## shadcn/ui Configuration + +- Style variant: `new-york` +- Base color: `neutral` +- Uses CSS variables for theming +- Configuration in [components.json](components.json:1) + +**Adding new shadcn/ui components:** +```bash +pnpm dlx shadcn@latest add +``` + +Components are added to `components/ui/` and should not be manually edited (use composition instead). + +## TypeScript Notes + +- Path alias: `@/*` points to root directory +- Strict mode enabled +- JSX runtime: `react-jsx` (no need to import React) +- Target: ES2017 + +## Styling Patterns + +- Use `cn()` utility from [lib/utils.ts](lib/utils.ts:1) to merge Tailwind classes +- Custom scrollbar styling via `.scrollbar-thin` utility class +- Responsive breakpoints: `md:` (768px), `lg:` (1024px) +- Grid layouts for dashboard components (see [app/page.tsx](app/page.tsx:25)) + +## Client vs Server Components + +- Most components are Server Components by default +- Add `"use client"` directive only when needed: + - Theme-related components (using `useTheme`) + - Chart components (using Chart.js) + - Interactive components with hooks (useState, useEffect) + - shadcn/ui components (most require "use client") + +## Important Patterns + +### Component Composition +When creating new dashboard components, follow the established pattern: +1. Define TypeScript interface in `types/dashboard.ts` +2. Accept props with proper typing +3. Use shadcn/ui Card component as container +4. Apply consistent spacing and layout + +### Adding New Charts +1. Create data structure in `types/dashboard.ts` +2. Add mock data to `lib/mock-data.ts` +3. Create chart wrapper in `components/charts/` or `components/dashboard/` +4. Use `getChartColors(theme)` for theme-aware styling +5. Mark component with `"use client"` + +### Icon Usage +Use Lucide React icons: +```typescript +import { IconName } from "lucide-react" +``` + +Icons are passed as string identifiers in metric cards and dynamically resolved in the component. diff --git a/components/layout/user-nav.tsx b/components/layout/user-nav.tsx index ba930b1..6543328 100644 --- a/components/layout/user-nav.tsx +++ b/components/layout/user-nav.tsx @@ -17,7 +17,7 @@ export function UserNav() { diff --git a/lib/mock-data.ts b/lib/mock-data.ts index fdb124c..7847b9a 100644 --- a/lib/mock-data.ts +++ b/lib/mock-data.ts @@ -138,42 +138,42 @@ export function getDashboardData(): DashboardData { name: "Sofia Davis", email: "sofia.davis@email.com", role: "Product Designer", - avatar: "/avatars/01.png", + avatar: "https://i.pravatar.cc/300?img=1", }, { id: "2", name: "Jackson Lee", email: "jackson.lee@email.com", role: "Frontend Developer", - avatar: "/avatars/02.png", + avatar: "https://i.pravatar.cc/300?img=12", }, { id: "3", name: "Isabella Nguyen", email: "isabella.nguyen@email.com", role: "Backend Developer", - avatar: "/avatars/03.png", + avatar: "https://i.pravatar.cc/300?img=5", }, { id: "4", name: "William Kim", email: "william.kim@email.com", role: "UX Researcher", - avatar: "/avatars/04.png", + avatar: "https://i.pravatar.cc/300?img=15", }, { id: "5", name: "Emily Wilson", email: "emily.wilson@email.com", role: "Marketing Manager", - avatar: "/avatars/05.png", + avatar: "https://i.pravatar.cc/300?img=20", }, { id: "6", name: "Michael Brown", email: "michael.brown@email.com", role: "DevOps Engineer", - avatar: "/avatars/06.png", + avatar: "https://i.pravatar.cc/300?img=33", }, ], }