# Tenant Preferences — Timezone & Delivery Hour

Admins can update their tenant's timezone and scheduled-mail delivery hour from a settings screen. The backend validates against the full IANA timezone database. All other preference keys (labels, units, currency, etc.) are read-only from the frontend perspective and are set by the superadmin.

---

## Endpoints

### `GET /timezones` — timezone picker data source

No auth required. Call once on settings screen mount to populate the timezone dropdown. Response is a flat array of valid IANA identifiers (~590 entries).

```json
{
  "data": [
    "Africa/Abidjan",
    "Africa/Nairobi",
    "Indian/Mauritius",
    "Europe/Paris",
    "UTC"
  ]
}
```

Cache this locally (session or module-level constant) — the list never changes between app versions.

---

### `GET /preferences` — current tenant preferences

Auth: Admin JWT.

Returns the full merged preference object for the authenticated admin's tenant. This is the same object returned inside `data.preferences` on login, but useful after an update to sync state without a full re-login.

```json
{
  "status": true,
  "message": "Tenant preferences",
  "data": {
    "water_label":       "CWA",
    "electricity_label": "CEB",
    "water_unit":        "m3",
    "electricity_unit":  "KWH",
    "gas_unit":          "m3",
    "currency":          "Rs.",
    "currency_position": "before",
    "date_format":       "d M Y",
    "wma_volume_ratio":  1.0,
    "signatory_name":    "The Syndic",
    "email_languages":   ["en", "fr"],
    "timezone":          "Indian/Mauritius",
    "delivery_hour":     22
  }
}
```

---

### `PATCH /preferences` — update timezone / delivery hour

Auth: Admin JWT.  
Both keys are optional — send only the ones being changed.

**Request body**

```json
{
  "timezone": "Africa/Nairobi",
  "delivery_hour": 18
}
```

| Field | Type | Constraints |
|---|---|---|
| `timezone` | string | Must be a valid IANA identifier (validated against `GET /timezones` list) |
| `delivery_hour` | integer | 0–23 (interpreted as the hour in the tenant's own timezone) |

**Success response — 200**

Returns the full updated preference object (same shape as `GET /preferences`). Replace the locally cached preferences with this response.

```json
{
  "status": true,
  "message": "Preferences updated",
  "data": {
    "timezone":      "Africa/Nairobi",
    "delivery_hour": 18
  }
}
```

**Validation error — 422**

```json
{
  "message": "The timezone must be a valid IANA timezone identifier (e.g. Indian/Mauritius, Africa/Nairobi)."
}
```

---

## UI flow

```
Settings screen mounts
  ├─ GET /timezones  →  populate <select> with IANA list
  └─ read preferences.timezone + preferences.delivery_hour from login state
       (or GET /preferences if state was lost)

User picks a timezone and/or delivery hour → clicks Save
  └─ PATCH /preferences { timezone, delivery_hour }
       ├─ 200  →  update local preferences state with response.data
       │           show success toast
       │           re-render any date displays that use the timezone
       └─ 422  →  show validation message inline on the field
```

---

## Notes for the Vue implementation

**Seeding the dropdown:** The IANA list is long (~590 entries). Consider grouping by continent prefix (everything before `/`) or pre-filtering to a curated shortlist relevant to your market, with a free-text search fallback for edge cases.

**Displaying the current hour:** `delivery_hour` is the hour in the **tenant's own timezone**, not UTC. If you show a preview ("emails will be sent at 10:00 PM"), derive it directly from the stored value — no conversion needed.

**After a successful PATCH:** The login response `data.preferences` in your Vuex/Pinia store will be stale. Replace it with `response.data` from the PATCH response — the backend returns the full merged object so you don't need a second request.

**Timezone display:** IANA identifiers like `Indian/Mauritius` are machine-readable but unfriendly. Consider mapping common identifiers to display labels on the frontend (e.g. `Indian/Mauritius → Mauritius (UTC+4)`). The backend stores and validates the raw IANA string regardless of how it's displayed.
