# SPEC — TL-194: Luxury amenities + amenity search + create defaults

Branch: `TL-194-MANAGER-Ajouter-jacuzzi-dans-les-commodités`

## Context

Enrich onboarding step 2 (« Commodités de l'établissement ») with luxury amenities for high-end
rentals, using amenities already **in-sync with Rentals United (RU) and the mobile app**; add an
in-section amenity search for better UX; and pre-check the most common amenities on a new property.

## Correctness model (evidence)

- Push is **verbatim/unvalidated** (`RentalsPayloadBuilder.php:126-131`); an invalid property-level
  AmenityID can make RU reject the whole `putProperty` (`PropertyService.php:449`). IDs are never guessed.
- Source of truth = the RU **property-level** catalog (`Pull_ListAmenities`), mirrored into the
  `amenities` table. A live Pull returned **1637**; the local DB (`thelandlbftest`, the mobile-app
  reference) holds **1640** — fully in-sync. All shipped luxury IDs were confirmed present in **both**.
- UI label = `__('amenities.'.$configKey)`; the amenity filter matches the stored RU JSON token
  (`%"@value":"<id>"%`) — token-exact, so a short id like 35 no longer collides with 135/350.

## What was built

**1. « Luxe & bien-être » accordion** (2nd, after Populaires) — **20 in-sync luxury amenities**:

| Category | Amenities (RU AmenityID) |
|---|---|
| Bien-être & spa | Sauna (365), Hammam (1489), Spa (606), Jacuzzi (35) |
| Piscines | Piscine chauffée (737), privée (816), intérieure (738), sur le toit (1090) |
| Divertissement | Home cinéma (371), Billard (647), Smart TV (852), Système de son (889) |
| Extérieur & vues | Vue mer (604), Vue panoramique (921), Accès rooftop (837), Plage privée (1087), Barbecue (408), Cheminée (364) |
| Services & tech | Borne de recharge électrique (991), Salle de sport (834) |

Search filters (property list): Jacuzzi, Sea View, Heated Pool, Private Pool, Sauna, EV Charging, Gym.

**2. In-section amenity search** (`step2.tsx`) — a search box above the amenity accordions filters
amenities across all groups by name; only groups with a match are shown (empty groups hidden), matching
groups auto-expand, and a « Aucune commodité trouvée » message shows when nothing matches. The five
hardcoded accordions were refactored into one data-driven, controlled `Accordion` (net −108 lines).

**3. Default-checked amenities on a NEW property** — config-driven `default-amenities`
`[174, 180, 789, 167, 7, 11]` = Internet, Climatisation, Chauffage, Télévision satellite, Linge &
serviettes, Machine à laver — passed as a prop and used to seed the create form's `amenities`. Edit is
untouched (loads existing).

## Files changed

| File | Change |
|---|---|
| `config/ameneties.php` | `luxury-amenities` group (20); `default-amenities`; jacuzzi moved out of popular |
| `config/ameneties-code.php` | 7 luxury search-filter labels → RU IDs |
| `app/Services/PropertyService.php` | token-exact amenity filter |
| `app/Http/Controllers/PropertyController.php` | map `luxury-amenities` (create+edit); `default-amenities` (create) |
| `resources/js/pages/logements/index.tsx` | luxury labels in `amenitiesOptions` |
| `resources/js/pages/logements/steps/step2.tsx` | data-driven searchable accordions + luxe group |
| `resources/js/pages/logements/create.tsx`, `edit.tsx` | `luxuryAmenities` prop; create seeds defaults |
| `lang/{fr,en}/amenities.php` | luxury labels (18 new) |
| `lang/{fr,en}/properties/step2.php` | `luxury_amenities`, `search_amenity`, `no_amenity_found` titles |
| `tests/Feature/Property/PropertyIndexFiltersTest.php` | luxe config contract, token-exact filter, defaults |

## Verification done

- PHP lint clean; `luxury-amenities` resolves 20 (correct fr/en labels); removed items gone;
  `default-amenities` = the 6 expected IDs; Concierge filter removed.
- **Tests: 5 passed / 61 assertions.**
- **tsc: zero new errors** in touched files (`step2.tsx` fully clean); 490 total = pre-existing baseline.

## Remaining before merge

1. **Live RU round-trip** — push a test property with a few luxe amenities; confirm
   `Push_PutProperty_RS Status = Success` (needs working RU outbound; prod flagged down).
2. **Restart dev server / rebuild** to see the accordion + search (Vite HMR won't reflect the edits).
3. Not committed — awaiting sign-off.

## Notes

- « Télé » default mapped to Télévision satellite (167), the only TV in the establishment popular group.
- ~34 more in-sync luxury candidates exist (Ocean View 729, Hot Tub 391, Outdoor Pool 740, Steam room
  607, Massage 718…) if the set should grow.
- Latent (out of scope): « Water View » filter uses `228` while onboarding uses `937` for « Vue sur
  l'eau »; new « Sea View » filter uses `604`.
