import {Controller} from "@hotwired/stimulus" // Connects to data-controller="main-calendar" export default class extends Controller { static targets = ["dateDisplay", "navigation", "teamFilter"] connect() { // Set height to full viewport document.getElementById('main-calendar').style.height = '100vh'; document.getElementById('main-calendar').style.width = '100vw'; // Get current locale from html lang attribute const currentLocale = document.documentElement.lang || 'bs'; // Get translations from data attribute const translations = JSON.parse(document.getElementById('main-calendar').dataset.translations || '{}'); // Translation helper const t = (key) => translations[key] || key; // Pre-process reservations to set up team calendars const reservations = JSON.parse(document.querySelector("#main-calendar").dataset.reservations); window.reservations = reservations; // Debug: Log the first reservation to inspect color format if (reservations && reservations.length > 0) { console.log("First reservation team color:", reservations[0].team.color); } // Extract unique teams and create calendar configurations const teamCalendars = []; const teamMap = {}; // Create calendar configs for each team reservations.forEach(reservation => { const teamId = reservation.team.id; if (!teamMap[teamId]) { const calendarId = `team-${teamId}`; teamMap[teamId] = calendarId; // Use color directly - it should be a hex string from the TeamSerializer const teamColor = reservation.team.color || '#00a9ff'; teamCalendars.push({ id: calendarId, name: reservation.team.name, backgroundColor: teamColor, borderColor: teamColor }); } }); // Store team calendars for filtering this.teamCalendars = teamCalendars; this.allCalendars = [...teamCalendars]; // Store all reservations for filtering this.allReservations = reservations; // Initialize calendar with all team calendars window.calendar = new tui.Calendar(document.getElementById('main-calendar'), { defaultView: 'week', usageStatistics: false, week: { taskView: false, scheduleView: false, eventView: ['time'], startDayOfWeek: 1, // Start week on Monday hourStart: 4, hourEnd: 21, }, timezone: { zones: [ { timezoneName: 'UTC', displayLabel: 'UTC' // Optional: Label for the timezone } ] }, // This is important - set the height to 100% height: '100%', // Make sure it takes full width width: '100%', template: { timegridDisplayPrimaryTime({time}) { return `${time.getHours()} ${t('hours')}`; }, popupDetailLocation(eventObj) { return ''; // Empty location as requested }, popupDetailAttendees(eventObj) { return eventObj.attendees[0]; // Show team name }, popupDetailState(eventObj) { return ''; }, popupDetailBody(eventObj) { return ''; }, popupEdit() { return t('edit'); }, popupDelete() { return t('delete'); } }, calendars: teamCalendars.length > 0 ? teamCalendars : [ { id: 'default', name: 'Default', backgroundColor: '#00a9ff', } ] }); // Create calendar events this.createCalendarEvents(reservations); // Set up initial date display this.updateDateDisplay(); // Handle calendar navigation window.calendar.on('beforeUpdateDay', (date) => { this.updateDateDisplay(); }); // Handle edit and delete actions window.calendar.on('clickEvent', (event) => { const reservation = event.event.reservation; // Redirect to edit page window.location.href = `/reservations/${reservation.id}/edit`; }); // Render the calendar window.calendar.render(); } // Create events for all reservations createCalendarEvents(reservations) { if (!window.calendar) return; // Process each reservation into a calendar event reservations.forEach(reservation => { const teamId = reservation.team.id; const calendarId = `team-${teamId}`; const startTime = new Date(reservation.start_time); const endTime = new Date(reservation.end_time); // Create the event const event = { id: `reservation-${reservation.id}`, calendarId: calendarId, title: reservation.customer ? `${reservation.customer.first_name} ${reservation.customer.surname}` : '', start: startTime, end: endTime, category: 'time', isReadOnly: false, reservation: reservation, attendees: [reservation.team.name] }; // Add event to calendar window.calendar.createEvents([event]); }); } getCalendardata() { // This method is now replaced by initialization in connect() // and createCalendarEvents method } // Helper function to get CSRF token from meta tag getCsrfToken() { const token = document.querySelector('meta[name="csrf-token"]')?.content; return token; } // Navigation methods - using the global window.calendar prev() { window.calendar.prev(); this.updateDateDisplay(); } next() { window.calendar.next(); this.updateDateDisplay(); } today() { window.calendar.today(); this.updateDateDisplay(); } // Helper for updating the date display updateDateDisplay() { if (this.hasDateDisplayTarget) { const calendar = window.calendar; const currentDate = calendar.getDate(); // Format the date range based on the current view const view = calendar.getViewName(); if (view === 'day') { this.dateDisplayTarget.textContent = this.formatDate(currentDate); } else if (view === 'week') { // For week view, show range (e.g., "Aug 1 - 7, 2023") const weekStart = new Date(currentDate); weekStart.setDate(weekStart.getDate() - weekStart.getDay() + (weekStart.getDay() === 0 ? -6 : 1)); const weekEnd = new Date(weekStart); weekEnd.setDate(weekStart.getDate() + 6); this.dateDisplayTarget.textContent = `${this.formatDateShort(weekStart)} - ${this.formatDateShort(weekEnd)}`; } else if (view === 'month') { // For month view, show month and year (e.g., "August 2023") this.dateDisplayTarget.textContent = currentDate.toLocaleString('default', { month: 'long', year: 'numeric' }); } } } // Helper for formatting dates formatDate(date) { return date.toLocaleDateString('default', { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric' }); } formatDateShort(date) { return date.toLocaleDateString('default', { month: 'short', day: 'numeric' }); } // Method for team filtering filterByTeam(event) { const selectedTeamId = event.target.value; // Store last value for test verification window.lastTeamFilterValue = selectedTeamId; console.log(`Filtering by team: ${selectedTeamId}`); if (!window.calendar) return; // Clear existing events window.calendar.clear(); // Process reservations based on filter let filteredReservations = this.allReservations; // If not "all", filter by team if (selectedTeamId !== 'all') { // Extract numeric ID if the value is in "team-{id}" format const teamId = selectedTeamId.toString().startsWith('team-') ? selectedTeamId.toString().replace('team-', '') : selectedTeamId.toString(); console.log(`Using team ID for filtering: ${teamId}`); filteredReservations = this.allReservations.filter(reservation => reservation.team.id.toString() === teamId ); console.log(`Found ${filteredReservations.length} reservations for team ${teamId}`); } // Create and add calendar events based on filtered reservations this.createCalendarEvents(filteredReservations); // Update calendar display window.calendar.render(); } }