diff --git a/.claude/component-usage.md b/.claude/component-usage.md index b855cf7..a468719 100644 --- a/.claude/component-usage.md +++ b/.claude/component-usage.md @@ -144,6 +144,9 @@ Stored value: ISO2 code (e.g. `"BH"`). |---|---|---| | `resources/views/user/profile.blade.php` | `nationality` | Edit Profile form | | `resources/views/auth/register.blade.php` | `nationality` | Registration form — mandatory | +| `resources/views/layouts/partials/sports-match-modal.blade.php` | `participants[p1_country]` | Fighter 1 country → header flag | +| `resources/views/layouts/partials/sports-match-modal.blade.php` | `participants[p2_country]` | Fighter 2 country → header flag | +| `resources/views/layouts/partials/sports-match-modal.blade.php` | `participants[referee_country]` | Referee country → header flag | --- diff --git a/app/Models/SportsMatch.php b/app/Models/SportsMatch.php index c948a7f..ccdf632 100644 --- a/app/Models/SportsMatch.php +++ b/app/Models/SportsMatch.php @@ -34,6 +34,63 @@ class SportsMatch extends Model 'reviews' => 'array', ]; + /** + * Shape the record into exactly what the match page header renders. Every value + * is null-safe so a video with no/partial match data degrades to just its title + * instead of falling back to hard-coded demo content. + */ + public function headerData(): array + { + $p = $this->participants ?? []; + $c = $this->competition ?? []; + $v = $this->venue ?? []; + + return [ + 'blue' => [ + 'name' => $this->participant1_name ?: null, + 'club' => $p['p1_club'] ?? null, + 'flag' => $this->flagFor($p['p1_country'] ?? null), + ], + 'red' => [ + 'name' => $this->participant2_name ?: null, + 'club' => $p['p2_club'] ?? null, + 'flag' => $this->flagFor($p['p2_country'] ?? null), + ], + 'weight_category' => $p['weight_class'] ?? null, + 'championship' => $c['championship_name'] ?? ($this->event_name ?: null), + 'match_number' => $c['match_number'] ?? null, + 'court' => $c['court'] ?? null, + 'referee' => [ + 'name' => $this->referee_name ?: null, + 'flag' => $this->flagFor($p['referee_country'] ?? null), + ], + 'venue' => [ + 'name' => $this->venue_name ?: ($v['name'] ?? null), + 'map_link' => $v['map_link'] ?? null, + ], + 'event_logo' => $this->media['event_poster'] ?? null, // rel path or null + ]; + } + + /** Resolve a country name or ISO2 code to a lowercase flag-icons code (or null). */ + private function flagFor(?string $country): ?string + { + $country = trim((string) $country); + if ($country === '') { + return null; + } + $countries = \App\Data\Countries::all(); + if (preg_match('/^[A-Za-z]{2}$/', $country) && isset($countries[strtoupper($country)])) { + return strtolower($country); + } + foreach ($countries as $iso2 => $meta) { + if (strcasecmp($meta['name'], $country) === 0) { + return strtolower($iso2); + } + } + return null; + } + public function video(): BelongsTo { return $this->belongsTo(Video::class); diff --git a/app/Models/Video.php b/app/Models/Video.php index a7d0117..880a5b4 100644 --- a/app/Models/Video.php +++ b/app/Models/Video.php @@ -434,6 +434,12 @@ class Video extends Model return $this->hasMany(CoachReview::class)->orderBy('start_time_seconds'); } + // The sports match record backing a type=match video (fighters, referee, etc.) + public function sportsMatch() + { + return $this->hasOne(SportsMatch::class); + } + // Get recent views count (within hours) public function getRecentViews($hours = 48) { diff --git a/resources/views/layouts/partials/sports-match-modal.blade.php b/resources/views/layouts/partials/sports-match-modal.blade.php index 2d3942f..321666a 100644 --- a/resources/views/layouts/partials/sports-match-modal.blade.php +++ b/resources/views/layouts/partials/sports-match-modal.blade.php @@ -91,6 +91,16 @@
+
+
+ + +
+
+ + +
+
{{-- Participants --}} @@ -126,8 +136,16 @@
- - +
+
+ + +
+
+ + +
+
@@ -196,7 +214,7 @@
-
+
@@ -207,7 +225,7 @@
-
+
diff --git a/resources/views/videos/types/match.blade.php b/resources/views/videos/types/match.blade.php index fd1f145..2a97405 100644 --- a/resources/views/videos/types/match.blade.php +++ b/resources/views/videos/types/match.blade.php @@ -2014,62 +2014,10 @@ @section('content') @php - // ===== DUMMY DATA FALLBACKS ===== - $blueFighter = - $blueFighter ?? - (object) [ - 'name' => 'Sami Al Manea', - 'flag' => 'bh', - 'photo' => 'https://takeone-dev.innovator.bh/storage/images/profiles/profile_5.png?v=1773157950', - 'team' => 'Emperor TaeKwonDo Academy', - 'country' => 'Bahrain', - 'logo' => 'https://takeone-dev.innovator.bh/storage/clubs/1/branding/logo_1771488666.png', - 'member_id' => 5, - 'club_url' => 'https://takeone-dev.innovator.bh/mobile/eta', - ]; - $redFighter = - $redFighter ?? - (object) [ - 'name' => 'Hassan Al Shallan', - 'flag' => 'bh', - 'photo' => 'https://takeone-dev.innovator.bh/storage/images/profiles/profile_11.png?t=1773268056907', - 'team' => 'Legend TaeKwonDo Academy', - 'country' => 'Bahrain', - 'logo' => 'https://takeone-dev.innovator.bh/storage/clubs/logos/logo_1773267551.png', - 'member_id' => 11, - 'club_url' => 'https://takeone-dev.innovator.bh/clubs/legend-taekwondo-academy', - ]; - $match = - $match ?? - (object) [ - 'number' => '103', - 'court' => '2', - 'weight_category' => 'U18', - 'score_blue' => 7, - 'score_red' => 5, - 'features' => - 'Electronic scoring system (PSS & head‑gear) • Video replay available for head kicks and gam-jeom appeals', - ]; - $referee = - $referee ?? - (object) [ - 'name' => 'Ghassan Yusuf', - 'flag' => 'bh', - 'photo' => 'https://takeone-dev.innovator.bh/storage/images/profiles/profile_8.png?t=1773267305519', - 'member_id' => 4, - ]; - $championship = - $championship ?? - (object) [ - 'name' => 'Championship 2026', - 'url' => '/championship/2026', - ]; - $venue = - $venue ?? - (object) [ - 'name' => 'Manama Sports Hall', - 'map_link' => 'https://maps.google.com/?q=Manama+Sports+Hall+Bahrain', - ]; + // Real match data (fighters, referee, championship, match#/court, venue) + // for this video. null when no SportsMatch record exists — the header then + // degrades to just the title/views/date instead of showing demo content. + $hd = $video->sportsMatch?->headerData(); @endphp @@ -2096,52 +2044,70 @@
- + @php + $flagStyle = 'width:20px;height:15px;border-radius:2px;display:inline-block;vertical-align:middle;'; + $hasBlue = $hd && $hd['blue']['name']; + $hasRed = $hd && $hd['red']['name']; + // Ordered inline meta pieces — only the ones that actually have data. + $metaPieces = []; + if ($hd) { + if ($hd['championship']) $metaPieces[] = ['type' => 'champ', 'val' => $hd['championship']]; + if ($hd['match_number']) $metaPieces[] = ['type' => 'num', 'val' => $hd['match_number']]; + if ($hd['court']) $metaPieces[] = ['type' => 'court', 'val' => $hd['court']]; + if ($hd['referee']['name']) $metaPieces[] = ['type' => 'ref', 'val' => $hd['referee']]; + } + @endphp +

- - {{ $video->title }} – - - - - {{ $blueFighter->name ?? 'Sami Al Manea' }} - - - vs - - - - {{ $redFighter->name ?? 'Hassan Al Shallan' }} - - - ({{ $match->weight_category ?? 'U18' }}) + + {{ $video->title }}@if ($hasBlue || $hasRed) –@endif + @if ($hasBlue) + + @if ($hd['blue']['flag'])@endif + {{ $hd['blue']['name'] }} + + @endif + @if ($hasBlue && $hasRed)vs@endif + @if ($hasRed) + + @if ($hd['red']['flag'])@endif + {{ $hd['red']['name'] }} + + @endif + @if ($hd && $hd['weight_category'])({{ $hd['weight_category'] }})@endif

- - - {{ $championship->name ?? 'Championship 2026' }} - - Match# - {{ $match->number ?? '103' }} - - Court - {{ $match->court ?? '2' }} - - - {{ $referee->name ?? 'Ghassan Yusuf' }} + {{-- Inline meta: championship • Match# • Court • referee • views/date. + Only non-empty pieces render; views/date always show. --}} +