161 lines
9.0 KiB
PHP
161 lines
9.0 KiB
PHP
@extends('layouts.master')
|
|
|
|
@section('content')
|
|
<div class="max-w-3xl mx-auto px-6 py-8">
|
|
|
|
<!-- Header -->
|
|
<div class="flex items-center justify-between mb-8">
|
|
<div>
|
|
<h1 class="text-slate-900 text-xl font-bold tracking-tight">Leaderboard</h1>
|
|
<p class="text-slate-500 text-sm mt-0.5">All-time cumulative scores · {{ $total }} students</p>
|
|
</div>
|
|
<a href="{{ route('home') }}"
|
|
class="flex items-center gap-2 bg-white hover:bg-slate-50 border border-slate-200 text-slate-600 text-sm font-medium px-4 py-2 rounded-lg transition-colors shadow-sm">
|
|
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<line x1="19" y1="12" x2="5" y2="12"/><polyline points="12 19 5 12 12 5"/>
|
|
</svg>
|
|
Dashboard
|
|
</a>
|
|
</div>
|
|
|
|
<!-- ── TOP 3 PODIUM ── -->
|
|
@if($students->count() >= 3)
|
|
<div class="relative mb-8">
|
|
|
|
<!-- Background glow -->
|
|
<div class="absolute inset-x-0 bottom-0 h-32 bg-gradient-to-t from-indigo-50 to-transparent rounded-2xl pointer-events-none"></div>
|
|
|
|
<div class="relative grid grid-cols-3 gap-3 items-end px-4 pt-6">
|
|
|
|
{{-- 2nd place --}}
|
|
<div class="flex flex-col items-center">
|
|
<div class="relative mb-3">
|
|
<div class="w-14 h-14 rounded-full bg-white border-4 border-slate-300 shadow-md flex items-center justify-center font-black text-slate-600 text-xl">
|
|
{{ strtoupper(substr($students[1]->name, 0, 1)) }}
|
|
</div>
|
|
<span class="absolute -bottom-1 -right-1 text-lg leading-none">🥈</span>
|
|
</div>
|
|
<p class="text-xs font-bold text-slate-700 text-center leading-tight mb-3 truncate w-full text-center">{{ explode(' ', $students[1]->name)[0] }}</p>
|
|
<div class="w-full bg-slate-200 border border-slate-300 rounded-t-2xl h-28 flex flex-col items-center justify-center gap-1 shadow-inner">
|
|
<span class="text-2xl font-black text-slate-700">{{ $students[1]->total_score }}</span>
|
|
<span class="text-xs text-slate-500 font-semibold uppercase tracking-wide">pts</span>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- 1st place --}}
|
|
<div class="flex flex-col items-center -mt-4">
|
|
<!-- Crown -->
|
|
<div class="text-2xl mb-1">👑</div>
|
|
<div class="relative mb-3">
|
|
<div class="w-18 h-18 w-[4.5rem] h-[4.5rem] rounded-full bg-gradient-to-br from-yellow-300 to-amber-400 border-4 border-yellow-400 shadow-lg shadow-yellow-200 flex items-center justify-center font-black text-white text-2xl">
|
|
{{ strtoupper(substr($students[0]->name, 0, 1)) }}
|
|
</div>
|
|
<div class="absolute inset-0 rounded-full bg-yellow-400/20 animate-ping"></div>
|
|
</div>
|
|
<p class="text-xs font-bold text-slate-800 text-center leading-tight mb-3 truncate w-full text-center">{{ explode(' ', $students[0]->name)[0] }}</p>
|
|
<div class="w-full bg-gradient-to-b from-yellow-400 to-amber-500 rounded-t-2xl h-40 flex flex-col items-center justify-center gap-1 shadow-lg shadow-amber-200">
|
|
<span class="text-3xl font-black text-white drop-shadow">{{ $students[0]->total_score }}</span>
|
|
<span class="text-xs text-yellow-100 font-bold uppercase tracking-wide">pts</span>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- 3rd place --}}
|
|
<div class="flex flex-col items-center">
|
|
<div class="relative mb-3">
|
|
<div class="w-14 h-14 rounded-full bg-white border-4 border-orange-300 shadow-md flex items-center justify-center font-black text-orange-500 text-xl">
|
|
{{ strtoupper(substr($students[2]->name, 0, 1)) }}
|
|
</div>
|
|
<span class="absolute -bottom-1 -right-1 text-lg leading-none">🥉</span>
|
|
</div>
|
|
<p class="text-xs font-bold text-slate-700 text-center leading-tight mb-3 truncate w-full text-center">{{ explode(' ', $students[2]->name)[0] }}</p>
|
|
<div class="w-full bg-gradient-to-b from-orange-200 to-orange-300 border border-orange-300 rounded-t-2xl h-20 flex flex-col items-center justify-center gap-1 shadow-inner">
|
|
<span class="text-2xl font-black text-orange-700">{{ $students[2]->total_score }}</span>
|
|
<span class="text-xs text-orange-500 font-semibold uppercase tracking-wide">pts</span>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<!-- ── FULL RANKINGS ── -->
|
|
<div class="bg-white rounded-2xl border border-slate-200 overflow-hidden shadow-sm">
|
|
|
|
<div class="px-5 py-3.5 border-b border-slate-100 flex items-center justify-between">
|
|
<div class="flex items-center gap-2 text-slate-700 font-semibold text-sm">
|
|
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/>
|
|
</svg>
|
|
All Rankings
|
|
</div>
|
|
<span class="text-xs text-slate-400 bg-slate-100 px-2 py-0.5 rounded-full font-medium">{{ $total }} students</span>
|
|
</div>
|
|
|
|
<div class="divide-y divide-slate-100">
|
|
@foreach($students as $i => $s)
|
|
@php $rank = $i + 1; @endphp
|
|
<div class="px-5 py-3.5 flex items-center gap-4
|
|
{{ $rank === 1 ? 'bg-amber-50/60' : 'hover:bg-slate-50/60' }} transition-colors">
|
|
|
|
<!-- Rank badge -->
|
|
<div class="w-8 shrink-0 flex justify-center">
|
|
@if($rank === 1)
|
|
<span class="text-xl">🥇</span>
|
|
@elseif($rank === 2)
|
|
<span class="text-xl">🥈</span>
|
|
@elseif($rank === 3)
|
|
<span class="text-xl">🥉</span>
|
|
@else
|
|
<span class="w-6 h-6 rounded-full bg-slate-100 flex items-center justify-center text-xs font-bold text-slate-500">{{ $rank }}</span>
|
|
@endif
|
|
</div>
|
|
|
|
<!-- Avatar -->
|
|
<div class="w-9 h-9 rounded-full flex items-center justify-center shrink-0 font-bold text-sm
|
|
{{ $rank === 1 ? 'bg-amber-100 text-amber-600 ring-2 ring-amber-300' : 'bg-indigo-100 text-indigo-600' }}">
|
|
{{ strtoupper(substr($s->name, 0, 1)) }}
|
|
</div>
|
|
|
|
<!-- Name + meta -->
|
|
<div class="flex-1 min-w-0">
|
|
<p class="font-semibold text-slate-800 text-sm truncate {{ $rank === 1 ? 'text-amber-800' : '' }}">
|
|
{{ $s->name }}
|
|
</p>
|
|
<p class="text-xs text-slate-400 mt-0.5">
|
|
{{ $s->sessions_count }} session{{ $s->sessions_count !== 1 ? 's' : '' }}
|
|
· {{ $s->phone }}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Progress bar -->
|
|
<div class="w-28 hidden sm:block">
|
|
<div class="h-1.5 bg-slate-100 rounded-full overflow-hidden">
|
|
<div class="h-full rounded-full transition-all duration-500
|
|
{{ $rank === 1 ? 'bg-gradient-to-r from-amber-400 to-yellow-500' : 'bg-gradient-to-r from-indigo-400 to-indigo-500' }}"
|
|
style="width: {{ $maxScore > 0 ? round(($s->total_score / $maxScore) * 100) : 0 }}%">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Score -->
|
|
<div class="flex items-baseline gap-1 shrink-0">
|
|
<svg width="12" height="12" viewBox="0 0 24 24" fill="{{ $rank === 1 ? '#f59e0b' : '#6366f1' }}" stroke="none">
|
|
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/>
|
|
</svg>
|
|
<span class="font-black text-slate-900 text-base">{{ $s->total_score }}</span>
|
|
<span class="text-xs text-slate-400 font-medium">pts</span>
|
|
</div>
|
|
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
|
|
@if($students instanceof \Illuminate\Pagination\LengthAwarePaginator && $students->hasPages())
|
|
<div class="px-5 py-3 border-t border-slate-100">
|
|
{{ $students->links() }}
|
|
</div>
|
|
@endif
|
|
|
|
</div>
|
|
</div>
|
|
@endsection |