# Nadiplayer cPanel — v1.2.9 Re-upload Guide

## What's in this ZIP

```
nadiplayer/
├── .htaccess                  ← SPA routing (skips /api/)
├── index.html                 ← fresh v1.2.9 build, points at /api/
├── assets/  images/  audio/  locales/   ← static frontend
├── admin_panel/               ← optional PHP admin UI
└── api/
    ├── .htaccess              ← routes to index.php + no-cache headers
    ├── index.php              ← front controller
    ├── config.php             ← *** EDIT DB CREDENTIALS HERE ***
    ├── lib/  routes/
    └── secrets/
        └── firebase-service-account.json   (chmod 0600 if you use FCM)
```

## Admin credentials (auto-seeded on first request)

```
Username: nadinadi
Password: 0644782611
```

The PHP code re-syncs the admin password from `config.php` every request,
so just editing `ADMIN_PASSWORD` in config.php is enough to rotate it.

## Upload steps

1. **Backup** your current `public_html/4kmovies.vip/nadiplayer/` folder.
2. **Delete** the contents of `public_html/4kmovies.vip/nadiplayer/`
   (or just delete `index.html`, `assets/`, and the `api/` folder).
3. Unzip this archive locally and **upload the contents of `nadiplayer/`**
   into `public_html/4kmovies.vip/nadiplayer/`.
4. Open `api/config.php` and update **lines 15-16** with your real cPanel
   MySQL host / port / db / user / pass:

   ```php
   define('DB_HOST', '127.0.0.1'); define('DB_PORT', 3306);   // ← cPanel default
   define('DB_NAME', 'youruser_nadiplayer');
   define('DB_USER', 'youruser_nadi');
   define('DB_PASS', 'YOUR_REAL_DB_PASSWORD');
   ```

5. Visit `https://4kmovies.vip/nadiplayer/api/` — should return
   `{"message":"Hello World"}`. If yes, hit `/api/setup-db` once to
   create tables. Then login to the app with **nadinadi / 0644782611**.

6. **Purge Cloudflare cache** for the `/nadiplayer/api/*` paths
   (Cloudflare dashboard → Caching → Configuration → Purge Custom URL).
   This is critical — old cached HTML responses are why the Android
   APK was getting "Unexpected non-JSON response" before.

## What changed in v1.2.9 vs 1.2.9

* **PHP**: anti-cache headers on every API response (`Cache-Control: no-store`
  + `CDN-Cache-Control: no-store`) so Cloudflare cannot serve a stale SPA
  HTML page on `/api/*` URLs.
* **PHP**: admin defaults are now `nadinadi` / `0644782611`.
* **Frontend (Android)**: `CapacitorHttp` plugin enabled — fetch goes
  through Android's native HTTP client, no more WebView CORS quirks.
* **Frontend**: cleaner login error messages (shows the actual server
  status code & body snippet instead of a generic null-crash).
* **Frontend**: Movies / Series grid no longer collapses to thin lines on
  large screens; tiles now have explicit `aspect-[2/3]` and adaptive grid
  columns up to `2xl:grid-cols-7`.
* **Frontend**: Live TV defaults to **grid view**, channel column scales
  on TV resolutions (340 → 380 → 440 → 500 px), player frame goes up to
  1280 px wide on 4K TVs.
* **Frontend**: `PageLayout` is locked to `h-screen`, so only the inner
  list scrolls (not the whole page).

## v1.4.5 — World Cup Hub (Sports API)

Adds a server-side proxy for the World Cup / football fixtures shown
on the in-app **World Cup** tab. The mobile client NEVER sees the
upstream API key.

### New files to upload (replace if they already exist)

```
nadiplayer/api/index.php                       # added /sports + /admin/sports route dispatch
nadiplayer/api/routes/sports.php               # NEW — fixtures + standings + admin test/clear
nadiplayer/api/routes/admin.php                # adds world_cup / sports_* settings defaults
nadiplayer/api/routes/public.php               # adds `world_cup` block to /api/public/app-info
nadiplayer/admin_panel/index.php               # adds `save_sports` POST handler
nadiplayer/admin_panel/views/layout.php        # adds "World Cup" nav link
nadiplayer/admin_panel/views/sports.php        # NEW — Sports settings page
schema.sql                                     # adds optional `sports_cache` table
```

### One-time admin steps after upload

1. Open **/admin_panel/?page=sports**.
2. Sign up for a free key at <https://www.api-football.com> (the
   free tier ships with 100 requests/day — enough with the default
   300-second cache).
3. Paste the key into **API Key**, pick the **League ID**
   (`1` = FIFA World Cup), the **Season** year, and an optional
   **Cache TTL** (60..3600s, default 300).
4. Click **Test connection** — you should see
   `OK · X / 100 requests used today`.
5. Tick **Enable World Cup tab** and **Save**.

The mobile app picks up the change on its next call to
`/api/public/app-info` and the World Cup tile becomes visible.

### Endpoints exposed

* `GET  /api/sports/fixtures?league=&season=` — cached fixtures
* `GET  /api/sports/standings?league=&season=` — group standings
* `POST /api/admin/sports/test` — admin "validate new key" button
* `POST /api/admin/sports/clear-cache` — force-refresh

The `sports_cache` table is created lazily on first request, so no
SQL migration is strictly required. Schema is included in
`schema.sql` for admins who provision DB up-front.

