index.blade.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. @extends('layouts.app')
  2. @section('content')
  3. <div class="d-flex justify-content-end mb-3">
  4. <button type="button"
  5. id="mark-all-notifications-read"
  6. class="btn btn-outline-primary"
  7. @disabled(auth()->user()->unreadUserNotifications()->count() === 0)>
  8. Прочитано все
  9. </button>
  10. </div>
  11. @include('partials.table', [
  12. 'id' => $id,
  13. 'header' => $header,
  14. 'strings' => $notifications,
  15. ])
  16. @include('partials.pagination', ['items' => $notifications])
  17. @endsection
  18. @push('scripts')
  19. <script type="module">
  20. function updateNotificationBadge(count) {
  21. const badge = document.getElementById('notification-badge');
  22. if (!badge) return;
  23. const safeCount = Math.max(0, parseInt(count || 0, 10));
  24. badge.dataset.count = String(safeCount);
  25. badge.classList.toggle('d-none', safeCount === 0);
  26. const markAllButton = document.getElementById('mark-all-notifications-read');
  27. if (markAllButton) {
  28. markAllButton.disabled = safeCount === 0;
  29. }
  30. }
  31. function applyReadState($row, readAt) {
  32. if (!$row || !$row.length) {
  33. return;
  34. }
  35. $row.removeClass('notification-unread');
  36. const typeClass = $row.data('read-class');
  37. if (typeClass) $row.addClass(typeClass);
  38. $row.data('notification-read', '1');
  39. if (readAt) {
  40. $row.find('.column_read_at').text(readAt);
  41. }
  42. }
  43. async function markNotificationRead(id, $row) {
  44. const response = await fetch(`/notifications/${id}/read`, {
  45. method: 'POST',
  46. headers: {
  47. 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
  48. 'Accept': 'application/json',
  49. },
  50. });
  51. if (response.ok) {
  52. const data = await response.json();
  53. if (typeof data.unread !== 'undefined') {
  54. updateNotificationBadge(data.unread);
  55. }
  56. applyReadState($row, data.read_at);
  57. }
  58. }
  59. async function markAllNotificationsRead() {
  60. const response = await fetch(`{{ route('notifications.read-all') }}`, {
  61. method: 'POST',
  62. headers: {
  63. 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
  64. 'Accept': 'application/json',
  65. },
  66. });
  67. if (!response.ok) {
  68. return;
  69. }
  70. const data = await response.json();
  71. if (typeof data.unread !== 'undefined') {
  72. updateNotificationBadge(data.unread);
  73. }
  74. $('#tbl tbody tr[data-notification-id]').each(function () {
  75. const $row = $(this);
  76. const isRead = $row.data('notification-read') === '1' || $row.data('notification-read') === 1;
  77. if (!isRead) {
  78. applyReadState($row, data.read_at);
  79. }
  80. });
  81. }
  82. $(document).on('dblclick', '#tbl tbody tr[data-notification-id]', function (e) {
  83. const $row = $(this);
  84. const id = $row.data('notification-id');
  85. const isRead = $row.data('notification-read') === '1' || $row.data('notification-read') === 1;
  86. if (!isRead && id) {
  87. e.preventDefault();
  88. markNotificationRead(id, $row);
  89. }
  90. });
  91. $(document).on('click', '#mark-all-notifications-read', function () {
  92. if (this.disabled) {
  93. return;
  94. }
  95. markAllNotificationsRead();
  96. });
  97. </script>
  98. @endpush