160 lines
6.2 KiB
Markdown
160 lines
6.2 KiB
Markdown
# United Tattoo — Official Website (Next.js + ShadCN UI)
|
||
|
||
Hi, I’m 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), there’s 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:
|
||
- npm run dev
|
||
- Open http://localhost:3000
|
||
|
||
- 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 best‑effort local dry‑run: `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):
|
||
- docker run --rm -p 3000:3000 -e PORT=3000 united-tattoo:latest
|
||
- Open http://localhost: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. It’s a community with real people and real art. This site tries to honor that.
|
||
|
||
— Nicholai
|