index.blade.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. {{--
  2. Вьюха: Ссылки для парсера — динамический список URL-адресов
  3. Создана: 2026-06-06
  4. Контроллер: Admin\ParserLinkController::index() / update()
  5. Переменные: $links (коллекция ParserLink, отсортированная по sort_order)
  6. Логика: POST сохраняет весь список целиком (truncate + insert).
  7. JS позволяет добавлять/удалять строки без перезагрузки страницы.
  8. --}}
  9. @extends('admin.layout')
  10. @section('title', 'Ссылки для парсера')
  11. @section('content_header')
  12. <div class="d-flex justify-content-between align-items-center">
  13. <h1 class="m-0">Ссылки для парсера</h1>
  14. </div>
  15. @stop
  16. @section('breadcrumb')
  17. <li class="breadcrumb-item"><a href="{{ route('admin.dashboard') }}">Главная</a></li>
  18. <li class="breadcrumb-item active">Ссылки для парсера</li>
  19. @stop
  20. @section('content')
  21. @if(session('success'))
  22. <div class="alert alert-success alert-dismissible">
  23. <button type="button" class="close" data-dismiss="alert">&times;</button>
  24. {{ session('success') }}
  25. </div>
  26. @endif
  27. @if($errors->any())
  28. <div class="alert alert-danger alert-dismissible">
  29. <button type="button" class="close" data-dismiss="alert">&times;</button>
  30. <ul class="mb-0">
  31. @foreach($errors->all() as $e)<li>{{ $e }}</li>@endforeach
  32. </ul>
  33. </div>
  34. @endif
  35. <div class="row justify-content-center">
  36. <div class="col-md-8">
  37. <div class="card card-primary card-outline">
  38. <div class="card-header">
  39. <h3 class="card-title">URL-адреса для обхода парсером</h3>
  40. </div>
  41. <div class="card-body">
  42. <form action="{{ route('admin.parser-links.update') }}" method="POST" id="parser-links-form">
  43. @csrf
  44. <div id="links-container">
  45. @forelse($links as $link)
  46. <div class="link-row input-group mb-2">
  47. <input type="text" name="urls[]"
  48. class="form-control"
  49. value="{{ $link->url }}"
  50. placeholder="https://example.com/catalog">
  51. <div class="input-group-append">
  52. <button type="button" class="btn btn-danger btn-remove-link" title="Удалить">
  53. <i class="fas fa-times"></i>
  54. </button>
  55. </div>
  56. </div>
  57. @empty
  58. <div class="link-row input-group mb-2">
  59. <input type="text" name="urls[]"
  60. class="form-control"
  61. placeholder="https://example.com/catalog">
  62. <div class="input-group-append">
  63. <button type="button" class="btn btn-danger btn-remove-link" title="Удалить">
  64. <i class="fas fa-times"></i>
  65. </button>
  66. </div>
  67. </div>
  68. @endforelse
  69. </div>
  70. <div class="mb-3">
  71. <button type="button" id="btn-add-link" class="btn btn-outline-primary btn-sm">
  72. <i class="fas fa-plus"></i> Добавить ссылку
  73. </button>
  74. </div>
  75. <div class="d-flex">
  76. <button type="submit" class="btn btn-primary">
  77. <i class="fas fa-save"></i> Сохранить
  78. </button>
  79. </div>
  80. </form>
  81. </div>
  82. <div class="card-footer text-muted small">
  83. Каждая строка — отдельный URL. Пустые строки игнорируются при сохранении.
  84. </div>
  85. </div>
  86. </div>
  87. </div>
  88. @stop
  89. @push('js')
  90. <script>
  91. (function () {
  92. var container = document.getElementById('links-container');
  93. function makeRow(value) {
  94. var row = document.createElement('div');
  95. row.className = 'link-row input-group mb-2';
  96. row.innerHTML =
  97. '<input type="text" name="urls[]" class="form-control" value="' + (value || '') + '" placeholder="https://example.com/catalog">' +
  98. '<div class="input-group-append">' +
  99. '<button type="button" class="btn btn-danger btn-remove-link" title="Удалить">' +
  100. '<i class="fas fa-times"></i>' +
  101. '</button>' +
  102. '</div>';
  103. return row;
  104. }
  105. // Добавить строку
  106. document.getElementById('btn-add-link').addEventListener('click', function () {
  107. var row = makeRow('');
  108. container.appendChild(row);
  109. row.querySelector('input').focus();
  110. });
  111. // Удалить строку (делегирование на контейнер)
  112. container.addEventListener('click', function (e) {
  113. var btn = e.target.closest('.btn-remove-link');
  114. if (!btn) return;
  115. var rows = container.querySelectorAll('.link-row');
  116. if (rows.length === 1) {
  117. // Если последняя строка — просто очищаем её
  118. rows[0].querySelector('input').value = '';
  119. } else {
  120. btn.closest('.link-row').remove();
  121. }
  122. });
  123. })();
  124. </script>
  125. @endpush