Skip to content

feat: DESIRE tier — dark mode, shadcn primitives, Result type, logger, DX scripts#8

Open
bryansayler wants to merge 9 commits into
mainfrom
claude/desire-features
Open

feat: DESIRE tier — dark mode, shadcn primitives, Result type, logger, DX scripts#8
bryansayler wants to merge 9 commits into
mainfrom
claude/desire-features

Conversation

@bryansayler
Copy link
Copy Markdown
Contributor

Summary

DESIRE tier from the original plan. Adds the polish and DX features that make the scaffold feel complete rather than just functional.

Changes

Dark mode

  • next-themes with ThemeProvider in providers.tsx (attribute="class", defaultTheme="system")
  • ThemeToggle component — Sun/Moon icon button using lucide-react
  • globals.css already had full .dark OKLCH vars; this activates them

shadcn/ui primitives

  • Card (+ Header, Title, Description, Content, Footer)
  • Input (text field with ring focus styles)
  • Label (via @radix-ui/react-label + CVA)
  • Separator (via @radix-ui/react-separator, horizontal/vertical)
  • Sonner Toaster (theme-aware via next-themes)

Hand-written to match shadcn new-york v4 patterns (CLI registry was unreachable).

lib/result.ts

Lightweight Result<T, E> union type for explicit error handling:

  • ok(), err() constructors
  • tryCatch() / tryCatchAsync() wrappers
  • unwrap(), unwrapOr() extractors
  • map(), mapErr() transformers
  • 10 unit tests covering all paths

lib/logger.ts

Structured pino logger with ISO timestamps. JSON output in prod, readable in dev. LOG_LEVEL env var for verbosity.

DX scripts

CLAUDE.md

Updated directory tree, component list, and commands table to reflect all additions.

Test plan

  • bun run validate passes (lint + type-check + 12 unit tests + build)
  • All commits pass Lefthook hooks + commitlint
  • CI validate + e2e green
  • Manual: bun run dev → import <ThemeToggle /> in layout → toggle dark/light
  • Manual: import { toast } from 'sonner'toast('hello') renders themed toast

Notes for reviewer

https://claude.ai/code/session_012Mh4xLVoCPRt2pNacxpPtH


Generated by Claude Code

claude added 7 commits May 19, 2026 15:17
globals.css already defined full .dark OKLCH color vars but had no
way to activate them. Adds next-themes with:

- ThemeProvider in providers.tsx (attribute="class", defaultTheme="system")
- ThemeToggle component using Sun/Moon icons from lucide-react
- Renders as a ghost Button; toggles between light/dark on click

Drop <ThemeToggle /> anywhere in a layout to enable the toggle. The
system preference is respected by default.

https://claude.ai/code/session_012Mh4xLVoCPRt2pNacxpPtH
Adds the five shadcn/ui primitives most commonly needed for real
UI work. Hand-written to match shadcn new-york v4 patterns since
the shadcn CLI registry is unreachable in this environment.

- Card (+ Header, Title, Description, Content, Footer)
- Input (text field with ring focus styles)
- Label (via @radix-ui/react-label + CVA)
- Separator (via @radix-ui/react-separator, h/v)
- Sonner Toaster (theme-aware via next-themes)

https://claude.ai/code/session_012Mh4xLVoCPRt2pNacxpPtH
Lightweight Result<T, E> union type for representing success/failure
without exceptions. Provides:

- ok(), err() constructors
- tryCatch() / tryCatchAsync() wrappers
- unwrap(), unwrapOr() extractors
- map(), mapErr() transformers

10 unit tests covering all paths. Use for DB operations, API calls,
and anywhere "this might fail" needs to be explicit in the type.

https://claude.ai/code/session_012Mh4xLVoCPRt2pNacxpPtH
Single shared logger instance with ISO timestamps and structured
JSON output. Uses pino/file transport in development for readable
stdout; raw JSON in production for log aggregators.

Set LOG_LEVEL env var to control verbosity (default: info).

import { logger } from "@/lib/logger";
logger.info({ userId }, "user signed in");

https://claude.ai/code/session_012Mh4xLVoCPRt2pNacxpPtH
- db:reset: wipes local.db and re-runs migrations (clean slate)
- db:seed: runs scripts/seed.ts to populate test users

Seed script inserts two demo users (admin@quirk.systems and
dev@quirk.systems). Extend with additional tables as schema grows.
Only for local development — never run against production.

https://claude.ai/code/session_012Mh4xLVoCPRt2pNacxpPtH
Adds logger.ts, result.ts, theme-toggle.tsx, expanded shadcn ui list,
ThemeProvider, db:reset, and db:seed to the directory structure and
commands tables.

https://claude.ai/code/session_012Mh4xLVoCPRt2pNacxpPtH
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 40eb5d35f0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/result.ts Outdated
}
}

export function unwrap<T>(result: Result<T>): T {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Accept generic error variants in unwrap helper

Result is defined with a generic error type and this module already produces non-Error variants (for example via err("...") or mapErr), but unwrap only accepts Result<T> which defaults the error side to Error. That makes unwrap unusable for valid Result<T, E> values where E is not Error, breaking composability of the API introduced in this commit; the signature should carry E through (and unwrapOr has the same issue).

Useful? React with 👍 / 👎.

claude added 2 commits May 19, 2026 15:32
Both helpers were typed as Result<T> which defaults E to Error,
making them unusable with Result<T, string> or any custom error
variant. Now carry E through so the full Result<T, E> API composes.

https://claude.ai/code/session_012Mh4xLVoCPRt2pNacxpPtH
The scaffold's first impression is no longer a dead <h1>. The home
page now showcases what's configured:

- ThemeToggle wired (dark mode works out of the box)
- Sonner Toaster mounted in layout (toast() calls render immediately)
- Four Card tiles summarizing App Router, Database, Testing, and
  Tooling capabilities
- GitHub + Next.js Docs link buttons

Adds src/middleware.ts as a passthrough skeleton with PUBLIC_PATHS
set and a TODO for Auth.js integration once PR #6 merges. Matcher
excludes static assets and _next paths.

Updates the page test to match the new description text.

https://claude.ai/code/session_012Mh4xLVoCPRt2pNacxpPtH
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants