# WBMCZ — deploy notes · 07 Sep 2026 (second batch)
## Frozen header row, and the user-list filter bar

**4 files. No database change.**

    includes/admin_list.php                9,262    Reset keeps the page's own audience
    admin/includes/sidebar.php            56,955    the frozen header row, shared by every page
    admin/includes/user_list_engine.php  190,820    the new filter bar, and the header row
    admin/includes/product_engine.php    153,378    the header row

Upload `includes/admin_list.php` first, then the two engines and the sidebar.

---

## 1 · THE HEADER ROW STAYS PUT — EVERY MANAGEMENT TABLE BUT ONE

The columns were already frozen sideways. Going down they were not, so past
row 20 a column of dates and a column of money looked the same.

The header row now stays at the top of its own box while the rows run under it.
For that to work the box has to be the thing that scrolls, so each table gets a
height — the same bargain a spreadsheet makes for a frozen pane.

Where the frozen row crosses the two frozen columns, those two header cells sit
highest of all, so nothing slides over them from either direction.

**Activity & Task is left alone**, as marked. It is skipped by name.

### How it reaches the other pages

The two engines carry it themselves, so that is 8 user lists, 13 catalogue
pages and 11 seller-submission pages settled at once.

Everything else — Orders, Sellers, Staff, Leads, Wallet History, Transactions
and the rest — gets it from one block in `sidebar.php`, which every admin page
already loads. That block is deliberately shy. A table is only touched when all
of this is true:

* it already sits in a wrapper that scrolls sideways
* it has a real header row and more than a handful of rows
* it is not inside a dialog

Anything else is left exactly as it was, so no page can be knocked out of shape
by this. A page that wants out can say `data-wbfz="off"` on the table.

One detail worth knowing: a sticky cell paints nothing of its own, so a header
that borrowed its colour from the row behind it would go see-through as the
rows passed under. Only the header cells that really are transparent are given
a background, so pages with their own coloured headers keep them.

---

## 2 · THE FILTER BAR, REBUILT

One line now, in the order you read a list in — **who, when, where**:

    Search  ·  From — To  ·  State  ·  District  ·  Time  ·  Search / Reset

**User Type has gone.** Every one of these pages already *is* a type — User,
Seller, Employees, Admin — so the box could only ever contradict the page you
were standing on.

**The two date boxes are on the bar in their own right.** They used to hide
behind a "Custom date…" choice in the Time box. Either end can be left blank,
so "from 01 Aug" and "up to 31 Aug" each work alone, and they narrow whatever
Time already chose rather than replacing it.

The four narrower questions — KYC, Subscription, Account, Wallet — sit under
**More filters**. It opens by itself whenever one of them is on, so nothing can
be filtering without being visible. Say the word if you would rather they went
altogether.

**Export CSV** is where it was, and still exports the list exactly as filtered,
or only the ticked rows.

---

## 3 · THE "1 FILTER ACTIVE" BANNER HAS GONE

Each of these pages writes its own audience into the filter fields on every
load. The banner counted that as a filter, so it sat there on a clean page
announcing `User type: customer` — something nobody had chosen and nobody could
turn off. What is actually switched on is visible in the boxes themselves and
in the count line under them.

---

## 4 · FOUND WHILE TESTING — RESET WAS WIDENING THE LIST

Not something you asked for, but it turned up on the way and it matters.

`Reset` handed back the bare defaults, which included **User type = all**. So
pressing Reset on the **User** page showed sellers and staff as well — 1,201
rows instead of 417. The same went for the recycle bin (Reset walked you out of
it) and for the plan-only lists.

Reset now clears what *you* chose and leaves what the *page* is. Checked on all
eight lists — fresh count and post-Reset count now match on every one:

    users_user        417      users_deleted      1
    users_seller      778      users_free       417
    users_employee      4      users_pro          0
    users_admin         2      users_all      1,201

This mattered beyond tidiness: an employee given only the User page could have
pressed Reset and seen staff accounts.

---

## CHECKED

* all four files pass `php -l`
* 68 admin pages load with no fatal, no warning and no notice
* signed in as the owner: the four user lists, the recycle bin, three catalogue
  pages, Orders, Staff, Sellers, Wallet History, Transactions and Activity &
  Task all render clean
* frozen header present on the user lists and the catalogue; **absent on
  Activity & Task**, which still has its own step-row scrollbar
* the User Type box is gone from the bar (the hidden one in the page-jump form
  stays — that is what carries your filter from page 2 to page 3)
* the dates work alone: from-only 116, to-only 5, both 116, cleared 417
* Reset holds the audience on all eight lists

**Needs your eyes:**

1. Any user list — scroll down: the column names should stay.
2. The same table — scroll right: tick box and name should stay.
3. Activity & Task — should be exactly as it was.
4. A date in **From**, nothing in **To**, press Search.
5. **More filters** → pick a KYC state → Search → the panel should still be open.
6. Press **Reset** on the User page and check the count is still 417.

---

## FILE LIST

`FILE_LIST_2026_09_07.md` already names all four of these files. Three of them
have new sizes, and `includes/admin_list.php` was not on the changed list
before — it is now. Sizes to check against after upload:

    9,262    includes/admin_list.php
    56,955   admin/includes/sidebar.php
    190,820  admin/includes/user_list_engine.php
    153,378  admin/includes/product_engine.php
