| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- # app/shared/EventDetailModal/index.coffee
- document.head.insertAdjacentHTML('beforeend','<style type="text/tailwindcss" component="EventDetailModal">'+stylFns['app/shared/EventDetailModal/index.styl']+'</style>')
- 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
- debug.log "Бронирование билетов на: "+@event.title
- @$emit 'ticket-booking', @event
-
- # Имитация процесса покупки
- openModal('SuccessModal', {
- title: 'Билет забронирован'
- content: "Вы успешно забронировали билет на \""+@event.title+"\""
- })
- else
- openModal('SuccessModal', {
- 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']
|