# FansUnited React Widgets — Documentation

> Purpose: **Embed mini‑game widgets powered by the FansUnited SDK**. The bundle scans for placeholder `<div>`s with data‑attributes and mounts interactive widgets into them.

*Last updated: 2025‑08‑12*

---

## 1) Overview

**Project name:** `fansunited-react-widgets`\
**Version:** `0.3.6`\
**Runtime:** Preact 10 (via Vite)\
**SDK:** `fansunited-sdk-esm`\
**Output:** Single IIFE bundle named → `public/docs/fu-r-widgets.js`

### What it does

- Looks for widget **placeholders** in the DOM (e.g. a `div` with a specific data‑attribute `data-fu-widget="WIDGET_TYPE"`).
- Hydrates each placeholder with the correct **mini‑game** component.
- Uses FansUnited SDK for data/auth.

> **Note:** Core entry is `src/fu-r-widgets.jsx` (referenced in `vite.config.js`).

---

## 2) Quick Start (Dev & Build)

### Install

```bash
# Installation
yarn install
```

### Scripts (from package.json)

```bash
# Start dev server (Vite)
yarn dev

# Build production bundle (IIFE)
yarn build

# Deploy helper (deploys on jsdelivr.com package fansunited-react-widgets)
yarn deploy
```

Build output: `public/docs/fu-r-widgets.js` (global name: `FuReactWidgets`).

---

## 3) Embedding on a Host Website

### 3.1 Include the bundle

```html
<script src="/path/to/fu-r-widgets.js"></script>
```
or
```html
<script src="https://cdn.jsdelivr.net/npm/fansunited-react-widgets@0.3.6/public/docs/fu-r-widgets.js"></script>
```
> **Note:** There could be a newer version.

> Host this file from your CDN/site. The bundle registers a `window.FuReactWidgets` global.

### 3.2 Add placeholders

Use simple markup where the widget should appear.

```html
<!-- Example placeholder -->
<div
  data-fu-widget="poll"
  data-fu-content-id="POLL_ID"
></div>
```

**Attribute schema:**

- `data-fu-widget` — widget type (e.g. `poll`, `poll-lists`, `classic-quiz`, `classic-quiz-lists`, `article-topx-widget`, `topx-game`, `match-quiz`, `match-quiz-lists`, `match-quiz-card`,  `my-leaderboard`, `trophies`).
- `data-fu-content-id` — (used on some widgets) The id of the selected widget.

> Each widget can have its own exclusive attributes.

### 3.3 Initialization

**Auto‑init:** the bundle scans on `DOMContentLoaded` and mounts automatically.

```html
<script>
  // Example
  document.addEventListener("DOMContentLoaded", function() {
      FuReactWidgets.init({
          fansUnited: {
              apiKey: "FANS_UNITED_API_KEY",
              clientId: "FANS_UNITED_PROJECT_NAME",
              lang: "LANGUAGE_CODE" // Two-letter ISO 639-1
          },
          labels: { // JSON with the translation labels
              "next":"Seguinte",
              "previous":"Anterior"
          }, 
          routes: { // Your project's routes
              loginUrl: '/oauth/ringier-connect/redirect-to-login',
              matchQuiz: {
                  url: "/fans-arena/match-quiz/{id}",
              },
              classicQuiz: {
                  url: "/fans-arena/classic-quiz/{id}",
              },
          },
      });
  });
</script>
```

---

## 4) Project Structure

- `src/fu-r-widgets.jsx` — **Entry** that exposes the scanning and initialization logic.
- `src/App.jsx` / `src/main.jsx` — local demo/app shell (not shipped in the IIFE).
- `src/components/`
    - `ProgressBar.jsx`, `GenericPopup.jsx`, `LeadPopup.jsx`, `UnloggedPopupComponent.jsx` — shared UI used by widgets.
- Other feature folders (Quizzes, Leaderboards, Poll, etc.) as referenced by Vite aliases in `vite.config.js`.

**Aliases** (from `vite.config.js`): `@assets`, `@classic-quiz`, `@components`, `@helpers`, `@leaderboards`, `@match-quiz`, `@services`, `@topx`, `@trophies`, `@pages`, `@poll`.

---

## 5) Styling & Theming

- Ship **scoped CSS** with BEM‑like prefixes (e.g., `.fu-r-widget__*`).
- All CSS rules are included in `src/fu-r-widgets.scss`
- During build time, the css is compiled and included in `fu-r-widgets.js`
- On initialization the script is injecting the CSS into the website's header.

---

## 6) Deployment

- `yarn build` → `public/docs/fu-r-widgets.js`.
- `yarn deploy` → Push to jsdelivr.net CDN; version using the package version (e.g., `/0.3.6/public/docs/fu-r-widgets.js`).

---

## 7) Host Integration Cheatsheet

```html
<!-- 1) Include the bundle -->
<script src="https://cdn.jsdelivr.net/npm/fansunited-react-widgets@0.3.6/public/docs/fu-r-widgets.js"></script>

<!-- 2) Include the initialization script -->
<script>
    document.addEventListener("DOMContentLoaded", function() {
        FuReactWidgets.init(config) // See chapter 3.3 for config details
    });
</script>

<!-- 3) Place a placeholder where you want the widget -->
<div data-fu-widget="poll" data-fu-content-id="RXTgvgN8srpgQBInhZdv7"></div>
```

---

## 8) Widget placeholder reference

```html
<!-- Poll List -->
<div 
    data-fu-widget="poll-lists" 
    data-limit="50"
></div>

<!-- Poll Widget -->
<div 
    data-fu-widget="poll" 
    data-fu-content-id="POLL_ID"
></div>

<!-- Classic Quiz List -->
<div
    data-fu-widget="classic-quiz-lists"
    data-fu-splash="false" <!-- overlay on start: "true"; no splash: "false" (default); redirect flow: "redirect"; overlay above section: "above" -->
></div>

<!-- Classic Quiz Widget -->
<div
    data-fu-widget="classic-quiz"
    data-fu-content-id="CLASSIC_QUIZ_ID"
    data-fu-splash="false" <!-- same options as Classic Quiz List -->
></div>

<!-- Match Quiz List -->
<div 
    data-fu-widget="match-quiz-lists" 
    data-limit="2"
></div>

<!-- Match Quiz Card (displays a card that redirects to the actual match quiz)-->
<div
    data-fu-widget="match-quiz-card"
    data-fu-content-id="MATCH_QUIZ_ID"
></div>

<!-- Match Quiz Widget -->
<div
    data-fu-widget="match-quiz"
    data-fu-content-id="MATCH_QUIZ_ID"
    data-fu-slider="true" <!-- true if we want the quiz to be a slider or false to display all questions vertically -->
></div>

<!-- Top X Game (the current Top X game, we can have only one at a time) -->
<div data-fu-widget="topx-game"></div>

<!-- Article TopX Widget -->
<div
    data-fu-widget="article-topx-widget"
    data-fu-content-id="TOPX_ID"
></div>

<!-- Leaderboards -->
<div
    data-fu-widget="my-leaderboard"
    data-leaderboard="LEADERBOARD_ID"
    data-limit="5" <!-- how many players to display -->
    data-paginated="true" <!-- or false for no pagination -->
    data-type="topx" <!-- type of the leaderboard, if it is TopX we display current season and overall stats -->
></div>

<!-- Trophies -->
<div 
    data-fu-widget="trophies" 
    data-type="all" <!-- all | all-simple | topX -->
></div>
```

---

## 9) Appendix

- Dependencies: `axios`, `dayjs`, `js-cookie`, `jwt-decode`, `firebase`, `wouter`, `fansunited-sdk-esm`.
- Dev tooling: Vite 7, Prettier, ESLint, Preact preset.
