Index: ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/filter/InviteFilter.java
===================================================================
--- ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/filter/InviteFilter.java	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-backend/src/main/java/mk/ukim/finki/it/reservengo/config/filter/InviteFilter.java	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -28,5 +28,14 @@
         String path = request.getRequestURI();
 
+
         if (path.contains("/register/local-manager") || path.contains("/register/local-worker") || path.contains("/register/invite/check")) {
+
+            //Solution for bug
+            if (request.getMethod().equals("OPTIONS")) {
+                filterChain.doFilter(request, response);
+                return;
+            }
+            //Solution for bug
+
             if (token == null || token.isEmpty()) {
                 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
Index: ReserveNGo-frontend/src/Api_Classes/HttpClient.js
===================================================================
--- ReserveNGo-frontend/src/Api_Classes/HttpClient.js	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/Api_Classes/HttpClient.js	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -100,9 +100,10 @@
     return this.json(endpoint, 'PUT', data, options)
   }
-
+  patch(endpoint, data, options = {}) {
+    return this.json(endpoint, 'PATCH', data, options)
+  }
   delete(endpoint, body= null, options = {}) {
     return this.json(endpoint, 'DELETE', body, options)
   }
-
   upload(endpoint, formData, options = {}) {
     return this.form(endpoint, 'POST', formData, options)
Index: ReserveNGo-frontend/src/App.vue
===================================================================
--- ReserveNGo-frontend/src/App.vue	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/App.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -6,4 +6,5 @@
     </main>
   </div>
+  <ToastContainer></ToastContainer>
 </template>
 
@@ -11,7 +12,8 @@
 import NavBar from './components/Project/Nav_bar_new.vue'
 import { userStore } from '@/PiniaStores/UserStore.js'
+import ToastContainer from './components/Project/Utility/ToastContainer.vue'
 
 export default {
-  components: { NavBar },
+  components: { NavBar, ToastContainer },
   beforeMount() {
     userStore().getLocalStorage()
Index: ReserveNGo-frontend/src/PiniaStores/UserStore.js
===================================================================
--- ReserveNGo-frontend/src/PiniaStores/UserStore.js	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/PiniaStores/UserStore.js	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -102,4 +102,16 @@
     getToken(){
       return 'Bearer ' + this.data.token;
+    },
+    isLocaleManager(){
+      return this.data.role === "ROLE_LOCAL_MANAGER";
+    },
+    isLocaleWorker(){
+      return this.data.role === "ROLE_LOCAL_WORKER";
+    },
+    isCustomer(){
+      return this.data.role === "ROLE_CUSTOMER";
+    },
+    isAdmin(){
+      return this.data.role === "ROLE_ADMIN";
     }
   }
Index: ReserveNGo-frontend/src/components/Project/Admin/AdminDashboard.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Admin/AdminDashboard.vue	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/components/Project/Admin/AdminDashboard.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -1,6 +1,11 @@
 <script>
 import { userStore } from '@/PiniaStores/UserStore.js'
+import { useToasts } from '@/composables/useToast.js'
+import { isValidEmail } from '@/mixins/utilFunctions.js'
+import { useAdmin } from '@/repository/Admin.ts'
+import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
 
 export default {
+  components: { LoadingIcon },
   data() {
     return {
@@ -16,146 +21,150 @@
       selectedLocalId: null,
       useUserStore: userStore(),
+      emailToManager: '',
+      showToast: useToasts().showToast,
+      isEmailSending: false,
+      isAddingRestaurant: false,
+      assigningManagerId: null,
+      removingManagerId: null,
     }
   },
   computed: {
     sortedRestaurants() {
-      if (!this.sortKey) return this.restaurants;
-
+      if (!this.sortKey) return this.restaurants
       return [...this.restaurants].sort((a, b) => {
-        let valueA = a[this.sortKey];
-        let valueB = b[this.sortKey];
-
+        let valueA = a[this.sortKey]
+        let valueB = b[this.sortKey]
         if (this.sortKey === 'createdAt' || this.sortKey === 'modifiedAt') {
-          valueA = new Date(valueA);
-          valueB = new Date(valueB);
+          valueA = new Date(valueA)
+          valueB = new Date(valueB)
         }
-
-        if (valueA < valueB) return this.sortOrder === 'asc' ? -1 : 1;
-        if (valueA > valueB) return this.sortOrder === 'asc' ? 1 : -1;
-        return 0;
-      });
-    }
+        if (valueA < valueB) return this.sortOrder === 'asc' ? -1 : 1
+        if (valueA > valueB) return this.sortOrder === 'asc' ? 1 : -1
+        return 0
+      })
+    },
   },
   methods: {
     sortBy(key) {
       if (this.sortKey === key) {
-        this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc';
+        this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc'
       } else {
-        this.sortKey = key;
-        this.sortOrder = 'asc';
+        this.sortKey = key
+        this.sortOrder = 'asc'
       }
     },
     formatDate(dateStr) {
-      const date = new Date(dateStr);
-      return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
-    },
-    removeRestaurant(localId) {
-      fetch(`http://localhost:8080/api/admin/delete-local/${localId}`, {
-        method: 'DELETE',
-        headers: {
-          'Content-Type': 'application/json',
-          Authorization: this.useUserStore.getToken },
-      })
-        .then((response) => {
-          if (!response.ok) console.log(response);
-          this.fetchRestaurants();
-        })
-        .catch((error) => console.log(error));
+      const date = new Date(dateStr)
+      return date.toLocaleDateString() + ' ' + date.toLocaleTimeString()
+    },
+    async removeRestaurant(localId) {
+      if (
+        !confirm('Are you sure you want to delete this restaurant? This action cannot be undone.')
+      )
+        return
+
+      try {
+        await useAdmin.deleteRestaurant(localId)
+        this.showToast('Restaurant successfully deleted!')
+        this.fetchRestaurants()
+      } catch (error) {
+        this.showToast(error.response || 'Failed to delete restaurant.', 'error')
+      }
     },
     fetchRestaurants() {
-      fetch('http://localhost:8080/api/admin/locals', {
-        method: 'GET',
-        headers: {
-          'Content-Type': 'application/json',
-          'Authorization': this.useUserStore.getToken
-        },
-      })
-        .then((res) => res.json())
-        .then((data) => (this.restaurants = data))
-        .catch((err) => console.log(err));
+      useAdmin
+        .fetchRestaurants()
+        .then((res) => (this.restaurants = res))
+        .catch((err) => console.log(err))
     },
     fetchManagers() {
-      fetch("http://localhost:8080/api/admin/local-managers", {
-        method: 'GET',
-        headers: {
-          'Content-Type': 'application/json',
-          Authorization: this.useUserStore.getToken
-        }
-      })
-        .then((res) => res.json())
-        .then((data) => (this.managers = data))
-        .catch((err) => console.log(err));
+      useAdmin
+        .fetchLocalMangers()
+        .then((res) => (this.managers = res))
+        .catch((err) => console.log(err))
     },
     fetchManagersForRestaurant(localId) {
-      fetch(`http://localhost:8080/api/admin/local-managers/${localId}`, {
-        method: 'GET',
-        headers: {
-          'Content-Type': 'application/json',
-          Authorization: this.useUserStore.getToken
-        }
-      })
-        .then((res) => res.json())
-        .then((data) => (this.managersForLocal = data))
-        .catch((err) => console.log(err));
-    },
-    assignManager(localId, managerId) {
-      fetch(`http://localhost:8080/api/admin/assign/${localId}/${managerId}`, {
-        method: 'POST',
-        headers: {
-          'Content-Type': 'application/json',
-          'Authorization': this.useUserStore.getToken
-        }
-      })
-        .then((response) => {
-          if (!response.ok) throw new Error('Failed to assign manager');
-          this.managers = this.managers.filter(manager => manager.id !== managerId);
-          this.fetchRestaurants();
-          this.fetchManagersForRestaurant(localId);
-        })
-        .catch((error) => console.log(error));
-    },
-    removeManager(localId, managerId) {
-      fetch(`http://localhost:8080/api/admin/remove/${managerId}`, {
-        method: 'DELETE',
-        headers: {
-          'Content-Type': 'application/json',
-          'Authorization': this.useUserStore.getToken
-        }
-      })
-        .then((response) => {
-          if (!response.ok) throw new Error('Failed to remove manager');
-          this.fetchManagersForRestaurant(localId);
-        })
-        .catch((error) => console.log(error));
-    },
+      useAdmin
+        .fetchManagersForRestaurant(localId)
+        .then((res) => (this.managersForLocal = res))
+        .catch((err) => console.log(err))
+    },
+
+    async assignManager(localId, manager) {
+      this.assigningManagerId = manager.id
+      try {
+        await useAdmin.assignManager(localId, manager.id)
+        this.showToast(`Assigned ${manager.firstName} successfully.`, 'success')
+        this.fetchManagers()
+        this.fetchManagersForRestaurant(localId)
+      } catch (error) {
+        this.showToast(error.response || 'Failed to assign manager.', 'error')
+      } finally {
+        this.assigningManagerId = null
+      }
+    },
+
+    async removeManager(localId, manager) {
+      this.removingManagerId = manager.id
+      try {
+        await useAdmin.removeManager(manager.id)
+        this.showToast(`Removed ${manager.firstName} successfully.`, 'success')
+        this.fetchManagersForRestaurant(localId)
+      } catch (error) {
+        this.showToast(error.response || 'Failed to remove manager.', 'error')
+      } finally {
+        this.removingManagerId = null
+      }
+    },
+
     async addRestaurant() {
-      await fetch('http://localhost:8080/api/admin/add-local', {
-        method: 'POST',
-        headers: {
-          'Content-Type': 'application/json',
-          'Authorization': this.useUserStore.getToken
-        },
-        body: JSON.stringify({ name: this.name })
-      })
-        .then((response) => {
-          if (!response.ok) throw new Error('Failed to add restaurant');
-          this.fetchRestaurants();
-          this.showAddRestaurantModal = false;
-        })
-        .catch((error) => console.log(error));
-    },
+      this.isAddingRestaurant = true
+      try {
+        await useAdmin.addRestaurant(this.name)
+        this.showToast('Restaurant added successfully!', 'success')
+        this.fetchRestaurants()
+        this.showAddRestaurantModal = false
+        this.name = ''
+      } catch (error) {
+        this.showToast(error.response || 'Failed to add restaurant.', 'error')
+      } finally {
+        this.isAddingRestaurant = false
+      }
+    },
+
     openAddManagerModal(localId) {
-      this.selectedLocalId = localId;
-      this.fetchManagers();
-      this.showAddManagerModal = true;
+      this.selectedLocalId = localId
+      this.fetchManagers()
+      this.showAddManagerModal = true
     },
     openEditManagersModal(localId) {
-      this.selectedLocalId = localId;
-      this.fetchManagersForRestaurant(localId);
-      this.showEditRestaurantManagersModal = true;
-    }
+      this.selectedLocalId = localId
+      this.fetchManagersForRestaurant(localId)
+      this.showEditRestaurantManagersModal = true
+    },
+
+    async sendEmailToManager() {
+      if (this.emailToManager === '') {
+        this.showToast('Fill out the email form', 'error')
+        return
+      }
+      if (!isValidEmail(this.emailToManager)) {
+        this.showToast('Please enter a valid email format', 'error')
+        return
+      }
+      this.isEmailSending = true
+      try {
+        await useAdmin.inviteManager(this.emailToManager)
+        this.showToast(`Invite sent to ${this.emailToManager}`, 'success')
+        this.emailToManager = ''
+      } catch (error) {
+        this.showToast(error.response || 'Failed to send email.', 'error')
+      } finally {
+        this.isEmailSending = false
+      }
+    },
   },
   mounted() {
-    this.fetchRestaurants();
+    this.fetchRestaurants()
   },
 }
@@ -167,10 +176,19 @@
 
     <!-- Add Restaurant Modal -->
-    <div v-if="showAddRestaurantModal" class="modal fade show d-block" tabindex="-1" style="background: rgba(0,0,0,0.5);">
+    <div
+      v-if="showAddRestaurantModal"
+      class="modal fade show d-block"
+      tabindex="-1"
+      style="background: rgba(0, 0, 0, 0.5)"
+    >
       <div class="modal-dialog">
         <div class="modal-content">
           <div class="modal-header">
             <h5 class="modal-title">Add New Restaurant</h5>
-            <button type="button" class="btn-close" @click="showAddRestaurantModal = false"></button>
+            <button
+              type="button"
+              class="btn-close"
+              @click="showAddRestaurantModal = false"
+            ></button>
           </div>
           <div class="modal-body">
@@ -178,7 +196,17 @@
               <div class="mb-3">
                 <label for="name" class="form-label">Restaurant Name</label>
-                <input v-model="name" type="text" id="name" class="form-control" placeholder="Enter restaurant name" required>
+                <input
+                  v-model="name"
+                  type="text"
+                  id="name"
+                  class="form-control"
+                  placeholder="Enter restaurant name"
+                  required
+                />
               </div>
-              <button type="submit" class="btn btn-primary">Add</button>
+              <button type="submit" class="btn btn-primary" :disabled="isAddingRestaurant">
+                <LoadingIcon v-if="isAddingRestaurant" />
+                {{ isAddingRestaurant ? 'Adding...' : 'Add' }}
+              </button>
             </form>
           </div>
@@ -188,5 +216,10 @@
 
     <!-- Add Manager Modal -->
-    <div v-if="showAddManagerModal" class="modal fade show d-block" tabindex="-1" style="background: rgba(0,0,0,0.5);">
+    <div
+      v-if="showAddManagerModal"
+      class="modal fade show d-block"
+      tabindex="-1"
+      style="background: rgba(0, 0, 0, 0.5)"
+    >
       <div class="modal-dialog modal-lg">
         <div class="modal-content">
@@ -197,7 +230,18 @@
           <div class="modal-body">
             <ul class="list-group">
-              <li v-for="manager in managers" :key="manager.id" class="list-group-item d-flex justify-content-between align-items-center">
+              <li
+                v-for="manager in managers"
+                :key="manager.id"
+                class="list-group-item d-flex justify-content-between align-items-center"
+              >
                 <span>{{ manager.firstName }} {{ manager.lastName }} - {{ manager.email }}</span>
-                <button class="btn btn-sm btn-success" @click="assignManager(selectedLocalId, manager.id)">Add</button>
+                <button
+                  class="btn btn-sm btn-success"
+                  @click="assignManager(selectedLocalId, manager)"
+                  :disabled="assigningManagerId === manager.id"
+                >
+                  <LoadingIcon v-if="assigningManagerId === manager.id" />
+                  {{ assigningManagerId === manager.id ? 'Adding...' : 'Add' }}
+                </button>
               </li>
             </ul>
@@ -208,16 +252,36 @@
 
     <!-- Edit Managers Modal -->
-    <div v-if="showEditRestaurantManagersModal" class="modal fade show d-block" tabindex="-1" style="background: rgba(0,0,0,0.5);">
+    <div
+      v-if="showEditRestaurantManagersModal"
+      class="modal fade show d-block"
+      tabindex="-1"
+      style="background: rgba(0, 0, 0, 0.5)"
+    >
       <div class="modal-dialog modal-lg">
         <div class="modal-content">
           <div class="modal-header">
             <h5 class="modal-title">Restaurant Managers</h5>
-            <button type="button" class="btn-close" @click="showEditRestaurantManagersModal = false"></button>
+            <button
+              type="button"
+              class="btn-close"
+              @click="showEditRestaurantManagersModal = false"
+            ></button>
           </div>
           <div class="modal-body">
             <ul class="list-group">
-              <li v-for="manager in managersForLocal" :key="manager.id" class="list-group-item d-flex justify-content-between align-items-center">
+              <li
+                v-for="manager in managersForLocal"
+                :key="manager.id"
+                class="list-group-item d-flex justify-content-between align-items-center"
+              >
                 <span>{{ manager.firstName }} {{ manager.lastName }} - {{ manager.email }}</span>
-                <button class="btn btn-sm btn-danger" @click="removeManager(selectedLocalId, manager.id)">Remove</button>
+                <button
+                  class="btn btn-sm btn-danger"
+                  @click="removeManager(selectedLocalId, manager)"
+                  :disabled="removingManagerId === manager.id"
+                >
+                  <LoadingIcon v-if="removingManagerId === manager.id" />
+                  {{ removingManagerId === manager.id ? 'Removing...' : 'Remove' }}
+                </button>
               </li>
             </ul>
@@ -227,63 +291,86 @@
     </div>
 
-    <!-- Restaurants Table -->
     <div class="table-responsive shadow-sm table-container">
       <table class="table table-striped table-hover align-middle">
         <thead class="table-light">
-        <tr>
-          <th style="width: 80px;">Logo</th>
-          <th style="width: 200px; cursor: pointer;" @click="sortBy('localName')">
-            Name
-            <span v-if="sortKey === 'localName'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
-          </th>
-          <th style="width: 180px; cursor: pointer;" @click="sortBy('createdAt')">
-            Created At
-            <span v-if="sortKey === 'createdAt'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
-          </th>
-          <th style="width: 180px; cursor: pointer;" @click="sortBy('modifiedAt')">
-            Modified At
-            <span v-if="sortKey === 'modifiedAt'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
-          </th>
-          <th class="text-end" style="width: 220px;">Actions</th>
-        </tr>
+          <tr>
+            <th style="width: 80px">Logo</th>
+            <th style="width: 200px; cursor: pointer" @click="sortBy('localName')">
+              Name<span v-if="sortKey === 'localName'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
+            </th>
+            <th style="width: 180px; cursor: pointer" @click="sortBy('createdAt')">
+              Created At<span v-if="sortKey === 'createdAt'">{{
+                sortOrder === 'asc' ? '↑' : '↓'
+              }}</span>
+            </th>
+            <th style="width: 180px; cursor: pointer" @click="sortBy('modifiedAt')">
+              Modified At<span v-if="sortKey === 'modifiedAt'">{{
+                sortOrder === 'asc' ? '↑' : '↓'
+              }}</span>
+            </th>
+            <th class="text-end" style="width: 220px">Actions</th>
+          </tr>
         </thead>
         <tbody>
-        <tr v-for="restaurant in sortedRestaurants" :key="restaurant.localId">
-          <td>
-            <img
-              v-if="restaurant.localLogo"
-              :src="restaurant.localLogo"
-              alt="Logo"
-              class="img-thumbnail"
-              style="width: 40px; height: 40px; object-fit: cover;"
-            />
-            <span v-else class="text-muted">No Logo</span>
-          </td>
-          <td class="text-truncate">{{ restaurant.localName }}</td>
-          <td>{{ formatDate(restaurant.createdAt) }}</td>
-          <td>{{ formatDate(restaurant.modifiedAt) }}</td>
-          <td class="text-end">
-            <div class="d-flex justify-content-end gap-2 flex-wrap">
-              <button class="btn btn-sm btn-primary" @click="openAddManagerModal(restaurant.localId)">Add Manager</button>
-              <button class="btn btn-sm btn-primary" @click="openEditManagersModal(restaurant.localId)">Edit Managers</button>
-              <button class="btn btn-sm btn-outline-danger" @click="removeRestaurant(restaurant.localId)">
-                <i class="fas fa-trash-alt"></i> Delete restaurant
-              </button>
-            </div>
-          </td>
-        </tr>
+          <tr v-for="restaurant in sortedRestaurants" :key="restaurant.localId">
+            <td>
+              <img
+                v-if="restaurant.localLogo"
+                :src="restaurant.localLogo"
+                alt="Logo"
+                class="img-thumbnail"
+                style="width: 40px; height: 40px; object-fit: cover"
+              /><span v-else class="text-muted">No Logo</span>
+            </td>
+            <td class="text-truncate">{{ restaurant.localName }}</td>
+            <td>{{ formatDate(restaurant.createdAt) }}</td>
+            <td>{{ formatDate(restaurant.modifiedAt) }}</td>
+            <td class="text-end">
+              <div class="d-flex justify-content-end gap-2 flex-wrap">
+                <button
+                  class="btn btn-sm btn-primary"
+                  @click="openAddManagerModal(restaurant.localId)"
+                >
+                  Add Manager</button
+                ><button
+                  class="btn btn-sm btn-primary"
+                  @click="openEditManagersModal(restaurant.localId)"
+                >
+                  Edit Managers</button
+                ><button
+                  class="btn btn-sm btn-outline-danger"
+                  @click="removeRestaurant(restaurant.localId)"
+                >
+                  <i class="fas fa-trash-alt"></i> Delete restaurant
+                </button>
+              </div>
+            </td>
+          </tr>
         </tbody>
       </table>
     </div>
 
-    <!-- Add Restaurant Button -->
     <button class="btn btn-success mt-3" @click="showAddRestaurantModal = true">
       + Add Restaurant
     </button>
+    <div id="sendMailGroup" class="mt-3">
+      <button @click="sendEmailToManager" class="btn btn-success">
+        <LoadingIcon v-if="isEmailSending" />
+        <span v-else>+ </span>
+        Send Manager register mail
+      </button>
+      <input
+        v-model="emailToManager"
+        class="form-control"
+        type="text"
+        placeholder="Enter manager's email"
+      />
+    </div>
   </div>
 </template>
 
 <style scoped>
-html, body {
+html,
+body {
   margin: 0;
   padding: 0;
@@ -291,5 +378,4 @@
   overflow: hidden;
 }
-
 .container {
   max-width: 1200px;
@@ -301,10 +387,8 @@
   overflow: hidden;
 }
-
 .table-container {
   flex: 1 1 auto;
   overflow-y: auto;
 }
-
 table {
   font-size: 0.95rem;
@@ -312,5 +396,4 @@
   width: 100%;
 }
-
 th,
 td {
@@ -319,5 +402,4 @@
   text-overflow: ellipsis;
 }
-
 thead th {
   position: sticky;
@@ -327,14 +409,11 @@
   user-select: none;
 }
-
 th span {
   margin-left: 5px;
   font-size: 0.8rem;
 }
-
 td img {
   display: block;
 }
-
 .text-truncate {
   overflow: hidden;
@@ -342,7 +421,19 @@
   white-space: nowrap;
 }
-
 .modal {
   display: block;
 }
+#sendMailGroup {
+  display: flex;
+}
+#sendMailGroup > .btn {
+  flex-shrink: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+#sendMailGroup > .form-control {
+  flex-grow: 1;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
 </style>
Index: ReserveNGo-frontend/src/components/Project/Auth/register_.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Auth/register_.vue	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/components/Project/Auth/register_.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -5,4 +5,5 @@
 import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
 import { useAuth } from '@/repository/Authentication.ts'
+import {useToasts} from '@/composables/useToast.js'
 
 export default {
@@ -23,4 +24,5 @@
       isLoading: false,
       errorMessage: '',
+      showToast: useToasts().showToast,
     }
   },
@@ -34,13 +36,24 @@
           this.form_info.phoneNumber,
           this.form_info.password,
-          this.path,
+          this.roleType,
+          this.tokenRegister
         )
         .then((json) => {
-          this.userStore_.setLocalStorage(json)
-          router.push('/')
+          if (this.roleType === "local-manager" || this.roleType === "local-worker") {
+            router.push('/login')
+            this.showToast("Successfully registered business account")
+
+          }
+          else {
+            this.showToast("Successfully registered user account")
+            router.push('/login')
+          }
         })
         .catch((err) => {
           if (err.status === 409) {
             this.errorMessage = "It looks like an account already exists with that email address. Do you want to log in instead?"
+          }
+          else {
+            this.errorMessage = err.response || "Something Went wrong";
           }
         })
@@ -50,4 +63,20 @@
     },
   },
+  computed: {
+    tokenRegister() {
+      return this.$route.query.token || null;
+    },
+    roleType(){
+      if (this.$route.params.userType)
+        return `local-${this.$route.params.userType}`
+        //local-manager
+      else {
+        return "customer"
+      }
+
+    }
+  }
+
+
 }
 </script>
@@ -61,5 +90,5 @@
             <div class="card shadow-sm border-0">
               <div class="card-body p-4">
-                <h3 class="mb-4 text-center">Register</h3>
+                <h3 class="mb-4 text-center">Register {{roleType}}</h3>
                 <form @submit.prevent="register" method="POST">
                   <div class="mb-3">
@@ -127,14 +156,4 @@
                     />
                   </div>
-
-                  <div class="mb-4">
-                    <label for="role" class="form-label">Role</label>
-                    <select class="form-select" id="role" v-model="path" required>
-                      <option value="" disabled>Select a role</option>
-                      <option value="customer">Customer</option>
-                      <option value="local-worker">Local Worker</option>
-                      <option value="local-manager">Local Manager</option>
-                    </select>
-                  </div>
                   <div style="color: red;">{{errorMessage}}</div>
                   <div class="d-grid">
Index: ReserveNGo-frontend/src/components/Project/Customer/Profile_Page.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Customer/Profile_Page.vue	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/components/Project/Customer/Profile_Page.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -2,164 +2,151 @@
 import { userStore } from '@/PiniaStores/UserStore.js'
 import blankProfile from '@/components/ectd/blank-profile.webp'
+import { useToasts } from '@/composables/useToast.js'
+import { isValidEmail } from '@/mixins/utilFunctions.js'
+import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
+import {useUser} from '@/repository/user.ts'
 
 export default {
+  components: { LoadingIcon },
   data() {
     return {
       userStore_: userStore(),
-      newFirstName: '',
-      newLastName: '',
-      newPhoneNumber: '',
-      newEmail: '',
       newPassword: '',
       currentPassword: '',
-
       profileData: {},
-
       isProfileImageButtonDisabled: true,
       profileImageSrc: null,
-
-      blankProfile: blankProfile
+      blankProfile: blankProfile,
+      showToast: useToasts().showToast,
+
+      isSavingDetails: false,
+      isUpdatingEmail: false,
+      isUpdatingPassword: false,
+      isUpdatingPicture: false,
     }
   },
   methods: {
     async updateProfileSettings() {
-      try {
-        const response = await fetch('http://localhost:8080/api/user/edit', {
-          method: 'PUT',
-          headers: {
-            'Content-Type': 'application/json',
-            Authorization: this.userStore_.getToken,
-          },
-          body: JSON.stringify({
-            firstName: this.profileData.firstName,
-            lastName: this.profileData.lastName,
-            phoneNumber: this.profileData.phoneNumber,
-          }),
+      this.isSavingDetails = true
+      try {
+        const payload = {
+          firstName: this.profileData.firstName,
+          lastName: this.profileData.lastName,
+          phoneNumber: this.profileData.phoneNumber,
+        }
+        const updatedUser = await useUser.updateProfile(payload)
+        this.userStore_.setNewEditedDataToLocalStorage(updatedUser)
+        this.showToast('Profile details saved successfully!', 'success')
+      } catch (err) {
+        this.showToast(err.response || 'Failed to save details.', 'error')
+      } finally {
+        this.isSavingDetails = false
+      }
+    },
+    async updateEmail() {
+      if (!isValidEmail(this.profileData.email)) {
+        this.showToast('Please enter a valid email address.', 'error')
+        return
+      }
+      this.isUpdatingEmail = true
+      try {
+        const payload = { newEmail: this.profileData.email }
+        const updatedTokenData = (await useUser.changeEmail(payload))
+        this.userStore_.setNewEmailToLocalStorage(updatedTokenData) // Assumes this updates the token with new email info
+        this.showToast(
+          'Email updated successfully! Please check your old email for confirmation.',
+          'success',
+        )
+      } catch (err) {
+        this.showToast(err.response || 'Failed to update email.', 'error')
+      } finally {
+        this.isUpdatingEmail = false
+      }
+    },
+    async updatePassword() {
+      this.isUpdatingPassword = true
+      try {
+        const payload = {
+          currentPassword: this.currentPassword,
+          newPassword: this.newPassword,
+        }
+        await useUser.changePassword(payload)
+        this.showToast('Password changed successfully.', 'success')
+        this.currentPassword = ''
+        this.newPassword = ''
+      } catch (err) {
+        this.showToast(err.response || 'Failed to change password.', 'error')
+      } finally {
+        this.isUpdatingPassword = false
+      }
+    },
+    async updateProfilePicture() {
+      const profilePictureFile = document.getElementById('profilePhotoInput').files[0]
+      if (!profilePictureFile) return
+
+      this.isUpdatingPicture = true
+      const formData = new FormData()
+      formData.append('avatar', profilePictureFile)
+
+      try {
+        const profileAvatarStringPath = await useUser.uploadAvatar(formData)
+
+        const response = await fetch('http://localhost:8080' + profileAvatarStringPath, {
+          headers: { Authorization: this.userStore_.getToken },
         })
-        const json = await response.json()
-        this.userStore_.setNewEditedDataToLocalStorage(json)
-      } catch (err) {
-        console.log(err)
-      }
-    },
-    async updateEmail() {
-      try {
-        const response = await fetch('http://localhost:8080/api/user/change-email', {
-          method: 'PATCH',
-          headers: {
-            'Content-Type': 'application/json',
-            Authorization: this.userStore_.getToken,
-          },
-          body: JSON.stringify({ newEmail: this.profileData.email }),
-        })
-        const json = await response.json()
-        this.userStore_.setNewEmailToLocalStorage(json)
-      } catch (err) {
-        console.log(err)
-      }
-    },
-    async updatePassword() {
-      try {
-        await fetch('http://localhost:8080/api/user/change-password', {
-          method: 'PATCH',
-          headers: {
-            'Content-Type': 'application/json',
-            Authorization: this.userStore_.getToken,
-          },
-          body: JSON.stringify({
-            currentPassword: this.currentPassword,
-            newPassword: this.newPassword,
-          }),
-        })
-      } catch (err) {
-        console.log(err)
-      }
-    },
-    updateProfilePicture() {
-      const profilePictureFile = document.getElementById('profilePhotoInput').files[0];
-      if (!profilePictureFile) return;
-
-      const formData = new FormData();
-      formData.append('avatar', profilePictureFile);
-
-      fetch('http://localhost:8080/api/user/upload-avatar', {
-        method: 'POST',
-        headers: {
-          Authorization: this.userStore_.getToken,
-        },
-        body: formData
-      })
-        .then(response => response.text())
-        .then(profileAvatarStringPath => {console.log("Profile Picture data returned", profileAvatarStringPath);
-
-
-
-            fetch('http://localhost:8080' + profileAvatarStringPath, {
-              headers: {
-                Authorization: this.userStore_.getToken,
-              }
-            })
-              .then(response => response.blob())
-              .then(blob => {
-                const reader = new FileReader();
-                reader.onloadend = () => {
-                  const base64data = reader.result;
-
-                  this.userStore_.setProfilePicturePathToLocalStorage(profileAvatarStringPath, base64data)
-                };
-                reader.readAsDataURL(blob);
-              })
-              .catch(err => console.log("Error parsing the blob", err))
-
-        })
-        .catch(err => console.log("Profile picture upload failed:", err));
-    },
-    deleteProfilePicture() {
-      fetch('http://localhost:8080/api/user/delete-avatar', {
-        method: 'DELETE',
-        headers: {
-          Authorization: this.userStore_.getToken,
+        const blob = await response.blob()
+        const reader = new FileReader()
+        reader.onloadend = () => {
+          this.userStore_.setProfilePicturePathToLocalStorage(
+            profileAvatarStringPath,
+            reader.result,
+          )
+          this.showToast('Profile picture updated!', 'success')
         }
-      })
-        .then(() => this.userStore_.removeProfilePictureFromLocaleStorage())
-        .catch(err => console.log("Erorr didnt remove profile picture", err))
+        reader.readAsDataURL(blob)
+      } catch (err) {
+        this.showToast(err.response || 'Profile picture upload failed.', 'error')
+      } finally {
+        this.isUpdatingPicture = false
+        this.isProfileImageButtonDisabled = true
+      }
+    },
+    async deleteProfilePicture() {
+      this.isUpdatingPicture = true
+      try {
+        await useUser.deleteAvatar()
+        this.userStore_.removeProfilePictureFromLocaleStorage()
+        this.showToast('Profile picture removed.', 'success')
+      } catch (err) {
+        this.showToast(err.response || 'Failed to remove profile picture.', 'error')
+      } finally {
+        this.isUpdatingPicture = false
+      }
+    },
+  },
+  async beforeMount() {
+    try {
+      this.profileData = await useUser.getProfile()
+    } catch (error) {
+      console.log('Error fetching profile settings', error)
+      this.showToast('Could not load your profile data.', 'error')
     }
-
-
-  },
-  beforeMount() {
-    fetch('http://localhost:8080/api/user/profile', {
-      method: 'GET',
-      headers: {
-        Authorization: this.userStore_.getToken,
-      },
-    })
-      .then((response) => response.json())
-      .then((data) => {
-        this.profileData = data
-        console.log('Priting response from profile api', this.profileData)
-      })
-      .catch((error) => {
-        console.log('Error fetching profile settings', error)
-      })
   },
   mounted() {
-    this.isProfileImageButtonDisabled = true;
-    const profilePictureImage = document.getElementById('profilePictureModal');
-    const inputProfilePicture = document.getElementById('profilePhotoInput');
+    this.isProfileImageButtonDisabled = true
+    const profilePictureImage = document.getElementById('profilePictureModal')
+    const inputProfilePicture = document.getElementById('profilePhotoInput')
 
     inputProfilePicture.addEventListener('change', (event) => {
-      this.isProfileImageButtonDisabled = false;
-
-      const file = event.target.files[0];
+      this.isProfileImageButtonDisabled = false
+      const file = event.target.files[0]
       if (file && file.type.startsWith('image/')) {
-        const reader = new FileReader();
+        const reader = new FileReader()
         reader.onload = (e) => {
-          profilePictureImage.src = e.target.result;
-        };
-        reader.readAsDataURL(file);
-      }
-    });
-
+          profilePictureImage.src = e.target.result
+        }
+        reader.readAsDataURL(file)
+      }
+    })
   },
 }
@@ -175,5 +162,5 @@
               <img
                 class="rounded-circle border me-3"
-                :src=" this.userStore_.data.profilePictureBase64Encoded || blankProfile"
+                :src="this.userStore_.data.profilePictureBase64Encoded || blankProfile"
                 alt="Profile Picture"
                 width="100"
@@ -182,9 +169,7 @@
             </div>
           </div>
-
           <h4>{{ profileData.firstName }} {{ profileData.lastName }}</h4>
           <p><strong>Email:</strong> {{ profileData.email }}</p>
           <p><strong>Phone Number:</strong> {{ profileData.phoneNumber }}</p>
-
           <button
             type="button"
@@ -218,6 +203,6 @@
             ></button>
           </div>
-
           <div class="modal-body">
+            <!-- Profile Picture Section -->
             <div class="d-flex justify-content-center">
               <div class="position-relative">
@@ -225,5 +210,5 @@
                   id="profilePictureModal"
                   class="rounded-circle border"
-                  :src=" this.userStore_.data.profilePictureBase64Encoded || blankProfile"
+                  :src="this.userStore_.data.profilePictureBase64Encoded || blankProfile"
                   alt="Profile Picture"
                   width="100"
@@ -236,5 +221,4 @@
                   accept="image/*"
                 />
-
                 <label
                   for="profilePhotoInput"
@@ -245,12 +229,28 @@
                 </label>
               </div>
-
             </div>
             <div class="d-flex justify-content-center">
-            <button v-if="userStore_.data.logoUrl == null" @click="updateProfilePicture" :class="{'disabled': this.isProfileImageButtonDisabled}" class="text-center btn btn-dark mb-3 mt-2">Save Picture</button>
-              <button v-if="userStore_.data.logoUrl != null" @click="deleteProfilePicture" class="text-center btn btn-dark mb-3 mt-2">Remove Picture</button>
-            </div>
-
-            <!-- Edit Name and Phone -->
+              <!-- --- MODIFIED: Added loading states to picture buttons --- -->
+              <button
+                v-if="!userStore_.data.profilePictureBase64Encoded"
+                @click="updateProfilePicture"
+                :disabled="isProfileImageButtonDisabled || isUpdatingPicture"
+                class="text-center btn btn-dark mb-3 mt-2"
+              >
+                <LoadingIcon v-if="isUpdatingPicture" />
+                Save Picture
+              </button>
+              <button
+                v-if="userStore_.data.profilePictureBase64Encoded"
+                @click="deleteProfilePicture"
+                :disabled="isUpdatingPicture"
+                class="text-center btn btn-dark mb-3 mt-2"
+              >
+                <LoadingIcon v-if="isUpdatingPicture" />
+                Remove Picture
+              </button>
+            </div>
+
+            <!-- Personal Details Section -->
             <h6>Personal Details</h6>
             <div class="mb-3">
@@ -262,7 +262,7 @@
                 class="form-control"
                 :placeholder="profileData.firstName"
-              />
-            </div>
-
+                :disabled="isSavingDetails"
+              />
+            </div>
             <div class="mb-3">
               <label for="lastName" class="form-label">Last Name</label>
@@ -273,7 +273,7 @@
                 class="form-control"
                 :placeholder="profileData.lastName"
-              />
-            </div>
-
+                :disabled="isSavingDetails"
+              />
+            </div>
             <div class="mb-3">
               <label for="phoneNumber" class="form-label">Phone Number</label>
@@ -284,31 +284,39 @@
                 class="form-control"
                 :placeholder="profileData.phoneNumber"
-              />
-            </div>
-
+                :disabled="isSavingDetails"
+              />
+            </div>
             <button
               @click="updateProfileSettings()"
               type="button"
               class="btn btn-dark w-100 mb-4"
-              data-bs-dismiss="modal"
+              :disabled="isSavingDetails"
             >
-              Save Changes
+              <LoadingIcon v-if="isSavingDetails" />
+              {{ isSavingDetails ? 'Saving...' : 'Save Changes' }}
             </button>
 
-            <!-- Change Email -->
+            <!-- Change Email Section -->
             <h6>Change Email</h6>
             <div class="input-group mb-3">
-              <input v-model="profileData.email" type="text" class="form-control" placeholder="New Email" />
+              <input
+                v-model="profileData.email"
+                type="text"
+                class="form-control"
+                placeholder="New Email"
+                :disabled="isUpdatingEmail"
+              />
               <button
                 @click="updateEmail()"
                 type="button"
                 class="btn btn-secondary"
-                data-bs-dismiss="modal"
+                :disabled="isUpdatingEmail"
               >
-                Update Email
+                <LoadingIcon v-if="isUpdatingEmail" />
+                {{ isUpdatingEmail ? 'Updating...' : 'Update Email' }}
               </button>
             </div>
 
-            <!-- Change Password -->
+            <!-- Change Password Section -->
             <h6>Change Password</h6>
             <div class="mb-2">
@@ -319,19 +327,25 @@
                 id="currentPassword"
                 class="form-control"
-              />
-            </div>
-
+                :disabled="isUpdatingPassword"
+              />
+            </div>
             <div class="mb-3">
               <label for="newPassword" class="form-label">New Password</label>
-              <input v-model="newPassword" type="password" id="newPassword" class="form-control" />
-            </div>
-
+              <input
+                v-model="newPassword"
+                type="password"
+                id="newPassword"
+                class="form-control"
+                :disabled="isUpdatingPassword"
+              />
+            </div>
             <button
               @click="updatePassword()"
               type="button"
               class="btn btn-secondary w-100"
-              data-bs-dismiss="modal"
+              :disabled="isUpdatingPassword"
             >
-              Change Password
+              <LoadingIcon v-if="isUpdatingPassword" />
+              {{ isUpdatingPassword ? 'Changing...' : 'Change Password' }}
             </button>
           </div>
Index: ReserveNGo-frontend/src/components/Project/Event/AddEventModal.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Event/AddEventModal.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
+++ ReserveNGo-frontend/src/components/Project/Event/AddEventModal.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -0,0 +1,159 @@
+<script>
+import { userStore } from '@/PiniaStores/UserStore.js'
+import { useLocalManager } from '@/repository/LocalManager.ts'
+import {useToasts} from '@/composables/useToast.js'
+
+export default {
+  props: {
+    show: {
+      type: Boolean,
+      required: true,
+    },
+  },
+  emits: ['close', 'event-added'],
+  data() {
+    return {
+      event: {
+        name: '',
+        description: '',
+        eventType: '',
+        eventStart: '',
+        eventEnd: '',
+      },
+      user: userStore(),
+      isLoading: false,
+      showToast: useToasts().showToast,
+    }
+  },
+  methods: {
+    close() {
+
+      this.$emit('close')
+    },
+    async addEvent() {
+      if (this.isLoading) return
+      this.isLoading = true
+
+
+      if (!this.event.name || !this.event.eventStart || !this.event.eventEnd) {
+        alert('Please fill in all required fields (Name, Start Date, End Date).')
+        this.isLoading = false
+        return
+      }
+
+      useLocalManager.addEvent(this.event)
+        .then(() => {
+          this.$emit('event-added')
+          this.event = {
+            name: '',
+            description: '',
+            eventType: 'Music',
+            eventStart: '',
+            eventEnd: ''
+          }
+          this.close()
+          this.showToast("Successfully added the event")
+        })
+        .catch((err) => {
+          this.showToast(err.response, 'error')
+        })
+        .finally(() => {
+          this.isLoading = false
+        })
+
+    },
+  },
+}
+</script>
+
+<template>
+  <!-- Modal Backdrop -->
+  <div v-if="show" class="modal-backdrop fade show"></div>
+
+  <!-- Modal -->
+  <div
+    v-if="show"
+    class="modal fade show"
+    style="display: block"
+    tabindex="-1"
+    aria-labelledby="addEventModalLabel"
+    aria-modal="true"
+    role="dialog"
+  >
+    <div class="modal-dialog modal-dialog-centered">
+      <div class="modal-content">
+        <form @submit.prevent="addEvent">
+          <div class="modal-header">
+            <h5 class="modal-title" id="addEventModalLabel">Add New Event</h5>
+            <button type="button" class="btn-close" @click="close" aria-label="Close"></button>
+          </div>
+          <div class="modal-body">
+            <!-- Event Name -->
+            <div class="mb-3">
+              <label for="eventName" class="form-label">Event Name</label>
+              <input type="text" class="form-control" id="eventName" v-model="event.name" required />
+            </div>
+
+            <!-- Event Description -->
+            <div class="mb-3">
+              <label for="eventDescription" class="form-label">Description</label>
+              <textarea
+                class="form-control"
+                id="eventDescription"
+                rows="3"
+                v-model="event.description"
+              ></textarea>
+            </div>
+
+            <!-- Event Type -->
+            <div class="mb-3">
+              <label for="eventType" class="form-label">Event Type</label>
+              <select class="form-select" id="eventType" v-model="event.eventType">
+                <option>LIVE_MUSIC</option>
+                <option>DJ_NIGHT</option>
+                <option>FOOD_SPECIAL</option>
+                <option>DRINK_SPECIAL</option>
+                <option>HAPPY_HOUR</option>
+              </select>
+            </div>
+
+            <!-- Event Start/End -->
+            <div class="row">
+              <div class="col-md-6 mb-3">
+                <label for="eventStart" class="form-label">Start Date & Time</label>
+                <input
+                  type="datetime-local"
+                  class="form-control"
+                  id="eventStart"
+                  v-model="event.eventStart"
+                  required
+                />
+              </div>
+              <div class="col-md-6 mb-3">
+                <label for="eventEnd" class="form-label">End Date & Time</label>
+                <input
+                  type="datetime-local"
+                  class="form-control"
+                  id="eventEnd"
+                  v-model="event.eventEnd"
+                  required
+                />
+              </div>
+            </div>
+          </div>
+          <div class="modal-footer">
+            <button type="button" class="btn btn-secondary" @click="close">Close</button>
+            <button type="submit" class="btn btn-primary" :disabled="isLoading">
+              <span v-if="isLoading" class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
+              {{ isLoading ? 'Saving...' : 'Save Event' }}
+            </button>
+          </div>
+        </form>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style scoped>
+
+</style>
Index: ReserveNGo-frontend/src/components/Project/Event/EditEventModal.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Event/EditEventModal.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
+++ ReserveNGo-frontend/src/components/Project/Event/EditEventModal.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -0,0 +1,230 @@
+<script>
+import { userStore } from '@/PiniaStores/UserStore.js'
+import { useLocalManager } from '@/repository/LocalManager.ts'
+import { useToasts } from '@/composables/useToast.js'
+
+export default {
+  props: {
+    show: {
+      type: Boolean,
+      required: true,
+    },
+    // --- NEW: Optional prop for the event to edit ---
+    // If this is passed, we're in "Edit Mode".
+    eventToEdit: {
+      type: Object,
+      default: null,
+    },
+  },
+  emits: ['close', 'event-added', 'event-updated'], // Added 'event-updated' emit
+
+  data() {
+    return {
+      // We now use a local copy for the form to avoid mutating props.
+      eventData: {},
+      user: userStore(),
+      isLoading: false,
+      showToast: useToasts().showToast,
+    }
+  },
+
+  // --- NEW: Computed properties for a dynamic UI ---
+  computed: {
+    isEditMode() {
+      // The modal is in "Edit Mode" if an event prop was passed.
+      return !!this.eventToEdit;
+    },
+    modalTitle() {
+      return this.isEditMode ? 'Edit Event' : 'Add New Event';
+    },
+    saveButtonText() {
+      if (this.isLoading) {
+        return this.isEditMode ? 'Updating...' : 'Saving...';
+      }
+      return this.isEditMode ? 'Update Event' : 'Save Event';
+    },
+  },
+
+  // --- NEW: Watcher to initialize the form when the modal opens ---
+  watch: {
+    show(newVal) {
+      if (newVal) {
+        // When the modal is shown, populate the form.
+        this.initializeForm();
+      }
+    }
+  },
+
+  methods: {
+    close() {
+      this.$emit('close');
+    },
+
+    // --- NEW: Helper to set up the form for either mode ---
+    initializeForm() {
+      if (this.isEditMode) {
+        // In Edit Mode, create a deep copy of the prop to avoid mutation.
+        // This also ensures the form data has the event's ID.
+        this.eventData = JSON.parse(JSON.stringify(this.eventToEdit));
+      } else {
+        // In Add Mode, set up a fresh, empty object.
+        this.eventData = {
+          name: '',
+          description: '',
+          eventType: 'LIVE_MUSIC', // A sensible default
+          eventStart: '',
+          eventEnd: '',
+        };
+      }
+    },
+
+    // --- NEW: Master submit handler ---
+    async handleSubmit() {
+      // This single method decides which action to take.
+      if (this.isEditMode) {
+        await this.updateEvent();
+      } else {
+        await this.addEvent();
+      }
+    },
+
+    // --- REFACTORED: Now uses async/await for cleaner syntax ---
+    async addEvent() {
+      if (this.isLoading) return;
+      this.isLoading = true;
+
+      if (!this.eventData.name || !this.eventData.eventStart || !this.eventData.eventEnd) {
+        alert('Please fill in all required fields (Name, Start Date, End Date).');
+        this.isLoading = false;
+        return;
+      }
+
+      try {
+        await useLocalManager.addEvent(this.eventData);
+        this.$emit('event-added');
+        this.close();
+        this.showToast("Successfully added the event", "success");
+      } catch (err) {
+        this.showToast(err.response?.data?.message || 'Failed to add event', 'error');
+      } finally {
+        this.isLoading = false;
+      }
+    },
+
+    // --- NEW: Method for updating an existing event ---
+    async updateEvent() {
+      if (this.isLoading) return;
+      this.isLoading = true;
+
+      try {
+        // Assumes your updateEvent method needs the event object (with its ID).
+        await useLocalManager.updateEvent(this.eventData, this.eventData.id);
+        this.$emit('event-updated', this.eventData); // Emit the new data back
+        this.close();
+        this.showToast("Successfully updated the event", "success");
+      } catch (err) {
+        this.showToast(err.response?.data?.message || 'Failed to update event', 'error');
+      } finally {
+        this.isLoading = false;
+      }
+    },
+  },
+}
+</script>
+
+<template>
+  <!-- Modal Backdrop (No changes) -->
+  <div v-if="show" class="modal-backdrop fade show"></div>
+
+  <!-- Modal -->
+  <div
+    v-if="show"
+    class="modal fade show"
+    style="display: block"
+    tabindex="-1"
+    aria-labelledby="eventFormModalLabel"
+    aria-modal="true"
+    role="dialog"
+  >
+    <div class="modal-dialog modal-dialog-centered">
+      <div class="modal-content">
+        <!-- MODIFIED: Form now calls the master handleSubmit method -->
+        <form @submit.prevent="handleSubmit">
+          <div class="modal-header">
+            <!-- MODIFIED: Title is now dynamic -->
+            <h5 class="modal-title" id="eventFormModalLabel">{{ modalTitle }}</h5>
+            <button type="button" class="btn-close" @click="close" aria-label="Close"></button>
+          </div>
+          <div class="modal-body">
+            <!-- All v-model instances are now bound to `eventData` instead of `event` -->
+
+            <!-- Event Name -->
+            <div class="mb-3">
+              <label for="eventName" class="form-label">Event Name</label>
+              <input type="text" class="form-control" id="eventName" v-model="eventData.name" required />
+            </div>
+
+            <!-- Event Description -->
+            <div class="mb-3">
+              <label for="eventDescription" class="form-label">Description</label>
+              <textarea
+                class="form-control"
+                id="eventDescription"
+                rows="3"
+                v-model="eventData.description"
+              ></textarea>
+            </div>
+
+            <!-- Event Type -->
+            <div class="mb-3">
+              <label for="eventType" class="form-label">Event Type</label>
+              <select class="form-select" id="eventType" v-model="eventData.eventType">
+                <option>LIVE_MUSIC</option>
+                <option>DJ_NIGHT</option>
+                <option>FOOD_SPECIAL</option>
+                <option>DRINK_SPECIAL</option>
+                <option>HAPPY_HOUR</option>
+              </select>
+            </div>
+
+            <!-- Event Start/End -->
+            <div class="row">
+              <div class="col-md-6 mb-3">
+                <label for="eventStart" class="form-label">Start Date & Time</label>
+                <input
+                  type="datetime-local"
+                  class="form-control"
+                  id="eventStart"
+                  v-model="eventData.eventStart"
+                  required
+                />
+              </div>
+              <div class="col-md-6 mb-3">
+                <label for="eventEnd" class="form-label">End Date & Time</label>
+                <input
+                  type="datetime-local"
+                  class="form-control"
+                  id="eventEnd"
+                  v-model="eventData.eventEnd"
+                  required
+                />
+              </div>
+            </div>
+          </div>
+          <div class="modal-footer">
+            <button type="button" class="btn btn-secondary" @click="close">Close</button>
+            <!-- MODIFIED: Button text is now dynamic -->
+            <button type="submit" class="btn btn-primary" :disabled="isLoading">
+              <span v-if="isLoading" class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
+              {{ saveButtonText }}
+            </button>
+          </div>
+        </form>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style scoped>
+/* No style changes needed */
+</style>
Index: ReserveNGo-frontend/src/components/Project/Event/events_carousel.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Event/events_carousel.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
+++ ReserveNGo-frontend/src/components/Project/Event/events_carousel.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -0,0 +1,168 @@
+<script lang="ts">
+import { userStore } from '@/PiniaStores/UserStore.js'
+import { useLocales } from '@/repository/Locale'
+import { config } from '@/constants/Api_config'
+import pankake from '@/components/ectd/easy-american-pancake-recipe.jpg'
+import { transformArray } from '@/mixins/utilFunctions'
+
+
+export default {
+  data() {
+    return {
+      userStore_: userStore(),
+      pankake: pankake,
+      itemsPerSlide: 3,
+    }
+  },
+  props: ['allEvents'],
+
+  watch: {
+    allEvents: {
+      handler(events) {
+        if (events && events.length > 0) {
+          events.forEach((eventGroup) => {
+            eventGroup.forEach((event) => {
+              useLocales.getSpecificLocale(event.localId).then((locale) => {
+                event.logo = locale.logo
+              })
+            })
+          })
+        } else {
+          console.log('allEvents is still empty or undefined.')
+        }
+      },
+      immediate: true,
+      deep: true,
+    },
+  },
+
+  // 2. COMPUTED: Create a property that automatically recalculates when its dependencies change.
+  computed: {
+    /**
+     * This computed property flattens the original nested allEvents array
+     * and then re-chunks it based on the current `itemsPerSlide`.
+     */
+    chunkedEvents() {
+    /*  console.log("CHUNKED EVENTS",this.allEvents)*/
+      // Return empty array if the prop is not yet ready.
+      if (!this.allEvents || this.allEvents.length === 0) {
+        return []
+      }
+
+      // First, flatten the nested array into a single list of all events.
+      // e.g., [[1,2,3], [4,5,6]] becomes [1,2,3,4,5,6]
+      const flatEvents = this.allEvents.flat()
+      /*console.log('flatEvents', flatEvents)*/
+
+      // This is the abstract "resize the array" method you mentioned.
+      // It chunks the flat list into new sub-arrays.
+
+      return transformArray(flatEvents, this.itemsPerSlide, false)
+    },
+  },
+
+  methods: {
+    /**
+     * Checks the window width and updates the `itemsPerSlide` data property.
+     * This will trigger the `chunkedEvents` computed property to recalculate.
+     */
+    updateItemsPerSlide() {
+      const width = window.innerWidth
+      // Using standard Bootstrap breakpoints
+      if (width < 768) {
+        // Small devices (phones)
+        this.itemsPerSlide = 1
+      } else if (width < 992) {
+        // Medium devices (tablets/laptops)
+        this.itemsPerSlide = 2
+      } else {
+        // Large devices (desktops)
+        this.itemsPerSlide = 3
+      }
+    },
+
+    getImageLogo(imageLogo: string): any {
+      if (!imageLogo || !imageLogo.startsWith('/')) {
+        return pankake
+      }
+      return config.API_BASE_URL + imageLogo
+    },
+  },
+
+  mounted() {
+ /*   setInterval(() => {
+      console.log(this.chunkedEvents)
+    }, 1000)*/
+    // Call the method once on component mount to set the initial state.
+    this.updateItemsPerSlide()
+    // Add event listener for window resizing.
+    window.addEventListener('resize', this.updateItemsPerSlide)
+  },
+
+  beforeUnmount() {
+    // IMPORTANT: Remove the event listener when the component is destroyed
+    // to prevent memory leaks.
+    window.removeEventListener('resize', this.updateItemsPerSlide)
+  },
+}
+</script>
+
+<template>
+  <div id="carouselMulti3" class="carousel slide col-12" data-bs-ride="carousel">
+    <div class="carousel-inner">
+      <div
+        class="carousel-item"
+        v-for="(eventGroup, index) in chunkedEvents"
+        :key="index"
+        :class="{ active: index === 0 }"
+      >
+        <div style="gap: 0.2rem" class="d-flex justify-content-center">
+          <!-- The inner loop now iterates over the `eventGroup` (the chunk) -->
+          <div class="" v-for="event in eventGroup" :key="event.id">
+            <div class="card" style="width: 18rem">
+              <img
+                height="100"
+                :src="getImageLogo(event.logo) || pankake"
+                class="card-img-top"
+                alt="..."
+              />
+              <div class="card-body">
+                <h5 class="card-title fw-bold">{{ event.name }}</h5>
+                <div class="card-text d-flex justify-content-between">
+                  <div class="text-muted">{{ event.eventType }}</div>
+                  <div class="text-muted">
+                    {{ event.eventStart.date }} <br />
+                    <i class="fas fa-clock me-2 text-secondary"></i> {{ event.eventStart.time }}
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <button
+      class="carousel-control-prev"
+      type="button"
+      data-bs-target="#carouselMulti3"
+      data-bs-slide="prev"
+    >
+      <span class="carousel-control-prev-icon"></span>
+    </button>
+    <button
+      class="carousel-control-next"
+      type="button"
+      data-bs-target="#carouselMulti3"
+      data-bs-slide="next"
+    >
+      <span class="carousel-control-next-icon"></span>
+    </button>
+  </div>
+</template>
+
+<style scoped>
+.carousel-control-prev-icon,
+.carousel-control-next-icon {
+  filter: invert(100%); /* This turns white into black */
+}
+</style>
Index: ReserveNGo-frontend/src/components/Project/Event/events_carousel_in_locale.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Event/events_carousel_in_locale.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
+++ ReserveNGo-frontend/src/components/Project/Event/events_carousel_in_locale.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -0,0 +1,160 @@
+<script lang="ts">
+import { userStore } from '@/PiniaStores/UserStore.js'
+import { useLocales } from '@/repository/Locale'
+import {useLocalManager} from '@/repository/LocalManager.ts'
+import { config } from '@/constants/Api_config'
+import pankake from '@/components/ectd/easy-american-pancake-recipe.jpg'
+import { transformArray } from '@/mixins/utilFunctions'
+import {useToasts} from '@/composables/useToast.js'
+
+
+export default {
+  data() {
+    return {
+      userStore_: userStore(),
+      pankake: pankake,
+      itemsPerSlide: 3,
+      showEditModal: false,
+      showToast: useToasts().showToast,
+    }
+  },
+  props: ['allEvents'],
+  emits: ['event-deleted', 'edit-started'],
+
+  // 2. COMPUTED: Create a property that automatically recalculates when its dependencies change.
+  computed: {
+    /**
+     * This computed property flattens the original nested allEvents array
+     * and then re-chunks it based on the current `itemsPerSlide`.
+     */
+    chunkedEvents() {
+      /*  console.log("CHUNKED EVENTS",this.allEvents)*/
+      // Return empty array if the prop is not yet ready.
+      if (!this.allEvents || this.allEvents.length === 0) {
+        return []
+      }
+
+      // First, flatten the nested array into a single list of all events.
+      // e.g., [[1,2,3], [4,5,6]] becomes [1,2,3,4,5,6]
+      const flatEvents = this.allEvents.flat()
+      /*console.log('flatEvents', flatEvents)*/
+
+      // This is the abstract "resize the array" method you mentioned.
+      // It chunks the flat list into new sub-arrays.
+
+      return transformArray(flatEvents, this.itemsPerSlide, false)
+    },
+  },
+
+  methods: {
+    /**
+     * Checks the window width and updates the `itemsPerSlide` data property.
+     * This will trigger the `chunkedEvents` computed property to recalculate.
+     */
+    updateItemsPerSlide() {
+      const width = window.innerWidth
+      // Using standard Bootstrap breakpoints
+      if (width < 992) {
+        // Small devices (phones)
+        this.itemsPerSlide = 1
+      } else if (width < 1100) {
+        // Medium devices (tablets/laptops)
+        this.itemsPerSlide = 2
+      } else {
+        // Large devices (desktops)
+        this.itemsPerSlide = 3
+      }
+    },
+
+    getImageLogo(imageLogo: string): any {
+      if (!imageLogo || !imageLogo.startsWith('/')) {
+        return pankake
+      }
+      return config.API_BASE_URL + imageLogo
+    },
+    deleteEvent(eventId){
+      useLocalManager.deleteEvent(eventId)
+        .then(() => {
+          this.$emit('event-deleted', eventId)
+          this.showToast("Successfully deleted event")
+        })
+        .catch((err)=> {
+          this.showToast(err.response, 'error')
+        })
+    }
+  },
+
+  mounted() {
+    /*   setInterval(() => {
+         console.log(this.chunkedEvents)
+       }, 1000)*/
+    // Call the method once on component mount to set the initial state.
+    this.updateItemsPerSlide()
+    // Add event listener for window resizing.
+    window.addEventListener('resize', this.updateItemsPerSlide)
+  },
+
+  beforeUnmount() {
+    // IMPORTANT: Remove the event listener when the component is destroyed
+    // to prevent memory leaks.
+    window.removeEventListener('resize', this.updateItemsPerSlide)
+  },
+}
+</script>
+
+<template>
+  <div id="carouselMulti3" class="carousel slide col-12" data-bs-ride="carousel">
+    <div class="carousel-inner">
+      <div
+        class="carousel-item"
+        v-for="(eventGroup, index) in chunkedEvents"
+        :key="index"
+        :class="{ active: index === 0 }"
+      >
+        <div style="gap: 0.2rem" class="d-flex justify-content-center">
+          <!-- The inner loop now iterates over the `eventGroup` (the chunk) -->
+          <div class="" v-for="event in eventGroup" :key="event.id">
+            <div class="card" style="width: 18rem">
+              <div class="card-body mb-2">
+                <h5 class="card-title fw-bold">{{ event.name }}</h5>
+                <p>{{event.description}}</p>
+                <div class="card-text d-flex justify-content-between">
+                  <div class="text-muted">{{ event.eventType }}</div>
+                  <div class="text-muted">
+                    {{ event.eventStart.date }} <br />
+                    <i class="fas fa-clock me-2 text-secondary mb-2"></i> {{ event.eventStart.time }}
+                  </div>
+                </div>
+                <button v-if="userStore_.isLocaleManager" class="btn btn-dark " @click="$emit('edit-started', event.id)">Edit event</button>
+                <button v-if="userStore_.isLocaleManager" class="btn btn-danger " @click="deleteEvent(event.id)">Delete event</button>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+    <button
+      class="carousel-control-prev"
+      type="button"
+      data-bs-target="#carouselMulti3"
+      data-bs-slide="prev"
+    >
+      <span class="carousel-control-prev-icon"></span>
+    </button>
+    <button
+      class="carousel-control-next"
+      type="button"
+      data-bs-target="#carouselMulti3"
+      data-bs-slide="next"
+    >
+      <span class="carousel-control-next-icon"></span>
+    </button>
+  </div>
+</template>
+
+<style scoped>
+.carousel-control-prev-icon,
+.carousel-control-next-icon {
+  filter: invert(100%); /* This turns white into black */
+}
+</style>
Index: ReserveNGo-frontend/src/components/Project/Manager/ManagerDashboard.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Manager/ManagerDashboard.vue	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/components/Project/Manager/ManagerDashboard.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -1,6 +1,11 @@
 <script>
 import { userStore } from '@/PiniaStores/UserStore.js'
+import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
+import { isValidEmail } from '@/mixins/utilFunctions.js'
+import { useLocalManager } from '@/repository/LocalManager.ts'
+import { useToasts } from '@/composables/useToast.js'
 
 export default {
+  components: { LoadingIcon },
   data() {
     return {
@@ -13,121 +18,119 @@
       sortKey: '',
       sortOrder: 'asc',
+      showToast: useToasts().showToast,
+      emailToWorker: '',
+      isEmailSending: false,
+
+      assigningWorkerId: null,
+      removingWorkerId: null,
     }
   },
   computed: {
     sortedWorkers() {
-      if (!this.sortKey) return this.workersForLocal;
-
+      if (!this.sortKey) return this.workersForLocal
       return [...this.workersForLocal].sort((a, b) => {
-        let valueA = a[this.sortKey] || '';
-        let valueB = b[this.sortKey] || '';
-
+        let valueA = a[this.sortKey] || ''
+        let valueB = b[this.sortKey] || ''
         if (typeof valueA === 'string') {
-          valueA = valueA.toLowerCase();
-          valueB = valueB.toLowerCase();
+          valueA = valueA.toLowerCase()
+          valueB = valueB.toLowerCase()
         }
-
-        if (valueA < valueB) return this.sortOrder === 'asc' ? -1 : 1;
-        if (valueA > valueB) return this.sortOrder === 'asc' ? 1 : -1;
-        return 0;
-      });
-    }
+        if (valueA < valueB) return this.sortOrder === 'asc' ? -1 : 1
+        if (valueA > valueB) return this.sortOrder === 'asc' ? 1 : -1
+        return 0
+      })
+    },
   },
   methods: {
     sortBy(key) {
       if (this.sortKey === key) {
-        this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc';
+        this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc'
       } else {
-        this.sortKey = key;
-        this.sortOrder = 'asc';
-      }
-    },
-    fetchWorkersForLocal() {
-      fetch('http://localhost:8080/api/local-manager/local-workers', {
-        method: 'GET',
-        headers: {
-          'Content-Type': 'application/json',
-          Authorization: this.user.getToken,
-        },
-      })
-        .then((res) => res.json())
-        .then((data) => (this.workersForLocal = data))
-        .catch((err) => console.log(err))
-    },
-    fetchWorkers() {
-      fetch('http://localhost:8080/api/local-manager/workers', {
-        method: 'GET',
-        headers: {
-          'Content-Type': 'application/json',
-          Authorization: this.user.getToken,
-        },
-      })
-        .then((res) => res.json())
-        .then((data) => (this.workers = data))
-        .catch((err) => console.log(err))
-    },
-    fetchLocal() {
-      fetch('http://localhost:8080/api/local-manager/my-local', {
-        method: 'GET',
-        headers: {
-          'Content-Type': 'application/json',
-          Authorization: this.user.getToken,
-        },
-      })
-        .then((res) => res.json())
-        .then((data) => (this.localId = data.id))
-        .catch((err) => console.log(err))
-    },
-    assignWorker(workerId) {
-      fetch(`http://localhost:8080/api/local-manager/assign/${workerId}`, {
-        method: 'POST',
-        headers: {
-          'Content-Type': 'application/json',
-          Authorization: this.user.getToken,
-        },
-      })
-        .then((response) => {
-          if (!response.ok) throw new Error('Failed to Assign worker.')
-          this.workers = this.workers.filter((worker) => worker.workerId !== workerId)
-          this.fetchWorkers()
-          this.fetchWorkersForLocal()
-        })
-        .catch((err) => console.log(err))
-    },
-    removeWorker(workerId) {
-      fetch(`http://localhost:8080/api/local-manager/remove/${workerId}`, {
-        method: 'DELETE',
-        headers: {
-          'Content-Type': 'application/json',
-          Authorization: this.user.getToken,
-        },
-      })
-        .then((response) => {
-          if (!response.ok) throw new Error('Failed to remove worker')
-          this.fetchWorkersForLocal()
-          this.fetchWorkers()
-        })
-        .catch((err) => console.log(err))
-    },
-    changeWorkerPosition(workerId, position) {
-      fetch(`http://localhost:8080/api/local-manager/change-position/${workerId}`, {
-        method: 'PUT',
-        headers: {
-          'Content-Type': 'application/json',
-          Authorization: this.user.getToken,
-        },
-        body: JSON.stringify({
-          position: position,
-        }),
-      })
-        .then((response) => {
-          if (!response.ok) throw new Error('Failed to change position');
-          this.fetchWorkersForLocal();
-        })
-        .catch(err => console.error('Error changing position:', err));
+        this.sortKey = key
+        this.sortOrder = 'asc'
+      }
+    },
+
+    async fetchWorkersForLocal() {
+      try {
+        this.workersForLocal = await useLocalManager.getLocalWorkers()
+      } catch (error) {
+        console.error('Failed to fetch local workers:', error)
+        this.showToast('Could not load your workers.', 'error')
+      }
+    },
+    async fetchWorkers() {
+      try {
+        this.workers = await useLocalManager.getAvailableWorkers()
+      } catch (error) {
+        console.error('Failed to fetch available workers:', error)
+      }
+    },
+    async fetchLocal() {
+      try {
+        const local = await useLocalManager.getMyLocal()
+        this.localId = local.id
+      } catch (error) {
+        console.error('Failed to fetch your local:', error)
+      }
+    },
+    async assignWorker(worker) {
+      this.assigningWorkerId = worker.id;
+      try {
+        await useLocalManager.assignWorker(worker.id)
+        this.showToast(`Assigned ${worker.firstName} successfully.`, 'success')
+        await this.fetchWorkers()
+        await this.fetchWorkersForLocal()
+      } catch (error) {
+        this.showToast(error.response || 'Failed to assign worker.', 'error')
+      } finally {
+        this.assigningWorkerId = null
+      }
+    },
+    async removeWorker(worker) {
+      this.removingWorkerId = worker.id;
+      try {
+        await useLocalManager.removeWorker(worker.id)
+        this.showToast(`Removed ${worker.firstName} successfully.`, 'success')
+        await this.fetchWorkersForLocal()
+      } catch (error) {
+        this.showToast(error.response || 'Failed to remove worker.', 'error')
+      } finally {
+        this.removingWorkerId = null
+      }
+    },
+    async changeWorkerPosition(workerId, position) {
+      try {
+        await useLocalManager.changeWorkerPosition(workerId, position)
+        this.showToast(`Position updated successfully.`, 'success')
+      } catch (error) {
+        this.showToast(error.response?.data?.message || 'Failed to change position.', 'error')
+        await this.fetchWorkersForLocal()
+      }
     },
     openAddWorkerModal() {
       this.fetchWorkers()
       this.showAddWorkerModal = true
+    },
+    async sendEmailToWorker() {
+      if (this.emailToWorker === '') {
+        this.showToast('Fill out the email form', 'error')
+        return
+      }
+      if (!isValidEmail(this.emailToWorker)) {
+        this.showToast('Please enter a valid email format', 'error')
+        return
+      }
+
+      this.isEmailSending = true
+      try {
+        await useLocalManager.inviteWorker(this.emailToWorker)
+        this.showToast(`Invite sent to ${this.emailToWorker}`, 'success')
+        this.emailToWorker = ''
+      } catch (error) {
+        this.showToast(error.response?.data?.message || 'Failed to send email.', 'error')
+      } finally {
+        this.isEmailSending = false
+      }
     },
   },
@@ -164,5 +167,12 @@
               >
                 <span>{{ worker.firstName }} {{ worker.lastName }} - {{ worker.email }}</span>
-                <button class="btn btn-sm btn-success" @click="assignWorker(worker.id)">Add</button>
+                <button
+                  class="btn btn-sm btn-success"
+                  @click="assignWorker(worker)"
+                  :disabled="assigningWorkerId === worker.id"
+                >
+                  <LoadingIcon v-if="assigningWorkerId === worker.id" />
+                  <span v-else>Add</span>
+                </button>
               </li>
             </ul>
@@ -176,52 +186,69 @@
       <table class="table table-striped table-hover align-middle">
         <thead class="table-light">
-        <tr>
-          <th style="cursor: pointer;" @click="sortBy('firstName')">
-            First Name
-            <span v-if="sortKey === 'firstName'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
-          </th>
-          <th style="cursor: pointer;" @click="sortBy('lastName')">
-            Last Name
-            <span v-if="sortKey === 'lastName'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
-          </th>
-          <th>Email</th>
-          <th>Phone Number</th>
-          <th style="cursor: pointer;" @click="sortBy('position')">
-            Position
-            <span v-if="sortKey === 'position'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
-          </th>
-          <th class="text-end">Actions</th>
-        </tr>
+          <tr>
+            <th style="cursor: pointer" @click="sortBy('firstName')">
+              First Name
+              <span v-if="sortKey === 'firstName'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
+            </th>
+            <th style="cursor: pointer" @click="sortBy('lastName')">
+              Last Name
+              <span v-if="sortKey === 'lastName'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
+            </th>
+            <th>Email</th>
+            <th>Phone Number</th>
+            <th style="cursor: pointer" @click="sortBy('position')">
+              Position
+              <span v-if="sortKey === 'position'">{{ sortOrder === 'asc' ? '↑' : '↓' }}</span>
+            </th>
+            <th class="text-end">Actions</th>
+          </tr>
         </thead>
         <tbody>
-        <tr v-for="worker in sortedWorkers" :key="worker.id">
-          <td>{{ worker.firstName }}</td>
-          <td>{{ worker.lastName }}</td>
-          <td>{{ worker.email }}</td>
-          <td>{{ worker.phoneNumber }}</td>
-          <td>
-            <select
-              class="form-select form-select-sm"
-              :value="worker.position"
-              @change="changeWorkerPosition(worker.id, $event.target.value)"
-            >
-              <option :value="null" selected disabled>
-                {{ worker.position ? worker.position : 'Assign Position' }}
-              </option>
-              <option v-for="pos in positions" :key="pos" :value="pos">
-                {{ pos }}
-              </option>
-            </select>
-          </td>
-          <td class="text-end">
-            <button class="btn btn-sm btn-outline-danger" @click="removeWorker(worker.id)">Remove</button>
-          </td>
-        </tr>
+          <tr v-for="worker in sortedWorkers" :key="worker.id">
+            <td>{{ worker.firstName }}</td>
+            <td>{{ worker.lastName }}</td>
+            <td>{{ worker.email }}</td>
+            <td>{{ worker.phoneNumber }}</td>
+            <td>
+              <select
+                class="form-select form-select-sm"
+                :value="worker.position"
+                @change="changeWorkerPosition(worker.id, $event.target.value)"
+              >
+                <option :value="null" selected disabled>
+                  {{ worker.position ? worker.position : 'Assign Position' }}
+                </option>
+                <option v-for="pos in positions" :key="pos" :value="pos">{{ pos }}</option>
+              </select>
+            </td>
+            <td class="text-end">
+              <button
+                class="btn btn-sm btn-outline-danger"
+                @click="removeWorker(worker)"
+                :disabled="removingWorkerId === worker.id"
+              >
+                <LoadingIcon v-if="removingWorkerId === worker.id" />
+                <span v-else>Remove</span>
+              </button>
+            </td>
+          </tr>
         </tbody>
       </table>
     </div>
 
-    <!-- Add Worker Button -->
     <button class="btn btn-success mt-3" @click="openAddWorkerModal">+ Add Worker</button>
+    <div id="sendMailGroup" class="mt-3">
+      <button @click="sendEmailToWorker" class="btn btn-success">
+        <LoadingIcon v-if="isEmailSending" />
+        <span v-else>+ </span>
+        Send worker register mail
+      </button>
+      <input
+        v-model="emailToWorker"
+        class="form-control"
+        type="text"
+        placeholder="Enter worker's email"
+      />
+    </div>
   </div>
 </template>
@@ -235,5 +262,4 @@
   overflow: hidden;
 }
-
 .container {
   max-width: 1200px;
@@ -245,10 +271,8 @@
   overflow: hidden;
 }
-
 .table-container {
   flex: 1 1 auto;
   overflow-y: auto;
 }
-
 table {
   font-size: 0.95rem;
@@ -256,5 +280,4 @@
   width: 100%;
 }
-
 th,
 td {
@@ -263,5 +286,4 @@
   text-overflow: ellipsis;
 }
-
 thead th {
   position: sticky;
@@ -271,12 +293,23 @@
   user-select: none;
 }
-
 th span {
   margin-left: 5px;
   font-size: 0.8rem;
 }
-
 .modal {
   display: block;
 }
+#sendMailGroup {
+  display: flex;
+}
+#sendMailGroup > .btn {
+  flex-shrink: 0;
+  border-bottom-right-radius: 0;
+  border-top-right-radius: 0;
+}
+#sendMailGroup > .form-control {
+  flex-grow: 1;
+  border-bottom-left-radius: 0;
+  border-top-left-radius: 0;
+}
 </style>
Index: ReserveNGo-frontend/src/components/Project/Restaurant/Locale_.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Restaurant/Locale_.vue	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/components/Project/Restaurant/Locale_.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -3,5 +3,5 @@
 import { useRouter } from 'vue-router'
 import { transformArray } from '@/mixins/utilFunctions.js'
-import events_carousel from '@/components/Project/Restaurant/events_carousel_in_locale.vue'
+import events_carousel from '@/components/Project/Event/events_carousel_in_locale.vue'
 import WorkingHoursTable from '@/components/Project/Restaurant/working-hours-table.vue'
 import { useLocalManager } from '@/repository/LocalManager.ts'
@@ -12,8 +12,13 @@
 import { config } from '@/constants/Api_config.js'
 import ManagerFileInput from '@/components/Project/Utility/ManagerFileInput.vue'
-
+import HorizontalScroller from '@/components/Project/Utility/HorizontalScroller.vue'
+import AddEventModal from '@/components/Project/Event/EditEventModal.vue'
+import {useToasts} from '@/composables/useToast.js'
+import LoadingIcon from '@/components/Project/Utility/LoadingIcon.vue'
 
 export default {
   components: {
+    LoadingIcon,
+    HorizontalScroller,
     events_carousel,
     WorkingHoursTable,
@@ -22,4 +27,5 @@
     RatingsForLocal,
     ManagerFileInput,
+    AddEventModal,
   },
   data() {
@@ -72,6 +78,21 @@
       //END UPLOADINg files state
 
-
+      //loading details
+      isSaveChangesLoading: false,
+      //END loading details
+
+      isAddEventModalVisible: false,
+
+
+      //Edit Event
+      isEventModalVisible: false,
+      targetEditEvent: null,
+      //End Edit event
+
+      //Toast
+      showToast: useToasts().showToast,
+      //Toast end
     }
+
   },
   computed: {
@@ -108,7 +129,9 @@
       useLocalManager
         .deletePhoto({ localPhotosUrls })
-        .then((response) => console.log('SUCCESUFL DELATION', response))
+        .then((response) => {
+          this.showToast("Successfully deleted a locale image")
+        })
         .catch((error) => {
-          console.log('UNSUCCESFUL DELATION', error.rawResponse)
+          this.showToast(error.response, 'error')
           this.locale.localPhotos.push(image)
         })
@@ -117,5 +140,5 @@
     openImageModal(index, secondRow = false) {
       if (secondRow) {
-        index += 1
+        index += 2
       }
       this.selectedImageIndex = index
@@ -131,7 +154,7 @@
         .then((data) => {
           this.locale = data
-          console.log('LOCALE', this.locale)
+        /*  console.log('LOCALE', this.locale)*/
           // Safety checks for nested objects
-          console.log('LOCALE DATA FOR PICTURES', this.locale)
+         /* console.log('LOCALE DATA FOR PICTURES', this.locale)*/
           if (!this.locale.contact) {
             this.locale.contact = { phone: '', email: '' }
@@ -157,5 +180,5 @@
     },
     uploadLogo(fileInput) {
-      this.isLogoUploading = true;
+      this.isLogoUploading = true
       const picture = fileInput
       if (!picture) {
@@ -167,16 +190,25 @@
       useLocalManager
         .uploadLogo(formData)
-        .then((imagePath) =>
-          {useUtility.fetchImageBase64(imagePath).then((base64) => {this.locale_logo_base64encoded = base64});
-            this.$refs.uploadLogoInputRef.reset();})
+        .then((imagePath) => {
+          useUtility.fetchImageBase64(imagePath).then((base64) => {
+            this.locale_logo_base64encoded = base64
+          })
+          this.$refs.uploadLogoInputRef.reset()
+          this.showToast("Successfully uploaded the logo")
+        })
         .catch((error) => {
-          console.log(error)
+          if (error.status === 409) {
+            this.showToast(error.response, 'error')
+          }
+          else {
+            this.showToast("You do not have permission to make this request", 'error')
+          }
         })
         .finally(() => {
-          this.isLogoUploading = false;
+          this.isLogoUploading = false
         })
     },
     uploadPhoto(fileInput) {
-      this.isPhotoUploading = true;
+      this.isPhotoUploading = true
       const picture = fileInput
       if (!picture) {
@@ -189,10 +221,19 @@
         .uploadImage(formData)
         .then((response) => {
-          console.log('SUCCESFUL UPLOAD', response)
-          this.fetchLocaleData();
-          this.$refs.uploadPhotoInputRef.reset();
-        })
-        .catch((error) => console.log('Unable To upload image', error))
-        .finally(() => {this.isPhotoUploading = false;})
+          this.fetchLocaleData()
+          this.$refs.uploadPhotoInputRef.reset()
+          this.showToast("Successfully uploaded the photo")
+        })
+        .catch((error) => {
+          if (error.status === 409) {
+            this.showToast(error.response, 'error')
+          }
+          else {
+            this.showToast("You do not have permission to make this request", 'error')
+          }
+        })
+        .finally(() => {
+          this.isPhotoUploading = false
+        })
     },
     startEditing() {
@@ -208,4 +249,5 @@
     },
     saveLocalChanges() {
+      this.isSaveChangesLoading = true;
       // Prepare the payload for saving. The `workingHours` property is sent as-is.
       const payload = { ...this.locale }
@@ -213,30 +255,32 @@
       delete payload.eventsForCarousel
 
-      fetch(`http://localhost:8080/api/local-manager/my-local/edit`, {
-        method: 'PUT',
-        headers: {
-          Authorization: this.userStore.getToken,
-          'Content-Type': 'application/json',
-        },
-        body: JSON.stringify(payload),
-      })
+      useLocalManager.saveDetailChanges(payload)
         .then((res) => {
-          if (!res.ok) {
-            this.locale = this.cachedLocale // Revert on failure
-            alert('Failed to save changes. Please try again.')
-            throw new Error(`Server responded with status: ${res.status}`)
-          }
+          this.cachedLocale = null
+          this.showToast("Successfully updated")
+          this.fetchLocaleData()
+        })
+        .catch((error) => {
+          this.locale = this.cachedLocale // Revert on failure
+          this.showToast(error.response, 'error')
+        })
+        .finally(() => {
+          this.isSaveChangesLoading = false
           this.isEditing = false
-          this.cachedLocale = null
-          return res.json()
-        })
-        .then(() => {
-          console.log('Successfully updated.')
-          this.fetchLocaleData() // Refresh data to see the changes
-        })
-        .catch((error) => {
-          console.error('Error updating local:', error)
-        })
-    },
+        })
+    },
+    deleteEvent(eventId) {
+      this.locale.events = this.locale.events.filter(event=>event.id !== eventId);
+      this.fetchLocaleData()
+    },
+    addEvent() {
+      this.fetchLocaleData()
+      this.isModalVisible = false
+    },
+    startEditingEvent(eventId){
+      this.targetEditEvent = this.locale.events.find(event=>event.id === eventId);
+      console.log("TARGET EDIT EVENT", this.targetEditEvent)
+      this.isEventModalVisible = true;
+    }
   },
 }
@@ -261,4 +305,5 @@
             />
             <ManagerFileInput
+              v-if="userStore.isLocaleManager"
               ref="uploadLogoInputRef"
               @file-sent="uploadLogo"
@@ -279,4 +324,5 @@
           ></PhotosGridSystem>
           <ManagerFileInput
+            v-if="userStore.isLocaleManager"
             ref="uploadPhotoInputRef"
             style="margin-top: 1rem"
@@ -410,12 +456,11 @@
             <div class="mb-4">
               <h6 class="fw-bold">Services</h6>
-              <div v-if="!isEditing" class="d-flex flex-wrap gap-2">
-                <span
-                  v-for="service in locale.services"
-                  :key="service"
-                  class="badge bg-primary text-light"
-                  >{{ service }}</span
-                >
-              </div>
+              <HorizontalScroller v-if="!isEditing">
+                  <div
+                    v-for="service in locale.services"
+                    :key="service"
+                    class="badge bg-primary text-light p-2"
+                    >{{ service }}</div>
+              </HorizontalScroller>
               <div v-else>
                 <label for="servicesInput" class="form-label">Services (comma-separated)</label>
@@ -431,12 +476,20 @@
             <!--Rating component-->
             <div class="mb-3 row" v-if="userStore.data.role === 'ROLE_CUSTOMER'">
-              <RatingsForLocal :local-id="this.local_id" @rating-updated="fetchLocaleData"/>
+              <RatingsForLocal :local-id="this.local_id" @rating-updated="fetchLocaleData" />
             </div>
 
             <!-- Events Carousel (Read-only) -->
             <h6 class="fw-bold">Events</h6>
-            <div class="mb-3 row">
-              <events_carousel :all-events="eventsForCarousel" />
-            </div>
+
+            <div class="mb-2 row">
+              <events_carousel @edit-started="startEditingEvent" :all-events="eventsForCarousel" @event-deleted="deleteEvent" />
+            </div>
+            <button
+              v-if="userStore.isLocaleManager"
+              class="btn btn-primary btn-sm mb-2"
+              @click="isEventModalVisible = true"
+            >
+              <i class="fas fa-plus me-1"></i> Add Event
+            </button>
 
             <!-- Main Action Buttons -->
@@ -457,5 +510,7 @@
                 <template v-else>
                   <button class="btn btn-success" @click="saveLocalChanges">
-                    <i class="fas fa-save me-1"></i> Save
+                    <i v-if="!isSaveChangesLoading" class="fas fa-save me-1"></i>
+                    <span v-else><LoadingIcon></LoadingIcon></span>
+                    Save
                   </button>
                   <button class="btn btn-secondary" @click="cancelEditing">
@@ -465,5 +520,8 @@
               </template>
 
-              <router-link to="/" class="btn btn-outline-secondary" v-if="userStore.data.role !== 'ROLE_LOCAL_MANAGER'"
+              <router-link
+                to="/"
+                class="btn btn-outline-secondary"
+                v-if="userStore.data.role !== 'ROLE_LOCAL_MANAGER'"
                 ><i class="fas fa-arrow-left me-1"></i> Back</router-link
               >
@@ -474,4 +532,11 @@
     </div>
   </div>
+  <AddEventModal
+    :show="isEventModalVisible"
+    @close="isEventModalVisible = false; targetEditEvent=null"
+    @event-added="addEvent"
+    @event-updated="addEvent"
+    :event-to-edit="targetEditEvent"
+  />
 </template>
 
@@ -489,3 +554,2 @@
 }
 </style>
-
Index: serveNGo-frontend/src/components/Project/Restaurant/events_carousel.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Restaurant/events_carousel.vue	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ 	(revision )
@@ -1,174 +1,0 @@
-<script lang="ts">
-import { userStore } from '@/PiniaStores/UserStore.js'
-import { useLocales } from '@/repository/Locale'
-import { config } from '@/constants/Api_config'
-import pankake from '@/components/ectd/easy-american-pancake-recipe.jpg'
-import { transformArray } from '@/mixins/utilFunctions'
-
-
-export default {
-  data() {
-    return {
-      userStore_: userStore(),
-      pankake: pankake,
-      itemsPerSlide: 3,
-    }
-  },
-  props: ['allEvents'],
-
-  watch: {
-    allEvents: {
-      handler(events) {
-        if (events && events.length > 0) {
-          events.forEach((eventGroup) => {
-            eventGroup.forEach((event) => {
-              useLocales.getSpecificLocale(event.localId).then((locale) => {
-                event.logo = locale.logo
-              })
-            })
-          })
-        } else {
-          console.log('allEvents is still empty or undefined.')
-        }
-      },
-      immediate: true,
-      deep: true,
-    },
-  },
-
-  // 2. COMPUTED: Create a property that automatically recalculates when its dependencies change.
-  computed: {
-    /**
-     * This computed property flattens the original nested allEvents array
-     * and then re-chunks it based on the current `itemsPerSlide`.
-     */
-    chunkedEvents() {
-    /*  console.log("CHUNKED EVENTS",this.allEvents)*/
-      // Return empty array if the prop is not yet ready.
-      if (!this.allEvents || this.allEvents.length === 0) {
-        return []
-      }
-
-      // First, flatten the nested array into a single list of all events.
-      // e.g., [[1,2,3], [4,5,6]] becomes [1,2,3,4,5,6]
-      const flatEvents = this.allEvents.flat()
-      /*console.log('flatEvents', flatEvents)*/
-
-      // This is the abstract "resize the array" method you mentioned.
-      // It chunks the flat list into new sub-arrays.
-
-      return transformArray(flatEvents, this.itemsPerSlide, false)
-    },
-  },
-
-  methods: {
-    /**
-     * Checks the window width and updates the `itemsPerSlide` data property.
-     * This will trigger the `chunkedEvents` computed property to recalculate.
-     */
-    updateItemsPerSlide() {
-      const width = window.innerWidth
-      // Using standard Bootstrap breakpoints
-      if (width < 768) {
-        // Small devices (phones)
-        this.itemsPerSlide = 1
-      } else if (width < 992) {
-        // Medium devices (tablets/laptops)
-        this.itemsPerSlide = 2
-      } else {
-        // Large devices (desktops)
-        this.itemsPerSlide = 3
-      }
-    },
-
-    getImageLogo(imageLogo: string): any {
-      if (!imageLogo || !imageLogo.startsWith('/')) {
-        return pankake
-      }
-      return config.API_BASE_URL + imageLogo
-    },
-  },
-
-  mounted() {
- /*   setInterval(() => {
-      console.log(this.chunkedEvents)
-    }, 1000)*/
-    // Call the method once on component mount to set the initial state.
-    this.updateItemsPerSlide()
-    // Add event listener for window resizing.
-    window.addEventListener('resize', this.updateItemsPerSlide)
-  },
-
-  beforeUnmount() {
-    // IMPORTANT: Remove the event listener when the component is destroyed
-    // to prevent memory leaks.
-    window.removeEventListener('resize', this.updateItemsPerSlide)
-  },
-}
-</script>
-
-<template>
-  <div id="carouselMulti3" class="carousel slide col-12 col-md-8" data-bs-ride="carousel">
-    <div class="carousel-inner">
-      <!--
-        HERE IS THE FIX:
-        - We use a single v-for to loop through our reactive `chunkedEvents`.
-        - `chunkedEvents` will contain arrays of 1, 2, or 3 items, depending on screen size.
-        - `:class="{ active: index === 0 }"` dynamically makes the first carousel slide active.
-      -->
-      <div
-        class="carousel-item"
-        v-for="(eventGroup, index) in chunkedEvents"
-        :key="index"
-        :class="{ active: index === 0 }"
-      >
-        <div style="gap: 0.2rem" class="d-flex justify-content-center">
-          <!-- The inner loop now iterates over the `eventGroup` (the chunk) -->
-          <div class="" v-for="event in eventGroup" :key="event.id">
-            <div class="card" style="width: 18rem">
-              <img
-                height="100"
-                :src="getImageLogo(event.logo) || pankake"
-                class="card-img-top"
-                alt="..."
-              />
-              <div class="card-body">
-                <h5 class="card-title fw-bold">{{ event.name }}</h5>
-                <div class="card-text d-flex justify-content-between">
-                  <div class="text-muted">{{ event.eventType }}</div>
-                  <div class="text-muted">
-                    {{ event.eventStart.date }} <br />
-                    <i class="fas fa-clock me-2 text-secondary"></i> {{ event.eventStart.time }}
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-    <button
-      class="carousel-control-prev"
-      type="button"
-      data-bs-target="#carouselMulti3"
-      data-bs-slide="prev"
-    >
-      <span class="carousel-control-prev-icon"></span>
-    </button>
-    <button
-      class="carousel-control-next"
-      type="button"
-      data-bs-target="#carouselMulti3"
-      data-bs-slide="next"
-    >
-      <span class="carousel-control-next-icon"></span>
-    </button>
-  </div>
-</template>
-
-<style scoped>
-.carousel-control-prev-icon,
-.carousel-control-next-icon {
-  filter: invert(100%); /* This turns white into black */
-}
-</style>
Index: serveNGo-frontend/src/components/Project/Restaurant/events_carousel_in_locale.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Restaurant/events_carousel_in_locale.vue	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ 	(revision )
@@ -1,129 +1,0 @@
-<script lang="ts">
-
-import { userStore } from '@/PiniaStores/UserStore.js'
-
-/*function transformDate(dateTime) {
-  let [date, time] = dateTime.split('T')
-  let timeSplit = time.split(':')
-  time = timeSplit[0] + ":" + timeSplit[1]
-  return {date: date, time: time}
-}
-
-
-function transformArray(arr) {
-
-  arr.forEach(item => {
-    item.eventEnd = transformDate(item.eventEnd)
-    item.eventStart = transformDate(item.eventStart)
-  })
-
-  let newArray = []
-  for (let i = 0; i<arr.length; i+=3) {
-    newArray.push(arr.slice(i, i + 3))
-  }
-  return newArray;
-
-}*/
-
-export default {
-  data() {
-    return {
-      userStore_: userStore()
-    }
-  },
-  props: ['allEvents'],
-
-  /* beforeMount() {
-     //Events ne bi trebalo da bara authorisation. !!!!
-     fetch('http://localhost:8080/api/events',
-       {
-         method: 'GET',
-         headers: {
-
-           Authorization: this.userStore_.getToken,
-
-         }
-       })
-     .then(res => res.json())
-     .then(data => { this.allEvents = transformArray(data.events); console.log("Currently Reading here", this.allEvents) })
-       .catch(error => console.log("Probobly failed fetching events because of login",error))
-   }*/
-
-}
-
-</script>
-
-<template>
-
-  <!--
-    <div id="carouselExampleControls" class="col-6 carousel slide" data-bs-ride="carousel">
-      <div class="carousel-inner">
-        <div class="carousel-item active">
-          <img height="200" src="../../ectd/easy-american-pancake-recipe.jpg" data-bs-interval="5000" class="d-block w-100" alt="...">
-        </div>
-        <div class="carousel-item">
-          <img height="200" src="../../ectd/easy-american-pancake-recipe.jpg" data-bs-interval="5000" class="d-block w-100" alt="...">
-        </div>
-        <div class="carousel-item">
-          <img height="200" src="../../ectd/easy-american-pancake-recipe.jpg" data-bs-interval="5000" class="d-block w-100" alt="...">
-        </div>
-      </div>
-      <button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="prev">
-        <span class="carousel-control-prev-icon" aria-hidden="true"></span>
-      </button>
-      <button class="carousel-control-next" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="next">
-        <span class="carousel-control-next-icon" aria-hidden="true"></span>
-      </button>
-    </div>-->
-
-  <div id="carouselMulti3" class="carousel slide col-12" data-bs-ride="carousel">
-    <div class="carousel-inner">
-      <div class="carousel-item active">
-        <div style="gap: 0.2rem" class="d-flex">
-          <div class="" v-for="event in allEvents[0]" :key="event.id">
-            <div class="card" style="width: 18rem;">
-              <img height="100" src="../../ectd/easy-american-pancake-recipe.jpg" class="card-img-top" alt="...">
-              <div class="card-body">
-                <h5 class="card-title fw-bold">{{event.name}}</h5>
-                <div class="card-text d-flex justify-content-between">
-                  <div class="text-muted"> {{event.eventType}}</div>
-                  <div class="text-muted">{{event.eventStart.date}} <br> <i class="fas fa-clock me-2 text-secondary"></i>{{event.eventStart.time}}</div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-      <!--      Sto Ako listata e pomala od 3 !!!!!!! -->
-      <div class="carousel-item" v-for="eventGroup in allEvents.slice(1)" :key="eventGroup">
-        <div style="gap: 0.2rem" class="d-flex">
-          <div class="" v-for="event in eventGroup" :key="event.id">
-            <div class="card" style="width: 18rem;">
-              <img height="100" src="../../ectd/easy-american-pancake-recipe.jpg" class="card-img-top" alt="...">
-              <div class="card-body">
-                <h5 class="card-title fw-bold">{{event.name}}</h5>
-                <div class="card-text d-flex justify-content-between">
-                  <div class="text-muted"> {{event.eventType}}</div>
-                  <div class="text-muted" >{{event.eventStart.date}} <br> <i class="fas fa-clock me-2 text-secondary"></i> {{event.eventStart.time}}</div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-
-    </div>
-    <button class="carousel-control-prev" type="button" data-bs-target="#carouselMulti3" data-bs-slide="prev">
-      <span class="carousel-control-prev-icon"></span>
-    </button>
-    <button class="carousel-control-next" type="button" data-bs-target="#carouselMulti3" data-bs-slide="next">
-      <span class="carousel-control-next-icon"></span>
-    </button>
-  </div>
-
-
-</template>
-
-<style scoped>
-
-</style>
Index: ReserveNGo-frontend/src/components/Project/Restaurant/home_.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Restaurant/home_.vue	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/components/Project/Restaurant/home_.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -2,5 +2,5 @@
 import Locale_listing_container from '@/components/Project/Restaurant/Locale_listing_container.vue'
 import SearchFilterPanel from '@/components/Project/Restaurant/search_filter_panel.vue'
-import Events_carousel from '@/components/Project/Restaurant/events_carousel.vue'
+import Events_carousel from '@/components/Project/Event/events_carousel.vue'
 import { transformArray } from '@/mixins/utilFunctions.js'
 
Index: ReserveNGo-frontend/src/components/Project/Restaurant/local_in_local_listing.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Restaurant/local_in_local_listing.vue	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/components/Project/Restaurant/local_in_local_listing.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -55,5 +55,5 @@
   computed: {
     locale_logo() {
-      if (!this.local.logo.startsWith('/')) {return this.pankake}
+      if (this.local.logo === null) {return this.pankake}
       const url = new URL(this.local.logo, config.API_BASE_URL)
       return url.toString();
Index: ReserveNGo-frontend/src/components/Project/Utility/HorizontalScroller.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/HorizontalScroller.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
+++ ReserveNGo-frontend/src/components/Project/Utility/HorizontalScroller.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -0,0 +1,243 @@
+<!-- components/HorizontalScroller.vue -->
+<template>
+  <div class="scroller-wrapper">
+    <!-- Left Navigation Arrow -->
+    <button
+      v-if="canScrollLeft"
+      class="nav-arrow prev"
+      @click="scrollLeft"
+      aria-label="Scroll left"
+    >
+      <LeftArrow></LeftArrow>
+    </button>
+
+    <!-- The container that hides the scrollbar and captures events -->
+    <div class="scroll-container" ref="scrollContainer" @scroll.passive="handleScroll">
+      <!-- The flex wrapper for your content -->
+      <div class="content-wrapper" ref="contentWrapper">
+        <slot></slot>
+      </div>
+    </div>
+
+    <!-- Right Navigation Arrow -->
+    <button
+      v-if="canScrollRight"
+      class="nav-arrow next"
+      @click="scrollRight"
+      aria-label="Scroll right"
+    >
+      <RightArrow></RightArrow>
+    </button>
+  </div>
+</template>
+
+<script>
+import LeftArrow from '@/components/Project/Utility/LeftArrow.vue'
+import RightArrow from '@/components/Project/Utility/RightArrow.vue'
+
+export default {
+  name: 'HorizontalScroller',
+  components: { RightArrow, LeftArrow },
+  data() {
+    return {
+      // These booleans control the visibility of the arrows
+      canScrollLeft: false,
+      canScrollRight: false,
+      // A ResizeObserver to detect when the container or content size changes
+      resizeObserver: null,
+      // Add a new property for debugging
+      thirdChildOffsetLeft: 'N/A',
+      scrollContainerScrollLeftValue: 'N/A',
+    }
+  },
+  mounted() {
+    // Wait for the DOM to be ready before doing calculations
+    this.$nextTick(() => {
+      this.checkForOverflow()
+
+      this.resizeObserver = new ResizeObserver(() => this.checkForOverflow())
+      this.resizeObserver.observe(this.$refs.contentWrapper)
+      this.resizeObserver.observe(this.$refs.scrollContainer)
+    })
+  },
+  methods: {
+    /**
+     * This is the master method that checks if scrolling is possible
+     * and updates the visibility of the navigation arrows.
+     */
+    checkForOverflow() {
+      const container = this.$refs.scrollContainer
+      if (!container) return
+      const content = this.$refs.contentWrapper
+
+      // --- START: Debugging Logic ---
+      // Check if the third child exists (arrays are 0-indexed)
+      if (content.children && content.children.length > 2) {
+        const thirdChild = content.children[6]
+      /*  console.log("chiled", thirdChild)*/
+        // Get the element's offset relative to its parent.
+        // This value only changes on window resize or layout change.
+        this.thirdChildOffsetLeft = thirdChild.offsetLeft
+        this.scrollContainerScrollLeftValue = container.scrollLeft + container.clientWidth
+        /*console.log("ThirdChieldOffSetLEft", this.thirdChildOffsetLeft)*/
+      } else {
+        this.thirdChildOffsetLeft = 'N/A'
+      }
+      // --- END: Debugging Logic ---
+
+      const hasOverflow = container.scrollWidth > container.clientWidth
+
+      this.canScrollLeft = hasOverflow && container.scrollLeft > 0
+      this.canScrollRight =
+        hasOverflow && container.scrollLeft + 1 < container.scrollWidth - container.clientWidth
+    },
+
+    /**
+     * This method is called whenever the user scrolls the container,
+     * either with the arrows or manually (e.g., trackpad).
+     */
+    handleScroll() {
+      // We just need to re-run the check to update the arrow states.
+      this.checkForOverflow()
+    },
+
+    /**
+     * The core logic for scrolling to the right.
+     * It finds the first item that is currently clipped on the right
+     * and scrolls just enough to make it fully visible.
+     */
+    scrollRight() {
+      const container = this.$refs.scrollContainer
+      const items = this.$refs.contentWrapper.children
+      if (!container || items.length === 0) return
+
+      const containerRightEdge = container.scrollLeft + container.clientWidth
+
+      // Find the first item whose left edge is past the visible area
+      let targetItem = null
+      for (const item of items) {
+        if (item.offsetLeft >= containerRightEdge) {
+          targetItem = item
+          break
+        }
+      }
+
+      // If no item is found (we might be at the end), we don't scroll
+      if (targetItem) {
+/*        console.log("TargetItem", targetItem)*/
+        container.scrollTo({
+          left: targetItem.offsetLeft + targetItem.clientWidth - container.clientWidth,
+          behavior: 'smooth',
+        })
+      }
+    },
+
+    /**
+     * The core logic for scrolling to the left.
+     * It finds the first fully visible item and scrolls to make the
+     * item *before* it the new first visible item.
+     */
+    scrollLeft() {
+      const container = this.$refs.scrollContainer
+      const items = this.$refs.contentWrapper.children
+      if (!container || items.length === 0) return
+
+      const containerLeftEdge = container.scrollLeft
+
+      // Find the last item that starts before the visible area
+      let targetItem = null
+      for (const item of items) {
+        if (item.offsetLeft < containerLeftEdge - 1) {
+          targetItem = item
+        } else {
+          // As soon as we find an item that starts inside the view, we can stop.
+          break
+        }
+      }
+
+      if (targetItem) {
+        container.scrollTo({
+          left: targetItem.offsetLeft,
+          behavior: 'smooth',
+        })
+      } else {
+        // If no item is clipped on the left, scroll to the very beginning
+        container.scrollTo({ left: 0, behavior: 'smooth' })
+      }
+    },
+  },
+
+}
+</script>
+
+<style scoped>
+.scroller-wrapper {
+  position: relative;
+  width: 100%;
+}
+
+.scroll-container {
+  /* This is the key: hide the native scrollbar */
+  overflow-x: scroll;
+  scrollbar-width: none; /* For Firefox */
+  -ms-overflow-style: none; /* For Internet Explorer and Edge */
+
+  /* Enables smooth scrolling on iOS devices */
+  -webkit-overflow-scrolling: touch;
+}
+
+.scroll-container::-webkit-scrollbar {
+  display: none; /* For Chrome, Safari, and Opera */
+}
+
+.content-wrapper {
+  display: flex;
+  flex-wrap: nowrap;
+  gap: 1rem; /* Adjust the gap between your items */
+  padding-block: 1rem; /* Adds some vertical space so arrows aren't on the edge */
+}
+
+.content-wrapper > * {
+  flex-grow: 1;
+  flex-shrink: 0;
+  flex-basis: 5rem;
+}
+
+.nav-arrow {
+  position: absolute;
+  top: 50%;
+  transform: translateY(-50%);
+  z-index: 10;
+  /*width: 40px;*/
+  aspect-ratio: 1 / 1;
+  padding: 10px;
+  border-radius: 50%;
+  background-color: rgba(255, 255, 255, 0.7);
+  border: 1px solid #ddd;
+  box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.1);
+  cursor: pointer;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  /*  vertical-align: top;
+  text-align: start;*/
+
+  color: #333;
+  transition:
+    transform 0.2s ease,
+    box-shadow 0.2s ease;
+}
+
+.nav-arrow:hover {
+  transform: translateY(-50%) scale(1.1);
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+}
+
+.nav-arrow.prev {
+  left: -20px; /* Position half-way out of the container */
+}
+
+.nav-arrow.next {
+  right: -20px; /* Position half-way out of the container */
+}
+</style>
Index: ReserveNGo-frontend/src/components/Project/Utility/ImageModalLocale.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/ImageModalLocale.vue	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/components/Project/Utility/ImageModalLocale.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -1,6 +1,4 @@
 <!-- components/ImageModal.vue -->
 <script lang="ts">
-
-import {useLocalManager} from '@/repository/LocalManager'
 import {userStore} from '@/PiniaStores/UserStore'
 
@@ -10,6 +8,5 @@
     startIndex: { type: Number, default: 0 },
     show: { type: Boolean, default: false },
-    // --- NEW: Prop to check the user's role ---
-    userRole: { type: String, default: 'USER' },
+
   },
   emits: ['close', 'remove-image'], // Added 'remove-image' emit
@@ -27,7 +24,4 @@
     },
     // --- NEW: A computed property to easily check the role ---
-    isManager() {
-      return true;
-    },
   },
   methods: {
@@ -90,5 +84,5 @@
             <!-- === NEW: Conditional Remove Button === -->
             <button
-              v-if="isManager"
+              v-if="userStore_.isLocaleManager || userStore_.isAdmin"
               @click.stop="handleRemove(image, index)"
               class="btn btn-danger btn-sm remove-btn"
Index: ReserveNGo-frontend/src/components/Project/Utility/LeftArrow.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/LeftArrow.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
+++ ReserveNGo-frontend/src/components/Project/Utility/LeftArrow.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -0,0 +1,5 @@
+<template>
+  <svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
+    <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m15 6l-6 6l6 6" />
+  </svg>
+</template>
Index: ReserveNGo-frontend/src/components/Project/Utility/LoadingIcon.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/LoadingIcon.vue	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/components/Project/Utility/LoadingIcon.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -1,4 +1,4 @@
 <template>
-  <svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
+  <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24">
     <g>
       <rect width="2" height="5" x="11" y="1" fill="currentColor" opacity="0.14" />
Index: ReserveNGo-frontend/src/components/Project/Utility/PhotosGridSystem.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/PhotosGridSystem.vue	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/components/Project/Utility/PhotosGridSystem.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -36,5 +36,5 @@
     <!-- Bottom row with 3 images -->
     <div class="grid-row-bottom">
-      <img @click="openImageModal(index, true)" class="grid-image" v-for="(image, index) in images.slice(2, 4)" :key="index" :src="image" alt="">
+      <img @click="openImageModal(index, true)" class="grid-image" v-for="(image, index) in images.slice(2, 5)" :key="index" :src="image" alt="">
     </div>
   </div>
Index: ReserveNGo-frontend/src/components/Project/Utility/RightArrow.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/RightArrow.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
+++ ReserveNGo-frontend/src/components/Project/Utility/RightArrow.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -0,0 +1,5 @@
+<template>
+  <svg xmlns="http://www.w3.org/2000/svg" width="1.2em" height="1.2em" viewBox="0 0 24 24">
+    <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m9 6l6 6l-6 6" />
+  </svg>
+</template>
Index: ReserveNGo-frontend/src/components/Project/Utility/ToastContainer.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/ToastContainer.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
+++ ReserveNGo-frontend/src/components/Project/Utility/ToastContainer.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -0,0 +1,59 @@
+<template>
+  <TransitionGroup tag="div" name="toast-stack" class="toast-container">
+    <ToastNotification
+      v-for="toast in toasts"
+      :key="toast.id"
+      :message="toast.message"
+      :type="toast.type"
+      :duration="toast.duration"
+      :id="toast.id"
+      @dismiss="removeToast"
+    />
+  </TransitionGroup>
+</template>
+
+<script>
+import ToastNotification from './ToastNotification.vue';
+import {useToasts} from '@/composables/useToast.js'
+
+export default {
+  name: 'ToastContainer',
+  components: { ToastNotification },
+  setup() {
+    const { toasts, removeToast } = useToasts();
+
+    return {
+      toasts,
+      removeToast,
+    };
+  },
+};
+</script>
+
+<style scoped>
+.toast-container {
+  position: fixed;
+  bottom: 1rem;
+  right: 1rem;
+  z-index: 9999;
+}
+
+/* --- Transitions for TransitionGroup --- */
+
+/* 1. Enter/Leave transitions (slide in/out from the right) */
+.toast-stack-enter-active,
+.toast-stack-leave-active {
+  transition: all 0.5s ease;
+}
+.toast-stack-enter-from,
+.toast-stack-leave-to {
+  opacity: 0;
+  transform: translateX(100%);
+}
+
+/* 2. Move transition (the magic for smooth stacking) */
+/* This is applied when items in the list change position */
+.toast-stack-move {
+  transition: transform 0.4s ease-out;
+}
+</style>
Index: ReserveNGo-frontend/src/components/Project/Utility/ToastNotification.vue
===================================================================
--- ReserveNGo-frontend/src/components/Project/Utility/ToastNotification.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
+++ ReserveNGo-frontend/src/components/Project/Utility/ToastNotification.vue	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -0,0 +1,74 @@
+<template>
+  <div :class="['toast-notification', `toast--${type}`]">
+    <span class="toast-message">{{ message }}</span>
+    <div
+      class="toast-timer"
+      :style="{ animationDuration: `${duration}ms` }"
+    ></div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'ToastNotification',
+  props: {
+    message: { type: String, required: true },
+    type: { type: String, default: 'success' },
+    duration: { type: Number, default: 5000 },
+    id: { type: [String, Number], required: true },
+  },
+  emits: ['dismiss'],
+  mounted() {
+    setTimeout(() => {
+      this.$emit('dismiss', this.id);
+    }, this.duration);
+  },
+};
+</script>
+
+<style scoped>
+@keyframes deplete {
+  from {
+    width: 100%;
+  }
+  to {
+    width: 0;
+  }
+}
+
+.toast-notification {
+  width: 320px;
+  margin-bottom: 1rem;
+  padding: 1rem;
+  border-radius: 8px;
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+  display: flex;
+  flex-direction: column;
+  color: white;
+  position: relative;
+  overflow: hidden;
+}
+
+.toast--success {
+  background-color: #28a745;
+}
+.toast--error {
+  background-color: #dc3545;
+}
+
+.toast-message {
+  font-weight: 500;
+}
+
+.toast-timer {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  height: 4px;
+  background-color: rgba(255, 255, 255, 0.4);
+
+  animation-name: deplete;
+  animation-timing-function: linear;
+  animation-fill-mode: forwards;
+}
+</style>
Index: ReserveNGo-frontend/src/composables/useToast.js
===================================================================
--- ReserveNGo-frontend/src/composables/useToast.js	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
+++ ReserveNGo-frontend/src/composables/useToast.js	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -0,0 +1,29 @@
+import { readonly, reactive } from 'vue';
+
+const toasts = reactive([]);
+
+function showToast(message, type = 'success', duration = 5000) {
+  const id = Date.now() + Math.random();
+
+  toasts.push({
+    id,
+    message,
+    type,
+    duration,
+  });
+}
+
+function removeToast(id) {
+  const index = toasts.findIndex(toast => toast.id === id);
+  if (index > -1) {
+    toasts.splice(index, 1);
+  }
+}
+
+export function useToasts() {
+  return {
+    toasts: readonly(toasts),
+    showToast,
+    removeToast,
+  };
+}
Index: ReserveNGo-frontend/src/mixins/utilFunctions.js
===================================================================
--- ReserveNGo-frontend/src/mixins/utilFunctions.js	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/mixins/utilFunctions.js	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -9,8 +9,8 @@
 export function transformArray(arr, howMany, doDateEdit = true) {
 
-
+  const copiedArray = JSON.parse(JSON.stringify(arr));
 
   if (doDateEdit) {
-  arr.forEach(item => {
+  copiedArray.forEach(item => {
     item.eventEnd = transformDate(item.eventEnd)
     item.eventStart = transformDate(item.eventStart)
@@ -20,7 +20,14 @@
   let newArray = []
   for (let i = 0; i<arr.length; i+=howMany) {
-    newArray.push(arr.slice(i, i + howMany))
+    newArray.push(copiedArray.slice(i, i + howMany))
   }
   return newArray;
 
 }
+
+export function isValidEmail(email) {
+  const emailRegex = new RegExp(
+    /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
+  );
+  return emailRegex.test(email);
+}
Index: ReserveNGo-frontend/src/repository/Admin.ts
===================================================================
--- ReserveNGo-frontend/src/repository/Admin.ts	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
+++ ReserveNGo-frontend/src/repository/Admin.ts	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -0,0 +1,45 @@
+import { config } from '@/constants/Api_config'
+import { HttpClient } from '@/Api_Classes/HttpClient'
+
+const BASE_API_URL = config.API_BASE_URL
+
+class Admin {
+  private readonly httpClient: HttpClient
+
+  constructor(baseUrl: string) {
+    this.httpClient = new HttpClient(baseUrl)
+  }
+
+  inviteManager(newEmail: string): Promise<any> {
+    return this.httpClient.post('invite-manager', { newEmail })
+  }
+  addRestaurant(name: string): Promise<any> {
+    return this.httpClient.post('add-local', { name })
+  }
+
+  async deleteRestaurant(localId: number): Promise<any> {
+    return this.httpClient.delete(`delete-local/${localId}`)
+  }
+
+  fetchRestaurants() : Promise<any>  {
+    return this.httpClient.get('locals')
+  }
+
+  fetchLocalMangers(): Promise<any> {
+    return this.httpClient.get('local-managers')
+  }
+
+  fetchManagersForRestaurant(localId: number): Promise<any> {
+    return this.httpClient.get(`local-managers/${localId}`)
+  }
+
+  async assignManager(localId: number, managerId: number): Promise<any> {
+    return this.httpClient.post(`assign/${localId}/${managerId}`)
+  }
+
+  async removeManager(managerId) {
+    return this.httpClient.delete(`remove/${managerId}`)
+  }
+}
+
+export const useAdmin = new Admin(BASE_API_URL + '/api/admin/', )
Index: ReserveNGo-frontend/src/repository/Authentication.ts
===================================================================
--- ReserveNGo-frontend/src/repository/Authentication.ts	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/repository/Authentication.ts	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -22,6 +22,7 @@
     password: String,
     role: String,
+    inviteToken?: String
   ) {
-    return this.httpClient.post("register/" + role, { firstName, lastName, email, phoneNumber, password })
+    return this.httpClient.post("register/" + role, { firstName, lastName, email, phoneNumber, password }, {headers: {'Invite-Token': inviteToken} })
   }
 }
Index: ReserveNGo-frontend/src/repository/LocalManager.ts
===================================================================
--- ReserveNGo-frontend/src/repository/LocalManager.ts	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/repository/LocalManager.ts	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -1,11 +1,6 @@
-import { ApiClient } from '@/Api_Classes/ApiClient'
 import { config } from '@/constants/Api_config'
 import { HttpClient } from '@/Api_Classes/HttpClient'
 
 const BASE_API_URL = config.API_BASE_URL
-
-/*
-console.warn("THIS IS THE BASE URL",BASE_API_URL)
-*/
 
 class LocalManager {
@@ -14,4 +9,28 @@
   constructor(baseUrl: string) {
     this.httpClient = new HttpClient(baseUrl)
+  }
+
+  getMyLocal(): Promise<any> {
+    return this.httpClient.get('my-local');
+  }
+
+  getLocalWorkers(): Promise<any[]> {
+    return this.httpClient.get('local-workers');
+  }
+
+  getAvailableWorkers(): Promise<any[]> {
+    return this.httpClient.get('workers');
+  }
+
+  assignWorker(workerId: string): Promise<any> {
+    return this.httpClient.post(`assign/${workerId}`, {});
+  }
+
+  removeWorker(workerId: string): Promise<any> {
+    return this.httpClient.delete(`remove/${workerId}`);
+  }
+
+  changeWorkerPosition(workerId: string, position: string): Promise<any> {
+    return this.httpClient.put(`change-position/${workerId}`, { position });
   }
 
@@ -23,12 +42,22 @@
   }
   deletePhoto(photoUrls : Object): Promise<any> {
-    /*if (typeof photoUrls === 'string') {photoUrls = [photoUrls] }*/
     return this.httpClient.delete('delete-photos', photoUrls)
   }
-  getLocal(): Promise<any> {
-    return this.httpClient.get('my-local');
+  saveDetailChanges(payload): Promise<any> {
+    return this.httpClient.put('my-local/edit', payload);
   }
-
+  addEvent(formData: FormData): Promise<any> {
+    return this.httpClient.post('add-event', formData)
+  }
+  updateEvent(formData: FormData, eventId): Promise<any> {
+    return this.httpClient.put(`events/edit/${eventId}`, formData)
+  }
+  deleteEvent(eventId): Promise<any> {
+    return this.httpClient.delete(`delete-event/${eventId}`)
+  }
+  inviteWorker(newEmail: string) : Promise<any> {
+    return this.httpClient.post('invite-worker', { newEmail })
+  }
 }
 
-export const useLocalManager = new LocalManager(BASE_API_URL + '/api/local-manager/', )
+export const useLocalManager = new LocalManager(BASE_API_URL + '/api/local-manager/')
Index: ReserveNGo-frontend/src/repository/user.ts
===================================================================
--- ReserveNGo-frontend/src/repository/user.ts	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
+++ ReserveNGo-frontend/src/repository/user.ts	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -0,0 +1,41 @@
+// src/repository/user.ts (or wherever you keep the file)
+import { config } from '@/constants/Api_config'
+import { HttpClient } from '@/Api_Classes/HttpClient'
+
+const BASE_API_URL = config.API_BASE_URL
+
+class UserManager { // Renamed for clarity, but you can keep LocalManager
+  private readonly httpClient: HttpClient
+
+  constructor(baseUrl: string) {
+    this.httpClient = new HttpClient(baseUrl)
+  }
+
+  // --- NEW METHODS BASED ON YOUR COMPONENT'S FETCH CALLS ---
+
+  getProfile(): Promise<any> {
+    return this.httpClient.get('profile');
+  }
+
+  updateProfile(payload: { firstName: string; lastName: string; phoneNumber: string }): Promise<any> {
+    return this.httpClient.put('edit', payload);
+  }
+
+  changeEmail(payload: { newEmail: string }): Promise<any> {
+    return this.httpClient.patch('change-email', payload);
+  }
+
+  changePassword(payload: { currentPassword: string; newPassword: string }): Promise<any> {
+    return this.httpClient.patch('change-password', payload);
+  }
+
+  uploadAvatar(formData: FormData): Promise<any> {
+    return this.httpClient.upload('upload-avatar', formData);
+  }
+
+  deleteAvatar(): Promise<any> {
+    return this.httpClient.delete('delete-avatar');
+  }
+}
+
+export const useUser = new UserManager(BASE_API_URL + '/api/user/')
Index: ReserveNGo-frontend/src/router/index.js
===================================================================
--- ReserveNGo-frontend/src/router/index.js	(revision 423908fe24fd13db9896e83a732ea3c6ad0dad40)
+++ ReserveNGo-frontend/src/router/index.js	(revision 7db50745e8a98b64e3259400052ce3bbaafe7022)
@@ -38,5 +38,5 @@
     },
     {
-      path: '/register',
+      path: '/register/:userType?',
       name: 'register',
       component: register_,
