Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog.


[0.5.0] — 2026-05-31

First commercial release.

Added

  • Contacts inbox (/admin/contacts): full-text search with 350 ms debounce (SQL ILIKE), unread/all filter via URL search params, pagination (20 per page), side panel with full message and mailto reply link, automatic read-marking on open; three responsive layouts — side-by-side on desktop (≥1200 px), overlay on tablet, full-screen on mobile
  • contact_submissions table with readAt nullable column; markContactAsRead server action
  • Overview dashboard: unread contacts KPI (highlighted in red when non-zero), recent submissions widget (5 latest), homepage completion progress bar
  • Admin sub-sections tab navigation pattern: synchronous layout with <XxxNav> client component, usePathname exact-match active state, loading.tsx per sub-route for streaming skeleton feedback
  • Sticky header on the contacts page (position: sticky)

Changed

  • Admin sidebar overhauled for two display modes: collapsible vertical sidebar on desktop (icon-only collapsed / icon + label expanded, toggle on hover or click), fixed bottom bar on mobile with a hamburger overlay; resize transitions suppressed via double rAF to prevent animation artifacts at breakpoint changes
  • Product detail pages: gallery pagination (6 items per page, ChevronLeft / ChevronRight); selected product and page restored from URL hash (#slug) on load
  • NavModal: link list paginated (4 links per page); page resets to 0 on each open
  • CTA section: ctaLabel prop replaced by a dedicated CtaContactButton component

Removed

  • Customer registration page (/register) — outside pre-MVP scope
  • Customer dashboard (/dashboard) — outside pre-MVP scope
  • Customer login path — /login is now restricted to admin accounts only

[0.4.0-beta] — 2026-05-26

Added

  • Normalized media schema: dedicated media and media_usage tables replace direct URL storage; all entities reference media via foreign keys; usage tracking blocks accidental deletion of referenced files
  • Gallery page (/admin/gallery): centralized media library with per-file usage indicator, media replacement, and deletion guard
  • Video thumbnails: server-side thumbnail generation on upload; thumbnail slideshow in media picker; discrete video badge on gallery grid items
  • Full-screen media modal in gallery with navigation and quick actions
  • Four color themes — Navy, Deep Forest, Obsidian, Bordeaux — defined in src/lib/themes.ts and applied globally via server-side CSS variable injection through a ThemeStyle component; no client-side JavaScript involved
  • Theme selection UI in the Brand admin tab
  • Testimonials section: CRUD with validation and drag-and-drop reordering
  • FAQ section: CRUD with validation and drag-and-drop reordering
  • SEO management: meta description and Open Graph image (admin tab)
  • Legal pages (/legal) with admin editor for business name, address, and legal email
  • Social media links management in footer settings
  • Admin customization restructured into 5 sub-sections with tab navigation (Homepage, Brand, SEO, Footer & Socials, Legal)
  • NavModal context for managing modal open/close state across components
  • Footer tagline and contact email made editable via admin
  • Favicon management merged into brand section; logo auto-falls back as favicon when no explicit favicon is set

Changed

  • Caching strategy replaced: unstable_cache directives removed, ISR with explicit revalidatePath calls on every mutation is now the single pattern throughout the codebase
  • MediaPicker refactored to operate on mediaId integers and typed Media objects instead of raw URLs; auto-detects image vs. video from file MIME type

Fixed

  • revalidatePath scope corrected across all mutation actions: branding, SEO, footer, and social links now invalidate at layout level ('layout' scope) to update all pages
  • Database connection settings tuned for serverless cold starts: session pooler (port 5432), max: 1, prepare: false
  • useActionState dependency array changed from [state.success] to [state] to handle repeated saves where success stays true

[0.3.0-beta] — 2026-04-29

Added

  • PostgreSQL database schema (Drizzle ORM): products_categories, products tables with slug, category FK, and position column
  • Admin panel layout with sidebar navigation
  • Category management: create, edit, delete (guarded by confirmation modal)
  • Product management: create, edit, delete per category
  • Supabase Auth integration: login page with session cookies; registration page (later removed in v0.5)
  • Admin authentication guard on all server actions via requireAdmin(); Row-Level Security policies enabled on all tables
  • /setup page: one-shot admin account creation protected by SETUP_TOKEN
  • Contact form: Zod validation, submission persisted to database, email notification sent via Resend
  • Supabase Storage integration: image and video upload handling
  • MediaPicker component: file library browser, upload, and preview
  • Brand identity section: logo upload with display in header, footer, and admin sidebar
  • Homepage sections management in admin: Hero, About, Products highlight, CTA
  • CategorySorter with drag-and-drop for selecting and ordering product highlight categories on the homepage
  • DeleteSectionButton component for removing optional sections
  • Enhanced homepage section previews in admin (product category badges, image thumbnails)
  • Admin overview page with dynamic data fetching
  • Video support in MediaPicker: hover preview, file type auto-detection
  • useActionState pattern established across all admin forms (React 19)
  • Rich Text Editor (MDXEditor) for long-form content fields

[0.2.0-beta] — 2026-04-20

Complete rewrite of the project in Next.js 16 (App Router, React 19, TypeScript strict).

Added

  • Static product catalog: category index and per-product detail pages at /products/[slug]
  • Homepage sections: hero with background media (image or video), about section, product grid, CTA with contact scroll-to-footer button
  • BackgroundMedia component supporting both image and video backgrounds
  • ViewportHeroWithText hero component with full-viewport layout
  • ProductCard and responsive product grid
  • NavModal for mobile navigation with dynamic product category links
  • Responsive header and footer
  • Login and registration pages (UI only at this stage)
  • Google Fonts integration

Changed

  • Architecture migrated from static HTML + vanilla JavaScript to a React component model with file-based routing

[0.1.0-alpha] — 2024-10-23

Original static website built as a real-world drums rental business (drums-please.fr). This version served as the founding use case and product knowledge base for what would later become the Stonecast template.

Added

  • Static HTML/CSS website with product catalog: acoustic drums, electronic drums, classical percussion, traditional percussion
  • Per-product detail page with interactive selector (radio inputs, JavaScript-driven display)
  • Contact section in footer
  • Responsive navigation with animated header and mobile menu
  • Background video on homepage
  • Login and registration forms with client-side JavaScript validation
  • Image optimization: thumbnail versions generated for all product photos