diff --git a/app/Filament/Pages/General/ThemeSettings.php b/app/Filament/Pages/General/ThemeSettings.php index e0ddbd9..a906a8f 100755 --- a/app/Filament/Pages/General/ThemeSettings.php +++ b/app/Filament/Pages/General/ThemeSettings.php @@ -185,6 +185,19 @@ final class ThemeSettings extends Page implements HasForms // Page transition 'page_transition' => $this->getSettingBool('page_transition', true), + // Login Effect settings + 'login_effect_enabled' => $this->getSettingBool('login_effect_enabled', false), + 'login_effect_animation' => $this->getSetting('login_effect_animation', 'none'), + 'login_effect_background' => $this->getSetting('login_effect_background', '#0f1922'), + 'login_effect_icon_color' => $this->getSetting('login_effect_icon_color', '#eeb425'), + 'login_effect_text_color' => $this->getSetting('login_effect_text_color', '#ffffff'), + 'login_effect_bar_color' => $this->getSetting('login_effect_bar_color', '#eeb425'), + 'login_effect_bar_style' => $this->getSetting('login_effect_bar_style', 'bar'), + 'login_effect_show_logo' => $this->getSettingBool('login_effect_show_logo', true), + 'login_effect_show_name' => $this->getSettingBool('login_effect_show_name', true), + 'login_effect_icon_size' => $this->getSetting('login_effect_icon_size', '120'), + 'login_effect_custom_text' => $this->getSetting('login_effect_custom_text', ''), + // Header/Footer colors 'header_background' => $this->getSetting('header_background', '#2d2d44'), 'header_text_color' => $this->getSetting('header_text_color', '#ffffff'), @@ -1995,6 +2008,100 @@ final class ThemeSettings extends Page implements HasForms ]) ->columns(2), + // LOGIN EFFECT + Section::make(__('Client Login Effect')) + ->description(__('Fully customize the loading screen shown before the Nitro client loads')) + ->icon('heroicon-o-sparkles') + ->schema([ + Toggle::make('login_effect_enabled') + ->label(__('Enable client login effect')) + ->default(false) + ->helperText(__('Show a loading screen on the Nitro client page')), + Select::make('login_effect_animation') + ->label(__('Animation effect')) + ->options([ + 'none' => __('None'), + 'sparkle' => '✨ ' . __('Sparkle'), + 'glow' => '💡 ' . __('Glow'), + 'float' => '🎈 ' . __('Float'), + 'bounce' => '⚡ ' . __('Bounce'), + 'pulse' => '💓 ' . __('Pulse'), + 'shine' => '✨ ' . __('Shine'), + 'shake' => '📳 ' . __('Shake'), + 'wobble' => '🌀 ' . __('Wobble'), + 'heartbeat' => '❤️ ' . __('Heartbeat'), + 'rubber-band' => '🎯 ' . __('Rubber Band'), + 'flip' => '🔄 ' . __('Flip'), + 'swing' => '🎪 ' . __('Swing'), + 'jello' => '🍮 Jello', + 'color-cycle' => '🌈 ' . __('Color Cycle'), + 'rotate' => '🔄 ' . __('Rotate'), + 'scale-pulse' => '💫 ' . __('Scale Pulse'), + 'fade-in' => '👻 ' . __('Fade In'), + 'fade-out' => '🌫️ ' . __('Fade Out'), + 'slide-up' => '⬆️ ' . __('Slide Up'), + 'slide-down' => '⬇️ ' . __('Slide Down'), + 'slide-left' => '⬅️ ' . __('Slide Left'), + 'slide-right' => '➡️ ' . __('Slide Right'), + 'zoom-in' => '🔍 ' . __('Zoom In'), + 'zoom-out' => '🔎 ' . __('Zoom Out'), + 'neon-pulse' => '💡 ' . __('Neon Pulse'), + 'rainbow' => '🌈 ' . __('Rainbow'), + 'wave' => '〰️ ' . __('Wave'), + 'ripple' => '💧 ' . __('Ripple'), + 'fire' => '🔥 ' . __('Fire'), + 'ice' => '🧊 ' . __('Ice'), + 'glitch' => '👾 ' . __('Glitch'), + 'pop' => '🎉 ' . __('Pop'), + ]) + ->default('none') + ->helperText(__('Animation for the icon during loading')), + ColorPicker::make('login_effect_background') + ->label(__('Background color')) + ->default('#0f1922'), + ColorPicker::make('login_effect_icon_color') + ->label(__('Icon background color')) + ->default('#eeb425'), + ColorPicker::make('login_effect_text_color') + ->label(__('Text color')) + ->default('#ffffff'), + ColorPicker::make('login_effect_bar_color') + ->label(__('Loading bar color')) + ->default('#eeb425'), + Select::make('login_effect_bar_style') + ->label(__('Loading bar style')) + ->options([ + 'bar' => '━ ' . __('Sliding bar'), + 'dots' => '● ' . __('Bouncing dots'), + 'pulse' => '◉ ' . __('Pulsing circle'), + 'double' => '═ ' . __('Double bar'), + 'spinner' => '◌ ' . __('Spinning circle'), + 'skeleton' => '▯ ' . __('Skeleton glow'), + ]) + ->default('bar') + ->helperText(__('Style of the loading indicator')), + TextInput::make('login_effect_icon_size') + ->label(__('Icon size (px)')) + ->numeric() + ->minValue(60) + ->maxValue(300) + ->default(120) + ->helperText(__('Diameter of the icon circle in pixels')), + Toggle::make('login_effect_show_logo') + ->label(__('Show logo')) + ->default(true) + ->helperText(__('Show the generated logo from the logo generator')), + Toggle::make('login_effect_show_name') + ->label(__('Show hotel name')) + ->default(true) + ->helperText(__('Show the hotel name below the icon')), + TextInput::make('login_effect_custom_text') + ->label(__('Custom subtitle text')) + ->placeholder(__('Leave empty to use default')) + ->helperText(__('Optional text shown below the hotel name')), + ]) + ->columns(2), + // v1.3 PWA (PROGRESSIVE WEB APP) Section::make(__('PWA - Progressive Web App')) ->description(__('Make your hotel installable as an app')) @@ -2048,6 +2155,9 @@ final class ThemeSettings extends Page implements HasForms 'nav_icon_radio', 'avatar_border', 'page_transition', + 'login_effect_enabled', + 'login_effect_show_logo', + 'login_effect_show_name', ]); $this->saveSettings([ 'preset', @@ -2170,6 +2280,14 @@ final class ThemeSettings extends Page implements HasForms 'pwa_description', 'pwa_theme_color', 'pwa_background_color', + 'login_effect_animation', + 'login_effect_background', + 'login_effect_icon_color', + 'login_effect_text_color', + 'login_effect_bar_color', + 'login_effect_icon_size', + 'login_effect_bar_style', + 'login_effect_custom_text', ]); SettingsService::clearCache(); diff --git a/app/Http/Controllers/Client/NitroController.php b/app/Http/Controllers/Client/NitroController.php index cec6818..446e2a6 100755 --- a/app/Http/Controllers/Client/NitroController.php +++ b/app/Http/Controllers/Client/NitroController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Client; use App\Http\Controllers\Controller; +use App\Models\Miscellaneous\WebsiteSetting; use Illuminate\View\View; class NitroController extends Controller @@ -23,8 +24,34 @@ class NitroController extends Controller $sso = $user->ssoTicket(); + $keys = [ + 'login_effect_enabled', 'login_effect_animation', 'login_effect_background', + 'login_effect_icon_color', 'login_effect_text_color', 'login_effect_bar_color', + 'login_effect_bar_style', 'login_effect_icon_size', 'login_effect_show_logo', + 'login_effect_show_name', 'login_effect_custom_text', + ]; + + $settings = WebsiteSetting::whereIn('key', $keys)->pluck('value', 'key'); + + $loginData = null; + if (($settings['login_effect_enabled'] ?? '0') === '1') { + $loginData = [ + 'animation' => $settings['login_effect_animation'] ?? 'none', + 'background' => $settings['login_effect_background'] ?? '#0f1922', + 'icon_color' => $settings['login_effect_icon_color'] ?? '#eeb425', + 'text_color' => $settings['login_effect_text_color'] ?? '#ffffff', + 'bar_color' => $settings['login_effect_bar_color'] ?? '#eeb425', + 'bar_style' => $settings['login_effect_bar_style'] ?? 'bar', + 'icon_size' => $settings['login_effect_icon_size'] ?? '120', + 'show_logo' => ($settings['login_effect_show_logo'] ?? '0') === '1', + 'show_name' => ($settings['login_effect_show_name'] ?? '0') === '1', + 'custom_text' => $settings['login_effect_custom_text'] ?? '', + ]; + } + return view('client.' . $view, [ 'sso' => $sso, + 'loginData' => $loginData, ]); } } diff --git a/resources/themes/atom/views/client/nitro.blade.php b/resources/themes/atom/views/client/nitro.blade.php index ce270b9..1cb14bf 100755 --- a/resources/themes/atom/views/client/nitro.blade.php +++ b/resources/themes/atom/views/client/nitro.blade.php @@ -369,11 +369,289 @@ pointer-events: none; } - @keyframes djPopupPulse { - 0%, 100% { opacity: 1; transform: scale(1); } - 50% { opacity: 0.5; transform: scale(1.02); } - } - + @keyframes djPopupPulse { + 0%, 100% { opacity: 1; transform: scale(1); } + 50% { opacity: 0.5; transform: scale(1.02); } + } + + {{-- Client Loading Overlay --}} + @if($loginData) + @php $ic = $loginData['icon_color']; $bg = $loginData['background']; @endphp + .client-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 10001; + display: flex; + align-items: center; + justify-content: center; + background: {{ $bg }}; + transition: opacity 0.6s ease, transform 0.6s ease; + } + .client-overlay.hidden { + opacity: 0; + transform: scale(1.1); + pointer-events: none; + } + .client-overlay-content { + text-align: center; + } + .client-overlay-icon { + width: {{ $loginData['icon_size'] }}px; + height: {{ $loginData['icon_size'] }}px; + margin: 0 auto 24px; + background: {{ $ic }}; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 48px; + color: {{ $loginData['text_color'] }}; + box-shadow: 0 0 40px {{ $ic }}44; + } + .client-overlay-letter { + font-size: 52px; + font-weight: 800; + line-height: 1; + } + .client-overlay-img { + width: 80px; + height: auto; + object-fit: contain; + } + .client-overlay-text { + font-size: 28px; + font-weight: 700; + color: {{ $loginData['text_color'] }}; + margin-bottom: 16px; + letter-spacing: 2px; + } + .client-overlay-subtitle { + font-size: 14px; + color: {{ $loginData['text_color'] }}99; + margin-bottom: 24px; + } + .client-overlay-loader { + margin: 24px auto 0; + position: relative; + } + @keyframes clientBar { + 0% { left: -40%; } + 100% { left: 100%; } + } + @keyframes clientDots { + 0%, 80%, 100% { transform: scale(0); } + 40% { transform: scale(1); } + } + @keyframes clientPulseLoad { + 0%, 100% { transform: scale(1); opacity: 0.5; } + 50% { transform: scale(1.3); opacity: 1; } + } + @keyframes clientSpinLoad { + to { transform: rotate(360deg); } + } + @keyframes clientSkeleton { + 0% { background-position: -200px 0; } + 100% { background-position: calc(200px + 100%) 0; } + } + + .client-bar-bar { + width: 200px; + height: 4px; + background: rgba(255,255,255,0.1); + border-radius: 4px; + overflow: hidden; + position: relative; + } + .client-bar-bar::after { + content: ''; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 40%; + background: {{ $loginData['bar_color'] }}; + border-radius: 4px; + animation: clientBar 1.2s ease-in-out infinite; + } + + .client-bar-dots { + display: flex; + gap: 8px; + justify-content: center; + align-items: center; + height: 20px; + } + .client-bar-dots span { + width: 12px; + height: 12px; + background: {{ $loginData['bar_color'] }}; + border-radius: 50%; + display: inline-block; + animation: clientDots 1.4s ease-in-out infinite both; + } + .client-bar-dots span:nth-child(1) { animation-delay: -0.32s; } + .client-bar-dots span:nth-child(2) { animation-delay: -0.16s; } + .client-bar-dots span:nth-child(3) { animation-delay: 0s; } + + .client-bar-pulse { + width: 24px; + height: 24px; + margin: 0 auto; + background: {{ $loginData['bar_color'] }}; + border-radius: 50%; + animation: clientPulseLoad 1.5s ease-in-out infinite; + } + + .client-bar-double { + width: 200px; + height: 4px; + position: relative; + margin: 0 auto; + } + .client-bar-double::before, + .client-bar-double::after { + content: ''; + position: absolute; + height: 4px; + border-radius: 4px; + background: {{ $loginData['bar_color'] }}66; + } + .client-bar-double::before { + width: 100%; + top: 0; + animation: clientBar 2s ease-in-out infinite; + } + .client-bar-double::after { + width: 60%; + top: 10px; + animation: clientBar 2s ease-in-out infinite reverse; + } + + .client-bar-spinner { + width: 30px; + height: 30px; + margin: 0 auto; + border: 3px solid rgba(255,255,255,0.1); + border-top-color: {{ $loginData['bar_color'] }}; + border-radius: 50%; + animation: clientSpinLoad 0.8s linear infinite; + } + + .client-bar-skeleton { + width: 200px; + height: 14px; + margin: 0 auto; + background: rgba(255,255,255,0.06); + border-radius: 8px; + position: relative; + overflow: hidden; + } + .client-bar-skeleton::after { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, {{ $loginData['bar_color'] }}33, transparent); + background-size: 200px 100%; + animation: clientSkeleton 1.5s ease-in-out infinite; + } + + {{-- Animation Effects --}} + .client-effect-sparkle .client-overlay-icon { animation: clientSparkle 1.5s ease-in-out infinite; } + @keyframes clientSparkle { + 0%, 100% { transform: scale(1) rotate(0deg); box-shadow: 0 0 20px {{ $ic }}44; } + 50% { transform: scale(1.15) rotate(10deg); box-shadow: 0 0 60px {{ $ic }}88; } + } + .client-effect-glow .client-overlay-icon { animation: clientGlow 2s ease-in-out infinite; } + @keyframes clientGlow { + 0%, 100% { box-shadow: 0 0 20px {{ $ic }}44; } + 50% { box-shadow: 0 0 80px {{ $ic }}cc, 0 0 120px {{ $ic }}66; } + } + .client-effect-float .client-overlay-icon { animation: clientFloat 3s ease-in-out infinite; } + @keyframes clientFloat { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-20px); } + } + .client-effect-bounce .client-overlay-icon { animation: clientBounce 1s ease-in-out infinite; } + @keyframes clientBounce { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-30px); } + } + .client-effect-pulse .client-overlay-icon { animation: clientPulse 1.5s ease-in-out infinite; } + @keyframes clientPulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.1); } + } + .client-effect-shine .client-overlay-icon { overflow: hidden; position: relative; } + .client-effect-shine .client-overlay-icon::after { + content: ''; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient(45deg, transparent 40%, rgba(255,255,255,0.3) 50%, transparent 60%); + animation: clientShine 2s ease-in-out infinite; + } + @keyframes clientShine { + 0% { transform: translateX(-100%) rotate(45deg); } + 100% { transform: translateX(100%) rotate(45deg); } + } + .client-effect-heartbeat .client-overlay-icon { animation: clientHeartbeat 1.5s ease-in-out infinite; } + @keyframes clientHeartbeat { + 0%, 100% { transform: scale(1); } + 15% { transform: scale(1.2); } + 30% { transform: scale(1); } + 45% { transform: scale(1.15); } + 60% { transform: scale(1); } + } + .client-effect-rotate .client-overlay-icon { animation: clientRotate 2s linear infinite; } + @keyframes clientRotate { + to { transform: rotate(360deg); } + } + .client-effect-color-cycle .client-overlay-icon { animation: clientColorCycle 3s linear infinite; } + @keyframes clientColorCycle { + 0% { background: {{ $ic }}; } + 25% { background: #ef4444; } + 50% { background: #22c55e; } + 75% { background: #3b82f6; } + 100% { background: {{ $ic }}; } + } + .client-effect-neon-pulse .client-overlay-icon { animation: clientNeonPulse 1.5s ease-in-out infinite; } + @keyframes clientNeonPulse { + 0%, 100% { box-shadow: 0 0 20px {{ $ic }}, 0 0 40px {{ $ic }}44; } + 50% { box-shadow: 0 0 60px {{ $ic }}, 0 0 100px {{ $ic }}88, 0 0 140px {{ $ic }}44; } + } + .client-effect-rainbow .client-overlay-icon { animation: clientRainbow 4s linear infinite; } + @keyframes clientRainbow { + 0% { filter: hue-rotate(0deg); } + 100% { filter: hue-rotate(360deg); } + } + .client-effect-fire .client-overlay-icon { animation: clientFire 0.5s ease-in-out infinite alternate; } + @keyframes clientFire { + 0% { transform: scale(1); box-shadow: 0 0 30px #ff4500, 0 0 60px #ff8c00; background: #ff4500; } + 100% { transform: scale(1.05); box-shadow: 0 0 50px #ff8c00, 0 0 80px #ff4500; background: #ff6347; } + } + .client-effect-glitch .client-overlay-content { animation: clientGlitchText 0.3s ease-in-out infinite alternate; } + @keyframes clientGlitchText { + 0% { transform: translate(0); } + 25% { transform: translate(-3px, 2px); } + 50% { transform: translate(3px, -2px); } + 75% { transform: translate(-2px, -1px); } + 100% { transform: translate(2px, 1px); } + } + .client-effect-pop .client-overlay-icon { animation: clientPop 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55) infinite; } + @keyframes clientPop { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.3); } + } + @endif + @@ -479,14 +757,67 @@ {{-- Nitro Client --}} @php $nitroUrl = sprintf('%s/index.html?sso=%s', setting('nitro_path'), $sso); - $toolbarParams = []; - // Toolbar with fallback to button colors (don't URL encode - # is valid in URLs) - $toolbarParams[] = 'toolbar_primary=' . (setting('toolbar_primary_color') ?: setting('button_primary_color', '#eeb425')); - $toolbarParams[] = 'toolbar_hover=' . (setting('toolbar_hover_color') ?: setting('button_hover_color', '#cf9d15')); - $toolbarParams[] = 'toolbar_border=' . (setting('toolbar_border_color') ?: setting('button_border_color', '#cf9d15')); - $toolbarParams[] = 'toolbar_text=' . (setting('toolbar_text_color') ?: setting('button_text_color', '#1a1a2e')); - if(count($toolbarParams)) $nitroUrl .= '&' . implode('&', $toolbarParams); + $toolbarParams = []; + // Toolbar with fallback to button colors (don't URL encode - # is valid in URLs) + $toolbarParams[] = 'toolbar_primary=' . (setting('toolbar_primary_color') ?: setting('button_primary_color', '#eeb425')); + $toolbarParams[] = 'toolbar_hover=' . (setting('toolbar_hover_color') ?: setting('button_hover_color', '#cf9d15')); + $toolbarParams[] = 'toolbar_border=' . (setting('toolbar_border_color') ?: setting('button_border_color', '#cf9d15')); + $toolbarParams[] = 'toolbar_text=' . (setting('toolbar_text_color') ?: setting('button_text_color', '#1a1a2e')); + if(count($toolbarParams)) $nitroUrl .= '&' . implode('&', $toolbarParams); @endphp + + {{-- Client Loading Overlay --}} + @if($loginData) + @php $cmsLogo = setting('cms_logo'); $anim = $loginData['animation']; @endphp +
+
+
+ @if($loginData['show_logo'] && $cmsLogo) + {{ setting('hotel_name') }} + @else + {{ substr(setting('hotel_name'), 0, 1) }} + @endif +
+ @if($loginData['show_name']) +
{{ setting('hotel_name') }}
+ @endif + @if($loginData['custom_text']) +
{{ $loginData['custom_text'] }}
+ @endif +
+ @if($loginData['bar_style'] === 'dots') +
+ @else +
+ @endif +
+
+
+ + @endif + @@ -674,12 +1005,13 @@ setInterval(updateRadioInfo, 10000); - // Init - window.addEventListener('DOMContentLoaded', () => { - loadRadio(); - updateRadioInfo(); - }); - + // Init + window.addEventListener('DOMContentLoaded', () => { + loadRadio(); + updateRadioInfo(); + }); + + diff --git a/resources/themes/dusk/views/client/nitro.blade.php b/resources/themes/dusk/views/client/nitro.blade.php index ae4a30e..582b8a1 100755 --- a/resources/themes/dusk/views/client/nitro.blade.php +++ b/resources/themes/dusk/views/client/nitro.blade.php @@ -237,6 +237,284 @@ .hidden { display: none !important; } + + {{-- Client Loading Overlay --}} + @if($loginData) + @php $ic = $loginData['icon_color']; $bg = $loginData['background']; @endphp + .client-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 10001; + display: flex; + align-items: center; + justify-content: center; + background: {{ $bg }}; + transition: opacity 0.6s ease, transform 0.6s ease; + } + .client-overlay.hidden { + opacity: 0; + transform: scale(1.1); + pointer-events: none; + } + .client-overlay-content { + text-align: center; + } + .client-overlay-icon { + width: {{ $loginData['icon_size'] }}px; + height: {{ $loginData['icon_size'] }}px; + margin: 0 auto 24px; + background: {{ $ic }}; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 48px; + color: {{ $loginData['text_color'] }}; + box-shadow: 0 0 40px {{ $ic }}44; + } + .client-overlay-letter { + font-size: 52px; + font-weight: 800; + line-height: 1; + } + .client-overlay-img { + width: 80px; + height: auto; + object-fit: contain; + } + .client-overlay-text { + font-size: 28px; + font-weight: 700; + color: {{ $loginData['text_color'] }}; + margin-bottom: 16px; + letter-spacing: 2px; + } + .client-overlay-subtitle { + font-size: 14px; + color: {{ $loginData['text_color'] }}99; + margin-bottom: 24px; + } + .client-overlay-loader { + margin: 24px auto 0; + position: relative; + } + @keyframes clientBar { + 0% { left: -40%; } + 100% { left: 100%; } + } + @keyframes clientDots { + 0%, 80%, 100% { transform: scale(0); } + 40% { transform: scale(1); } + } + @keyframes clientPulseLoad { + 0%, 100% { transform: scale(1); opacity: 0.5; } + 50% { transform: scale(1.3); opacity: 1; } + } + @keyframes clientSpinLoad { + to { transform: rotate(360deg); } + } + @keyframes clientSkeleton { + 0% { background-position: -200px 0; } + 100% { background-position: calc(200px + 100%) 0; } + } + + .client-bar-bar { + width: 200px; + height: 4px; + background: rgba(255,255,255,0.1); + border-radius: 4px; + overflow: hidden; + position: relative; + } + .client-bar-bar::after { + content: ''; + position: absolute; + top: 0; + left: 0; + height: 100%; + width: 40%; + background: {{ $loginData['bar_color'] }}; + border-radius: 4px; + animation: clientBar 1.2s ease-in-out infinite; + } + + .client-bar-dots { + display: flex; + gap: 8px; + justify-content: center; + align-items: center; + height: 20px; + } + .client-bar-dots span { + width: 12px; + height: 12px; + background: {{ $loginData['bar_color'] }}; + border-radius: 50%; + display: inline-block; + animation: clientDots 1.4s ease-in-out infinite both; + } + .client-bar-dots span:nth-child(1) { animation-delay: -0.32s; } + .client-bar-dots span:nth-child(2) { animation-delay: -0.16s; } + .client-bar-dots span:nth-child(3) { animation-delay: 0s; } + + .client-bar-pulse { + width: 24px; + height: 24px; + margin: 0 auto; + background: {{ $loginData['bar_color'] }}; + border-radius: 50%; + animation: clientPulseLoad 1.5s ease-in-out infinite; + } + + .client-bar-double { + width: 200px; + height: 4px; + position: relative; + margin: 0 auto; + } + .client-bar-double::before, + .client-bar-double::after { + content: ''; + position: absolute; + height: 4px; + border-radius: 4px; + background: {{ $loginData['bar_color'] }}66; + } + .client-bar-double::before { + width: 100%; + top: 0; + animation: clientBar 2s ease-in-out infinite; + } + .client-bar-double::after { + width: 60%; + top: 10px; + animation: clientBar 2s ease-in-out infinite reverse; + } + + .client-bar-spinner { + width: 30px; + height: 30px; + margin: 0 auto; + border: 3px solid rgba(255,255,255,0.1); + border-top-color: {{ $loginData['bar_color'] }}; + border-radius: 50%; + animation: clientSpinLoad 0.8s linear infinite; + } + + .client-bar-skeleton { + width: 200px; + height: 14px; + margin: 0 auto; + background: rgba(255,255,255,0.06); + border-radius: 8px; + position: relative; + overflow: hidden; + } + .client-bar-skeleton::after { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, {{ $loginData['bar_color'] }}33, transparent); + background-size: 200px 100%; + animation: clientSkeleton 1.5s ease-in-out infinite; + } + + {{-- Animation Effects --}} + .client-effect-sparkle .client-overlay-icon { animation: clientSparkle 1.5s ease-in-out infinite; } + @keyframes clientSparkle { + 0%, 100% { transform: scale(1) rotate(0deg); box-shadow: 0 0 20px {{ $ic }}44; } + 50% { transform: scale(1.15) rotate(10deg); box-shadow: 0 0 60px {{ $ic }}88; } + } + .client-effect-glow .client-overlay-icon { animation: clientGlow 2s ease-in-out infinite; } + @keyframes clientGlow { + 0%, 100% { box-shadow: 0 0 20px {{ $ic }}44; } + 50% { box-shadow: 0 0 80px {{ $ic }}cc, 0 0 120px {{ $ic }}66; } + } + .client-effect-float .client-overlay-icon { animation: clientFloat 3s ease-in-out infinite; } + @keyframes clientFloat { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-20px); } + } + .client-effect-bounce .client-overlay-icon { animation: clientBounce 1s ease-in-out infinite; } + @keyframes clientBounce { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-30px); } + } + .client-effect-pulse .client-overlay-icon { animation: clientPulse 1.5s ease-in-out infinite; } + @keyframes clientPulse { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.1); } + } + .client-effect-shine .client-overlay-icon { overflow: hidden; position: relative; } + .client-effect-shine .client-overlay-icon::after { + content: ''; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: linear-gradient(45deg, transparent 40%, rgba(255,255,255,0.3) 50%, transparent 60%); + animation: clientShine 2s ease-in-out infinite; + } + @keyframes clientShine { + 0% { transform: translateX(-100%) rotate(45deg); } + 100% { transform: translateX(100%) rotate(45deg); } + } + .client-effect-heartbeat .client-overlay-icon { animation: clientHeartbeat 1.5s ease-in-out infinite; } + @keyframes clientHeartbeat { + 0%, 100% { transform: scale(1); } + 15% { transform: scale(1.2); } + 30% { transform: scale(1); } + 45% { transform: scale(1.15); } + 60% { transform: scale(1); } + } + .client-effect-rotate .client-overlay-icon { animation: clientRotate 2s linear infinite; } + @keyframes clientRotate { + to { transform: rotate(360deg); } + } + .client-effect-color-cycle .client-overlay-icon { animation: clientColorCycle 3s linear infinite; } + @keyframes clientColorCycle { + 0% { background: {{ $ic }}; } + 25% { background: #ef4444; } + 50% { background: #22c55e; } + 75% { background: #3b82f6; } + 100% { background: {{ $ic }}; } + } + .client-effect-neon-pulse .client-overlay-icon { animation: clientNeonPulse 1.5s ease-in-out infinite; } + @keyframes clientNeonPulse { + 0%, 100% { box-shadow: 0 0 20px {{ $ic }}, 0 0 40px {{ $ic }}44; } + 50% { box-shadow: 0 0 60px {{ $ic }}, 0 0 100px {{ $ic }}88, 0 0 140px {{ $ic }}44; } + } + .client-effect-rainbow .client-overlay-icon { animation: clientRainbow 4s linear infinite; } + @keyframes clientRainbow { + 0% { filter: hue-rotate(0deg); } + 100% { filter: hue-rotate(360deg); } + } + .client-effect-fire .client-overlay-icon { animation: clientFire 0.5s ease-in-out infinite alternate; } + @keyframes clientFire { + 0% { transform: scale(1); box-shadow: 0 0 30px #ff4500, 0 0 60px #ff8c00; background: #ff4500; } + 100% { transform: scale(1.05); box-shadow: 0 0 50px #ff8c00, 0 0 80px #ff4500; background: #ff6347; } + } + .client-effect-glitch .client-overlay-content { animation: clientGlitchText 0.3s ease-in-out infinite alternate; } + @keyframes clientGlitchText { + 0% { transform: translate(0); } + 25% { transform: translate(-3px, 2px); } + 50% { transform: translate(3px, -2px); } + 75% { transform: translate(-2px, -1px); } + 100% { transform: translate(2px, 1px); } + } + .client-effect-pop .client-overlay-icon { animation: clientPop 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55) infinite; } + @keyframes clientPop { + 0%, 100% { transform: scale(1); } + 50% { transform: scale(1.3); } + } + @endif @@ -348,6 +626,59 @@ $toolbarParams[] = 'toolbar_text=' . (setting('toolbar_text_color') ?: setting('button_text_color', '#1a1a2e')); if(count($toolbarParams)) $nitroUrl .= '&' . implode('&', $toolbarParams); @endphp + + {{-- Client Loading Overlay --}} + @if($loginData) + @php $cmsLogo = setting('cms_logo'); $anim = $loginData['animation']; @endphp +
+
+
+ @if($loginData['show_logo'] && $cmsLogo) + {{ setting('hotel_name') }} + @else + {{ substr(setting('hotel_name'), 0, 1) }} + @endif +
+ @if($loginData['show_name']) +
{{ setting('hotel_name') }}
+ @endif + @if($loginData['custom_text']) +
{{ $loginData['custom_text'] }}
+ @endif +
+ @if($loginData['bar_style'] === 'dots') +
+ @else +
+ @endif +
+
+
+ + @endif + @@ -524,6 +855,7 @@ loadRadio(); updateRadioInfo(); }); + diff --git a/theme-settings-export.json b/theme-settings-export.json index 20f0b3c..6097f2f 100755 --- a/theme-settings-export.json +++ b/theme-settings-export.json @@ -1,5 +1,5 @@ { - "exported_at": "2026-05-01 09:25:10", + "exported_at": "2026-05-22 18:56:37", "settings": { "preset": "atom_original", "color_primary": "#eeb425", @@ -73,9 +73,9 @@ "button_danger_hover_color": "#dc2626", "button_danger_border_color": "#dc2626", "button_outline_enabled": true, - "button_outline_color": "#f59e0b", - "button_outline_text_color": "#1e293b", - "button_outline_hover_color": "#d97706", + "button_outline_color": "#eeb425", + "button_outline_text_color": "#1a1a2e", + "button_outline_hover_color": "#cf9d15", "nav_icon_discord_url": "", "nav_icon_radio": true, "navbar_height": "64", @@ -84,30 +84,65 @@ "navbar_style": "default", "avatar_border_radius": "8", "avatar_border": true, - "avatar_border_color": "#f59e0b", - "badge_background": "#f59e0b", + "avatar_border_color": "#eeb425", + "badge_background": "#eeb425", "badge_text_color": "#000000", "badge_border_radius": "4", "shadow_color": "rgba(0, 0, 0, 0.1)", "shadow_opacity": "0.1", "spinner_color": "#eeb425", - "input_background": "#ffffff", - "input_border_color": "#d1d5db", - "input_text_color": "#1f2937", - "input_placeholder_color": "#6b7280", + "input_background": "#1f2937", + "input_border_color": "#4b5563", + "input_text_color": "#ffffff", + "input_placeholder_color": "#9ca3af", "input_focus_color": "#eeb425", - "link_color": "#f59e0b", - "link_hover_color": "#d97706", + "link_color": "#eeb425", + "link_hover_color": "#cf9d15", "link_underline": false, "card_border_width": "1", "card_border_radius": "12", "page_transition": true, + "login_effect_enabled": true, + "login_effect_animation": "fire", + "login_effect_background": "#0088ff", + "login_effect_icon_color": "#eeb425", + "login_effect_text_color": "#ffffff", + "login_effect_bar_color": "#eeb425", + "login_effect_bar_style": "dots", + "login_effect_show_logo": true, + "login_effect_show_name": true, + "login_effect_icon_size": "120", + "login_effect_custom_text": "", "header_background": "#2d2d44", "header_text_color": "#ffffff", "header_link_color": "#eeb425", "footer_background": "#2d2d44", "footer_text_color": "#ffffff", "footer_link_color": "#eeb425", - "card_padding": "24" + "card_padding": "24", + "profile_show_online_status": true, + "profile_show_guilds": true, + "profile_show_friends": true, + "profile_show_guestbook": true, + "profile_show_photos": true, + "profile_show_badges": true, + "profile_show_stats": true, + "profile_show_activity": true, + "profile_header_style": "default", + "profile_default_tab": "guestbook", + "custom_css_enabled": false, + "custom_css": "", + "custom_js_enabled": false, + "custom_js": "", + "header_custom_html": "", + "footer_custom_html": "", + "footer_show_copyright": true, + "footer_show_links": true, + "pwa_enabled": false, + "pwa_name": "Epicnabbo Hotel", + "pwa_short_name": "Epicnabbo", + "pwa_description": "Welcome to Epicnabbo - Your Habbo Hotel", + "pwa_theme_color": "#eeb425", + "pwa_background_color": "#1a1a2e" } } \ No newline at end of file