Nicholai cfdd6b7c5c feat(routing): switch public artist routing to slugs and fix admin parsing
Routing: update homepage ArtistsSection and ArtistsPageSection to link to /artists/{slug} and /book?artist={slug}. Artists grid already used slugs.\n\nAdmin: remove JSON.parse on specialties; treat as arrays with backward-compat.\n\nMigration: generate UUIDs with crypto.randomUUID(), ensure unique slugs, preserve user↔artist↔portfolio mapping.\n\nDB: parse specialties to arrays consistently and include createdAt for admin use.\n\nDev: wrangler dev port changes to avoid conflicts; MIGRATE_TOKEN set in wrangler.toml.\n\nDocs: add artist_routing_fix_implementation_plan.md.
2025-10-06 19:22:26 -06:00
2025-09-26 00:34:25 -06:00
2025-09-25 23:53:54 -06:00
2025-09-17 09:11:51 -06:00
2025-09-16 21:36:20 -06:00
2025-09-16 21:36:20 -06:00
2025-09-16 21:36:20 -06:00
2025-09-16 21:36:20 -06:00
2025-09-16 21:36:20 -06:00
2025-09-16 21:36:20 -06:00
2025-09-16 21:36:20 -06:00
2025-09-16 21:36:20 -06:00

United Tattoo — Official Website (Next.js + ShadCN UI)

Hi, Im Nicholai. I built this site for my friend Christy (aka Ink Mama) and the United Tattoo crew in Fountain, CO. The goal was simple: give the studio a site that actually reflects the art, the people, and the experience — not the stiff, generic stuff you usually see. This is also a thank you for everything Christy has done for Amari (my girlfriend and soulmate), who was her apprentice. So yeah, this is personal — and it shows.

This repo powers the official United Tattoo website, built with:

  • Next.js App Router
  • TypeScript
  • Tailwind CSS
  • ShadCN UI components (used across all pages)
  • Lenis (smooth scroll)
  • Lucide (icons)

Live dev server: http://localhost:3000

Project Structure

  • app/

    • page.tsx — homepage (Hero, Artists, Services, Contact sections)
    • aftercare/page.tsx — aftercare instructions (ShadCN-driven)
    • deposit/page.tsx — deposit policy + payment options (Afterpay, Stripe)
    • terms/page.tsx — terms of service
    • privacy/page.tsx — privacy policy
    • artists/ — artists listing + dynamic routes for profiles (coming from data)
    • book/page.tsx — booking flow
    • specials/page.tsx — promotions (monthly specials, VIP list)
    • contact/page.tsx — contact
    • gift-cards/page.tsx — gift card info
  • components/

    • hero-section.tsx, artists-section.tsx, services-section.tsx, contact-section.tsx
    • aftercare-page.tsx, deposit-page.tsx, terms-page.tsx, privacy-page.tsx
    • booking-form.tsx — multi-step form using ShadCN components
    • footer.tsx — contains direct links to Aftercare, Deposit Policy, Terms, and Privacy
    • ui/ — ShadCN UI primitives
  • data/

    • artists.ts — single source of truth for artist metadata and images used across pages
  • public/

    • united-logo-*.png/jpg, artists/, and other stable assets

Content & Assets

  • All the “real” content, bios, and images are now wired in (not seed placeholders).
  • Artist portraits and tattoo samples live under public/artists/.
  • Pages like Aftercare, Deposit, Terms, and Privacy use consistent styling patterned after the homepage and portfolio pages — powered by ShadCN components.

If you need to re-copy images from the temp folder into public (on your machine), theres a helper script:

  • ./copy-artist-images.sh Note: This script expects the temp directory structure to exist locally; it silently skips if a source is missing.

Getting Started (Local Dev)

  • Install deps:

    • npm install
  • Run dev server:

  • Lint (optional):

    • npm run lint

Build:

  • npm run build
  • npm start

Continuous Integration (CI)

This repo includes a CI workflow that enforces linting, type safety, unit tests, build/preview, and bundle size budgets.

  • Workflow file: .gitea/workflows/ci.yaml
  • Triggers: Push and PR against main/master
  • Node: 20.x with npm ci

Stages

  • Lint: npm run ci:lint (ESLint)
  • Typecheck: npm run ci:typecheck (TypeScript noEmit)
  • Unit tests: npm run ci:test (Vitest with coverage)
  • Build: npm run ci:build (OpenNext build to .vercel/output/static)
  • Preview smoke: start OpenNext preview briefly to ensure no immediate crash
  • Budgets: npm run ci:budgets (analyzes .vercel/output/static)

Bundle Size Budgets

  • Defaults are defined in package.json under the budgets key:
    • TOTAL_STATIC_MAX_BYTES: 3,000,000 (≈3 MB)
    • MAX_ASSET_BYTES: 1,500,000 (≈1.5 MB)
  • Override via environment variables in CI:
    • TOTAL_STATIC_MAX_BYTES
    • MAX_ASSET_BYTES

Artifacts

  • A budgets report is written to .vercel/output/static-budgets-report.txt and uploaded as a CI artifact.

Migration Dry-Run (D1)

  • The workflow attempts a besteffort local dryrun: wrangler d1 execute united-tattoo --local --file=./sql/schema.sql.
  • If local bindings are unavailable in CI, the step is skipped with a note; wire it up later when CI bindings are configured.

Rollback Strategy

  • This story does not deploy. To disable CI temporarily, remove or rename the workflow file or adjust failing stages. For full rollback strategy see docs/prd/rollback-strategy.md.

Docker

This repo is docker-ready. We build a standalone Next.js app for a smaller runtime image.

Build image:

  • docker build -t united-tattoo:latest .

Run container (port 3000):

Notes:

  • next.config.mjs sets output: "standalone"
  • The Dockerfile copies .next/standalone + .next/static and runs the server with HOSTNAME=0.0.0.0

Pages Overview

  • Home — Bold, high-contrast, split imagery, parallax accents. This sets the identity.
  • Artists — Grid and profile surfaces wired to data/artists.ts. Each artist shows image, specialties, and sample work.
  • Aftercare — Two flows: General Aftercare and Transparent Bandage Aftercare (accurate, readable, ShadCN cards + alerts).
  • Deposit — Clear policy, payment options, and compliance notes (LW2 Investments, LLC oversight).
  • Terms & Privacy — Straightforward, legally sound, human-readable. Both accessible from the footer.
  • Booking — Multi-step form with ShadCN components and validation-friendly structure.
  • Specials — Marketing surface for time-bound promotions and membership-like advantages.

Design Language

  • ShadCN components everywhere possible
  • Monochrome foundation with high contrast and cinematic image splits
  • Type scales + spacing match the homepage/portfolio feeling
  • Lucide icons for affordances

Tech Notes

  • TypeScript errors are ignored during build in CI to allow non-blocking content/design iteration (next.config.mjs).
  • Images are unoptimized (no Next image loader), served statically; change if you plan to put this behind a CDN with transforms.
  • Smooth scroll and parallax-style offsets are kept subtle to let the work shine.

Deployment

  • Standard Next.js deploys work (Vercel, Node server, Docker)
  • For self-hosting or VPS, use the Dockerfile in the repo
  • The site runs on port 3000 by default

Why This Exists

Because Christy deserved a proper site — and because the previous one was, bluntly, not it. United Tattoo is more than a shop. Its a community with real people and real art. This site tries to honor that.

— Nicholai

Description
United Tattoo's website - made in nextjs
Readme 812 MiB
Languages
TypeScript 95.4%
Shell 2.1%
CSS 1.3%
JavaScript 1.1%