Graphics Library Management & Builder Integration

Full graphics management system with database-backed CRUD, category organisation, S3 file uploads, searchable data table, and live integration into the uniform builder's library tab with search and category filtering.

Overview

A complete graphics and logos management module that replaces the placeholder library tabs with a fully functional, database-backed asset system. Users can upload, organise, and manage graphic assets (team logos, sponsor graphics, badges) through a dedicated management section, then browse and add them to uniform designs directly from the builder.

Features

Graphics Management Pages (/home/assets/graphics)

  • Data Table — Paginated, searchable table of all graphics with thumbnail preview, name, category, format, and status columns
  • Create / Edit Forms — Drag-and-drop file upload to S3, auto-generated code from name, category assignment, tags, sort order, and active toggle
  • Category Manager — Dialog-based CRUD for creating, editing, and deleting graphic categories with slug auto-generation
  • Filtering — Server-side filtering by category, file format, and active status with URL-based search params
  • Soft Delete / Restore — Graphics and categories support soft-delete with restore capability via database functions

Database Schema

  • graphic_categories — User-defined categories with name, slug, description, sort order, active flag, and soft-delete
  • graphics — Assets with name, unique code, category FK, S3 file URL, format, dimensions, tags (array), sort order, and soft-delete
  • RLS Policies — Authenticated users can read all active records; write operations restricted to creator or super admins
  • Indexes — Optimised queries on slug, code, category, format, active status, tags (GIN), and soft-delete filter
  • Functionssoft_delete_graphic, restore_graphic, soft_delete_graphic_category, restore_graphic_category

Builder Library Integration

  • Library Tab — The builder's graphics step "Library" tab now shows a live browsable grid of all active graphics from the database
  • Search & Filter — Client-side search by name/code and category dropdown filter within the builder
  • One-Click Add — Click any graphic to instantly add it to the canvas with auto-detected dimensions (px → mm conversion)
  • Loading & Empty States — Spinner during fetch, helpful empty-state message pointing to the management section

Shared Upload Hook

  • useS3Upload refactored from builder/_lib/hooks/ to ~/lib/hooks/ for reuse across both the builder and the graphics management form
  • WebP Support — Added image/webp to accepted MIME types in both the upload API route and the builder's format mapping
  • Sidebar Link — "Logos & Graphics" entry added under Assets in the personal account navigation
  • i18n Namespace — New graphics namespace with full translation coverage for the management UI (form labels, table headers, actions, errors, categories)
  • Path Configgraphics, graphicsNew, and graphicDetail routes registered in paths.config.ts

Technical Details

Architecture

  • Server ActionscreateGraphicAction, updateGraphicAction, deleteGraphicAction, restoreGraphicAction plus matching category actions, all using enhanceAction with Zod validation and auth
  • Service LayerGraphicService and GraphicCategoryService classes handle Supabase queries with pagination, filtering, code/slug uniqueness checks, and category joins
  • Zod SchemasCreateGraphicSchema, UpdateGraphicSchema, DeleteGraphicSchema, RestoreGraphicSchema (and category equivalents) for input validation
  • Builder HookuseGraphicsLibrary uses React Query (@tanstack/react-query) with 5-minute stale time to fetch graphics with joined category data

File Structure

assets/graphics/
├── page.tsx                          # List page with data table
├── new/page.tsx                      # Create form page
├── [id]/page.tsx                     # Edit form page
├── _components/
│   ├── graphics-data-table.tsx       # Paginated table with filters
│   ├── graphic-form.tsx              # Create/edit form with S3 upload
│   └── graphic-category-manager.tsx  # Category CRUD dialog
└── _lib/
    ├── schemas/
    │   ├── graphic.schema.ts         # Zod schemas + types
    │   └── graphic-category.schema.ts
    └── server/
        ├── server-actions.ts         # Enhanced server actions
        ├── graphic.service.ts        # Database service
        └── graphic-category.service.ts

Data Flow

  1. Admin uploads a graphic via the management form → S3 pre-signed URL → stored in graphics table
  2. Builder loads the library tab → useGraphicsLibrary fetches active graphics with category join via React Query
  3. User searches/filters and clicks a graphic → handleAddFromLibrary maps DB fields to builder's GraphicItem shape and appends to the form field array