HEX
Server: LiteSpeed
System: Linux us-phx-web629.main-hosting.eu 5.14.0-503.23.2.el9_5.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Feb 12 05:52:18 EST 2025 x86_64
User: u756937133 (756937133)
PHP: 8.2.27
Disabled: passthru,chgrp
Upload Files
File: /home/u756937133/domains/swingersnest.com/public_html/resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="scroll-smooth">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    @php
        $siteSettings = \App\Models\SiteSetting::getSettings();
        $siteTitle = $siteSettings->site_title ?? config('app.name', 'SwingersNest');
        $siteDescription = $siteSettings->site_description ?? config('app.meta_description', 'SwingersNest');
        $siteKeywords = $siteSettings->site_keywords ?? '';
    @endphp

    <title>@yield('title', $siteTitle)</title>
    <meta name="description" content="@yield('meta_description', $siteDescription)">
    @if($siteKeywords)
        <meta name="keywords" content="{{ $siteKeywords }}">
    @endif
    <meta name="csrf-token" content="{{ csrf_token() }}">
    
    {{-- Resource Hints for Performance --}}
    <link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
    <link rel="dns-prefetch" href="https://rsms.me">
    <link rel="dns-prefetch" href="https://ui-avatars.com">
    
    {{-- Favicon & Icon --}}
    <link rel="icon" type="image/svg+xml" href="{{ asset('assets/logonew.png') }}">
    <!-- @if($siteSettings->site_favicon)
        <link rel="icon" type="image/x-icon" href="{{ asset($siteSettings->site_favicon) }}">
    @else
        <link rel="icon" type="image/svg+xml" href="{{ asset('logonew.png') }}">
    @endif -->
    
    @if($siteSettings->site_icon)
        <link rel="apple-touch-icon" href="{{ asset($siteSettings->site_icon) }}">
    @elseif($siteSettings->site_favicon)
        <link rel="apple-touch-icon" href="{{ asset($siteSettings->site_favicon) }}">
    @else
        <link rel="apple-touch-icon" href="{{ asset('favicon.svg') }}">
    @endif

    {{-- Open Graph Meta Tags --}}
    @if($siteSettings->og_title || $siteSettings->og_description)
        <meta property="og:type" content="{{ $siteSettings->og_type ?? 'website' }}">
        <meta property="og:title" content="{{ $siteSettings->og_title ?? $siteTitle }}">
        <meta property="og:description" content="{{ $siteSettings->og_description ?? $siteDescription }}">
        @if($siteSettings->og_image)
            <meta property="og:image" content="{{ url(asset($siteSettings->og_image)) }}">
        @endif
        @if($siteSettings->og_site_name)
            <meta property="og:site_name" content="{{ $siteSettings->og_site_name }}">
        @endif
        @if($siteSettings->og_url)
            <meta property="og:url" content="{{ $siteSettings->og_url }}">
        @endif
    @endif

    {{-- Twitter Card Meta Tags --}}
    @if($siteSettings->twitter_title || $siteSettings->twitter_description)
        <meta name="twitter:card" content="{{ $siteSettings->twitter_card_type ?? 'summary_large_image' }}">
        <meta name="twitter:title" content="{{ $siteSettings->twitter_title ?? $siteTitle }}">
        <meta name="twitter:description" content="{{ $siteSettings->twitter_description ?? $siteDescription }}">
        @if($siteSettings->twitter_image)
            <meta name="twitter:image" content="{{ url(asset($siteSettings->twitter_image)) }}">
        @elseif($siteSettings->og_image)
            <meta name="twitter:image" content="{{ url(asset($siteSettings->og_image)) }}">
        @endif
    @endif

    {{-- Header Scripts (GSC, Analytics, etc.) --}}
    @if($siteSettings->header_scripts)
        {!! $siteSettings->header_scripts !!}
    @endif

    {{-- Custom CSS --}}
    @if($siteSettings->custom_css)
        <style>
            {!! $siteSettings->custom_css !!}
        </style>
    @endif

    <!-- Remix Icons CDN with preload -->
    <link
      rel="preload"
      href="https://cdn.jsdelivr.net/npm/remixicon@4.7.0/fonts/remixicon.css"
      as="style"
      onload="this.onload=null;this.rel='stylesheet'"
    >
    <noscript><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/remixicon@4.7.0/fonts/remixicon.css"></noscript>

    <!-- Google Fonts: Combined and optimized with font-display: swap -->
    <link
      rel="preload"
      href="https://fonts.googleapis.com/css2?family=Arimo:wght@400;500;600;700&family=Leckerli+One&family=Grand+Hotel&display=swap"
      as="style"
      onload="this.onload=null;this.rel='stylesheet'"
    >
    <noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Arimo:wght@400;500;600;700&family=Leckerli+One&family=Grand+Hotel&display=swap"></noscript>

    <!-- <link rel="stylesheet" href="{{ asset('public/style.css') }}"> -->

    @if(request()->routeIs('home') || request()->is('/'))

    <!-- <script src="https://cdn.tailwindcss.com"></script>  -->
    <!-- //Hasseb don't use CDN , run NPM run dev its auto enable all tailwind classes  -->
    @endif

    <style>
        /* Ensure user dropdown hover works */
        .group:hover #user-dropdown-menu,
        #user-dropdown-menu:hover {
            opacity: 1 !important;
            visibility: visible !important;
        }
    </style>

    <script>
        // Initialize theme immediately to prevent flash of wrong theme
        // Default to 'light' mode for new visitors - light mode is the default theme
        (function() {
            const storedTheme = localStorage.getItem('theme');
            const theme = storedTheme || 'light';
            if (theme === 'dark') {
                document.documentElement.classList.add('dark');
            } else {
                document.documentElement.classList.remove('dark');
            }
        })();
        
        // Global auth flag
        window.isAuthenticated = @json(auth()->check());
    </script>

    <!-- Inter font - optimized with preload -->
    <link
      rel="preload"
      href="https://rsms.me/inter/inter.css"
      as="style"
      onload="this.onload=null;this.rel='stylesheet'"
    >
    <noscript><link rel="stylesheet" href="https://rsms.me/inter/inter.css"></noscript>

    @vite(['resources/css/app.css', 'resources/js/app.js'])

    @stack('head')
</head>
<body class="antialiased font-sans {{ request()->routeIs('messages.*') ? 'messages-page-no-scroll' : '' }}">
    <script>
        // Clean up any leftover body styles from previous pages
        // The settings page was setting overflow: hidden and height: 100vh which shouldn't persist
        document.addEventListener('DOMContentLoaded', function() {
            // Small delay to check if modals need these styles
            setTimeout(function() {
                const hasOpenModal = document.querySelector('.fixed.inset-0.z-50:not(.hidden), [role="dialog"]:not([aria-hidden="true"])');
                // Clear height: 100vh as it's almost never needed on body
                if (document.body.style.height === '100vh' && !hasOpenModal) {
                    document.body.style.height = '';
                }
            }, 50);
        });
    </script>
    <div class="min-h-screen pt-[68px] {{ request()->routeIs('messages.*') ? 'h-screen overflow-hidden flex flex-col' : '' }}">
        @include('partials.header')

        {{-- Profile Pending Approval Bar --}}
        @auth
            @if(!Auth::user()->is_active && !Auth::user()->is_admin)
                <div class="w-full bg-red-600 text-white py-3 px-4 shadow-md">
                    <div class="container mx-auto flex items-center justify-between">
                        <div class="flex items-center gap-3">
                            <i class="ri-alert-line text-xl"></i>
                            <p class="font-semibold">
                                Your profile is pending admin approval. You will be able to access all features once your profile is approved.
                            </p>
                        </div>
                    </div>
                </div>
            @endif
        @endauth

        <main class="{{ request()->routeIs('messages.*') ? 'flex-1 min-h-0 min-w-0 overflow-hidden flex flex-col' : '' }}">

            @hasSection('full-width')
                @yield('full-width')
            @else
                <div class="px-4 sm:px-6 lg:px-8 py-6">
                    @yield('content')
                </div>
            @endif
        </main>

        @unless(request()->routeIs('messages.*'))
            @include('partials.footer')
        @endunless
    </div>

    {{-- Mobile Bottom Navigation Bar (authenticated users only) --}}
    @include('partials.mobile-bottom-nav')

    @include('components.toast')

    @stack('modals')

    @include('partials.auth-modals')
    
    <!-- Complete Profile Modal -->
    @auth
        @php
            $user = Auth::user();
            $profile = $user->profile;
            
            // Calculate Profile Completion Percentage (same logic as profile page)
            $languages = $profile && $profile->languages 
                ? (is_array($profile->languages) ? $profile->languages : json_decode($profile->languages, true) ?? [])
                : [];
            
            $preferences = $profile && $profile->preferences 
                ? (is_array($profile->preferences) ? $profile->preferences : json_decode($profile->preferences, true) ?? [])
                : [];
            
            $isCouple = $profile && $profile->category === 'couple';
            $coupleData = $profile && $profile->couple_data ? (is_array($profile->couple_data) ? $profile->couple_data : json_decode($profile->couple_data, true) ?? []) : [];
            
            $profileFields = [
                'category' => $profile && $profile->category ? 1 : 0,
                'preferences' => $profile && $profile->preferences && !empty($preferences) ? 1 : 0,
                'date_of_birth' => $profile && $profile->date_of_birth ? 1 : 0,
                'sexuality' => $profile && $profile->sexuality ? 1 : 0,
                'relationship_status' => $profile && $profile->relationship_status ? 1 : 0,
                'relationship_orientation' => $profile && $profile->relationship_orientation ? 1 : 0,
                'home_location' => $profile && $profile->home_location ? 1 : 0,
                'country' => $profile && $profile->country ? 1 : 0,
                'city' => $profile && $profile->city ? 1 : 0,
                'languages' => !empty($languages) ? 1 : 0,
                'bio' => $profile && $profile->bio ? 1 : 0,
                'weight' => $profile && $profile->weight ? 1 : 0,
                'height' => $profile && $profile->height ? 1 : 0,
                'body_type' => $profile && $profile->body_type ? 1 : 0,
                'eye_color' => $profile && $profile->eye_color ? 1 : 0,
                'hair_color' => $profile && $profile->hair_color ? 1 : 0,
                'profile_photo' => ($profile && $profile->profile_photo) || ($user->profile_image) ? 1 : 0,
            ];
            
            // For couple profiles, check couple_data fields
            if ($isCouple && !empty($coupleData)) {
                $profileFields['date_of_birth'] = (!empty($coupleData['date_of_birth_her']) || !empty($coupleData['date_of_birth_him'])) ? 1 : $profileFields['date_of_birth'];
                $profileFields['sexuality'] = (!empty($coupleData['sexuality_her']) || !empty($coupleData['sexuality_him'])) ? 1 : $profileFields['sexuality'];
            }
            
            $completedFields = array_sum($profileFields);
            $totalFields = count($profileFields);
            $profileCompletion = $totalFields > 0 ? round(($completedFields / $totalFields) * 100) : 0;
            
            // Show modal ONLY if profile completion is less than 80%
            // Modal will automatically stop showing once profile reaches 80% or more
            // Don't show on auth pages or edit profile page
            $excludedRoutes = ['account.profile.edit', 'login', 'register', 'password.request', 'password.reset'];
            $isExcludedRoute = false;
            foreach($excludedRoutes as $route) {
                if(request()->routeIs($route)) {
                    $isExcludedRoute = true;
                    break;
                }
            }
            
            // Modal shows when completion < 80%, hides automatically when >= 80%
            $showCompleteProfileModal = $profileCompletion < 80 && !$isExcludedRoute;
        @endphp
        
        @if($showCompleteProfileModal)
            <div id="complete-profile-modal" class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4 hidden">
                <div class="bg-white dark:bg-black rounded-2xl shadow-2xl max-w-md w-full transform transition-all">
                    <!-- Modal Header -->
                    <div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
                        <div class="flex items-center justify-between">
                            <h3 class="text-xl font-bold text-gray-900 dark:text-white">Complete Your Profile</h3>
                            <button id="close-complete-profile-modal" class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors">
                                <i class="ri-close-line text-2xl"></i>
                            </button>
                        </div>
                    </div>
                    
                    <!-- Modal Body -->
                    <div class="px-6 py-6">
                        <div class="text-center mb-6">
                            <div class="w-20 h-20 mx-auto mb-4 bg-gradient-to-br from-pink-100 to-pink-200 dark:from-pink-900/30 dark:to-pink-800/30 rounded-full flex items-center justify-center">
                                <i class="ri-user-settings-line text-4xl text-[#9810FA] dark:text-[#E60076] dark:text-[#9810FA] dark:text-[#E60076]"></i>
                            </div>
                            <h4 class="text-lg font-semibold text-gray-900 dark:text-white mb-2">
                                Your profile is {{ $profileCompletion }}% complete
                            </h4>
                            <p class="text-sm text-gray-600 dark:text-gray-400">
                                Complete your profile to get better matches and connect with more members. Add your photos, preferences, and personal details to stand out!
                            </p>
                            
                            <!-- Progress Bar -->
                            <div class="mt-4">
                                <div class="w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-full overflow-hidden">
                                    <div class="h-full bg-gradient-to-r from-[#9810FA] to-[#E60076] rounded-full transition-all duration-300" style="width: {{ $profileCompletion }}%"></div>
                                </div>
                                <p class="text-xs text-gray-500 dark:text-gray-400 mt-2">{{ $completedFields }} of {{ $totalFields }} fields completed</p>
                            </div>
                        </div>
                    </div>
                    
                    <!-- Modal Footer -->
                    <div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700 flex gap-3">
                        <button id="continue-browsing-btn" class="flex-1 px-4 py-2.5 bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-xl font-semibold hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors">
                            Continue Browsing
                        </button>
                        <a href="{{ route('account.profile.edit') }}" class="flex-1 px-4 py-2.5 bg-gradient-to-r from-[#9810FA] to-[#E60076] text-white rounded-xl font-semibold hover:shadow-lg transition-all text-center">
                            Complete Profile
                        </a>
                    </div>
                </div>
            </div>
            
            <script>
                document.addEventListener('DOMContentLoaded', function() {
                    const modal = document.getElementById('complete-profile-modal');
                    const closeBtn = document.getElementById('close-complete-profile-modal');
                    const continueBtn = document.getElementById('continue-browsing-btn');
                    
                    // Storage key for tracking when modal was last closed
                    const storageKey = 'complete-profile-modal-closed';
                    const hoursToWait = 24;
                    const millisecondsToWait = hoursToWait * 60 * 60 * 1000; // 24 hours in milliseconds
                    
                    // Check if modal should be shown based on 24-hour rule
                    function shouldShowModal() {
                        const lastClosed = localStorage.getItem(storageKey);
                        if (!lastClosed) {
                            // Never been closed, show it
                            return true;
                        }
                        
                        const lastClosedTime = parseInt(lastClosed, 10);
                        const currentTime = Date.now();
                        const timeDifference = currentTime - lastClosedTime;
                        
                        // Show modal if 24 hours have passed
                        return timeDifference >= millisecondsToWait;
                    }
                    
                    // Store the current timestamp when modal is closed
                    function markModalAsClosed() {
                        localStorage.setItem(storageKey, Date.now().toString());
                    }
                    
                    // Show modal on page load if conditions are met
                    if (modal) {
                        if (shouldShowModal()) {
                            // Delay showing modal slightly for better UX
                            setTimeout(function() {
                                modal.classList.remove('hidden');
                                document.body.style.overflow = 'hidden';
                            }, 1000);
                        } else {
                            // Don't show modal, but keep it in DOM (hidden)
                            modal.classList.add('hidden');
                        }
                    }
                    
                    function closeModal() {
                        if (modal) {
                            modal.classList.add('hidden');
                            document.body.style.overflow = '';
                            // Mark modal as closed with current timestamp
                            markModalAsClosed();
                        }
                    }
                    
                    if (closeBtn) {
                        closeBtn.addEventListener('click', closeModal);
                    }
                    
                    if (continueBtn) {
                        continueBtn.addEventListener('click', closeModal);
                    }
                    
                    // Close modal when clicking outside
                    if (modal) {
                        modal.addEventListener('click', function(e) {
                            if (e.target === modal) {
                                closeModal();
                            }
                        });
                    }
                    
                    // Close modal on Escape key
                    document.addEventListener('keydown', function(e) {
                        if (e.key === 'Escape' && modal && !modal.classList.contains('hidden')) {
                            closeModal();
                        }
                    });
                });
            </script>
        @endif
    @endauth

    {{-- Footer Scripts --}}
    @if($siteSettings->footer_scripts)
        {!! $siteSettings->footer_scripts !!}
    @endif

    {{-- Custom JavaScript --}}
    @if($siteSettings->custom_js)
        <script>
            {!! $siteSettings->custom_js !!}
        </script>
    @endif

    @stack('scripts')
    
    <!-- Global Settings Toggle Script -->
    <script>
    document.addEventListener('DOMContentLoaded', function() {
        const settingsToggleBtn = document.getElementById('settings-toggle-btn');
        
        if (settingsToggleBtn) {
            // Remove any existing listeners
            const newBtn = settingsToggleBtn.cloneNode(true);
            settingsToggleBtn.parentNode.replaceChild(newBtn, settingsToggleBtn);
            
            newBtn.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                
                // Check if we're on the profile page (index or edit)
                const isProfilePage = window.location.pathname.includes('/account/profile');
                const isEditPage = window.location.pathname.includes('/account/profile/edit');
                
                if (isProfilePage && !isEditPage) {
                    // If on profile index page, toggle sidebar
                    const sidebar = document.getElementById('settings-sidebar');
                    if (sidebar) {
                        const isOpen = sidebar.style.width !== '0px' && sidebar.style.width !== '0';
                        if (isOpen) {
                            // Close sidebar
                            sidebar.style.width = '0';
                            sidebar.style.minWidth = '0';
                            sidebar.style.overflow = 'hidden';
                        } else {
                            // Open sidebar
                            sidebar.style.width = '320px'; // w-80 = 320px
                            sidebar.style.minWidth = '320px';
                            sidebar.style.overflow = 'auto';
                        }
                    } else {
                        // Fallback: use global function if available
                        if (typeof window.toggleSettingsSidebar === 'function') {
                            window.toggleSettingsSidebar();
                        }
                    }
                    // Don't navigate, just toggle sidebar
                    return;
                } else {
                    // If on edit page or not on profile page, navigate to profile page and open sidebar
                    window.location.href = '{{ route("account.profile") }}?settings=true';
                }
            });
        }
    });

    // Show toast notifications for session messages
    // Wait for app.js to load first
    function showSessionToasts() {
        if (typeof showToast === 'undefined') {
            // Retry after a short delay if showToast is not yet available
            setTimeout(showSessionToasts, 100);
            return;
        }

        @if (session('success'))
            showToast('{{ addslashes(session('success')) }}', 'success', 5000);
        @endif

        @if (session('coins_earned'))
            showToast('You got {{ (int) session('coins_earned') }} SNC!', 'success', 5000);
        @endif

        @if (session('error'))
            showToast('{{ addslashes(session('error')) }}', 'error', 5000);
        @endif

        @if ($errors->any())
            @foreach ($errors->all() as $error)
                showToast('{{ addslashes($error) }}', 'error', 5000);
            @endforeach
        @endif
    }

    // Run when DOM is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', showSessionToasts);
    } else {
        // DOM is already ready
        showSessionToasts();
    }
    </script>
</body>
</html>