Jelajahi Sumber

style(notifications): improve UI interaction and code formatting

- Change notification click event from single to double-click
- Add cursor pointer to notification items for better UX
- Fix indentation and formatting in SCSS files
- Add notification_logs table mapping to FilterController
- Import Attribute class in NotificationDeliveryLog model
- Clean up code formatting across notification-related files
Alexander Musikhin 1 bulan lalu
induk
melakukan
74102d314f

+ 16 - 0
app/Http/Controllers/FilterController.php

@@ -21,11 +21,13 @@ class FilterController extends Controller
         'spare_parts'   => 'spare_parts_view',
         'spare_part_orders' => 'spare_part_orders_view',
         'notifications' => 'user_notifications',
+        'notification_logs' => 'notification_delivery_logs',
     ];
 
     const SKIP_YEAR_FILTER = [
         'reclamations',
         'notifications',
+        'notification_logs',
     ];
 
     /**
@@ -77,6 +79,20 @@ class FilterController extends Controller
                 'shipped'  => 'Отгружено',
             ],
         ],
+        'notification_logs' => [
+            'channel' => [
+                'in_app'  => 'В приложении',
+                'browser' => 'Браузер',
+                'push'    => 'Push',
+                'email'   => 'Email',
+            ],
+            'status' => [
+                'sent'        => 'Отправлено',
+                'failed'      => 'Ошибка',
+                'skipped'     => 'Пропущено',
+                'dead_letter' => 'Dead letter',
+            ],
+        ],
     ];
 
     public function getFilters(FilterRequest $request)

+ 1 - 0
app/Http/Controllers/UserNotificationController.php

@@ -68,6 +68,7 @@ class UserNotificationController extends Controller
 
         return response()->json([
             'ok' => true,
+            'read_at' => $notification->read_at->format('d.m.Y H:i:s'),
             'unread' => UserNotification::query()
                 ->where('user_id', $request->user()->id)
                 ->whereNull('read_at')

+ 29 - 0
app/Models/NotificationDeliveryLog.php

@@ -2,6 +2,7 @@
 
 namespace App\Models;
 
+use Illuminate\Database\Eloquent\Casts\Attribute;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -20,6 +21,20 @@ class NotificationDeliveryLog extends Model
     public const STATUS_SKIPPED = 'skipped';
     public const STATUS_DEAD_LETTER = 'dead_letter';
 
+    public const CHANNEL_LABELS = [
+        self::CHANNEL_IN_APP  => 'В приложении',
+        self::CHANNEL_BROWSER => 'Браузер',
+        self::CHANNEL_PUSH    => 'Push',
+        self::CHANNEL_EMAIL   => 'Email',
+    ];
+
+    public const STATUS_LABELS = [
+        self::STATUS_SENT        => 'Отправлено',
+        self::STATUS_FAILED      => 'Ошибка',
+        self::STATUS_SKIPPED     => 'Пропущено',
+        self::STATUS_DEAD_LETTER => 'Dead letter',
+    ];
+
     public const DEFAULT_SORT_BY = 'created_at';
     public const DEFAULT_ORDER_BY = 'desc';
 
@@ -33,6 +48,20 @@ class NotificationDeliveryLog extends Model
         'error',
     ];
 
+    protected function channel(): Attribute
+    {
+        return Attribute::make(
+            get: fn($value) => self::CHANNEL_LABELS[$value] ?? $value,
+        );
+    }
+
+    protected function status(): Attribute
+    {
+        return Attribute::make(
+            get: fn($value) => self::STATUS_LABELS[$value] ?? $value,
+        );
+    }
+
     public function user(): BelongsTo
     {
         return $this->belongsTo(User::class);

+ 1 - 0
resources/sass/app.scss

@@ -577,6 +577,7 @@
 
 .notification-unread {
   background: #fce7ea;
+  cursor: pointer;
 }
 
 .notification-read-platform {

+ 6 - 9
resources/views/notifications/index.blade.php

@@ -41,24 +41,21 @@
                     const typeClass = $row.data('read-class');
                     if (typeClass) $row.addClass(typeClass);
                     $row.data('notification-read', '1');
+
+                    if (data.read_at) {
+                        $row.find('.column_read_at').text(data.read_at);
+                    }
                 }
             }
         }
 
-        $(document).on('click', '#tbl tbody tr[data-notification-id]', function (e) {
+        $(document).on('dblclick', '#tbl tbody tr[data-notification-id]', function (e) {
             const $row = $(this);
             const id = $row.data('notification-id');
             const isRead = $row.data('notification-read') === '1' || $row.data('notification-read') === 1;
 
             if (!isRead && id) {
-                const link = $(e.target).closest('a');
-                if (link.length && link.attr('href')) {
-                    e.preventDefault();
-                    markNotificationRead(id, $row).then(() => {
-                        window.location.href = link.attr('href');
-                    });
-                    return;
-                }
+                e.preventDefault();
                 markNotificationRead(id, $row);
             }
         });