اذهب إلى المحتوى

السؤال

نشر (معدل)
 <!-- الجرس -->
       <li class="nav-item dropdown mx-2" style="list-style: none;">
    <a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown">
        <i class="fas fa-bell"></i>
        <span class="badge bg-danger notif-count" style="display: none;">0</span>
    </a>

    <div class="dropdown-menu dropdown-menu-end" style="width: 300px;">
        <h6 class="dropdown-header">التنبيهات</h6>
        
        <div class="alert-body">
            <p class="text-center small text-muted my-2 empty-msg">لا توجد تنبيهات جديدة</p>
        </div>

        <div class="dropdown-divider"></div>
        <div class="text-center">
            <a class="dropdown-item small text-gray-500" href="#">عرض جميع التنبيهات</a>
        </div>
    </div>
</li>
<script type="module">
    $(document).ready(function() {
        @if(Auth::check())
            var post_userId = {{ Auth::user()->id }};
            
            Echo.private(`real-notification.${post_userId}`)
                .listen('CommentNotification', (data) => {
                    
                    // 1. إخفاء رسالة "لا توجد تنبيهات" عند وصول أول تنبيه
                    $('.empty-msg').hide();

                    // 2. تحديث العداد وإظهاره
                    var countElem = $('.notif-count');
                    var currentCount = parseInt(countElem.text()) || 0;
                    countElem.text(currentCount + 1).show();

                    // 3. بناء هيكل الإشعار
                    var newNotif = `
                        <a class="dropdown-item d-flex align-items-center border-bottom" href="#">
                            <div class="ml-2 shadow-sm" style="margin-left: 10px;">
                                <img src="${data.user_image}" class="rounded-circle" width="40" height="40">
                            </div>
                            <div>
                                <div class="small text-gray-500">${data.date}</div>
                                <span class="font-weight-bold" style="white-space: normal; display: block; line-height: 1.2;">
                                    ${data.user_name} علق على منشورك
                                </span>
                            </div>
                        </a>`;

                    // 4. إضافة الإشعار في بداية القائمة (alert-body)
                    $('.alert-body').prepend(newNotif);
                });
        @endif
    });
</script>

 

تم التعديل في بواسطة ايمن ميلاد

Recommended Posts

  • 0
نشر

قمت بحل مشكلة الان عدد اشعار  لايظهر  لكن اشعار يظهر 

<script>
    var token = '{{ csrf_token() }}'; 
    var urlNotify = '{{ route("notification") }}';

  $('#alertsDropdown').on('shown.bs.dropdown', function () {

    var notificationsCountElem = $('#alertsDropdown .notif-count');

    $('.alert-body').html('<p class="text-center small text-muted my-2">جاري التحميل...</p>');

    $.ajax({
        method: 'POST',
        url: urlNotify,
        data: { _token: token },
        success: function(data) {

            if (data.count && data.count > 0) {
                notificationsCountElem.text(data.count).show();
            } else {
                notificationsCountElem.hide();
            }

            var responseNotifications = "";

            if (data.someNotifications && data.someNotifications.length > 0) {
                $.each(data.someNotifications, function(i, item) {

                    var post_url = "{{ route('post.show', ':post_slug') }}";
                    post_url = post_url.replace(':post_slug', item.post_slug);

                    responseNotifications += `
                        <a class="dropdown-item d-flex align-items-center border-bottom" href="${post_url}">
                            <div class="ms-3">
                                <img src="${item.user_image}" width="40" height="40" class="rounded-circle">
                            </div>
                            <div>
                                <div class="small text-gray-500">${item.date}</div>
                                <span>${item.user_name} علق على ${item.post_title}</span>
                            </div>
                        </a>`;
                });
            } else {
                responseNotifications = '<p class="text-center small text-muted my-2">لا توجد تنبيهات</p>';
            }

            $('.alert-body').html(responseNotifications);
        }
    });
});
</script>
  <li class="nav-item dropdown mx-2" style="list-style: none;">
    <a class="nav-link dropdown-toggle position-relative" href="#" id="alertsDropdown" data-bs-toggle="dropdown" aria-expanded="false">
        <i class="fas fa-bell"></i>
       <span class="badge rounded-pill bg-danger notif-count position-absolute"
      style="top: 0; right: 0; transform: translate(50%, -20%); font-size: 0.6rem; ">
    0
</span>
    </a>

    <div class="dropdown-menu dropdown-menu-end shadow" style="width: 300px; border: none;">
        <h6 class="dropdown-header bg-dark text-white">التنبيهات</h6>
        
        <div class="alert-body" style="max-height: 300px; overflow-y: auto;">
            <p class="text-center small text-muted my-3 empty-msg">لا توجد تنبيهات جديدة</p>
        </div>

        <div class="dropdown-divider"></div>
        <div class="text-center">
            <a class="dropdown-item small text-gray-500" href="#">عرض جميع التنبيهات</a>
        </div>
    </div>
</li>

 

  • 0
نشر

 

في التعديل الثاني، الإستجابة من الخادم لا تحتوي على خاصية count، الشرط if (data.count && data.count > 0) سيكون false، وسيتم إخفاء الشارة حتى لو كان هناك إشعارات فعلية.

بالتالي ستظهر عناصر الإشعارات لأن someNotifications موجودة لكن العداد لا يظهر لأن data.count مفقود أو صفر، أو أن الكود يخفيه.

أيضاً استبدال $('.alert-body').html(responseNotifications) سيحذف أي إشعارات أضيفت مسبقاً عبر Laravel Echo مما يسبب فقدانها.

لذا يجب إما تعديل الـ Controller ليعيد count، أو جلب العدد من طول المصفوفة مباشرة data.someNotifications.length والحل الأول أفضل بالطبع.

ثم كتابة كود جافاسكريبت، وبه تحتفظ بقائمة محملة مبدئياً من السيرفر عند تحميل الصفحة، ثم نحدّثها فقط عبر Echo، وعند فتح القائمة نعرض القائمة ولا نعيد تحميلها من الخادم.

المتحكم NotificationController.php:


public function getNotifications(Request $request)
{
    $user = auth()->user();
    $unreadNotifications = $user->unreadNotifications;
    $count = $unreadNotifications->count();
    $someNotifications = $unreadNotifications->take(5)->map(function ($item) {
        return [
            'id' => $item->id,
            'user_name' => $item->data['user_name'],
            'user_image' => $item->data['user_image'] ?? asset('images/default-user.png'),
            'post_title' => $item->data['post_title'],
            'post_slug' => $item->data['post_slug'],
            'date' => $item->created_at->diffForHumans(),
        ];
    });

    return response()->json([
        'count' => $count,
        'someNotifications' => $someNotifications,
    ]);
}

HTML:

<li class="nav-item dropdown mx-2" style="list-style: none;">
    <a class="nav-link dropdown-toggle position-relative" href="#" id="alertsDropdown" data-bs-toggle="dropdown" aria-expanded="false">
        <i class="fas fa-bell"></i>
        <span class="badge rounded-pill bg-danger notif-count position-absolute"
              style="top: 0; right: 0; transform: translate(50%, -20%); font-size: 0.6rem; display: none;">
            0
        </span>
    </a>

    <div class="dropdown-menu dropdown-menu-end shadow" style="width: 300px; border: none;">
        <h6 class="dropdown-header bg-dark text-white">التنبيهات</h6>
        
        <div class="alert-body" style="max-height: 300px; overflow-y: auto;">
            <p class="text-center small text-muted my-3 empty-msg">لا توجد تنبيهات جديدة</p>
        </div>

        <div class="dropdown-divider"></div>
        <div class="text-center">
            <a class="dropdown-item small text-gray-500" href="#">عرض جميع التنبيهات</a>
        </div>
    </div>
</li>

JS:

<script>
var token = '{{ csrf_token() }}';
var urlNotify = '{{ route("notification") }}';
var postShowUrlBase = '{{ route("post.show", ":post_slug") }}';

$(document).ready(function() {
    function loadInitialNotifications() {
        $.ajax({
            method: 'POST',
            url: urlNotify,
            data: { _token: token },
            success: function(data) {
                var count = data.count || 0;
                var badge = $('.notif-count');

                if (count > 0) {
                    badge.text(count).show();
                } else {
                    badge.hide();
                    $('.empty-msg').show();
                }

                var html = '';
                if (data.someNotifications && data.someNotifications.length > 0) {
                    $('.empty-msg').hide();
                    $.each(data.someNotifications, function(i, item) {
                        var url = postShowUrlBase.replace(':post_slug', item.post_slug);
                        html += `
                            <a class="dropdown-item d-flex align-items-center border-bottom notif-item" href="${url}" data-id="${item.id}">
                                <div class="ms-3">
                                    <img src="${item.user_image}" width="40" height="40" class="rounded-circle">
                                </div>
                                <div>
                                    <div class="small text-gray-500">${item.date}</div>
                                    <span>${item.user_name} علق على ${item.post_title}</span>
                                </div>
                            </a>`;
                    });
                } else {
                    html = '<p class="text-center small text-muted my-3 empty-msg">لا توجد تنبيهات جديدة</p>';
                }
                $('.alert-body').html(html);
            }
        });
    }

    @if(Auth::check())
        loadInitialNotifications();
    @endif

    @if(Auth::check())
        var userId = {{ Auth::user()->id }};
        if (typeof Echo !== 'undefined') {
            Echo.private('real-notification.' + userId)
                .listen('CommentNotification', (data) => {
                    $('.empty-msg').hide();

                    var badge = $('.notif-count');
                    var currentCount = parseInt(badge.text()) || 0;
                    badge.text(currentCount + 1).show();

                    var url = postShowUrlBase.replace(':post_slug', data.post_slug);
                    var newNotif = `
                        <a class="dropdown-item d-flex align-items-center border-bottom notif-item" href="${url}" data-id="${data.id}">
                            <div class="ms-3">
                                <img src="${data.user_image}" class="rounded-circle" width="40" height="40">
                            </div>
                            <div>
                                <div class="small text-gray-500">${data.date}</div>
                                <span class="fw-bold">${data.user_name} علق على منشورك</span>
                            </div>
                        </a>`;

                    $('.alert-body').prepend(newNotif);
                });
        }
    @endif
});
</script>

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...