Skip to content

Components

All shared UI lives under frontend/src/components/. Pages only import from here — no cross-page imports.


components/SiteNav.tsx

Public top navigation bar, used on all public-facing pages (/campaigns, /campaign/:id, /trust-score, /s/:username, etc.).

Props:

ts
{ activePath?: string }

Features:

  • Verifluence logo (links to /)
  • Role-based right-side controls: sign-in button when unauthenticated, avatar menu with profile / sign-out when streamer session is active
  • Mobile hamburger menu
  • Active link highlight driven by activePath
  • Handles sign-out via AuthContext

CampaignCardPublic

components/CampaignCardPublic.tsx

Campaign card shown to unauthenticated visitors and in the public marketplace. Built with Flowbite Button and Badge components; uses semantic Tailwind classes throughout.

Props:

ts
{
  campaign:  Campaign;
  onApply:   (id: string) => void;
  applying?: boolean;
}

Card layout (top → bottom):

  1. Status badge — absolute top-right corner (StatusBadge type="campaign")
  2. Operator avatar + name, category badge
  3. Campaign name (2-line clamp)
  4. Platform badges, GEOs, language chip, duration
  5. Budget progress bar
  6. Requirements row (min followers, viewers)
  7. Apply button — Flowbite <Button> with ArrowRight icon, disabled / loading states

Apply button states:

StateAppearance
DefaultFilled violet "Apply now →"
ApplyingLoading spinner + "Applying…"
Closed / expiredDisabled gray "Closed"
Already appliedDisabled green "Re-apply"

CampaignCardVerified

components/CampaignCardVerified.tsx

Authenticated-streamer variant of the campaign card. Extends CampaignCardPublic with application status awareness — shows "Applied ✓" if the streamer has already applied to this campaign.


StatusBadge

components/StatusBadge.tsx

Unified status pill component. Renders a Flowbite Badge with the correct colour for each status string.

Props:

ts
{
  type:   "campaign" | "deal" | "offer" | "negotiation" | "submission" | "kyc";
  status: string;
  size?:  "sm" | "md";
}

Campaign status → colour:

StatusColour
prepared / draftGray — "Draft"
fundedAmber — "Funded"
in_progressBlue — "In Progress"
completedGreen — "Completed"
cancelledRed — "Cancelled"

FundDonut

components/FundDonut.tsx

SVG donut chart showing campaign budget allocation in four segments:

SegmentColour
Rewarded (paid out)Green
Escrowed (allocated, pending)Violet
RefundedAmber
Unallocated (remaining)Gray

Props:

ts
{
  size:             number;          // diameter in px (e.g. 32, 36, 72)
  rewarded:         number;
  escrowed:         number;
  refunded:         number;
  total:            number;
  showLegend?:      boolean;         // full legend below chart (72px variant)
}

Used at three sizes: 32 px (ActivePage list), 36 px (CampaignsPage list), 72 px (CampaignsPage detail panel).


FundCampaignPanel

components/FundCampaignPanel.tsx

On-chain escrow deposit flow. Shown inside the CampaignsPage detail view when a campaign has status prepared and no escrow_id yet.

Flow:

  1. Connect MetaMask wallet
  2. Select deposit amount (pre-filled to budget_cap_usdc)
  3. Approve ERC-20 spend allowance
  4. Call deposit() on the Escrow contract
  5. Show tx hash + confirmation

InviteCampaignModal

components/InviteCampaignModal.tsx

Operator modal for inviting a specific streamer to one of their campaigns. Fully migrated to Flowbite Modal + semantic token colours.

Props:

ts
{
  streamer:  { id: number; username: string };
  onClose:   () => void;
}

Sections:

  • Campaign selector (list of operator's active campaigns)
  • Terms form (pre-filled from campaign minimums, all 5 negotiable fields)
  • Custom invite message textarea
  • Offer terms summary banner
  • Submit / Cancel buttons

NegTermEditor

components/NegTermEditor.tsx

Bilateral negotiation terms form. Renders all five negotiation fields (timeframe_days, deliveries, min_viewers, min_duration, payment_per_stream) with per-field agree/propose controls and colour-coded agreement state.

Used inside NegotiationCard (streamer view) and OperatorNegotiationCard.


StreamerAvatar

components/StreamerAvatar.tsx

Avatar component with graceful fallback.

Priority: Kick profile image → initials circle (styled with semantic tokens).

Props:

ts
{
  username:   string;
  avatarUrl?: string | null;
  size?:      number;   // px, default 40
}

AppFooter

components/AppFooter.tsx

Site footer. Nav links to key public pages, social links, copyright line.

VFFooter.tsx is a legacy alias kept for backward compatibility — new code should import AppFooter.


Subdirectory components

components/dashboard/

ComponentPurpose
ActivityRowSingle item in the streamer activity feed
EarningsTileSummary tile (Total Earned, This Month, etc.)

components/deals/

ComponentPurpose
DealCardStreamer deal summary card
OperatorDealCardOperator deal summary card
DealAllocationCardSlot allocation stepper + submission panel
AllocationStepperVisual slot progress bar
SlotRowSingle slot row inside DealAllocationCard
StreamSubmissionRowSubmission attempt row with status badge
FundsDonutInline mini donut for deal payout progress
OnChainOpsListList of on-chain allocation operations
AgreedTermsBadgesCompact badge row for agreed deal terms

components/negotiations/

ComponentPurpose
NegotiationCardStreamer-side negotiation card
OperatorNegotiationCardOperator-side negotiation card
NegStatusBannerStatus banner at top of negotiation view
EmptyNegotiationsStateEmpty state illustration + CTA

components/offers/

Offer list items and per-role offer cards.

components/personal/

Profile settings sub-panels (channel list, bio editor, visibility toggles).

components/streamer/delivery/

Delivery proof submission panel and tracked session picker.


Flowbite component usage

The following Flowbite React components are in active use:

ComponentImported from
Buttonflowbite-react
Badgeflowbite-react
Alertflowbite-react
Spinnerflowbite-react
Modal, ModalBody, ModalHeader, ModalFooterflowbite-react
Table, TableHead, TableHeadCell, TableBody, TableRow, TableCellflowbite-react
Tooltipflowbite-react

Icons come from flowbite-react-icons (imported individually):

ts
import { ArrowRight, CheckCircle, UserCircle } from "flowbite-react-icons/outline";

Flowbite dark mode

Flowbite respects the html.dark class. Combined with the semantic token system, dark mode requires no per-component overrides — set the class and every surface adapts.

Verifluence Documentation