// API Client class ApiClient { constructor() { this.baseUrl = '/api'; this.token = localStorage.getItem('token'); } async request(endpoint, options = {}) { const url = `${this.baseUrl}${endpoint}`; const config = { headers: { 'Content-Type': 'application/json', ...options.headers, }, ...options, }; if (this.token) { config.headers.Authorization = `Bearer ${this.token}`; } const response = await fetch(url, config); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); } // Auth async login(credentials) { const response = await fetch('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(credentials), }); const data = await response.json(); if (data.token) { this.token = data.token; localStorage.setItem('token', data.token); } return data; } // Guests async searchGuests(query) { return this.request(`/guests/search?q=${encodeURIComponent(query)}`); } async getGuest(id) { return this.request(`/guests/${id}`); } async createGuest(guestData) { return this.request('/guests', { method: 'POST', body: JSON.stringify(guestData), }); } async checkinGuest(id, checkinData) { return this.request(`/guests/${id}/checkin`, { method: 'POST', body: JSON.stringify(checkinData), }); } async getCrossSellSuggestions(id) { return this.request(`/guests/${id}/cross-sell-suggestions`); } async addGuestTags(id, tags) { return this.request(`/guests/${id}/tags`, { method: 'POST', body: JSON.stringify({ tags }), }); } async addGuestNote(id, note) { return this.request(`/guests/${id}/notes`, { method: 'POST', body: JSON.stringify({ note_text: note }), }); } // Loyalty async getTiers() { return this.request('/loyalty/tiers'); } async awardPoints(id, points) { return this.request(`/guests/${id}/award-points`, { method: 'POST', body: JSON.stringify({ points }), }); } async getLoyaltyStatus(id) { return this.request(`/guests/${id}/loyalty-status`); } // Vouchers async getVouchers() { return this.request('/vouchers'); } async issueVoucher(guestId, voucherId) { return this.request(`/guests/${guestId}/issue-voucher/${voucherId}`, { method: 'POST', }); } // Admin async getKpis() { return this.request('/dashboard/kpis'); } async getCharts() { return this.request('/dashboard/charts'); } async createCampaign(campaignData) { return this.request('/campaigns', { method: 'POST', body: JSON.stringify(campaignData), }); } async getVenues() { return this.request('/venues'); } async selectVenue(venueId) { return this.request(`/venues/${venueId}/select`, { method: 'POST', }); } } const api = new ApiClient(); // UI Helpers function showToast(message, type = 'success') { const toastHtml = ` `; const container = document.createElement('div'); container.innerHTML = toastHtml; document.body.appendChild(container); const toastElement = container.firstElementChild; const toast = new bootstrap.Toast(toastElement); toast.show(); toastElement.addEventListener('hidden.bs.toast', () => { document.body.removeChild(container); }); } // Initialize on page load document.addEventListener('DOMContentLoaded', function() { // Theme toggle const themeToggle = document.getElementById('theme-toggle'); if (themeToggle) { themeToggle.addEventListener('click', function() { document.body.classList.toggle('dark-theme'); localStorage.setItem('theme', document.body.classList.contains('dark-theme') ? 'dark' : 'light'); }); // Load saved theme if (localStorage.getItem('theme') === 'dark') { document.body.classList.add('dark-theme'); } } // Venue selector const venueSelect = document.getElementById('venue-select'); if (venueSelect) { venueSelect.addEventListener('change', async function() { try { await api.selectVenue(this.value); showToast('Venue changed successfully'); } catch (error) { showToast('Failed to change venue', 'danger'); } }); } // Global search const globalSearch = document.getElementById('global-search'); const globalSearchBtn = document.getElementById('global-search-btn'); if (globalSearch && globalSearchBtn) { globalSearchBtn.addEventListener('click', function() { const query = globalSearch.value.trim(); if (query) { window.location.href = `/guests/search?q=${encodeURIComponent(query)}`; } }); globalSearch.addEventListener('keypress', function(e) { if (e.key === 'Enter') { globalSearchBtn.click(); } }); } });