You've already forked Atomcms-edit
319 lines
22 KiB
PHP
Executable File
319 lines
22 KiB
PHP
Executable File
<x-app-layout>
|
|
@push('title', 'Radio Leaderboard')
|
|
|
|
<div class="col-span-12 lg:col-span-9 lg:w-[96%]">
|
|
<div class="flex flex-col gap-y-4">
|
|
<x-content.content-card icon="trophy" classes="border dark:border-gray-900">
|
|
<x-slot:title>
|
|
Radio Leaderboard
|
|
</x-slot:title>
|
|
|
|
<x-slot:under-title>
|
|
Wie zijn de meest toegewijde luisteraars?
|
|
</x-slot:under-title>
|
|
|
|
<div class="px-2 text-sm space-y-4 dark:text-gray-200">
|
|
<!-- Period Navigation -->
|
|
<div class="flex flex-wrap gap-2 mb-6">
|
|
<a href="{{ route('radio.leaderboard', ['period' => 'all']) }}"
|
|
class="inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-all duration-300 transform hover:scale-105
|
|
{{ $period === 'all'
|
|
? 'bg-gradient-to-r from-yellow-400 to-yellow-500 text-gray-900 shadow-lg shadow-yellow-500/30'
|
|
: 'bg-gray-700/50 text-gray-200 hover:bg-gray-600' }}">
|
|
🌟 Alles
|
|
</a>
|
|
<a href="{{ route('radio.leaderboard', ['period' => 'weekly']) }}"
|
|
class="inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-all duration-300 transform hover:scale-105
|
|
{{ $period === 'weekly'
|
|
? 'bg-gradient-to-r from-yellow-400 to-yellow-500 text-gray-900 shadow-lg shadow-yellow-500/30'
|
|
: 'bg-gray-700/50 text-gray-200 hover:bg-gray-600' }}">
|
|
📅 Deze Week
|
|
</a>
|
|
<a href="{{ route('radio.leaderboard', ['period' => 'monthly']) }}"
|
|
class="inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-all duration-300 transform hover:scale-105
|
|
{{ $period === 'monthly'
|
|
? 'bg-gradient-to-r from-yellow-400 to-yellow-500 text-gray-900 shadow-lg shadow-yellow-500/30'
|
|
: 'bg-gray-700/50 text-gray-200 hover:bg-gray-600' }}">
|
|
📆 Deze Maand
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Top 3 Podium -->
|
|
@if(!empty($users) && count($users) >= 3)
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-8">
|
|
<!-- 2nd Place -->
|
|
<div class="order-1 md:order-1">
|
|
<div class="bg-gradient-to-b from-gray-700 to-gray-800 rounded-xl p-6 text-center border border-gray-600/50 shadow-xl transform hover:scale-105 transition-all duration-300 relative overflow-hidden">
|
|
<div class="absolute inset-0 bg-gradient-to-b from-gray-500/10 to-transparent"></div>
|
|
<div class="relative">
|
|
<div class="absolute -top-6 left-1/2 -translate-x-1/2">
|
|
<div class="w-16 h-16 rounded-full bg-gradient-to-br from-gray-300 to-gray-400 flex items-center justify-center text-2xl shadow-lg">
|
|
🥈
|
|
</div>
|
|
</div>
|
|
<div class="mt-8 mb-3">
|
|
<img src="{{ $users[1]['avatar'] ?? 'https://ui-avatars.com/api/?name=' . urlencode($users[1]['username']) . '&size=128&background=6b7280&color=ffffff' }}"
|
|
alt="{{ $users[1]['username'] }}"
|
|
class="w-24 h-24 rounded-full mx-auto border-4 border-gray-500 shadow-lg">
|
|
</div>
|
|
<h4 class="font-bold text-xl text-white mb-1">{{ $users[1]['username'] }}</h4>
|
|
<div class="inline-flex items-center gap-1 px-4 py-1.5 rounded-full bg-gray-600 text-gray-200 font-medium text-sm">
|
|
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
|
|
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
|
|
</svg>
|
|
{{ number_format($users[1]['points']) }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 1st Place -->
|
|
<div class="order-2">
|
|
<div class="bg-gradient-to-b from-yellow-500/20 to-gray-800 rounded-xl p-6 text-center border-2 border-yellow-500/50 shadow-xl shadow-yellow-500/20 transform hover:scale-105 transition-all duration-300 relative overflow-hidden">
|
|
<div class="absolute inset-0 bg-gradient-to-b from-yellow-500/10 to-transparent"></div>
|
|
<div class="absolute -top-8 left-1/2 -translate-x-1/2">
|
|
<div class="w-20 h-20 rounded-full bg-gradient-to-br from-yellow-300 to-yellow-500 flex items-center justify-center text-3xl shadow-lg shadow-yellow-500/50 animate-pulse">
|
|
🥇
|
|
</div>
|
|
</div>
|
|
<div class="mt-10 mb-3">
|
|
<img src="{{ $users[0]['avatar'] ?? 'https://ui-avatars.com/api/?name=' . urlencode($users[0]['username']) . '&size=128&background=eeb425&color=000000' }}"
|
|
alt="{{ $users[0]['username'] }}"
|
|
class="w-28 h-28 rounded-full mx-auto border-4 border-yellow-400 shadow-lg shadow-yellow-500/30">
|
|
</div>
|
|
<h4 class="font-bold text-xl text-yellow-400 mb-1">{{ $users[0]['username'] }}</h4>
|
|
<div class="inline-flex items-center gap-1 px-4 py-1.5 rounded-full bg-yellow-500/20 text-yellow-400 font-medium text-sm">
|
|
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
|
|
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
|
|
</svg>
|
|
{{ number_format($users[0]['points']) }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 3rd Place -->
|
|
<div class="order-3 md:order-3">
|
|
<div class="bg-gradient-to-b from-orange-700/50 to-gray-800 rounded-xl p-6 text-center border border-orange-600/30 shadow-xl transform hover:scale-105 transition-all duration-300 relative overflow-hidden">
|
|
<div class="absolute inset-0 bg-gradient-to-b from-orange-500/10 to-transparent"></div>
|
|
<div class="relative">
|
|
<div class="absolute -top-6 left-1/2 -translate-x-1/2">
|
|
<div class="w-14 h-14 rounded-full bg-gradient-to-br from-orange-400 to-orange-600 flex items-center justify-center text-xl shadow-lg">
|
|
🥉
|
|
</div>
|
|
</div>
|
|
<div class="mt-6 mb-3">
|
|
<img src="{{ $users[2]['avatar'] ?? 'https://ui-avatars.com/api/?name=' . urlencode($users[2]['username']) . '&size=128&background=ea580c&color=ffffff' }}"
|
|
alt="{{ $users[2]['username'] }}"
|
|
class="w-20 h-20 rounded-full mx-auto border-4 border-orange-500 shadow-lg">
|
|
</div>
|
|
<h4 class="font-bold text-lg text-orange-400 mb-1">{{ $users[2]['username'] }}</h4>
|
|
<div class="inline-flex items-center gap-1 px-4 py-1.5 rounded-full bg-orange-500/20 text-orange-400 font-medium text-sm">
|
|
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 24 24">
|
|
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
|
|
</svg>
|
|
{{ number_format($users[2]['points']) }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<!-- Leaderboard List -->
|
|
<div class="bg-gray-800/50 backdrop-blur-sm rounded-xl overflow-hidden border border-gray-700/50 shadow-xl">
|
|
<div class="px-6 py-4 border-b border-gray-700/50 bg-gradient-to-r from-gray-800/80 to-gray-800/40">
|
|
<h4 class="font-bold text-white flex items-center gap-3">
|
|
<span class="w-8 h-8 rounded-lg bg-[#eeb425]/20 flex items-center justify-center">
|
|
<svg class="w-5 h-5 text-[#eeb425]" fill="currentColor" viewBox="0 0 24 24">
|
|
<path d="M3 13h2v-2H3v2zm0 4h2v-2H3v2zm0-8h2V7H3v2zm4 4h14v-2H7v2zm0 4h14v-2H7v2zM7 7v2h14V7H7z"/>
|
|
</svg>
|
|
</span>
|
|
Alle Luisteraars
|
|
<span class="ml-auto text-sm font-normal text-gray-400">({{ count($users) }})</span>
|
|
</h4>
|
|
</div>
|
|
|
|
<div class="max-h-[500px] overflow-y-auto custom-scrollbar">
|
|
@forelse($users as $user)
|
|
<div class="flex items-center gap-4 px-6 py-3 border-b border-gray-700/30 last:border-b-0 hover:bg-gray-700/30 transition-all duration-200 group">
|
|
<!-- Rank -->
|
|
<div class="w-8 flex-shrink-0">
|
|
@if($user['rank'] <= 3)
|
|
<div class="flex items-center justify-center w-8 h-8 rounded-full font-bold text-sm
|
|
{{ $user['rank'] === 1 ? 'bg-gradient-to-br from-yellow-400 to-yellow-600 text-gray-900 shadow-lg shadow-yellow-500/30' :
|
|
($user['rank'] === 2 ? 'bg-gradient-to-br from-gray-300 to-gray-500 text-gray-900' :
|
|
'bg-gradient-to-br from-orange-400 to-orange-600 text-white') }}">
|
|
{{ $user['rank'] }}
|
|
</div>
|
|
@else
|
|
<div class="flex items-center justify-center w-8 h-8 rounded-full bg-gray-700/50 text-gray-400 text-sm font-medium">
|
|
{{ $user['rank'] }}
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<!-- Avatar -->
|
|
<div class="relative flex-shrink-0">
|
|
<img src="{{ $user['avatar'] ?? 'https://ui-avatars.com/api/?name=' . urlencode($user['username']) . '&size=64&background=374151&color=eeb425' }}"
|
|
alt="{{ $user['username'] }}"
|
|
class="w-12 h-12 rounded-full border-2 border-gray-600 group-hover:border-[#eeb425] transition-colors duration-200">
|
|
@if($user['rank'] <= 3)
|
|
<div class="absolute -top-1 -right-1 w-5 h-5 rounded-full flex items-center justify-center text-xs
|
|
{{ $user['rank'] === 1 ? 'bg-yellow-400' : ($user['rank'] === 2 ? 'bg-gray-300' : 'bg-orange-400') }}">
|
|
{{ $user['rank'] }}
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<!-- Username -->
|
|
<div class="flex-1 min-w-0">
|
|
<div class="font-semibold text-white group-hover:text-[#eeb425] transition-colors duration-200 truncate">{{ $user['username'] }}</div>
|
|
@if($user['rank'] <= 3)
|
|
<div class="text-xs">
|
|
<span class="{{ $user['rank'] === 1 ? 'text-yellow-400' : ($user['rank'] === 2 ? 'text-gray-300' : 'text-orange-400') }}">
|
|
{{ $user['rank'] === 1 ? '👑 Kampioen' : ($user['rank'] === 2 ? '🥈 Runner-up' : '🥉 Top 3') }}
|
|
</span>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<!-- Points -->
|
|
<div class="flex items-center gap-3 flex-shrink-0">
|
|
<div class="px-3 py-1.5 rounded-lg bg-gradient-to-r from-[#eeb425]/10 to-[#eeb425]/5 border border-[#eeb425]/20">
|
|
<span class="text-[#eeb425] font-bold">{{ number_format($user['points']) }}</span>
|
|
<span class="text-[#eeb425]/60 text-xs ml-1">pts</span>
|
|
</div>
|
|
@if($user['rank'] === 1)
|
|
<span class="text-2xl">🏆</span>
|
|
@elseif($user['rank'] <= 10)
|
|
<span class="text-lg">⭐</span>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
@empty
|
|
<div class="text-center py-16 px-4">
|
|
<div class="relative inline-block mb-4">
|
|
<div class="w-24 h-24 rounded-full bg-gray-700/50 flex items-center justify-center text-5xl">
|
|
🎵
|
|
</div>
|
|
<div class="absolute -bottom-2 -right-2 w-10 h-10 rounded-full bg-[#eeb425] flex items-center justify-center text-xl">
|
|
🤔
|
|
</div>
|
|
</div>
|
|
<h4 class="text-xl font-bold text-white mb-2">{{ __('radio.no_listeners') }}</h4>
|
|
<p class="text-gray-400 mb-6 max-w-sm mx-auto">{{ __('radio.listen_to_earn') }}</p>
|
|
<a href="{{ route('radio.index') }}"
|
|
class="inline-flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-[#eeb425] to-yellow-500 text-gray-900 rounded-xl font-semibold hover:from-yellow-400 hover:to-yellow-400 transition-all duration-300 transform hover:scale-105 shadow-lg shadow-yellow-500/30">
|
|
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
|
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>
|
|
</svg>
|
|
{{ __('radio.start_listening') }}
|
|
</a>
|
|
</div>
|
|
@endforelse
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</x-content.content-card>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div class="col-span-12 lg:col-span-3 lg:w-[110%] space-y-4 lg:-ml-[32px]">
|
|
<x-content.content-card icon="info" classes="border dark:border-gray-900 bg-gradient-to-br from-gray-800/50 to-gray-900/50">
|
|
<x-slot:title>
|
|
{{ __('radio.leaderboard_info') }}
|
|
</x-slot:title>
|
|
|
|
<x-slot:under-title>
|
|
{{ __('radio.how_it_works') }}
|
|
</x-slot:under-title>
|
|
|
|
<div class="px-2 text-sm space-y-4 dark:text-gray-200">
|
|
<p class="text-gray-300">{{ __('radio.points_auto') }}</p>
|
|
<div class="space-y-3 text-xs">
|
|
<div class="flex items-center gap-3 p-3 rounded-lg bg-green-500/10 border border-green-500/20">
|
|
<span class="w-3 h-3 rounded-full bg-green-500 shadow-lg shadow-green-500/50"></span>
|
|
<span class="text-green-400">{{ __('radio.points_per_minute') }}</span>
|
|
</div>
|
|
<div class="flex items-center gap-3 p-3 rounded-lg bg-yellow-500/10 border border-yellow-500/20">
|
|
<span class="w-3 h-3 rounded-full bg-yellow-500 shadow-lg shadow-yellow-500/50"></span>
|
|
<span class="text-yellow-400">{{ __('radio.max_points_per_day') }}</span>
|
|
</div>
|
|
<div class="flex items-center gap-3 p-3 rounded-lg bg-blue-500/10 border border-blue-500/20">
|
|
<span class="w-3 h-3 rounded-full bg-blue-500 shadow-lg shadow-blue-500/50"></span>
|
|
<span class="text-blue-400">{{ __('radio.leaderboard_updated') }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</x-content.content-card>
|
|
|
|
<x-content.content-card icon="trophy" classes="border dark:border-gray-900 bg-gradient-to-br from-[#eeb425]/10 to-transparent">
|
|
<x-slot:title>
|
|
{{ __('radio.quick_stats') }}
|
|
</x-slot:title>
|
|
|
|
<x-slot:under-title>
|
|
{{ __('radio.current_stand') }}
|
|
</x-slot:under-title>
|
|
|
|
<div class="px-2 text-sm space-y-4 dark:text-gray-200">
|
|
<div class="flex justify-between items-center p-3 rounded-lg bg-gray-700/30">
|
|
<span class="text-gray-400">{{ __('radio.active_listeners') }}</span>
|
|
<span class="font-bold text-[#eeb425] text-lg">{{ count($users) }}</span>
|
|
</div>
|
|
@if(!empty($users))
|
|
<div class="flex justify-between items-center p-3 rounded-lg bg-yellow-500/10 border border-yellow-500/20">
|
|
<span class="text-gray-400">{{ __('radio.current_leader') }}</span>
|
|
<span class="font-bold text-yellow-400 flex items-center gap-2">
|
|
👑 {{ $users[0]['username'] }}
|
|
</span>
|
|
</div>
|
|
@endif
|
|
<div class="flex justify-between items-center p-3 rounded-lg bg-gray-700/30">
|
|
<span class="text-gray-400">{{ __('radio.current_period') }}</span>
|
|
<span class="font-semibold text-white">
|
|
{{ $period === 'weekly' ? __('radio.this_week') : ($period === 'monthly' ? __('radio.this_month') : __('radio.total')) }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</x-content.content-card>
|
|
|
|
<!-- Top 3 Compact -->
|
|
@if(!empty($users) && count($users) >= 3)
|
|
<x-content.content-card icon="trophy" classes="border dark:border-gray-900">
|
|
<x-slot:title>
|
|
Top 3
|
|
</x-slot:title>
|
|
|
|
<x-slot:under-title>
|
|
De beste luisteraars
|
|
</x-slot:under-title>
|
|
|
|
<div class="px-2 space-y-3">
|
|
@foreach(array_slice($users, 0, 3) as $index => $user)
|
|
<div class="flex items-center gap-3 p-3 rounded-lg {{ $index === 0 ? 'bg-yellow-500/10 border border-yellow-500/20' : 'bg-gray-700/30' }}">
|
|
<div class="w-8 h-8 rounded-full flex items-center justify-center font-bold text-sm
|
|
{{ $index === 0 ? 'bg-gradient-to-br from-yellow-400 to-yellow-600 text-gray-900' :
|
|
($index === 1 ? 'bg-gradient-to-br from-gray-300 to-gray-500 text-gray-900' :
|
|
'bg-gradient-to-br from-orange-400 to-orange-600 text-white') }}">
|
|
{{ $index + 1 }}
|
|
</div>
|
|
<img src="{{ $user['avatar'] ?? 'https://ui-avatars.com/api/?name=' . urlencode($user['username']) . '&size=64&background=374151&color=eeb425' }}"
|
|
alt="{{ $user['username'] }}"
|
|
class="w-10 h-10 rounded-full border-2 border-gray-600">
|
|
<div class="flex-1 min-w-0">
|
|
<div class="font-semibold text-white truncate">{{ $user['username'] }}</div>
|
|
<div class="text-xs text-[#eeb425]">{{ number_format($user['points']) }} pts</div>
|
|
</div>
|
|
<span class="text-xl">
|
|
{{ $index === 0 ? '🏆' : ($index === 1 ? '🥈' : '🥉') }}
|
|
</span>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</x-content.content-card>
|
|
@endif
|
|
</div>
|
|
</x-app-layout>
|