diff --git a/.claude/settings.json b/.claude/settings.json index 4e595ab..79f72e0 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -8,14 +8,18 @@ "mcp__playwright__browser_close", "mcp__playwright__browser_console_messages", "mcp__playwright__browser_evaluate", + "mcp__playwright__browser_fill_form", + "mcp__playwright__browser_hover", "mcp__playwright__browser_navigate", "mcp__playwright__browser_navigate_back", "mcp__playwright__browser_network_requests", + "mcp__playwright__browser_press_key", "mcp__playwright__browser_resize", "mcp__playwright__browser_run_code", "mcp__playwright__browser_snapshot", "mcp__playwright__browser_tabs", "mcp__playwright__browser_take_screenshot", + "mcp__playwright__browser_type", "mcp__playwright__browser_wait_for", "Bash(cat:*)", "Bash(echo:*)", @@ -26,9 +30,11 @@ "Bash(tree:*)", "Bash(wc:*)", "Bash(xargs:*)", + "Bash(git diff:*)", "Bash(git log:*)", "Bash(gh pr checks:*)", "Bash(gh pr list:*)", + "Bash(gh pr view:*)", "Bash(gh run list:*)", "Bash(gh run view:*)", "Bash(npm run build)", @@ -44,6 +50,7 @@ "Bash(npx @biomejs/biome:*)", "Bash(npx lefthook:*)", "Bash(npx playwright:*)", + "Bash(npx vercel:*)", "Bash(vercel --help)", "Bash(vercel env --help)", "Bash(vercel env ls:*)", diff --git a/app/(root)/layout.tsx b/app/(root)/layout.tsx index f8d842c..aefd44e 100644 --- a/app/(root)/layout.tsx +++ b/app/(root)/layout.tsx @@ -1,8 +1,8 @@ import { cookies } from "next/headers"; -import { DesktopTopBar } from "@/components/navigation/desktop-top-bar"; +import { DesktopTopBar } from "@/components/navigation/desktop-topbar"; import { LeftSidebar } from "@/components/navigation/left-sidebar"; -import { MobileTopBar } from "@/components/navigation/mobile-top-bar"; -import { RightSidebar } from "@/components/navigation/right-sidebar"; +import { MobileTopBar } from "@/components/navigation/mobile-topbar"; +import { RightSidebar } from "@/components/right-sidebar/right-sidebar"; import { SidebarProvider } from "@/components/ui/sidebar"; const RootLayout = async ({ children }: { children: React.ReactNode }) => { diff --git a/app/(root)/question/[id]/page.tsx b/app/(root)/question/[id]/page.tsx new file mode 100644 index 0000000..dd2111e --- /dev/null +++ b/app/(root)/question/[id]/page.tsx @@ -0,0 +1,8 @@ +type QuestionPageProps = { + params: Promise<{ id: string }>; +}; + +export default async function QuestionPage({ params }: QuestionPageProps) { + const { id } = await params; + return

Question {id}

; +} diff --git a/app/(root)/tags/[slug]/page.tsx b/app/(root)/tags/[slug]/page.tsx new file mode 100644 index 0000000..9c41f51 --- /dev/null +++ b/app/(root)/tags/[slug]/page.tsx @@ -0,0 +1,8 @@ +type TagPageProps = { + params: Promise<{ slug: string }>; +}; + +export default async function TagPage({ params }: TagPageProps) { + const { slug } = await params; + return

Tag: {slug}

; +} diff --git a/app/globals.css b/app/globals.css index 6180cf6..e7ffeff 100644 --- a/app/globals.css +++ b/app/globals.css @@ -62,7 +62,6 @@ --color-sidebar-ring: var(--sidebar-ring); /* Custom */ - --color-mobile-nav: var(--mobile-nav); --color-overlay: var(--overlay); } @@ -119,13 +118,16 @@ var(--primary-gradient-to) 99.54% ); - /* Custom: Navigation */ - --mobile-nav: oklch(1 0 0); /* #FFFFFF */ + /* Custom: Overlay */ --overlay: oklch(0 0 0); /* black, both modes */ /* Custom: Assets (theme-aware URLs) */ --logo-full-themed: url("/images/logo-light.svg"); --auth-bg: url("/images/auth-bg-light.webp"); + + /* Custom: Tag badges */ + --tag-bg: oklch(0.9722 0.0034 247.86); /* #F4F6F8 */ + --tag-text: oklch(0.6504 0.0475 272.34); /* #858EAD */ } /* Dark mode overrides — these values take precedence over :root when .dark is active */ @@ -178,13 +180,16 @@ var(--primary-gradient-to) 99.54% ); /* same as root */ - /* Custom: Navigation */ - --mobile-nav: oklch(0.1288 0.0406 264.7); /* #07080b */ + /* Custom: Overlay */ --overlay: oklch(0 0 0); /* same as root */ /* Custom: Assets (theme-aware URLs) */ --logo-full-themed: url("/images/logo-dark.svg"); --auth-bg: url("/images/auth-bg-dark.webp"); + + /* Custom: Tag badges */ + --tag-bg: oklch(0.2102 0.0185 270.39); /* #151821 */ + --tag-text: oklch(0.6547 0.0897 269.9); /* #7B8EC8 */ } @layer base { diff --git a/components/navigation/desktop-top-bar.tsx b/components/navigation/desktop-topbar.tsx similarity index 100% rename from components/navigation/desktop-top-bar.tsx rename to components/navigation/desktop-topbar.tsx diff --git a/components/navigation/mobile-nav.tsx b/components/navigation/mobile-nav.tsx index a527616..5a075b0 100644 --- a/components/navigation/mobile-nav.tsx +++ b/components/navigation/mobile-nav.tsx @@ -10,7 +10,7 @@ import { import { Menu, X } from "lucide-react"; import Link from "next/link"; import { useState } from "react"; -import { MobileNavLink } from "@/components/navigation/mobile-nav-link"; +import { MobileNavLink } from "@/components/navigation/mobile-navlink"; import { NAV_LINKS } from "@/components/navigation/nav-links.constants"; import { ThemedFullLogo } from "@/components/navigation/themed-full-logo"; import { Button } from "@/components/ui/button"; @@ -58,7 +58,7 @@ export function MobileNav() { diff --git a/components/navigation/mobile-nav-link.tsx b/components/navigation/mobile-navlink.tsx similarity index 100% rename from components/navigation/mobile-nav-link.tsx rename to components/navigation/mobile-navlink.tsx diff --git a/components/navigation/mobile-top-bar.tsx b/components/navigation/mobile-topbar.tsx similarity index 100% rename from components/navigation/mobile-top-bar.tsx rename to components/navigation/mobile-topbar.tsx diff --git a/components/right-sidebar/question-link.tsx b/components/right-sidebar/question-link.tsx new file mode 100644 index 0000000..36d4490 --- /dev/null +++ b/components/right-sidebar/question-link.tsx @@ -0,0 +1,21 @@ +import { ChevronRight } from "lucide-react"; +import Link from "next/link"; + +type QuestionLinkProps = { + id: string; + title: string; +}; + +export function QuestionLink({ id, title }: QuestionLinkProps) { + return ( + + + {title} + + + + ); +} diff --git a/components/navigation/right-sidebar.tsx b/components/right-sidebar/right-sidebar.tsx similarity index 57% rename from components/navigation/right-sidebar.tsx rename to components/right-sidebar/right-sidebar.tsx index 50f8aed..3acd881 100644 --- a/components/navigation/right-sidebar.tsx +++ b/components/right-sidebar/right-sidebar.tsx @@ -1,15 +1,23 @@ +import { QuestionLink } from "@/components/right-sidebar/question-link"; +import { TagLink } from "@/components/right-sidebar/tag-link"; import { Sidebar, SidebarContent, SidebarGroup, SidebarGroupContent, } from "@/components/ui/sidebar"; -import { Skeleton } from "@/components/ui/skeleton"; +import { getTopQuestions } from "@/lib/data/questions"; +import { getPopularTags } from "@/lib/data/tags"; /** Asymmetric padding: more on left, less on right (scrollbar side), reduced bottom */ const GROUP_PADDING = "pt-6 pb-2 pl-6 pr-3"; -export function RightSidebar() { +export async function RightSidebar() { + const [topQuestions, popularTags] = await Promise.all([ + getTopQuestions(5), + getPopularTags(5), + ]); + return (