_builder_card.blade.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. {{--
  2. Partial: правая колонка page-edit — конструктор страницы (page builder)
  3. Переменные из родителя: $page, $sections, $availableBlocks
  4. --}}
  5. <div class="card card-primary card-outline">
  6. <div class="card-header d-flex align-items-center">
  7. <h3 class="card-title"><i class="fas fa-layer-group mr-1"></i> Конструктор страницы</h3>
  8. <div class="card-tools">
  9. <button id="btn-save-order" class="btn btn-sm btn-primary" disabled>
  10. <i class="fas fa-save"></i> Сохранить порядок
  11. </button>
  12. </div>
  13. </div>
  14. <div class="card-body p-0">
  15. @if($sections->isEmpty())
  16. <div class="text-center text-muted p-5" id="empty-hint">
  17. <i class="fas fa-layer-group fa-2x mb-2 d-block"></i>
  18. Страница пуста. Добавьте блоки или текстовые области с помощью кнопок ниже.
  19. </div>
  20. @endif
  21. {{-- Список секций — перетаскиваемый --}}
  22. <ul id="sortable-sections" class="list-group list-group-flush" style="min-height:10px;">
  23. @foreach($sections as $section)
  24. <li class="list-group-item p-0 border-bottom" data-id="{{ $section->id }}">
  25. <div class="d-flex align-items-stretch">
  26. {{-- Хэндл перетаскивания --}}
  27. <div class="drag-handle d-flex align-items-center px-3 text-muted"
  28. style="cursor:grab; background:#f8f9fa; border-right:1px solid #dee2e6;">
  29. <i class="fas fa-grip-vertical"></i>
  30. </div>
  31. <div class="flex-grow-1 p-3">
  32. @if($section->type === 'block')
  33. {{-- Блочная секция --}}
  34. <div class="d-flex align-items-center">
  35. <span class="badge badge-primary mr-2">Блок</span>
  36. @if($section->block)
  37. <strong>{{ $section->block->title }}</strong>
  38. <small class="text-muted ml-2"><code>{{ $section->block->name }}</code></small>
  39. @else
  40. <span class="text-danger">Блок удалён</span>
  41. @endif
  42. </div>
  43. @else
  44. {{-- Текстовая секция --}}
  45. <div>
  46. <span class="badge badge-secondary mb-2">Текстовая область</span>
  47. <textarea class="content-editor form-control"
  48. data-section-id="{{ $section->id }}"
  49. data-save-url="{{ route('admin.pages.sections.update', [$page, $section]) }}"
  50. style="display:none;">{{ $section->content }}</textarea>
  51. <div class="summernote-wrapper">
  52. <div class="summernote-editor" id="editor-{{ $section->id }}">
  53. {!! $section->content !!}
  54. </div>
  55. </div>
  56. <div class="mt-2 d-flex align-items-center">
  57. <button type="button"
  58. class="btn btn-xs btn-success btn-save-content mr-2"
  59. data-section-id="{{ $section->id }}">
  60. <i class="fas fa-save"></i> Сохранить текст
  61. </button>
  62. <span class="save-status text-success small" id="status-{{ $section->id }}" style="display:none;">
  63. <i class="fas fa-check"></i> Сохранено
  64. </span>
  65. </div>
  66. </div>
  67. @endif
  68. </div>
  69. {{-- Кнопки действий --}}
  70. <div class="d-flex flex-column justify-content-center px-3"
  71. style="border-left:1px solid #dee2e6;">
  72. @if($section->type === 'block' && $section->block)
  73. <a href="{{ route('admin.blocks.edit', $section->block_id) }}"
  74. class="btn btn-xs btn-outline-secondary mb-1"
  75. title="Редактировать блок">
  76. <i class="fas fa-edit"></i>
  77. </a>
  78. @endif
  79. <form method="POST"
  80. action="{{ route('admin.pages.sections.destroy', [$page, $section]) }}"
  81. onsubmit="return confirm('Удалить эту секцию?')">
  82. @csrf
  83. @method('DELETE')
  84. <button type="submit" class="btn btn-xs btn-outline-danger"
  85. title="Удалить секцию">
  86. <i class="fas fa-trash"></i>
  87. </button>
  88. </form>
  89. </div>
  90. </div>
  91. </li>
  92. @endforeach
  93. </ul>
  94. </div>
  95. {{-- Панель добавления секций --}}
  96. <div class="card-footer p-0">
  97. <div class="p-3 border-bottom bg-light">
  98. <small class="text-muted text-uppercase font-weight-bold" style="letter-spacing:.05em;">
  99. <i class="fas fa-plus-circle mr-1"></i> Добавить секцию на страницу
  100. </small>
  101. </div>
  102. <div class="row no-gutters">
  103. {{-- Карточка 1: Текстовая область --}}
  104. <div class="col-md-6 border-right">
  105. <div class="p-3">
  106. <div class="d-flex align-items-start mb-2">
  107. <span class="mr-3" style="font-size:24px; line-height:1; color:#6c757d;">
  108. <i class="fas fa-align-left"></i>
  109. </span>
  110. <div>
  111. <div class="font-weight-bold">Текстовая область</div>
  112. <small class="text-muted">Произвольный HTML-текст — заголовки, абзацы, списки. Редактируется через встроенный редактор.</small>
  113. </div>
  114. </div>
  115. <form method="POST" action="{{ route('admin.pages.sections.add-content', $page) }}">
  116. @csrf
  117. <button type="submit" class="btn btn-block btn-outline-secondary btn-sm">
  118. <i class="fas fa-plus"></i> Добавить текстовую область
  119. </button>
  120. </form>
  121. </div>
  122. </div>
  123. {{-- Карточка 2: Готовый блок --}}
  124. <div class="col-md-6">
  125. <div class="p-3">
  126. <div class="d-flex align-items-start mb-2">
  127. <span class="mr-3" style="font-size:24px; line-height:1; color:#007bff;">
  128. <i class="fas fa-layer-group"></i>
  129. </span>
  130. <div>
  131. <div class="font-weight-bold">Готовый блок</div>
  132. <small class="text-muted">Переиспользуемый блок из библиотеки — например «Почему мы», баннер, CTA. Редактируется централизованно.</small>
  133. </div>
  134. </div>
  135. @if($availableBlocks->isNotEmpty())
  136. <form method="POST" action="{{ route('admin.pages.sections.attach-block', $page) }}">
  137. @csrf
  138. <div class="input-group input-group-sm">
  139. <select name="block_id" class="form-control" required>
  140. <option value="">— выбрать из библиотеки —</option>
  141. @foreach($availableBlocks as $block)
  142. <option value="{{ $block->id }}">{{ $block->title }}</option>
  143. @endforeach
  144. </select>
  145. <div class="input-group-append">
  146. <button type="submit" class="btn btn-outline-primary">
  147. <i class="fas fa-plus"></i> Добавить
  148. </button>
  149. </div>
  150. </div>
  151. </form>
  152. @else
  153. <div class="text-muted small mb-2">
  154. <i class="fas fa-check-circle text-success"></i> Все активные блоки уже на странице
  155. </div>
  156. @endif
  157. <a href="{{ route('admin.blocks.create') }}" class="btn btn-sm btn-link p-0 mt-1 text-muted">
  158. <i class="fas fa-plus-square"></i> Создать новый блок в библиотеке
  159. </a>
  160. </div>
  161. </div>
  162. </div>
  163. </div>
  164. </div>