generated from theradcoza/Laravel-Docker-Dev-Template
205 lines
9.9 KiB
PHP
205 lines
9.9 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta http-equiv="refresh" content="10">
|
|
<title>Shell Leaderboard</title>
|
|
<link rel="preconnect" href="https://fonts.bunny.net">
|
|
<link href="https://fonts.bunny.net/css?family=inter:400,500,600,700,800,900&display=swap" rel="stylesheet" />
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script>
|
|
tailwind.config = {
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
shell: {
|
|
red: '#E60000',
|
|
yellow: '#FFD100',
|
|
dark: '#1A1A1A',
|
|
}
|
|
},
|
|
fontFamily: {
|
|
sans: ['Inter', 'system-ui', 'sans-serif'],
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
<style>
|
|
@keyframes pulse-glow {
|
|
0%, 100% { box-shadow: 0 0 20px rgba(230, 0, 0, 0.3); }
|
|
50% { box-shadow: 0 0 40px rgba(230, 0, 0, 0.6); }
|
|
}
|
|
.leader-glow {
|
|
animation: pulse-glow 2s ease-in-out infinite;
|
|
}
|
|
@keyframes slide-in {
|
|
from { opacity: 0; transform: translateX(-20px); }
|
|
to { opacity: 1; transform: translateX(0); }
|
|
}
|
|
.animate-row {
|
|
animation: slide-in 0.3s ease-out forwards;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="bg-shell-dark min-h-screen font-sans antialiased">
|
|
<!-- Header -->
|
|
<header class="bg-gradient-to-r from-shell-red to-red-700 py-6 px-8 shadow-2xl">
|
|
<div class="max-w-7xl mx-auto flex items-center justify-between">
|
|
<div class="flex items-center gap-6">
|
|
<div class="w-16 h-16 bg-shell-yellow rounded-lg flex items-center justify-center shadow-lg">
|
|
<svg class="w-10 h-10 text-shell-dark" fill="currentColor" viewBox="0 0 24 24">
|
|
<path d="M12 2L1 12h3v9h6v-6h4v6h6v-9h3L12 2z"/>
|
|
</svg>
|
|
</div>
|
|
<div>
|
|
<h1 class="text-4xl md:text-5xl lg:text-6xl font-black text-white tracking-tight">SHELL LEADERBOARD</h1>
|
|
<p class="text-shell-yellow text-lg md:text-xl font-semibold tracking-widest uppercase mt-1">Race Results</p>
|
|
</div>
|
|
</div>
|
|
<div class="text-right hidden md:block">
|
|
<div class="text-white/80 text-sm uppercase tracking-wider">Live Standings</div>
|
|
<div class="text-shell-yellow text-2xl font-bold tabular-nums" id="clock">{{ now()->format('H:i:s') }}</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Leaderboard -->
|
|
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
@if($participants->isEmpty())
|
|
<div class="text-center py-20">
|
|
<div class="text-shell-yellow text-6xl mb-4">🏁</div>
|
|
<h2 class="text-3xl font-bold text-white mb-2">No Participants Yet</h2>
|
|
<p class="text-gray-400 text-lg">Waiting for race data...</p>
|
|
</div>
|
|
@else
|
|
<!-- Table Header -->
|
|
<div class="bg-shell-dark/50 border-b-2 border-shell-yellow mb-2 rounded-t-xl overflow-hidden">
|
|
<div class="grid grid-cols-12 gap-4 px-6 py-4 text-shell-yellow font-bold uppercase tracking-wider text-sm md:text-base">
|
|
<div class="col-span-1 text-center">POS</div>
|
|
<div class="col-span-1 text-center">#</div>
|
|
<div class="col-span-6">DRIVER</div>
|
|
<div class="col-span-2 text-center">TIME</div>
|
|
<div class="col-span-2 text-center">GAP</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Participants -->
|
|
<div class="space-y-2">
|
|
@php $leaderTime = $participants->first()?->time_ms; @endphp
|
|
@foreach($participants as $index => $participant)
|
|
@php
|
|
$position = $index + 1;
|
|
$isLeader = $position === 1;
|
|
$isPodium = $position <= 3;
|
|
$gap = null;
|
|
if ($leaderTime && $participant->time_ms && !$isLeader) {
|
|
$gapMs = $participant->time_ms - $leaderTime;
|
|
$gapSec = $gapMs / 1000;
|
|
$gap = sprintf('+%.3f', $gapSec);
|
|
}
|
|
@endphp
|
|
<div class="animate-row {{ $isLeader ? 'leader-glow' : '' }}" style="animation-delay: {{ $index * 0.05 }}s">
|
|
<div class="grid grid-cols-12 gap-4 px-6 py-4 md:py-5 rounded-xl items-center transition-all duration-300 hover:scale-[1.01]
|
|
@if($isLeader)
|
|
bg-gradient-to-r from-shell-red to-red-800 text-white
|
|
@elseif($position === 2)
|
|
bg-gradient-to-r from-gray-600 to-gray-700 text-white
|
|
@elseif($position === 3)
|
|
bg-gradient-to-r from-amber-700 to-amber-800 text-white
|
|
@else
|
|
bg-gray-800/80 text-white hover:bg-gray-700/80
|
|
@endif
|
|
">
|
|
<!-- Position -->
|
|
<div class="col-span-1 text-center">
|
|
<span class="inline-flex items-center justify-center w-10 h-10 md:w-12 md:h-12 rounded-full font-black text-xl md:text-2xl
|
|
@if($isLeader) bg-shell-yellow text-shell-dark
|
|
@elseif($position === 2) bg-gray-300 text-gray-800
|
|
@elseif($position === 3) bg-amber-500 text-amber-900
|
|
@else bg-gray-600 text-white
|
|
@endif
|
|
">
|
|
{{ $position }}
|
|
</span>
|
|
</div>
|
|
|
|
<!-- Car Number -->
|
|
<div class="col-span-1 text-center">
|
|
<span class="text-xl md:text-2xl font-bold {{ $isLeader ? 'text-shell-yellow' : 'text-gray-300' }}">
|
|
{{ $participant->car_number ?? '-' }}
|
|
</span>
|
|
</div>
|
|
|
|
<!-- Name -->
|
|
<div class="col-span-6">
|
|
<span class="text-xl md:text-2xl lg:text-3xl font-bold tracking-wide uppercase">
|
|
{{ $participant->name }}
|
|
</span>
|
|
@if($participant->status === 'dnf')
|
|
<span class="ml-3 px-2 py-1 bg-red-600 text-white text-xs font-bold rounded uppercase">DNF</span>
|
|
@elseif($participant->status === 'pending')
|
|
<span class="ml-3 px-2 py-1 bg-yellow-600 text-white text-xs font-bold rounded uppercase">In Progress</span>
|
|
@endif
|
|
</div>
|
|
|
|
<!-- Time -->
|
|
<div class="col-span-2 text-center">
|
|
<span class="text-xl md:text-2xl lg:text-3xl font-mono font-bold {{ $isLeader ? 'text-shell-yellow' : '' }}">
|
|
@if($participant->formatted_time)
|
|
{{ $participant->formatted_time }}
|
|
@else
|
|
<span class="text-gray-500">--:--.---</span>
|
|
@endif
|
|
</span>
|
|
</div>
|
|
|
|
<!-- Gap -->
|
|
<div class="col-span-2 text-center">
|
|
<span class="text-lg md:text-xl font-mono {{ $isLeader ? 'text-shell-yellow font-bold' : 'text-gray-400' }}">
|
|
@if($isLeader && $participant->time_ms)
|
|
LEADER
|
|
@elseif($gap)
|
|
{{ $gap }}
|
|
@else
|
|
-
|
|
@endif
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</main>
|
|
|
|
<!-- Footer -->
|
|
<footer class="fixed bottom-0 left-0 right-0 bg-gradient-to-r from-shell-dark via-gray-900 to-shell-dark py-4 border-t border-gray-800">
|
|
<div class="max-w-7xl mx-auto px-8 flex items-center justify-between">
|
|
<div class="flex items-center gap-4">
|
|
<div class="w-8 h-8 bg-shell-yellow rounded flex items-center justify-center">
|
|
<span class="text-shell-dark font-black text-sm">S</span>
|
|
</div>
|
|
<span class="text-gray-400 text-sm">Shell Racing Event</span>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<span class="inline-block w-2 h-2 bg-green-500 rounded-full animate-pulse"></span>
|
|
<span class="text-gray-400 text-sm">Auto-refresh every 10s</span>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
<script>
|
|
function updateClock() {
|
|
const clock = document.getElementById('clock');
|
|
if (clock) {
|
|
const now = new Date();
|
|
clock.textContent = now.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
|
}
|
|
}
|
|
setInterval(updateClock, 1000);
|
|
</script>
|
|
</body>
|
|
</html>
|