# Shop · Packages / Bundles — UI Parity

## Demo screens

The demo lives **inside** the Services page (`portals/shop/Services.tsx`) as two of
five segmented tabs: Services · Routines · Add-ons · **Bundles** · **Packages**
(`Services.tsx:123-149`). Counts are shown per tab. A global "Show inactive" toggle
sits to the right (`:135-138`). One "+ Add Bundle/Package" button in the page header
adapts its label to the active tab (`:103-120`).

### Bundles grid (`Services.tsx:364-423`)
- Responsive card grid (1 / 2 / 3 cols).
- Each card: thumbnail (image or `Layers` glyph fallback), a teal **"Bundle"** badge,
  status badges, a `LifecycleActions` menu (edit / activate-deactivate / hide /
  delete), the bundle name, the **member service names joined by " + "**, optional
  **free-item pills** (attached freebies, each with a "Free" tag), and a price row
  showing the **struck-through list price** next to the bold effective price.
- Empty state: `EmptyState` with `Layers` icon + "No bundles" (`:370-371`).

### Packages grid (`Services.tsx:425-475`)
- Same card grid. Each card: thumbnail (`Package` glyph fallback), an amber
  **"N sessions"** badge, an optional teal **"Auto-renews"** badge with a `RefreshCw`
  icon, status badges, `LifecycleActions`, the package name, a line "Valid N days ·
  SAR X / session", and the bold price.
- Empty state: `EmptyState` with `Package` icon + "No packages" (`:431-432`).

### Add/Edit modal (`CatalogueModal`, `Services.tsx:856-1155`)
- Size `xl`, title adapts (Add/Edit · Bundle/Package).
- Sections: **Identity** (bilingual name [required] + bilingual description + image +
  variants), **Pricing** (3 live cards: before-discount w/ VAT split · discount
  selector none/fixed/percent as icon radios · after-discount w/ final price, savings
  %, VAT split), **Details** (bundle: included-services multiselect; package:
  sessions + validity number inputs, included-services multiselect, auto-renew toggle
  → billing-period select monthly/6mo/12mo), **Extras** (routine-before /
  routine-after / free add-ons multiselects with running "+N min"), **Agents**
  (read-only — managed in Team).
- Footer Save is **disabled until valid**, with an inline amber hint listing what is
  missing (name / price / services) (`:1149-1153, 762-767`).
- RTL: uses logical props throughout (`me-`, `pe-`, `end-`) so it mirrors under Arabic.

## Our screens

We have a **dedicated full-page CRUD** (not a tab inside Services):

### List — `frontend/views/package/index.php`
- Page header "Packages List" + shop title + a "Create Package" pill button (`:88-99`).
- Card grid 1/2/3 cols (`:103`). Each card: gradient thumbnail strip (image or `gift`
  glyph), a **status chip** that is the real `toggle-status` POST action (`:124-137`),
  name, scheduling summary line ("Always Available" / days · date range, `:60-85`),
  edit (pencil → update) + delete (trash → POST delete) icons (`:150-171`), a price
  chip + a "N Services" chip, and a list of the first 4 included service names with
  "+N more" (`:176-212`).
- Empty state: centered card, `gift` icon, "Packages List" + Create button (`:231-243`).
- Real `LinkPager` pagination, restyled (`:218-230`).

### Create/Edit — `frontend/views/package/_form.php`
- Full-page (not modal), aurora chrome, `max-w-4xl`. Back link + title + subtitle.
- Language switch tab strip for the multilang **name** (`:158-172`).
- Sections as white cards: **Package Details** (image + name + **period** [auto]),
  **Pricing** (price_before + discount + discount_type + readonly price + a
  `#calc-price` VAT-breakdown panel), **Included Services & Agents** (services Select2
  + agents Select2), **Scheduling & Availability** (active_days Select2 + start/end
  DatePickers), **Status** (dropdown). Save button at the bottom.
- Third-party widgets (Select2, DatePicker, filekit) are repainted via a scoped
  `.tw-package-form` stylesheet (`:389-512`).

## Concrete UI gaps (ours vs demo)

1. **No Bundles vs Packages split** — we have a single "Package" surface; the demo's
   two tabs (and the whole SubscriptionPackage concept) are missing.
2. **Not integrated into the Services page** — demo packages/bundles are tabs on
   Services; ours is a standalone controller/route. (Functional, but different IA.)
3. **No "Show inactive" toggle** and **no auto-hide of inactive** rows — inactive
   packages render inline with a red chip.
4. **No struck-through list price / savings** on the card (bundle) and **no
   per-session price** line (package — concept absent).
5. **No session/validity/auto-renew/billing-period UI** at all.
6. **No description field**, **no variants**, **no freebies (routines/add-ons)**
   attachment UI.
7. **No live discount feedback** (savings amount/%, "discount zeroes price" warning).
   We show only a server VAT breakdown panel.
8. **Agents are editable here** vs demo's read-only "managed in Team" section.
9. **Edit/Create is a full page**, not the demo's `xl` modal — acceptable but a UX
   divergence; no disabled-until-valid Save with a missing-fields hint (we rely on
   server-side `errorSummary`, `_form.php:146-152`).

## RTL / empty / error states

- **Empty**: both sides have a dedicated empty state (parity).
- **Error**: ours surfaces server validation via `errorSummary` in a restyled red
  container (`_form.php:146-152`); demo prevents submit client-side. Different model,
  both acceptable.
- **RTL**: ours uses logical `start/end` utilities and the Arabic layout direction
  from the aurora layout; demo uses the same logical-prop approach. Parity OK.
