diff --git a/refilc/lib/database/init.dart b/refilc/lib/database/init.dart
index 80d0286..3691a8c 100644
--- a/refilc/lib/database/init.dart
+++ b/refilc/lib/database/init.dart
@@ -66,7 +66,12 @@ const userDataDB = DatabaseStruct("user_data", {
   // renamed teachers // non kreta data
   "renamed_teachers": String,
   // "subject_lesson_count": String, // non kreta data
+  // notifications and surprise grades // non kreta data
   "last_seen_grade": int,
+  "last_seen_surprisegrade": int,
+  "last_seen_absence": int,
+  "last_seen_message": int,
+  "last_seen_lesson": int,
   // goal planning // non kreta data
   "goal_plans": String,
   "goal_averages": String,
@@ -129,7 +134,11 @@ Future<Database> initDB(DatabaseProvider database) async {
       // renamed teachers // non kreta data
       "renamed_teachers": "{}",
       // "subject_lesson_count": "{}", // non kreta data
-      "last_seen_grade": 0,
+      "last_seen_grade": DateTime.now().millisecondsSinceEpoch,
+      "last_seen_surprisegrade": 0,
+      "last_seen_absence": DateTime.now().millisecondsSinceEpoch,
+      "last_seen_message": DateTime.now().millisecondsSinceEpoch,
+      "last_seen_lesson": DateTime.now().millisecondsSinceEpoch,
       // goal planning // non kreta data
       "goal_plans": "{}",
       "goal_averages": "{}",
@@ -207,3 +216,4 @@ Future<void> migrateDB(
     print("INFO: Database migrated");
   }
 }
+
diff --git a/refilc/lib/database/query.dart b/refilc/lib/database/query.dart
index 4758ba2..aef1725 100644
--- a/refilc/lib/database/query.dart
+++ b/refilc/lib/database/query.dart
@@ -1,6 +1,7 @@
 import 'dart:convert';
 import 'package:refilc/api/providers/database_provider.dart';
 import 'package:refilc/models/linked_account.dart';
+import 'package:refilc/helpers/notification_helper.dart';
 import 'package:refilc/models/self_note.dart';
 import 'package:refilc/models/subject_lesson_count.dart';
 import 'package:refilc/models/user.dart';
@@ -213,11 +214,11 @@ class UserDatabaseQuery {
     return lessonCount;
   }
 
-  Future<DateTime> lastSeenGrade({required String userId}) async {
+  Future<DateTime> lastSeen({required String userId, required LastSeenCategory category}) async {
     List<Map> userData =
         await db.query("user_data", where: "id = ?", whereArgs: [userId]);
     if (userData.isEmpty) return DateTime(0);
-    int? lastSeenDate = userData.elementAt(0)["last_seen_grade"] as int?;
+    int? lastSeenDate = userData.elementAt(0)["last_seen_${category.name}"] as int?;
     if (lastSeenDate == null) return DateTime(0);
     DateTime lastSeen = DateTime.fromMillisecondsSinceEpoch(lastSeenDate);
     return lastSeen;
diff --git a/refilc/lib/database/store.dart b/refilc/lib/database/store.dart
index 18728b3..4b0f23f 100644
--- a/refilc/lib/database/store.dart
+++ b/refilc/lib/database/store.dart
@@ -1,5 +1,6 @@
 import 'dart:convert';
 import 'package:refilc/models/linked_account.dart';
+import 'package:refilc/helpers/notification_helper.dart';
 import 'package:refilc/models/self_note.dart';
 import 'package:refilc/models/subject_lesson_count.dart';
 import 'package:refilc_kreta_api/models/week.dart';
@@ -129,12 +130,13 @@ class UserDatabaseStore {
         where: "id = ?", whereArgs: [userId]);
   }
 
-  Future<void> storeLastSeenGrade(DateTime date,
-      {required String userId}) async {
+  Future<void> storeLastSeen(DateTime date,
+      {required String userId, required LastSeenCategory category}) async {
     int lastSeenDate = date.millisecondsSinceEpoch;
-    await db.update("user_data", {"last_seen_grade": lastSeenDate},
+    await db.update("user_data", {"last_seen_${category.name}": lastSeenDate},
         where: "id = ?", whereArgs: [userId]);
   }
+  
 
   // renamed things
   Future<void> storeRenamedSubjects(Map<String, String> subjects,
diff --git a/refilc/lib/helpers/notification_helper.dart b/refilc/lib/helpers/notification_helper.dart
index e21b4a3..fa1ed8a 100644
--- a/refilc/lib/helpers/notification_helper.dart
+++ b/refilc/lib/helpers/notification_helper.dart
@@ -1,8 +1,12 @@
+import 'package:flutter/foundation.dart';
 import 'package:refilc/api/providers/database_provider.dart';
 import 'package:refilc/api/providers/status_provider.dart';
 import 'package:refilc/api/providers/user_provider.dart';
 import 'package:refilc/models/settings.dart';
 import 'package:refilc/helpers/notification_helper.i18n.dart';
+import 'package:refilc/models/user.dart';
+import 'package:refilc/utils/navigation_service.dart';
+import 'package:refilc/utils/service_locator.dart';
 import 'package:refilc_kreta_api/client/api.dart';
 import 'package:refilc_kreta_api/client/client.dart';
 import 'package:refilc_kreta_api/models/absence.dart';
@@ -13,10 +17,19 @@ import 'package:refilc_kreta_api/providers/grade_provider.dart';
 import 'package:refilc_kreta_api/providers/timetable_provider.dart';
 import 'package:flutter_local_notifications/flutter_local_notifications.dart'
     hide Message;
-import 'package:i18n_extension/i18n_extension.dart';
+import 'package:i18n_extension/i18n_widget.dart';
 import 'package:intl/intl.dart';
 import 'package:refilc_kreta_api/models/message.dart';
 
+// if you want to add a new category, also add it to the DB or else the app will probably crash
+enum LastSeenCategory {
+  grade,
+  surprisegrade,
+  absence,
+  message,
+  lesson
+} // didn't know a better place for this
+
 class NotificationsHelper {
   late DatabaseProvider database;
   late SettingsProvider settingsProvider;
@@ -25,41 +38,19 @@ class NotificationsHelper {
   FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
       FlutterLocalNotificationsPlugin();
 
-  List<T> combineLists<T, K>(
-    List<T> list1,
-    List<T> list2,
-    K Function(T) keyExtractor,
-  ) {
-    Set<K> uniqueKeys = <K>{};
-    List<T> combinedList = [];
-
-    for (T item in list1) {
-      K key = keyExtractor(item);
-      if (!uniqueKeys.contains(key)) {
-        uniqueKeys.add(key);
-        combinedList.add(item);
-      }
-    }
-
-    for (T item in list2) {
-      K key = keyExtractor(item);
-      if (!uniqueKeys.contains(key)) {
-        uniqueKeys.add(key);
-        combinedList.add(item);
-      }
-    }
-
-    return combinedList;
-  }
 
   String dayTitle(DateTime date) {
     try {
-      return DateFormat("EEEE", I18n.locale.languageCode).format(date);
+      String dayTitle =
+          DateFormat("EEEE", I18n.locale.languageCode).format(date);
+      dayTitle = dayTitle[0].toUpperCase() +
+          dayTitle.substring(1); // capitalize string
+      return dayTitle;
     } catch (e) {
       return "Unknown";
     }
   }
-
+  
   @pragma('vm:entry-point')
   void backgroundJob() async {
     // initialize providers
@@ -69,540 +60,553 @@ class NotificationsHelper {
     userProvider = await database.query.getUsers(settingsProvider);
 
     if (userProvider.id != null && settingsProvider.notificationsEnabled) {
-      // refresh kreta login
-      final status = StatusProvider();
-      kretaClient = KretaClient(
-          user: userProvider, settings: settingsProvider, status: status);
-      kretaClient.refreshLogin();
-      if (settingsProvider.notificationsGradesEnabled) gradeNotification();
-      if (settingsProvider.notificationsAbsencesEnabled) absenceNotification();
-      if (settingsProvider.notificationsMessagesEnabled) messageNotification();
-      if (settingsProvider.notificationsLessonsEnabled) lessonNotification();
+      List<User> users = userProvider.getUsers();
+
+      // Process notifications for each user asynchronously
+      await Future.forEach(users, (User user) async {
+        // Create a new instance of userProvider for each user
+        UserProvider userProviderForUser = await database.query.getUsers(settingsProvider);
+        userProviderForUser.setUser(user.id);
+
+        // Refresh kreta login for current user
+        final status = StatusProvider();
+        KretaClient kretaClientForUser = KretaClient(
+            user: userProviderForUser, settings: settingsProvider, status: status);
+        await kretaClientForUser.refreshLogin();
+
+        // Process notifications for current user
+        if (settingsProvider.notificationsGradesEnabled) await gradeNotification(userProviderForUser, kretaClientForUser);
+        if (settingsProvider.notificationsAbsencesEnabled) await absenceNotification(userProviderForUser, kretaClientForUser);
+        if (settingsProvider.notificationsMessagesEnabled) await messageNotification(userProviderForUser, kretaClientForUser);
+        if (settingsProvider.notificationsLessonsEnabled) await lessonNotification(userProviderForUser, kretaClientForUser);
+      });
     }
   }
 
-  void gradeNotification() async {
+  Future<void> gradeNotification(UserProvider currentuserProvider, KretaClient currentKretaClient) async {
     // fetch grades
     GradeProvider gradeProvider = GradeProvider(
         settings: settingsProvider,
-        user: userProvider,
+        user: currentuserProvider,
         database: database,
-        kreta: kretaClient);
-    gradeProvider.fetch();
-    List<Grade> grades =
-        await database.userQuery.getGrades(userId: userProvider.id ?? "");
-    DateTime lastSeenGrade =
-        await database.userQuery.lastSeenGrade(userId: userProvider.id ?? "");
+        kreta: currentKretaClient);
+    await gradeProvider.fetch();
+    database.userQuery
+        .getGrades(userId: currentuserProvider.id!)
+        .then((grades) async {
+      DateTime lastSeenGrade = await database.userQuery.lastSeen(
+          userId: currentuserProvider.id!, category: LastSeenCategory.grade);
 
-    // loop through grades and see which hasn't been seen yet
-    for (Grade grade in grades) {
-      // if grade is not a normal grade (1-5), don't show it
-      if ([1, 2, 3, 4, 5].contains(grade.value.value)) {
-        // if the grade was added over a week ago, don't show it to avoid notification spam
-        // it worked in reverse, cuz someone added a * -1 to it, but it has been fixed now :D
-        // old code below
-        // if (grade.seenDate.isAfter(lastSeenGrade) &&
-        //     grade.date.difference(DateTime.now()).inDays * -1 < 7) {
-        // new code from here :P
-        if (grade.seenDate.isAfter(lastSeenGrade) &&
-            grade.date.difference(DateTime.now()).inDays < 7) {
-          // send notificiation about new grade
-          AndroidNotificationDetails androidNotificationDetails =
-              AndroidNotificationDetails(
-            'GRADES',
-            'Jegyek',
-            channelDescription: 'Értesítés jegyek beírásakor',
-            importance: Importance.max,
-            priority: Priority.max,
-            color: settingsProvider.customAccentColor,
-            ticker: 'Jegyek',
-          );
-          NotificationDetails notificationDetails =
-              NotificationDetails(android: androidNotificationDetails);
-          if (userProvider.getUsers().length == 1) {
-            await flutterLocalNotificationsPlugin.show(
-              grade.id.hashCode,
-              "title_grade".i18n,
-              "body_grade".i18n.fill(
-                [
-                  grade.value.value.toString(),
-                  grade.subject.isRenamed &&
-                          settingsProvider.renamedSubjectsEnabled
-                      ? grade.subject.renamedTo!
-                      : grade.subject.name
-                ],
-              ),
-              notificationDetails,
-            );
-          } else {
-            // multiple users are added, also display student name
-            await flutterLocalNotificationsPlugin.show(
-              grade.id.hashCode,
-              "title_grade".i18n,
-              "body_grade_multiuser".i18n.fill(
-                [
-                  userProvider.displayName!,
-                  grade.value.value.toString(),
-                  grade.subject.isRenamed &&
-                          settingsProvider.renamedSubjectsEnabled
-                      ? grade.subject.renamedTo!
-                      : grade.subject.name
-                ],
-              ),
-              notificationDetails,
+      // loop through grades and see which hasn't been seen yet
+      for (Grade grade in grades) {
+        // if grade is not a normal grade (1-5), don't show it
+        if ([1, 2, 3, 4, 5].contains(grade.value.value)) {
+          // if the grade was added over a week ago, don't show it to avoid notification spam
+          if (grade.date.isAfter(lastSeenGrade) &&
+              DateTime.now().difference(grade.date).inDays < 7) {
+            // send notificiation about new grade
+            AndroidNotificationDetails androidNotificationDetails =
+                AndroidNotificationDetails(
+              'GRADES',
+              'Jegyek',
+              channelDescription: 'Értesítés jegyek beírásakor',
+              importance: Importance.max,
+              priority: Priority.max,
+              color: settingsProvider.customAccentColor,
+              ticker: 'Jegyek',
             );
+            NotificationDetails notificationDetails =
+                NotificationDetails(android: androidNotificationDetails);
+            if (currentuserProvider.getUsers().length == 1) {
+              await flutterLocalNotificationsPlugin.show(
+                grade.id.hashCode,
+                "title_grade".i18n,
+                "body_grade".i18n.fill(
+                  [
+                    grade.value.value.toString(),
+                    grade.subject.isRenamed &&
+                            settingsProvider.renamedSubjectsEnabled
+                        ? grade.subject.renamedTo!
+                        : grade.subject.name
+                  ],
+                ),
+                notificationDetails,
+                payload: "grades"
+              );
+            } else {
+              // multiple users are added, also display student name
+              await flutterLocalNotificationsPlugin.show(
+                grade.id.hashCode,
+                "title_grade".i18n,
+                "body_grade_multiuser".i18n.fill(
+                  [
+                    currentuserProvider.displayName!,
+                    grade.value.value.toString(),
+                    grade.subject.isRenamed &&
+                            settingsProvider.renamedSubjectsEnabled
+                        ? grade.subject.renamedTo!
+                        : grade.subject.name
+                  ],
+                ),
+                notificationDetails,
+                payload: "grades"
+              );
+            }
           }
         }
       }
-    }
-    // set grade seen status
-    gradeProvider.seenAll();
+      // set grade seen status
+      database.userStore.storeLastSeen(DateTime.now(), userId: currentuserProvider.id!, category: LastSeenCategory.grade);
+    });
   }
 
-  void absenceNotification() async {
+  Future<void> absenceNotification(UserProvider currentuserProvider, KretaClient currentKretaClient) async {
     // get absences from api
-    List? absenceJson = await kretaClient
-        .getAPI(KretaAPI.absences(userProvider.instituteCode ?? ""));
-    List<Absence> storedAbsences =
-        await database.userQuery.getAbsences(userId: userProvider.id!);
+    List? absenceJson = await currentKretaClient
+        .getAPI(KretaAPI.absences(currentuserProvider.instituteCode ?? ""));
     if (absenceJson == null) {
       return;
     }
-    // format api absences to correct format while preserving isSeen value
-    List<Absence> absences = absenceJson.map((e) {
-      Absence apiAbsence = Absence.fromJson(e);
-      Absence storedAbsence = storedAbsences.firstWhere(
-          (stored) => stored.id == apiAbsence.id,
-          orElse: () => apiAbsence);
-      apiAbsence.isSeen = storedAbsence.isSeen;
-      return apiAbsence;
-    }).toList();
-    List<Absence> modifiedAbsences = [];
-    if (absences != storedAbsences) {
-      // remove absences that are not new
-      absences.removeWhere((element) => storedAbsences.contains(element));
-      for (Absence absence in absences) {
-        if (!absence.isSeen) {
-          absence.isSeen = true;
-          modifiedAbsences.add(absence);
-          AndroidNotificationDetails androidNotificationDetails =
-              AndroidNotificationDetails(
-            'ABSENCES',
-            'Hiányzások',
-            channelDescription: 'Értesítés hiányzások beírásakor',
-            importance: Importance.max,
-            priority: Priority.max,
-            color: settingsProvider.customAccentColor,
-            ticker: 'Hiányzások',
+    DateTime lastSeenAbsence = await database.userQuery
+        .lastSeen(userId: currentuserProvider.id!, category: LastSeenCategory.absence);
+    // format api absences
+    List<Absence> absences =
+        absenceJson.map((e) => Absence.fromJson(e)).toList();
+    for (Absence absence in absences) {
+      if (absence.date.isAfter(lastSeenAbsence)) {
+        AndroidNotificationDetails androidNotificationDetails =
+            AndroidNotificationDetails(
+          'ABSENCES',
+          'Hiányzások',
+          channelDescription: 'Értesítés hiányzások beírásakor',
+          importance: Importance.max,
+          priority: Priority.max,
+          color: settingsProvider.customAccentColor,
+          ticker: 'Hiányzások',
+        );
+        NotificationDetails notificationDetails =
+            NotificationDetails(android: androidNotificationDetails);
+        if (currentuserProvider.getUsers().length == 1) {
+          await flutterLocalNotificationsPlugin.show(
+            absence.id.hashCode,
+            "title_absence"
+                .i18n, // https://discord.com/channels/1111649116020285532/1153273625206591528
+            "body_absence".i18n.fill(
+              [
+                DateFormat("yyyy-MM-dd").format(absence.date),
+                absence.subject.isRenamed &&
+                        settingsProvider.renamedSubjectsEnabled
+                    ? absence.subject.renamedTo!
+                    : absence.subject.name
+              ],
+            ),
+            notificationDetails,
+            payload: "absences"
+          );
+        } else {
+          await flutterLocalNotificationsPlugin.show(
+            absence.id.hashCode,
+            "title_absence"
+                .i18n, // https://discord.com/channels/1111649116020285532/1153273625206591528
+            "body_absence_multiuser".i18n.fill(
+              [
+                currentuserProvider.displayName!,
+                DateFormat("yyyy-MM-dd").format(absence.date),
+                absence.subject.isRenamed &&
+                        settingsProvider.renamedSubjectsEnabled
+                    ? absence.subject.renamedTo!
+                    : absence.subject.name
+              ],
+            ),
+            notificationDetails,
+            payload: "absences"
           );
-          NotificationDetails notificationDetails =
-              NotificationDetails(android: androidNotificationDetails);
-          if (userProvider.getUsers().length == 1) {
-            await flutterLocalNotificationsPlugin.show(
-              absence.id.hashCode,
-              "title_absence"
-                  .i18n, // https://discord.com/channels/1111649116020285532/1153273625206591528
-              "body_absence".i18n.fill(
-                [
-                  DateFormat("yyyy-MM-dd").format(absence.date),
-                  absence.subject.isRenamed &&
-                          settingsProvider.renamedSubjectsEnabled
-                      ? absence.subject.renamedTo!
-                      : absence.subject.name
-                ],
-              ),
-              notificationDetails,
-            );
-          } else {
-            await flutterLocalNotificationsPlugin.show(
-              absence.id.hashCode,
-              "title_absence"
-                  .i18n, // https://discord.com/channels/1111649116020285532/1153273625206591528
-              "body_absence_multiuser".i18n.fill(
-                [
-                  userProvider.displayName!,
-                  DateFormat("yyyy-MM-dd").format(absence.date),
-                  absence.subject.isRenamed &&
-                          settingsProvider.renamedSubjectsEnabled
-                      ? absence.subject.renamedTo!
-                      : absence.subject.name
-                ],
-              ),
-              notificationDetails,
-            );
-          }
         }
       }
     }
-    // combine modified absences and storedabsences list and save them to the database
-    List<Absence> combinedAbsences = combineLists(
-      modifiedAbsences,
-      storedAbsences,
-      (Absence absence) => absence.id,
-    );
-    await database.userStore
-        .storeAbsences(combinedAbsences, userId: userProvider.id!);
+    await database.userStore.storeLastSeen(DateTime.now(),
+          userId: currentuserProvider.id!, category: LastSeenCategory.absence);
   }
 
-  void messageNotification() async {
-    // get messages from api
-    List? messageJson =
-        await kretaClient.getAPI(KretaAPI.messages("beerkezett"));
-    List<Message> storedmessages =
-        await database.userQuery.getMessages(userId: userProvider.id!);
-    if (messageJson == null) {
-      return;
-    }
-    // format api messages to correct format while preserving isSeen value
-    // Parse messages
-    List<Message> messages = [];
-    await Future.wait(List.generate(messageJson.length, (index) {
-      return () async {
-        Map message = messageJson.cast<Map>()[index];
-        Map? innerMessageJson = await kretaClient
-            .getAPI(KretaAPI.message(message["azonosito"].toString()));
-        if (innerMessageJson != null) {
-          messages.add(
-              Message.fromJson(innerMessageJson, forceType: MessageType.inbox));
+      Future<void> messageNotification(UserProvider currentuserProvider, KretaClient currentKretaClient) async {
+        // get messages from api
+        List? messageJson =
+            await currentKretaClient.getAPI(KretaAPI.messages("beerkezett"));
+        if (messageJson == null) {
+          return;
         }
-      }();
-    }));
-
-    for (Message message in messages) {
-      for (Message storedMessage in storedmessages) {
-        if (message.id == storedMessage.id) {
-          message.isSeen = storedMessage.isSeen;
-        }
-      }
-    }
-    List<Message> modifiedmessages = [];
-    if (messages != storedmessages) {
-      // remove messages that are not new
-      messages.removeWhere((element) => storedmessages.contains(element));
-      for (Message message in messages) {
-        if (!message.isSeen) {
-          message.isSeen = true;
-          modifiedmessages.add(message);
-          AndroidNotificationDetails androidNotificationDetails =
-              AndroidNotificationDetails(
-            'MESSAGES',
-            'Üzenetek',
-            channelDescription: 'Értesítés kapott üzenetekkor',
-            importance: Importance.max,
-            priority: Priority.max,
-            color: settingsProvider.customAccentColor,
-            ticker: 'Üzenetek',
-          );
-          NotificationDetails notificationDetails =
-              NotificationDetails(android: androidNotificationDetails);
-          if (userProvider.getUsers().length == 1) {
-            await flutterLocalNotificationsPlugin.show(
-              message.id.hashCode,
-              message.author,
-              message.content.replaceAll(RegExp(r'<[^>]*>'), ''),
-              notificationDetails,
-            );
-          } else {
-            await flutterLocalNotificationsPlugin.show(
-              message.id.hashCode,
-              "(${userProvider.displayName!}) ${message.author}",
-              message.content.replaceAll(RegExp(r'<[^>]*>'), ''),
-              notificationDetails,
-            );
-          }
-        }
-      }
-    }
-    // combine modified messages and storedmessages list and save them to the database
-    List<Message> combinedmessages = combineLists(
-      modifiedmessages,
-      storedmessages,
-      (Message message) => message.id,
-    );
-    await database.userStore
-        .storeMessages(combinedmessages, userId: userProvider.id!);
-  }
-
-  void lessonNotification() async {
-    // get lesson from api
-    TimetableProvider timetableProvider = TimetableProvider(
-        user: userProvider, database: database, kreta: kretaClient);
-    List<Lesson> storedlessons =
-        timetableProvider.lessons[Week.current()] ?? [];
-    List? apilessons = timetableProvider.getWeek(Week.current()) ?? [];
-    for (Lesson lesson in apilessons) {
-      for (Lesson storedLesson in storedlessons) {
-        if (lesson.id == storedLesson.id) {
-          lesson.isSeen = storedLesson.isSeen;
-        }
-      }
-    }
-    List<Lesson> modifiedlessons = [];
-    if (apilessons != storedlessons) {
-      // remove lessons that are not new
-      apilessons.removeWhere((element) => storedlessons.contains(element));
-      for (Lesson lesson in apilessons) {
-        if (!lesson.isSeen && lesson.isChanged) {
-          lesson.isSeen = true;
-          modifiedlessons.add(lesson);
-          AndroidNotificationDetails androidNotificationDetails =
-              AndroidNotificationDetails(
-            'LESSONS',
-            'Órák',
-            channelDescription:
-                'Értesítés órák elmaradásáról, helyettesítésről',
-            importance: Importance.max,
-            priority: Priority.max,
-            color: settingsProvider.customAccentColor,
-            ticker: 'Órák',
-          );
-          NotificationDetails notificationDetails =
-              NotificationDetails(android: androidNotificationDetails);
-          if (userProvider.getUsers().length == 1) {
-            if (lesson.status?.name == "Elmaradt") {
-              switch (I18n.localeStr) {
-                case "en_en":
-                  {
-                    await flutterLocalNotificationsPlugin.show(
-                      lesson.id.hashCode,
-                      "title_lesson".i18n,
-                      "body_lesson_canceled".i18n.fill(
-                        [
-                          lesson.lessonIndex,
-                          lesson.name,
-                          dayTitle(lesson.date)
-                        ],
-                      ),
-                      notificationDetails,
-                    );
-                    break;
-                  }
-                case "hu_hu":
-                  {
-                    await flutterLocalNotificationsPlugin.show(
-                      lesson.id.hashCode,
-                      "title_lesson".i18n,
-                      "body_lesson_canceled".i18n.fill(
-                        [
-                          dayTitle(lesson.date),
-                          lesson.lessonIndex,
-                          lesson.name
-                        ],
-                      ),
-                      notificationDetails,
-                    );
-                    break;
-                  }
-                default:
-                  {
-                    await flutterLocalNotificationsPlugin.show(
-                      lesson.id.hashCode,
-                      "title_lesson".i18n,
-                      "body_lesson_canceled".i18n.fill(
-                        [
-                          lesson.lessonIndex,
-                          lesson.name,
-                          dayTitle(lesson.date)
-                        ],
-                      ),
-                      notificationDetails,
-                    );
-                    break;
-                  }
-              }
-            } else if (lesson.substituteTeacher?.name != "") {
-              switch (I18n.localeStr) {
-                case "en_en":
-                  {
-                    await flutterLocalNotificationsPlugin.show(
-                      lesson.id.hashCode,
-                      "title_lesson".i18n,
-                      "body_lesson_substituted".i18n.fill(
-                        [
-                          lesson.lessonIndex,
-                          lesson.name,
-                          dayTitle(lesson.date),
-                          lesson.substituteTeacher!.isRenamed
-                              ? lesson.substituteTeacher!.renamedTo!
-                              : lesson.substituteTeacher!.name
-                        ],
-                      ),
-                      notificationDetails,
-                    );
-                    break;
-                  }
-                case "hu_hu":
-                  {
-                    await flutterLocalNotificationsPlugin.show(
-                      lesson.id.hashCode,
-                      "title_lesson".i18n,
-                      "body_lesson_substituted".i18n.fill(
-                        [
-                          dayTitle(lesson.date),
-                          lesson.lessonIndex,
-                          lesson.name,
-                          lesson.substituteTeacher!.isRenamed
-                              ? lesson.substituteTeacher!.renamedTo!
-                              : lesson.substituteTeacher!.name
-                        ],
-                      ),
-                      notificationDetails,
-                    );
-                    break;
-                  }
-                default:
-                  {
-                    await flutterLocalNotificationsPlugin.show(
-                      lesson.id.hashCode,
-                      "title_lesson".i18n,
-                      "body_lesson_substituted".i18n.fill(
-                        [
-                          lesson.lessonIndex,
-                          lesson.name,
-                          dayTitle(lesson.date),
-                          lesson.substituteTeacher!.isRenamed
-                              ? lesson.substituteTeacher!.renamedTo!
-                              : lesson.substituteTeacher!.name
-                        ],
-                      ),
-                      notificationDetails,
-                    );
-                    break;
-                  }
-              }
+        // format api messages to correct format
+        // Parse messages
+        List<Message> messages = [];
+        await Future.wait(List.generate(messageJson.length, (index) {
+          return () async {
+            Map message = messageJson.cast<Map>()[index];
+            Map? innerMessageJson = await currentKretaClient
+                .getAPI(KretaAPI.message(message["azonosito"].toString()));
+            await Future.delayed(const Duration(seconds: 1));
+            if (innerMessageJson != null) {
+              messages.add(Message.fromJson(innerMessageJson,
+                  forceType: MessageType.inbox));
             }
-          } else {
-            if (lesson.status?.name == "Elmaradt") {
-              switch (I18n.localeStr) {
-                case "en_en":
-                  {
-                    await flutterLocalNotificationsPlugin.show(
-                      lesson.id.hashCode,
-                      "title_lesson".i18n,
-                      "body_lesson_canceled".i18n.fill(
-                        [
-                          userProvider.displayName!,
-                          lesson.lessonIndex,
-                          lesson.name,
-                          dayTitle(lesson.date)
-                        ],
-                      ),
-                      notificationDetails,
-                    );
-                    break;
-                  }
-                case "hu_hu":
-                  {
-                    await flutterLocalNotificationsPlugin.show(
-                      lesson.id.hashCode,
-                      "title_lesson".i18n,
-                      "body_lesson_canceled".i18n.fill(
-                        [
-                          userProvider.displayName!,
-                          dayTitle(lesson.date),
-                          lesson.lessonIndex,
-                          lesson.name
-                        ],
-                      ),
-                      notificationDetails,
-                    );
-                    break;
-                  }
-                default:
-                  {
-                    await flutterLocalNotificationsPlugin.show(
-                      lesson.id.hashCode,
-                      "title_lesson".i18n,
-                      "body_lesson_canceled".i18n.fill(
-                        [
-                          userProvider.displayName!,
-                          lesson.lessonIndex,
-                          lesson.name,
-                          dayTitle(lesson.date)
-                        ],
-                      ),
-                      notificationDetails,
-                    );
-                    break;
-                  }
+          }();
+        }));
+
+        DateTime lastSeenMessage = await database.userQuery.lastSeen(
+            userId: currentuserProvider.id!, category: LastSeenCategory.message);
+
+        for (Message message in messages) {
+          if (message.date.isAfter(lastSeenMessage)) {
+            AndroidNotificationDetails androidNotificationDetails =
+                AndroidNotificationDetails(
+              'MESSAGES',
+              'Üzenetek',
+              channelDescription: 'Értesítés kapott üzenetekkor',
+              importance: Importance.max,
+              priority: Priority.max,
+              color: settingsProvider.customAccentColor,
+              ticker: 'Üzenetek',
+            );
+            NotificationDetails notificationDetails =
+                NotificationDetails(android: androidNotificationDetails);
+            if (currentuserProvider.getUsers().length == 1) {
+              await flutterLocalNotificationsPlugin.show(
+                message.id.hashCode,
+                message.author,
+                message.content.replaceAll(RegExp(r'<[^>]*>'), ''),
+                notificationDetails,
+                payload: "messages",
+              );
+            } else {
+              await flutterLocalNotificationsPlugin.show(
+                message.id.hashCode,
+                "(${currentuserProvider.displayName!}) ${message.author}",
+                message.content.replaceAll(RegExp(r'<[^>]*>'), ''),
+                notificationDetails,
+                payload: "messages",
+              );
+            }
+          }
+        }
+        await database.userStore.storeLastSeen(DateTime.now(),
+            userId: currentuserProvider.id!, category: LastSeenCategory.message);
+      }
+
+      Future<void> lessonNotification(UserProvider currentuserProvider, KretaClient currentKretaClient) async {
+        // get lessons from api
+        TimetableProvider timetableProvider = TimetableProvider(
+            user: currentuserProvider, database: database, kreta: currentKretaClient);
+        await timetableProvider.restoreUser();
+        await timetableProvider.fetch(week: Week.current());
+        List<Lesson> apilessons =
+            timetableProvider.getWeek(Week.current()) ?? [];
+
+        DateTime lastSeenLesson = await database.userQuery.lastSeen(
+            userId: currentuserProvider.id!, category: LastSeenCategory.lesson);
+        Lesson? latestLesson;
+
+        for (Lesson lesson in apilessons) {
+          if((lesson.status?.name != "Elmaradt" || lesson.substituteTeacher?.name != "") && lesson.date.isAfter(latestLesson?.start ?? DateTime(1970))) {
+              latestLesson = lesson;
+            }
+          if (lesson.date.isAfter(lastSeenLesson)) {
+            AndroidNotificationDetails androidNotificationDetails =
+                AndroidNotificationDetails(
+              'LESSONS',
+              'Órák',
+              channelDescription:
+                  'Értesítés órák elmaradásáról, helyettesítésről',
+              importance: Importance.max,
+              priority: Priority.max,
+              color: settingsProvider.customAccentColor,
+              ticker: 'Órák',
+            );
+            NotificationDetails notificationDetails =
+                NotificationDetails(android: androidNotificationDetails);
+            if (currentuserProvider.getUsers().length == 1) {
+              if (lesson.status?.name == "Elmaradt") {
+                switch (I18n.localeStr) {
+                  case "en_en":
+                    {
+                      await flutterLocalNotificationsPlugin.show(
+                        lesson.id.hashCode,
+                        "title_lesson".i18n,
+                        "body_lesson_canceled".i18n.fill(
+                          [
+                            lesson.lessonIndex,
+                            lesson.name,
+                            dayTitle(lesson.date)
+                          ],
+                        ),
+                        notificationDetails,
+                        payload: "timetable"
+                      );
+                      break;
+                    }
+                  case "hu_hu":
+                    {
+                      await flutterLocalNotificationsPlugin.show(
+                        lesson.id.hashCode,
+                        "title_lesson".i18n,
+                        "body_lesson_canceled".i18n.fill(
+                          [
+                            dayTitle(lesson.date),
+                            lesson.lessonIndex,
+                            lesson.name
+                          ],
+                        ),
+                        notificationDetails,
+                        payload: "timetable"
+                      );
+                      break;
+                    }
+                  default:
+                    {
+                      await flutterLocalNotificationsPlugin.show(
+                        lesson.id.hashCode,
+                        "title_lesson".i18n,
+                        "body_lesson_canceled".i18n.fill(
+                          [
+                            lesson.lessonIndex,
+                            lesson.name,
+                            dayTitle(lesson.date)
+                          ],
+                        ),
+                        notificationDetails,
+                        payload: "timetable"
+                      );
+                      break;
+                    }
+                }
+              } else if (lesson.substituteTeacher?.name != "" && lesson.substituteTeacher != null) {
+                switch (I18n.localeStr) {
+                  case "en_en":
+                    {
+                      await flutterLocalNotificationsPlugin.show(
+                        lesson.id.hashCode,
+                        "title_lesson".i18n,
+                        "body_lesson_substituted".i18n.fill(
+                          [
+                            lesson.lessonIndex,
+                            lesson.name,
+                            dayTitle(lesson.date),
+                            lesson.substituteTeacher!.isRenamed
+                                ? lesson.substituteTeacher!.renamedTo!
+                                : lesson.substituteTeacher!.name
+                          ],
+                        ),
+                        notificationDetails,
+                        payload: "timetable",
+                      );
+                      break;
+                    }
+                  case "hu_hu":
+                    {
+                      await flutterLocalNotificationsPlugin.show(
+                        lesson.id.hashCode,
+                        "title_lesson".i18n,
+                        "body_lesson_substituted".i18n.fill(
+                          [
+                            dayTitle(lesson.date),
+                            lesson.lessonIndex,
+                            lesson.name,
+                            lesson.substituteTeacher!.isRenamed
+                                ? lesson.substituteTeacher!.renamedTo!
+                                : lesson.substituteTeacher!.name
+                          ],
+                        ),
+                        notificationDetails,
+                        payload: "timetable",
+                      );
+                      break;
+                    }
+                  default:
+                    {
+                      await flutterLocalNotificationsPlugin.show(
+                        lesson.id.hashCode,
+                        "title_lesson".i18n,
+                        "body_lesson_substituted".i18n.fill(
+                          [
+                            lesson.lessonIndex,
+                            lesson.name,
+                            dayTitle(lesson.date),
+                            lesson.substituteTeacher!.isRenamed
+                                ? lesson.substituteTeacher!.renamedTo!
+                                : lesson.substituteTeacher!.name
+                          ],
+                        ),
+                        notificationDetails,
+                        payload: "timetable",
+                      );
+                      break;
+                    }
+                }
               }
-            } else if (lesson.substituteTeacher?.name != "") {
-              switch (I18n.localeStr) {
-                case "en_en":
-                  {
-                    await flutterLocalNotificationsPlugin.show(
-                      lesson.id.hashCode,
-                      "title_lesson".i18n,
-                      "body_lesson_substituted".i18n.fill(
-                        [
-                          userProvider.displayName!,
-                          lesson.lessonIndex,
-                          lesson.name,
-                          dayTitle(lesson.date),
-                          lesson.substituteTeacher!.isRenamed
-                              ? lesson.substituteTeacher!.renamedTo!
-                              : lesson.substituteTeacher!.name
-                        ],
-                      ),
-                      notificationDetails,
-                    );
-                    break;
-                  }
-                case "hu_hu":
-                  {
-                    await flutterLocalNotificationsPlugin.show(
-                      lesson.id.hashCode,
-                      "title_lesson".i18n,
-                      "body_lesson_substituted".i18n.fill(
-                        [
-                          userProvider.displayName!,
-                          dayTitle(lesson.date),
-                          lesson.lessonIndex,
-                          lesson.name,
-                          lesson.substituteTeacher!.isRenamed
-                              ? lesson.substituteTeacher!.renamedTo!
-                              : lesson.substituteTeacher!.name
-                        ],
-                      ),
-                      notificationDetails,
-                    );
-                    break;
-                  }
-                default:
-                  {
-                    await flutterLocalNotificationsPlugin.show(
-                      lesson.id.hashCode,
-                      "title_lesson".i18n,
-                      "body_lesson_substituted".i18n.fill(
-                        [
-                          userProvider.displayName!,
-                          lesson.lessonIndex,
-                          lesson.name,
-                          dayTitle(lesson.date),
-                          lesson.substituteTeacher!.isRenamed
-                              ? lesson.substituteTeacher!.renamedTo!
-                              : lesson.substituteTeacher!.name
-                        ],
-                      ),
-                      notificationDetails,
-                    );
-                    break;
-                  }
+            } else {
+              if (lesson.status?.name == "Elmaradt") {
+                switch (I18n.localeStr) {
+                  case "en_en":
+                    {
+                      await flutterLocalNotificationsPlugin.show(
+                        lesson.id.hashCode,
+                        "title_lesson".i18n,
+                        "body_lesson_canceled_multiuser".i18n.fill(
+                          [
+                            currentuserProvider.displayName!,
+                            lesson.lessonIndex,
+                            lesson.name,
+                            dayTitle(lesson.date)
+                          ],
+                        ),
+                        notificationDetails,
+                        payload: "timetable",
+                      );
+                      break;
+                    }
+                  case "hu_hu":
+                    {
+                      await flutterLocalNotificationsPlugin.show(
+                        lesson.id.hashCode,
+                        "title_lesson".i18n,
+                        "body_lesson_canceled_multiuser".i18n.fill(
+                          [
+                            currentuserProvider.displayName!,
+                            dayTitle(lesson.date),
+                            lesson.lessonIndex,
+                            lesson.name
+                          ],
+                        ),
+                        notificationDetails,
+                        payload: "timetable",
+                      );
+                      break;
+                    }
+                  default:
+                    {
+                      await flutterLocalNotificationsPlugin.show(
+                        lesson.id.hashCode,
+                        "title_lesson".i18n,
+                        "body_lesson_canceled_multiuser".i18n.fill(
+                          [
+                            currentuserProvider.displayName!,
+                            lesson.lessonIndex,
+                            lesson.name,
+                            dayTitle(lesson.date)
+                          ],
+                        ),
+                        notificationDetails,
+                        payload: "timetable",
+                      );
+                      break;
+                    }
+                }
+              } else if (lesson.substituteTeacher?.name != "") {
+                switch (I18n.localeStr) {
+                  case "en_en":
+                    {
+                      await flutterLocalNotificationsPlugin.show(
+                        lesson.id.hashCode,
+                        "title_lesson".i18n,
+                        "body_lesson_substituted_multiuser".i18n.fill(
+                          [
+                            currentuserProvider.displayName!,
+                            lesson.lessonIndex,
+                            lesson.name,
+                            dayTitle(lesson.date),
+                            lesson.substituteTeacher!.isRenamed
+                                ? lesson.substituteTeacher!.renamedTo!
+                                : lesson.substituteTeacher!.name
+                          ],
+                        ),
+                        notificationDetails,
+                        payload: "timetable",
+                      );
+                      break;
+                    }
+                  case "hu_hu":
+                    {
+                      await flutterLocalNotificationsPlugin.show(
+                        lesson.id.hashCode,
+                        "title_lesson".i18n,
+                        "body_lesson_substituted_multiuser".i18n.fill(
+                          [
+                            currentuserProvider.displayName!,
+                            dayTitle(lesson.date),
+                            lesson.lessonIndex,
+                            lesson.name,
+                            lesson.substituteTeacher!.isRenamed
+                                ? lesson.substituteTeacher!.renamedTo!
+                                : lesson.substituteTeacher!.name
+                          ],
+                        ),
+                        notificationDetails,
+                        payload: "timetable",
+                      );
+                      break;
+                    }
+                  default:
+                    {
+                      await flutterLocalNotificationsPlugin.show(
+                        lesson.id.hashCode,
+                        "title_lesson".i18n,
+                        "body_lesson_substituted_multiuser".i18n.fill(
+                          [
+                            currentuserProvider.displayName!,
+                            lesson.lessonIndex,
+                            lesson.name,
+                            dayTitle(lesson.date),
+                            lesson.substituteTeacher!.isRenamed
+                                ? lesson.substituteTeacher!.renamedTo!
+                                : lesson.substituteTeacher!.name
+                          ],
+                        ),
+                        notificationDetails,
+                        payload: "timetable",
+                      );
+                      break;
+                    }
+                }
               }
             }
           }
         }
+        // lesson.date does not contain time, only the date
+        await database.userStore.storeLastSeen(latestLesson?.start ?? DateTime.now(),
+            userId: currentuserProvider.id!, category: LastSeenCategory.lesson);
+      }
+      
+      // Called when the user taps a notification
+      void onDidReceiveNotificationResponse(NotificationResponse notificationResponse) async {
+        final String? payload = notificationResponse.payload;
+        if (notificationResponse.payload != null) {
+          debugPrint('notification payload: $payload');
+        }
+        switch(payload) {
+          case "timetable":
+            locator<NavigationService>().navigateTo("timetable");
+            break;
+          case "grades":
+            locator<NavigationService>().navigateTo("grades");
+            break;
+          case "messages":
+            locator<NavigationService>().navigateTo("messages");
+            break;
+          case "absences":
+            locator<NavigationService>().navigateTo("absences");
+            break;
+          case "settings":
+            locator<NavigationService>().navigateTo("settings");
+            break;
+          default:
+            break;
+        }
+      }
+
+      // Set all notification categories to seen
+      Future<void> setAllCategoriesSeen(UserProvider userProvider) async {
+        if(userProvider.id != null) {
+          for(LastSeenCategory category in LastSeenCategory.values) {
+            await database.userStore.storeLastSeen(DateTime.now(), userId: userProvider.id!, category: category);
+          }
+        }
       }
-      // combine modified lesson and storedlesson list and save them to the database
-      List<Lesson> combinedlessons = combineLists(
-        modifiedlessons,
-        storedlessons,
-        (Lesson message) => message.id,
-      );
-      Map<Week, List<Lesson>> timetableLessons = timetableProvider.lessons;
-      timetableLessons[Week.current()] = combinedlessons;
-      await database.userStore
-          .storeLessons(timetableLessons, userId: userProvider.id!);
     }
-  }
-}
diff --git a/refilc/lib/helpers/notification_helper.i18n.dart b/refilc/lib/helpers/notification_helper.i18n.dart
index 37e6ff0..49db9f7 100644
--- a/refilc/lib/helpers/notification_helper.i18n.dart
+++ b/refilc/lib/helpers/notification_helper.i18n.dart
@@ -1,4 +1,5 @@
 import 'package:i18n_extension/i18n_extension.dart';
+import 'package:refilc/api/providers/database_provider.dart';
 
 extension Localization on String {
   static final _t = Translations.byLocale("hu_hu") +
@@ -43,8 +44,19 @@ extension Localization on String {
           "body_lesson_substituted_multiuser": "(%s) Lektion Nr. %s (%s) wird am %s durch %s ersetzt"
         },
       };
+  String get i18n {
+    // very hacky way to get app language in notifications
+    // i18n does not like being in background functions (it cannot retrieve locale sometimes)
+    final DatabaseProvider databaseProvider = DatabaseProvider();
+    databaseProvider.init().then((value) {
+      databaseProvider.query.getSettings(databaseProvider).then((settings) {
+      return localize(this, _t, locale: "${settings.language}_${settings.language.toUpperCase()}");
+    });
+    });
 
-  String get i18n => localize(this, _t);
+
+    return localize(this, _t);
+  }
   String fill(List<Object> params) => localizeFill(this, params);
   String plural(int value) => localizePlural(value, this, _t);
   String version(Object modifier) => localizeVersion(modifier, this, _t);
diff --git a/refilc/lib/main.dart b/refilc/lib/main.dart
index 91b569f..2d341e9 100644
--- a/refilc/lib/main.dart
+++ b/refilc/lib/main.dart
@@ -10,6 +10,8 @@ import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:refilc/app.dart';
 import 'package:flutter/services.dart';
+import 'package:refilc/utils/navigation_service.dart';
+import 'package:refilc/utils/service_locator.dart';
 import 'package:refilc_mobile_ui/screens/error_screen.dart';
 import 'package:refilc_mobile_ui/screens/error_report_screen.dart';
 import 'package:flutter_local_notifications/flutter_local_notifications.dart';
@@ -23,12 +25,20 @@ void main() async {
   // ignore: deprecated_member_use
   binding.renderView.automaticSystemUiAdjustment = false;
   SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
+  // navigation
+  setupLocator();
+
   // Startup
   Startup startup = Startup();
   await startup.start();
 
   // Custom error page
   ErrorWidget.builder = errorBuilder;
+  
+  // initialize stripe key
+  stripe.Stripe.publishableKey =
+      'pk_test_51Oo7iUBS0FxsTGxKjGZSQqzDKWHY5ZFYM9XeI0qSdIh2w8jWy6GhHlYpT7GLTzgpl1xhE5YP4BXpA4gMZqPmgMId00cGFYFzbh';
+
 
   BackgroundFetch.registerHeadlessTask(backgroundHeadlessTask);
 
@@ -53,6 +63,9 @@ class Startup {
     settings = await database.query.getSettings(database);
     user = await database.query.getUsers(settings);
 
+    // Set all notification categories to seen to avoid having notifications that the user has already seen in the app
+    NotificationsHelper().setAllCategoriesSeen(user);
+
     late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
     // Notifications setup
     if (!kIsWeb) {
@@ -113,6 +126,7 @@ class Startup {
       // Initialize notifications
       await flutterLocalNotificationsPlugin.initialize(
         initializationSettings,
+        onDidReceiveNotificationResponse: NotificationsHelper().onDidReceiveNotificationResponse,
       );
     }
 
diff --git a/refilc/lib/utils/navigation_service.dart b/refilc/lib/utils/navigation_service.dart
new file mode 100644
index 0000000..ee8a479
--- /dev/null
+++ b/refilc/lib/utils/navigation_service.dart
@@ -0,0 +1,9 @@
+import 'package:flutter/material.dart';
+
+class NavigationService {
+  final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
+
+  Future<dynamic> navigateTo(String routeName) {
+    return navigatorKey.currentState!.pushNamed(routeName);
+  }
+}
\ No newline at end of file
diff --git a/refilc/lib/utils/service_locator.dart b/refilc/lib/utils/service_locator.dart
new file mode 100644
index 0000000..0ca94b7
--- /dev/null
+++ b/refilc/lib/utils/service_locator.dart
@@ -0,0 +1,8 @@
+import 'package:get_it/get_it.dart';
+import 'package:refilc/utils/navigation_service.dart';
+
+GetIt locator = GetIt.instance;
+
+void setupLocator() {
+  locator.registerLazySingleton(() => NavigationService());
+}
\ No newline at end of file
diff --git a/refilc/pubspec.yaml b/refilc/pubspec.yaml
index 842ea9f..fbc9620 100644
--- a/refilc/pubspec.yaml
+++ b/refilc/pubspec.yaml
@@ -77,6 +77,8 @@ dependencies:
   extension_google_sign_in_as_googleapis_auth: ^2.0.12
   maps_launcher: ^2.2.0
   google_fonts: ^6.1.0
+  flutter_stripe: ^10.0.0
+  get_it: ^7.6.7
 
 dev_dependencies:
   flutter_lints: ^3.0.1
@@ -166,6 +168,7 @@ flutter:
           weight: 500
 
 
+
 flutter_launcher_icons:
   image_path: assets/icons/ic_android.png
   android: true
diff --git a/refilc_kreta_api/lib/models/absence.dart b/refilc_kreta_api/lib/models/absence.dart
index 232f671..5baad76 100644
--- a/refilc_kreta_api/lib/models/absence.dart
+++ b/refilc_kreta_api/lib/models/absence.dart
@@ -50,6 +50,7 @@ class Absence {
     DateTime lessonStart;
     DateTime lessonEnd;
     int? lessonIndex;
+    bool isSeen = json["isSeen"] ?? false;
     if (json["Ora"] != null) {
       lessonStart = json["Ora"]["KezdoDatum"] != null
           ? DateTime.parse(json["Ora"]["KezdoDatum"]).toLocal()
@@ -62,7 +63,6 @@ class Absence {
       lessonStart = DateTime(0);
       lessonEnd = DateTime(0);
     }
-
     return Absence(
       id: json["Uid"],
       date: json["Datum"] != null
@@ -89,7 +89,7 @@ class Absence {
       lessonIndex: lessonIndex,
       group:
           json["OsztalyCsoport"] != null ? json["OsztalyCsoport"]["Uid"] : "",
-      isSeen: false,
+      isSeen: json["isSeen"] ?? false,
       json: json,
     );
   }
diff --git a/refilc_kreta_api/lib/providers/grade_provider.dart b/refilc_kreta_api/lib/providers/grade_provider.dart
index c3918ba..3ab9701 100644
--- a/refilc_kreta_api/lib/providers/grade_provider.dart
+++ b/refilc_kreta_api/lib/providers/grade_provider.dart
@@ -1,5 +1,6 @@
 import 'package:refilc/api/providers/user_provider.dart';
 import 'package:refilc/api/providers/database_provider.dart';
+import 'package:refilc/helpers/notification_helper.dart';
 import 'package:refilc/models/settings.dart';
 import 'package:refilc/models/user.dart';
 import 'package:refilc_kreta_api/client/api.dart';
@@ -49,7 +50,7 @@ class GradeProvider with ChangeNotifier {
     String? userId = _user.id;
     if (userId != null) {
       final userStore = _database.userStore;
-      userStore.storeLastSeenGrade(DateTime.now(), userId: userId);
+      userStore.storeLastSeen(DateTime.now(), userId: userId, category: LastSeenCategory.surprisegrade);
       _lastSeen = DateTime.now();
     }
   }
@@ -58,7 +59,7 @@ class GradeProvider with ChangeNotifier {
     String? userId = _user.id;
     if (userId != null) {
       final userStore = _database.userStore;
-      userStore.storeLastSeenGrade(DateTime(1969), userId: userId);
+      userStore.storeLastSeen(DateTime(1969), userId: userId, category: LastSeenCategory.surprisegrade);
       _lastSeen = DateTime(1969);
     }
   }
@@ -74,7 +75,7 @@ class GradeProvider with ChangeNotifier {
       await convertBySettings();
       _groupAvg = await userQuery.getGroupAverages(userId: userId);
       notifyListeners();
-      DateTime lastSeenDB = await userQuery.lastSeenGrade(userId: userId);
+      DateTime lastSeenDB = await userQuery.lastSeen(userId: userId, category: LastSeenCategory.surprisegrade);
       if (lastSeenDB.millisecondsSinceEpoch == 0 ||
           lastSeenDB.year == 0 ||
           !_settings.gradeOpeningFun) {
diff --git a/refilc_mobile_ui/lib/screens/navigation/navigation_screen.dart b/refilc_mobile_ui/lib/screens/navigation/navigation_screen.dart
index 820b87f..b12c5a7 100644
--- a/refilc_mobile_ui/lib/screens/navigation/navigation_screen.dart
+++ b/refilc_mobile_ui/lib/screens/navigation/navigation_screen.dart
@@ -5,6 +5,8 @@ import 'package:refilc/helpers/quick_actions.dart';
 import 'package:refilc/icons/filc_icons.dart';
 import 'package:refilc/models/settings.dart';
 import 'package:refilc/theme/observer.dart';
+import 'package:refilc/utils/navigation_service.dart';
+import 'package:refilc/utils/service_locator.dart';
 import 'package:refilc_kreta_api/client/client.dart';
 import 'package:refilc_kreta_api/providers/grade_provider.dart';
 import 'package:refilc_mobile_ui/common/system_chrome.dart';
@@ -45,7 +47,7 @@ class NavigationScreenState extends State<NavigationScreen>
     with WidgetsBindingObserver {
   late NavigationRoute selected;
   List<String> initializers = [];
-  final _navigatorState = GlobalKey<NavigatorState>();
+  final _navigatorState = locator<NavigationService>().navigatorKey;
 
   late SettingsProvider settings;
   late NewsProvider newsProvider;
diff --git a/refilc_mobile_ui/lib/screens/settings/notifications_screen.dart b/refilc_mobile_ui/lib/screens/settings/notifications_screen.dart
index 6066691..5aeae16 100644
--- a/refilc_mobile_ui/lib/screens/settings/notifications_screen.dart
+++ b/refilc_mobile_ui/lib/screens/settings/notifications_screen.dart
@@ -1,12 +1,17 @@
+import 'package:flutter/foundation.dart';
+import 'package:refilc/api/providers/database_provider.dart';
+import 'package:refilc/api/providers/user_provider.dart';
+import 'package:refilc/helpers/notification_helper.dart';
 import 'package:refilc/models/settings.dart';
+import 'package:refilc/models/user.dart';
 import 'package:refilc/theme/colors/colors.dart';
 import 'package:refilc_mobile_ui/common/beta_chip.dart';
-import 'package:refilc_mobile_ui/common/panel/panel.dart';
 import 'package:refilc_mobile_ui/common/panel/panel_button.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_feather_icons/flutter_feather_icons.dart';
 import 'package:provider/provider.dart';
+import 'package:refilc_mobile_ui/common/splitted_panel/splitted_panel.dart';
 import 'notifications_screen.i18n.dart';
 
 class MenuNotifications extends StatelessWidget {
@@ -53,6 +58,19 @@ class MenuNotifications extends StatelessWidget {
 class NotificationsScreen extends StatelessWidget {
   const NotificationsScreen({super.key});
 
+  // Set all notification categories as seen to avoid spamming the user with notifications when they turn on notifications
+  void setAll(BuildContext context, DateTime date) {
+    DatabaseProvider database =
+        Provider.of<DatabaseProvider>(context, listen: false);
+    User? user = Provider.of<UserProvider>(context, listen: false).user;
+    if (user != null) {
+      for (LastSeenCategory category in LastSeenCategory.values) {
+        database.userStore
+            .storeLastSeen(date, userId: user.id, category: category);
+      }
+    }
+  }
+
   @override
   Widget build(BuildContext context) {
     SettingsProvider settings = Provider.of<SettingsProvider>(context);
@@ -69,151 +87,188 @@ class NotificationsScreen extends StatelessWidget {
       body: SingleChildScrollView(
         child: Padding(
           padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
-          child: Panel(
-            child: Column(
-              children: [
-                Material(
-                  type: MaterialType.transparency,
-                  child: SwitchListTile(
-                    shape: RoundedRectangleBorder(
-                        borderRadius: BorderRadius.circular(12.0)),
-                    value: settings.notificationsGradesEnabled,
-                    onChanged: (v) =>
-                        settings.update(notificationsGradesEnabled: v),
-                    title: Row(
-                      children: [
-                        Icon(
-                          FeatherIcons.bookmark,
-                          color: settings.notificationsGradesEnabled
-                              ? Theme.of(context).colorScheme.secondary
-                              : AppColors.of(context).text.withOpacity(.25),
-                        ),
-                        const SizedBox(width: 14.0),
-                        Expanded(
-                          child: Text(
-                            "grades".i18n,
-                            style: TextStyle(
-                              fontWeight: FontWeight.w600,
-                              fontSize: 16.0,
-                              color: AppColors.of(context).text.withOpacity(
-                                    settings.notificationsGradesEnabled
-                                        ? 1.0
-                                        : .5,
-                                  ),
-                            ),
-                          ),
-                        ),
-                      ],
+          child: Column(
+            children: [
+              SplittedPanel(
+                padding: const EdgeInsets.only(top: 8.0),
+                cardPadding: const EdgeInsets.all(4.0),
+                isSeparated: true,
+                children: [
+                  PanelButton(
+                    padding: const EdgeInsets.only(left: 14.0, right: 6.0),
+                    onPressed: () {
+                      settings.update(
+                          notificationsGradesEnabled:
+                              !settings.notificationsGradesEnabled);
+                      setAll(context, DateTime.now());
+                    },
+                    title: Text(
+                      "grades".i18n,
+                      style: TextStyle(
+                        color: AppColors.of(context).text.withOpacity(
+                            settings.notificationsGradesEnabled ? .95 : .25),
+                      ),
+                    ),
+                    leading: Icon(
+                      FeatherIcons.bookmark,
+                      size: 22.0,
+                      color: AppColors.of(context).text.withOpacity(
+                          settings.notificationsGradesEnabled ? .95 : .25),
+                    ),
+                    trailing: Switch(
+                      onChanged: (v) =>
+                          settings.update(notificationsGradesEnabled: v),
+                      value: settings.notificationsGradesEnabled,
+                      activeColor: Theme.of(context).colorScheme.secondary,
+                    ),
+                    borderRadius: const BorderRadius.vertical(
+                      top: Radius.circular(12.0),
+                      bottom: Radius.circular(12.0),
                     ),
                   ),
-                ),
-                Material(
-                  type: MaterialType.transparency,
-                  child: SwitchListTile(
-                    shape: RoundedRectangleBorder(
-                        borderRadius: BorderRadius.circular(12.0)),
-                    value: settings.notificationsAbsencesEnabled,
-                    onChanged: (v) =>
-                        settings.update(notificationsAbsencesEnabled: v),
-                    title: Row(
-                      children: [
-                        Icon(
-                          FeatherIcons.clock,
-                          color: settings.notificationsAbsencesEnabled
-                              ? Theme.of(context).colorScheme.secondary
-                              : AppColors.of(context).text.withOpacity(.25),
-                        ),
-                        const SizedBox(width: 14.0),
-                        Expanded(
-                          child: Text(
-                            "absences".i18n,
-                            style: TextStyle(
-                              fontWeight: FontWeight.w600,
-                              fontSize: 16.0,
-                              color: AppColors.of(context).text.withOpacity(
-                                    settings.notificationsAbsencesEnabled
-                                        ? 1.0
-                                        : .5,
-                                  ),
-                            ),
-                          ),
-                        ),
-                      ],
+                ],
+              ),
+              SplittedPanel(
+                padding: const EdgeInsets.only(top: 8.0),
+                cardPadding: const EdgeInsets.all(4.0),
+                isSeparated: true,
+                children: [
+                  PanelButton(
+                    padding: const EdgeInsets.only(left: 14.0, right: 6.0),
+                    onPressed: () {
+                      settings.update(
+                          notificationsAbsencesEnabled:
+                              !settings.notificationsAbsencesEnabled);
+                      setAll(context, DateTime.now());
+                    },
+                    title: Text(
+                      "absences".i18n,
+                      style: TextStyle(
+                        color: AppColors.of(context).text.withOpacity(
+                            settings.notificationsAbsencesEnabled ? .95 : .25),
+                      ),
+                    ),
+                    leading: Icon(
+                      FeatherIcons.clock,
+                      size: 22.0,
+                      color: AppColors.of(context).text.withOpacity(
+                          settings.notificationsAbsencesEnabled ? .95 : .25),
+                    ),
+                    trailing: Switch(
+                      onChanged: (v) =>
+                          settings.update(notificationsAbsencesEnabled: v),
+                      value: settings.notificationsAbsencesEnabled,
+                      activeColor: Theme.of(context).colorScheme.secondary,
+                    ),
+                    borderRadius: const BorderRadius.vertical(
+                      top: Radius.circular(12.0),
+                      bottom: Radius.circular(12.0),
                     ),
                   ),
-                ),
-                Material(
-                  type: MaterialType.transparency,
-                  child: SwitchListTile(
-                    shape: RoundedRectangleBorder(
-                        borderRadius: BorderRadius.circular(12.0)),
-                    value: settings.notificationsMessagesEnabled,
-                    onChanged: (v) =>
-                        settings.update(notificationsMessagesEnabled: v),
-                    title: Row(
-                      children: [
-                        Icon(
-                          FeatherIcons.messageSquare,
-                          color: settings.notificationsMessagesEnabled
-                              ? Theme.of(context).colorScheme.secondary
-                              : AppColors.of(context).text.withOpacity(.25),
-                        ),
-                        const SizedBox(width: 14.0),
-                        Expanded(
-                          child: Text(
-                            "messages".i18n,
-                            style: TextStyle(
-                              fontWeight: FontWeight.w600,
-                              fontSize: 16.0,
-                              color: AppColors.of(context).text.withOpacity(
-                                    settings.notificationsMessagesEnabled
-                                        ? 1.0
-                                        : .5,
-                                  ),
-                            ),
-                          ),
-                        ),
-                      ],
+                ],
+              ),
+              SplittedPanel(
+                padding: const EdgeInsets.only(top: 8.0),
+                cardPadding: const EdgeInsets.all(4.0),
+                isSeparated: true,
+                children: [
+                  PanelButton(
+                    padding: const EdgeInsets.only(left: 14.0, right: 6.0),
+                    onPressed: () {
+                      settings.update(
+                          notificationsMessagesEnabled:
+                              !settings.notificationsMessagesEnabled);
+                      setAll(context, DateTime.now());
+                    },
+                    title: Text(
+                      "messages".i18n,
+                      style: TextStyle(
+                        color: AppColors.of(context).text.withOpacity(
+                            settings.notificationsMessagesEnabled ? .95 : .25),
+                      ),
+                    ),
+                    leading: Icon(
+                      FeatherIcons.messageSquare,
+                      size: 22.0,
+                      color: AppColors.of(context).text.withOpacity(
+                          settings.notificationsMessagesEnabled ? .95 : .25),
+                    ),
+                    trailing: Switch(
+                      onChanged: (v) =>
+                          settings.update(notificationsMessagesEnabled: v),
+                      value: settings.notificationsMessagesEnabled,
+                      activeColor: Theme.of(context).colorScheme.secondary,
+                    ),
+                    borderRadius: const BorderRadius.vertical(
+                      top: Radius.circular(12.0),
+                      bottom: Radius.circular(12.0),
                     ),
                   ),
-                ),
-                Material(
-                  type: MaterialType.transparency,
-                  child: SwitchListTile(
-                    shape: RoundedRectangleBorder(
-                        borderRadius: BorderRadius.circular(12.0)),
-                    value: settings.notificationsLessonsEnabled,
-                    onChanged: (v) =>
-                        settings.update(notificationsLessonsEnabled: v),
-                    title: Row(
-                      children: [
-                        Icon(
-                          FeatherIcons.calendar,
-                          color: settings.notificationsLessonsEnabled
-                              ? Theme.of(context).colorScheme.secondary
-                              : AppColors.of(context).text.withOpacity(.25),
-                        ),
-                        const SizedBox(width: 14.0),
-                        Expanded(
-                          child: Text(
-                            "lessons".i18n,
-                            style: TextStyle(
-                              fontWeight: FontWeight.w600,
-                              fontSize: 16.0,
-                              color: AppColors.of(context).text.withOpacity(
-                                    settings.notificationsLessonsEnabled
-                                        ? 1.0
-                                        : .5,
-                                  ),
-                            ),
-                          ),
-                        ),
-                      ],
+                ],
+              ),
+              SplittedPanel(
+                padding: const EdgeInsets.only(top: 8.0),
+                cardPadding: const EdgeInsets.all(4.0),
+                isSeparated: true,
+                children: [
+                  PanelButton(
+                    padding: const EdgeInsets.only(left: 14.0, right: 6.0),
+                    onPressed: () {
+                      settings.update(
+                          notificationsLessonsEnabled:
+                              !settings.notificationsLessonsEnabled);
+                      setAll(context, DateTime.now());
+                    },
+                    title: Text(
+                      "lessons".i18n,
+                      style: TextStyle(
+                        color: AppColors.of(context).text.withOpacity(
+                            settings.notificationsLessonsEnabled ? .95 : .25),
+                      ),
+                    ),
+                    leading: Icon(
+                      FeatherIcons.bookmark,
+                      size: 22.0,
+                      color: AppColors.of(context).text.withOpacity(
+                          settings.notificationsLessonsEnabled ? .95 : .25),
+                    ),
+                    trailing: Switch(
+                      onChanged: (v) =>
+                          settings.update(notificationsLessonsEnabled: v),
+                      value: settings.notificationsLessonsEnabled,
+                      activeColor: Theme.of(context).colorScheme.secondary,
+                    ),
+                    borderRadius: const BorderRadius.vertical(
+                      top: Radius.circular(12.0),
+                      bottom: Radius.circular(12.0),
                     ),
                   ),
-                ),
-              ],
-            ),
+                ],
+              ),
+              // only used for debugging, pressing **will** cause notification spam
+              kDebugMode
+                  ? SplittedPanel(
+                      padding: const EdgeInsets.only(top: 9.0),
+                      cardPadding: const EdgeInsets.all(4.0),
+                      isSeparated: true,
+                      children: [
+                        PanelButton(
+                          onPressed: () => setAll(
+                              context, DateTime(1970, 1, 1, 0, 0, 0, 0, 0)),
+                          title: Text("set_all_as_unseen".i18n),
+                          leading: Icon(
+                            FeatherIcons.mail,
+                            size: 22.0,
+                            color: AppColors.of(context).text.withOpacity(0.95),
+                          ),
+                          borderRadius: const BorderRadius.vertical(
+                              top: Radius.circular(12.0),
+                              bottom: Radius.circular(4.0)),
+                        )
+                      ],
+                    )
+                  : const SizedBox.shrink(),
+            ],
           ),
         ),
       ),
diff --git a/refilc_mobile_ui/lib/screens/settings/notifications_screen.i18n.dart b/refilc_mobile_ui/lib/screens/settings/notifications_screen.i18n.dart
index c9d0087..310779f 100644
--- a/refilc_mobile_ui/lib/screens/settings/notifications_screen.i18n.dart
+++ b/refilc_mobile_ui/lib/screens/settings/notifications_screen.i18n.dart
@@ -8,7 +8,8 @@ extension SettingsLocalization on String {
           "grades": "Grades",
           "absences": "Absences",
           "messages": "Messages",
-          "lessons": "Lessons"
+          "lessons": "Lessons",
+          "set_all_as_unseen": "Set all as unseen",
           
         },
         "hu_hu": {
@@ -16,14 +17,16 @@ extension SettingsLocalization on String {
           "grades": "Jegyek",
           "absences": "Hiányzások",
           "messages": "Üzenetek",
-          "lessons": "Órák"
+          "lessons": "Órák",
+          "set_all_as_unseen": "Összes kategória beállítása olvasatlannak",
         },
         "de_de": {
           "notifications_screen": "Mitteilung",
           "grades": "Noten",
           "absences": "Fehlen",
           "messages": "Nachrichten",
-          "lessons": "Unterricht"
+          "lessons": "Unterricht",
+          "set_all_as_unseen": "Alle als ungelesen einstellen",
         },
       };
 
diff --git a/refilc_mobile_ui/pubspec.yaml b/refilc_mobile_ui/pubspec.yaml
index dfc0a70..2fd214e 100644
--- a/refilc_mobile_ui/pubspec.yaml
+++ b/refilc_mobile_ui/pubspec.yaml
@@ -66,9 +66,10 @@ dependencies:
   google_fonts: ^6.1.0
   flutter_any_logo: ^1.1.1
   custom_sliding_segmented_control: ^1.8.1
-  
+  get_it: ^7.6.7
+
 dev_dependencies:
   flutter_lints: ^3.0.1
 
 flutter:
-  uses-material-design: true
\ No newline at end of file
+  uses-material-design: true