Feature Owner: Jethro Magdaleno Lagmay
Module: White Labeling
Priority: High
Sprint: #12
Date: July 2, 2026
EXECUTIVE SUMMARY
What is this feature? A White Labeling engine that allows administrators to dynamically customize the platform's visual identity. It includes a comprehensive 20-point UI theme customizer (colors for navigation, typography, buttons, etc.) and a logo upload utility.
Why does it matter? It eliminates the need for hardcoded styling and developer intervention every time a brand update is required. Organizations can instantly align the platform's look and feel with their corporate identity directly from the admin dashboard.
What’s the MVP scope? The MVP is restricted to Super Admins applying global branding across the entire platform. The backend and state management logic includes foundational support for Agency Admins (organization-specific overrides), but this is strictly reserved for a future release.
1. USER PAIN POINT & SOLUTION
Current State (Without Feature) The application's theme and logo are statically defined in the codebase. Any branding changes require a developer to update the repository, open a pull request, and trigger a deployment.
Pain Point
Emotional: Admins feel restricted by the lack of customization and frustrated by the turnaround time for simple visual updates.
Functional: The platform cannot be easily visually adapted for white-label enterprise clients.
Business Impact: Bottlenecks in onboarding enterprise clients who demand brand consistency.
Future State (With Feature) Super Admins navigate to the Branding settings, upload a logo, use a color picker to adjust the UI theme, and save. The player updates instantly across the platform.
Marketing Hook "Make the platform your own in seconds with our complete white-label branding engine."
2. 4D FRAMEWORK MAPPING
Diagnose: The platform needs a dynamic, zero-code way to inject custom CSS variables/themes and logos into the UI.
Design: A three-tab interface (
BrandingTabs) containing Email Settings, Logo Upload, and a Theme Customizer.Develop: Implemented via a Next.js App Router API, React Context (
BrandingContext) for global state, Supabase Storage for assets, andlocalStoragefor immediate client-side hydration.Deliver: A seamless admin UI that instantly updates the player experience without flashing unstyled content.
3. USER FLOWS
Entry Point Admin Dashboard -> Settings -> Branding.
Success Criteria
Logo is uploaded and stored securely.
Theme colors are saved to the database.
The Player successfully reads the updated theme and applies it on reload.
Main Flow (Happy Path)
Admin opens the Branding tabs.
Admin uploads a
.pngor.svglogo.Admin adjusts the "Primary Button" color in the Theme tab.
Admin clicks Save.
BrandingContextinstantly updates local state andlocalStorage.API successfully commits the JSON payload and logo URL to the
branding_detailstable in Supabase.
Edge Cases
API Failure: If the API fails to fetch on initial load, the system falls back to
localStorage.Missing Theme Keys: If a specific color key is deleted or missing,
createDefaultTheme()provides a safe fallback.Network Loss During Upload: Storage upload fails; UI alerts the user and reverts the preview.
Decision Points
Is the user a Super Admin? Show all tabs.
(Future) Is the user an Agency Admin? Hide the Email tab and apply changes only to their specific agency tenant.
4. INFORMATION ARCHITECTURE
Primary Information (Always visible)
Logo preview image.
Core color pickers (Primary buttons, Backgrounds, Text).
Secondary Information
SMTP Email configuration settings (restricted to Super Admins).
Secondary/Hover color states.
Tertiary Information (Hidden until needed)
Error boundaries and upload failure toasts.
Actions
Primary CTA: Save Branding Changes.
Secondary Actions: Upload Logo, Delete Logo, Test SMTP Connection.
5. WIREFRAMES
N/A - Developed directly based on standard UI component library (shadcn/ui).
6. WIREFLOWS
N/A
7. PROTOTYPE
Already synced in the development server.
8. BACKEND SCHEMA
Database Tables
branding_detailsid(uuid, Primary Key)created_at(timestamptz)updated_at(timestamptz)color_theme(jsonb) — Handles all the colors for the different parts of the UI (primary, hover, backgrounds, typography, etc.).logo(text) — Stores the public URL string for the uploaded logo.agency_id(uuid) — Identifier for future multi-tenant organization scoping.
Indexes
Index on
agency_idto ensure performant queries when querying specific tenant themes during the future agency rollout.
Constraints
color_thememust be a valid JSONB object.logomust be a valid text string (URL).
RLS Policies
SELECT: Public (or authenticated platform users) can read the branding payload to hydrate the client-side context.UPDATE/INSERT: Restricted to users with super admin privileges (for platform-wide updates) or authorized agency admins whose ID matches theagency_id.
9. API ENDPOINTS
Endpoint 1: Get Platform Branding
Path:
GET /api/platform/brandingPurpose: Fetches the global branding configuration from the
branding_detailstable.Response:
JSON
{"data": {"logo": "https://storage.url/logo.png","color_theme": {"primaryButtonBg": "#FF5733","topNavBg": "#111111"}}}
Endpoint 2: Get Agency Branding (Future Scope)
Path:
GET /api/agency/brandingPurpose: Fetches organization-specific branding overrides from
branding_detailsby matching the user's associatedagency_id.Response: Identical schema to Endpoint 1, returning the agency's specific UI overrides.
Endpoint 3: Update Branding
Path:
PUT/POST /api/platform/branding(and/api/agency/branding)Purpose: Updates the
logoandcolor_themefields in thebranding_detailstable. Updates theupdated_attimestamp.Payload:
JSON
{"logo": "https://storage.url/new-logo.png","color_theme": {"topNavBg": "#000000","primaryButtonBg": "#4F46E5"}}
10. DATA REQUIREMENTS
Frontend Needs
A 20-key JSON object mapping specific UI elements to hex codes fetched from the
color_themecolumn.A fully qualified public URL for the logo image fetched from the
logocolumn.
API Calls Frontend Will Make
fetchBrandingData()triggers onBrandingProvidermount.
Caching Strategy
Critical: To avoid the "flash of unstyled content" (FOUC),
BrandingContextsynchronously reads fromwindow.localStorage(branding_themeandbranding_logo_url) before the API request completes.The API response silently overwrites
localStorageif changes occurred on another device.
11. PERFORMANCE CONSIDERATIONS
Database Optimization: Fetching the platform theme is a single row read from
branding_details. Ensure theagency_idcolumn is indexed for performant multi-tenant queries when the Agency Admin feature is rolled out.Caching Strategy: Client-side
localStoragecompletely eliminates database latency for the end-user rendering the player.API Response Time: Expected
< 100msas it requires minimal data joining. Supabase Edge Functions could be utilized if latency becomes an issue globally.
12. SECURITY & AUTHORIZATION
Who can access this feature? Super Admins only.
Authorization Logic The UI component BrandingTabs accepts a hideTheme and hideEmail prop based on user role resolution higher in the component tree. The backend API must verify the session JWT contains Super Admin claims before accepting PUT/POST requests.
Data Validation
Uploaded files must be verified as standard image MIME types (e.g.,
image/png,image/jpeg,image/svg+xml).Theme values should be sanitized to ensure they are valid hex codes or CSS variables to prevent CSS injection attacks.
13. ERROR HANDLING
API Down: If
/api/platform/brandingreturns a 500, the context gracefully falls back tolocalStorageorcreateDefaultTheme().Corrupted LocalStorage: The frontend includes a
try/catchblock aroundJSON.parse(stored). If it fails, it defaults tonulland waits for the API.Invalid Image Upload: Supabase Storage bucket restrictions will reject non-image files; UI displays a toast notification to the Admin.
14. TESTING CHECKLIST
Happy Path
[ ] Super Admin uploads logo -> displays in Player.
[ ] Super Admin changes
primaryButtonBg-> all primary buttons update.[ ] Refreshing the page loads the theme instantly via
localStorage.
Edge Cases
[ ] Admin deletes the logo completely -> falls back to default text or empty state without broken image icon.
[ ] Simulate slow 3G network -> ensure
localStoragetheme applies immediately while API loads in background.[ ] Clear
localStorage-> ensure it fetches from API and successfully rebuilds the local cache.
15. OPEN QUESTIONS
What are the exact Supabase bucket policies for the logo uploads (e.g., size limits)?
Are we enforcing an aspect ratio on the logo upload to prevent the Top Nav from breaking visually?
16. OUT OF SCOPE
Agency Admin Branding: The backend logic is present (
preferAgency), but the UI rollout and permission enforcement for specific sub-organizations is slated for a future sprint.Layout Changes: This feature handles CSS colors and one image asset; it does not support changing the physical layout of the player components.
17. SUCCESS METRICS
0 instances of "Flash of Unstyled Content" reported by end-users.
100% of global branding changes handled by Admins without developer intervention.
18. DEPENDENCIES
This feature depends on:
Supabase Storage (for logo hosting).
Supabase Database (for JSONB theme storage).
shadcn/ui Tabs component.
These features depend on this:
The overall Player UI (relies on
BrandingContextto render its stylesheet).
19. TIMELINE & OWNERSHIP
Implemented: Partially implemented
Owner: Jethro Magdaleno Lagmay
Document Version - 1.0.2
Changelog
1.0.0 - Initial document
1.0.1 - Added changelog
1.0.2 - Made edits for backend documentation