# Spartan River Report Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Build a single-page Spartan River Report video archive that auto-discovers MP4s from a dedicated server folder and plays them in a modal lightbox.

**Architecture:** `river_report.php` globs `public/assets/video/river_report/*.mp4`, parses month/year from each filename, sorts reverse-chronologically, and renders a card grid. Clicking a card opens a modal `<video>` player. No database, no hardcoded list — adding a new month means dropping a file in the folder.

**Tech Stack:** PHP 8, vanilla JS (no framework), existing intranet CSS classes (`card-container`, `link-card`), inline `<style>` block for modal (same pattern as `public/hr/pitstop/video.php`).

---

## File Map

| Action | Path | Responsibility |
|--------|------|---------------|
| Create dir | `public/assets/video/river_report/` | Holds all River Report MP4s |
| Create | `public/executive/river_report.php` | Discovery, card grid, modal player |
| Modify | `public/menu.php` | Add top-level nav link before HR dropdown |

---

## Task 1: Create video directory and drop renamed files in

**Files:**
- Create: `public/assets/video/river_report/`

- [ ] **Step 1: Create the directory**

```bash
mkdir -p public/assets/video/river_report
```

- [ ] **Step 2: Move/rename the two existing Clayton videos into it**

Rename on server (ssh `ww_secure`, web root `/var/www/whitewater-secure`):

```bash
# On the server — Eric handles this
mv public/assets/video/ClaytonLeadershipAlignment_Jan2026.mp4 \
   public/assets/video/river_report/RiverReport_Jan_2026.mp4

mv public/assets/video/Clayton_Monthly_Leadership_Mar_2026.mp4 \
   public/assets/video/river_report/RiverReport_Mar_2026.mp4
```

- [ ] **Step 3: Verify the folder contains both files**

```bash
ls public/assets/video/river_report/
```

Expected:
```
RiverReport_Jan_2026.mp4
RiverReport_Mar_2026.mp4
```

---

## Task 2: Add nav link to menu.php

**Files:**
- Modify: `public/menu.php` — insert one `<a>` tag before line 89

- [ ] **Step 1: Open `public/menu.php` and locate the HR dropdown (around line 89)**

Find this block:
```php
    <div class="dropdown">
        <button class="dropbtn<?= nav_active('/hr', false) ?>">HR <i class="fa fa-caret-down"></i></button>
```

- [ ] **Step 2: Insert the Spartan River Report link immediately before the HR dropdown**

Insert this line before the `<div class="dropdown">` that opens the HR section:

```php
    <a class="nav-link<?= nav_active('/executive/river_report.php') ?>" href="<?= htmlspecialchars(app_url('/executive/river_report.php'), ENT_QUOTES) ?>">Spartan River Report</a>

    <div class="dropdown">
        <button class="dropbtn<?= nav_active('/hr', false) ?>">HR <i class="fa fa-caret-down"></i></button>
```

- [ ] **Step 3: Verify in browser**

Load `http://whitewater-secure/public/home.php` and confirm "Spartan River Report" appears in the nav bar before "HR". Clicking it should 404 (page doesn't exist yet — that's expected at this step).

- [ ] **Step 4: Commit**

```bash
git add public/menu.php
git commit -m "feat: add Spartan River Report nav link"
```

---

## Task 3: Create `river_report.php`

**Files:**
- Create: `public/executive/river_report.php`

- [ ] **Step 1: Create the directory**

```bash
mkdir -p public/executive
```

- [ ] **Step 2: Create `public/executive/river_report.php` with the full implementation**

```php
<?php
declare(strict_types=1);
require __DIR__ . '/../../app/bootstrap_env.php';
requireLogin();

// Auto-discover videos from the river_report folder
$video_dir = __DIR__ . '/../assets/video/river_report/';
$files     = glob($video_dir . '*.mp4') ?: [];

$videos = [];
foreach ($files as $file) {
    $basename = basename($file);
    if (preg_match('/^RiverReport_([A-Za-z]+)_(\d{4})\.mp4$/i', $basename, $m)) {
        $date = DateTime::createFromFormat('M Y', ucfirst(strtolower($m[1])) . ' ' . $m[2]);
        if ($date) {
            $videos[] = [
                'filename'  => $basename,
                'title'     => $date->format('F Y'),
                'timestamp' => $date->getTimestamp(),
            ];
        }
    }
}

// Newest first
usort($videos, fn($a, $b) => $b['timestamp'] - $a['timestamp']);
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WhiteWater - Spartan River Reports</title>
    <link rel="icon" type="image/png" href="../assets/images/wwlogo_200x200.png">
    <link rel="stylesheet" href="<?php echo app_url('assets/css/intranet.css'); ?>">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <style>
        /* Modal overlay */
        .rr-modal {
            display: none;
            position: fixed;
            inset: 0;
            background: rgba(0, 0, 0, 0.82);
            z-index: 1000;
            align-items: center;
            justify-content: center;
            flex-direction: column;
        }
        .rr-modal.active {
            display: flex;
        }
        .rr-modal-inner {
            position: relative;
            width: 90%;
            max-width: 860px;
            background: #111;
            border-radius: 10px;
            overflow: hidden;
        }
        .rr-modal-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 12px 16px;
            background: #1a1a1a;
        }
        .rr-modal-title {
            color: #fff;
            font-size: 1rem;
            font-weight: 600;
            margin: 0;
        }
        .rr-modal-close {
            background: none;
            border: none;
            color: #aaa;
            font-size: 1.4rem;
            cursor: pointer;
            line-height: 1;
            padding: 0 4px;
        }
        .rr-modal-close:hover { color: #fff; }
        .rr-modal video {
            display: block;
            width: 100%;
            max-height: 70vh;
            background: #000;
        }
        /* NEW badge on card */
        .rr-new-badge {
            display: inline-block;
            background: #e53935;
            color: #fff;
            font-size: 0.65rem;
            font-weight: 700;
            letter-spacing: 0.05em;
            padding: 2px 7px;
            border-radius: 3px;
            margin-left: 8px;
            vertical-align: middle;
            text-transform: uppercase;
        }
    </style>
</head>
<body>

<div class="hero-section">
    <div class="hero-overlay"></div>
    <img src="<?php echo app_url('assets/images/wwlogo_200x200.png'); ?>" alt="WhiteWater Express" class="hero-logo-topleft">
    <?php render_search_box(); ?>
    <div class="hero-content">
        <h2 class="hero-title">Spartan River Reports</h2>
        <div class="hero-underline"></div>
    </div>
</div>

<div class="menu-section">
    <div class="menu-wrapper">
        <?php include('../menu.php'); ?>
    </div>
    <?php include('../motto.php'); ?>
</div>

<div class="categories-section">
    <div class="categories-wrapper">
        <div class="content-page">
            <div class="content-page-inner">
                <h2 class="section-header">Videos</h2>

                <?php if (empty($videos)): ?>
                    <p>No videos available yet.</p>
                <?php else: ?>
                <div class="card-container">
                    <?php foreach ($videos as $i => $v): ?>
                    <button type="button"
                            class="link-card"
                            data-video-src="<?= htmlspecialchars(app_url('/assets/video/river_report/' . $v['filename']), ENT_QUOTES) ?>"
                            data-title="<?= htmlspecialchars($v['title'], ENT_QUOTES) ?>">
                        <i class="fas fa-video"></i>
                        <div class="link-card-content">
                            <div class="link-card-title">
                                <?= htmlspecialchars($v['title'], ENT_QUOTES) ?>
                                <?php if ($i === 0): ?>
                                    <span class="rr-new-badge">NEW</span>
                                <?php endif; ?>
                            </div>
                        </div>
                        <i class="fas fa-play link-card-arrow"></i>
                    </button>
                    <?php endforeach; ?>
                </div>
                <?php endif; ?>

            </div>
        </div>
    </div>
</div>

<div class="footer-section">
    <div class="footer-content">
        <?php include('../footer.php'); ?>
    </div>
</div>

<!-- Modal player -->
<div class="rr-modal" id="rr-modal">
    <div class="rr-modal-inner">
        <div class="rr-modal-header">
            <p class="rr-modal-title" id="rr-modal-title"></p>
            <button class="rr-modal-close" id="rr-modal-close" aria-label="Close">&times;</button>
        </div>
        <video id="rr-modal-video" controls playsinline preload="none"></video>
    </div>
</div>

<script>
(function () {
    const modal      = document.getElementById('rr-modal');
    const modalVideo = document.getElementById('rr-modal-video');
    const modalTitle = document.getElementById('rr-modal-title');

    function openModal(src, title) {
        modalTitle.textContent = title;
        modalVideo.src = src;
        modal.classList.add('active');
        modalVideo.play();
    }

    function closeModal() {
        modal.classList.remove('active');
        modalVideo.pause();
        modalVideo.removeAttribute('src');
        modalVideo.load();
    }

    document.querySelectorAll('[data-video-src]').forEach(function (btn) {
        btn.addEventListener('click', function () {
            openModal(btn.dataset.videoSrc, btn.dataset.title);
        });
    });

    document.getElementById('rr-modal-close').addEventListener('click', closeModal);

    modal.addEventListener('click', function (e) {
        if (e.target === modal) closeModal();
    });

    document.addEventListener('keydown', function (e) {
        if (e.key === 'Escape') closeModal();
    });
}());
</script>

</body>
</html>
```

- [ ] **Step 3: Load the page in browser**

`http://whitewater-secure/public/executive/river_report.php`

Verify:
- Hero shows "Spartan River Reports"
- Card grid shows two cards: "March 2026" (with NEW badge) and "January 2026"
- Nav bar highlights "Spartan River Report"

- [ ] **Step 4: Test modal**

- Click "March 2026" card → modal opens, video plays
- Click ✕ → modal closes, video stops
- Click "March 2026" again → modal re-opens cleanly (no leftover src)
- Click backdrop → modal closes
- Press ESC → modal closes

- [ ] **Step 5: Test empty state**

Temporarily rename a file or test with an empty folder to confirm the "No videos available yet." message renders instead of a broken grid.

- [ ] **Step 6: Commit**

```bash
git add public/executive/river_report.php
git commit -m "feat: Spartan River Report archive page with modal player"
```

---

## Post-Deploy Checklist

- [ ] Move/rename video files on the server (Task 1, Step 2) if not done locally
- [ ] Confirm `http://intranet.whitewatercw.com/executive/river_report.php` loads and both videos play
- [ ] Confirm "Spartan River Report" nav link is visible and active-highlighted on that page
- [ ] Confirm home.php is unchanged (no regression on the leadership widget)

---

## Adding Future Videos

Drop a file matching `RiverReport_MMM_YYYY.mp4` (e.g., `RiverReport_Apr_2026.mp4`) into `public/assets/video/river_report/` on the server. The page picks it up automatically — no code changes needed.
