edit.blade.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. @extends('layouts.app')
  2. @section('content')
  3. @php
  4. $commonCatalogReadableFields = $commonCatalogReadableFields ?? [];
  5. $commonCatalogWritableFields = $commonCatalogWritableFields ?? [];
  6. $canView = static fn (string $field): bool => (bool) ($commonCatalogReadableFields[$field] ?? false);
  7. $canUpdate = static fn (string $field): bool => (bool) ($commonCatalogWritableFields[$field] ?? false);
  8. $calculatorEnabledValue = old(
  9. 'calculator_enabled',
  10. $item === null || $item->calculator_enabled === null ? '' : (string) (int) $item->calculator_enabled,
  11. );
  12. $priceFields = [
  13. 'builders_price' => 'строители',
  14. 'wholesale_price' => 'опт',
  15. 'recommended_price' => 'рек',
  16. 'retail_price' => 'розница',
  17. 'project_price' => 'проект',
  18. 'project_with_installation_price' => 'проект+м',
  19. 'pik_price' => 'пик',
  20. 'recommended_plus_10_price' => 'рек+10',
  21. ];
  22. @endphp
  23. <div class="px-3">
  24. <div class="row mb-3">
  25. <div class="col-md-7 d-flex align-items-center">
  26. <h3 class="mb-0">
  27. {{ $item ? 'Позиция '.($canView('article') ? $item->article : '') : 'Новая позиция общего каталога' }}
  28. </h3>
  29. </div>
  30. @if($item)
  31. <div class="col-md-5 d-flex flex-wrap align-items-center justify-content-end gap-2 action-toolbar">
  32. @if(hasPermission('common-catalog.image.upload'))
  33. <button type="button" class="btn btn-sm btn-outline-success"
  34. onclick="document.getElementById('common-catalog-image-input').click()">
  35. <i class="bi bi-image"></i> Загрузить фото
  36. </button>
  37. <form action="{{ route('common-catalog.image.upload', ['commonCatalogItem' => $item, 'nav' => $nav ?? null]) }}"
  38. method="POST" enctype="multipart/form-data" class="visually-hidden">
  39. @csrf
  40. <input id="common-catalog-image-input" type="file" name="image"
  41. accept=".jpg,.jpeg,.png,.webp" required onchange="this.form.submit()">
  42. </form>
  43. @endif
  44. <button type="button" class="btn btn-sm btn-outline-secondary" disabled
  45. title="Будет подключено после получения контракта API">
  46. <i class="bi bi-calculator"></i> Калькуляция
  47. </button>
  48. </div>
  49. @endif
  50. </div>
  51. @if($item?->imageFile && $canView('image'))
  52. <div class="card mb-3">
  53. <div class="card-body d-flex align-items-start gap-3">
  54. <a href="{{ $item->imageFile->link }}" data-toggle="lightbox" data-gallery="common-catalog">
  55. <img src="{{ $item->imageFile->thumbnail_link }}" alt="{{ $item->article }}"
  56. class="img-thumbnail" style="max-width: 180px; max-height: 180px">
  57. </a>
  58. @if(hasPermission('common-catalog.image.delete'))
  59. <form action="{{ route('common-catalog.image.delete', ['commonCatalogItem' => $item, 'nav' => $nav ?? null]) }}"
  60. method="POST" onsubmit="return confirm('Удалить изображение?')">
  61. @csrf
  62. @method('DELETE')
  63. <button type="submit" class="btn btn-sm btn-outline-danger">Удалить фото</button>
  64. </form>
  65. @endif
  66. </div>
  67. </div>
  68. @endif
  69. <form action="{{ $item ? route('common-catalog.update', $item) : route('common-catalog.store') }}" method="POST">
  70. @csrf
  71. @if($item) @method('PUT') @endif
  72. <input type="hidden" name="nav" value="{{ $nav ?? '' }}">
  73. <div class="row">
  74. <div class="col-xl-6">
  75. @if($canView('article'))
  76. @include('partials.input', ['name' => 'article', 'title' => 'Артикул', 'required' => true, 'value' => $item?->article, 'disabled' => !$canUpdate('article')])
  77. @endif
  78. @if($canView('calculator_name'))
  79. <div class="row mb-2">
  80. <label for="calculator_name" class="col-form-label small col-md-4 text-md-end">
  81. Наименование <sup>*</sup>
  82. </label>
  83. <div class="col-md-8">
  84. <textarea name="calculator_name" id="calculator_name" rows="4" required
  85. @disabled(!$canUpdate('calculator_name'))
  86. class="form-control form-control-sm @error('calculator_name') is-invalid @enderror">{{ old('calculator_name', $item?->calculator_name) }}</textarea>
  87. @error('calculator_name')
  88. <div class="invalid-feedback"><strong>{{ $message }}</strong></div>
  89. @enderror
  90. </div>
  91. </div>
  92. @endif
  93. @if($canView('kind')) @include('partials.input', ['name' => 'kind', 'title' => 'Вид', 'value' => $item?->kind, 'disabled' => !$canUpdate('kind')]) @endif
  94. @if($canView('dimension_length')) @include('partials.input', ['name' => 'dimension_length', 'title' => 'Габариты: длина', 'value' => $item?->dimension_length, 'disabled' => !$canUpdate('dimension_length')]) @endif
  95. @if($canView('dimension_width')) @include('partials.input', ['name' => 'dimension_width', 'title' => 'Габариты: ширина', 'value' => $item?->dimension_width, 'disabled' => !$canUpdate('dimension_width')]) @endif
  96. @if($canView('dimension_height')) @include('partials.input', ['name' => 'dimension_height', 'title' => 'Габариты: высота', 'value' => $item?->dimension_height, 'disabled' => !$canUpdate('dimension_height')]) @endif
  97. @if($canView('site_length')) @include('partials.input', ['name' => 'site_length', 'title' => 'Размер участка: длина', 'value' => $item?->site_length, 'disabled' => !$canUpdate('site_length')]) @endif
  98. @if($canView('site_width')) @include('partials.input', ['name' => 'site_width', 'title' => 'Размер участка: ширина', 'value' => $item?->site_width, 'disabled' => !$canUpdate('site_width')]) @endif
  99. @if($canView('fall_height')) @include('partials.input', ['name' => 'fall_height', 'title' => 'Высота падения', 'type' => 'number', 'min' => 0, 'step' => '0.001', 'value' => $item?->fall_height, 'disabled' => !$canUpdate('fall_height')]) @endif
  100. @if($canView('additional_info'))
  101. <div class="row mb-2">
  102. <label for="additional_info" class="col-form-label small col-md-4 text-md-end">Дополнительные сведения</label>
  103. <div class="col-md-8">
  104. <textarea name="additional_info" id="additional_info" rows="4"
  105. @disabled(!$canUpdate('additional_info'))
  106. class="form-control form-control-sm @error('additional_info') is-invalid @enderror">{{ old('additional_info', $item?->additional_info) }}</textarea>
  107. @error('additional_info')
  108. <div class="invalid-feedback"><strong>{{ $message }}</strong></div>
  109. @enderror
  110. </div>
  111. </div>
  112. @endif
  113. </div>
  114. <div class="col-xl-6">
  115. @if($canView('dimension_unit')) @include('partials.input', ['name' => 'dimension_unit', 'title' => 'Единица измерения габаритов', 'value' => $item?->dimension_unit, 'disabled' => !$canUpdate('dimension_unit')]) @endif
  116. @if($canView('weight')) @include('partials.input', ['name' => 'weight', 'title' => 'Вес, кг.', 'type' => 'number', 'min' => 0, 'step' => '0.001', 'value' => $item?->weight, 'disabled' => !$canUpdate('weight')]) @endif
  117. @if($canView('volume')) @include('partials.input', ['name' => 'volume', 'title' => 'Объем, м3', 'type' => 'number', 'min' => 0, 'step' => '0.001', 'value' => $item?->volume, 'disabled' => !$canUpdate('volume')]) @endif
  118. @if($canView('places')) @include('partials.input', ['name' => 'places', 'title' => 'Места', 'type' => 'number', 'min' => 0, 'step' => 1, 'value' => $item?->places, 'disabled' => !$canUpdate('places')]) @endif
  119. @if($canView('composition'))
  120. <div class="row mb-2">
  121. <label for="composition" class="col-form-label small col-md-4 text-md-end">Состав</label>
  122. <div class="col-md-8">
  123. <textarea name="composition" id="composition" rows="4"
  124. @disabled(!$canUpdate('composition'))
  125. class="form-control form-control-sm @error('composition') is-invalid @enderror">{{ old('composition', $item?->composition) }}</textarea>
  126. @error('composition')
  127. <div class="invalid-feedback"><strong>{{ $message }}</strong></div>
  128. @enderror
  129. </div>
  130. </div>
  131. @endif
  132. @if($canView('age_group')) @include('partials.input', ['name' => 'age_group', 'title' => 'Возрастная группа', 'value' => $item?->age_group, 'disabled' => !$canUpdate('age_group')]) @endif
  133. @if($canView('max_users')) @include('partials.input', ['name' => 'max_users', 'title' => 'Макс. кол-во пользователей', 'type' => 'number', 'min' => 0, 'step' => 1, 'value' => $item?->max_users, 'disabled' => !$canUpdate('max_users')]) @endif
  134. @if($canView('unit')) @include('partials.input', ['name' => 'unit', 'title' => 'Ед.', 'value' => $item?->unit, 'disabled' => !$canUpdate('unit')]) @endif
  135. @if($canView('series')) @include('partials.input', ['name' => 'series', 'title' => 'Серия', 'value' => $item?->series, 'disabled' => !$canUpdate('series')]) @endif
  136. @if($canView('trademark')) @include('partials.input', ['name' => 'trademark', 'title' => 'ТМ', 'value' => $item?->trademark, 'disabled' => !$canUpdate('trademark')]) @endif
  137. @if($canView('calculator_enabled'))
  138. <div class="row mb-2">
  139. <label for="calculator_enabled" class="col-form-label small col-md-4 text-md-end">Калькулятор</label>
  140. <div class="col-md-8">
  141. <select name="calculator_enabled" id="calculator_enabled"
  142. @disabled(!$canUpdate('calculator_enabled'))
  143. class="form-select form-select-sm @error('calculator_enabled') is-invalid @enderror">
  144. <option value="">—</option>
  145. <option value="1" @selected((string) $calculatorEnabledValue === '1')>да</option>
  146. <option value="0" @selected((string) $calculatorEnabledValue === '0')>нет</option>
  147. </select>
  148. @error('calculator_enabled')
  149. <div class="invalid-feedback"><strong>{{ $message }}</strong></div>
  150. @enderror
  151. </div>
  152. </div>
  153. @endif
  154. </div>
  155. </div>
  156. @if(collect(array_keys($priceFields))->contains(fn (string $field): bool => $canView($field)))
  157. <div class="card mt-3">
  158. <div class="card-header"><strong>Цены</strong></div>
  159. <div class="card-body row">
  160. @foreach($priceFields as $field => $label)
  161. @if($canView($field))
  162. <div class="col-xl-6">
  163. @include('partials.input', [
  164. 'name' => $field,
  165. 'title' => $label,
  166. 'type' => 'number',
  167. 'min' => 0,
  168. 'step' => '0.01',
  169. 'value' => $item?->{$field},
  170. 'disabled' => !$canUpdate($field),
  171. ])
  172. </div>
  173. @endif
  174. @endforeach
  175. </div>
  176. </div>
  177. @endif
  178. <div class="d-flex flex-wrap gap-2 mt-3">
  179. @if(($item && hasPermission('common-catalog.update')) || (!$item && hasPermission('common-catalog.create')))
  180. <button type="submit" class="btn btn-sm btn-primary">Сохранить</button>
  181. @endif
  182. <a href="{{ $back_url ?? route('common-catalog.index') }}" class="btn btn-sm btn-outline-secondary">Назад</a>
  183. </div>
  184. </form>
  185. @if($item)
  186. <div class="card mt-4">
  187. <div class="card-header d-flex justify-content-between align-items-center">
  188. <strong>Документы</strong>
  189. @if(hasPermission('common-catalog.documents.upload'))
  190. <form action="{{ route('common-catalog.documents.upload', ['commonCatalogItem' => $item, 'nav' => $nav ?? null]) }}"
  191. method="POST" enctype="multipart/form-data" class="d-flex gap-2">
  192. @csrf
  193. <input type="file" name="document" class="form-control form-control-sm" required>
  194. <button type="submit" class="btn btn-sm btn-outline-primary">Загрузить</button>
  195. </form>
  196. @endif
  197. </div>
  198. <div class="card-body">
  199. @forelse($item->documents as $document)
  200. <div class="d-flex justify-content-between align-items-center border-bottom py-2">
  201. <a href="{{ $document->link }}" target="_blank" rel="noopener">{{ $document->original_name }}</a>
  202. @if(hasPermission('common-catalog.documents.delete'))
  203. <form action="{{ route('common-catalog.documents.delete', ['commonCatalogItem' => $item, 'file' => $document, 'nav' => $nav ?? null]) }}"
  204. method="POST" onsubmit="return confirm('Удалить документ?')">
  205. @csrf
  206. @method('DELETE')
  207. <button type="submit" class="btn btn-sm btn-outline-danger">Удалить</button>
  208. </form>
  209. @endif
  210. </div>
  211. @empty
  212. <span class="text-muted">Документы не загружены.</span>
  213. @endforelse
  214. </div>
  215. </div>
  216. <div class="card mt-4">
  217. <div class="card-header"><strong>Техническое описание</strong></div>
  218. <div class="card-body text-muted">
  219. Блок подготовлен к подключению данных и выгрузок из готового Laravel-модуля технических описаний.
  220. </div>
  221. </div>
  222. @if(hasPermission('common-catalog.delete'))
  223. <form action="{{ route('common-catalog.destroy', $item) }}" method="POST" class="mt-4"
  224. onsubmit="return confirm('Удалить позицию общего каталога?')">
  225. @csrf
  226. @method('DELETE')
  227. <button type="submit" class="btn btn-sm btn-danger">Удалить позицию</button>
  228. </form>
  229. @endif
  230. @endif
  231. </div>
  232. @endsection