← Tous les designs

gauth-0002-library-programs-broadcasts-notes · frontend/src

Spec — Unified Program Library v2

Implementation spec for Program Library v2 (current).dc.html (design) and Program Library v2 - AntD code.dc.html (antd composition).

Audience: a developer or Claude Code working in RandomCoffee/randomcoffee, branch master, under frontend/src/.


1. What this feature is

Today the template library is a flat grid of use cases at frontend/src/pages/account/admin/campaigns/templates.tsx (UseCaseLibrary), reachable from the sidebar as Campaigns → Use Cases Library.

v2 turns it into a single unified library that serves two program types:

Both types live in one library, browsable along two independent axes:

AxisValuesSource today
Program typeAll types (default) · Coffee Connect · Mentoringdoes not exist yet — new field
CategoryOnboarding, Career, Cross-team, Remote, Social, Leadership, D&IuseCase.categories (already returned)

Everything else stays: creating from scratch, previewing before use, creating the campaign from a template.


2. What changes vs. the existing code

2.1 Keep as-is

These already work and v2 does not change their contract:

campaign:created:from-template, usecases:cancel:click, campaigns:add:own:campaign

2.2 Changes to existing files

**pages/account/admin/campaigns/templates.tsx**

tags. v2 replaces it with a left filter rail: a Menu mode="inline" for program type and a second Menu mode="inline" for category. The search moves into the library header, horizontally centered.

search + selected (categories) conditions.

colored Tag. The Button type="primary" block>Preview in the card footer is replaced by a Use template → action; preview becomes the whole-card click.

the "Start from scratch" row pinned above the grid.

**pages/account/admin/campaigns/template-modal.tsx**

SetupBlock / OptionsBlock on the left, Segmented optin/match + email preview on the right, footer [Alert, Back to programs, UpgradeButton]).

Mentoring add-on, the modal body is replaced by the add-on pitch and the footer's primary action becomes Unlock Mentoring instead of Use this program.

**layouts/sidebar.tsx** — no change. v2 lives entirely under the existing templates key.

2.3 New files to create

pages/account/admin/campaigns/library/
  index.tsx            # page shell: header (search) + filter rail + results
  filters.tsx          # ProgramTypeMenu + CategoryMenu
  template-card.tsx    # card with cover, type Tag, category Tag, actions
  start-choice.tsx     # "from scratch" vs "use a template" entry step
  locked-card.tsx      # greyscale cover + "Add-on" Badge.Ribbon + Unlock action
  unlock-modal.tsx     # Mentoring add-on upsell

3. Screens and their components

All eight screens are on the canvas in reading order. Component names below are the actual antd components used — see Program Library v2 - AntD code.dc.html for the exact composition.

① Programs list (context only)

Existing page. Entry point is the Create program primary Button in the page header. Wrap in <PageLayout title={gettext('Programs')} actions={[...]}> per layouts/page.tsx (Title level={3}).

② Start choice — "How do you want to start?"

New step shown when the user clicks Create program.

Elementantd
ProgressSteps size="small" — Start / Setup / Launch
Two optionsRow + Col span={12}, each a Card hoverable with cover and Card.Meta
Template countBadge.Ribbon text="12 templates" on the recommended card
Popular templatesRow + 3 × Col span={8} with small Cards

Left card → history.push('/account/${slug}/admin/campaigns/new') (existing route). Right card → the library (③).

③ Library — default view, all types

The core screen.

Regionantd
HeaderInput.Search allowClear centered, Button type="text" back/close
Type filterMenu mode="inline" — keys all (default) / coffee / mentoring
Category filterMenu mode="inline" — key cat-all default
Results barTypography.Text strong + count, Select sort (Most used / Recently added / A→Z)
From scratchAlert type="info" with action={<Button size="small">Create</Button>}
GridRow gutter + Col span={8} (xs=24 md=8 in the app), Card size="small" hoverable with cover + actions
Type / categoryTag color="orange" (Coffee Connect) · Tag color="purple" (Mentoring) · plain Tag for category

Default state matters: "All types" is selected on arrival and shows both program types interleaved. Do not default to a single type.

④ Coffee Connect — filtered

Same shell, type menu on coffee, results title and count follow the filter. Confirms the filter is a filter, not a mode switch.

⑤ Detail panel — a template selected

Grid narrows to Col span={12}; a 340px panel opens on the right.

Elementantd
Selected card2px colorPrimary border + 0 0 0 3px rgba(68,81,234,.10) halo + check pastille on the cover
RatingRate disabled allowHalf + uses count
SettingsDescriptions column={1} size="small" borderedMatching method / Intros frequency / Groups size, the real fields from SetupBlock (template.algo, template.frequency, template.users_per_group)
What's includedList size="small" split={false}
FooterButton type="primary" block Use this template · Button block Preview program

Note: the product's own preview is a 1200px Modal (template-modal.tsx). This side panel is a new, lighter affordance for scanning; the full modal stays available behind "Preview program". Decide with design whether both survive or the panel replaces the modal.

⑥ Mentoring add-on not included

Same library, degraded for entitlement.

Treatmentantd
Type menuMentoring item disabled: true with a LockOutlined and the sub-label "Add-on required"
BannerAlert type="info" — "The Mentoring add-on isn't included in your plan" + action Unlock Mentoring
Locked cardsBadge.Ribbon text="Add-on" color="#6D28D9", cover filter: grayscale(1) + dark overlay, action Unlock with a lock icon

Rules

every plan.

⑦ Unlock modal

Modal width={460} centered with a LockOutlined title, a short pitch, a List of the five Mentoring capabilities, and footer [Maybe later, Unlock Mentoring].

The five capabilities are fixed copy, identical everywhere they appear:

  1. Custom program architecture and funnels
  2. All Mentoring use cases library unlocked
  3. Mentor / Mentee advanced matching rules
  4. Goals and milestones per mentor-mentee pairing
  5. Mentor / Mentee shared space

⑧ Template detail — prebuilt assets

Sells what ships with a template: Row of four Card size="small", each with a Tag color="green" Included in extra.

AssetPreview built with
Kickoff Broadcastmini email mock
Expectations SurveyRadio.Group
Session structureSteps size="small" — Intro / Goals / Review / Wrap-up
Matching rulesList size="small"

Right rail: Descriptions at-a-glance + Alert "Fully customizable after creating the campaign" (the existing product string from template-modal.tsx's footer).


4. Data and API work required

This is the part the design cannot fake. The use-case payload behind company/getUseCases needs:

FieldTypeWhy
program_type`'coffee_connect' \'mentoring'`drives the type filter and the type Tag; backfill every existing use case to coffee_connect
cover_imageurlcard covers; needs a fallback per category while the library is being illustrated
categorystringthe cards show one primary category. categories (plural) already exists and stays the filter source — decide whether category is a new field or categories[0]
uses_countintthe "2.3k uses" affordance and the "Most used" sort
ratingfloat, optionalRate in the detail panel; hide the row if absent

Sort options need backend or client support for most_used (uses_count desc) and recent.

Entitlement

Add-on access is not isOnFree(). It needs its own check, e.g. getBilling().hasAddon('mentoring'). Gate three things with it:

  1. the Mentoring item in the type Menu (disabled)
  2. the card treatment (locked vs normal)
  3. the modal's primary action (Unlock Mentoring vs Use this program)

Creating a Mentoring campaign must also be refused server-side — the client gate is UX, not security.


5. Suggested build order

  1. Backend: program_type on use cases + backfill; expose uses_count.
  2. library/index.tsx shell with the two filter Menus, reusing the existing getUseCases data and

client-side filtering. Ship it behind the existing templates route.

  1. template-card.tsx with cover + type/category tags, replacing TemplateItem.
  2. Entitlement helper + ⑥/⑦ locked states.
  3. start-choice.tsx (②) in front of campaigns/new.
  4. ⑤ detail panel and ⑧ prebuilt-assets view.
  5. cover_image and ratings once the content team has assets.

Steps 1–3 are shippable on their own and already deliver the unified library.


6. Prototype-only details — do not copy

The antd file runs in a browser canvas, so three things there are scaffolding:

dataSource={...} and style={...} normally.

Modal (getContainer={false}) inside its frame. In the app use a normal portal Modal with default motion.

The bespoke 56px page headers on ③–⑧ exist to frame the canvas. In the app these screens wrap in <PageLayout title={...} actions={[...]}>.