Files
Atomcms-edit/resources/themes/atom/views/user/profile.blade.php
T
root c53a5a8a2c Complete Hubbly theme conversion: all pages rewritten with CSS variable theming
- Converted all views from Dusk components (x-content.content-card, x-form.*) to inline Hubbly style
- All pages use consistent card pattern: rounded-lg, gradient headers, color-mix borders
- Added Hubbly-style homepage with 2-column layout, login card, swiper news carousel
- Rewrote navigation with Alpine.js dropdowns, CSS variable colors, Hubbly assets
- Updated profile page with Hubbly cards, fixed data bugs (friend/guild relationships)
- Rewrote register page to match Hubbly layout: banner header, avatar preview with Frank GIF, 2-column form, avatar carousel selector, border-4 inputs
- Rewrote login, settings, help center, radio, applications, utility pages
- All colors use CSS variables controlled by Filament theme editor
- Added Hubbly assets: banner, Frank GIF, navigation icons, online badge
- Removed all dependencies on x-content.* and x-form.* components
2026-06-27 17:01:02 +02:00

252 lines
16 KiB
PHP
Executable File

<x-app-layout>
@push('title', $user->username)
<div class="col-span-12">
<div class="flex flex-col gap-y-6">
{{-- Profile Header --}}
<div class="rounded-lg relative overflow-hidden" style="background: linear-gradient(140deg, var(--color-primary) 0%, color-mix(in srgb, var(--color-primary) 60%, #000) 100%);">
<div class="absolute inset-0 bg-black/30 z-10"></div>
<div class="relative z-20 flex items-center gap-x-4 p-4 md:p-6">
<div class="flex-shrink-0">
<div class="rounded-full overflow-hidden border-4" style="width: 100px; height: 100px; border-color: color-mix(in srgb, var(--color-primary) 50%, #fff); background-color: var(--color-surface);">
<img style="image-rendering: pixelated; width: 100%; height: 100%; object-fit: cover; object-position: center -10px;"
src="{{ setting('avatar_imager') }}{{ $user->look }}&direction=2&head_direction=3&gesture=sml&action=wav&size=l"
alt="">
</div>
</div>
<div class="flex flex-col text-white">
<h3 class="text-lg font-semibold opacity-80">{{ __('My name is,') }}</h3>
<h2 class="text-3xl font-bold text-shadow">
{{ $user->username }}
</h2>
<h4 class="text-base font-semibold italic opacity-80">{{ $user->motto }}</h4>
@if(isset($showOnline) && $showOnline)
<small class="text-xs mt-1 opacity-60">{{ __('Last online:') }} {{ $lastLogin ?? 'Unknown' }}</small>
@endif
</div>
</div>
</div>
{{-- Stats Bar --}}
@if(isset($showStats) && $showStats)
<div class="flex flex-wrap gap-4 p-3 rounded-lg" style="background-color: var(--color-surface); border: 1px solid color-mix(in srgb, var(--color-text-muted) 15%, transparent);">
<div class="flex items-center gap-2">
<svg class="w-4 h-4" style="color: var(--color-primary)" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
</svg>
<span class="text-sm" style="color: var(--color-text-muted)">{{ __('Account:') }}</span>
<span class="font-semibold" style="color: var(--color-primary)">{{ $accountAge ?? 'Unknown' }}</span>
</div>
<div class="flex items-center gap-2">
<svg class="w-4 h-4 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
<span class="text-sm" style="color: var(--color-text-muted)">{{ __('Friends:') }}</span>
<span class="font-semibold text-blue-400">{{ $totalFriends ?? 0 }}</span>
</div>
<div class="flex items-center gap-2">
<svg class="w-4 h-4 text-purple-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/>
</svg>
<span class="text-sm" style="color: var(--color-text-muted)">{{ __('Guilds:') }}</span>
<span class="font-semibold text-purple-400">{{ $totalGuilds ?? 0 }}</span>
</div>
</div>
@endif
{{-- Currency Boxes --}}
<div class="grid w-full grid-cols-1 gap-3 md:grid-cols-3">
<div class="rounded-lg flex flex-col gap-y-2 items-center justify-center py-4" style="background: linear-gradient(135deg, #f8ef2b 0%, #f8ef2b 100%);">
<img src="{{ asset('/assets/images/profile/credits.png') }}" alt="">
<h4 class="font-semibold text-2xl" style="color: #b16d18;">
{{ $user->credits }}
</h4>
</div>
<div class="rounded-lg flex flex-col gap-y-2 items-center justify-center py-4" style="background: linear-gradient(135deg, #e99bdc 0%, #e99bdc 100%);">
<img src="{{ asset('/assets/images/profile/duckets.png') }}" alt="">
<h4 class="font-semibold text-2xl" style="color: #812378;">
{{ $user->currency('duckets') }}
</h4>
</div>
<div class="rounded-lg flex flex-col gap-y-2 items-center justify-center py-4" style="background: linear-gradient(135deg, #82d6db 0%, #82d6db 100%);">
<img src="{{ asset('/assets/images/profile/diamonds.png') }}" alt="">
<h4 class="font-semibold text-2xl" style="color: #146867;">
{{ $user->currency('diamonds') }}
</h4>
</div>
</div>
{{-- Badges + Groups --}}
<div class="grid gap-4 grid-cols-1 md:grid-cols-2">
<x-user.profile-info-card col-span="1">
<x-slot:image>
<img class="h-[100px] w-full object-cover object-left rounded-t-lg" src="{{ asset('/assets/images/profile/badges.png') }}" alt="">
</x-slot:image>
<x-slot:title>
{{ __('Badges') }}
</x-slot:title>
<div class="flex flex-wrap gap-2 justify-between">
@forelse($badges as $badge)
<div data-tippy-content="{{ $badge->badge_code }}"
class="user-badge h-[70px] w-[70px] rounded-full flex items-center justify-center cursor-pointer"
style="border: 2px solid color-mix(in srgb, var(--color-text-muted) 30%, transparent);">
<img src="{{ setting('badges_path') }}/{{ $badge->badge_code }}.gif"
class="max-h-[55px] max-w-[55px]" alt="">
</div>
@empty
<div class="w-full text-center py-4" style="color: var(--color-text-muted)">
{{ __('It seems like :user has no badges.', ['user' => $user->username]) }}
</div>
@endforelse
</div>
</x-user.profile-info-card>
<x-user.profile-info-card col-span="1">
<x-slot:image>
<img class="h-[100px] w-full object-cover object-left rounded-t-lg" src="{{ asset('/assets/images/profile/groups.png') }}" alt="">
</x-slot:image>
<x-slot:title>
{{ __('Groups') }}
</x-slot:title>
<div class="flex flex-wrap gap-4 justify-between">
@forelse($groups as $group)
<div class="h-[70px] w-[70px] rounded-full overflow-hidden flex items-center justify-center p-1 cursor-pointer group-badge"
data-tippy-content="{{ $group->guild?->name ?? 'Unknown' }}"
style="border: 2px solid color-mix(in srgb, var(--color-text-muted) 30%, transparent);">
<img src="{{ setting('group_badge_path') }}/{{ $group->guild?->badge }}.png"
alt="">
</div>
@empty
<div class="w-full text-center py-4" style="color: var(--color-text-muted)">
{{ __('It seems like :user is not a member of any groups.', ['user' => $user->username]) }}
</div>
@endforelse
</div>
</x-user.profile-info-card>
</div>
{{-- Rooms + Friends --}}
<div class="grid gap-4 grid-cols-1 md:grid-cols-2">
<x-user.profile-info-card col-span="1">
<x-slot:image>
<img class="h-[100px] w-full object-cover object-left rounded-t-lg" src="{{ asset('/assets/images/profile/rooms.png') }}" alt="">
</x-slot:image>
<x-slot:title>
{{ __('Rooms') }}
</x-slot:title>
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
@forelse($user->rooms as $room)
<div class="flex flex-col gap-y-1 rounded-md overflow-hidden" style="background-color: color-mix(in srgb, var(--color-text-muted) 8%, transparent);">
<div class="relative">
<img
class="w-full h-[80px] object-cover"
src="{{ setting('room_thumbnail_path') }}/{{ $room->id }}.png"
alt="{{ $room->name }}"
onerror="this.onerror=null;this.src='{{ asset('/assets/images/profile/room_placeholder.png') }}';"
>
<div class="absolute bottom-1 left-1/2 transform -translate-x-1/2">
<div class="{{ $room->users > 0 ? 'bg-[#00800B]' : '' }} px-1 py-[1px] font-semibold rounded flex gap-x-[3px] items-center text-xs" style="color: var(--color-text); {{ $room->users > 0 ? '' : 'background-color: var(--color-text-muted);' }}">
<svg xmlns="http://www.w3.org/2000/svg" class="h-[12px]" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z" clip-rule="evenodd"/>
</svg>
{{ $room->users }}
</div>
</div>
</div>
<div class="flex items-center justify-between px-1 py-1">
<p class="truncate text-sm" style="color: var(--color-text)">{{ Str::limit($room->name, 10) }}</p>
</div>
</div>
@empty
<div class="col-span-3 text-center py-4" style="color: var(--color-text-muted)">
{{ __('It seems like :user got no rooms.', ['user' => $user->username]) }}
</div>
@endforelse
</div>
</x-user.profile-info-card>
<x-user.profile-info-card col-span="1">
<x-slot:image>
<img class="h-[100px] w-full object-cover object-left rounded-t-lg" src="{{ asset('/assets/images/profile/friends.png') }}" alt="">
</x-slot:image>
<x-slot:title>
{{ __('Friends') }}
</x-slot:title>
<div class="grid grid-cols-3 gap-2 sm:grid-cols-4 md:grid-cols-3 lg:grid-cols-4">
@forelse($friends as $friend)
<a href="{{ route('profile.show', $friend->user->username ?? 'SystemAccount') }}"
class="rounded-full overflow-hidden flex items-center justify-center p-1 cursor-pointer friend"
data-tippy-content="{{ $friend->user->username ?? 'Unknown' }}"
style="border: 2px solid color-mix(in srgb, var(--color-text-muted) 30%, transparent); width: 70px; height: 70px;">
<img class="transition duration-200 ease-in-out hover:scale-110"
style="image-rendering: pixelated; margin-top: 15px;"
src="{{ setting('avatar_imager') }}{{ $friend->user?->look }}&headonly=1"
alt="">
</a>
@empty
<div class="col-span-4 text-center py-4" style="color: var(--color-text-muted)">
{{ __('It seems like :user has no friends.', ['user' => $user->username]) }}
</div>
@endforelse
</div>
</x-user.profile-info-card>
</div>
{{-- Guestbook Section --}}
@if(isset($guestbook) && $guestbook->count() > 0)
<x-user.profile-info-card col-span="1">
<x-slot:image>
<div class="h-[60px] w-full rounded-t-lg flex items-center px-4" style="background: linear-gradient(140deg, var(--color-primary) 0%, color-mix(in srgb, var(--color-primary) 60%, #000) 100%);">
<span class="text-white font-bold text-lg">{{ __('Guestbook') }}</span>
</div>
</x-slot:image>
<x-slot:title>
{{ __('Recent Messages') }}
</x-slot:title>
<div class="flex flex-col gap-3">
@foreach($guestbook as $entry)
<div class="flex gap-3 p-2 rounded-lg" style="background-color: color-mix(in srgb, var(--color-text-muted) 8%, transparent);">
<div class="flex-shrink-0">
<div class="w-10 h-10 rounded-full overflow-hidden" style="border: 2px solid color-mix(in srgb, var(--color-text-muted) 30%, transparent);">
<img src="{{ setting('avatar_imager') }}{{ $entry->user?->look }}&headonly=1"
alt="" class="w-full h-full object-cover">
</div>
</div>
<div class="flex-1">
<div class="flex items-center gap-2">
<span class="font-semibold text-sm" style="color: var(--color-primary)">{{ $entry->user?->username ?? 'Unknown' }}</span>
<span class="text-xs" style="color: var(--color-text-muted)">{{ $entry->created_at?->diffForHumans() ?? '' }}</span>
</div>
<p class="text-sm mt-1" style="color: var(--color-text)">{{ $entry->message }}</p>
</div>
</div>
@endforeach
</div>
</x-user.profile-info-card>
@endif
</div>
</div>
@push('javascript')
<script type="module">
tippy('.user-badge');
tippy('.friend');
tippy('.group-badge');
</script>
@endpush
</x-app-layout>