Index: kupi-mk/backend/routes/favorites.js
===================================================================
--- kupi-mk/backend/routes/favorites.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
+++ kupi-mk/backend/routes/favorites.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
@@ -0,0 +1,111 @@
+const express = require('express');
+const { pool } = require('../config/database');
+const { auth } = require('../middleware/auth');
+
+const router = express.Router();
+
+// Get all favorites for logged-in user
+router.get('/', auth, async (req, res) => {
+  try {
+    const userId = req.user.userId;
+
+    const favorites = await pool.query(
+      `SELECT 
+        f.id as favorite_id,
+        f.created_at as favorited_at,
+        p.id,
+        p.title,
+        p.description,
+        p.price,
+        p.images,
+        p.stock_quantity,
+        p.location,
+        p.is_active,
+        c.name as category_name,
+        u.username as seller_username
+       FROM favorites f
+       JOIN products p ON f.product_id = p.id
+       LEFT JOIN categories c ON p.category_id = c.id
+       LEFT JOIN users u ON p.seller_id = u.id
+       WHERE f.user_id = $1
+       ORDER BY f.created_at DESC`,
+      [userId]
+    );
+
+    res.json(favorites.rows);
+  } catch (error) {
+    console.error('Error fetching favorites:', error);
+    res.status(500).json({ message: 'Server error' });
+  }
+});
+
+// Check if product is favorited
+router.get('/check/:productId', auth, async (req, res) => {
+  try {
+    const userId = req.user.userId;
+    const productId = req.params.productId;
+
+    const result = await pool.query(
+      'SELECT id FROM favorites WHERE user_id = $1 AND product_id = $2',
+      [userId, productId]
+    );
+
+    res.json({ isFavorited: result.rows.length > 0 });
+  } catch (error) {
+    console.error('Error checking favorite:', error);
+    res.status(500).json({ message: 'Server error' });
+  }
+});
+
+// Add product to favorites
+router.post('/:productId', auth, async (req, res) => {
+  try {
+    const userId = req.user.userId;
+    const productId = req.params.productId;
+
+    // Check if product exists
+    const productCheck = await pool.query(
+      'SELECT id FROM products WHERE id = $1 AND is_active = true',
+      [productId]
+    );
+
+    if (productCheck.rows.length === 0) {
+      return res.status(404).json({ message: 'Product not found' });
+    }
+
+    // Add to favorites (ignore if already exists due to UNIQUE constraint)
+    await pool.query(
+      'INSERT INTO favorites (user_id, product_id) VALUES ($1, $2) ON CONFLICT (user_id, product_id) DO NOTHING',
+      [userId, productId]
+    );
+
+    res.json({ success: true, message: 'Added to favorites' });
+  } catch (error) {
+    console.error('Error adding to favorites:', error);
+    res.status(500).json({ message: 'Server error' });
+  }
+});
+
+// Remove product from favorites
+router.delete('/:productId', auth, async (req, res) => {
+  try {
+    const userId = req.user.userId;
+    const productId = req.params.productId;
+
+    const result = await pool.query(
+      'DELETE FROM favorites WHERE user_id = $1 AND product_id = $2 RETURNING *',
+      [userId, productId]
+    );
+
+    if (result.rows.length === 0) {
+      return res.status(404).json({ message: 'Favorite not found' });
+    }
+
+    res.json({ success: true, message: 'Removed from favorites' });
+  } catch (error) {
+    console.error('Error removing from favorites:', error);
+    res.status(500).json({ message: 'Server error' });
+  }
+});
+
+module.exports = router;
Index: kupi-mk/backend/routes/notifications.js
===================================================================
--- kupi-mk/backend/routes/notifications.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
+++ kupi-mk/backend/routes/notifications.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
@@ -0,0 +1,126 @@
+const express = require('express');
+const { pool } = require('../config/database');
+const { auth } = require('../middleware/auth');
+
+const router = express.Router();
+
+// Get all notifications for the logged-in user
+router.get('/', auth, async (req, res) => {
+  try {
+    const userId = req.user.userId;
+    const unreadOnly = req.query.unread === 'true';
+
+    let query = `SELECT n.*, o.total_amount, o.status as order_status
+       FROM notifications n
+       LEFT JOIN orders o ON n.order_id = o.id
+       WHERE n.user_id = $1`;
+    
+    if (unreadOnly) {
+      query += ' AND n.is_read = FALSE';
+    }
+    
+    query += ' ORDER BY n.created_at DESC LIMIT 50';
+
+    const notifications = await pool.query(query, [userId]);
+
+    res.json(notifications.rows);
+  } catch (error) {
+    console.error('Error fetching notifications:', error);
+    res.status(500).json({ message: 'Server error' });
+  }
+});
+
+// Get unread notification count
+router.get('/unread-count', auth, async (req, res) => {
+  try {
+    const userId = req.user.userId;
+
+    const result = await pool.query(
+      'SELECT COUNT(*) as count FROM notifications WHERE user_id = $1 AND is_read = FALSE',
+      [userId]
+    );
+
+    res.json({ count: parseInt(result.rows[0].count) });
+  } catch (error) {
+    console.error('Error fetching unread count:', error);
+    res.status(500).json({ message: 'Server error' });
+  }
+});
+
+// Mark notification as read
+router.patch('/:id/read', auth, async (req, res) => {
+  try {
+    const userId = req.user.userId;
+    const notificationId = req.params.id;
+
+    const result = await pool.query(
+      'UPDATE notifications SET is_read = TRUE WHERE id = $1 AND user_id = $2 RETURNING *',
+      [notificationId, userId]
+    );
+
+    if (result.rows.length === 0) {
+      return res.status(404).json({ message: 'Notification not found' });
+    }
+
+    res.json(result.rows[0]);
+  } catch (error) {
+    console.error('Error marking notification as read:', error);
+    res.status(500).json({ message: 'Server error' });
+  }
+});
+
+// Mark all notifications as read
+router.patch('/read-all', auth, async (req, res) => {
+  try {
+    const userId = req.user.userId;
+
+    await pool.query(
+      'UPDATE notifications SET is_read = TRUE WHERE user_id = $1 AND is_read = FALSE',
+      [userId]
+    );
+
+    res.json({ message: 'All notifications marked as read' });
+  } catch (error) {
+    console.error('Error marking all notifications as read:', error);
+    res.status(500).json({ message: 'Server error' });
+  }
+});
+
+// Delete a notification
+router.delete('/:id', auth, async (req, res) => {
+  try {
+    const userId = req.user.userId;
+    const notificationId = req.params.id;
+
+    const result = await pool.query(
+      'DELETE FROM notifications WHERE id = $1 AND user_id = $2 RETURNING *',
+      [notificationId, userId]
+    );
+
+    if (result.rows.length === 0) {
+      return res.status(404).json({ message: 'Notification not found' });
+    }
+
+    res.json({ message: 'Notification deleted' });
+  } catch (error) {
+    console.error('Error deleting notification:', error);
+    res.status(500).json({ message: 'Server error' });
+  }
+});
+
+// Helper function to create a notification (used by other routes)
+const createNotification = async (userId, type, title, message, orderId = null) => {
+  try {
+    const result = await pool.query(
+      `INSERT INTO notifications (user_id, type, title, message, order_id)
+       VALUES ($1, $2, $3, $4, $5) RETURNING *`,
+      [userId, type, title, message, orderId]
+    );
+    return result.rows[0];
+  } catch (error) {
+    console.error('Error creating notification:', error);
+    throw error;
+  }
+};
+
+module.exports = { router, createNotification };
Index: kupi-mk/backend/routes/orders.js
===================================================================
--- kupi-mk/backend/routes/orders.js	(revision 4facaa06d5f929f207596ff9d7aea93427f31064)
+++ kupi-mk/backend/routes/orders.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
@@ -3,4 +3,5 @@
 const { pool } = require('../config/database');
 const { auth } = require('../middleware/auth');
+const { createNotification } = require('./notifications');
 
 // =============================
@@ -43,5 +44,6 @@
                 p.price,
                 p.stock_quantity,
-                p.is_active
+                p.is_active,
+                p.seller_id
             FROM cart_items ci
             JOIN products p ON ci.product_id = p.id
@@ -101,5 +103,21 @@
         await client.query('DELETE FROM cart_items WHERE user_id = $1', [userId]);
         
-        await client.query('COMMIT');      //save everyrthing
+        await client.query('COMMIT');      //save everything
+        
+        // Create notifications for sellers (after commit so order exists)
+        const sellerIds = [...new Set(cartItems.map(item => item.seller_id))];
+        for (const sellerId of sellerIds) {
+            const sellerItems = cartItems.filter(item => item.seller_id === sellerId);
+            const sellerTotal = sellerItems.reduce((sum, item) => sum + (item.price * item.quantity), 0);
+            const itemCount = sellerItems.length;
+            
+            await createNotification(
+                sellerId,
+                'new_order',
+                'Нова нарачка!',
+                `Имате нова нарачка за ${itemCount} ${itemCount === 1 ? 'производ' : 'производи'} во вредност од ${sellerTotal.toFixed(2)} ден.`,
+                order.id
+            );
+        }
         
         res.json({
@@ -503,4 +521,22 @@
         );
         
+        // Create notification for buyer about status change
+        const statusMessages = {
+            'pending': 'Вашата нарачка е во очекување.',
+            'confirmed': 'Вашата нарачка е потврдена!',
+            'processing': 'Вашата нарачка се процесира.',
+            'shipped': 'Вашата нарачка е испратена!',
+            'delivered': 'Вашата нарачка е доставена!',
+            'cancelled': 'Вашата нарачка е откажана.'
+        };
+        
+        await createNotification(
+            currentOrder.user_id,
+            'order_status_change',
+            'Промена на статус на нарачка',
+            statusMessages[status] || `Статусот на вашата нарачка е променет на ${status}.`,
+            orderId
+        );
+        
         await client.query('COMMIT');
         
Index: kupi-mk/backend/server.js
===================================================================
--- kupi-mk/backend/server.js	(revision 4facaa06d5f929f207596ff9d7aea93427f31064)
+++ kupi-mk/backend/server.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
@@ -14,4 +14,6 @@
 const orderRoutes = require('./routes/orders');
 const reviewRoutes = require('./routes/reviews');
+const { router: notificationRoutes } = require('./routes/notifications');
+const favoritesRoutes = require('./routes/favorites');
 const { connectDB } = require('./config/database');
 
@@ -75,4 +77,6 @@
 app.use('/api/orders', orderRoutes);
 app.use('/api/reviews', reviewRoutes);
+app.use('/api/notifications', notificationRoutes);
+app.use('/api/favorites', favoritesRoutes);
 
 // Health check
Index: kupi-mk/database_updates_favorites.sql
===================================================================
--- kupi-mk/database_updates_favorites.sql	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
+++ kupi-mk/database_updates_favorites.sql	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
@@ -0,0 +1,12 @@
+-- Add favorites/wishlist table
+CREATE TABLE IF NOT EXISTS favorites (
+    id SERIAL PRIMARY KEY,
+    user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
+    product_id INTEGER NOT NULL REFERENCES products(id) ON DELETE CASCADE,
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    UNIQUE(user_id, product_id)
+);
+
+-- Create index for faster queries
+CREATE INDEX IF NOT EXISTS idx_favorites_user_id ON favorites(user_id);
+CREATE INDEX IF NOT EXISTS idx_favorites_product_id ON favorites(product_id);
Index: kupi-mk/database_updates_notifications.sql
===================================================================
--- kupi-mk/database_updates_notifications.sql	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
+++ kupi-mk/database_updates_notifications.sql	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
@@ -0,0 +1,20 @@
+-- Create notifications table
+CREATE TABLE IF NOT EXISTS notifications (
+  id SERIAL PRIMARY KEY,
+  user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
+  type VARCHAR(50) NOT NULL, -- 'new_order', 'order_status_change'
+  title VARCHAR(255) NOT NULL,
+  message TEXT NOT NULL,
+  order_id INTEGER REFERENCES orders(id) ON DELETE CASCADE,
+  is_read BOOLEAN DEFAULT FALSE,
+  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
+
+-- Create index for faster queries
+CREATE INDEX IF NOT EXISTS idx_notifications_user_id ON notifications(user_id);
+CREATE INDEX IF NOT EXISTS idx_notifications_is_read ON notifications(is_read);
+CREATE INDEX IF NOT EXISTS idx_notifications_created_at ON notifications(created_at DESC);
+
+-- Add notification preferences to users table (optional - for future)
+ALTER TABLE users ADD COLUMN IF NOT EXISTS email_notifications BOOLEAN DEFAULT TRUE;
+ALTER TABLE users ADD COLUMN IF NOT EXISTS push_notifications BOOLEAN DEFAULT TRUE;
Index: kupi-mk/frontend/src/App.js
===================================================================
--- kupi-mk/frontend/src/App.js	(revision 4facaa06d5f929f207596ff9d7aea93427f31064)
+++ kupi-mk/frontend/src/App.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
@@ -18,4 +18,5 @@
 import Orders from './pages/Orders';
 import SellerDashboard from './pages/SellerDashboard';
+import Favorites from './pages/Favorites';
 import ProtectedRoute from './components/ProtectedRoute';
 import SellerRoute from './components/SellerRoute';
@@ -77,4 +78,12 @@
                 />
                 <Route 
+                  path="/favorites" 
+                  element={
+                    <ProtectedRoute>
+                      <Favorites />
+                    </ProtectedRoute>
+                  } 
+                />
+                <Route 
                   path="/seller-dashboard" 
                   element={
Index: kupi-mk/frontend/src/components/Navbar.js
===================================================================
--- kupi-mk/frontend/src/components/Navbar.js	(revision 4facaa06d5f929f207596ff9d7aea93427f31064)
+++ kupi-mk/frontend/src/components/Navbar.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
@@ -4,4 +4,5 @@
 import CartIcon from './CartIcon';
 import CartSidebar from './CartSidebar';
+import NotificationBell from './NotificationBell';
 import logo from '../images/logo.jpg';
 
@@ -63,4 +64,7 @@
             {isAuthenticated() ? (
               <>
+                {/* Notifications Bell - only show when logged in */}
+                <NotificationBell />
+                
                 {/* Cart Icon - only show when logged in */}
                 <CartIcon onClick={() => setIsCartOpen(true)} />
@@ -105,4 +109,10 @@
                     >
                       Мои нарачки
+                    </Link>
+                    <Link
+                      to="/favorites"
+                      className="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100"
+                    >
+                      ❤️ Омилени
                     </Link>
                     {/* Seller Dashboard: only show for sellers */}
Index: kupi-mk/frontend/src/components/NotificationBell.js
===================================================================
--- kupi-mk/frontend/src/components/NotificationBell.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
+++ kupi-mk/frontend/src/components/NotificationBell.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
@@ -0,0 +1,348 @@
+import React, { useState, useEffect, useRef, useCallback } from 'react';
+import { useNavigate } from 'react-router-dom';
+import api from '../services/api';
+
+const NotificationBell = () => {
+  const [notifications, setNotifications] = useState([]);
+  const [unreadCount, setUnreadCount] = useState(0);
+  const [showDropdown, setShowDropdown] = useState(false);
+  const [loading, setLoading] = useState(false);
+  const navigate = useNavigate();
+  const lastNotificationIdRef = useRef(null); // Track last seen notification ID
+  const audioRef = useRef(null);
+  const isInitialLoadRef = useRef(true);
+
+  const requestNotificationPermission = async () => {
+    if ('Notification' in window && Notification.permission === 'default') {
+      const permission = await Notification.requestPermission();
+      console.log('Notification permission:', permission);
+    }
+  };
+
+  const playNotificationSound = useCallback(() => {
+    try {
+      console.log('🔊 Playing notification sound...');
+      if (audioRef.current) {
+        audioRef.current();
+        console.log('✅ Sound played successfully');
+      } else {
+        console.log('❌ Audio ref is null');
+      }
+    } catch (err) {
+      console.log('❌ Audio play failed:', err);
+    }
+  }, []);
+
+  const showBrowserNotification = useCallback((title, body) => {
+    console.log('🔔 Showing browser notification:', title, body);
+    if ('Notification' in window && Notification.permission === 'granted') {
+      const notification = new Notification(title, {
+        body: body,
+        icon: '/favicon.ico',
+        badge: '/favicon.ico',
+        tag: 'kupi-mk-notification',
+        requireInteraction: false
+      });
+
+      notification.onclick = () => {
+        window.focus();
+        notification.close();
+      };
+
+      // Auto close after 5 seconds
+      setTimeout(() => notification.close(), 5000);
+      console.log('✅ Browser notification shown');
+    } else {
+      console.log('❌ Notification permission not granted or not supported');
+    }
+  }, []);
+
+  const fetchUnreadCount = useCallback(async () => {
+    try {
+      // Fetch all unread notifications (not just count)
+      const response = await api.get('/notifications?unread=true');
+      const unreadNotifications = response.data;
+      const newCount = unreadNotifications.length;
+      
+      console.log('📊 Unread notifications:', newCount, 'Last ID:', lastNotificationIdRef.current, 'IsInitial:', isInitialLoadRef.current);
+      
+      // Skip notification on initial load
+      if (isInitialLoadRef.current) {
+        console.log('⏭️ Skipping initial load');
+        isInitialLoadRef.current = false;
+        if (unreadNotifications.length > 0) {
+          lastNotificationIdRef.current = unreadNotifications[0].id;
+        }
+        setUnreadCount(newCount);
+        return;
+      }
+      
+      // Check if there's a new notification (by comparing the latest notification ID)
+      if (unreadNotifications.length > 0) {
+        const latestNotification = unreadNotifications[0];
+        
+        if (lastNotificationIdRef.current !== null && latestNotification.id !== lastNotificationIdRef.current) {
+          console.log('🆕 New notification detected! ID:', latestNotification.id, 'Previous ID:', lastNotificationIdRef.current);
+          playNotificationSound();
+          showBrowserNotification(
+            latestNotification.title,
+            latestNotification.message
+          );
+        }
+        
+        lastNotificationIdRef.current = latestNotification.id;
+      }
+      
+      setUnreadCount(newCount);
+    } catch (error) {
+      console.error('Error fetching unread notifications:', error);
+    }
+  }, [playNotificationSound, showBrowserNotification]);
+
+  useEffect(() => {
+    console.log('🚀 NotificationBell mounted');
+    
+    // Request notification permission on mount
+    requestNotificationPermission();
+    
+    // Create audio context and oscillator for notification sound (better browser compatibility)
+    const createNotificationSound = () => {
+      const audioContext = new (window.AudioContext || window.webkitAudioContext)();
+      return () => {
+        const oscillator = audioContext.createOscillator();
+        const gainNode = audioContext.createGain();
+        
+        oscillator.connect(gainNode);
+        gainNode.connect(audioContext.destination);
+        
+        oscillator.frequency.value = 800; // Frequency in Hz
+        oscillator.type = 'sine';
+        
+        gainNode.gain.setValueAtTime(0.3, audioContext.currentTime);
+        gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.5);
+        
+        oscillator.start(audioContext.currentTime);
+        oscillator.stop(audioContext.currentTime + 0.5);
+      };
+    };
+    
+    try {
+      audioRef.current = createNotificationSound();
+      console.log('✅ Audio context created');
+    } catch (err) {
+      console.log('❌ Audio context not supported:', err);
+    }
+    
+    fetchUnreadCount();
+    // Poll for new notifications every 30 seconds
+    const interval = setInterval(fetchUnreadCount, 30000);
+    return () => {
+      console.log('🛑 NotificationBell unmounted');
+      clearInterval(interval);
+    };
+  }, [fetchUnreadCount]);
+
+  const fetchNotifications = async () => {
+    try {
+      setLoading(true);
+      const response = await api.get('/notifications');
+      setNotifications(response.data);
+    } catch (error) {
+      console.error('Error fetching notifications:', error);
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  const handleBellClick = () => {
+    setShowDropdown(!showDropdown);
+    if (!showDropdown) {
+      fetchNotifications();
+    }
+  };
+
+  const handleNotificationClick = async (notification) => {
+    try {
+      // Mark as read
+      await api.patch(`/notifications/${notification.id}/read`);
+      
+      // Update local state
+      setNotifications(notifications.map(n => 
+        n.id === notification.id ? { ...n, is_read: true } : n
+      ));
+      setUnreadCount(prev => Math.max(0, prev - 1));
+      
+      // Navigate to order details if it's an order notification
+      if (notification.order_id) {
+        navigate(`/orders/${notification.order_id}`);
+      }
+      
+      setShowDropdown(false);
+    } catch (error) {
+      console.error('Error marking notification as read:', error);
+    }
+  };
+
+  const handleMarkAllRead = async () => {
+    try {
+      await api.patch('/notifications/read-all');
+      setNotifications(notifications.map(n => ({ ...n, is_read: true })));
+      setUnreadCount(0);
+    } catch (error) {
+      console.error('Error marking all as read:', error);
+    }
+  };
+
+  const handleDelete = async (e, notificationId) => {
+    e.stopPropagation();
+    try {
+      await api.delete(`/notifications/${notificationId}`);
+      setNotifications(notifications.filter(n => n.id !== notificationId));
+      fetchUnreadCount();
+    } catch (error) {
+      console.error('Error deleting notification:', error);
+    }
+  };
+
+  const formatTimeAgo = (dateString) => {
+    const date = new Date(dateString);
+    const now = new Date();
+    const seconds = Math.floor((now - date) / 1000);
+
+    if (seconds < 60) return 'пред неколку секунди';
+    if (seconds < 3600) return `пред ${Math.floor(seconds / 60)} минути`;
+    if (seconds < 86400) return `пред ${Math.floor(seconds / 3600)} часа`;
+    if (seconds < 604800) return `пред ${Math.floor(seconds / 86400)} дена`;
+    return date.toLocaleDateString('mk-MK');
+  };
+
+  return (
+    <div className="relative">
+      {/* Bell Icon */}
+      <button
+        onClick={handleBellClick}
+        className="relative p-2 text-gray-600 hover:text-gray-900 focus:outline-none"
+      >
+        <svg
+          className="w-6 h-6"
+          fill="none"
+          stroke="currentColor"
+          viewBox="0 0 24 24"
+        >
+          <path
+            strokeLinecap="round"
+            strokeLinejoin="round"
+            strokeWidth={2}
+            d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"
+          />
+        </svg>
+        {unreadCount > 0 && (
+          <span className="absolute top-0 right-0 inline-flex items-center justify-center px-2 py-1 text-xs font-bold leading-none text-white transform translate-x-1/2 -translate-y-1/2 bg-red-600 rounded-full">
+            {unreadCount > 9 ? '9+' : unreadCount}
+          </span>
+        )}
+      </button>
+
+      {/* Dropdown */}
+      {showDropdown && (
+        <>
+          <div
+            className="fixed inset-0 z-10"
+            onClick={() => setShowDropdown(false)}
+          ></div>
+          <div className="absolute right-0 mt-2 w-80 bg-white rounded-lg shadow-lg z-20 max-h-96 overflow-y-auto">
+            {/* Header */}
+            <div className="p-4 border-b border-gray-200 flex justify-between items-center">
+              <h3 className="text-lg font-semibold text-gray-900">
+                Известувања
+              </h3>
+              {unreadCount > 0 && (
+                <button
+                  onClick={handleMarkAllRead}
+                  className="text-sm text-primary-600 hover:text-primary-700"
+                >
+                  Označи сè како прочитано
+                </button>
+              )}
+            </div>
+
+            {/* Notifications List */}
+            <div className="divide-y divide-gray-200">
+              {loading ? (
+                <div className="p-4 text-center text-gray-500">
+                  Се вчитува...
+                </div>
+              ) : notifications.length === 0 ? (
+                <div className="p-4 text-center text-gray-500">
+                  Немате известувања
+                </div>
+              ) : (
+                notifications.map((notification) => (
+                  <div
+                    key={notification.id}
+                    onClick={() => handleNotificationClick(notification)}
+                    className={`p-4 hover:bg-gray-50 cursor-pointer transition-colors ${
+                      !notification.is_read ? 'bg-blue-50' : ''
+                    }`}
+                  >
+                    <div className="flex justify-between items-start">
+                      <div className="flex-1">
+                        <p className="text-sm font-medium text-gray-900">
+                          {notification.title}
+                        </p>
+                        <p className="text-sm text-gray-600 mt-1">
+                          {notification.message}
+                        </p>
+                        <p className="text-xs text-gray-400 mt-2">
+                          {formatTimeAgo(notification.created_at)}
+                        </p>
+                      </div>
+                      <button
+                        onClick={(e) => handleDelete(e, notification.id)}
+                        className="ml-2 text-gray-400 hover:text-red-600"
+                      >
+                        <svg
+                          className="w-4 h-4"
+                          fill="none"
+                          stroke="currentColor"
+                          viewBox="0 0 24 24"
+                        >
+                          <path
+                            strokeLinecap="round"
+                            strokeLinejoin="round"
+                            strokeWidth={2}
+                            d="M6 18L18 6M6 6l12 12"
+                          />
+                        </svg>
+                      </button>
+                    </div>
+                    {!notification.is_read && (
+                      <div className="absolute left-2 top-1/2 transform -translate-y-1/2 w-2 h-2 bg-blue-600 rounded-full"></div>
+                    )}
+                  </div>
+                ))
+              )}
+            </div>
+
+            {/* Footer */}
+            {notifications.length > 0 && (
+              <div className="p-2 border-t border-gray-200">
+                <button
+                  onClick={() => {
+                    navigate('/notifications');
+                    setShowDropdown(false);
+                  }}
+                  className="w-full text-center text-sm text-primary-600 hover:text-primary-700 py-2"
+                >
+                  Види сè
+                </button>
+              </div>
+            )}
+          </div>
+        </>
+      )}
+    </div>
+  );
+};
+
+export default NotificationBell;
Index: kupi-mk/frontend/src/components/ProductCard.js
===================================================================
--- kupi-mk/frontend/src/components/ProductCard.js	(revision 4facaa06d5f929f207596ff9d7aea93427f31064)
+++ kupi-mk/frontend/src/components/ProductCard.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
@@ -1,13 +1,61 @@
-import React, { useState } from 'react';
+import React, { useState, useEffect, useCallback } from 'react';
 import { Link, useNavigate } from 'react-router-dom';
 import { useAuth } from '../context/AuthContext';
 import { useCart } from '../context/CartContext';
 import StarRating from './StarRating';
-
-const ProductCard = ({ product }) => {
+import api from '../services/api';
+
+const ProductCard = ({ product, onRemoveFavorite }) => {
   const navigate = useNavigate();
   const { isAuthenticated } = useAuth();
   const { addToCart } = useCart();
   const [isAddingToCart, setIsAddingToCart] = useState(false);
+  const [isFavorited, setIsFavorited] = useState(false);
+  const [favLoading, setFavLoading] = useState(false);
+
+  const checkFavoriteStatus = useCallback(async () => {
+    if (!isAuthenticated() || !product.id) return;
+    
+    try {
+      const response = await api.get(`/favorites/check/${product.id}`);
+      setIsFavorited(response.data.isFavorited);
+    } catch (error) {
+      console.error('Error checking favorite status:', error);
+    }
+  }, [isAuthenticated, product.id]);
+
+  useEffect(() => {
+    checkFavoriteStatus();
+  }, [checkFavoriteStatus]);
+
+  const handleToggleFavorite = async (e) => {
+    e.preventDefault();
+    e.stopPropagation();
+    
+    if (!isAuthenticated()) {
+      navigate('/login');
+      return;
+    }
+
+    setFavLoading(true);
+    try {
+      if (isFavorited) {
+        await api.delete(`/favorites/${product.id}`);
+        setIsFavorited(false);
+        // If onRemoveFavorite callback exists (from Favorites page), call it
+        if (onRemoveFavorite) {
+          onRemoveFavorite(product.id);
+        }
+      } else {
+        await api.post(`/favorites/${product.id}`);
+        setIsFavorited(true);
+      }
+    } catch (error) {
+      console.error('Error toggling favorite:', error);
+      alert('Грешка при промена на омилени');
+    } finally {
+      setFavLoading(false);
+    }
+  };
   
   const getImageUrl = (imagePath) => {
@@ -62,5 +110,27 @@
 
   return (
-    <div className="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow duration-300 group">
+    <div className="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow duration-300 group relative">
+      {/* Favorite Button - Top Right Corner */}
+      <button
+        onClick={handleToggleFavorite}
+        disabled={favLoading}
+        className="absolute top-2 right-2 z-10 bg-white rounded-full p-2 shadow-md hover:bg-gray-100 transition-colors"
+        title={isFavorited ? 'Отстрани од омилени' : 'Додај во омилени'}
+      >
+        <svg
+          className={`w-6 h-6 ${isFavorited ? 'text-red-500 fill-current' : 'text-gray-400'} ${favLoading ? 'opacity-50' : ''}`}
+          fill={isFavorited ? 'currentColor' : 'none'}
+          stroke="currentColor"
+          strokeWidth="2"
+          viewBox="0 0 24 24"
+        >
+          <path
+            strokeLinecap="round"
+            strokeLinejoin="round"
+            d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
+          />
+        </svg>
+      </button>
+
       {/* Product Image and Info - Clickable Link */}
       <Link to={`/product/${product.id}`} className="block">
Index: kupi-mk/frontend/src/pages/Favorites.js
===================================================================
--- kupi-mk/frontend/src/pages/Favorites.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
+++ kupi-mk/frontend/src/pages/Favorites.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
@@ -0,0 +1,96 @@
+import React, { useState, useEffect } from 'react';
+import { Link } from 'react-router-dom';
+import api from '../services/api';
+import ProductCard from '../components/ProductCard';
+
+const Favorites = () => {
+  const [favorites, setFavorites] = useState([]);
+  const [loading, setLoading] = useState(true);
+
+  useEffect(() => {
+    fetchFavorites();
+  }, []);
+
+  const fetchFavorites = async () => {
+    try {
+      setLoading(true);
+      const response = await api.get('/favorites');
+      setFavorites(response.data);
+    } catch (error) {
+      console.error('Error fetching favorites:', error);
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  const handleRemoveFavorite = async (productId) => {
+    try {
+      await api.delete(`/favorites/${productId}`);
+      // Remove from local state
+      setFavorites(favorites.filter(fav => fav.id !== productId));
+    } catch (error) {
+      console.error('Error removing favorite:', error);
+      alert('Грешка при отстранување од омилени');
+    }
+  };
+
+  if (loading) {
+    return (
+      <div className="flex justify-center items-center min-h-screen">
+        <div className="text-xl text-gray-600">Се вчитува...</div>
+      </div>
+    );
+  }
+
+  return (
+    <div className="container mx-auto px-4 py-8">
+      <div className="flex justify-between items-center mb-8">
+        <h1 className="text-3xl font-bold text-gray-900">
+          Омилени производи
+        </h1>
+        <span className="text-gray-600">
+          {favorites.length} {favorites.length === 1 ? 'производ' : 'производи'}
+        </span>
+      </div>
+
+      {favorites.length === 0 ? (
+        <div className="text-center py-16">
+          <svg
+            className="mx-auto h-24 w-24 text-gray-400 mb-4"
+            fill="none"
+            stroke="currentColor"
+            viewBox="0 0 24 24"
+          >
+            <path
+              strokeLinecap="round"
+              strokeLinejoin="round"
+              strokeWidth={2}
+              d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
+            />
+          </svg>
+          <p className="text-xl text-gray-600 mb-4">
+            Немате омилени производи
+          </p>
+          <Link
+            to="/"
+            className="text-primary-600 hover:text-primary-700 font-medium"
+          >
+            Прелистајте производи →
+          </Link>
+        </div>
+      ) : (
+        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
+          {favorites.map((product) => (
+            <ProductCard 
+              key={product.id} 
+              product={product} 
+              onRemoveFavorite={handleRemoveFavorite}
+            />
+          ))}
+        </div>
+      )}
+    </div>
+  );
+};
+
+export default Favorites;
Index: kupi-mk/frontend/src/pages/ProductDetail.js
===================================================================
--- kupi-mk/frontend/src/pages/ProductDetail.js	(revision 4facaa06d5f929f207596ff9d7aea93427f31064)
+++ kupi-mk/frontend/src/pages/ProductDetail.js	(revision bf1ffc3db5dee87bce3d1eb06634e8f68b6012d9)
@@ -26,4 +26,6 @@
   const [averageRating, setAverageRating] = useState(0);
   const [totalReviews, setTotalReviews] = useState(0);
+  const [isFavorited, setIsFavorited] = useState(false);
+  const [favLoading, setFavLoading] = useState(false);
 
   const copyProductLink = () => {
@@ -92,4 +94,38 @@
   };
 
+  const handleToggleFavorite = async () => {
+    if (!isAuthenticated()) {
+      navigate('/login');
+      return;
+    }
+
+    setFavLoading(true);
+    try {
+      if (isFavorited) {
+        await api.delete(`/favorites/${id}`);
+        setIsFavorited(false);
+      } else {
+        await api.post(`/favorites/${id}`);
+        setIsFavorited(true);
+      }
+    } catch (error) {
+      console.error('Error toggling favorite:', error);
+      alert('Грешка при промена на омилени');
+    } finally {
+      setFavLoading(false);
+    }
+  };
+
+  const checkFavoriteStatus = useCallback(async () => {
+    if (!isAuthenticated() || !id) return;
+    
+    try {
+      const response = await api.get(`/favorites/check/${id}`);
+      setIsFavorited(response.data.isFavorited);
+    } catch (error) {
+      console.error('Error checking favorite status:', error);
+    }
+  }, [isAuthenticated, id]);
+
   const handleQuantityChange = (newQuantity) => {
     if (newQuantity >= 1 && newQuantity <= (product?.stock_quantity || 0)) {
@@ -151,5 +187,6 @@
     loadProduct();
     fetchReviews();
-  }, [id, fetchProduct, fetchReviews]);
+    checkFavoriteStatus();
+  }, [id, fetchProduct, fetchReviews, checkFavoriteStatus]);
 
   if (loading) {
@@ -218,7 +255,31 @@
           <div className="space-y-6">
             <div>
-              <h1 className="text-3xl font-bold text-gray-900 mb-2">
-                {product.title}
-              </h1>
+              <div className="flex justify-between items-start mb-2">
+                <h1 className="text-3xl font-bold text-gray-900 flex-1">
+                  {product.title}
+                </h1>
+                
+                {/* Add to Favorites Button */}
+                <button
+                  onClick={handleToggleFavorite}
+                  disabled={favLoading}
+                  className="ml-4 p-2 rounded-full hover:bg-gray-100 transition-colors"
+                  title={isFavorited ? 'Отстрани од омилени' : 'Додај во омилени'}
+                >
+                  <svg
+                    className={`w-8 h-8 ${isFavorited ? 'text-red-500 fill-current' : 'text-gray-400'} ${favLoading ? 'opacity-50' : ''}`}
+                    fill={isFavorited ? 'currentColor' : 'none'}
+                    stroke="currentColor"
+                    strokeWidth="2"
+                    viewBox="0 0 24 24"
+                  >
+                    <path
+                      strokeLinecap="round"
+                      strokeLinejoin="round"
+                      d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
+                    />
+                  </svg>
+                </button>
+              </div>
               
               <div className="flex items-center space-x-4 text-sm text-gray-600 mb-4">
