Dashboard half of Rosmi720/XC_VM@8fa1e67f, which 78d7b232 left out over
tenant scoping. Same three panels, built on the endpoints that already
enforce the reseller's scope instead of on fresh SQL in the controller.
- Connections by Location: world map plus a top-countries breakdown, from
one `lines_activity` query joined onto `lines`. Gated on
save_closed_connection + dashboard_map and only ships jsvectormap once
there is something to paint, mirroring the admin dashboard.
- Live Connections: the ./table?id=live_connections serverSide table the
Live Connections page uses, five rows, kill button included. Rendered
only with reseller_client_connection_logs.
- Recently Added: Streams / Movies / Episodes tabs over
./table?id=streams|movies|episodes, newest first. Rendered only with
can_view_vod.
- Recent Activity and Expiring Lines become DataTables (sort, search,
paging) instead of fixed-height scroll boxes.
- Activity rows: text-dark / text-secondary -> text-body /
text-body-secondary. The Bootstrap 5.3 `text-dark` is near-black, so
those links were unreadable on the dark skin.
- Tolerate a request that lost its user: the controller and the shell now
fall back to '' / 0 instead of fataling on $rUserInfo['username'] and
['member_group_id'].
Changed on import:
- No unscoped fallbacks. Upstream re-ran the country, movie and live
stream queries without the tenant filter whenever the scoped one came
back empty, and never scoped series or episodes at all, so an empty
reseller saw the whole panel's data. Empty scope now means empty panel,
which is what ResellerTableRenderer does everywhere else.
- Drop the hardcoded 'EG' fallback for connections GeoIP could not place;
those rows are left out of the map instead of being pinned to Egypt.
- $rCanVod reads the can_view_vod permission. Upstream set it to a literal
true, which showed the media panels to resellers without VOD access.
- No CategoryService::getAll() alias and no category-name resolver: the
table endpoints already return a resolved category per row.
- No stream_view links. That route is registered for admin only, so the
per-row links and View buttons upstream added would 404 for a reseller.
(Seven existing reseller views have the same dead link — separate fix.)
- Only the three strings the panels ask for, not all 138 upstream keys;
the rest are already present or unreferenced.
Verified: 869 tests, make gates, CRAP gate, PHPStan. Visual layout still
wants a browser pass.
Refs: #148