Index: c/main/java/com/zinemasterapp/zinemasterapp/controller/DevNotifyController.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/controller/DevNotifyController.java	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ 	(revision )
@@ -1,45 +1,0 @@
-package com.zinemasterapp.zinemasterapp.controller;
-
-import com.zinemasterapp.zinemasterapp.dto.Notificationdto;
-import com.zinemasterapp.zinemasterapp.dto.UserDTO;
-import com.zinemasterapp.zinemasterapp.repository.UserRepository;
-import com.zinemasterapp.zinemasterapp.service.RequestNotificationService;
-import org.springframework.context.annotation.Profile;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.time.Instant;
-import java.util.Map;
-import java.util.UUID;
-
-//samo za DEMO(proba dali rabotat notifikaciite ako e nekoj online) -> vo krajniot sistem nema da ima vakvo kopce
-@RestController
-@RequestMapping("/api/dev")//pocetok na url
-public class DevNotifyController {
-
-    private final RequestNotificationService notifier;//servis za prakjanje notifikacii
-
-    public DevNotifyController(RequestNotificationService notifier) {
-        this.notifier = notifier;
-    }
-
-    @PostMapping("/ping-admins")
-    public ResponseEntity<Void> pingAdmins(@AuthenticationPrincipal org.springframework.security.core.userdetails.User me) {//samo vrakja http status
-        var payload = new Notificationdto(
-                "TEST-" + UUID.randomUUID().toString().substring(0,8).toUpperCase(),
-                me.getUsername(),
-                Instant.now(),
-                1,
-                "Test notification from " + me.getUsername(),
-                "REQUEST_CREATED"
-        );
-        notifier.notifyAdmins(payload);
-        return ResponseEntity.noContent().build();
-    }
-}
-
Index: src/main/java/com/zinemasterapp/zinemasterapp/controller/ForecastController.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/controller/ForecastController.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
+++ src/main/java/com/zinemasterapp/zinemasterapp/controller/ForecastController.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -0,0 +1,21 @@
+package com.zinemasterapp.zinemasterapp.controller;
+
+import com.zinemasterapp.zinemasterapp.service.ProductForecastAppService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.zinemasterapp.zinemasterapp.service.StockForecastService.Result;
+
+@RestController
+@RequiredArgsConstructor
+public class ForecastController {
+
+    private final ProductForecastAppService app;
+
+    @GetMapping("/api/products/{id}/forecast")
+    public Result forecast(@PathVariable String id) {
+        return app.forecastForProduct(id);
+    }
+}
Index: src/main/java/com/zinemasterapp/zinemasterapp/controller/UserController.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/controller/UserController.java	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ src/main/java/com/zinemasterapp/zinemasterapp/controller/UserController.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -31,4 +31,5 @@
         this.userRepository = userRepository;
     }
+
 
     @PutMapping("/{id}/profile-pic")//sakame da smenime profilna i mora da e PUT bidejki POST ne e idempotentno
Index: src/main/java/com/zinemasterapp/zinemasterapp/controller/UserCounterController.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/controller/UserCounterController.java	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ src/main/java/com/zinemasterapp/zinemasterapp/controller/UserCounterController.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -12,6 +12,6 @@
 @RestController
 @RequestMapping("/api/users")
-@RequiredArgsConstructor
-public class UserCounterController {
+@RequiredArgsConstructor//ova e za da ne e potreben konstruktor
+public class UserCounterController {//isto ova moze i vo usercontroller, vaka e po pregledno
     private final UserRepository users;
     private final NotificationCounterService counters;
Index: src/main/java/com/zinemasterapp/zinemasterapp/model/Product.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/model/Product.java	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ src/main/java/com/zinemasterapp/zinemasterapp/model/Product.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -4,4 +4,5 @@
 import jakarta.persistence.*;
 
+import java.time.Instant;
 import java.util.HashSet;
 import java.util.Set;
@@ -38,4 +39,22 @@
     @Column(nullable = false,name = "accessable")
     private boolean accessable = true;
+
+    @Column(name = "added_at", nullable = false)
+    private Instant addedAt;
+
+    @PrePersist
+    public void onCreate() {
+        if (addedAt == null) {
+            addedAt = Instant.now();
+        }
+    }
+
+    public Instant getAddedAt() {
+        return addedAt;
+    }
+
+    public void setAddedAt(Instant addedAt) {
+        this.addedAt = addedAt;
+    }
 
     public boolean isAccessable() {
Index: src/main/java/com/zinemasterapp/zinemasterapp/model/ProductRequestItem.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/model/ProductRequestItem.java	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ src/main/java/com/zinemasterapp/zinemasterapp/model/ProductRequestItem.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -4,4 +4,6 @@
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import jakarta.persistence.*;
+
+import java.time.Instant;
 
 @Entity
@@ -23,4 +25,22 @@
     @JsonIgnore//za da ne e vo beskonecen ciklus
     private ProductRequest request;
+
+    @Column(name = "reserved_at", nullable = false, updatable = false)
+    private Instant reservedAt;
+
+    @PrePersist
+    public void onCreate() {
+        if (reservedAt == null) {
+            reservedAt = Instant.now();
+        }
+    }
+
+    public Instant getReservedAt() {
+        return reservedAt;
+    }
+
+    public void setReservedAt(Instant reservedAt) {
+        this.reservedAt = reservedAt;
+    }
 
     public Product getProduct() {
Index: src/main/java/com/zinemasterapp/zinemasterapp/projections/DailyQty.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/projections/DailyQty.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
+++ src/main/java/com/zinemasterapp/zinemasterapp/projections/DailyQty.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -0,0 +1,8 @@
+package com.zinemasterapp.zinemasterapp.projections;
+
+import java.time.LocalDate;
+
+public interface DailyQty {
+    LocalDate getDay();
+    Integer getQty();
+}
Index: src/main/java/com/zinemasterapp/zinemasterapp/repository/ProductRequestItemRepository.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/repository/ProductRequestItemRepository.java	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ src/main/java/com/zinemasterapp/zinemasterapp/repository/ProductRequestItemRepository.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -3,5 +3,8 @@
 import com.zinemasterapp.zinemasterapp.dto.ProductRequestItemDTO;
 import com.zinemasterapp.zinemasterapp.model.ProductRequestItem;
+import com.zinemasterapp.zinemasterapp.projections.DailyQty;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
 
 import java.util.List;
@@ -10,3 +13,35 @@
     List<ProductRequestItem> findByRequestId(String requestId);
     List<ProductRequestItem> findByProductId(String productId);
+
+    @Query(value = """
+  WITH bounds AS (
+    SELECT p.id AS product_id,
+           CAST(p.added_at AS date) AS start_day
+    FROM products p
+    WHERE p.id = :productId
+  ),
+  days AS (
+    SELECT CAST(
+             generate_series(
+               (SELECT start_day FROM bounds),
+               CURRENT_DATE,
+               interval '1 day'
+             )
+           AS date) AS day
+  ),
+  daily AS (
+    SELECT d.day,
+           COALESCE(SUM(i.quantity_requested), 0) AS qty
+    FROM days d
+    LEFT JOIN product_request_items i
+      ON i.product_id = (SELECT product_id FROM bounds)
+     AND CAST(i.reserved_at AS date) = d.day
+    GROUP BY d.day
+    ORDER BY d.day
+  )
+  SELECT day, qty FROM daily
+  """, nativeQuery = true)
+    List<DailyQty> findDailyByProduct(@Param("productId") String productId);
+
+
 }
Index: src/main/java/com/zinemasterapp/zinemasterapp/repository/UserRepository.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/repository/UserRepository.java	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ src/main/java/com/zinemasterapp/zinemasterapp/repository/UserRepository.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -59,5 +59,5 @@
     Integer getRequestsProcessed(@Param("id") String id);
 
-    @Modifying
+    @Modifying(clearAutomatically = true, flushAutomatically = true)
     @Query("""
          update User u
@@ -66,5 +66,5 @@
           where u.username = :username
          """)
-    int transferPendingToUnread(@Param("username") String username);
+    void transferPendingToUnread(@Param("username") String username);
 
     @Modifying
Index: src/main/java/com/zinemasterapp/zinemasterapp/security/SecurityConfig.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/security/SecurityConfig.java	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ src/main/java/com/zinemasterapp/zinemasterapp/security/SecurityConfig.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -16,4 +16,7 @@
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.oauth2.client.web.DefaultOAuth2AuthorizationRequestResolver;
+import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestResolver;
+import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@@ -22,5 +25,8 @@
 import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
 
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+
 //za bezbednost e ova
 @Configuration
Index: src/main/java/com/zinemasterapp/zinemasterapp/service/EmailDigestScheduler.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/service/EmailDigestScheduler.java	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ src/main/java/com/zinemasterapp/zinemasterapp/service/EmailDigestScheduler.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -22,5 +22,5 @@
     }
 
-    @Scheduled(cron = "0 0 8-18 * * * ")
+    @Scheduled(cron = " 0 0 8-18 * * *")
     @Transactional
     public void sendDigestEmails() {
@@ -32,21 +32,26 @@
 
             String subject = "[ZineMaster] "+ count +" New Requests";
-            String body = "Hello"+admin.getUsername()+",\n\nYou have " + count + " new request"
+            String body = "Hello "+admin.getUsername()+",\n\nYou have " + count + " new request"
                     + (count == 1 ? "" : "s") + " since the last digest. You are receiving this e-mail because you are offline.\n\n"
-                    + "-ZineMaster";
+                    + "— ZineMaster";
 
             emailService.sendEmail(admin.getEmail(), subject, body);
-
+            System.out.println(userRepository.getUnread(admin.getId())+" one ");
+            userRepository.transferPendingToUnread(admin.getUsername());
+            notificationCounterService.transferPendingToUnread(admin.getUsername());
+            System.out.println(userRepository.getUnread(admin.getId())+ "two");
             admin.setPendingEmailCount(0);
             notificationCounterService.resetPending(admin.getId());
-            userRepository.save(admin);
+         //   userRepository.save(admin);
         }
     }
 
 
-    @Scheduled(cron = "0 0 8-18 * * * ")
+    @Scheduled(cron = "0 0 8-18 * * *")
+    @Transactional
     public void sendProcessedDigests() {
         for (var user : userRepository.findAll()) {
             int n = notificationUpdateHelper.getProcessedCount(user.getId());
+            System.out.println(n + " processed " + user.getUsername());
             if (n <= 0) continue;
 
@@ -58,5 +63,9 @@
 
             emailService.sendEmail(user.getEmail(), subject, body);
+
+            userRepository.transferProcessedToUnseen(user.getId());
+
             userRepository.resetProccessedRequests(user.getId());
+
         }
     }
Index: src/main/java/com/zinemasterapp/zinemasterapp/service/MakerStatusNotifyListener.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/service/MakerStatusNotifyListener.java	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ src/main/java/com/zinemasterapp/zinemasterapp/service/MakerStatusNotifyListener.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -26,36 +26,36 @@
 
 
-    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
-    public void onStatusChangedone(RequestStatusChangedEvent e) {
-        String maker = e.getMakerUsername();
-        String makerId = e.getMakerId();
-        System.out.println("Listener something");
-
-        var payload = Map.of(
-                "type", "STATUS_CHANGED",
-                "requestId", e.getRequestId(),
-                "newStatus", e.getNewStatus(),
-                "decidedBy", e.getDecidedBy(),
-                "changedAt", e.getChangedAt().toString(),
-                "summary", "Request " + e.getRequestId() + " → " + e.getNewStatus()
-        );
-
-
-
-        if (!presence.isOnline(maker)) {
-            //notification.incrementProcessedRequestsByUserId(makerId);
-            notificationCounterService.bumpOffline(makerId);
-        }else{
-            notificationCounterService.bumpUnseen(makerId);
-        }
-
-    System.out.println("ITS KINDA WORKING");
-
-        messaging.convertAndSendToUser(maker, "/queue/status", payload);
-        System.out.println("Listener");
-        System.out.println("LISTENER IS WORKING");
-
-
-    }
+//    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
+//    public void onStatusChangedone(RequestStatusChangedEvent e) {
+//        String maker = e.getMakerUsername();
+//        String makerId = e.getMakerId();
+//        System.out.println("Listener something");
+//
+//        var payload = Map.of(
+//                "type", "STATUS_CHANGED",
+//                "requestId", e.getRequestId(),
+//                "newStatus", e.getNewStatus(),
+//                "decidedBy", e.getDecidedBy(),
+//                "changedAt", e.getChangedAt().toString(),
+//                "summary", "Request " + e.getRequestId() + " → " + e.getNewStatus()
+//        );
+//
+//
+//
+//        if (!presence.isOnline(maker)) {
+//            //notification.incrementProcessedRequestsByUserId(makerId);
+//            notificationCounterService.bumpOffline(makerId);
+//        }else{
+//            notificationCounterService.bumpUnseen(makerId);
+//        }
+//
+//    System.out.println("ITS KINDA WORKING");
+//
+//        messaging.convertAndSendToUser(maker, "/queue/status", payload);
+//        System.out.println("Listener");
+//        System.out.println("LISTENER IS WORKING");
+//
+//
+//    }
 
 
Index: src/main/java/com/zinemasterapp/zinemasterapp/service/ProductForecastAppService.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/service/ProductForecastAppService.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
+++ src/main/java/com/zinemasterapp/zinemasterapp/service/ProductForecastAppService.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -0,0 +1,43 @@
+package com.zinemasterapp.zinemasterapp.service;
+
+
+import com.zinemasterapp.zinemasterapp.projections.DailyQty;
+import com.zinemasterapp.zinemasterapp.repository.ProductRepository;
+import com.zinemasterapp.zinemasterapp.repository.ProductRequestItemRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.time.ZoneOffset;
+import java.util.*;
+
+@Service
+@RequiredArgsConstructor
+public class ProductForecastAppService {
+
+    private final ProductRepository productRepo;
+    private final ProductRequestItemRepository priRepo;
+    private final StockForecastService forecast;
+
+    public StockForecastService.Result forecastForProduct(String productId) {
+        var p = productRepo.findById(productId).orElseThrow();
+
+
+        List<DailyQty> grouped = priRepo.findDailyByProduct(productId);
+
+
+        LocalDate start = p.getAddedAt().atZone(ZoneOffset.UTC).toLocalDate();
+        LocalDate end = LocalDate.now();
+
+        Map<LocalDate, Integer> map = new HashMap<>();
+        for (var g : grouped) map.put(g.getDay(), g.getQty());
+
+        var series = new ArrayList<StockForecastService.Daily>();
+        for (LocalDate d = start; !d.isAfter(end); d = d.plusDays(1)) {
+            series.add(new StockForecastService.Daily(d, map.getOrDefault(d, 0)));
+        }
+
+        int onHand = Optional.ofNullable(p.getQuantity()).orElse(0);//kolku ima ostanato
+        return forecast.forecast(productId, onHand, series);
+    }
+}
Index: src/main/java/com/zinemasterapp/zinemasterapp/service/RequestNotificationService.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/service/RequestNotificationService.java	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ src/main/java/com/zinemasterapp/zinemasterapp/service/RequestNotificationService.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -10,4 +10,5 @@
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 @Service
@@ -36,4 +37,6 @@
         for (String adminUsername : presence.getOnlineUsers()) {
             //if (adminUsername.equalsIgnoreCase(actorUsername)) continue;
+            User u = userRepository.findByUsername(adminUsername).orElse(null);
+            if (Objects.equals(u.getUserType(), "ProductAdministrator")){
             try {
                 notificationCounterService.increment(null, adminUsername);
@@ -44,4 +47,6 @@
 
             messaging.convertAndSendToUser(adminUsername, "/queue/requests", payload);
+            }
+
 
         }
Index: src/main/java/com/zinemasterapp/zinemasterapp/service/StockForecastService.java
===================================================================
--- src/main/java/com/zinemasterapp/zinemasterapp/service/StockForecastService.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
+++ src/main/java/com/zinemasterapp/zinemasterapp/service/StockForecastService.java	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -0,0 +1,65 @@
+package com.zinemasterapp.zinemasterapp.service;
+
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class StockForecastService {
+
+    private static final double RECENT_BOOST = 3.0;//povekje vredat poslednite tri dena
+    private static final double EPS = 0.1;//da ne delam so 0
+    private static final double MIN_BASE_RATE = 0.3;//najmalce sto moze(za na pr ako mn malce dena e ili nema nikoj poracano)
+
+    public record Daily(LocalDate day, int qty) {}
+    public record Result(
+            String productId,
+            double forecastPerDay,
+            double daysToStockout,
+            LocalDate predictedOutDate,
+            boolean redWarning
+    ) {}
+    //record se za prefrluvanje data, ne treba constructor,klasa poednostavna e
+
+    public Result forecast(String productId, int onHandQty, List<Daily> history) {
+
+        int n = history.size();//kolku dena go ima produktot
+        double xw = 0, wsum = 0;
+
+        for (int i = 0; i < n; i++) {
+            int q = history.get(i).qty();//zemame kolku se
+            double w = (n - i <= 3) ? RECENT_BOOST : 1.0;//dali se vo poslednite tri dena
+            xw += q * w;
+            wsum += w;
+        }
+
+        double rate = (wsum > 0 ? xw / wsum : 0.0);
+
+        if (n < 3) {
+            double avg = history.stream().mapToInt(Daily::qty).average().orElse(0.0);
+            rate = Math.max(rate, Math.max(avg, MIN_BASE_RATE));
+        } else if (rate < EPS) {
+            rate = Math.max(rate, MIN_BASE_RATE);
+        }
+
+        double days = (onHandQty <= 0) ? 0.0 : onHandQty / Math.max(rate, EPS);
+        LocalDate outDate = LocalDate.now().plusDays((long)Math.ceil(days));
+        boolean red = days < 5.0;
+
+        return new Result(
+                productId,
+                round2(rate),
+                round2(days),
+                outDate,
+                red
+        );
+    }
+
+    private static double round2(double x) {
+        return Math.round(x * 100.0) / 100.0;
+    }
+}
Index: zinemaster-frontend/src/components/AllRequests.vue
===================================================================
--- zinemaster-frontend/src/components/AllRequests.vue	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ zinemaster-frontend/src/components/AllRequests.vue	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -12,5 +12,5 @@
           <img :src="userProfileImage" alt="Profile" class="rounded-circle me-2 " style="width: 35px; height: 35px; object-fit: cover; border: 2px solid white; cursor: pointer;"/>
         </router-link>
-        <StatusBell v-if="user.userType === 'Worker'" />
+        <StatusBell  />
         <router-link v-if="user.userType === 'UserAdministrator'" to="/manage-users" class="btn btn-outline-warning btn-sm me-2">
           Управувај со корисници
@@ -57,4 +57,10 @@
         <option v-for="u in uniqueUsers" :key="u" :value="u">{{ u }}</option>
       </select>
+      <!--Site osvem toj sto go klikam-->
+      <div class="form-check mt-2">
+        <input class="form-check-input" type="checkbox" id="excludeUser" v-model="excludeUser">
+        <label class="form-check-label" for="excludeUser">Без овој корисник</label>
+      </div>
+
     </div>
 
@@ -119,4 +125,5 @@
         </div>
       </div>
+
     </div>
   </div>
@@ -152,4 +159,5 @@
 const dateFilterType = ref('from');
 const selectedUser = ref('all');
+const excludeUser = ref(false);//ako go trgame
 const uniqueUsers = computed(() => {
   const users = allRequests.value.map(r => r.username);
@@ -162,4 +170,6 @@
 
 const { startLiveAcknowledge, stopLiveAcknowledge , markAllRead} = useBell('request', USERNAME_SAFE)
+
+
 
 onMounted(async () => {
@@ -311,5 +321,11 @@
   return allRequests.value.filter(req => {
     const statusMatch = selectedStatus.value === 'all' || req.status === selectedStatus.value;
-    const userMatch = selectedUser.value === 'all' || req.username === selectedUser.value;
+
+
+    let userMatch = true;
+    if (selectedUser.value !== 'all') {
+      userMatch = excludeUser.value ? req.username !== selectedUser.value : req.username === selectedUser.value;
+    }
+
 
     let dateMatch = true;
Index: zinemaster-frontend/src/components/LoginPage.vue
===================================================================
--- zinemaster-frontend/src/components/LoginPage.vue	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ zinemaster-frontend/src/components/LoginPage.vue	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -70,6 +70,5 @@
 };
 
-const username = ref('');
-const password = ref('');
+
 const error = ref('');//reactive promenlivi - real time change
 const router = useRouter();
Index: zinemaster-frontend/src/components/MainPage.vue
===================================================================
--- zinemaster-frontend/src/components/MainPage.vue	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ zinemaster-frontend/src/components/MainPage.vue	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -13,5 +13,5 @@
           </router-link>
 
-          <StatusBell v-if="user.userType === 'Worker' " />
+          <StatusBell />
           <router-link v-if="user.userType === 'UserAdministrator'" to="/manage-users" class="btn btn-outline-warning btn-sm me-2">
             Управувај со корисници
@@ -136,4 +136,13 @@
               <p class="card-text">Достапно: {{ product.quantity - product.reserved - product.tempReserved }}</p>
               <p class="card-text text-muted small">Резервирано: {{ product.reserved + product.tempReserved }}</p>
+              <!-- Forecast (warning) -->
+              <div v-if="product.forecast" class="mt-1">
+                <small :class="product.forecast.redWarning ? 'text-danger fw-bold' : 'text-muted'">
+                  ~{{ product.forecast.forecastPerDay }}/ден • ≈ {{ Math.floor(product.forecast.daysToStockout) }} дена
+                  ({{ product.forecast.predictedOutDate }})
+                </small>
+
+              </div>
+
               <input type="number" min="1" :max="product.quantity" v-model.number="selectedQuantities[product.id]" class="form-control mb-2" placeholder="Количина">
               <button class="btn btn-sm btn-primary" @click="addToRequest(product)">Додади</button>
@@ -162,4 +171,12 @@
               <p class="card-text">Достапно: {{ product.quantity - product.reserved }}</p>
               <p class="card-text text-muted small">Резервирано: {{ product.reserved }}</p>
+              <!-- Forecast (warning) -->
+              <div v-if="product.forecast" class="mt-1">
+
+                <div v-if="product.forecast.redWarning" class = 'text-danger fw-bold' >
+                  Ќе се потроши за ≈ {{ Math.floor(product.forecast.daysToStockout) }} дена({{ product.forecast.predictedOutDate }})
+                </div>
+              </div>
+
               <div v-if="user.userType === 'ProductAdministrator' ">
                 <input type="number" v-model.number="product.addQuantity" min="1" placeholder="Додади количина" class="form-control form-control-sm d-inline w-50 me-2">
@@ -183,5 +200,5 @@
 
     </main>
-    <button class="btn btn-sm btn-primary" @click="ping">Ping Admins</button>
+
   </div>
 
@@ -204,17 +221,6 @@
 console.log(user)
 const processedCount = ref(0)
-const token = localStorage.getItem('auth_token')
-
-
-
-async function ping(){
-  try {
-    await axios.post('http://localhost:8081/api/dev/ping-admins', null,{
-      headers: { Authorization: `Bearer ${token}` }
-    })
-  } catch (e) {
-    console.error('Ping failed:', e?.response?.status, e?.response?.data || e.message)
-  }
-}
+
+
 onMounted(async () => {
   const stored = localStorage.getItem('user');
@@ -237,4 +243,6 @@
   router.push('/login');
 };
+
+
 
 const creatingRequest = ref(false);
@@ -304,6 +312,19 @@
 
 
+
+
 const submitRequest = async () => {
-  const payload = {//body
+  if (!requestItems.value.length) {
+    await Swal.fire("Грешка", "Додајте барем еден производ.", "warning");
+    return;
+  }
+  const token = localStorage.getItem('auth_token');
+  if (!token) {
+    await Swal.fire("Немате пристап", "Најавете се повторно.", "error");
+    router.push('/login');
+    return;
+  }
+
+  const payload = {
     userId: user.value.id,
     items: requestItems.value.map(item => ({
@@ -312,24 +333,37 @@
     }))
   };
-  console.log("Payload za naracka:", payload);
-
-  const res = await fetch('http://localhost:8081/api/requests', {
-    method: 'POST',
-    headers: { 'Content-Type': 'application/json' },
-    body: JSON.stringify(payload)
-  });
-
-  if (res.ok) {
-    const newRequestId = await res.text();
-    await Swal.fire("Успешно",
-        `Нарачката е поднесена со ID: ${newRequestId}`,
-        "success");
+
+  try {
+    const { data } = await axios.post(
+        'http://localhost:8081/api/requests',
+        payload,
+        { headers: { Authorization: `Bearer ${token}` } }
+    );
+
+    // success
+    await Swal.fire("Успешно", `Нарачката е поднесена со ID: ${data || ''}`, "success");
     creatingRequest.value = false;
-    fetchUserRequests();
-  } else {
-    Swal.fire("Грешка", "Грешка при поднесување.", "error");
-  }
-
-  await fetchProducts();
+    requestItems.value = [];
+    selectedQuantities.value = {};
+    await fetchUserRequests();
+    await fetchProducts();
+
+  } catch (err) {
+    const res = err?.response;
+    const code = res?.status;
+
+    console.error('POST /api/requests failed', code, res?.data || err?.message);
+
+    if (code === 401 || code === 403) {
+      await Swal.fire("Немате пристап", "Најавете се повторно.", "error");
+      router.push('/login');
+      return;
+    }
+    if (code === 400) {
+      await Swal.fire("Грешка (400)", (res?.data || "Невалиден payload."), "error");
+      return;
+    }
+    await Swal.fire("Грешка", `Поднесувањето не успеа (${code || 'N/A'}).`, "error");
+  }
 };
 
@@ -392,4 +426,13 @@
     addQuantity: 0
   }));
+
+  await Promise.all(products.value.map(async (p) => {
+    try {
+      const r = await fetch(`http://localhost:8081/api/products/${p.id}/forecast`);
+      if (r.ok) p.forecast = await r.json();
+    } catch (e) {
+      console.warn('Forecast failed for', p.id, e);
+    }
+  }));
 };
 
Index: zinemaster-frontend/src/components/ManageUsers.vue
===================================================================
--- zinemaster-frontend/src/components/ManageUsers.vue	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ zinemaster-frontend/src/components/ManageUsers.vue	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -10,4 +10,5 @@
           <img :src="userProfileImage" alt="Profile" class="rounded-circle me-2 " style="width: 35px; height: 35px; object-fit: cover; border: 2px solid white; cursor: pointer;"/>
         </router-link>
+        <StatusBell  />
 
 
@@ -163,5 +164,5 @@
 import { useRouter } from 'vue-router';
 import Swal from 'sweetalert2'//za poubavi confirms i alerts
-
+import StatusBell from './StatusBell.vue';
 
 const router = useRouter();
@@ -356,4 +357,5 @@
 const logout = () => {
   localStorage.removeItem('user');
+  localStorage.removeItem('auth_token');
   router.push('/login');
 };
Index: zinemaster-frontend/src/components/ProductDetails.vue
===================================================================
--- zinemaster-frontend/src/components/ProductDetails.vue	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ zinemaster-frontend/src/components/ProductDetails.vue	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -1,12 +1,27 @@
 <template>
-  <div class="mt-4">
-    <h3 class="text-center">{{ productName }}</h3>
+  <header class="bg-dark text-white p-3 fixed-top shadow-sm">
+    <div class="container d-flex justify-content-between align-items-center">
+
+      <h4 class="mb-0">ZineMaster</h4>
+
+
+      <button @click="goBack" class="btn btn-outline-light btn-sm">
+        <i class="fas fa-arrow-left me-1"></i> Назад
+      </button>
+    </div>
+  </header>
+
+  <div class="container" style="margin-top: 100px;">
+    <h3 class="text-center mb-4">{{ productName }}</h3>
     <div class="row justify-content-center">
       <div class="col-md-8 col-lg-6">
-        <canvas ref="chartCanvas" class="w-100"></canvas>
+        <div class="card shadow-sm p-3">
+          <canvas ref="chartCanvas" class="w-100"></canvas>
+        </div>
       </div>
     </div>
   </div>
 </template>
+
 
 <script>
@@ -22,4 +37,9 @@
     };
   },
+  methods: {
+    goBack() {
+      this.$router.back()
+    }
+  },
   async mounted() {
     try {
@@ -27,9 +47,22 @@
       this.productName = productRes.data.name;
 
-      const res = await axios.get(`http://localhost:8081/api/products/${this.id}/reservations-by-month`);//api/json
+      const res = await axios.get(`http://localhost:8081/api/products/${this.id}/reservations-by-month`);
       const data = res.data;
 
-      const labels = Object.keys(data);
-      const values = Object.values(data);
+
+      const MONTH_INDEX = {
+        JANUARY: 0, FEBRUARY: 1, MARCH: 2, APRIL: 3, MAY: 4, JUNE: 5,
+        JULY: 6, AUGUST: 7, SEPTEMBER: 8, OCTOBER: 9, NOVEMBER: 10, DECEMBER: 11
+      };
+
+      const entries = Object.entries(data).sort(([a], [b]) => {
+        const [aMonth, aYear] = a.split(' ');
+        const [bMonth, bYear] = b.split(' ');
+        if (aYear !== bYear) return Number(aYear) - Number(bYear);
+        return MONTH_INDEX[aMonth.toUpperCase()] - MONTH_INDEX[bMonth.toUpperCase()];
+      });
+
+      const labels = entries.map(([label]) => label);
+      const values = entries.map(([, value]) => value);
 
       console.log(data);
Index: zinemaster-frontend/src/components/ProfilePage.vue
===================================================================
--- zinemaster-frontend/src/components/ProfilePage.vue	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ zinemaster-frontend/src/components/ProfilePage.vue	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -9,5 +9,5 @@
         <RequestBell v-if="user.userType === 'ProductAdministrator'" />
         <button class="btn btn-outline-light btn-sm me-2" @click="logout">Logout</button>
-        <StatusBell v-if="user.userType === 'Worker' "/>
+        <StatusBell />
         <router-link v-if="user.userType === 'UserAdministrator'" to="/manage-users" class="btn btn-outline-warning btn-sm me-2">
           Управувај со корисници
@@ -133,5 +133,5 @@
     </div>
   </div>
-  <button class="btn btn-sm btn-primary" @click="ping">Ping Admins</button>
+
 
 </template>
@@ -141,10 +141,10 @@
 import { useRouter } from 'vue-router';
 import Swal from 'sweetalert2';
-import axios from 'axios';
+
 import RequestBell from './RequestBell.vue';
 import { useBell } from './useBell';
 import StatusBell from './StatusBell.vue';
 
-const token = localStorage.getItem("auth_token")
+
 function getStoredUser() {
   try {
@@ -157,13 +157,4 @@
 console.log('[ProfilePage] USERNAME_SAFE =', USERNAME_SAFE)
 
-async function ping(){
-  try {
-    await axios.post('http://localhost:8081/api/dev/ping-admins', null,{
-      headers: { Authorization: `Bearer ${token}` }
-    })
-  } catch (e) {
-    console.error('Ping failed:', e?.response?.status, e?.response?.data || e.message)
-  }
-}
 const { startLiveAcknowledge, stopLiveAcknowledge , markAllRead} = useBell('status', USERNAME_SAFE)
 
@@ -254,4 +245,5 @@
 const logout = () => {
   localStorage.removeItem('user');
+  localStorage.removeItem('auth_token');
   router.push('/login');
 };
Index: zinemaster-frontend/src/components/ResetPassword.vue
===================================================================
--- zinemaster-frontend/src/components/ResetPassword.vue	(revision 157c73048f63a67fef803399cb69ddef6c7f26de)
+++ zinemaster-frontend/src/components/ResetPassword.vue	(revision ba4b97ae2adcae89bc2148075fc16ab543fe53a2)
@@ -17,5 +17,13 @@
       </div>
 
-      <button @click="submitNewPassword" class="btn btn-primary w-100">
+      <ul class="text-muted small mb-3">
+        <li :class="{ 'text-success': /[0-9]/.test(password) }">Мора да содржи барем една бројка</li>
+        <li :class="{ 'text-success': /[A-Z]/.test(password) }">Мора да содржи барем една голема буква</li>
+        <li :class="{ 'text-success': /[a-z]/.test(password) }">Мора да содржи барем една мала буква</li>
+        <li :class="{ 'text-success': /[^A-Za-z0-9]/.test(password) }">Мора да содржи бареме ден специјален карактер</li>
+        <li :class="{ 'text-success': password.length > 5 }">Мора да е составен од минимум 6 карактери</li>
+      </ul>
+
+      <button @click="submitNewPassword" class="btn btn-primary w-100" :disabled="!isPasswordValid">
         Промени Лозинка
       </button>
@@ -28,5 +36,5 @@
 
 <script setup>
-import { ref, onMounted } from 'vue';
+import { ref,computed, onMounted } from 'vue';
 import { useRoute } from 'vue-router';
 import axios from 'axios';
@@ -61,3 +69,13 @@
   }
 };
+
+const isPasswordValid = computed(() => {
+  return (
+      /[0-9]/.test(password.value) &&
+      /[A-Z]/.test(password.value) &&
+      /[a-z]/.test(password.value) &&
+      /[^A-Za-z0-9]/.test(password.value) &&
+      password.value.length > 5
+  )
+})
 </script>
