# SFM Quick Facts Widget

Lightweight widget to render Sendai Framework Monitor (SFM) quick fact. Utilizes UNDRR Datum (DataHub) as a conduit.

- **Parent issue**: [web-backlog #2389](https://gitlab.com/undrr/web-backlog/-/issues/2389)
- **Quick start**: see `sfm-quick-facts.html`
- **Sample data**: `data/sample/mock.json`, `data/sample/mock-invalid.json`

## Adding the SFM Widget to Drupal

Want to embed the SFM Quick Facts widget in your Drupal site using the Gutenberg editor? Here’s how (don’t worry, it’s easier than assembling IKEA furniture).

### 1. Navigate to Your Page

- Go to the Drupal page where you want the widget to appear.
- Click **Edit** to open the Gutenberg editor.

### 2. Add a Custom HTML Block

- Click the **+** button to add a new block.
- Search for **"Custom HTML"** and select it from the list.

### 3. Paste the Widget Code

Copy the code below and paste it into the Custom HTML block:

```html
<div class="sfm-widget-sample-container"></div>
<link rel="stylesheet" href="https://assets.undrr.org/projects/sfm-quick-facts/sfm-widget-embedded.css">
<script src="https://assets.undrr.org/projects/sfm-quick-facts/sfm-widget.js"></script>
<script>
setTimeout(function() {
  if (window.SFMWidget) {
    window.SFMWidget.init({
      selector: ".sfm-widget-sample-container",
      // override as needed, see below
      options: {
        count: 1,
        countries: ["Algeria"]
      }
    });
  }
}, 500);
</script>
```

### 4.  Multiple Widgets on Same Page?

Use different CSS selectors for each widget:

```html
<div class="sfm-widget-sample-container-1"></div>
<div class="sfm-widget-sample-container-2"></div>

<script>
// Initialize first widget
window.SFMWidget.init({
  selector: ".sfm-widget-sample-container-1",
  // ... configuration
});

// Initialize second widget
window.SFMWidget.init({
  selector: ".sfm-widget-sample-container-2",
  // ... configuration
});
</script>
```

#### 4. Preview and Save

Click **Preview** to see how the widget looks. If everything appears correctly, click **Save** or **Publish** to make the changes live.

#### 5. Customize (Optional)

You can customize the widget by modifying the options in the initialization code:

- `count`: Change to display multiple facts (e.g., `count: 3`)
- `random`: Set to `false` to show facts in order

---

## Troubleshooting

### Widget Not Appearing?

- Ensure you're using the **Custom HTML** block, not a regular text block.
- Check that the script URLs are accessible from your Drupal site.
- Clear your browser cache and Drupal cache.
- Check the browser console for any JavaScript errors.

### Styling Issues?

- Your theme's CSS might be overriding widget styles.
- Add custom CSS in your theme to adjust the appearance.


## Configuration Options

The widget accepts a configuration object with the following properties:

| Property   | Type   | Description                             | Status       |
| ---------- | ------ | --------------------------------------- | ------------ |
| `selector` | String | CSS selector for target container(s)    | **Required** |
| `endpoint` | String | URL to fetch JSON data from             | **Required** |
| `map`      | Object | Field mapping configuration (see below) | **Required** |
| `options`  | Object | Additional display and styling options  | Optional     |

### Field Mapping (`map`)

Map your JSON data structure to widget fields using dot notation:

| Field         | Maps To                    | Example Value           | Status       |
| ------------- | -------------------------- | ----------------------- | ------------ |
| `year`        | Year of the event          | 2024                    | **Required** |
| `countryName` | Country name               | "Uruguay"               | **Required** |
| `countryCode` | ISO3 country code (for filters) | "URY"                | Optional     |
| `count`       | Number affected            | 843                     | **Required** |
| `unit`        | Impact type                | "affected", "displaced" | Optional     |
| `region`      | Specific region/department | "Florida Department"    | Optional     |
| `tailText`    | Additional context         | "by floods"             | Optional     |
| `tag`         | Category label             | "local"                 | Optional     |
| `linkUrl`     | Analytics/details URL      | "https://..."           | Optional     |
| `linkText`    | Link display text          | "View Details"          | Optional     |

### Options (`options`)

Configure widget behavior and styling:

| Option   | Type    | Default | Description                                                                    |
| -------- | ------- | ------- | ------------------------------------------------------------------------------ |
| `count`  | Number  | `1`     | Number of facts to display (1 or more)                                         |
| `random` | Boolean | `true`  | Randomize fact selection when count > 1. Set to false for sequential selection |
| `countries` | String or Array | — | Filter by country names (case-insensitive). Accepts "Uruguay", "Uruguay,Brazil" or ["Uruguay", "Brazil"]. |
| `cc3`    | String or Array | — | Filter by ISO3 country codes (case-insensitive). Accepts "URY", "URY,BRA" or ["URY", "BRA"]. |

Note: `countryNames` is an alias of `countries`, and `countryCodes` is an alias of `cc3`.

### Filter by Country

Use either human-readable names or ISO3 codes. Names and codes can be provided as a comma-separated string or an array.

```html
<div class="sfm-widget-sample-container"></div>
<link rel="stylesheet" href="https://assets.undrr.org/projects/sfm-quick-facts/sfm-widget-embedded.css">
<script src="https://assets.undrr.org/projects/sfm-quick-facts/sfm-widget.js"></script>
<script>
window.SFMWidget.init({
  selector: ".sfm-widget-sample-container",
  options: {
    // Example using country names
    countries: ["Uruguay", "Brazil"],

    // Or, example using ISO3 codes
    // cc3: "URY,BRA"
  }
});
</script>
```

## Data update workflow

Follow these steps to update the SFM Quick Facts data:

### 1. Access the Source Data

The Quick Facts data is maintained in an Excel spreadsheet on SharePoint. Authorized users can access and edit this file to update the facts displayed by the widget.

- **Location:** SharePoint `[specific path to be provided]`
- **Format:** Excel (.xlsx) following the CSV structure above
- **Access:** Request edit permissions from the data management team

### 2. Edit the Data

Make your updates in the Excel file following these guidelines:

- Ensure all required fields are filled
- Use proper country codes (ISO 3166-1 alpha-3)
- Format large numbers with commas for readability
- Keep text descriptions concise and clear
- Verify URLs in the Link column are valid

### 3. Request Data Ingestion

After updating the Excel file, contact the Datum FP to process the update. As of September 2025, that's Ryan.

## Data Management & Updates

The SFM Quick Facts data is managed through a structured process that ensures data quality and consistency.

### Data Source & API Structure

The live data is available via the UNDRR Data Hub API: https://data.undrr.org/api/json/preventionweb/sfm-quick-facts/1.0.0

The API returns data in the standard DataHub structure with records wrapped in a `data[]` array:

```json
{
  "data": [
    {
      "id": "unique-identifier",
      "year": 2024,
      "country": {
        "name": "Uruguay",
        "cc3": "URY"
      },
      "metrics": {
        "unit": "Affected",
        "metric": 843
      },
      "target": "B",
      "region": "Florida Department",
      "insight": "people whose livelihoods were lost or disrupted",
      "labels": ["local"],
      "links": {
        "analytics": "https://example.com/analytics/123"
      }
    }
    // ... more records
  ],
  "totalCount": 16
}
```

### CSV Data Format

The source data is maintained in CSV format following this structure:

| Column      | Description                                      | Example                           | Required |
| ----------- | ------------------------------------------------ | --------------------------------- | -------- |
| `Target`    | Sendai Framework target (A, B, or C)             | A                                 | Required |
| `Country`   | Full country name                                | Guatemala                         | Required |
| `CC3`       | 3-letter ISO country code                        | GTM                               | Required |
| `Year`      | Year of the data                                 | 2024                              | Required |
| `Indicator` | Type of metric (Deaths, Affected, Economic loss) | Deaths                            | Required |
| `Value`     | Numeric value (can include formatting)           | 47,500,000                        | Required |
| `Text`      | Additional context or description                | due to landslides                 | Optional |
| `Tags`      | Category labels (hazard, local, etc.)            | hazard                            | Optional |
| `Link`      | URL for detailed analytics                       | https://example.com/analytics/123 | Optional |

#### Example CSV Data

```csv
Target,Country,CC3,Year,Indicator,Value,Text,Tags,Link
A,Guatemala,GTM,2024,Deaths,709,,,,
A,Indonesia,IDN,2024,Deaths,213,due to landslides,hazard,
B,Brazil,BRA,2024,Affected,"47,500,000",representing 22% of total population,,
B,Uruguay,URY,2024,Affected,843,people whose livelihoods were lost or disrupted in the Florida Department,local,https://example.com/analytics/123
C,Romania,ROU,2024,Economic loss,100,Hectares of Agave fibres crops were destroyed,,
C,Colombia,COL,2024,Economic loss,"28,200",hectares of forest area were affected by forest fires,hazard,
```

## Data Validation Rules

Ensure your data meets these validation requirements:

### Required Fields

- **Target:** Must be A, B, or C
- **Country:** Valid country name matching ISO standards
- **CC3:** Valid ISO 3166-1 alpha-3 country code
- **Year:** Four-digit year (e.g., 2024)
- **Indicator:** One of: Deaths, Affected, Economic loss
- **Value:** Numeric value (commas allowed for formatting)

### Optional Fields

- **Text:** Additional context (max 100 characters recommended)
- **Tags:** Comma-separated if multiple (e.g., "hazard,local")
- **Link:** Must be a valid URL starting with https\://

### Target Definitions

- **Target A:** Substantially reduce global disaster mortality
- **Target B:** Substantially reduce the number of affected people
- **Target C:** Reduce direct disaster economic loss
