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.
| Feature | Detail |
|---|---|
| List view | Shows quote number, status badge, sport, product name, date, price, and preview thumbnail |
| Detail view | Drill-down with product card, colors, sizes, customer info, shipping, notes, and timeline |
| Search | Client-side + server-side filtering by quote number, sport, or product name |
| Auth-gated | Button only renders when user is authenticated |
| Mutual exclusivity | Opening Quotes closes Brand Template panel, and vice versa |
Architecture
| Component | Purpose |
|---|---|
QuotesPanelContext | Manages panel open/close state and selected quote for detail view |
QuotesPanelProvider | Wraps the builder layout (alongside BrandTemplateProvider) |
QuotesPanel | Container with header, close button, list/detail routing |
QuotesPanelList | Fetches quotes via fetchQuotesForPanelAction, renders list |
QuotesPanelDetail | Compact stacked card layout for narrow panel width |
QuotesPanelButton | Quick Action button with active state indicator |
fetchQuotesForPanelAction | Server action using enhanceAction + existing QuoteService |
Data Flow
- User clicks "My Quotes" in Quick Actions
QuotesPanelContexttogglesisQuotesPanelOpenBuilderLayoutrendersQuotesPanelin the 1/3 slot (instead of steps or brand panel)- Panel fetches quotes via server action (RLS-scoped to user's account)
- 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:
| Screenshot | Method | Source |
|---|---|---|
| Front (3D) | Reset camera view → capture WebGL canvas | capture3DScreenshot() via CameraControlsContext |
| Back (3D) | Rotate camera to Math.PI → capture | rotateTo() + capture3DScreenshot() |
| 2D Canvas | Direct fabric canvas export | get2DDataUrl() via CanvasTextureContext |
Capture Sequence
useBuilderScreenshotshook runs on Review step mount- Captures 2D canvas first (always mounted, even in 3D mode)
- Switches to 3D mode if needed, resets view, captures front
- Rotates to back, captures back
- Restores original view mode
- Displays 3 thumbnails in a
grid-cols-3layout with loading spinners
S3 Upload on Submission
When the user submits a quote:
QuoteFormWizardconverts data URLs toFileobjects viadataUrlToFile()- Uploads each to S3
screenshots/folder usinguseS3Upload(pre-signed URLs) - Passes public URLs to
submitQuoteAction - Server action stores URLs in
preview_front_url,preview_back_url, andcanva_2dcolumns
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.
| Context | New Methods |
|---|---|
CameraControlsContext | set3DCanvasElement(), rotateTo(), capture3DScreenshot(), gl3DCanvasRef |
CanvasTextureContext | get2DDataUrl() — synchronous fabric canvas export |
Builder3DScene | CanvasRegistrar 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.
| Feature | Detail |
|---|---|
| Search panel | Instant search by school name or customer number |
| Color mapping | Brand primary/secondary → builder color fields; additional colors → accent slots |
| Logo injection | Primary logo added to graphics.items as a brand asset |
| Confirmation dialog | Preview of colors and logo before applying |
| Active indicator | Sidebar button shows "Brand: {name}" when template is applied |
| Mutual exclusivity | Opening 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 Item | Roles |
|---|---|
| Home | All authenticated users |
| Changelog | Admin, designer, super-admin (hidden for member, sales-rep) |
| Super Admin | Super-admin only |
| Sign Out | All authenticated users |
| Theme Toggle | All users |
Implementation
ProfileAccountDropdownContainerresolves the effective role (super-admin → admin fallback)PersonalAccountDropdownreceivesshowChangelogandshowAdminLinkboolean props- Role check uses
app_metadata.rolefor super-admin detection, workspacerolefor 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-0to 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
| File | Purpose |
|---|---|
builder/_lib/context/quotes-panel-context.tsx | Quotes panel state management |
builder/_lib/server/fetch-quotes-panel.action.ts | Server action for panel data |
builder/_components/quotes-panel/* | Panel, list, and detail components |
builder/_lib/hooks/use-builder-screenshots.ts | Screenshot capture orchestration hook |
Modified Files
| File | Change |
|---|---|
builder/_lib/context/camera-controls-context.tsx | Added 3D canvas ref, rotateTo, capture3DScreenshot |
builder/_lib/context/canvas-texture-context.tsx | Added get2DDataUrl() |
builder/_components/canvas/3d/builder-3d-scene.tsx | Added CanvasRegistrar for WebGL canvas registration |
builder/_components/canvas/builder-canvas-panel.tsx | Removed providers (hoisted to layout) |
builder/_components/layout/builder-layout.tsx | Hoisted providers, added quotes panel rendering |
builder/_components/layout/builder-sidebar.tsx | Added Quotes button, mutual exclusivity logic |
builder/_components/steps/review-step.tsx | Screenshot previews, sticky CTA button |
builder/_components/steps/quote-form/quote-form-wizard.tsx | S3 screenshot upload on submit |
builder/_lib/server/submit-quote.action.ts | Preview URL fields in schema and insert |
quotes/_lib/schemas/quote.schema.ts | Added canva_2d to Quote type |
(uniform-builder)/layout.tsx | Wrapped with QuotesPanelProvider |
Database Dependencies
quotestable — existing columnspreview_front_url,preview_back_urlnow populated; new columncanva_2dfor 2D canvas screenshot URL- S3 bucket
asb-sports-assets—screenshots/folder for quote preview images