@vite(['resources/css/app.css', 'resources/js/app.js']) {{-- Anti-FOUC: apply dark class before first paint --}}
{{-- ===== SIDEBAR ===== --}} {{-- END SIDEBAR --}} {{-- Mobile backdrop: closes drawer when tapped --}}
{{-- ===== MAIN CONTENT ===== --}}
{{-- Top Header --}}
{{-- Sidebar toggle --}}

@yield('page_title', 'Dashboard')

{{-- Dark mode toggle --}} {{-- Help & tours launcher --}}
Help & guides
{{ auth()->user()->initials() }}
{{-- Page Content --}}
@if(auth()->check() && !auth()->user()->isAdmin() && !$activeShift)

No active shift. You can view records but cannot make any changes until your shift is started. Start shift →

@endif @yield('content')
{{-- Footer --}}
{{-- ===== GLOBAL CONFIRM DIALOG ===== --}} {{-- ===== ONBOARDING TOUR ===== --}} @php $tu = auth()->user(); $tourSteps = []; $whatsNewSteps = []; $tourAutorun = false; if ($tu) { // Auto-run the full tour only on first login this session, until permanently dismissed. // The steps themselves are built unconditionally so the Help menu can replay them anytime. $tourAutorun = !$tu->tutorial_completed_at && !session('pms_tour_shown'); if ($tourAutorun) { session(['pms_tour_shown' => true]); // don't re-pop on every page navigation this session } // ---- Full guided tour (role-scoped) ---- $tourSteps = [ ['target' => null, 'title' => 'Welcome to NXT-ePMS!', 'desc' => 'A quick guided tour of the system. Close it anytime — you can replay it (or tour the page you\'re on) from the Help "?" menu in the top bar. You only see the areas your role can access.'], ['target' => '#tour-dashboard', 'title' => 'Dashboard', 'desc' => 'Your daily command center — today\'s occupancy, arrivals, revenue, and a summary of all recent activity at a glance.'], ]; // Front Desk if ($tu->can('reservations.view')) $tourSteps[] = ['target' => '#tour-reservations', 'title' => 'Reservations', 'desc' => 'Manage all bookings: create and confirm reservations, collect payments, check guests in and out, and view folios. Handles group bookings and rate plans too.']; if ($tu->can('front_desk.view')) { $tourSteps[] = ['target' => '#tour-checkin', 'title' => 'Check-in Queue', 'desc' => 'Today\'s arrivals, with overdue ones highlighted. Confirm the guest\'s nationality for DOT statistics as you check them in.']; $tourSteps[] = ['target' => '#tour-checkout', 'title' => 'Check-out Queue', 'desc' => 'Guests due to depart, each with their outstanding balance. Settle the folio, then check them out — the room drops into the housekeeping queue.']; $tourSteps[] = ['target' => '#tour-roomrack', 'title' => 'Room Rack', 'desc' => 'A live visual grid of every room. Filter by status to see what\'s occupied, clean, dirty, or under maintenance.']; } if ($tu->can('guests.view')) $tourSteps[] = ['target' => '#tour-guests', 'title' => 'Guest Profiles', 'desc' => 'The guest directory — contact details, stay history, VIP and blacklist flags, and government-ID records.']; if ($tu->can('billing.view')) $tourSteps[] = ['target' => '#tour-billing', 'title' => 'Billing & Folios', 'desc' => 'Every folio in one list with live balances. Open one to add extra charges and print a VAT-itemized statement.']; if ($tu->can('calendar.view')) $tourSteps[] = ['target' => '#tour-calendar', 'title' => 'My Calendar', 'desc' => 'A Gantt-style timeline of rooms across dates. Drag a checked-in booking onto another room to transfer it.']; // Operations if ($tu->can('housekeeping.view')) $tourSteps[] = ['target' => '#tour-housekeeping', 'title' => 'Housekeeping', 'desc' => 'Room cleanliness by floor, with arriving-today rooms flagged as priority. Mark rooms clean when ready.']; if ($tu->can('maintenance.view')) $tourSteps[] = ['target' => '#tour-maintenance', 'title' => 'Maintenance', 'desc' => 'Log work orders for rooms or common areas, set priority and category, and resolve them when the job is done.']; if ($tu->can('pos.view')) $tourSteps[] = ['target' => '#tour-pos', 'title' => 'Point of Sale', 'desc' => 'Ring up food, drinks, and services — settle directly or charge to a guest\'s room. Every direct sale gets a BIR OR number.']; if ($tu->can('shifts.view')) $tourSteps[] = ['target' => '#tour-shifts', 'title' => 'Shift Log', 'desc' => 'Clock in to start your shift and out to end it, counting cash so over/short is tracked. Writes are locked without an open shift.']; // Revenue if ($tu->can('rate_plans.view')) $tourSteps[] = ['target' => '#tour-rates', 'title' => 'Rate Plans', 'desc' => 'Percent-off, amount-off, and fixed-rate plans (with promo codes) that feed both the booking form and the public site.']; if ($tu->can('channel_manager.view')) $tourSteps[] = ['target' => '#tour-channels', 'title' => 'Channel Manager', 'desc' => 'Map each booking source (Booking.com, Agoda, walk-in…) to a rate plan and review per-channel performance.']; if ($tu->canViewAnyReport()) $tourSteps[] = ['target' => '#tour-reports', 'title' => 'Reports', 'desc' => '14 reports across performance, financial control, cash & audit, operations, and PH compliance (DOT, Senior/PWD, BIR VAT) — each printable and exportable to CSV or Excel.']; // Website & Marketing if ($tu->canWebsiteAny()) $tourSteps[] = ['target' => '#tour-website', 'title' => 'Website & Marketing', 'desc' => 'Runs the public hotel site + booking engine: the multi-language content CMS, news, promotions, testimonials, FAQ, attractions, the media library, and the contact & newsletter inboxes.']; // Settings if ($tu->can('rooms.view')) $tourSteps[] = ['target' => '#tour-rooms', 'title' => 'Room Management', 'desc' => 'The room inventory — add and edit rooms, types, rates, and amenities across all floors.']; if ($tu->can('staff.view')) $tourSteps[] = ['target' => '#tour-staff', 'title' => 'Staff & Roles', 'desc' => 'Manage staff accounts and the role/permission matrix that controls exactly what each person can see and do.']; if ($tu->can('settings.view')) { $tourSteps[] = ['target' => '#tour-settings', 'title' => 'Property Settings', 'desc' => 'Property details, check-in/out times, VAT rate, and BIR receipt info (registered name, TIN, OR prefix).']; $tourSteps[] = ['target' => '#tour-activity', 'title' => 'Activity Log', 'desc' => 'A full audit trail of who did what and when — the source behind the Voids & Overrides report.']; } if ($tu->isAdmin()) $tourSteps[] = ['target' => '#tour-backups', 'title' => 'Database Backups', 'desc' => 'Back up the full database on demand (automated backups also run nightly) — and now restore from any saved backup, with a safety snapshot taken first.']; $tourSteps[] = ['target' => '#tour-profile', 'title' => 'Your Profile', 'desc' => 'Update your name, email, phone, and password here. Start Shift and Sign Out are also in this menu.']; // ---- "What's new" — a short spotlight of recent additions, role-scoped ---- $whatsNewSteps = [ ['target' => null, 'title' => "What's new in NXT-ePMS", 'desc' => 'A quick look at the latest additions available to your role. Replay this anytime from the Help "?" menu.'], ]; if ($tu->can('calendar.view')) $whatsNewSteps[] = ['target' => '#tour-calendar', 'title' => 'Drag-to-transfer calendar', 'desc' => 'On My Calendar you can now drag a checked-in guest\'s bar straight onto another room to transfer them.']; if ($tu->canViewAnyReport()) $whatsNewSteps[] = ['target' => '#tour-reports', 'title' => 'CSV & Excel exports', 'desc' => 'Every report now exports to CSV and real Excel (.xlsx) in one click, on top of the printable letterhead view.']; if ($tu->can('shifts.view')) $whatsNewSteps[] = ['target' => '#tour-shifts', 'title' => 'Cash shift tracking', 'desc' => 'Open and close shifts with a cash count so over/short is tracked per cashier and surfaced in the Cash Variance report.']; if ($tu->canWebsiteAny()) $whatsNewSteps[] = ['target' => '#tour-website', 'title' => 'Multilingual site & media', 'desc' => 'The public site is now English + Filipino + Bisaya, with a reusable media library, a news/blog module, promotions, and testimonials.']; if ($tu->isAdmin()) $whatsNewSteps[] = ['target' => '#tour-backups', 'title' => 'Database restore', 'desc' => 'You can now restore the database from a saved backup — a safety snapshot is taken automatically first, so it\'s reversible.']; } @endphp @if($tu) {{-- Per-page contextual tour steps are pushed here by individual views (window.__pmsPageTour). --}} @stack('pageTour') @endif