Quotes v2.0, Brand Templates & Admin Profile Actions

Quotes panel in the builder Quick Actions with inline list and detail views, automatic screenshot capture (front, back, 2D canvas) on review with S3 upload, brand template apply workflow, and admin profile dropdown with role-based actions.

Overview

This release delivers three major improvements: the Quotes v2.0 system with an inline panel inside the builder, automatic screenshot capture for quote submissions, and enhanced admin profile dropdown logic for role-based navigation and actions.

Quotes v2.0 — Builder Quick Actions Panel

Inline Quotes Panel

A new "My Quotes" button in the builder sidebar Quick Actions opens a panel in the 1/3 container slot (same slot used by the Brand Template panel and Builder Steps). The panel lets authenticated users browse and review their quotes without leaving the builder.

FeatureDetail
List viewShows quote number, status badge, sport, product name, date, price, and preview thumbnail
Detail viewDrill-down with product card, colors, sizes, customer info, shipping, notes, and timeline
SearchClient-side + server-side filtering by quote number, sport, or product name
Auth-gatedButton only renders when user is authenticated
Mutual exclusivityOpening Quotes closes Brand Template panel, and vice versa

Architecture

ComponentPurpose
QuotesPanelContextManages panel open/close state and selected quote for detail view
QuotesPanelProviderWraps the builder layout (alongside BrandTemplateProvider)
QuotesPanelContainer with header, close button, list/detail routing
QuotesPanelListFetches quotes via fetchQuotesForPanelAction, renders list
QuotesPanelDetailCompact stacked card layout for narrow panel width
QuotesPanelButtonQuick Action button with active state indicator
fetchQuotesForPanelActionServer action using enhanceAction + existing QuoteService

Data Flow

  1. User clicks "My Quotes" in Quick Actions
  2. QuotesPanelContext toggles isQuotesPanelOpen
  3. BuilderLayout renders QuotesPanel in the 1/3 slot (instead of steps or brand panel)
  4. Panel fetches quotes via server action (RLS-scoped to user's account)
  5. Click a quote → inline detail view with back button

Automatic Screenshot Capture

Review Step Previews

When the user reaches the Review step, three screenshots are automatically captured and displayed in a preview grid:

ScreenshotMethodSource
Front (3D)Reset camera view → capture WebGL canvascapture3DScreenshot() via CameraControlsContext
Back (3D)Rotate camera to Math.PI → capturerotateTo() + capture3DScreenshot()
2D CanvasDirect fabric canvas exportget2DDataUrl() via CanvasTextureContext

Capture Sequence

  1. useBuilderScreenshots hook runs on Review step mount
  2. Captures 2D canvas first (always mounted, even in 3D mode)
  3. Switches to 3D mode if needed, resets view, captures front
  4. Rotates to back, captures back
  5. Restores original view mode
  6. Displays 3 thumbnails in a grid-cols-3 layout with loading spinners

S3 Upload on Submission

When the user submits a quote:

  1. QuoteFormWizard converts data URLs to File objects via dataUrlToFile()
  2. Uploads each to S3 screenshots/ folder using useS3Upload (pre-signed URLs)
  3. Passes public URLs to submitQuoteAction
  4. Server action stores URLs in preview_front_url, preview_back_url, and canva_2d columns

Context Changes

Both CameraControlsProvider and CanvasTextureProvider were hoisted from BuilderCanvasPanel up to BuilderLayout so that both the steps panel (Review step) and the canvas panel share the same context instances.

ContextNew Methods
CameraControlsContextset3DCanvasElement(), rotateTo(), capture3DScreenshot(), gl3DCanvasRef
CanvasTextureContextget2DDataUrl() — synchronous fabric canvas export
Builder3DSceneCanvasRegistrar component registers gl.domElement on mount

Brand Template Apply Workflow

The Apply Brand Template feature allows users to search for a school or organization brand and apply its colors and logo to the current design in one click.

FeatureDetail
Search panelInstant search by school name or customer number
Color mappingBrand primary/secondary → builder color fields; additional colors → accent slots
Logo injectionPrimary logo added to graphics.items as a brand asset
Confirmation dialogPreview of colors and logo before applying
Active indicatorSidebar button shows "Brand: {name}" when template is applied
Mutual exclusivityOpening brand panel closes quotes panel

Admin Profile Dropdown — Role-Based Actions

The personal account dropdown now adapts its menu items based on the user's role, providing appropriate navigation and actions for each access level.

Visibility Rules

Menu ItemRoles
HomeAll authenticated users
ChangelogAdmin, designer, super-admin (hidden for member, sales-rep)
Super AdminSuper-admin only
Sign OutAll authenticated users
Theme ToggleAll users

Implementation

  • ProfileAccountDropdownContainer resolves the effective role (super-admin → admin fallback)
  • PersonalAccountDropdown receives showChangelog and showAdminLink boolean props
  • Role check uses app_metadata.role for super-admin detection, workspace role for team roles
  • Navigation config (personal-account-navigation.config.tsx) filters sidebar routes by role

Review Step UX Improvements

  • Sticky CTA button — "Request a Quote" uses sticky bottom-0 to stay pinned at the bottom of the scroll area, always visible above the Previous/Next navigation
  • Screenshot previews — 3-column grid with loading spinners during capture, labels for Front / Back / Print File

Files Changed

New Files

FilePurpose
builder/_lib/context/quotes-panel-context.tsxQuotes panel state management
builder/_lib/server/fetch-quotes-panel.action.tsServer action for panel data
builder/_components/quotes-panel/*Panel, list, and detail components
builder/_lib/hooks/use-builder-screenshots.tsScreenshot capture orchestration hook

Modified Files

FileChange
builder/_lib/context/camera-controls-context.tsxAdded 3D canvas ref, rotateTo, capture3DScreenshot
builder/_lib/context/canvas-texture-context.tsxAdded get2DDataUrl()
builder/_components/canvas/3d/builder-3d-scene.tsxAdded CanvasRegistrar for WebGL canvas registration
builder/_components/canvas/builder-canvas-panel.tsxRemoved providers (hoisted to layout)
builder/_components/layout/builder-layout.tsxHoisted providers, added quotes panel rendering
builder/_components/layout/builder-sidebar.tsxAdded Quotes button, mutual exclusivity logic
builder/_components/steps/review-step.tsxScreenshot previews, sticky CTA button
builder/_components/steps/quote-form/quote-form-wizard.tsxS3 screenshot upload on submit
builder/_lib/server/submit-quote.action.tsPreview URL fields in schema and insert
quotes/_lib/schemas/quote.schema.tsAdded canva_2d to Quote type
(uniform-builder)/layout.tsxWrapped with QuotesPanelProvider

Database Dependencies

  • quotes table — existing columns preview_front_url, preview_back_url now populated; new column canva_2d for 2D canvas screenshot URL
  • S3 bucket asb-sports-assetsscreenshots/ folder for quote preview images