Notification bell with icon

Programming Language : programming_language : MySQL

Mayank Kolwal

Email

1000089475.png

Notification bell insert your website

0
HTML Code
<div class="notification-wrapper">

    <button
        id="notificationButton"
        class="notification-button"
        type="button"
        aria-label="Notifications"
    >

        <span class="bell-icon">🔔</span>

        <span
            id="notificationBadge"
            class="notification-badge"
        >0</span>

    </button>


    <div
        id="notificationDropdown"
        class="notification-dropdown"
    >

        <div class="notification-header">

            <strong>Notifications</strong>

            <button
                id="markAllRead"
                type="button"
            >
                Mark all read
            </button>

        </div>


        <div
            id="notificationList"
            class="notification-list"
        >

            <div class="notification-loading">
                Loading...
            </div>

        </div>


        <div class="notification-footer">

            <a href="/notifications/">
                View All Notifications
            </a>

        </div>

    </div>

</div>
CSS Code
.notification-wrapper {
    position: relative;
    display: inline-block;
    font-family: Arial, sans-serif;
}


/* Bell button */

.notification-button {
    position: relative;

    width: 46px;
    height: 46px;

    border: none;
    border-radius: 50%;

    background: #ffffff;

    cursor: pointer;

    display: flex;
    align-items: center;
    justify-content: center;

    transition: 0.2s ease;
}

.notification-button:hover {
    background: #f3f3f3;
    transform: scale(1.05);
}


/* Bell */

.bell-icon {
    font-size: 25px;
    line-height: 1;
}


/* Red badge */

.notification-badge {
    position: absolute;

    top: -2px;
    right: -2px;

    min-width: 19px;
    height: 19px;

    padding: 0 5px;

    border-radius: 50px;

    background: #ff3040;
    color: white;

    font-size: 11px;
    font-weight: bold;

    display: flex;
    align-items: center;
    justify-content: center;

    border: 2px solid white;
}

.notification-badge.hidden {
    display: none;
}


/* Dropdown */

.notification-dropdown {
    position: absolute;

    top: 55px;
    right: 0;

    width: 360px;

    background: #ffffff;

    border-radius: 14px;

    box-shadow:
        0 10px 35px rgba(0, 0, 0, 0.15);

    overflow: hidden;

    z-index: 99999;

    display: none;
}

.notification-dropdown.show {
    display: block;
}


/* Header */

.notification-header {
    height: 58px;

    padding: 0 18px;

    display: flex;
    align-items: center;
    justify-content: space-between;

    border-bottom: 1px solid #eeeeee;
}

.notification-header strong {
    font-size: 18px;
    color: #222;
}

.notification-header button {
    border: none;
    background: transparent;

    color: #6c35d9;

    font-size: 13px;

    cursor: pointer;
}


/* Notification list */

.notification-list {
    max-height: 390px;
    overflow-y: auto;
}


/* Notification item */

.notification-item {
    display: flex;

    gap: 12px;

    padding: 14px 16px;

    border-bottom: 1px solid #eeeeee;

    cursor: pointer;

    transition: background 0.2s;
}

.notification-item:hover {
    background: #f7f7f7;
}


/* Unread notification */

.notification-item.unread {
    background: #f3f7ff;
}


/* Icon */

.notification-item-icon {
    width: 40px;
    height: 40px;

    flex-shrink: 0;

    border-radius: 50%;

    background: #eeeeee;

    display: flex;
    align-items: center;
    justify-content: center;

    font-size: 19px;
}


/* Content */

.notification-content {
    flex: 1;
}

.notification-message {
    font-size: 14px;

    color: #222;

    line-height: 1.4;
}

.notification-time {
    margin-top: 4px;

    color: #888;

    font-size: 12px;
}


/* Red unread dot */

.notification-unread-dot {
    width: 8px;
    height: 8px;

    background: #ff3040;

    border-radius: 50%;

    margin-top: 7px;
}


/* Footer */

.notification-footer {
    padding: 13px;

    text-align: center;

    border-top: 1px solid #eeeeee;
}

.notification-footer a {
    color: #6c35d9;

    text-decoration: none;

    font-weight: 600;

    font-size: 14px;
}


/* Empty */

.notification-empty {
    padding: 40px 20px;

    text-align: center;

    color: #888;

    font-size: 14px;
}


/* Loading */

.notification-loading {
    padding: 35px;

    text-align: center;

    color: #888;
}


/* Mobile */

@media (max-width: 600px) {

    .notification-dropdown {
        position: fixed;

        top: 65px;
        left: 10px;
        right: 10px;

        width: auto;

        max-width: none;

        border-radius: 14px;
    }

    .notification-list {
        max-height: 70vh;
    }

}
JavaScript Code
<script>

const notificationButton =
    document.getElementById("notificationButton");

const notificationDropdown =
    document.getElementById("notificationDropdown");

const notificationBadge =
    document.getElementById("notificationBadge");

const notificationList =
    document.getElementById("notificationList");

const markAllRead =
    document.getElementById("markAllRead");


/* Open / close notification */

notificationButton.addEventListener("click", function(event) {

    event.stopPropagation();

    notificationDropdown.classList.toggle("show");

});


/* Prevent dropdown from closing */

notificationDropdown.addEventListener("click", function(event) {

    event.stopPropagation();

});


/* Close when clicking outside */

document.addEventListener("click", function() {

    notificationDropdown.classList.remove("show");

});


/* Load notifications */

function loadNotifications() {

    fetch("fetch_notifications.php")

        .then(response => response.json())

        .then(data => {

            if (!data.success) {
                return;
            }


            /* Badge */

            const count = parseInt(data.unread_count);


            if (count > 0) {

                notificationBadge.textContent =
                    count > 99 ? "99+" : count;

                notificationBadge.classList.remove("hidden");

            } else {

                notificationBadge.classList.add("hidden");

            }


            /* Notifications */

            notificationList.innerHTML = "";


            if (data.notifications.length === 0) {

                notificationList.innerHTML = `
                    <div class="notification-empty">
                        No notifications yet.
                    </div>
                `;

                return;
            }


            data.notifications.forEach(notification => {

                const item =
                    document.createElement("div");


                item.className =
                    "notification-item " +
                    (notification.is_read == 0
                        ? "unread"
                        : "");


                item.innerHTML = `

                    <div class="notification-item-icon">
                        ${notification.icon || "🔔"}
                    </div>

                    <div class="notification-content">

                        <div class="notification-message">
                            ${escapeHTML(notification.message)}
                        </div>

                        <div class="notification-time">
                            ${formatDate(notification.created_at)}
                        </div>

                    </div>

                    ${
                        notification.is_read == 0
                        ? '<div class="notification-unread-dot"></div>'
                        : ''
                    }

                `;


                item.addEventListener("click", function() {

                    markNotificationRead(notification.id);

                });


                notificationList.appendChild(item);

            });

        })

        .catch(error => {

            console.error(
                "Notification error:",
                error
            );

        });

}


/* Mark single notification */

function markNotificationRead(id) {

    const formData = new FormData();

    formData.append(
        "notification_id",
        id
    );


    fetch(
        "mark_notification_read.php",
        {
            method: "POST",
            body: formData
        }
    )

    .then(response => response.json())

    .then(data => {

        if (data.success) {

            loadNotifications();

        }

    });

}


/* Mark all */

markAllRead.addEventListener(
    "click",
    function() {

        fetch(
            "mark_all_read.php",
            {
                method: "POST"
            }
        )

        .then(response => response.json())

        .then(data => {

            if (data.success) {

                loadNotifications();

            }

        });

    }
);


/* Escape HTML */

function escapeHTML(text) {

    const div = document.createElement("div");

    div.textContent = text;

    return div.innerHTML;

}


/* Date */

function formatDate(dateString) {

    const date =
        new Date(dateString);

    return date.toLocaleString();

}


/* Initial loading */

loadNotifications();


/* Automatically refresh every 10 seconds */

setInterval(
    loadNotifications,
    10000
);

</script>
PHP Code
<?php

session_start();

/* =========================================================
   1. DATABASE CONNECTION
   ========================================================= */

$host = "localhost";
$dbname = "YOUR_DATABASE_NAME";
$username = "YOUR_DATABASE_USERNAME";
$password = "YOUR_DATABASE_PASSWORD";

$conn = new mysqli(
    $host,
    $username,
    $password,
    $dbname
);

if ($conn->connect_error) {

    http_response_code(500);

    echo json_encode([
        "success" => false,
        "message" => "Database connection failed"
    ]);

    exit;
}

$conn->set_charset("utf8mb4");


/* =========================================================
   2. CHECK USER LOGIN
   ========================================================= */

if (!isset($_SESSION['user_id'])) {

    header("Content-Type: application/json");

    echo json_encode([
        "success" => false,
        "message" => "User not logged in"
    ]);

    exit;
}

$user_id = intval($_SESSION['user_id']);


/* =========================================================
   3. ACTION
   ========================================================= */

$action = isset($_GET['action'])
    ? $_GET['action']
    : 'fetch';


/* =========================================================
   4. MARK ONE NOTIFICATION AS READ
   ========================================================= */

if ($action === 'read') {

    $notification_id = isset($_POST['notification_id'])
        ? intval($_POST['notification_id'])
        : 0;

    if ($notification_id <= 0) {

        echo json_encode([
            "success" => false,
            "message" => "Invalid notification ID"
        ]);

        exit;
    }


    $sql = "
        UPDATE notifications
        SET is_read = 1
        WHERE id = ?
        AND user_id = ?
    ";

    $stmt = $conn->prepare($sql);

    $stmt->bind_param(
        "ii",
        $notification_id,
        $user_id
    );

    $stmt->execute();


    echo json_encode([
        "success" => true,
        "message" => "Notification marked as read"
    ]);

    exit;
}


/* =========================================================
   5. MARK ALL NOTIFICATIONS AS READ
   ========================================================= */

if ($action === 'read_all') {

    $sql = "
        UPDATE notifications
        SET is_read = 1
        WHERE user_id = ?
    ";

    $stmt = $conn->prepare($sql);

    $stmt->bind_param(
        "i",
        $user_id
    );

    $stmt->execute();


    echo json_encode([
        "success" => true,
        "message" => "All notifications marked as read"
    ]);

    exit;
}


/* =========================================================
   6. GET UNREAD NOTIFICATION COUNT
   ========================================================= */

$count_sql = "
    SELECT COUNT(*) AS unread_count
    FROM notifications
    WHERE user_id = ?
    AND is_read = 0
";

$count_stmt = $conn->prepare($count_sql);

$count_stmt->bind_param(
    "i",
    $user_id
);

$count_stmt->execute();

$count_result =
    $count_stmt->get_result();

$count_data =
    $count_result->fetch_assoc();

$unread_count =
    intval($count_data['unread_count']);


/* =========================================================
   7. GET LATEST NOTIFICATIONS
   ========================================================= */

$sql = "
    SELECT
        id,
        message,
        icon,
        is_read,
        created_at
    FROM notifications
    WHERE user_id = ?
    ORDER BY created_at DESC
    LIMIT 10
";

$stmt = $conn->prepare($sql);

$stmt->bind_param(
    "i",
    $user_id
);

$stmt->execute();

$result =
    $stmt->get_result();


/* =========================================================
   8. CREATE NOTIFICATION ARRAY
   ========================================================= */

$notifications = [];

while ($row = $result->fetch_assoc()) {

    $notifications[] = [

        "id" =>
            intval($row["id"]),

        "message" =>
            $row["message"],

        "icon" =>
            $row["icon"],

        "is_read" =>
            intval($row["is_read"]),

        "created_at" =>
            $row["created_at"]

    ];
}


/* =========================================================
   9. SEND JSON RESPONSE
   ========================================================= */

header("Content-Type: application/json");

echo json_encode([

    "success" => true,

    "unread_count" =>
        $unread_count,

    "notifications" =>
        $notifications

]);

?>
MySQL Code
CREATE TABLE notifications (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    message TEXT NOT NULL,
    icon VARCHAR(255) DEFAULT '',
    is_read TINYINT(1) DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Leave a Comment