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
This commit is contained in:
root
2026-06-27 17:01:02 +02:00
parent 61bb70ac1d
commit c53a5a8a2c
68 changed files with 4708 additions and 4608 deletions
@@ -1,137 +1,99 @@
<div class="relative hidden h-full w-full flex-col items-center gap-y-2 py-3 md:flex md:flex-row md:gap-x-8 md:gap-y-0 md:py-0" id="mobile-menu" style="color: var(--color-navbar-text)">
@auth
<x-navigation.dropdown icon="home" route-group="user*">
{{ auth()->user()->username }}
<div class="flex flex-col md:flex-row md:items-center md:justify-center w-full gap-y-3 md:gap-x-0 md:gap-y-0" id="mobile-menu"
:class="{ 'show-mobile': dropdownVisible }">
<x-slot:children>
<x-navigation.dropdown-child :route="route('me.show')">
{{ __('Home') }}
</x-navigation.dropdown-child>
<x-navigation.dropdown-child :route="route('draw-badge')">
{{ __('Badge Drawer') }}
</x-navigation.dropdown-child>
<x-navigation.dropdown-child :route="route('profile.show', auth()->user()->username)">
{{ __('My Profile') }}
</x-navigation.dropdown-child>
</x-slot:children>
</x-navigation.dropdown>
@else
<a href="{{ route('welcome') }}"
class="nav-item {{ request()->routeIs('welcome') ? 'border-b-2 border-[var(--color-primary)]' : '' }}">
<i class="mr-1 hidden navigation-icon home lg:inline-flex"></i>
{{ __('Home') }}
</a>
@endauth
@auth
<x-navigation.dropdown icon="community" route-group="community*" :uppercase="true">
{{ __('Community') }}
<x-slot:children>
<x-navigation.dropdown-child :route="route('article.index')">
{{ __('Articles') }}
</x-navigation.dropdown-child>
<x-navigation.dropdown-child :route="route('staff.index')">
{{ __('Staff') }}
</x-navigation.dropdown-child>
<x-navigation.dropdown-child :route="route('teams.index')">
{{ __('Teams') }}
</x-navigation.dropdown-child>
<x-navigation.dropdown-child :route="route('team-applications.index')">
{{ __('Team applications') }}
</x-navigation.dropdown-child>
<x-navigation.dropdown-child :route="route('staff-applications.index')">
{{ __('Staff applications') }}
</x-navigation.dropdown-child>
<x-navigation.dropdown-child :route="route('photos.index')">
{{ __('Photos') }}
</x-navigation.dropdown-child>
</x-slot:children>
</x-navigation.dropdown>
<a href="{{ route('leaderboard.index') }}"
class="nav-item {{ request()->routeIs('leaderboard.*') ? 'border-b-2 border-[var(--color-primary)]' : '' }}">
<i class="navigation-icon leaderboards mr-1 hidden lg:inline-flex"></i>
{{ __('Leaderboards') }}
</a>
<a href="{{ route('values.index') }}"
class="nav-item {{ request()->routeIs('values.*') ? 'border-b-2 border-[var(--color-primary)]' : '' }}">
<i class="navigation-icon leaderboards mr-1 hidden lg:inline-flex"></i>
{{ __('Rare values') }}
</a>
<a data-turbolinks="false" href="{{ route('shop.index') }}"
class="nav-item {{ request()->routeIs('shop.*') ? 'border-b-2 border-[var(--color-primary)]' : '' }}">
<i class="navigation-icon mr-1 hidden lg:inline-flex shop"></i>
{{ __('Shop') }}
</a>
@endauth
<x-navigation.dropdown icon="rules" route-group="help-center*" :uppercase="true">
{{ __('Assistance') }}
<x-slot:children>
@auth
<x-navigation.dropdown-child :route="route('help-center.index')">
{{ __('Help center') }}
</x-navigation.dropdown-child>
@if(hasPermission('manage_website_tickets'))
<x-navigation.dropdown-child :route="route('help-center.ticket.index')">
{{ __('Open tickets') }}
</x-navigation.dropdown-child>
@endif
@else
<x-navigation.dropdown-child :route="route('help-center.rules.index')">
{{ __('Rules') }}
</x-navigation.dropdown-child>
@endauth
</x-slot:children>
</x-navigation.dropdown>
<a href="{{ is_array(setting('discord_invitation_link')) ? '' : setting('discord_invitation_link') }}" target="_blank" class="nav-item">
{{ __('Discord') }}
</a>
<x-navigation.dropdown icon="music" route-group="radio*">
{{ __('Radio') }}
<x-slot:children>
<x-navigation.dropdown-child :route="route('radio.index')">
{{ __('Radio Home') }}
</x-navigation.dropdown-child>
<x-navigation.dropdown-child :route="route('radio.rooster')">
{{ __('DJ Rooster') }}
</x-navigation.dropdown-child>
<x-navigation.dropdown-child :route="route('radio.shouts')">
{{ __('Live Shouts') }}
</x-navigation.dropdown-child>
<x-navigation.dropdown-child :route="route('radio.apply')">
{{ __('Word DJ') }}
</x-navigation.dropdown-child>
<x-navigation.dropdown-child :route="route('radio.leaderboard')">
{{ __('Radio punten') }}
</x-navigation.dropdown-child>
</x-slot:children>
</x-navigation.dropdown>
<div class="w-full flex md:hidden gap-x-1 justify-center">
<x-navigation.language-selector>
<img src="/assets/images/icons/flags/{{ session()->has('locale') ? session()->get('locale') : config('habbo.site.default_language') }}.png"
alt="">
</x-navigation.language-selector>
<div x-data="{ open: false }" class="w-full py-1 md:py-0 md:w-auto md:relative" x-on:click.outside="open = false">
@auth
<a href="#" class="flex gap-2 px-1 h-auto md:h-[60px] items-center text-[14px] font-semibold uppercase transition duration-200 ease-in-out md:border-b-4 md:border-transparent md:hover:border-b-[var(--color-primary)] md:px-4"
style="color: var(--color-navbar-text);"
x-on:click.prevent="open = !open">
<img src="{{ asset('assets/images/icons/navigation/me.png') }}" alt="me" />
<span>{{ auth()->user()->username }}</span>
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor" style="color: var(--color-text-muted);"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
</a>
@else
<a href="{{ route('welcome') }}" class="flex gap-2 px-1 h-auto md:h-[60px] items-center text-[14px] font-semibold uppercase transition duration-200 ease-in-out md:border-b-4 md:border-transparent md:hover:border-b-[var(--color-primary)] md:px-4"
style="color: var(--color-navbar-text);">
<img src="{{ asset('assets/images/icons/navigation/me.png') }}" alt="home" />
<span>{{ __('Home') }}</span>
</a>
@endauth
@auth
<div x-show="open" x-cloak x-transition.duration.200ms
class="w-full md:absolute md:top-full md:left-0 md:z-50 md:min-w-[220px] md:py-2 md:mt-1 rounded-xl"
style="background-color: var(--color-dropdown); color: var(--color-text); border: 1px solid color-mix(in srgb, var(--color-primary) 30%, transparent); box-shadow: 0 4px 24px rgba(0,0,0,0.25);">
<a href="{{ route('me.show') }}" class="block py-4 px-8 font-semibold text-base transition hover:opacity-80 rounded-xl" style="color: var(--color-text);">{{ __('Home') }}</a>
<a href="{{ route('draw-badge') }}" class="block py-4 px-8 font-semibold text-base transition hover:opacity-80 rounded-xl" style="color: var(--color-text);">{{ __('Badge Drawer') }}</a>
<a href="{{ route('profile.show', auth()->user()->username) }}" class="block py-4 px-8 font-semibold text-base transition hover:opacity-80 rounded-xl" style="color: var(--color-text);">{{ __('My Profile') }}</a>
</div>
@endauth
</div>
</div>
<div x-data="{ open: false }" class="w-full py-1 md:py-0 md:w-auto md:relative" x-on:click.outside="open = false">
<a href="#" class="flex gap-2 px-1 h-auto md:h-[60px] items-center text-[14px] font-semibold uppercase transition duration-200 ease-in-out md:border-b-4 md:border-transparent md:hover:border-b-[var(--color-primary)] md:px-4"
style="color: var(--color-navbar-text);"
x-on:click.prevent="open = !open">
<img src="{{ asset('assets/images/icons/navigation/community.png') }}" alt="community" />
<span>{{ __('Community') }}</span>
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor" style="color: var(--color-text-muted);"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
</a>
<div x-show="open" x-cloak x-transition.duration.200ms
class="w-full md:absolute md:top-full md:left-0 md:z-50 md:min-w-[220px] md:py-2 md:mt-1 rounded-xl"
style="background-color: var(--color-dropdown); color: var(--color-text); border: 1px solid color-mix(in srgb, var(--color-primary) 30%, transparent); box-shadow: 0 4px 24px rgba(0,0,0,0.25);">
<a href="{{ route('article.index') }}" class="block py-4 px-8 font-semibold text-base transition hover:opacity-80 rounded-xl" style="color: var(--color-text);">{{ __('News') }}</a>
<a href="{{ route('photos.index') }}" class="block py-4 px-8 font-semibold text-base transition hover:opacity-80 rounded-xl" style="color: var(--color-text);">{{ __('Photos') }}</a>
<a href="{{ route('staff.index') }}" class="block py-4 px-8 font-semibold text-base transition hover:opacity-80 rounded-xl" style="color: var(--color-text);">{{ __('Staff') }}</a>
<a href="{{ route('teams.index') }}" class="block py-4 px-8 font-semibold text-base transition hover:opacity-80 rounded-xl" style="color: var(--color-text);">{{ __('Teams') }}</a>
<a href="{{ route('help-center.rules.index') }}" class="block py-4 px-8 font-semibold text-base transition hover:opacity-80 rounded-xl" style="color: var(--color-text);">{{ __('Rules') }}</a>
</div>
</div>
<div x-data="{ open: false }" class="w-full py-1 md:py-0 md:w-auto md:relative" x-on:click.outside="open = false">
<a href="#" class="flex gap-2 px-1 h-auto md:h-[60px] items-center text-[14px] font-semibold uppercase transition duration-200 ease-in-out md:border-b-4 md:border-transparent md:hover:border-b-[var(--color-primary)] md:px-4"
style="color: var(--color-navbar-text);"
x-on:click.prevent="open = !open">
<img src="{{ asset('assets/images/icons/navigation/goody.png') }}" alt="goodies" />
<span>{{ __('Goodies') }}</span>
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor" style="color: var(--color-text-muted);"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
</a>
<div x-show="open" x-cloak x-transition.duration.200ms
class="w-full md:absolute md:top-full md:left-0 md:z-50 md:min-w-[220px] md:py-2 md:mt-1 rounded-xl"
style="background-color: var(--color-dropdown); color: var(--color-text); border: 1px solid color-mix(in srgb, var(--color-primary) 30%, transparent); box-shadow: 0 4px 24px rgba(0,0,0,0.25);">
<a href="{{ route('shop.index') }}" class="block py-4 px-8 font-semibold text-base transition hover:opacity-80 rounded-xl" style="color: var(--color-text);">{{ __('Marketplace') }}</a>
</div>
</div>
<div x-data class="w-full py-1 md:py-0 md:w-auto md:relative">
<a href="{{ route('leaderboard.index') }}" class="flex gap-2 px-1 h-auto md:h-[60px] items-center text-[14px] font-semibold uppercase transition duration-200 ease-in-out md:border-b-4 md:border-transparent md:hover:border-b-[var(--color-primary)] md:px-4"
style="color: var(--color-navbar-text);">
<img src="{{ asset('assets/images/icons/navigation/leaderboards.png') }}" alt="leaderboards" />
<span>{{ __('Leaderboards') }}</span>
</a>
</div>
<div x-data class="w-full py-1 md:py-0 md:w-auto md:relative">
<a href="{{ route('shop.index') }}" class="flex gap-2 px-1 h-auto md:h-[60px] items-center text-[14px] font-semibold uppercase transition duration-200 ease-in-out md:border-b-4 md:border-transparent md:hover:border-b-[var(--color-primary)] md:px-4"
style="color: var(--color-navbar-text);">
<img src="{{ asset('assets/images/icons/navigation/shop.png') }}" alt="store" />
<span>{{ __('Store') }}</span>
</a>
</div>
<div x-data="{ open: false }" class="w-full py-1 md:py-0 md:w-auto md:relative" x-on:click.outside="open = false">
<a href="#" class="flex gap-2 px-1 h-auto md:h-[60px] items-center text-[14px] font-semibold uppercase transition duration-200 ease-in-out md:border-b-4 md:border-transparent md:hover:border-b-[var(--color-primary)] md:px-4"
style="color: var(--color-navbar-text);"
x-on:click.prevent="open = !open">
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" /></svg>
<span>{{ __('Radio') }}</span>
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" viewBox="0 0 20 20" fill="currentColor" style="color: var(--color-text-muted);"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/></svg>
</a>
<div x-show="open" x-cloak x-transition.duration.200ms
class="w-full md:absolute md:top-full md:left-0 md:z-50 md:min-w-[220px] md:py-2 md:mt-1 rounded-xl"
style="background-color: var(--color-dropdown); color: var(--color-text); border: 1px solid color-mix(in srgb, var(--color-primary) 30%, transparent); box-shadow: 0 4px 24px rgba(0,0,0,0.25);">
<a href="{{ route('radio.index') }}" class="block py-4 px-8 font-semibold text-base transition hover:opacity-80 rounded-xl" style="color: var(--color-text);">{{ __('Listen') }}</a>
<a href="{{ route('radio.rooster') }}" class="block py-4 px-8 font-semibold text-base transition hover:opacity-80 rounded-xl" style="color: var(--color-text);">{{ __('Schedule') }}</a>
<a href="{{ route('radio.leaderboard') }}" class="block py-4 px-8 font-semibold text-base transition hover:opacity-80 rounded-xl" style="color: var(--color-text);">{{ __('Points') }}</a>
<a href="{{ route('radio.shouts') }}" class="block py-4 px-8 font-semibold text-base transition hover:opacity-80 rounded-xl" style="color: var(--color-text);">{{ __('Shouts') }}</a>
</div>
</div>
</div>