npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fansunited-frontend-components

v0.0.31-RC6

Published

Various user centric components for Fans United features

Downloads

861

Readme

Fans United Frontend Components

A collection of interactive components for Fans United widgets providing engaging experiences and tools.

Installation

npm install fansunited-frontend-components fansunited-frontend-core
yarn add fansunited-frontend-components fansunited-frontend-core

Note: Both packages are required. fansunited-frontend-core provides types and utilities, while fansunited-frontend-components provides the UI components.

Quick Start

import React from "react";
import { ClassicQuizPlay } from "fansunited-frontend-components";
import { ClassicQuizPlayProps, WidgetTemplate } from "fansunited-frontend-core";
import { FansUnitedSDK } from "fansunited-sdk-esm";

const sdk = FansUnitedSDK({
  // your config here
});

const App: React.FC = () => {
  const props: ClassicQuizPlayProps = {
    entityId: "your-quiz-id",
    sdk,
    template: WidgetTemplate.STANDARD, // Also SPLIT and OVERLAY templates are available
    language: "en", // "bg" | "en" | "ro" | "pt" | "sr" | "fr" | "de" | "it" | "fr-be" | "fr" | "pl" | "pt" | "pt-br" | "sk
  };

  return (
    <div>
      <h1>My App</h1>
      <ClassicQuizPlay {...props} />
    </div>
  );
};

export default App;

Components

ClassicQuizPlay

Interactive quiz component with multiple templates and customization options.

Required Props

| Prop | Type | Description | | ---------- | -------------------- | ----------------------- | | entityId | string | Classic Quiz identifier | | sdk | FansUnitedSDKModel | SDK instance | | template | WidgetTemplate | Layout template | | language | LanguageType | Display language |

Optional Props

| Prop | Type | Description | | ---------------------------- | ----------------------- | ------------------------------------------- | | themeOptions | CustomThemeOptions | Theme configuration | | showAnswerExplanations | boolean | Show explanations after quiz completion | | leads | LeadsOptions | Lead collection settings | | imagePosition | "left" \| "right" | Image position (STANDARD template only) | | defaultImagePlaceholderUrl | string | URL for default image placeholder | | userIsLoggedIn | boolean | Determine if the user is logged in | | signInCTA | SignInCTADetails | Sign in call to action button configuration | | additionalCTA | AdditionalCTADetails | Additional call to action button configuration | | rulesDisplay | RulesDisplay | Game rules display configuration |

Templates

import { WidgetTemplate, ClassicQuizPlayProps } from "fansunited-frontend-core";

// Standard template with optional image positioning
const standardProps: ClassicQuizPlayProps = {
  template: WidgetTemplate.STANDARD,
  imagePosition: "left", // or 'right'
  // ... other props
};

// Other templates
const overlayProps: ClassicQuizPlayProps = {
  template: WidgetTemplate.OVERLAY, // WidgetTemplate.SPLIT
  // imagePosition not available for non-standard templates
  // ... other props
};

Theming

Customize the appearance using theme options:

import { CustomThemeOptions } from "fansunited-frontend-core";

// Default theme options
const themeOptions: CustomThemeOptions = {
  mode: "light", // or 'dark'
  colorSchemes: {
    light: {
      palette: {
        success: {
          plainColor: "#4CAF50",
          outlinedBorder: "#4CAF50",
          softBg: "#E3FBE3",
        },
        danger: {
          softBg: "#FEE4E2",
          plainColor: "#F44336",
          outlinedBorder: "#F44336",
        },
        primary: {
          plainColor: "#1A77D2",
          outlinedBorder: "#1A77D2",
          onPrimary: "#FAFAFA",
          primaryContainer: "#2397F3",
        },
        warning: {
          softBg: "#FEF0C7",
          plainColor: "#DC6803",
        },
      },
      textPrimary: "#212121",
      textSecondary: "#212121",
      textColor: "#212121",
      textDisabled: "#212121",
      surface: "#FFFFFF",
      onSurface: "#F5F5F5",
      surfaceVariant: "#EEEEEE",
      surfaceTintDim: "#212121",
      surfaceInverse: "#F5F5F5",
      outlineEnabledBorder: "#E0E0E0",
      secondaryContainer: "#BDBDBD",
    },
    dark: {
      palette: {
        primary: {
          plainColor: "#1A77D2",
          outlinedBorder: "#1A77D2",
          onPrimary: "#FAFAFA",
          primaryContainer: "#2397F3",
        },
        success: {
          plainColor: "#4CAF50",
          outlinedBorder: "#4CAF50",
          softBg: "#042F04",
        },
        danger: {
          softBg: "#430A0A",
          plainColor: "#F44336",
          outlinedBorder: "#F44336",
        },
        warning: {
          softBg: "#FEF0C7",
          plainColor: "#DC6803",
        },
      },
      textPrimary: "#FAFAFA",
      textSecondary: "#FAFAFA",
      textColor: "#FAFAFA",
      textDisabled: "#FAFAFA",
      surface: "#424242",
      onSurface: "#212121",
      surfaceVariant: "#616161",
      surfaceTintDim: "#FAFAFA",
      surfaceInverse: "#FAFAFA",
      outlineEnabledBorder: "#757575",
      secondaryContainer: "#757575",
    },
  },
  customBreakpoints: {
    values: {
      xs: 0,
      sm: 444,
      md: 600,
      lg: 900,
      xl: 1200,
      xxl: 1536,
    },
  },
  spacingScale: {
    "3xs": "2px",
    "2xs": "4px",
    xs: "8px",
    sm: "12px",
    md: "16px",
    lg: "24px",
    xl: "32px",
    "2xl": "40px",
    "3xl": "48px",
  },
  customFontFamily: {
    light: {
      primary: "Ubuntu, sans-serif",
      secondary: "Roboto, sans-serif",
    },
    dark: {
      primary: "Ubuntu, sans-serif",
      secondary: "Roboto, sans-serif",
    },
  },
  customRadius: {
    light: {
      none: "0px",
      "2xs": "2px",
      xs: "4px",
      sm: "8px",
      md: "12px",
      lg: "16px",
      xl: "24px",
      "2xl": "232px",
      full: "1000px",
    },
    dark: {
      none: "0px",
      "2xs": "2px",
      xs: "4px",
      sm: "8px",
      md: "12px",
      lg: "16px",
      xl: "24px",
      "2xl": "232px",
      full: "1000px",
    },
  },
  border: {
    light: {
      size: "1px",
    },
    dark: {
      size: "2px",
    },
  },
  imageBackgroundGradient: {
    light: {
      standard:
        "linear-gradient(270deg, rgba(255, 255, 255, 0) 0%, rgba(18, 18, 18, 0.8) 100%)",
      split:
        "linear-gradient(270deg, rgba(255, 255, 255, 0) 0%, rgba(18, 18, 18, 0.8) 100%)",
    },
    dark: {
      standard:
        "linear-gradient(270deg, rgba(255, 255, 255, 0) 0%, rgba(18, 18, 18, 0.8) 100%)",
      split:
        "linear-gradient(270deg, rgba(255, 255, 255, 0) 0%, rgba(18, 18, 18, 0.8) 100%)",
      overlay:
        "linear-gradient(270deg, rgba(255, 255, 255, 0) 0%, rgba(18, 18, 18, 0.8) 100%)",
    },
  },
};

<ClassicQuizPlay {...otherProps} themeOptions={themeOptions} />;

Lead Collection

Enable lead capture functionality:

import { LeadsOptions } from "fansunited-frontend-core";

const leads: LeadsOptions = {
  position: "before", // "before" | "after"
  fields: ["fullName"], // Available: "fullName" | "firstName" | "lastName" | "email" | "gender" | "country" | "phoneCountryCode" | "phoneNumber"
  campaignId: "test-quizzes",
  campaignName: "Test Quizzes",
  phoneCountryCode: "359", // When not provided will set the phone country code from component language prop. So for example if the language is "bg" and phoneCountryCode is not provided, it will fallback to "359"
  syncWithProfile: true, // Optional: sync form data to user profile after successful submission
};

<ClassicQuizPlay {...otherProps} leads={leads} />;

Sign in Configuration

Control user authentication and sign-in behavior using the userIsLoggedIn and signInCTA props.

import { SignInCTADetails } from "fansunited-frontend-core";

// Basic sign-in with onClick handler
const signInCTA: SignInCTADetails = {
  defaultLabel: "Sign In",
  onClick: () => {
    // Handle sign-in logic
    console.log("Sign in clicked");
  },
};

// Sign-in with URL navigation
const signInCTA: SignInCTADetails = {
  defaultLabel: "Login",
  url: "https://your-auth-provider.com/login",
  target: "_blank", // or "_self"
};

// Custom sign-in component
const signInCTA: SignInCTADetails = {
  component: <CustomSignInButton />,
};

<ClassicQuizPlay
  {...otherProps}
  userIsLoggedIn={false}
  signInCTA={signInCTA}
/>;

Sign-in Priority Order:

  1. Custom Component - If signInCTA.component is provided, it will be rendered
  2. Click Handler - If signInCTA.onClick is provided, a button with the handler will be rendered
  3. URL Navigation - If signInCTA.url is provided, a button will be rendered and clicking will navigate to the URL
  4. Disabled - If no signInCTA is provided, a disabled button will be shown

Behavior:

  • When userIsLoggedIn is false and the quiz requires authentication (authRequirement: "REGISTERED"), the sign-in screen will be displayed instead of the quiz

Additional CTA Configuration

Add an extra call-to-action button to the quiz completion screen using the additionalCTA prop.

import { AdditionalCTADetails } from "fansunited-frontend-core";

// Custom component
const additionalCTA: AdditionalCTADetails = {
  component: <CustomCTAButton />,
};

// Basic CTA with onClick handler
const additionalCTA: AdditionalCTADetails = {
  defaultLabel: "See More",
  onClick: () => {
    // Handle click logic
    console.log("Additional CTA clicked");
  },
};

// CTA with URL navigation
const additionalCTA: AdditionalCTADetails = {
  defaultLabel: "Visit Website",
  url: "https://your-website.com",
  target: "_blank", // or "_self"
};

<ClassicQuizPlay
  {...otherProps}
  additionalCTA={additionalCTA}
/>;

Priority Order:

  1. Custom Component - If additionalCTA.component is provided, it will be rendered
  2. Click Handler - If additionalCTA.onClick is provided, a button with the handler will be rendered
  3. URL Navigation - If additionalCTA.url is provided, a button will be rendered and clicking will navigate to the URL

Placement:

  • Standard variant: Displayed after "Play Again" and "Share Result" buttons
  • Split variant: Displayed after "Play Again" button in the thank you container
  • Overlay variant: Displayed after "Play Again" and "Share Result" buttons

Rules Display Configuration

Display game rules and instructions to users with a clickable info icon in the component headline using the rulesDisplay prop.

import { RulesDisplay } from "fansunited-frontend-core";

// Display rules in a modal dialog (default)
const rulesDisplay: RulesDisplay = {
  type: "modal",
};

// Display rules as a clickable link
const rulesDisplay: RulesDisplay = {
  type: "link",
  url: "https://your-website.com/quiz-rules",
  target: "_blank", // or "_self"
};

// Custom rules content component
const rulesDisplay: RulesDisplay = {
  type: "modal",
  component: <CustomRulesContent />,
};

<ClassicQuizPlay
  {...otherProps}
  rulesDisplay={rulesDisplay}
/>;

Display Types:

  1. Modal - Opens rules in a modal dialog overlay (default behavior)

    • Uses the quiz's rules field from the backend
    • Displays in a centered modal with close button
    • Supports HTML content rendering
  2. Link - Opens rules URL in a new tab/window

    • Requires url property
    • Optional target property (_blank or _self)
    • Useful for external documentation or detailed rule pages

Features:

  • Info Icon: Displays a small info icon (ⓘ) next to the component headline
  • Responsive: Adapts to all three templates (Standard, Split, Overlay)
  • Theme-Aware: Automatically adjusts colors based on theme mode and variant
  • Accessible: Keyboard navigable and screen reader friendly
  • Non-Intrusive: Icon only appears when rules are configured

Behavior:

  • The rules icon appears in the headline section across all component states (main view, sign-in, error, score state, lead collection)
  • Modal dialogs can be closed by clicking the close button, clicking outside, or pressing Escape
  • Link type opens in a new tab by default for better user experience

TypeScript Support

This package is built with TypeScript and provides full type definitions. Import types from fansunited-frontend-core:

import {
  ClassicQuizPlayProps,
  WidgetTemplate,
  MainProps,
  CustomThemeOptions,
  LeadsOptions,
  RulesDisplay,
  SignInCTADetails,
  AdditionalCTADetails,
  AnalyticsEvent,
} from "fansunited-frontend-core";

Peer Dependencies

{
  "react": ">=16.8.0",
  "react-dom": ">=16.8.0"
}

Bundle

The component uses shadow DOM and emotion for isolated styling, ensuring no CSS conflicts with your application.

Examples

Basic Quiz
import { ClassicQuizPlay } from "fansunited-frontend-components";
import { WidgetTemplate } from "fansunited-frontend-core";

<ClassicQuizPlay
  entityId="quiz-123"
  sdk={sdkInstance}
  template={WidgetTemplate.STANDARD}
  language="en"
/>;
Customized Quiz
<ClassicQuizPlay
  entityId="quiz-123"
  sdk={sdkInstance}
  template={WidgetTemplate.STANDARD}
  imagePosition="right"
  language="en"
  showAnswerExplanations={true}
  themeOptions={{
    mode: "dark",
  }}
  leads={{
    phoneCountryCode: "44",
    syncWithProfile: true,
  }}
/>

PollVote

Interactive poll voting component with real-time results, multiple choice support, and customizable templates. Perfect for engaging audiences with opinion polls, surveys, and voting campaigns.

Key Features:

  • Single and multiple choice voting
  • Real-time vote results and percentages
  • Three responsive templates (Standard, Split, Overlay)
  • Lead collection integration
  • Authentication support
  • Vote attempt limits
  • Custom theming and branding

Required Props

| Prop | Type | Description | | ---------- | -------------------- | ----------------------- | | entityId | string | Classic Quiz identifier | | sdk | FansUnitedSDKModel | SDK instance | | template | WidgetTemplate | Layout template | | language | LanguageType | Display language |

Optional Props

| Prop | Type | Description | | ---------------------------- | ----------------------- | ------------------------------------------- | | themeOptions | CustomThemeOptions | Theme configuration | | leads | LeadsOptions | Lead collection settings | | imagePosition | "left" \| "right" | Image position (STANDARD template only) | | defaultImagePlaceholderUrl | string | URL for default image placeholder | | userIsLoggedIn | boolean | Determine if the user is logged in | | signInCTA | SignInCTADetails | Sign in call to action button configuration | | additionalCTA | AdditionalCTADetails | Additional call to action button configuration | | rulesDisplay | RulesDisplay | Poll rules display configuration |

Templates

import { WidgetTemplate, PollVoteProps } from "fansunited-frontend-core";

// Standard template with optional image positioning
const standardProps: PollVoteProps = {
  template: WidgetTemplate.STANDARD,
  imagePosition: "left", // or 'right'
  // ... other props
};

// Split template - side-by-side layout
const splitProps: PollVoteProps = {
  template: WidgetTemplate.SPLIT,
  // imagePosition not available for non-standard templates
  // ... other props
};

// Overlay template - full-screen immersive experience
const overlayProps: PollVoteProps = {
  template: WidgetTemplate.OVERLAY,
  // ... other props
};

Sign in Configuration

Control user authentication and voting permissions using the userIsLoggedIn and signInCTA props.

import { SignInCTADetails } from "fansunited-frontend-core";

// Custom sign-in component
const signInCTA: SignInCTADetails = {
  component: <CustomSignInButton />,
};

// Basic sign-in with onClick handler
const signInCTA: SignInCTADetails = {
  defaultLabel: "Sign in to vote",
  onClick: () => {
    // Handle sign-in logic
    console.log("Sign in clicked");
  },
};

// Sign-in with URL navigation
const signInCTA: SignInCTADetails = {
  defaultLabel: "Login to participate",
  url: "https://your-auth-provider.com/login",
  target: "_blank",
};

<PollVote {...otherProps} userIsLoggedIn={false} signInCTA={signInCTA} />;

Sign-in Priority Order:

  1. Custom Component - If signInCTA.component is provided, it will be rendered
  2. Click Handler - If signInCTA.onClick is provided, a button with the handler will be rendered
  3. URL Navigation - If signInCTA.url is provided, a button will be rendered and clicking will navigate to the URL
  4. Disabled - If no signInCTA is provided, a disabled button will be shown

Behavior:

  • When userIsLoggedIn is false and the poll requires authentication (authRequirement: "REGISTERED"), the sign-in screen will be displayed instead of the poll

Additional CTA Configuration

Add an extra call-to-action button to the poll results screen using the additionalCTA prop.

import { AdditionalCTADetails } from "fansunited-frontend-core";

// Custom component
const additionalCTA: AdditionalCTADetails = {
  component: <CustomCTAButton />,
};

// Basic CTA with onClick handler
const additionalCTA: AdditionalCTADetails = {
  defaultLabel: "Learn More",
  onClick: () => {
    // Handle click logic
    console.log("Additional CTA clicked");
  },
};

// CTA with URL navigation
const additionalCTA: AdditionalCTADetails = {
  defaultLabel: "View Details",
  url: "https://your-website.com/poll-details",
  target: "_blank", // or "_self"
};

<PollVote
  {...otherProps}
  additionalCTA={additionalCTA}
/>;

Priority Order:

  1. Custom Component - If additionalCTA.component is provided, it will be rendered
  2. Click Handler - If additionalCTA.onClick is provided, a button with the handler will be rendered
  3. URL Navigation - If additionalCTA.url is provided, a button will be rendered and clicking will navigate to the URL

Placement:

  • Standard variant: Displayed before "Vote Again" button
  • Split variant: Displayed in the same container as "Vote Again" button
  • Overlay variant: Displayed after "Vote Again" button

Lead Collection

Capture user information before or after voting:

import { LeadsOptions } from "fansunited-frontend-core";

const leads: LeadsOptions = {
  position: "before", // "before" | "after"
  fields: ["fullName", "email"], // Available: "fullName" | "firstName" | "lastName" | "email" | "gender" | "country" | "phoneCountryCode" | "phoneNumber"
  campaignId: "poll-campaign-2024",
  campaignName: "User Opinion Poll",
  phoneCountryCode: "44", // Default country code for phone fields
  syncWithProfile: true, // Optional: sync form data to user profile after successful submission
};

<PollVote {...otherProps} leads={leads} />;

Profile Sync

When syncWithProfile is enabled in the leads configuration, form data will be automatically synced to the user's profile after successful submission:

import { LeadsOptions } from "fansunited-frontend-core";

const leads: LeadsOptions = {
  position: "after",
  fields: ["firstName", "lastName", "email", "phoneNumber", "country"],
  campaignId: "user-profile-sync",
  campaignName: "Profile Sync Campaign",
  syncWithProfile: true, // Enable profile synchronization
};

<PollVote {...otherProps} leads={leads} />

How it works:

  • Only fields that are both included in the form configuration AND have non-empty values will be synced
  • Supported fields: fullName, firstName, lastName, email, phoneNumber, phoneCountryCode, country, gender
  • Uses the SDK profile namespace: sdk.profile.getOwn().setName().setEmail()...update()
  • Profile sync failures are logged but don't break the lead collection flow
  • Sync happens automatically after successful lead form submission

Name Field Priority:

  • If fullName is configured and has a value, it takes priority for the profile name
  • If both firstName and lastName are configured and have values, they are combined: "firstName lastName"
  • If only firstName is configured and has a value, it becomes the profile name
  • If only lastName is configured and has a value, it becomes the profile name

Examples

Basic Poll
import { PollVote } from "fansunited-frontend-components";
import { WidgetTemplate } from "fansunited-frontend-core";

<PollVote
  entityId="poll-123"
  sdk={sdkInstance}
  template={WidgetTemplate.STANDARD}
  language="en"
/>;
Customized Poll
<PollVote
  entityId="poll-123"
  sdk={sdkInstance}
  template={WidgetTemplate.OVERLAY}
  language="en"
  userIsLoggedIn={false}
  signInCTA={{
    defaultLabel: "Sign in to vote",
    onClick: () => handleSignIn(),
  }}
  leads={{
    position: "after",
    fields: ["fullName", "email"],
    campaignId: "poll-campaign",
    campaignName: "User Survey 2024",
    phoneCountryCode: "44",
    syncWithProfile: true,
  }}
  themeOptions={{
    mode: "dark",
  }}
/>

CollectLead

Lead collection component for capturing user information with customizable forms, branding, and success actions. Perfect for newsletter signups, contact forms, and user registration flows.

Key Features:

  • Customizable form fields (name, email, phone, country, gender, custom fields)
  • Consent management and privacy policy integration
  • Custom branding and theming support
  • Success page with custom CTAs
  • Three responsive templates (Standard, Split, Overlay)
  • Phone number validation with country codes
  • Multi-language support

Required Props

| Prop | Type | Description | | ---------- | -------------------- | ------------------------------- | | entityId | string | Lead collection form identifier | | sdk | FansUnitedSDKModel | SDK instance | | template | WidgetTemplate | Layout template | | language | LanguageType | Display language |

Optional Props

| Prop | Type | Description | | ---------------------------- | --------------------- | ----------------------------------------- | | themeOptions | CustomThemeOptions | Theme configuration | | fields | LeadField[] | Form fields to display | | labels | LeadLabels | Custom labels for form elements | | imagePosition | "left" \| "right" | Image position (STANDARD template only) | | defaultImagePlaceholderUrl | string | URL for default image placeholder | | phoneCountryCode | string | Default country code for phone fields | | syncWithProfile | boolean | Sync form data to user profile after successful submission | | onSuccessCTA | OnSuccessCTADetails | Success page call to action configuration | | customFields | LeadCustomField[] | Additional custom form fields | | consents | LeadConsent[] | Consent checkboxes for privacy compliance | | content | ContentInfo | Content metadata | | campaign | CampaignInfo | Campaign information | | branding | BrandingInfo | Branding configuration | | images | ImagesModel | Image assets |

Templates

import { WidgetTemplate, CollectLeadProps } from "fansunited-frontend-core";

// Standard template with optional image positioning
const standardProps: CollectLeadProps = {
  template: WidgetTemplate.STANDARD,
  imagePosition: "left", // or 'right'
  // ... other props
};

// Split template - side-by-side layout
const splitProps: CollectLeadProps = {
  template: WidgetTemplate.SPLIT,
  // imagePosition not available for non-standard templates
  // ... other props
};

// Overlay template - full-screen immersive experience
const overlayProps: CollectLeadProps = {
  template: WidgetTemplate.OVERLAY,
  // ... other props
};

Form Configuration

Configure which fields to display and their behavior:

import {
  LeadField,
  LeadCustomField,
  LeadConsent,
} from "fansunited-frontend-core";

// Standard form fields
const fields: LeadField[] = [
  "fullName",
  "email",
  "phoneNumber",
  "country",
  "gender",
];

// Custom fields for additional data collection
const customFields: LeadCustomField[] = [
  {
    key: "company",
    label: "Company Name",
    type: "input",
    required: true,
    placeholder: "Enter your company name",
  },
  {
    key: "message",
    label: "Message",
    type: "textarea",
    required: false,
    placeholder: "Tell us about your needs...",
  },
];

// Consent checkboxes for privacy compliance
const consents: LeadConsent[] = [
  {
    id: "marketing",
    label: "I agree to receive marketing communications",
  },
  {
    id: "newsletter",
    label: "Subscribe to our newsletter",
  },
];

<CollectLead
  {...otherProps}
  fields={fields}
  customFields={customFields}
  consents={consents}
/>;

Custom Labels

Customize all text displayed in the form:

import { LeadLabels } from "fansunited-frontend-core";

const labels: LeadLabels = {
  title: "Join Our Community",
  description: "Get exclusive updates and early access to new features",
  formTitle: "Sign Up Today",
  formDescription: "Fill out the form below to get started",
  formFullNameLabel: "Full Name",
  formFullNamePlaceholder: "Enter your full name",
  formEmailLabel: "Email Address",
  formGenderLabel: "Gender",
  formGenderPlaceholder: "Select your gender",
  formCountryLabel: "Country",
  formCountryPlaceholder: "Select your country",
  formPhoneNumberLabel: "Phone Number",
  formPhoneNumberPlaceholder: "Enter your phone number",
  submitButtonLabel: "Subscribe Now",
  successTitle: "Welcome Aboard!",
  successDescription:
    "Thank you for joining our community. Check your email for next steps.",
  privacyPolicyUrlLabel: "Privacy Policy",
  termsAndConditionsUrlLabel: "Terms & Conditions",
  presentedByLabel: "Powered by",
};

<CollectLead {...otherProps} labels={labels} />;

Success Actions

Configure what happens after successful form submission:

import { OnSuccessCTADetails } from "fansunited-frontend-core";

// Custom success action with onClick handler
const onSuccessCTA: OnSuccessCTADetails = {
  defaultLabel: "Continue to Dashboard",
  onClick: () => {
    // Handle post-submission logic
    window.location.href = "/dashboard";
  },
};

// Success action with URL navigation
const onSuccessCTA: OnSuccessCTADetails = {
  defaultLabel: "Visit Our Website",
  url: "https://your-website.com",
  target: "_blank",
};

// Custom success component
const onSuccessCTA: OnSuccessCTADetails = {
  component: <CustomSuccessButton />,
};

<CollectLead {...otherProps} onSuccessCTA={onSuccessCTA} />;

Profile Sync

Enable automatic profile synchronization to update user profiles with form data:

<CollectLead
  entityId="lead-form-123"
  sdk={sdkInstance}
  template={WidgetTemplate.STANDARD}
  language="en"
  fields={["firstName", "lastName", "email", "phoneNumber", "country", "gender"]}
  syncWithProfile={true} // Enable profile synchronization
  labels={{
    title: "Update Your Profile",
    submitButtonLabel: "Save & Update Profile",
  }}
/>

Profile Sync Features:

  • Automatic Sync: Form data is automatically synced to the user's profile after successful submission
  • Field Mapping: Only configured fields with non-empty values are synced to the profile
  • Supported Fields: fullName, firstName, lastName, email, phoneNumber, phoneCountryCode, country, gender
  • SDK Integration: Uses the profile builder pattern: sdk.profile.getOwn().setName().setEmail()...update()
  • Error Handling: Profile sync failures are logged but don't prevent lead collection
  • Optional: Defaults to false, completely opt-in behavior

Name Field Handling:

  • Priority 1: fullName (if configured and has value) → sets profile name directly
  • Priority 2: firstName + lastName (if both configured and have values) → combined as "firstName lastName"
  • Priority 3: firstName only (if configured and has value) → sets profile name
  • Priority 4: lastName only (if configured and has value) → sets profile name

Use Cases:

  • User registration forms that also update profiles
  • Newsletter signups that capture additional profile information
  • Contact forms that enhance user profiles with new data
  • Profile update forms with lead tracking

Examples

Basic Lead Form
import { CollectLead } from "fansunited-frontend-components";
import { WidgetTemplate } from "fansunited-frontend-core";

<CollectLead
  entityId="lead-form-123"
  sdk={sdkInstance}
  template={WidgetTemplate.STANDARD}
  language="en"
  fields={["fullName", "email"]}
/>;
Advanced Lead Form
<CollectLead
  entityId="lead-form-123"
  sdk={sdkInstance}
  template={WidgetTemplate.OVERLAY}
  language="en"
  fields={["fullName", "email", "phoneNumber", "country"]}
  phoneCountryCode="44"
  syncWithProfile={true}
  customFields={[
    {
      key: "company",
      label: "Company",
      type: "input",
      required: true,
    },
  ]}
  consents={[
    {
      id: "marketing",
      label: "I agree to receive marketing emails",
    },
  ]}
  labels={{
    title: "Get Early Access",
    submitButtonLabel: "Join Waitlist",
    successTitle: "You're In!",
    successDescription: "We'll notify you when we launch.",
  }}
  onSuccessCTA={{
    defaultLabel: "Learn More",
    url: "https://example.com/learn-more",
    target: "_blank",
  }}
  themeOptions={{
    mode: "dark",
  }}
/>

PersonalityQuizPlay

Interactive personality quiz component that matches users with personas based on their answers. Features comprehensive result displays with persona matching, detailed explanations, and customizable templates.

Key Features:

  • Personality matching algorithm with percentage scores
  • Multiple persona results with detailed descriptions
  • Tabbed result interface with top match highlighting
  • Answer explanations and persona insights
  • Three responsive templates (Standard, Split, Overlay)
  • Lead collection integration
  • Authentication support
  • Custom theming and branding
  • Result sharing capabilities

Required Props

| Prop | Type | Description | | ---------- | -------------------- | --------------------------- | | entityId | string | Personality Quiz identifier | | sdk | FansUnitedSDKModel | SDK instance | | template | WidgetTemplate | Layout template | | language | LanguageType | Display language |

Optional Props

| Prop | Type | Description | | ---------------------------- | ----------------------- | ------------------------------------------- | | themeOptions | CustomThemeOptions | Theme configuration | | showAnswerExplanations | boolean | Show explanations after quiz completion | | leads | LeadsOptions | Lead collection settings | | imagePosition | "left" \| "right" | Image position (STANDARD template only) | | defaultImagePlaceholderUrl | string | URL for default image placeholder | | userIsLoggedIn | boolean | Determine if the user is logged in | | signInCTA | SignInCTADetails | Sign in call to action button configuration | | additionalCTA | AdditionalCTADetails | Additional call to action button configuration | | optionsLayout | OptionsLayout | Layout for answer options | | rulesDisplay | RulesDisplay | Quiz rules display configuration |

Templates

import {
  WidgetTemplate,
  PersonalityQuizPlayProps,
} from "fansunited-frontend-core";

// Standard template with optional image positioning
const standardProps: PersonalityQuizPlayProps = {
  template: WidgetTemplate.STANDARD,
  imagePosition: "left", // or 'right'
  // ... other props
};

// Split template - side-by-side layout
const splitProps: PersonalityQuizPlayProps = {
  template: WidgetTemplate.SPLIT,
  // imagePosition not available for non-standard templates
  // ... other props
};

// Overlay template - full-screen immersive experience
const overlayProps: PersonalityQuizPlayProps = {
  template: WidgetTemplate.OVERLAY,
  // ... other props
};

Options Layout

Configure how answer options are displayed:

import { OptionsLayout } from "fansunited-frontend-core";

// Two-by-two grid layout
const twoByTwoLayout: PersonalityQuizPlayProps = {
  optionsLayout: "twoByTwo",
  // ... other props
};

// Horizontal row layout
const rowLayout: PersonalityQuizPlayProps = {
  optionsLayout: "row",
  // ... other props
};

// Vertical column layout
const columnLayout: PersonalityQuizPlayProps = {
  optionsLayout: "column",
  // ... other props
};

Sign in Configuration

Control user authentication and quiz access using the userIsLoggedIn and signInCTA props.

import { SignInCTADetails } from "fansunited-frontend-core";

// Custom sign-in component
const signInCTA: SignInCTADetails = {
  component: <CustomSignInButton />,
};

// Basic sign-in with onClick handler
const signInCTA: SignInCTADetails = {
  defaultLabel: "Sign in to take quiz",
  onClick: () => {
    // Handle sign-in logic
    console.log("Sign in clicked");
  },
};

// Sign-in with URL navigation
const signInCTA: SignInCTADetails = {
  defaultLabel: "Login to discover your personality",
  url: "https://your-auth-provider.com/login",
  target: "_blank",
};

<PersonalityQuizPlay
  {...otherProps}
  userIsLoggedIn={false}
  signInCTA={signInCTA}
/>;

Sign-in Priority Order:

  1. Custom Component - If signInCTA.component is provided, it will be rendered
  2. Click Handler - If signInCTA.onClick is provided, a button with the handler will be rendered
  3. URL Navigation - If signInCTA.url is provided, a button will be rendered and clicking will navigate to the URL
  4. Disabled - If no signInCTA is provided, a disabled button will be shown

Behavior:

  • When userIsLoggedIn is false and the quiz requires authentication (authRequirement: "REGISTERED"), the sign-in screen will be displayed instead of the quiz

Additional CTA Configuration

Add an extra call-to-action button to the quiz results screen using the additionalCTA prop.

import { AdditionalCTADetails } from "fansunited-frontend-core";

// Custom component
const additionalCTA: AdditionalCTADetails = {
  component: <CustomCTAButton />,
};

// Basic CTA with onClick handler
const additionalCTA: AdditionalCTADetails = {
  defaultLabel: "Explore More",
  onClick: () => {
    // Handle click logic
    console.log("Additional CTA clicked");
  },
};

// CTA with URL navigation
const additionalCTA: AdditionalCTADetails = {
  defaultLabel: "Discover Your Type",
  url: "https://your-website.com/personality-types",
  target: "_blank", // or "_self"
};

<PersonalityQuizPlay
  {...otherProps}
  additionalCTA={additionalCTA}
/>;

Priority Order:

  1. Custom Component - If additionalCTA.component is provided, it will be rendered
  2. Click Handler - If additionalCTA.onClick is provided, a button with the handler will be rendered
  3. URL Navigation - If additionalCTA.url is provided, a button will be rendered and clicking will navigate to the URL

Placement:

  • Standard variant: Displayed before "Play Again" button
  • Split variant: Displayed in the thank you container after "Play Again" button
  • Overlay variant: Displayed after "Play Again" button if available

Lead Collection

Capture user information before or after taking the personality quiz:

import { LeadsOptions } from "fansunited-frontend-core";

const leads: LeadsOptions = {
  position: "before", // "before" | "after"
  fields: ["fullName", "email"], // Available: "fullName" | "firstName" | "lastName" | "email" | "gender" | "country" | "phoneCountryCode" | "phoneNumber"
  campaignId: "personality-quiz-2024",
  campaignName: "Personality Assessment Campaign",
  phoneCountryCode: "1", // Default country code for phone fields
  syncWithProfile: true, // Optional: sync form data to user profile after successful submission
};

<PersonalityQuizPlay {...otherProps} leads={leads} />;

Answer Explanations

Enable detailed explanations for quiz answers and persona matching:

<PersonalityQuizPlay {...otherProps} showAnswerExplanations={true} />

When enabled, users will see:

  • Explanations for each answer choice
  • Detailed persona descriptions
  • Matching algorithm insights
  • Percentage breakdowns for each persona

Examples

Basic Personality Quiz
import { PersonalityQuizPlay } from "fansunited-frontend-components";
import { WidgetTemplate } from "fansunited-frontend-core";

<PersonalityQuizPlay
  entityId="personality-quiz-123"
  sdk={sdkInstance}
  template={WidgetTemplate.STANDARD}
  language="en"
/>;
Advanced Personality Quiz
<PersonalityQuizPlay
  entityId="personality-quiz-123"
  sdk={sdkInstance}
  template={WidgetTemplate.OVERLAY}
  language="en"
  showAnswerExplanations={true}
  optionsLayout="twoByTwo"
  userIsLoggedIn={false}
  signInCTA={{
    defaultLabel: "Sign in to save results",
    onClick: () => handleSignIn(),
  }}
  leads={{
    position: "after",
    fields: ["fullName", "email"],
    campaignId: "personality-campaign",
    campaignName: "Personality Assessment 2024",
    phoneCountryCode: "44",
    syncWithProfile: true,
  }}
  themeOptions={{
    mode: "dark",
    colorSchemes: {
      dark: {
        textPrimary: "#ffffff",
        surface: "#1a1a1a",
      },
    },
  }}
/>
Customized Layout
<PersonalityQuizPlay
  entityId="personality-quiz-123"
  sdk={sdkInstance}
  template={WidgetTemplate.STANDARD}
  imagePosition="right"
  language="en"
  optionsLayout="column"
  showAnswerExplanations={true}
  themeOptions={{
    mode: "light",
    customFontFamily: {
      light: {
        primary: "Inter, sans-serif",
        secondary: "Roboto, sans-serif",
      },
    },
  }}
/>

MatchQuizPlay

Interactive match prediction quiz component that allows users to make predictions on various football match markets. Features multiple fixture types, real-time countdown timers, points system, and comprehensive result tracking with leaderboards.

Key Features:

  • Multiple prediction markets (1X2, Correct Score, Player Markets, Over/Under Goals, Corners, etc.)
  • Real-time countdown timer for prediction cutoff
  • Points system with loyalty integration
  • Leaderboard and ranking system
  • Prediction summary and editing capabilities
  • Three responsive templates (Standard, Split, Overlay)
  • Lead collection integration
  • Authentication support
  • Custom theming and branding
  • Detailed prediction results and explanations

Required Props

| Prop | Type | Description | | ---------- | -------------------- | --------------------- | | entityId | string | Match Quiz identifier | | sdk | FansUnitedSDKModel | SDK instance | | template | WidgetTemplate | Layout template | | language | LanguageType | Display language |

Optional Props

| Prop | Type | Description | | ---------------------------- | ----------------------- | ------------------------------------------------- | | themeOptions | CustomThemeOptions | Theme configuration | | leads | LeadsOptions | Lead collection settings | | imagePosition | "left" \| "right" | Image position (STANDARD template only) | | defaultImagePlaceholderUrl | string | URL for default image placeholder | | userIsLoggedIn | boolean | Determine if the user is logged in | | signInCTA | SignInCTADetails | Sign in call to action button configuration | | additionalCTA | AdditionalCTADetails | Additional call to action button configuration | | showCountdown | boolean | Show countdown timer when Match Quiz is open | | showTeamLabels | boolean | Show team name labels in fixture components | | showPoints | boolean | Show points display for each fixture | | showPredictionDetails | boolean | Show detailed prediction results after completion | | rulesDisplay | RulesDisplay | Match quiz rules display configuration |

Templates

import { WidgetTemplate, MatchQuizPlayProps } from "fansunited-frontend-core";

// Standard template with optional image positioning
const standardProps: MatchQuizPlayProps = {
  template: WidgetTemplate.STANDARD,
  imagePosition: "left", // or 'right'
  // ... other props
};

// Split template - side-by-side layout
const splitProps: MatchQuizPlayProps = {
  template: WidgetTemplate.SPLIT,
  // imagePosition not available for non-standard templates
  // ... other props
};

// Overlay template - full-screen immersive experience
const overlayProps: MatchQuizPlayProps = {
  template: WidgetTemplate.OVERLAY,
  // ... other props
};

Supported Markets

MatchQuizPlay supports a wide variety of football prediction markets:

Match Result Markets:

  • FT_1X2 - Full Time 1X2 (Home Win, Draw, Away Win)
  • HT_1X2 - Half Time 1X2

Score Markets:

  • CORRECT_SCORE - Exact final score prediction
  • CORRECT_SCORE_HT - Exact half-time score prediction
  • CORRECT_SCORE_ADVANCED - Advanced correct score with alternative points

Player Markets:

  • PLAYER_SCORE_FIRST_GOAL - First goalscorer prediction
  • PLAYER_SCORE - Anytime goalscorer
  • PLAYER_YELLOW_CARD - Player to receive yellow card
  • PLAYER_RED_CARD - Player to receive red card
  • PLAYER_SCORE_HATTRICK - Player to score hat-trick
  • PLAYER_SCORE_TWICE - Player to score twice

Over/Under Markets:

  • OVER_GOALS_0_5 to OVER_GOALS_6_5 - Total goals over/under
  • OVER_CORNERS_6_5 to OVER_CORNERS_13_5 - Total corners over/under

Special Markets:

  • CORNERS_MATCH - Total corners in the match
  • PENALTY_MATCH - Penalty awarded in the match
  • RED_CARD_MATCH - Red card shown in the match

Game Status States

Match quizzes have 5 distinct status states:

  • PENDING - Not yet open for predictions
  • OPEN - Ready for predictions (default state)
  • LIVE - Match has started, no new predictions accepted
  • CLOSED - Match finished, backend resolving predictions
  • SETTLED - Predictions resolved, leaderboard available

Countdown Timer

Enable countdown timer to show time remaining for predictions:

<MatchQuizPlay {...otherProps} showCountdown={true} />

The countdown timer:

  • Displays when Match Quiz status is OPEN
  • Shows days, hours, minutes, and seconds remaining
  • Uses predictionsCutoffTime from the Match Quiz data
  • Automatically hides when cutoff time is reached

Points System

Enable points display to show potential rewards:

<MatchQuizPlay {...otherProps} showPoints={true} />

Points system features:

  • Shows potential points for each fixture
  • Displays earned vs possible points
  • Integrates with loyalty system configuration
  • Supports alternative point structures for advanced markets
  • Mobile-friendly tooltip display

Prediction Details

Show detailed prediction results and explanations:

<MatchQuizPlay {...otherProps} showPredictionDetails={true} />

When enabled, users see:

  • Tabulated interface
  • Correct vs incorrect prediction highlighting
  • Detailed market results
  • Points breakdown per fixture

Sign in Configuration

Control user authentication and quiz access using the userIsLoggedIn and signInCTA props.

import { SignInCTADetails } from "fansunited-frontend-core";

// Custom sign-in component
const signInCTA: SignInCTADetails = {
  component: <CustomSignInButton />,
};

// Basic sign-in with onClick handler
const signInCTA: SignInCTADetails = {
  defaultLabel: "Sign in to predict",
  onClick: () => {
    // Handle sign-in logic
    console.log("Sign in clicked");
  },
};

// Sign-in with URL navigation
const signInCTA: SignInCTADetails = {
  defaultLabel: "Login to join the competition",
  url: "https://your-auth-provider.com/login",
  target: "_blank",
};

<MatchQuizPlay {...otherProps} userIsLoggedIn={false} signInCTA={signInCTA} />;

Sign-in Priority Order:

  1. Custom Component - If signInCTA.component is provided, it will be rendered
  2. Click Handler - If signInCTA.onClick is provided, a button with the handler will be rendered
  3. URL Navigation - If signInCTA.url is provided, a button will be rendered and clicking will navigate to the URL
  4. Disabled - If no signInCTA is provided, a disabled button will be shown

Behavior:

  • When userIsLoggedIn is false and the quiz requires authentication (authRequirement: "REGISTERED"), the sign-in screen will be displayed instead of the quiz

Additional CTA Configuration

Add an extra call-to-action button to the match quiz results screen using the additionalCTA prop.

import { AdditionalCTADetails } from "fansunited-frontend-core";

// Custom component
const additionalCTA: AdditionalCTADetails = {
  component: <CustomCTAButton />,
};

// Basic CTA with onClick handler
const additionalCTA: AdditionalCTADetails = {
  defaultLabel: "View Leaderboard",
  onClick: () => {
    // Handle click logic
    console.log("Additional CTA clicked");
  },
};

// CTA with URL navigation
const additionalCTA: AdditionalCTADetails = {
  defaultLabel: "Match Details",
  url: "https://your-website.com/match-details",
  target: "_blank", // or "_self"
};

<MatchQuizPlay
  {...otherProps}
  additionalCTA={additionalCTA}
/>;

Priority Order:

  1. Custom Component - If additionalCTA.component is provided, it will be rendered
  2. Click Handler - If additionalCTA.onClick is provided, a button with the handler will be rendered
  3. URL Navigation - If additionalCTA.url is provided, a button will be rendered and clicking will navigate to the URL

Placement:

  • Standard variant: Displayed on the same line as the branding logo
  • Split variant: Displayed centered after main content
  • Overlay variant: Displayed on the same line as the branding logo

Lead Collection

Capture user information before or after making predictions:

import { LeadsOptions } from "fansunited-frontend-core";

const leads: LeadsOptions = {
  position: "before", // "before" | "after"
  fields: ["fullName", "email"], // Available: "fullName" | "firstName" | "lastName" | "email" | "gender" | "country" | "phoneCountryCode" | "phoneNumber"
  campaignId: "match-quiz-2024",
  campaignName: "Football Prediction Campaign",
  phoneCountryCode: "44", // Default country code for phone fields
  syncWithProfile: true, // Optional: sync form data to user profile after successful submission
};

<MatchQuizPlay {...otherProps} leads={leads} />;

Examples

Basic Match Quiz
import { MatchQuizPlay } from "fansunited-frontend-components";
import { WidgetTemplate } from "fansunited-frontend-core";

<MatchQuizPlay
  entityId="match-quiz-123"
  sdk={sdkInstance}
  template={WidgetTemplate.STANDARD}
  language="en"
/>;
Advanced Match Quiz
<MatchQuizPlay
  entityId="match-quiz-123"
  sdk={sdkInstance}
  template={WidgetTemplate.OVERLAY}
  language="en"
  showCountdown={true}
  showTeamLabels={true}
  showPoints={true}
  showPredictionDetails={true}
  userIsLoggedIn={false}
  signInCTA={{
    defaultLabel: "Sign in to compete",
    onClick: () => handleSignIn(),
  }}
  leads={{
    position: "after",
    fields: ["fullName", "email"],
    campaignId: "match-prediction-campaign",
    campaignName: "Football Predictions 2024",
    phoneCountryCode: "44",
    syncWithProfile: true,
  }}
  themeOptions={{
    mode: "dark",
    colorSchemes: {
      dark: {
        textPrimary: "#ffffff",
        surface: "#1a1a1a",
      },
    },
  }}
/>
Customized Layout
<MatchQuizPlay
  entityId="match-quiz-123"
  sdk={sdkInstance}
  template={WidgetTemplate.STANDARD}
  imagePosition="right"
  language="en"
  showCountdown={true}
  showTeamLabels={false}
  showPoints={true}
  themeOptions={{
    mode: "light",
    customFontFamily: {
      light: {
        primary: "Inter, sans-serif",
        secondary: "Roboto, sans-serif",
      },
    },
  }}
/>

EventGamePlay

Interactive event prediction component for sports and entertainment events. Features flexible fixture types, real-time countdown timers, points system, and comprehensive result tracking with leaderboards.

Key Features:

  • Multiple outcome types (Boolean, Number, Enum, Free Input)
  • Real-time countdown timer for prediction cutoff
  • Points system with loyalty integration
  • Leaderboard and ranking system
  • Prediction summary and editing capabilities
  • Three responsive templates (Standard, Split, Overlay)
  • Custom theming

Required Props

| Prop | Type | Description | | ---------- | -------------------- | --------------------- | | entityId | string | Event Game identifier | | sdk | FansUnitedSDKModel | SDK instance | | template | WidgetTemplate | Layout template | | language | LanguageType | Display language |

Optional Props

| Prop | Type | Description | | ---------------------------- | ----------------------- | ------------------------------------------------- | | themeOptions | CustomThemeOptions | Theme configuration | | leads | LeadsOptions | Lead collection settings | | imagePosition | "left" \| "right" | Image position (STANDARD template only) | | defaultImagePlaceholderUrl | string | URL for default image placeholder | | userIsLoggedIn | boolean | Determine if the user is logged in | | signInCTA | SignInCTADetails | Sign in call to action button configuration | | additionalCTA | AdditionalCTADetails | Additional call to action button configuration | | showCountdown | boolean | Show countdown timer when Event Game is open | | showPoints | boolean | Show points display for each fixture | | showPredictionDetails | boolean | Show detailed prediction results after completion | | rulesDisplay | RulesDisplay | Event game rules display configuration |

Templates

import { WidgetTemplate, EventGamePlayProps } from "fansunited-frontend-core";

// Standard template with optional image positioning
const standardProps: EventGamePlayProps = {
  template: WidgetTemplate.STANDARD,
  imagePosition: "left", // or 'right'
  // ... other props
};

// Split template - side-by-side layout
const splitProps: EventGamePlayProps = {
  template: WidgetTemplate.SPLIT,
  // imagePosition not available for non-standard templates
  // ... other props
};

// Overlay template - full-screen immersive experience
const overlayProps: EventGamePlayProps = {
  template: WidgetTemplate.OVERLAY,
  // ... other props
};

Supported Outcome Types

EventGamePlay supports flexible prediction types for various event scenarios:

Boolean Outcomes:

  • BOOLEAN - Yes/No predictions (e.g., "Will the total points exceed 225?")

Number Outcomes:

  • NUMBER - Numeric predictions with optional min/max validation (e.g., "How many total points will be scored?")

Enum Outcomes:

  • ENUM - Multiple choice selection from predefined options (e.g., "Who will be the game's leading scorer?")

Free Input Outcomes:

  • FREE_INPUT - Open text input for custom predictions (e.g., "What will be the exact final score?")

Game Status States

Event games have 5 distinct status states:

  • PENDING - Not yet open for predictions
  • OPEN - Ready for predictions (default state)
  • LIVE - Event has started, no new predictions accepted
  • CLOSED - Event finished, backend resolving predictions
  • SETTLED - Predictions resolved, leaderboard available

Countdown Timer

Enable countdown timer to show time remaining for predictions:

<EventGamePlay {...otherProps} showCountdown={true} />

The countdown timer:

  • Displays when Event Game status is OPEN
  • Shows days, hours, minutes, and seconds remaining
  • Uses predictionsCutoff from the Event Game data
  • Automatically hides when cutoff time is reached

Points System

Enable points display to show potential rewards:

<EventGamePlay {...otherProps} showPoints={true} />

Points system features:

  • Shows potential points for each fixture
  • Mobile-friendly tooltip display

Prediction Details

Show detailed prediction results and explanations:

<EventGamePlay {...otherProps} showPredictionDetails={true} />

When enabled, users see:

  • Tabulated interface showing all predictions
  • Correct vs incorrect prediction highlighting
  • Comparison with correct outcomes

Additional CTA Configuration

Add an extra call-to-action button to the event game results screen using the additionalCTA prop.

import { AdditionalCTADetails } from "fansunited-frontend-core";

// Custom component
const additionalCTA: AdditionalCTADetails = {
  component: <CustomCTAButton />,
};

// Basic CTA with onClick handler
const additionalCTA: AdditionalCTADetails = {
  defaultLabel: "View Leaderboard",
  onClick: () => {
    // Handle click logic
    console.log("Additional CTA clicked");
  },
};

// CTA with URL navigation
const additionalCTA: AdditionalCTADetails = {
  defaultLabel: "Event Details",
  url: "https://your-website.com/event-details",
  target: "_blank", // or "_self"
};

<EventGamePlay
  {...otherProps}
  additionalCTA={additionalCTA}
/>;

Priority Order:

  1. Custom Component - If additionalCTA.component is provided, it will be rendered
  2. Click Handler - If additionalCTA.onClick is provided, a button with the handler will be rendered
  3. URL Navigation - If additionalCTA.url is provided, a button will be rendered and clicking will navigate to the URL

Placement:

  • Standard variant: Displayed after prediction summary
  • Split variant: Displayed after prediction summary
  • Overlay variant: Displayed after prediction summary

Examples

Basic Event Game
import { EventGamePlay } from "fansunited-frontend-components";
import { WidgetTemplate } from "fansunited-frontend-core";

<EventGamePlay
  entityId="event-game-123"
  sdk={sdkInstance}
  template={WidgetTemplate.STANDARD}
  language="en"
/>;
Advanced Event Game
<EventGamePlay
  entityId="event-game-123"
  sdk={sdkInstance}
  template={WidgetTemplate.OVERLAY}
  language="en"
  showCountdown={true}
  showPoints={true}
  showPredictionDetails={true}
  themeOptions={{
    mode: "dark",
    colorSchemes: {
      dark: {
        textPrimary: "#ffffff",
        surface: "#1a1a1a",
      },
    },
  }}
/>
Customized Layout
<EventGamePlay
  entityId="event-game-123"
  sdk={sdkInstance}
  template={WidgetTemplate.STANDARD}
  imagePosition="right"
  language="en"
  showCountdown={true}
  showPoints={true}
  themeOptions={{
    mode: "light",
    customFontFamily: {
      light: {
        primary: "Inter, sans-serif",
        secondary: "Roboto, sans-serif",
      },
    },
  }}
/>

Available Components

This package exports the following components:

  • ClassicQuizPlay - Traditional quiz with scoring and explanations
  • PollVote - Interactive polling with real-time results
  • CollectLead - Lead collection forms with custom fields
  • PersonalityQuizPlay - Personality assessment with persona matching
  • MatchQuizPlay - Football match prediction quiz with multiple markets
  • EventGamePlay - Event prediction game with flexible outcome types

Related Packages