Skip to content

chore: launch hardening pass (official assets + visual polish) - #27

Open
jerry-shimizutech wants to merge 29 commits into
mainfrom
chore/launch-hardening-pass-1
Open

chore: launch hardening pass (official assets + visual polish)#27
jerry-shimizutech wants to merge 29 commits into
mainfrom
chore/launch-hardening-pass-1

Conversation

@jerry-shimizutech

@jerry-shimizutech jerry-shimizutech commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR applies a launch-hardening pass for Marianas Open with official client-provided assets and targeted visual fixes.

What's included

  • Import and optimize selected official assets from Sedrick package
    • logos
    • hero image
    • curated gallery images
  • Wire official logo in header/footer
  • Update home hero/gallery to curated official photos
  • Remove public /admin footer link
  • Add launch QA checklist doc (docs/launch-qa-2026-03-12.md)
  • Add map fallback treatment on Event page to avoid blank map section in non-iframe contexts
  • Keep API target on local dev at VITE_API_URL=http://localhost:3000

Why

  • Improve brand authenticity (official visuals)
  • Reduce public-facing risk (remove admin link)
  • Improve perceived quality and consistency before launch

Validation

  • npm run build (web) ✅
  • Full-stack local run tested (web + api) ✅
  • Visual checks across: Home / Calendar / Event / About / Watch ✅

Notes

  • This PR intentionally uses a curated subset of the large asset pack (best-fit, web-optimized).
  • Additional photos/logos remain available for future sections and sponsor population updates.

Greptile Summary

This PR applies a launch-hardening pass: swapping in official brand assets (logo, hero image, gallery photos) across the header, footer, and home page; renaming event strings to "Guam Marianas Open" consistently across all six locales; removing the public /admin footer link; adding a viewOnGoogleMaps i18n key in all locales; and adding a map fallback treatment on the Event Detail page.

Key changes:

  • Header.tsx / Footer.tsx — official logo (mo-logo-white.png) replaces placeholder SVG; object-contain added for correct sizing.
  • Footer.tsx — public /admin link removed (security/UX improvement).
  • HomePage.tsx — hero and gallery images updated to curated official photos.
  • All locale files (en, ja, ko, pt, tl, zh) — event name strings updated to "Guam Marianas Open"; viewOnGoogleMaps key added; calendar subtitles refined.
  • EventDetailPage.tsx — map fallback UI added, but the z-0 / z-10 layering means the fallback div is permanently hidden behind the iframe element regardless of whether the embed loads — see inline comment for a state-based fix.

Confidence Score: 4/5

  • Safe to merge with one logic fix recommended for the map fallback visibility.
  • The branding, localisation, and admin-link removal changes are clean and low-risk. The only real issue is the map fallback being permanently hidden due to incorrect z-index stacking, which means the intended UX improvement (showing a graceful fallback when the embed can't load) doesn't actually work — but it doesn't break existing functionality either.
  • web/src/pages/EventDetailPage.tsx — map fallback z-index stacking needs to be corrected for the fallback to ever be visible.

Important Files Changed

Filename Overview
web/src/pages/EventDetailPage.tsx Adds map fallback UI, but the z-index stacking (fallback at z-0, iframe at z-10) means the fallback is always hidden — the iframe element covers it whether or not the embed loads successfully.
web/src/components/Footer.tsx Swaps placeholder logo SVG for official PNG, adds object-contain, and removes the public /admin link — all clean changes.
web/src/components/Header.tsx Updates logo path from /images/logo.svg to /images/logos/mo-logo-white.png and adds object-contain — straightforward branding update.
web/src/pages/HomePage.tsx Updates hero image to hero-podium.jpg and gallery image paths to official curated photos — straightforward asset swap.
web/src/locales/en.json Renames event branding strings to "Guam Marianas Open", adds viewOnGoogleMaps key, and updates calendar subtitle — consistent and complete.
docs/launch-qa-2026-03-12.md New launch QA checklist doc — informational only, no code impact.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Browser renders EventDetailPage] --> B[Map container div rendered\nposition: relative]
    B --> C[Fallback div\nposition: absolute, z-0]
    B --> D[iframe\nposition: relative, z-10]
    D --> E{Embed loads?}
    E -->|Yes| F[iframe renders map ✅\nCovers fallback z-0 ✅]
    E -->|No / X-Frame-Options| G[iframe renders blank/error frame\nStill occupies z-10 layer]
    G --> H[Fallback at z-0 permanently hidden ❌\nUsers see blank rectangle]
    F --> I[User sees map ✅]
    style H fill:#ff4444,color:#fff
    style I fill:#22aa44,color:#fff
    style G fill:#ff8800,color:#fff
Loading

Comments Outside Diff (2)

  1. web/src/pages/EventDetailPage.tsx, line 271-293 (link)

    Map fallback will never be shown on iframe failure

    The fallback div sits at z-0 and the iframe at z-10. When a Google Maps iframe fails to load (e.g., due to browser X-Frame-Options restrictions, CSP, or network issues), the iframe element is still rendered in the DOM as an opaque blank rectangle. That blank rectangle at z-10 permanently covers the fallback div at z-0, so the fallback is never visible to the user — defeating its purpose.

    To make the fallback functional, it should be shown by default and hidden only once the iframe successfully loads:

    {/* Embedded Map with fallback */}
    <div className="relative overflow-hidden border border-white/5 aspect-[16/7]">
      {/* Fallback shown by default; hidden after iframe loads */}
      <div id="map-fallback" className="absolute inset-0 bg-navy-800 flex flex-col items-center justify-center gap-3 z-0">
        <MapPin size={28} className="text-gold-500" />
        <p className="text-text-secondary text-sm">UOG Calvo Fieldhouse · Mangilao, Guam</p>
        <a
          href="https://maps.google.com/?q=UOG+Calvo+Fieldhouse+Guam"
          target="_blank"
          rel="noopener noreferrer"
          className="inline-flex items-center gap-2 text-gold-500 text-xs font-heading font-semibold uppercase tracking-wider hover:text-gold-400 transition-colors"
        >
          View on Google Maps <ExternalLink size={12} />
        </a>
      </div>
      <iframe
        title="UOG Calvo Fieldhouse Map"
        src="https://www.google.com/maps/embed?..."
        className="w-full h-full border-0 absolute inset-0 z-10 opacity-0"
        loading="lazy"
        referrerPolicy="no-referrer-when-downgrade"
        allowFullScreen
        onLoad={(e) => {
          (e.currentTarget as HTMLIFrameElement).style.opacity = '1';
        }}
      />
    </div>

    This way the fallback is always visible, and the iframe fades in only on a successful load, revealing itself over the fallback.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: web/src/pages/EventDetailPage.tsx
    Line: 271-293
    
    Comment:
    **Map fallback will never be shown on iframe failure**
    
    The fallback div sits at `z-0` and the iframe at `z-10`. When a Google Maps iframe fails to load (e.g., due to browser X-Frame-Options restrictions, CSP, or network issues), the iframe element is **still rendered in the DOM** as an opaque blank rectangle. That blank rectangle at `z-10` permanently covers the fallback div at `z-0`, so the fallback is never visible to the user — defeating its purpose.
    
    To make the fallback functional, it should be shown by default and hidden only once the iframe successfully loads:
    
    ```tsx
    {/* Embedded Map with fallback */}
    <div className="relative overflow-hidden border border-white/5 aspect-[16/7]">
      {/* Fallback shown by default; hidden after iframe loads */}
      <div id="map-fallback" className="absolute inset-0 bg-navy-800 flex flex-col items-center justify-center gap-3 z-0">
        <MapPin size={28} className="text-gold-500" />
        <p className="text-text-secondary text-sm">UOG Calvo Fieldhouse · Mangilao, Guam</p>
        <a
          href="https://maps.google.com/?q=UOG+Calvo+Fieldhouse+Guam"
          target="_blank"
          rel="noopener noreferrer"
          className="inline-flex items-center gap-2 text-gold-500 text-xs font-heading font-semibold uppercase tracking-wider hover:text-gold-400 transition-colors"
        >
          View on Google Maps <ExternalLink size={12} />
        </a>
      </div>
      <iframe
        title="UOG Calvo Fieldhouse Map"
        src="https://www.google.com/maps/embed?..."
        className="w-full h-full border-0 absolute inset-0 z-10 opacity-0"
        loading="lazy"
        referrerPolicy="no-referrer-when-downgrade"
        allowFullScreen
        onLoad={(e) => {
          (e.currentTarget as HTMLIFrameElement).style.opacity = '1';
        }}
      />
    </div>
    ```
    
    This way the fallback is always visible, and the iframe fades in only on a successful load, revealing itself over the fallback.
    
    How can I resolve this? If you propose a fix, please make it concise.
  2. web/src/pages/EventDetailPage.tsx, line 271-292 (link)

    Fallback is always hidden behind the iframe

    The fallback div has z-0 and the iframe has z-10. Because an iframe element always occupies its layout box — even when the Google Maps embed is blocked, fails, or shows a blank/error frame — the z-10 iframe will permanently sit on top of the z-0 fallback. Users will never see the fallback content in practice; they'll see either the loaded map or a blank/white rectangle from the failed iframe.

    A reliable approach is to use React state driven by the iframe's onLoad event to hide the fallback once the iframe has successfully loaded, then conditionally render the fallback when it hasn't loaded yet:

    const [iframeLoaded, setIframeLoaded] = React.useState(false);
    
    // …
    <div className="relative overflow-hidden border border-white/5 aspect-[16/7]">
      {!iframeLoaded && (
        <div className="absolute inset-0 bg-navy-800 flex flex-col items-center justify-center gap-3">
          <MapPin size={28} className="text-gold-500" />
          <p className="text-text-secondary text-sm">
            {t('event.venue')} · {t('event.location')}
          </p>
          <a
            href="https://maps.google.com/?q=UOG+Calvo+Fieldhouse+Guam"
            target="_blank"
            rel="noopener noreferrer"
            className="inline-flex items-center gap-2 text-gold-500 text-xs font-heading font-semibold uppercase tracking-wider hover:text-gold-400 transition-colors"
          >
            {t('event.viewOnGoogleMaps')} <ExternalLink size={12} />
          </a>
        </div>
      )}
      <iframe
        title="UOG Calvo Fieldhouse Map"
        src="…"
        className="w-full h-full border-0"
        loading="lazy"
        referrerPolicy="no-referrer-when-downgrade"
        allowFullScreen
        onLoad={() => setIframeLoaded(true)}
      />
    </div>

    Note: onLoad fires when the iframe document finishes loading (including error pages from X-Frame-Options rejections). If a stricter check is needed, you can inspect event.target.contentDocument in the handler, though that will throw a cross-origin error — which can itself be used as a signal that the embed loaded live map content successfully.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: web/src/pages/EventDetailPage.tsx
Line: 271-292

Comment:
**Fallback is always hidden behind the iframe**

The fallback `div` has `z-0` and the `iframe` has `z-10`. Because an `iframe` element always occupies its layout box — even when the Google Maps embed is blocked, fails, or shows a blank/error frame — the `z-10` iframe will permanently sit on top of the `z-0` fallback. Users will never see the fallback content in practice; they'll see either the loaded map or a blank/white rectangle from the failed iframe.

A reliable approach is to use React state driven by the iframe's `onLoad` event to hide the fallback once the iframe has successfully loaded, then conditionally render the fallback when it hasn't loaded yet:

```tsx
const [iframeLoaded, setIframeLoaded] = React.useState(false);

//
<div className="relative overflow-hidden border border-white/5 aspect-[16/7]">
  {!iframeLoaded && (
    <div className="absolute inset-0 bg-navy-800 flex flex-col items-center justify-center gap-3">
      <MapPin size={28} className="text-gold-500" />
      <p className="text-text-secondary text-sm">
        {t('event.venue')} · {t('event.location')}
      </p>
      <a
        href="https://maps.google.com/?q=UOG+Calvo+Fieldhouse+Guam"
        target="_blank"
        rel="noopener noreferrer"
        className="inline-flex items-center gap-2 text-gold-500 text-xs font-heading font-semibold uppercase tracking-wider hover:text-gold-400 transition-colors"
      >
        {t('event.viewOnGoogleMaps')} <ExternalLink size={12} />
      </a>
    </div>
  )}
  <iframe
    title="UOG Calvo Fieldhouse Map"
    src=""
    className="w-full h-full border-0"
    loading="lazy"
    referrerPolicy="no-referrer-when-downgrade"
    allowFullScreen
    onLoad={() => setIframeLoaded(true)}
  />
</div>
```

Note: `onLoad` fires when the iframe document finishes loading (including error pages from `X-Frame-Options` rejections). If a stricter check is needed, you can inspect `event.target.contentDocument` in the handler, though that will throw a cross-origin error — which can itself be used as a signal that the embed loaded live map content successfully.

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 2194fd3

- Add official logos: mo-logo-white/black (GuamMarianasOpen), msjjf,
  copa-seal, copa-logo-blue, asjjf, mo-copa-mp combined
- Add hero image: hero-podium.jpg (CDM 2026, 1920w, 524KB optimized)
- Add 6 gallery photos from 2026 CDM podium + Copa Sponsorship events
  (1200w, ~100-280KB each via sips)
- Wire Header + Footer to use official mo-logo-white.png (dark nav)
- Wire HomePage hero → hero-podium.jpg; gallery fallbacks → gallery/event-photo-{1-3}.jpg
- All originals preserved in assets/source/ untouched
- Public admin link remains absent (nav-only links are public routes)
event-photo-1.jpg (bracket sheet, bright white paper) was gallery[0]
which hurt readability of the $2M economic impact text overlay.

Replace with event-photo-4.jpg (adult group podium with trophies) —
consistent dark branded backdrop matches gallery[1] and [2], high energy,
clean bottom area for stat overlays.

Final gallery set:
  [0] event-photo-4.jpg — adult group podium (Copa 2026)
  [1] event-photo-2.jpg — single adult podium (Copa 2026)
  [2] event-photo-3.jpg — kids group podium (Copa 2026)
Shows MapPin icon + venue name + View on Google Maps link behind the iframe.
The iframe renders on top in production; fallback visible in headless/offline contexts.
@netlify

netlify Bot commented Mar 12, 2026

Copy link
Copy Markdown

Deploy Preview for marianas-open ready!

Name Link
🔨 Latest commit 2194fd3
🔍 Latest deploy log https://app.netlify.com/projects/marianas-open/deploys/69b2c3291e922e0007178054
😎 Deploy Preview https://deploy-preview-27--marianas-open.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai

coderabbitai Bot commented Mar 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f57eed64-9c13-4356-8732-3a29cf83c231

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/launch-hardening-pass-1
📝 Coding Plan for PR comments
  • Generate coding plan

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jerry-shimizutech

Copy link
Copy Markdown
Contributor Author

@greptile review

Comment thread web/src/pages/EventDetailPage.tsx Outdated
Comment on lines +275 to +283
<p className="text-text-secondary text-sm">UOG Calvo Fieldhouse · Mangilao, Guam</p>
<a
href="https://maps.google.com/?q=UOG+Calvo+Fieldhouse+Guam"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 text-gold-500 text-xs font-heading font-semibold uppercase tracking-wider hover:text-gold-400 transition-colors"
>
View on Google Maps <ExternalLink size={12} />
</a>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fallback text not using i18n

The venue name "UOG Calvo Fieldhouse · Mangilao, Guam" and the link label "View on Google Maps" are hardcoded in English. The rest of the component uses t('event.venue'), t('event.venueAddress'), etc. for internationalisation. These hardcoded strings will show in English regardless of the user's selected language.

Consider using the existing translation keys:

<p className="text-text-secondary text-sm">{t('event.venue')} · {t('event.location')}</p>
<a
  href="https://maps.google.com/?q=UOG+Calvo+Fieldhouse+Guam"
  target="_blank"
  rel="noopener noreferrer"
  className="inline-flex items-center gap-2 text-gold-500 text-xs font-heading font-semibold uppercase tracking-wider hover:text-gold-400 transition-colors"
>
  {t('event.viewOnGoogleMaps')} <ExternalLink size={12} />
</a>

(and add viewOnGoogleMaps to all locale files accordingly)

Prompt To Fix With AI
This is a comment left during a code review.
Path: web/src/pages/EventDetailPage.tsx
Line: 275-283

Comment:
**Fallback text not using i18n**

The venue name `"UOG Calvo Fieldhouse · Mangilao, Guam"` and the link label `"View on Google Maps"` are hardcoded in English. The rest of the component uses `t('event.venue')`, `t('event.venueAddress')`, etc. for internationalisation. These hardcoded strings will show in English regardless of the user's selected language.

Consider using the existing translation keys:

```tsx
<p className="text-text-secondary text-sm">{t('event.venue')} · {t('event.location')}</p>
<a
  href="https://maps.google.com/?q=UOG+Calvo+Fieldhouse+Guam"
  target="_blank"
  rel="noopener noreferrer"
  className="inline-flex items-center gap-2 text-gold-500 text-xs font-heading font-semibold uppercase tracking-wider hover:text-gold-400 transition-colors"
>
  {t('event.viewOnGoogleMaps')} <ExternalLink size={12} />
</a>
```

(and add `viewOnGoogleMaps` to all locale files accordingly)

How can I resolve this? If you propose a fix, please make it concise.

@jerry-shimizutech

Copy link
Copy Markdown
Contributor Author

Great catch — this is legit and now fixed.

✅ Fix applied

  • Replaced hardcoded English fallback text in EventDetailPage map block with i18n keys:
    • {t('event.venue')} · {t('event.location')}
    • {t('event.viewOnGoogleMaps')}
  • Added event.viewOnGoogleMaps to all locale files:
    • en, ja, ko, tl, zh, pt

Validation:

  • cd web && npm run build

@greptile review

@jerry-shimizutech

Copy link
Copy Markdown
Contributor Author

Superseded by clean-history PR #28 (same functionality, rebased from main with only launch-hardening commits). Please review/merge #28 instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant