# CC Soccer D11 - Session Handoff
**Date:** March 11, 2026
**Session:** iCal subscribe UX improvements
**Branch:** `main`

## Last Updated
2026-03-11

## Current State
- All core functionality working
- iCal subscription feed working and verified (data confirmed good)
- iCal UX now has copy-URL + download button

---

## ⚠️ Andrew: What You Need To Do

```bash
cd ~/Sites/ccsoccer-d11  # or wherever your local is
git pull
drush cr
```

**No schema changes. No composer changes. No cim needed.**

---

## What Was Done This Session

### 1. iCal Subscribe UX Overhaul (`buildSchedulePage()` in `ContentController.php`)

Replaced the plain tooltip link with a proper subscribe block:
- Explanatory blurb: "Subscribe to your schedule in Google Calendar or Apple Calendar..."
- Read-only URL input field (monospaced, full subscription URL with scheme+host)
- **Copy Link** button — uses `navigator.clipboard` with `execCommand` fallback
- **↓ Download .ics** button — same feed URL with `?download=1`, triggers file download
- PDF link below, separated from the iCal block
- JS moved to proper Drupal library (`ccsoccer/ical-subscribe`) — not inline script
- Markup uses `Markup::create()` to bypass Drupal's XSS filter stripping `<button>` and `<input>`

### 2. iCal Feed Download Support (`myScheduleIcalFeed()` in `ContentController.php`)

Added `?download=1` query param support:
- Without `?download=1`: serves as subscription feed (no Content-Disposition) — calendar apps poll this URL
- With `?download=1`: adds `Content-Disposition: attachment; filename="ccsoccer-my-schedule.ics"` — triggers browser download

### 3. League/Season game_duration fix

Men's 35+ league has `game_duration = 80`. Season entity was created before the default was set, so it has no `game_duration`. `Season::getGameDuration()` already falls back to the league value, so no data fix needed.

---

## Files Modified This Session

| File | Changes |
|------|---------|
| `web/modules/custom/ccsoccer/src/Controller/ContentController.php` | `buildSchedulePage()` — new iCal subscribe block with copy/download buttons; `myScheduleIcalFeed()` — `?download=1` support; added `use Drupal\Core\Render\Markup` import |
| `web/modules/custom/ccsoccer/css/content-pages.css` | Added `.ical-subscribe`, `.ical-subscribe__blurb`, `.ical-subscribe__actions`, `.ical-subscribe__url`, `.ical-subscribe__copy`, `.ical-subscribe__download`, `.schedule-pdf-link` styles |
| `web/modules/custom/ccsoccer/js/ical-subscribe.js` | New file — clipboard copy JS for the iCal subscribe button |
| `web/modules/custom/ccsoccer/ccsoccer.libraries.yml` | Added `ical-subscribe` library entry |

---

## Remaining Work

### Content
- [ ] Add description to 2026 Summer Cup tournament entity (`/admin/ccsoccer/tournaments`)

### Inner Page Styling
- [ ] Credits page
- [ ] Purchase Jerseys page
- [ ] Group management page

### Forms
- [ ] Registration form inputs, buttons, visual styling

### Navigation / Mobile
- [ ] Re-add Tournament Schedule to main nav

### Notifications
- [ ] "Don't send to already registered" logic
- [ ] Automated reminders (6/4/2/1 week intervals)

### Deployment Prep
- [ ] Enable reCAPTCHA on registration form; configure site key/secret in production `settings.local.php`
- [ ] Self-host Inter font
- [ ] Enable CSS/JS aggregation on test + production before launch
- [ ] Final mobile/browser testing
- [ ] Remove IP whitelist block from production `.htaccess`
- [ ] Decide canonical domain (www vs non-www)
- [ ] Confirm HTTPS redirect handling

### Small Items
- [ ] Breadcrumbs: custom builder for full trails on custom routes
- [ ] Game status: only show ON/CANCELLED after 3pm
- [ ] Contact page — does /contact exist? Footer links to it
- [ ] Social links — Facebook/Instagram URLs are placeholder (#)
- [ ] Hero width mismatch (doesn't go full bleed)
- [ ] Password reset flow for migrated users

---

## Test Server .htaccess (IP Whitelist)

The test server `.htaccess` has an IP whitelist block that is **not in git**.
It's protected from being overwritten by pulls via `skip-worktree`.

If the whitelist is ever lost again, paste this near the top of `web/.htaccess`
(before the `<FilesMatch>` block), then re-run the skip-worktree command:

```apache
# IP Whitelist - Test server only (DO NOT commit to git)
# Note: inline comments after IPs cause 500 errors - keep IPs on one line, no comments
# Note: <RequireAny> container causes 500 on InMotion shared hosting - use single line
# Caleb/Layne: 68.249.41.9 | Andrew: 35.151.50.130 | Dave: 99.8.107.54 | Haley: 97.84.70.141
Require ip 68.249.41.9 35.151.50.130 99.8.107.54 97.84.70.141

# Prevent search engine indexing - Test server only
<IfModule mod_headers.c>
  Header set X-Robots-Tag "noindex, nofollow, noarchive"
</IfModule>
```

```bash
# Run once after editing - prevents git pull from overwriting
git update-index --skip-worktree web/.htaccess
```

---

## Server Quick Reference
```bash
cd ~/public_html/test_ccsoccer_site
git pull

# If composer.lock changed (core updates, module adds/removes):
PATH=/opt/cpanel/ea-php83/root/usr/bin:$PATH /opt/cpanel/ea-php83/root/usr/bin/php /opt/cpanel/composer/bin/composer install --ignore-platform-req=ext-intl

# Standard post-pull:
PATH=/opt/cpanel/ea-php83/root/usr/bin:$PATH /opt/cpanel/ea-php83/root/usr/bin/php vendor/drush/drush/drush.php -r web updb -y
PATH=/opt/cpanel/ea-php83/root/usr/bin:$PATH /opt/cpanel/ea-php83/root/usr/bin/php vendor/drush/drush/drush.php -r web cr
```

## Git Workflow
- Always `git pull` before `git push` — Andrew may have pushed changes
- `main` is the primary branch
- `settings.local.php` is NOT in git — never commit it, manage per-environment manually
