# app/shared/EventDetailModal/index.coffee document.head.insertAdjacentHTML('beforeend','') module.exports = name: 'EventDetailModal' render: (new Function '_ctx', '_cache', renderFns['app/shared/EventDetailModal/index.pug'])() props: isVisible: type: Boolean default: false event: type: Object required: true validator: (value) -> value && typeof value == 'object' data: -> categoryLabels: classical: 'Классическая музыка' folk: 'Фольклор' jazz: 'Джаз' pop: 'Поп-музыка' dance: 'Танцевальное шоу' experimental: 'Экспериментальная музыка' theater: 'Театр' opera: 'Опера' mounted: -> @setupKeyboardListeners() beforeUnmount: -> @removeKeyboardListeners() watch: isVisible: (newVal) -> if newVal @$nextTick => @focusFirstInteractiveElement() methods: getCategoryLabel: (category) -> @categoryLabels[category] || category getCategoryBadgeClass: (category) -> classes = classical: 'bg-blue-500 text-white' folk: 'bg-green-500 text-white' jazz: 'bg-purple-500 text-white' pop: 'bg-pink-500 text-white' dance: 'bg-orange-500 text-white' experimental: 'bg-indigo-500 text-white' theater: 'bg-red-500 text-white' opera: 'bg-teal-500 text-white' classes[category] || 'bg-gray-500 text-white' formatDateTime: (dateString, timeString) -> try date = new Date(dateString) options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' } formattedDate = date.toLocaleDateString('ru-RU', options) "#{formattedDate}, #{timeString}" catch error console.error 'Error formatting date:', error "#{dateString}, #{timeString}" bookTickets: -> if @event?.availableTickets > 0 console.log 'Бронирование билетов на:', @event.title @$emit 'ticket-booking', @event # Имитация процесса покупки @$root.$emit('open-modal', { component: 'TicketPurchaseModal' props: { event: @event } }) else @$root.$emit('open-modal', { component: 'ErrorModal' props: { title: 'Билеты распроданы' content: 'К сожалению, все билеты на это мероприятие уже распроданы.' } }) addToCalendar: -> console.log 'Добавление в календарь:', @event.title @$emit 'add-to-calendar', @event # Создание ссылки для добавления в календарь try startDate = new Date("#{@event.date}T#{@event.time}") endDate = new Date(startDate.getTime() + 2 * 60 * 60 * 1000) # +2 часа googleCalendarUrl = @generateGoogleCalendarUrl(startDate, endDate) window.open(googleCalendarUrl, '_blank') catch error console.error 'Error generating calendar event:', error # Fallback: показать инструкции @showCalendarInstructions() generateGoogleCalendarUrl: (startDate, endDate) -> title = encodeURIComponent(@event.title) details = encodeURIComponent(@event.description) location = encodeURIComponent('Концертный зал "Кохи Борбад", Душанбе') startStr = startDate.toISOString().replace(/[-:]/g, '').split('.')[0] + 'Z' endStr = endDate.toISOString().replace(/[-:]/g, '').split('.')[0] + 'Z' "https://calendar.google.com/calendar/render?action=TEMPLATE&text=#{title}&details=#{details}&location=#{location}&dates=#{startStr}/#{endStr}" showCalendarInstructions: -> @$root.$emit('open-modal', { component: 'InfoModal' props: { title: 'Добавление в календарь' content: 'Скопируйте информацию о мероприятии и добавьте её в ваш календарь вручную.' } }) shareOnFacebook: -> try url = encodeURIComponent(window.location.href) text = encodeURIComponent("Посетите \"#{@event.title}\" в Кохи Борбад") shareUrl = "https://www.facebook.com/sharer/sharer.php?u=#{url}"e=#{text}" window.open(shareUrl, '_blank', 'width=600,height=400') catch error console.error 'Error sharing on Facebook:', error shareOnTwitter: -> try text = encodeURIComponent("\"#{@event.title}\" - #{@formatDateTime(@event.date, @event.time)} в Кохи Борбад") shareUrl = "https://twitter.com/intent/tweet?text=#{text}" window.open(shareUrl, '_blank', 'width=600,height=400') catch error console.error 'Error sharing on Twitter:', error setupKeyboardListeners: -> document.addEventListener 'keydown', @handleKeydown removeKeyboardListeners: -> document.removeEventListener 'keydown', @handleKeydown handleKeydown: (event) -> if event.key == 'Escape' and @isVisible @$emit 'update:isVisible', false else if event.key == 'Tab' and @isVisible @trapFocus(event) trapFocus: (event) -> modal = @$el.querySelector('.modal-content') return unless modal focusableElements = modal.querySelectorAll( 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' ) firstElement = focusableElements[0] lastElement = focusableElements[focusableElements.length - 1] if event.shiftKey if document.activeElement == firstElement event.preventDefault() lastElement.focus() else if document.activeElement == lastElement event.preventDefault() firstElement.focus() focusFirstInteractiveElement: -> @$nextTick -> modal = @$el.querySelector('.modal-content') return unless modal firstInteractive = modal.querySelector( 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' ) firstInteractive?.focus() getTicketAvailabilityClass: -> if @event?.availableTickets > 20 return 'text-green-600 dark:text-green-400' else if @event?.availableTickets > 5 return 'text-orange-600 dark:text-orange-400' else if @event?.availableTickets > 0 return 'text-red-600 dark:text-red-400' else return 'text-gray-500 dark:text-gray-400' emits: ['update:isVisible', 'ticket-booking', 'add-to-calendar']