@extends('layouts.app') @php use App\Services\Translator; @endphp @php $lang = app()->getLocale(); $fx = $fixture['fixture'] ?? []; $teams = $fixture['teams'] ?? []; $goals = $fixture['goals'] ?? []; $leagueInfo = $fixture['league'] ?? []; $venue = $fx['venue'] ?? []; $statusData = $fx['status'] ?? []; $home = $teams['home'] ?? []; $away = $teams['away'] ?? []; $homeName = Translator::team($home['name'] ?? ''); $awayName = Translator::team($away['name'] ?? ''); $leagueName = Translator::league($leagueInfo['name'] ?? '', $leagueInfo['country'] ?? null); $statusShort = $statusData['short'] ?? 'NS'; $elapsed = $statusData['elapsed'] ?? null; $isLive = in_array($statusShort, ['1H','2H','HT','LIVE','ET','P','BT']); $isFinished = in_array($statusShort, ['FT','AET','PEN']); $isUpcoming = in_array($statusShort, ['NS','TBD']); $isPostponed = in_array($statusShort, ['PST','CANC','ABD','SUSP']); $matchDate = null; try { if (!empty($fx['date'])) $matchDate = \Carbon\Carbon::parse($fx['date'])->setTimezone('Africa/Tunis'); } catch (\Exception $e) {} $dateTimeStr = $matchDate ? $matchDate->format('Y/m/d - H:i') : ''; $timeStr = $matchDate ? $matchDate->format('H:i') : '--:--'; $homeGoals = $goals['home'] ?? null; $awayGoals = $goals['away'] ?? null; // Round translation $round = $leagueInfo['round'] ?? ''; $formatRound = function($round) use ($lang) { if (!$round) return ''; if (preg_match('/(\d+)/', $round, $m)) { $num = $m[1]; if ($lang === 'ar') return "الجولة {$num}"; if ($lang === 'fr') return "Journée {$num}"; return "Round {$num}"; } return $round; }; // Rank color (Champions League / Europa / Relegation etc) — same as league-show $getRankColor = function(?string $description): string { if (!$description) return 'transparent'; $d = strtolower($description); if (str_contains($d, 'champions league') || str_contains($d, 'promotion')) return '#1A8D48'; if (str_contains($d, 'europa league')) return '#E67E22'; if (str_contains($d, 'conference league')) return '#3498DB'; if (str_contains($d, 'relegation')) return '#E74C3C'; return 'transparent'; }; $translateDescription = function(?string $desc) use ($lang) { if (!$desc) return ''; $d = strtolower($desc); if ($lang === 'ar') { if (str_contains($d, 'champions league')) return 'دوري الأبطال'; if (str_contains($d, 'europa league')) return 'الدوري الأوروبي'; if (str_contains($d, 'conference league')) return 'دوري المؤتمر'; if (str_contains($d, 'relegation')) return 'الهبوط'; if (str_contains($d, 'promotion')) return 'الصعود'; } elseif ($lang === 'fr') { if (str_contains($d, 'champions league')) return 'Ligue des Champions'; if (str_contains($d, 'europa league')) return 'Ligue Europa'; if (str_contains($d, 'conference league')) return 'Ligue Conférence'; if (str_contains($d, 'relegation')) return 'Relégation'; if (str_contains($d, 'promotion')) return 'Promotion'; } return $desc; }; // Build legend (unique descriptions with colors) for standings tab $standings = $standings ?? []; $topScorers = $topScorers ?? []; $legend = []; foreach ($standings as $group) { foreach ($group as $row) { $desc = $row['description'] ?? ''; if ($desc) { $color = $getRankColor($desc); if ($color !== 'transparent' && !isset($legend[$desc])) { $legend[$desc] = $color; } } } } // IDs of the two teams playing — used to highlight them in standings $homeTeamId = $home['id'] ?? 0; $awayTeamId = $away['id'] ?? 0; // For YS leagues, player IDs come from the YSScores scraper → pass ?ys=1 $ysLeagueIds = [186, 202, 200, 233, 308, 421, 387]; $isYsLeague = in_array($leagueInfo['id'] ?? 0, $ysLeagueIds, true); // Helper: build player URL $playerUrl = function ($pid) use ($isYsLeague) { if (!$pid) return '#'; return route('player.show', $pid) . ($isYsLeague ? '?ys=1' : ''); }; @endphp @section('title', "$homeName vs $awayName - " . __('messages.app_name')) @section('description', "$homeName vs $awayName - $leagueName") @section('og_image', $home['logo'] ?? asset('images/logosportirak.png')) @section('content')
{{-- ===== HEADER (Sliver style with background image) ===== --}}
{{-- Top bar: back + share --}}
{{-- Content --}}
{{-- League name + round --}}
{{ $leagueName }}
@if($round)
{{ $formatRound($round) }}
@endif
{{-- Teams row --}}
{{-- Home team --}}
@if(!empty($home['logo'])) {{ $homeName }} @else @endif
{{ $homeName }}
{{-- Score / time --}}
@if($isLive)
{{ $homeGoals ?? 0 }}
@php $elapsedVal = min(90, max(0, $elapsed ?? 0)); $circ = 2 * M_PI * 18; $remaining = $circ - ($elapsedVal / 90) * $circ; @endphp {{ $elapsed }}'
{{ $awayGoals ?? 0 }}
@elseif($isFinished)
{{ __('messages.finished') }}
{{ $homeGoals ?? 0 }} - {{ $awayGoals ?? 0 }}
@elseif($isPostponed)
{{ $statusShort === 'PST' ? ($lang === 'ar' ? 'مؤجلة' : 'Reportée') : strtoupper($statusShort) }}
@else {{ $timeStr }} @endif
{{-- Away team --}}
@if(!empty($away['logo'])) {{ $awayName }} @else @endif
{{ $awayName }}
@if($matchDate)
{{ $dateTimeStr }}
@endif
{{-- ===== TAB BAR ===== --}}
{{-- ===== SUMMARY TAB (Events timeline — identical to Flutter) ===== --}}
@if(empty($events))

{{ __('messages.no_events') }}

@else @php // Group events by half (like Flutter) $firstHalf = []; $secondHalf = []; $extraTime = []; foreach ($events as $ev) { $e = $ev['time']['elapsed'] ?? 0; $extra = $ev['time']['extra'] ?? null; if ($e > 90 || ($extra !== null && $e >= 90)) $extraTime[] = $ev; elseif ($e > 45 || ($e == 45 && $extra !== null && $extra > 0)) $secondHalf[] = $ev; else $firstHalf[] = $ev; } $homeTeamId = $home['id'] ?? 0; // Material icons (same as Flutter) — returns [svg_path, color, subtitle] $eventIconData = function($type, $detail, $assistName, $hasAssist) { $t = strtolower($type ?? ''); $d = strtolower($detail ?? ''); $subtitle = null; // SVG paths for Material icons $sportsSoccer = 'M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm6.93 6h-2.95c-.32-1.25-.78-2.45-1.38-3.56 1.84.63 3.37 1.9 4.33 3.56zM12 4.04c.83 1.2 1.48 2.53 1.91 3.96h-3.82c.43-1.43 1.08-2.76 1.91-3.96zM4.26 14C4.1 13.36 4 12.69 4 12s.1-1.36.26-2h3.38c-.08.66-.14 1.32-.14 2 0 .68.06 1.34.14 2H4.26zm.82 2h2.95c.32 1.25.78 2.45 1.38 3.56-1.84-.63-3.37-1.9-4.33-3.56zm2.95-8H5.08c.96-1.66 2.49-2.93 4.33-3.56C8.81 5.55 8.35 6.75 8.03 8zM12 19.96c-.83-1.2-1.48-2.53-1.91-3.96h3.82c-.43 1.43-1.08 2.76-1.91 3.96zM14.34 14H9.66c-.09-.66-.16-1.32-.16-2 0-.68.07-1.35.16-2h4.68c.09.65.16 1.32.16 2 0 .68-.07 1.34-.16 2zm.25 5.56c.6-1.11 1.06-2.31 1.38-3.56h2.95c-.96 1.65-2.49 2.93-4.33 3.56zM16.36 14c.08-.66.14-1.32.14-2 0-.68-.06-1.34-.14-2h3.38c.16.64.26 1.31.26 2s-.1 1.36-.26 2h-3.38z'; $squareRounded = 'M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z'; $squareFilled = 'M3 5c0-1.1.9-2 2-2h14c1.1 0 2 .9 2 2v14c0 1.1-.9 2-2 2H5c-1.1 0-2-.9-2-2V5z'; $swapHoriz = 'M6.99 11L3 15l3.99 4v-3H14v-2H6.99v-3zM21 9l-3.99-4v3H10v2h7.01v3L21 9z'; $infoOutline = 'M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z'; if ($t === 'goal') { $path = $sportsSoccer; if (str_contains($d, 'own goal')) { $color = '#E53E3E'; // live red $subtitle = app()->getLocale() === 'ar' ? 'هدف في مرماه' : (app()->getLocale() === 'fr' ? 'But contre son camp' : 'Own goal'); } elseif (str_contains($d, 'penalty')) { $color = '#38A169'; // success green $subtitle = app()->getLocale() === 'ar' ? 'هدف من ركلة جزاء' : (app()->getLocale() === 'fr' ? 'But sur penalty' : 'Penalty goal'); } else { $color = '#38A169'; } if ($hasAssist && !str_contains($d, 'own goal')) { $lbl = app()->getLocale() === 'ar' ? 'صانع الهدف' : (app()->getLocale() === 'fr' ? 'Passeur' : 'Assist'); $subtitle = $subtitle ? "{$subtitle} - {$assistName}" : "{$lbl}: {$assistName}"; } return [$path, $color, $subtitle]; } if ($t === 'card') { if (str_contains($d, 'red')) { return [$squareFilled, '#E53E3E', null]; } return [$squareFilled, '#D69E2E', null]; } if ($t === 'subst') { if ($hasAssist) $subtitle = $assistName; return [$swapHoriz, '#2e8b6b', $subtitle]; } if ($t === 'var') { return [$infoOutline, '#6B7280', $detail]; } return [$infoOutline, '#9CA3AF', null]; }; @endphp @foreach([['title' => __('messages.kick_off'), 'evs' => $firstHalf], ['title' => __('messages.second_half'), 'evs' => $secondHalf], ['title' => __('messages.extra_time'), 'evs' => $extraTime]] as $section) @if(!empty($section['evs'])) {{-- Timeline header (green pill with dot) --}}
{{ $section['title'] }}
@foreach($section['evs'] as $ev) @php $isHome = ($ev['team']['id'] ?? 0) == $homeTeamId; $playerName = Translator::player($ev['player']['name'] ?? ''); $assistName = !empty($ev['assist']['name']) ? Translator::player($ev['assist']['name']) : ''; $hasAssist = !empty($assistName); [$iconPath, $iconColor, $subtitle] = $eventIconData($ev['type'] ?? '', $ev['detail'] ?? '', $assistName, $hasAssist); $minute = ($ev['time']['elapsed'] ?? 0) . "'"; if (!empty($ev['time']['extra'])) $minute = ($ev['time']['elapsed'] ?? 0) . "'+" . $ev['time']['extra']; $type = strtolower($ev['type'] ?? ''); $subtitleColor = $type === 'subst' ? '#E53E3E' : '#6B7280'; @endphp
{{-- Home side (right in RTL) --}}
@if($isHome)
{{ $playerName }} @if($subtitle) {{ $subtitle }} @endif
@endif
{{-- Timeline center: vertical line + minute circle --}}
{{ $minute }}
{{-- Away side (left in RTL) --}}
@if(!$isHome)
{{ $playerName }} @if($subtitle) {{ $subtitle }} @endif
@endif
@endforeach @endif @endforeach {{-- Timeline end dot (if match finished) --}} @if($isFinished)
@endif @endif
{{-- ===== STATS TAB (identical to Flutter) ===== --}} {{-- ===== LINEUP TAB ===== --}} @php // Helper: build field rows from a lineup (grouping players by row, sorted by col) $buildFieldRows = function($lineup) { $startXI = $lineup['startXI'] ?? []; $formation = $lineup['formation'] ?? null; // Parse players (handle nested & flat) $parsed = []; foreach ($startXI as $entry) { if (is_array($entry)) { if (isset($entry['player']) && is_array($entry['player'])) { $parsed[] = $entry['player']; } else { $parsed[] = $entry; } } } // First pass: try API grid $apiGrids = []; $rowSet = []; foreach ($parsed as $p) { $grid = (string)($p['grid'] ?? ''); $parts = explode(':', $grid); if (count($parts) === 2) { $r = (int)$parts[0]; $c = (int)$parts[1]; $apiGrids[] = [$r, $c]; if ($r > 0) $rowSet[$r] = true; } else { $apiGrids[] = [0, 0]; } } $distinctRows = count($rowSet); $useApiGrid = $distinctRows >= 3; // Auto grid from formation $autoGrid = null; if (!$useApiGrid) { $effFormation = ($formation && strpos($formation, '-') !== false) ? $formation : '4-3-3'; $formParts = array_map('intval', array_map('trim', explode('-', $effFormation))); $autoGrid = [[1, 1]]; // GK foreach ($formParts as $i => $count) { $rowNum = $i + 2; for ($j = 0; $j < $count; $j++) { $autoGrid[] = [$rowNum, $j + 1]; } } } // Build players with positions $players = []; foreach ($parsed as $i => $p) { $row = 0; $col = 0; if ($useApiGrid && isset($apiGrids[$i])) { [$row, $col] = $apiGrids[$i]; } elseif ($autoGrid && isset($autoGrid[$i])) { [$row, $col] = $autoGrid[$i]; } $pid = $p['id'] ?? 0; $photo = $p['photo'] ?? ($pid ? "https://media.api-sports.io/football/players/{$pid}.png" : null); $players[] = [ 'id' => $pid, 'name' => Translator::player($p['name'] ?? ''), 'number' => $p['number'] ?? 0, 'row' => $row, 'col' => $col, 'photo' => $photo, ]; } // Group by row $rows = []; foreach ($players as $p) { $rows[$p['row']][] = $p; } ksort($rows); foreach ($rows as $k => $list) { usort($rows[$k], fn($a, $b) => $a['col'] <=> $b['col']); } return ['rows' => $rows, 'formation' => $formation]; }; @endphp {{-- ===== STANDINGS TAB ===== --}} {{-- ===== TOP SCORERS TAB ===== --}} {{-- ===== DETAILS TAB ===== --}}
@push('scripts') @endpush @endsection