Overview
This release introduces the Locker module (save, manage, and share builder designs), a public design catalogue with category-driven browsing, SendGrid as a new mailer provider, a lazy 3D screenshot renderer for catalogue thumbnails, and several database/config improvements.
Locker Module — Saved Designs
Database
Migration 20260226120000_lockers.sql creates public.lockers:
| Column | Type | Purpose |
|---|---|---|
account_id | uuid FK | Owner (personal account) |
sport | text | Sport category |
product_slug | text | Product identifier |
config_data | jsonb | Full BuilderData snapshot |
name | text | Optional user label |
preview_front_url | text | Front preview image |
preview_back_url | text | Back preview image |
RLS policies restrict all operations to the owning account. Indexed on (account_id, updated_at DESC) for fast listing.
Builder Panel
LockerPanel slides into the builder's 1/3-width sidebar slot (same container as steps, brand templates, and quotes). Two views:
- LockerPanelList — paginated list of saved designs with preview thumbnails, sport badge, and relative timestamps. Supports delete with confirmation.
- LockerPanelDetail — inline drill-down showing full config preview, "Load into Builder" and "Get Share Link" actions.
Context is managed by LockerPanelContext (open/close state, selected locker, data fetching).
Server Actions
| Action | Purpose |
|---|---|
saveLockerAction | Insert or update a locker. Receives config data + preview URLs. |
fetchLockersPanelAction | Fetch current user's lockers for the panel (paginated, newest first). |
deleteLockerAction | Soft-delete a locker by ID (RLS-enforced ownership check). |
getLockerShareLinkAction | Creates a builder_shared_configs entry and returns a shareable builder URL. |
Dashboard Pages
Full admin-style CRUD under /home/lockers:
- Lockers list page — data table with search, sort, and bulk actions.
- Locker detail page — read-only view with config inspector and action buttons.
- Navigation entry added to
personal-account-navigation.config.tsx. - Translation namespace:
lockers.json(51 keys).
Design Catalogue — Public Browsing
Architecture
The catalogue lives under the (uniform-builder) route group and provides category-driven design discovery:
- Landing page (
page.tsx) — rendersCategoryGridshowing all sport categories with product counts. - Category designs page (
[category]/designs/page.tsx) — rendersDesignGridwith product × design combinations for a category.
Server Loader
designs-catalogue.loader.ts exposes loadDesignCombinations(category):
- Fetches active, enabled products in the category.
- Fetches active, showable designs whose
productsarray overlaps the product IDs. - Builds the cross-product: one
DesignComboper (product, design) pair.
Components
| Component | Purpose |
|---|---|
CategoryGrid | Card grid of sport categories with product counts and icons. |
DesignCard | Individual product/design combo card with lazy 3D screenshot, sport badge, and "Customize" CTA. |
DesignGrid | Responsive grid of DesignCard items with filtering support. |
TeamNameSearch | Autocomplete search for team names — filters catalogue results by team. |
Lazy Screenshot Renderer
use-lazy-screenshot.ts generates 3D preview thumbnails on-demand:
- Uses
IntersectionObserver— only renders when the card scrolls into view. - Spins up an offscreen Three.js renderer, loads the GLB model, applies the SVG texture + color material, and captures a PNG frame.
- Module-level LRU cache (100 entries max) prevents redundant renders across re-mounts.
- Returns
{ ref, imageUrl, isLoading, error }for simple integration into any card component.
SendGrid Mailer Provider
New package @kit/mailers/sendgrid implements the Mailer interface using the Twilio SendGrid Web API v3 (@sendgrid/mail).
- Registered in
packages/mailers/core/src/registry.tsunder thesendgridprovider enum. - Environment variable:
SENDGRID_API_KEY(validated at startup via Zod). - Set
MAILER_PROVIDER=sendgridto activate.
Sales Rep Improvements
- Sales Rep Grid (
sales-rep-grid.tsx) — visual grid display of available sales reps with headshots, name, and territory info. - Sign-up with Sales Rep Preview — during sign-up, shows a preview card of the matched sales rep (geo-search or brand template) before account creation.
- API Route (
/api/salesreps/geo-search) — public-facing proxy to Game One geo-search endpoint, used by the sign-up flow for real-time rep matching.
Database Migrations
| Migration | Description |
|---|---|
20260226120000_lockers | lockers table with RLS, indexes, and grants |
20260226140000_fix_products_update_rls | Fixes restrictive UPDATE RLS policy on products |
20260226150000_seed_designs_from_source | Seeds design rows from source data for catalogue population |
Server Actions Body Size Limit
Added serverActions.bodySizeLimit: '5mb' to next.config.mjs. The default 1 MB limit was causing 413 errors on the review step when base64 screenshot data + builder config exceeded the threshold.
Builder & Auth Tweaks
- Text step — text assignment improvements for element placement.
- Builder 3D scene — simplified render pipeline, removed unused material overrides in
model-with-materials.tsx. - Auth provider — extended
AuthProviderto propagate additional user metadata for downstream contexts. - Sentry config — updated client and server configs with refined sampling and environment settings.