2026-05-29 09:37:07 +03:00
|
|
|
@extends('layouts.app')
|
|
|
|
|
|
2026-05-31 14:19:47 +03:00
|
|
|
@section('title', ($user->slug ?? $user->name) . ' — LoreKeepers')
|
2026-05-29 09:37:07 +03:00
|
|
|
|
|
|
|
|
@section('content')
|
|
|
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
|
|
|
|
|
|
|
|
|
|
{{-- Profile Header --}}
|
|
|
|
|
<div class="flex items-start gap-6 mb-10">
|
|
|
|
|
@if($user->avatar)
|
|
|
|
|
<img src="{{ $user->avatar }}" class="w-20 h-20 rounded-full object-cover border-2 border-white/10" alt="">
|
|
|
|
|
@else
|
|
|
|
|
<div class="w-20 h-20 rounded-full bg-purple-700 flex items-center justify-center text-2xl font-bold text-white flex-shrink-0">
|
|
|
|
|
{{ strtoupper(substr($user->name, 0, 1)) }}
|
|
|
|
|
</div>
|
|
|
|
|
@endif
|
|
|
|
|
|
|
|
|
|
<div class="flex-1">
|
2026-05-30 23:47:32 +03:00
|
|
|
<h1 class="text-2xl font-bold text-white">{{ $user->slug ?? $user->name }}</h1>
|
|
|
|
|
@if($user->slug && $user->name !== $user->slug)
|
2026-05-29 09:37:07 +03:00
|
|
|
<p class="text-slate-500 text-sm">{{ $user->name }}</p>
|
|
|
|
|
@endif
|
|
|
|
|
@if($user->bio)
|
|
|
|
|
<p class="text-slate-400 mt-2 max-w-xl">{{ $user->bio }}</p>
|
|
|
|
|
@endif
|
|
|
|
|
|
|
|
|
|
{{-- Stats --}}
|
|
|
|
|
<div class="flex flex-wrap gap-6 mt-4">
|
|
|
|
|
<div class="text-center">
|
|
|
|
|
<div class="text-xl font-bold text-white">{{ number_format($stats['total']) }}</div>
|
|
|
|
|
<div class="text-xs text-slate-500 uppercase tracking-wide">Games</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="text-center">
|
|
|
|
|
<div class="text-xl font-bold text-white">{{ number_format($stats['played']) }}</div>
|
|
|
|
|
<div class="text-xs text-slate-500 uppercase tracking-wide">Played</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="text-center">
|
|
|
|
|
<div class="text-xl font-bold text-white">{{ number_format($stats['playing']) }}</div>
|
|
|
|
|
<div class="text-xs text-slate-500 uppercase tracking-wide">Playing</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="text-center">
|
|
|
|
|
<div class="text-xl font-bold text-white">{{ number_format($stats['want_to_play']) }}</div>
|
|
|
|
|
<div class="text-xs text-slate-500 uppercase tracking-wide">Want to Play</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-05-30 11:23:24 +03:00
|
|
|
<div class="flex items-start gap-6">
|
|
|
|
|
{{-- Follower / Following counts --}}
|
|
|
|
|
<div class="flex gap-4 text-center">
|
|
|
|
|
<div>
|
|
|
|
|
<div class="text-lg font-bold text-white">{{ $user->followers()->count() }}</div>
|
|
|
|
|
<div class="text-xs text-slate-500 uppercase tracking-wide">Followers</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div>
|
|
|
|
|
<div class="text-lg font-bold text-white">{{ $user->following()->count() }}</div>
|
|
|
|
|
<div class="text-xs text-slate-500 uppercase tracking-wide">Following</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-05-30 12:02:24 +03:00
|
|
|
<div class="flex gap-2 flex-wrap">
|
2026-05-30 11:23:24 +03:00
|
|
|
@auth
|
|
|
|
|
@if(auth()->id() !== $user->id)
|
|
|
|
|
<div x-data="{
|
|
|
|
|
following: {{ auth()->user()->isFollowing($user) ? 'true' : 'false' }},
|
|
|
|
|
async toggle() {
|
|
|
|
|
const method = this.following ? 'DELETE' : 'POST';
|
2026-05-30 23:47:32 +03:00
|
|
|
const res = await fetch('{{ route('users.follow', $user->slug) }}', {
|
2026-05-30 11:23:24 +03:00
|
|
|
method,
|
|
|
|
|
headers: {
|
|
|
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name=csrf-token]').content,
|
|
|
|
|
'Accept': 'application/json'
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
if (res.ok) {
|
|
|
|
|
const d = await res.json();
|
|
|
|
|
this.following = d.following;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}">
|
|
|
|
|
<button @click="toggle()"
|
|
|
|
|
:class="following
|
|
|
|
|
? 'bg-white/10 text-slate-300 hover:bg-red-900/30 hover:text-red-400 border border-white/10'
|
|
|
|
|
: 'bg-purple-600 hover:bg-purple-700 text-white'"
|
|
|
|
|
class="px-4 py-2 text-sm font-medium rounded-lg transition-colors">
|
|
|
|
|
<span x-text="following ? 'Following' : 'Follow'"></span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
@endif
|
|
|
|
|
@endauth
|
2026-05-30 23:47:32 +03:00
|
|
|
<a href="{{ route('users.library', $user->slug) }}"
|
2026-05-30 11:23:24 +03:00
|
|
|
class="px-4 py-2 border border-white/10 hover:border-white/20 text-slate-300 hover:text-white text-sm font-medium rounded-lg transition-colors">
|
|
|
|
|
View Library
|
|
|
|
|
</a>
|
2026-05-30 12:02:24 +03:00
|
|
|
@auth
|
|
|
|
|
@if(auth()->id() !== $user->id)
|
2026-05-30 23:47:32 +03:00
|
|
|
<a href="{{ route('users.compare', $user->slug) }}"
|
2026-05-30 12:02:24 +03:00
|
|
|
class="px-4 py-2 border border-purple-500/40 hover:border-purple-500 text-purple-300 hover:text-white text-sm font-medium rounded-lg transition-colors">
|
|
|
|
|
Compare Libraries
|
|
|
|
|
</a>
|
|
|
|
|
@endif
|
|
|
|
|
@endauth
|
2026-05-30 11:23:24 +03:00
|
|
|
</div>
|
2026-05-29 09:37:07 +03:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-05-30 01:57:35 +03:00
|
|
|
{{-- Top Genres --}}
|
|
|
|
|
@if($genreStats->isNotEmpty())
|
|
|
|
|
<div class="mb-10">
|
|
|
|
|
<h2 class="text-lg font-semibold text-white mb-3">Top Genres</h2>
|
|
|
|
|
<div class="flex flex-wrap gap-2">
|
|
|
|
|
@foreach($genreStats as $genre)
|
|
|
|
|
<span class="inline-flex items-center gap-1.5 px-3 py-1.5 bg-[#16161d] border border-white/10 rounded-full text-sm text-slate-300">
|
|
|
|
|
{{ $genre->name }}
|
|
|
|
|
<span class="text-xs text-purple-400 font-semibold">{{ $genre->count }}</span>
|
|
|
|
|
</span>
|
|
|
|
|
@endforeach
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
@endif
|
|
|
|
|
|
|
|
|
|
{{-- Recent Library --}}
|
|
|
|
|
@if($allGames->isNotEmpty())
|
2026-05-29 09:37:07 +03:00
|
|
|
<div>
|
2026-05-30 01:57:35 +03:00
|
|
|
<div class="flex items-center justify-between mb-4">
|
|
|
|
|
<h2 class="text-lg font-semibold text-white">Recent Library</h2>
|
2026-05-30 23:47:32 +03:00
|
|
|
<a href="{{ route('users.library', $user->slug) }}" class="text-sm text-purple-400 hover:text-purple-300 transition-colors">
|
2026-05-30 01:57:35 +03:00
|
|
|
View all →
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
2026-05-29 09:37:07 +03:00
|
|
|
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-4">
|
2026-05-30 01:57:35 +03:00
|
|
|
@foreach($allGames as $entry)
|
|
|
|
|
@php
|
|
|
|
|
$statusColors = [
|
|
|
|
|
'playing' => 'bg-green-600',
|
|
|
|
|
'played' => 'bg-blue-600',
|
|
|
|
|
'want_to_play' => 'bg-yellow-600',
|
|
|
|
|
'on_hold' => 'bg-orange-600',
|
|
|
|
|
'dropped' => 'bg-red-700',
|
|
|
|
|
];
|
|
|
|
|
$statusLabels = [
|
|
|
|
|
'playing' => 'Playing',
|
|
|
|
|
'played' => 'Played',
|
|
|
|
|
'want_to_play' => 'Want to Play',
|
|
|
|
|
'on_hold' => 'On Hold',
|
|
|
|
|
'dropped' => 'Dropped',
|
|
|
|
|
];
|
|
|
|
|
@endphp
|
|
|
|
|
<div class="relative">
|
|
|
|
|
<x-game-card :game="$entry->game" />
|
|
|
|
|
<span class="absolute top-2 left-2 text-xs font-semibold px-1.5 py-0.5 rounded {{ $statusColors[$entry->status] ?? 'bg-slate-700' }} text-white leading-tight">
|
|
|
|
|
{{ $statusLabels[$entry->status] ?? $entry->status }}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
2026-05-29 09:37:07 +03:00
|
|
|
@endforeach
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
@else
|
2026-05-30 01:57:35 +03:00
|
|
|
{{-- Empty state --}}
|
|
|
|
|
<div class="text-center py-20">
|
|
|
|
|
<div class="w-16 h-16 rounded-full bg-[#16161d] flex items-center justify-center mx-auto mb-4">
|
|
|
|
|
<svg class="w-8 h-8 text-slate-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
|
|
|
|
|
d="M15 5v2m0 4v2m0 4v2M5 5a2 2 0 00-2 2v3a2 2 0 110 4v3a2 2 0 002 2h14a2 2 0 002-2v-3a2 2 0 110-4V7a2 2 0 00-2-2H5z"/>
|
|
|
|
|
</svg>
|
|
|
|
|
</div>
|
|
|
|
|
<h3 class="text-lg font-medium text-slate-300 mb-2">No games tracked yet</h3>
|
|
|
|
|
<p class="text-slate-500 mb-6">Start building your game library!</p>
|
|
|
|
|
<a href="{{ route('games.index') }}"
|
|
|
|
|
class="inline-flex items-center gap-2 px-5 py-2.5 bg-purple-600 hover:bg-purple-700 text-white font-semibold rounded-lg transition-colors">
|
|
|
|
|
Browse Games
|
|
|
|
|
</a>
|
|
|
|
|
</div>
|
2026-05-29 09:37:07 +03:00
|
|
|
@endif
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
@endsection
|