index.pug 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. div(class="page-container")
  2. //- Состояние загрузки
  3. div(v-if="loading" class="container mx-auto px-4 py-16 text-center")
  4. div(class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto")
  5. p(class="mt-4 text-gray-600") {{ getLocalizedString('loading') }}
  6. //- Состояние ошибки
  7. div(v-else-if="error" class="container mx-auto px-4 py-16")
  8. div(class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded max-w-2xl mx-auto")
  9. p {{ error }}
  10. app-link(
  11. to="/"
  12. class="mt-4 inline-block bg-red-600 text-white px-4 py-2 rounded hover:bg-red-700 transition-colors"
  13. ) {{ getLocalizedString('back_to_home') }}
  14. //- Страница не найдена
  15. div(v-else-if="notFound" class="container mx-auto px-4 py-16 text-center")
  16. div(class="max-w-2xl mx-auto")
  17. h1(class="text-6xl font-bold text-gray-300 mb-4") 404
  18. h2(class="text-2xl font-semibold text-gray-800 mb-4") {{ getLocalizedString('not_found') }}
  19. p(class="text-gray-600 mb-8") {{ getLocalizedString('page_not_found_description', 'Запрашиваемая страница не существует или была перемещена') }}
  20. app-link(
  21. to="/"
  22. class="bg-blue-600 text-white px-6 py-3 rounded-lg hover:bg-blue-700 transition-colors inline-block"
  23. ) {{ getLocalizedString('back_to_home') }}
  24. //- Отображение страницы
  25. div(v-else-if="page" class="page-content")
  26. //- Кастомный компонент если указан
  27. component(
  28. v-if="renderCustomComponent()"
  29. :is="renderCustomComponent()"
  30. :page="page"
  31. :settings="pageSettings"
  32. )
  33. //- Стандартное отображение
  34. div(v-else)
  35. //- Hero секция если есть изображение
  36. section(v-if="page.image" class="page-hero relative bg-gray-900")
  37. img(
  38. :src="getMultilingualText(page.image)"
  39. :alt="getMultilingualText(page.title)"
  40. class="w-full h-64 md:h-96 object-cover opacity-70"
  41. )
  42. div(class="absolute inset-0 flex items-center justify-center")
  43. div(class="text-center text-white")
  44. h1(class="text-4xl md:text-6xl font-bold mb-4") {{ getMultilingualText(page.title) }}
  45. p(v-if="getMultilingualText(page.excerpt)" class="text-xl opacity-90 max-w-2xl mx-auto") {{ getMultilingualText(page.excerpt) }}
  46. //- Контент страницы
  47. div(:class="{ 'container mx-auto px-4 py-16': !page.image }")
  48. //- Заголовок если нет hero изображения
  49. div(v-if="!page.image" class="text-center mb-12")
  50. h1(class="text-4xl font-bold text-gray-800 mb-4") {{ getMultilingualText(page.title) }}
  51. p(v-if="getMultilingualText(page.excerpt)" class="text-xl text-gray-600 max-w-2xl mx-auto") {{ getMultilingualText(page.excerpt) }}
  52. //- Основной контент
  53. article(
  54. class="prose prose-lg max-w-none prose-headings:text-gray-800 prose-p:text-gray-600 prose-a:text-blue-600 prose-a:no-underline hover:prose-a:underline prose-ul:text-gray-600 prose-ol:text-gray-600 prose-strong:text-gray-800 prose-blockquote:border-blue-600 prose-blockquote:text-gray-600"
  55. v-html="processedContent"
  56. @click="handleContentClick"
  57. )
  58. //- Галерея если есть
  59. div(v-if="page.gallery && page.gallery[0] && page.gallery[0].length > 0" class="mt-12")
  60. h2(class="text-2xl font-semibold text-gray-800 mb-6") {{ getLocalizedString('gallery', 'Галерея') }}
  61. div(class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4")
  62. img(
  63. v-for="(image, index) in getMultilingualText(page.gallery, [])"
  64. :key="index"
  65. :src="image"
  66. :alt="getMultilingualText(page.title) + ' - изображение ' + (index + 1)"
  67. class="w-full h-48 object-cover rounded-lg shadow-md hover:shadow-lg transition-shadow cursor-pointer"
  68. @click="openImageGallery(index)"
  69. )
  70. //- Модальное окно для галереи
  71. div(v-if="showGalleryModal" class="fixed inset-0 bg-black bg-opacity-90 flex items-center justify-center z-50 p-4")
  72. div(class="relative max-w-4xl max-h-full")
  73. button(
  74. @click="showGalleryModal = false"
  75. class="absolute -top-12 right-0 text-white text-2xl hover:text-gray-300 transition-colors"
  76. ) ×
  77. img(
  78. :src="currentGalleryImage"
  79. class="max-w-full max-h-full object-contain"
  80. )
  81. div(v-if="getMultilingualText(page.gallery, []).length > 1" class="absolute bottom-4 left-1/2 transform -translate-x-1/2 flex space-x-2")
  82. button(
  83. v-for="(image, index) in getMultilingualText(page.gallery, [])"
  84. :key="index"
  85. @click="currentGalleryIndex = index"
  86. :class="{ 'bg-blue-600': currentGalleryIndex === index, 'bg-white': currentGalleryIndex !== index }"
  87. class="w-3 h-3 rounded-full transition-colors"
  88. )