Wire match header to real SportsMatch data; add Match#/Court + country flags
The match page header rendered hard-coded demo content (Sami Al Manea vs Hassan Al Shallan, Match# 103, referee Ghassan Yusuf, external takeone-dev links) on EVERY match video, ignoring the SportsMatch record the create form saves. - Video::sportsMatch() hasOne relationship. - SportsMatch::headerData() maps the record into the header's shape (fighters + country flags, championship, weight class, referee, venue, match#/court), null-safe, with a country-name/ISO2 -> flag-icons resolver. - match.blade header now renders from headerData(): real names/flags, no external links, and degrades gracefully to just title/views/date when a video has no match data (instead of the fake card). - sports-match-modal: add Match # and Court fields (stored in the existing competition JSON, no migration) and convert fighter/referee country inputs to the mandated <x-country-select> so header flags resolve from ISO2. - Tracker updated for the new country-select usages. Verified: empty state (no SportsMatch) shows only title/views/date; a populated record renders fighters, flags (bh/us), championship, Match# 42, Court 3, U21, referee; modal compiles with the new fields. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
8ea63a6720
commit
af276f2cd1
5 files changed
+150
-100
No files matched your search
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user