Gogs 3 săptămâni în urmă
părinte
comite
eb814e15e5
2 a modificat fișierele cu 225 adăugiri și 31 ștergeri
  1. 1 1
      README.md
  2. 224 30
      vue/app/temp.coffee

+ 1 - 1
README.md

@@ -1,6 +1,6 @@
 # Текущая ззадача
 
-перепеши app/temp.coffee с учетом новых правил, определения глобальных переменных.
+напиши все файлы app/shared/SuccessModal
 
 
 # применяй правила:

+ 224 - 30
vue/app/temp.coffee

@@ -1,52 +1,246 @@
+# обязательно подключение глобальных массивов
 globalThis.renderFns = require 'pug.json'
 globalThis.stylFns   = require 'styl.json'
 
-debug.log "000"
+# подключение мета информации (строго в данном фиде)
 document.head.insertAdjacentHTML 'beforeend','<meta charset="UTF-8">'
 document.head.insertAdjacentHTML 'beforeend','<meta name="viewport" content="width=device-width, initial-scale=1.0">'
+document.head.insertAdjacentHTML('beforeend','<title>Кохи Борбад - Концертный зал Душанбе</title>')
 
-document.head.insertAdjacentHTML('beforeend','<style>'+stylFns['main.css']+'</style>')
+# Настройка tailwind
+tailwind.config = require 'tailwind.config.js'
+
+# подключение основных стилей
+## tailwind
+document.head.insertAdjacentHTML('beforeend','<style  type="text/tailwindcss"  page="main">'+stylFns['main.css']+'</style>')
+## базовой стиль приложения
 document.head.insertAdjacentHTML('beforeend','<style  type="text/tailwindcss"  page="root">'+stylFns['app/temp.styl']+'</style>')
 
-document.head.insertAdjacentHTML('beforeend','<title> Кохи Борбад - Концертный зал Душанбе</title>')
+# CouchDB сервис
+class CouchDBService
+    constructor: ->
+        @baseUrl = 'https://couchdb.favt.ru.net'
+        @dbName = 'kohi_borbad_events'
+        @headers = 
+            'Content-Type': 'application/json'
+            'Authorization': 'Basic ' + btoa('oleg:631074')
+
+    getAllEvents: ->
+        try
+            response = await fetch("#{@baseUrl}/#{@dbName}/_all_docs?include_docs=true", {
+                method: 'GET'
+                headers: @headers
+            })
+            
+            if response.ok
+                data = await response.json()
+                events = data.rows.map (row) -> row.doc
+                return events.filter (event) -> !event._id.startsWith('_design/')
+            else
+                debug.log "Ошибка получения мероприятий: "+response.statusText
+                return []
+        catch error
+            debug.log "Ошибка подключения к CouchDB: "+error
+            return []
+
+    getFeaturedEvents: ->
+        events = await @getAllEvents()
+        events
+            .filter (event) -> event.isFeatured || false
+            .slice(0, 6)
+
+    getSliderEvents: ->
+        events = await @getAllEvents()
+        events
+            .filter (event) -> event.inSlider || false
+            .map (event) ->
+                id: event._id
+                image: event.image || '/images/default-event.jpg'
+                title: event.title
+                description: event.shortDescription || event.description
+                cta: event.cta || 'Подробнее'
+                category: event.category
 
-debug.log "001"
 # Маршруты
 routes = [
-  { path: '/', component: require 'app/pages/Home' }
-  { path: '/events', component: require 'app/pages/Events' }
-  { path: '/about', component: require 'app/pages/About' }
-  #{ path: '/contacts', component: require 'app/pages/Contacts' }
+    { path: '/', component: require 'app/pages/Home' }
+    { path: '/events', component: require 'app/pages/Events' }
+    { path: '/about', component: require 'app/pages/About' }
+    { path: '/contacts', component: require 'app/pages/Contacts' }
 ]
-tailwind.config = require 'tailwind.config.js'
 
-debug.log "002"
-# Глобальное состояние темы
+# Глобальное определение vuejs приложения
 app = Vue.createApp
-  name: 'app'
-  data: ()->
-        return  {}
-  beforeMount: ()->
+    name: 'app'
+    data: ()->
+        return  
+            theme: 'light'
+            appState:
+                events: []
+                featuredEvents: []
+                sliderEvents: []
+                loading: true
+                error: null
+            modalState: 
+                currentModal: null
+                modalProps: {}
+            couchDBService: new CouchDBService()
+    beforeMount: ()->
         debug.log "start beforeMount"
+        # определение контекста vuejs приложения как глобальной переменной _
         globalThis._ = @
-  render: (new Function '_ctx', '_cache', renderFns['app/temp.pug'])()
-  mounted: ->{}
-  methods: {}
-  components:
-      'themetoggle':    require 'app/shared/ThemeToggle'
-      'multilevelmenu': require 'app/shared/MultiLevelMenu'
-      'imageslider':    require 'app/shared/ImageSlider'
+    render: (new Function '_ctx', '_cache', renderFns['app/temp.pug'])()
+    mounted: ->
+        # Предзагрузка темы
+        if localStorage.theme == 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
+            @theme = 'dark'
+            document.documentElement.classList.add('dark')
+        else
+            @theme = 'light'
+            document.documentElement.classList.remove('dark')
+        
+        # Загрузка данных из CouchDB
+        await @loadEventsData()
+        
+        # Обработчик открытия модальных окон
+        EventBus.$on 'open-modal', (config) =>
+            @modalState.currentModal = config.component
+            @modalState.modalProps = config.props || {}
+    methods:
+        toggleTheme: ->
+            @theme = if @theme == 'light' then 'dark' else 'light'
+            localStorage.setItem 'theme', @theme
+            document.documentElement.classList.toggle 'dark'
+            @$emit 'theme-changed', @theme
+        
+        loadEventsData: ->
+            @appState.loading = true
+            try
+                [events, featuredEvents, sliderEvents] = await Promise.all([
+                    @couchDBService.getAllEvents()
+                    @couchDBService.getFeaturedEvents()
+                    @couchDBService.getSliderEvents()
+                ])
+                
+                @appState.events = events
+                @appState.featuredEvents = featuredEvents
+                @appState.sliderEvents = sliderEvents
+                @appState.error = null
+                
+            catch error
+                debug.log "Ошибка загрузки данных: "+error
+                @appState.error = 'Не удалось загрузить данные мероприятий'
+                @loadTestData()
+            finally
+                @appState.loading = false
+        
+        loadTestData: ->
+            # Тестовые данные на случай недоступности CouchDB
+            @appState.events = [
+                {
+                    _id: '1'
+                    title: 'Концерт симфонического оркестра'
+                    date: '2025-10-15'
+                    time: '19:00'
+                    description: 'Произведения Чайковского и Рахманинова в исполнении Национального симфонического оркестра'
+                    image: '/images/event-classical.jpg'
+                    category: 'classical'
+                    price: 50
+                    venue: 'Большой зал'
+                    duration: '2 часа 30 минут'
+                    ageRestriction: '12+'
+                    availableTickets: 45
+                    isFeatured: true
+                    inSlider: true
+                    shortDescription: 'Шедевры классической музыки'
+                    cta: 'Купить билеты'
+                }
+                {
+                    _id: '2'
+                    title: 'Вечер таджикской народной музыки'
+                    date: '2025-10-20'
+                    time: '18:30'
+                    description: 'Выступление фольклорного ансамбля "Шашмаком" с программой традиционных мелодий и танцев'
+                    image: '/images/event-folk.jpg'
+                    category: 'folk'
+                    price: 30
+                    venue: 'Малый зал'
+                    duration: '2 часа'
+                    ageRestriction: '6+'
+                    availableTickets: 28
+                    isFeatured: true
+                    inSlider: true
+                    shortDescription: 'Традиционные мелодии и танцы Таджикистана'
+                    cta: 'Узнать больше'
+                }
+                {
+                    _id: '3'
+                    title: 'Джазовый фестиваль "Borbad Jazz"'
+                    date: '2025-10-25'
+                    time: '20:00'
+                    description: 'Международные джазовые коллективы из Европы и Азии в уникальной акустике зала'
+                    image: '/images/event-jazz.jpg'
+                    category: 'jazz'
+                    price: 70
+                    venue: 'Большой зал'
+                    duration: '3 часа'
+                    ageRestriction: '16+'
+                    availableTickets: 15
+                    isFeatured: true
+                    inSlider: true
+                    shortDescription: 'Международные джазовые коллективы'
+                    cta: 'Смотреть расписание'
+                }
+            ]
+            @appState.featuredEvents = @appState.events.filter((event) -> event.isFeatured).slice(0, 6)
+            @appState.sliderEvents = @appState.events.filter((event) -> event.inSlider).map (event) ->
+                id: event._id
+                image: event.image
+                title: event.title
+                description: event.shortDescription
+                cta: event.cta
+                category: event.category
+        
+        getEvents: -> @appState.events
+        getFeaturedEvents: -> @appState.featuredEvents
+        getSliderEvents: -> @appState.sliderEvents
+        isLoading: -> @appState.loading
+        hasError: -> @appState.error
+        
+        closeModal: ->
+            @modalState.currentModal = null
+            @modalState.modalProps = {}
+    components:
+        'themetoggle':    require 'app/shared/ThemeToggle'
+        'multilevelmenu': require 'app/shared/MultiLevelMenu'
+        'imageslider':    require 'app/shared/ImageSlider'
+        'modalwindow':    require 'app/shared/ModalWindow'
+        'formvalidator':  require 'app/shared/FormValidator'
+        'filtersort':     require 'app/shared/FilterSort'
+        'eventdetailmodal': require 'app/shared/EventDetailModal'
+        'successmodal':   require 'app/shared/SuccessModal'
+
+# Создаем глобальную шину событий
+globalThis.EventBus = new Vue()
+
 app.use(VueRouter.createRouter({
-  routes: routes
-  history: VueRouter.createWebHistory()
-  scrollBehavior: (to, from, savedPosition) ->
-    if savedPosition
-      return savedPosition
-    else
-      return { x: 0, y: 0 }
+    routes: routes
+    history: VueRouter.createWebHistory()
+    scrollBehavior: (to, from, savedPosition) ->
+        if savedPosition
+            return savedPosition
+        else
+            return { x: 0, y: 0 }
 }))
 
+# Глобальные функции для работы с модальными окнами
+globalThis.openModal = (component, props = {}) ->
+    EventBus.$emit 'open-modal', { component, props }
 
-app.mount('body')
+globalThis.closeModal = ->
+    EventBus.$emit 'close-modal'
 
+# подключаем в body ОБЯЗАТЕЛЬНО!!!
+app.mount('body')
 
+debug.log "Vue application initialized successfully"