# Super Admin Panel cPanel Deploy Guide

1. Zip the `super-admin-panel` folder from your local project.
2. In cPanel, open **File Manager** for your host document root (example: `master.sellxify.com`).
3. Upload the zip and extract it so this path exists: `.../super-admin-panel/super-admin.html` (or, for a **dedicated subdomain** whose document root *is* the panel folder, `super-admin.html` at domain root).
4. Ensure **[`.htaccess`](super-admin-panel/.htaccess)** is deployed with the panel when the vhost document root is that folder: it redirects `/` → `/super-admin.html` and sends **`Cache-Control: no-store`** for `.html/.htm/.js/.css` (requires Apache **`mod_rewrite`** and **`mod_headers`**). If headers do not apply, check cPanel → Select PHP Version → Extensions / EasyApache modules, or ask hosting to enable `mod_headers`. **Apache-only**; if the panel is only a subfolder of a larger site document root, do not drop this file blindly—adjust paths or omit redirect rules so you do not hijack the main site home page.
5. Confirm these files are present inside `super-admin-panel/api`:
   - `super-admin.local.php` (define `hardcoded_admin_email` and `hardcoded_admin_password_hash` from `password_hash()`; avoid plaintext passwords)
   - `firebase-admin-bootstrap.local.php`
   - `firebase-service-account.local.json`
6. Open: `https://YOUR_DOMAIN/super-admin-panel/super-admin.html` — or, on a dedicated super-admin host, `https://YOUR_SUPERADMIN_DOMAIN/` after `.htaccess` redirect.
7. Sign in with the email and password configured in `super-admin.local.php` (never commit real credentials to git).

## Open store dashboard after create (same idea as `setup.html` redirect)

1. In [`firebase-admin-bootstrap.local.php`](super-admin-panel/api/firebase-admin-bootstrap.local.php), set optional **`store_dashboard_base_url`** to your **main storefront origin** with no trailing slash (example: `https://master.sellxify.com`). Leave empty `''` to hide the “Open store dashboard” link until configured.
2. After a successful create, the API returns **`dashboardUrl`**: `…/index.html#siteInfo=<urlencoded JSON>` with `{ clientId, subdomain, siteName }`.
3. The repo root [`index.html`](index.html) includes a small script that reads `#siteInfo=…`, validates JSON, writes **`localStorage.siteInfo`**, then strips the hash — matching how [`setup.html`](setup.html) prepares the dashboard.

## Verify “Create new site” after upload (vs old cached panel)

If the logged-in view only shows **Clients** and **Client Action** but no create form, the host is usually serving **old files** or a **cached** `super-admin.html` / `super-admin.js`.

1. In **File Manager**, open `super-admin-panel/super-admin.html` on the server and search for the text `Create new site`. If it is missing, re-upload the whole `super-admin-panel` folder from your project (do not mix old and new `api/` only).
2. Confirm `super-admin-panel/api/super-admin-create-client.php` exists next to the other `super-admin-*.php` files.
3. In the browser **View source** (or DevTools → Network → `super-admin.html` → Response), confirm you see `id="create-site-card"` and `create-site-btn`. If not, you are not hitting the updated path or cache is stale.
4. **Hard refresh** the panel (`Ctrl+Shift+R` / `Cmd+Shift+R`) or open in a private window. This repo adds `?v=` on [`super-admin.css`](super-admin-panel/super-admin.css) and [`super-admin.js`](super-admin-panel/super-admin.js) in [`super-admin.html`](super-admin-panel/super-admin.html); **increment that number** whenever you deploy panel changes so visitors always pull the latest assets without relying on cache headers.

## Quick Verification Checklist

- `super-admin-auth-check.php` returns success only when a valid PHP session exists (it does not call Firebase Auth; “super admin” here means “logged in via super-admin-login.php”).
- Super admin can see clients in list.
- **Create site** (`super-admin-create-client.php`): creates a Firebase Auth user with the storefront Web API key, `POST`s a new `clients/{id}` record (same default catalog as `setup.html`, plus `wallet.balance: 0` and top-level `subdomain`), and patches `publicSiteMappings`, `userSites`, and `usersByEmail`. Requires `firebase_web_api_key` in `firebase-admin-bootstrap.local.php` (Identity Toolkit sign-up must be allowed for that key / project). Rate limit: 10 creations per super-admin session per rolling hour. Optional: set `store_dashboard_base_url` to receive `dashboardUrl` and use **Open store dashboard** (see section above).
- Status change works (`active/suspended`).
- Wallet adjust works and writes log in `superAdminLogs`. Per-client wallet updates are serialized on this server with a file lock (not a distributed RTDB transaction).
- Optional impersonation endpoint writes a token under RTDB `superAdminImpersonation/<token>`. The main client dashboard does not consume this token yet; to use it, add app logic that reads that node (verify `expiresAt`, `used === false`, matching `clientId`), marks `used`, then sets the admin session / `siteInfo` for that client—prefer short-lived tokens and HTTPS only.

## Troubleshooting `super-admin-list-clients.php` / empty client table

1. Open the browser **Network** tab, reload, select `super-admin-list-clients.php`, and note **Status** and **Response** body.
2. **HTTP 403** — No valid PHP session: sign out, sign in again via `super-admin-login.php`. If the panel lives under a subdirectory (e.g. `/super-admin-panel/`) and cookies behave oddly, set optional `'session_cookie_path' => '/super-admin-panel/'` in `super-admin.local.php` (must end with `/` and cover both `super-admin.html` and `api/` paths).
3. **HTTP 503** — Missing or invalid `super-admin.local.php`, `firebase-admin-bootstrap.local.php`, service account JSON path, or Google OAuth token error; the JSON body usually includes `message`.
4. **HTTP 500** with `Failed to load clients` — Firebase RTDB read failed (wrong `firebase_database_url`, rules, or network).
5. **Non-JSON response** (HTML, PHP notice, or empty) — PHP error or wrong URL (404). Fix server PHP errors or ensure you open `super-admin.html` from the correct folder so `./api/...` resolves.

After deploying the latest `super-admin.js`, error text in the panel includes **HTTP status** and a short **response snippet** when the server does not return JSON `message`.

## Firebase project (arafstore-14938)

The storefront uses shared client config in the repo root: `firebase-config.js` and `firebase-config-compat.js` (Realtime Database URL and Web API key must match this project).

On the server, `super-admin-panel/api/firebase-admin-bootstrap.local.php` must set:

- `firebase_database_url` — same RTDB URL as in `firebase-config.js` (`https://arafstore-14938-default-rtdb.firebaseio.com`)
- `firebase_web_api_key` — same Web API key as in `firebase-config.js`
- `service_account_json_path` — path to a **service account JSON** downloaded from Firebase Console for **arafstore-14938** (Project settings → Service accounts → Generate new private key). Copy `api/firebase-service-account.example.json` as a template, or save the download as `firebase-service-account.local.json`. Old JSON from another project will cause token or permission errors.

The main site’s `api/firebase-admin-bootstrap.local.php` and `api/firebase-service-account.local.json` should be updated the same way when pointing the whole stack at arafstore-14938.

**Key rotation:** If a service account JSON was ever exposed, delete that key in Google Cloud Console (IAM → Service Accounts → Keys) and replace both local JSON files with a newly generated key.

**Smoke test (on a machine with PHP):** from `super-admin-panel/api`, run:
`php -r "require_once 'firebase-rtdb-admin.php'; $b=include 'firebase-admin-bootstrap.local.php'; $t=firebase_service_account_access_token($b['service_account_json_path']); echo isset($t['access_token'])?'OK':'ERR';"`
Expect `OK`. Both `firebase-service-account.local.json` paths are listed in `.gitignore` — do not commit them.
