You've already forked Atomcms-edit
feat: add customizable Nitro client loading overlay with Filament settings
Add full Client Login Effect section to Theme & Buttons page with: - Enable toggle, 30+ animation effects, customizable colors/logo/text - 6 loading bar styles (sliding, dots, pulse, double, spinner, skeleton) - Optimized to single DB query via WebsiteSetting::whereIn - Overlay covers Nitro v3 internal loading (5s min, 15s fallback)
This commit is contained in:
@@ -185,6 +185,19 @@ final class ThemeSettings extends Page implements HasForms
|
|||||||
// Page transition
|
// Page transition
|
||||||
'page_transition' => $this->getSettingBool('page_transition', true),
|
'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/Footer colors
|
||||||
'header_background' => $this->getSetting('header_background', '#2d2d44'),
|
'header_background' => $this->getSetting('header_background', '#2d2d44'),
|
||||||
'header_text_color' => $this->getSetting('header_text_color', '#ffffff'),
|
'header_text_color' => $this->getSetting('header_text_color', '#ffffff'),
|
||||||
@@ -1995,6 +2008,100 @@ final class ThemeSettings extends Page implements HasForms
|
|||||||
])
|
])
|
||||||
->columns(2),
|
->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)
|
// v1.3 PWA (PROGRESSIVE WEB APP)
|
||||||
Section::make(__('PWA - Progressive Web App'))
|
Section::make(__('PWA - Progressive Web App'))
|
||||||
->description(__('Make your hotel installable as an app'))
|
->description(__('Make your hotel installable as an app'))
|
||||||
@@ -2048,6 +2155,9 @@ final class ThemeSettings extends Page implements HasForms
|
|||||||
'nav_icon_radio',
|
'nav_icon_radio',
|
||||||
'avatar_border',
|
'avatar_border',
|
||||||
'page_transition',
|
'page_transition',
|
||||||
|
'login_effect_enabled',
|
||||||
|
'login_effect_show_logo',
|
||||||
|
'login_effect_show_name',
|
||||||
]);
|
]);
|
||||||
$this->saveSettings([
|
$this->saveSettings([
|
||||||
'preset',
|
'preset',
|
||||||
@@ -2170,6 +2280,14 @@ final class ThemeSettings extends Page implements HasForms
|
|||||||
'pwa_description',
|
'pwa_description',
|
||||||
'pwa_theme_color',
|
'pwa_theme_color',
|
||||||
'pwa_background_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();
|
SettingsService::clearCache();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
namespace App\Http\Controllers\Client;
|
namespace App\Http\Controllers\Client;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Miscellaneous\WebsiteSetting;
|
||||||
use Illuminate\View\View;
|
use Illuminate\View\View;
|
||||||
|
|
||||||
class NitroController extends Controller
|
class NitroController extends Controller
|
||||||
@@ -23,8 +24,34 @@ class NitroController extends Controller
|
|||||||
|
|
||||||
$sso = $user->ssoTicket();
|
$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, [
|
return view('client.' . $view, [
|
||||||
'sso' => $sso,
|
'sso' => $sso,
|
||||||
|
'loginData' => $loginData,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -369,11 +369,289 @@
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes djPopupPulse {
|
@keyframes djPopupPulse {
|
||||||
0%, 100% { opacity: 1; transform: scale(1); }
|
0%, 100% { opacity: 1; transform: scale(1); }
|
||||||
50% { opacity: 0.5; transform: scale(1.02); }
|
50% { opacity: 0.5; transform: scale(1.02); }
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
{{-- 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
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="overflow-hidden" id="nitro-client">
|
<body class="overflow-hidden" id="nitro-client">
|
||||||
@@ -479,14 +757,67 @@
|
|||||||
{{-- Nitro Client --}}
|
{{-- Nitro Client --}}
|
||||||
@php
|
@php
|
||||||
$nitroUrl = sprintf('%s/index.html?sso=%s', setting('nitro_path'), $sso);
|
$nitroUrl = sprintf('%s/index.html?sso=%s', setting('nitro_path'), $sso);
|
||||||
$toolbarParams = [];
|
$toolbarParams = [];
|
||||||
// Toolbar with fallback to button colors (don't URL encode - # is valid in URLs)
|
// 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_primary=' . (setting('toolbar_primary_color') ?: setting('button_primary_color', '#eeb425'));
|
||||||
$toolbarParams[] = 'toolbar_hover=' . (setting('toolbar_hover_color') ?: setting('button_hover_color', '#cf9d15'));
|
$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_border=' . (setting('toolbar_border_color') ?: setting('button_border_color', '#cf9d15'));
|
||||||
$toolbarParams[] = 'toolbar_text=' . (setting('toolbar_text_color') ?: setting('button_text_color', '#1a1a2e'));
|
$toolbarParams[] = 'toolbar_text=' . (setting('toolbar_text_color') ?: setting('button_text_color', '#1a1a2e'));
|
||||||
if(count($toolbarParams)) $nitroUrl .= '&' . implode('&', $toolbarParams);
|
if(count($toolbarParams)) $nitroUrl .= '&' . implode('&', $toolbarParams);
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
|
{{-- Client Loading Overlay --}}
|
||||||
|
@if($loginData)
|
||||||
|
@php $cmsLogo = setting('cms_logo'); $anim = $loginData['animation']; @endphp
|
||||||
|
<div id="clientOverlay" class="client-overlay client-effect-{{ $anim }}">
|
||||||
|
<div class="client-overlay-content">
|
||||||
|
<div class="client-overlay-icon">
|
||||||
|
@if($loginData['show_logo'] && $cmsLogo)
|
||||||
|
<img src="{{ $cmsLogo }}" alt="{{ setting('hotel_name') }}" class="client-overlay-img">
|
||||||
|
@else
|
||||||
|
<span class="client-overlay-letter">{{ substr(setting('hotel_name'), 0, 1) }}</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
@if($loginData['show_name'])
|
||||||
|
<div class="client-overlay-text">{{ setting('hotel_name') }}</div>
|
||||||
|
@endif
|
||||||
|
@if($loginData['custom_text'])
|
||||||
|
<div class="client-overlay-subtitle">{{ $loginData['custom_text'] }}</div>
|
||||||
|
@endif
|
||||||
|
<div class="client-overlay-loader">
|
||||||
|
@if($loginData['bar_style'] === 'dots')
|
||||||
|
<div class="client-bar-dots"><span></span><span></span><span></span></div>
|
||||||
|
@else
|
||||||
|
<div class="client-bar-{{ $loginData['bar_style'] }}"></div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var overlay = document.getElementById('clientOverlay');
|
||||||
|
var iframe = document.getElementById('nitro');
|
||||||
|
var startTime = Date.now();
|
||||||
|
var hidden = false;
|
||||||
|
function hideOverlay() {
|
||||||
|
if (!hidden) {
|
||||||
|
hidden = true;
|
||||||
|
overlay.classList.add('hidden');
|
||||||
|
setTimeout(function() { overlay.remove(); }, 700);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (iframe) {
|
||||||
|
iframe.addEventListener('load', function() {
|
||||||
|
var elapsed = Date.now() - startTime;
|
||||||
|
var minWait = Math.max(0, 5000 - elapsed);
|
||||||
|
setTimeout(hideOverlay, minWait);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setTimeout(hideOverlay, 15000);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
@endif
|
||||||
|
|
||||||
<iframe id="nitro" src="{{ $nitroUrl }}"
|
<iframe id="nitro" src="{{ $nitroUrl }}"
|
||||||
class="absolute top-0 left-0 m-0 h-full w-full overflow-hidden border-none p-0"></iframe>
|
class="absolute top-0 left-0 m-0 h-full w-full overflow-hidden border-none p-0"></iframe>
|
||||||
|
|
||||||
@@ -674,12 +1005,13 @@
|
|||||||
|
|
||||||
setInterval(updateRadioInfo, 10000);
|
setInterval(updateRadioInfo, 10000);
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
window.addEventListener('DOMContentLoaded', () => {
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
loadRadio();
|
loadRadio();
|
||||||
updateRadioInfo();
|
updateRadioInfo();
|
||||||
});
|
});
|
||||||
</script>
|
|
||||||
|
</script>
|
||||||
|
|
||||||
<script src="{{ asset('assets/js/atom.js') }}"></script>
|
<script src="{{ asset('assets/js/atom.js') }}"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -237,6 +237,284 @@
|
|||||||
.hidden {
|
.hidden {
|
||||||
display: none !important;
|
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
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@@ -348,6 +626,59 @@
|
|||||||
$toolbarParams[] = 'toolbar_text=' . (setting('toolbar_text_color') ?: setting('button_text_color', '#1a1a2e'));
|
$toolbarParams[] = 'toolbar_text=' . (setting('toolbar_text_color') ?: setting('button_text_color', '#1a1a2e'));
|
||||||
if(count($toolbarParams)) $nitroUrl .= '&' . implode('&', $toolbarParams);
|
if(count($toolbarParams)) $nitroUrl .= '&' . implode('&', $toolbarParams);
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
|
{{-- Client Loading Overlay --}}
|
||||||
|
@if($loginData)
|
||||||
|
@php $cmsLogo = setting('cms_logo'); $anim = $loginData['animation']; @endphp
|
||||||
|
<div id="clientOverlay" class="client-overlay client-effect-{{ $anim }}">
|
||||||
|
<div class="client-overlay-content">
|
||||||
|
<div class="client-overlay-icon">
|
||||||
|
@if($loginData['show_logo'] && $cmsLogo)
|
||||||
|
<img src="{{ $cmsLogo }}" alt="{{ setting('hotel_name') }}" class="client-overlay-img">
|
||||||
|
@else
|
||||||
|
<span class="client-overlay-letter">{{ substr(setting('hotel_name'), 0, 1) }}</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
@if($loginData['show_name'])
|
||||||
|
<div class="client-overlay-text">{{ setting('hotel_name') }}</div>
|
||||||
|
@endif
|
||||||
|
@if($loginData['custom_text'])
|
||||||
|
<div class="client-overlay-subtitle">{{ $loginData['custom_text'] }}</div>
|
||||||
|
@endif
|
||||||
|
<div class="client-overlay-loader">
|
||||||
|
@if($loginData['bar_style'] === 'dots')
|
||||||
|
<div class="client-bar-dots"><span></span><span></span><span></span></div>
|
||||||
|
@else
|
||||||
|
<div class="client-bar-{{ $loginData['bar_style'] }}"></div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var overlay = document.getElementById('clientOverlay');
|
||||||
|
var iframe = document.getElementById('nitro');
|
||||||
|
var startTime = Date.now();
|
||||||
|
var hidden = false;
|
||||||
|
function hideOverlay() {
|
||||||
|
if (!hidden) {
|
||||||
|
hidden = true;
|
||||||
|
overlay.classList.add('hidden');
|
||||||
|
setTimeout(function() { overlay.remove(); }, 700);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (iframe) {
|
||||||
|
iframe.addEventListener('load', function() {
|
||||||
|
var elapsed = Date.now() - startTime;
|
||||||
|
var minWait = Math.max(0, 5000 - elapsed);
|
||||||
|
setTimeout(hideOverlay, minWait);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setTimeout(hideOverlay, 15000);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
@endif
|
||||||
|
|
||||||
<iframe id="nitro" src="{{ $nitroUrl }}"
|
<iframe id="nitro" src="{{ $nitroUrl }}"
|
||||||
class="absolute top-0 left-0 m-0 h-full w-full overflow-hidden border-none p-0"></iframe>
|
class="absolute top-0 left-0 m-0 h-full w-full overflow-hidden border-none p-0"></iframe>
|
||||||
|
|
||||||
@@ -524,6 +855,7 @@
|
|||||||
loadRadio();
|
loadRadio();
|
||||||
updateRadioInfo();
|
updateRadioInfo();
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="{{ asset('assets/js/atom.js') }}"></script>
|
<script src="{{ asset('assets/js/atom.js') }}"></script>
|
||||||
|
|||||||
+48
-13
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"exported_at": "2026-05-01 09:25:10",
|
"exported_at": "2026-05-22 18:56:37",
|
||||||
"settings": {
|
"settings": {
|
||||||
"preset": "atom_original",
|
"preset": "atom_original",
|
||||||
"color_primary": "#eeb425",
|
"color_primary": "#eeb425",
|
||||||
@@ -73,9 +73,9 @@
|
|||||||
"button_danger_hover_color": "#dc2626",
|
"button_danger_hover_color": "#dc2626",
|
||||||
"button_danger_border_color": "#dc2626",
|
"button_danger_border_color": "#dc2626",
|
||||||
"button_outline_enabled": true,
|
"button_outline_enabled": true,
|
||||||
"button_outline_color": "#f59e0b",
|
"button_outline_color": "#eeb425",
|
||||||
"button_outline_text_color": "#1e293b",
|
"button_outline_text_color": "#1a1a2e",
|
||||||
"button_outline_hover_color": "#d97706",
|
"button_outline_hover_color": "#cf9d15",
|
||||||
"nav_icon_discord_url": "",
|
"nav_icon_discord_url": "",
|
||||||
"nav_icon_radio": true,
|
"nav_icon_radio": true,
|
||||||
"navbar_height": "64",
|
"navbar_height": "64",
|
||||||
@@ -84,30 +84,65 @@
|
|||||||
"navbar_style": "default",
|
"navbar_style": "default",
|
||||||
"avatar_border_radius": "8",
|
"avatar_border_radius": "8",
|
||||||
"avatar_border": true,
|
"avatar_border": true,
|
||||||
"avatar_border_color": "#f59e0b",
|
"avatar_border_color": "#eeb425",
|
||||||
"badge_background": "#f59e0b",
|
"badge_background": "#eeb425",
|
||||||
"badge_text_color": "#000000",
|
"badge_text_color": "#000000",
|
||||||
"badge_border_radius": "4",
|
"badge_border_radius": "4",
|
||||||
"shadow_color": "rgba(0, 0, 0, 0.1)",
|
"shadow_color": "rgba(0, 0, 0, 0.1)",
|
||||||
"shadow_opacity": "0.1",
|
"shadow_opacity": "0.1",
|
||||||
"spinner_color": "#eeb425",
|
"spinner_color": "#eeb425",
|
||||||
"input_background": "#ffffff",
|
"input_background": "#1f2937",
|
||||||
"input_border_color": "#d1d5db",
|
"input_border_color": "#4b5563",
|
||||||
"input_text_color": "#1f2937",
|
"input_text_color": "#ffffff",
|
||||||
"input_placeholder_color": "#6b7280",
|
"input_placeholder_color": "#9ca3af",
|
||||||
"input_focus_color": "#eeb425",
|
"input_focus_color": "#eeb425",
|
||||||
"link_color": "#f59e0b",
|
"link_color": "#eeb425",
|
||||||
"link_hover_color": "#d97706",
|
"link_hover_color": "#cf9d15",
|
||||||
"link_underline": false,
|
"link_underline": false,
|
||||||
"card_border_width": "1",
|
"card_border_width": "1",
|
||||||
"card_border_radius": "12",
|
"card_border_radius": "12",
|
||||||
"page_transition": true,
|
"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_background": "#2d2d44",
|
||||||
"header_text_color": "#ffffff",
|
"header_text_color": "#ffffff",
|
||||||
"header_link_color": "#eeb425",
|
"header_link_color": "#eeb425",
|
||||||
"footer_background": "#2d2d44",
|
"footer_background": "#2d2d44",
|
||||||
"footer_text_color": "#ffffff",
|
"footer_text_color": "#ffffff",
|
||||||
"footer_link_color": "#eeb425",
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user