Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/JobvistaBackendApplication.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/JobvistaBackendApplication.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/JobvistaBackendApplication.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -26,4 +26,5 @@
 			admin.setRole(Role.ROLE_ADMIN);
 			admin.setEmail("admin@admin.com");
+			admin.setHasAccess(true);
 //			admin.setName("admin");
 //			admin.setSurname("admin");
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/config/SecurityConfiguration.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/config/SecurityConfiguration.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/config/SecurityConfiguration.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -32,5 +32,5 @@
                         // TO DO: FIX PERMISSIONS
                         .requestMatchers("/api/job-advertisements/**","/api/job-advertisements/view/**","/api/recruiter/info/**",
-                                "/api/job-advertisements/apply/**","/api/auth/**", "/api/resume/**", "/api/my-applications/**", "/api/applications/{id}/update").permitAll()
+                                "/api/job-advertisements/apply/**","/api/auth/**", "/api/resume/**", "/api/my-applications/**", "/api/applications/{id}/update", "/api/admin/**").permitAll()
                         //.requestMatchers("/api/job-advertisements/**").hasAnyAuthority(Role.ROLE_RECRUITER.name())
                         .anyRequest().authenticated())
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/controllers/AdminController.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/controllers/AdminController.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/controllers/AdminController.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -2,11 +2,30 @@
 
 import lombok.RequiredArgsConstructor;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.DTO.RecruiterDetailsDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.AdminService;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 @RestController
 @RequestMapping("/api/admin")
 @RequiredArgsConstructor
+@CrossOrigin(origins = "*")
 public class AdminController {
 
+    private final AdminService adminService;
+
+    @PostMapping("/change-access/{recruiter_id}")
+    public ResponseEntity<?> changeAccess(@PathVariable("recruiter_id") Long recruiterId, @RequestBody boolean access) {
+        RecruiterDetailsDTO recruiterDetailsDTO = adminService.changeAccess(recruiterId, access);
+        return new ResponseEntity<>(recruiterDetailsDTO, HttpStatus.OK);
+    }
+
+    @GetMapping("/recruiters")
+    public ResponseEntity<?> findAllRecruiters() {
+        List<RecruiterDetailsDTO> recruiterDetailsDTOList = adminService.findAllRecruiters();
+        return new ResponseEntity<>(recruiterDetailsDTOList, HttpStatus.OK);
+    }
 }
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/users/DTO/JwtAuthResponse.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/users/DTO/JwtAuthResponse.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/users/DTO/JwtAuthResponse.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -14,4 +14,5 @@
     private String name;
     private String role;
+    private boolean hasAccess;
     private String token;
     private String refreshToken;
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/users/DTO/RecruiterDetailsDTO.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/users/DTO/RecruiterDetailsDTO.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/users/DTO/RecruiterDetailsDTO.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -5,11 +5,16 @@
 import lombok.NoArgsConstructor;
 
+import java.time.LocalDateTime;
+
 @Data
 @AllArgsConstructor
 @NoArgsConstructor
 public class RecruiterDetailsDTO {
+    private Long id;
     private String email;
     private String companyName;
     private String companyDescription;
     private String phoneNumber;
+    private boolean hasAccess;
+    private LocalDateTime registeredOn;
 }
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/users/User.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/users/User.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/users/User.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -11,4 +11,5 @@
 import org.springframework.security.core.userdetails.UserDetails;
 
+import java.time.LocalDateTime;
 import java.util.Collection;
 import java.util.List;
@@ -32,4 +33,9 @@
     @Enumerated(EnumType.STRING)
     protected Role role;
+
+    @Column(name = "has_access")
+    protected boolean hasAccess;
+
+    protected LocalDateTime registeredOn;
 
 
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/users/mappers/RecruiterMapper.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/users/mappers/RecruiterMapper.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/users/mappers/RecruiterMapper.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -18,8 +18,11 @@
     public static RecruiterDetailsDTO mapToRecruiterDetailsDTO(Recruiter recruiter) {
         return new RecruiterDetailsDTO(
+                recruiter.getId(),
                 recruiter.getEmail(),
                 recruiter.getCompanyName(),
                 recruiter.getCompanyDescription(),
-                recruiter.getPhoneNumber()
+                recruiter.getPhoneNumber(),
+                recruiter.isHasAccess(),
+                recruiter.getRegisteredOn()
         );
     }
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/AdminServiceImpl.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/AdminServiceImpl.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/AdminServiceImpl.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -0,0 +1,38 @@
+package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.impl;
+
+import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.DTO.RecruiterDetailsDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.Recruiter;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.mappers.RecruiterMapper;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.repositories.RecruiterRepository;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.AdminService;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.RecruiterService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@AllArgsConstructor
+public class AdminServiceImpl implements AdminService {
+    private final RecruiterService recruiterService;
+    private final RecruiterRepository recruiterRepository;
+
+    @Override
+    public RecruiterDetailsDTO changeAccess(long recruiterId, boolean access) {
+        Recruiter recruiter = recruiterRepository.findById(recruiterId).orElse(null);
+        if (recruiter != null) {
+            recruiter.setHasAccess(access);
+            recruiterRepository.save(recruiter);
+            return RecruiterMapper.mapToRecruiterDetailsDTO(recruiter);
+        }
+        return null;
+
+    }
+
+    @Override
+    public List<RecruiterDetailsDTO> findAllRecruiters() {
+        List<Recruiter> recruiterList = recruiterRepository.findAll();
+        return recruiterList.stream().map(RecruiterMapper::mapToRecruiterDetailsDTO).toList();
+    }
+}
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/AuthServiceImpl.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/AuthServiceImpl.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/AuthServiceImpl.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -18,4 +18,5 @@
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDateTime;
 import java.util.HashMap;
 
@@ -34,4 +35,6 @@
     public User signUpJobSeeker(JobSeeker jobSeeker) {
         jobSeeker.setPassword(passwordEncoder.encode(jobSeeker.getPassword()));
+        jobSeeker.setHasAccess(true);
+        jobSeeker.setRegisteredOn(LocalDateTime.now());
         return jobSeekerRepository.save(jobSeeker);
     }
@@ -39,4 +42,6 @@
     public User signUpRecruiter(Recruiter recruiter) {
         recruiter.setPassword(passwordEncoder.encode(recruiter.getPassword()));
+        recruiter.setHasAccess(false);
+        recruiter.setRegisteredOn(LocalDateTime.now());
         return recruiterRepository.save(recruiter);
     }
@@ -49,5 +54,5 @@
         String refreshJwt = jwtService.generateRefreshToken(new HashMap<>(), user);
 
-        return new JwtAuthResponse(user.getId(), user.getEmail(), user.getName(), user.getRole().name(), jwt, refreshJwt);
+        return new JwtAuthResponse(user.getId(), user.getEmail(), user.getName(), user.getRole().name(), user.isHasAccess(), jwt, refreshJwt);
     }
     
@@ -58,5 +63,5 @@
             String jwt = jwtService.generateToken(user);
 
-            return new JwtAuthResponse(user.getId(), user.getEmail(), user.getName(), user.getRole().name(), jwt, refreshTokenRequest.getToken());
+            return new JwtAuthResponse(user.getId(), user.getEmail(), user.getName(), user.getRole().name(), user.isHasAccess(), jwt, refreshTokenRequest.getToken());
         }
         return null;
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/JwtServiceImpl.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/JwtServiceImpl.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/JwtServiceImpl.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -6,4 +6,5 @@
 import io.jsonwebtoken.io.Decoders;
 import io.jsonwebtoken.security.Keys;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.User;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.JwtService;
 import org.springframework.security.core.userdetails.UserDetails;
@@ -19,6 +20,9 @@
     private final static String SECRET_KEY = "7191b1d33668d4a2316a02f9a40798b77bccd22173bd882c93a0a916a5e921d1";
 
-    public String generateToken(UserDetails userDetails) {
-        return Jwts.builder().setSubject(userDetails.getUsername())
+    public String generateToken(User user) {
+        return Jwts.builder().setSubject(user.getUsername())
+                .claim("name", user.getName())
+                .claim("role", user.getRole())
+                .claim("access", user.isHasAccess())
                 .setIssuedAt(new Date())
                 .setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24))
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/AdminService.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/AdminService.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/AdminService.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -0,0 +1,10 @@
+package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef;
+
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.DTO.RecruiterDetailsDTO;
+
+import java.util.List;
+
+public interface AdminService {
+    RecruiterDetailsDTO changeAccess(long recruiterId, boolean access);
+    List<RecruiterDetailsDTO> findAllRecruiters();
+}
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/JwtService.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/JwtService.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/JwtService.java	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -1,4 +1,5 @@
 package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef;
 
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.User;
 import org.springframework.security.core.userdetails.UserDetails;
 
@@ -6,5 +7,5 @@
 
 public interface JwtService {
-    String generateToken(UserDetails userDetails);
+    String generateToken(User user);
     String generateRefreshToken(Map<String, Object> extraClaims, UserDetails userDetails);
     String extractUsername(String token);
Index: jobvista-frontend/package-lock.json
===================================================================
--- jobvista-frontend/package-lock.json	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-frontend/package-lock.json	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -19,4 +19,5 @@
         "axios": "^1.6.8",
         "formik": "^2.4.6",
+        "jwt-decode": "^4.0.0",
         "primereact": "^10.6.6",
         "quill": "^2.0.2",
@@ -12963,4 +12964,12 @@
       }
     },
+    "node_modules/jwt-decode": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz",
+      "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==",
+      "engines": {
+        "node": ">=18"
+      }
+    },
     "node_modules/keyv": {
       "version": "4.5.4",
Index: jobvista-frontend/package.json
===================================================================
--- jobvista-frontend/package.json	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-frontend/package.json	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -14,4 +14,5 @@
     "axios": "^1.6.8",
     "formik": "^2.4.6",
+    "jwt-decode": "^4.0.0",
     "primereact": "^10.6.6",
     "quill": "^2.0.2",
Index: jobvista-frontend/src/App.js
===================================================================
--- jobvista-frontend/src/App.js	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-frontend/src/App.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -1,11 +1,13 @@
 import logo from './logo.svg';
 import './App.css';
-import {useDispatch} from "react-redux";
+import {useDispatch, useSelector} from "react-redux";
 import {BrowserRouter} from "react-router-dom";
 import {Header} from "./views/static/Header";
 import {RoutesConfig} from "./auth/RoutesConfig";
-import {useEffect} from "react";
+import {useEffect, useState} from "react";
 import {AuthActions} from "./redux/actions/authActions";
 import {AUTH_TOKEN} from "./axios/axiosInstance";
+import {jwtDecode} from "jwt-decode";
+import {NoAccess} from "./views/static/NoAccess";
 
 function App() {
@@ -16,9 +18,50 @@
     }, [dispatch])
 
+    const [user, setUser] = useState(null);
+    const [loading, setLoading] = useState(true);
+    const auth = useSelector(state => state.auth);
+
+    useEffect(() => {
+        const token = localStorage.getItem(AUTH_TOKEN);
+        if (token !== null) {
+            try {
+                const decodedToken = jwtDecode(token);
+                setUser({
+                    name: decodedToken.name,
+                    role: decodedToken.role,
+                    hasAccess: auth.currentUser.access,
+                });
+                setLoading(false);
+            } catch (error) {
+                console.error('Failed to decode token', error);
+                setLoading(false);
+            }
+        } else {
+            setLoading(false);
+        }
+    }, [auth]);
+
+    if (loading) {
+        return <NoAccess />; // Replace LoadingSpinner with your loading indicator component
+    }
+
   return (
       <div className="App">
           <BrowserRouter>
-              <Header/>
-              <RoutesConfig/>
+              {user === null ? (
+                  <>
+                      <Header />
+                      <RoutesConfig />
+                  </>
+              ) : user.hasAccess ? (
+                  <>
+                      <Header />
+                      <RoutesConfig />
+                  </>
+              ) : (
+                  <NoAccess user={user}/>
+              )}
+
+
           </BrowserRouter>
       </div>
Index: jobvista-frontend/src/auth/RoutesConfig.js
===================================================================
--- jobvista-frontend/src/auth/RoutesConfig.js	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-frontend/src/auth/RoutesConfig.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -9,4 +9,9 @@
 import {ApplicationsByJobAd} from "../views/applications/ApplicationsByJobAd";
 import {ApplicationsByJobSeeker} from "../views/applications/ApplicationsByJobSeeker";
+import {useEffect, useState} from "react";
+import {AUTH_TOKEN} from "../axios/axiosInstance";
+import {jwtDecode} from "jwt-decode";
+import {useSelector} from "react-redux";
+import {AdminPanel} from "../views/admin_panel/AdminPanel";
 export const RoutesConfig = () => {
 
@@ -21,4 +26,5 @@
                 <Route path="/job-advertisements/:id" element={<JobAdDetails/>}></Route>
                 <Route path="/my-job-advertisements/:advertisement_id/applications" element={<ApplicationsByJobAd/>}></Route>
+                <Route path="/admin-panel" element={<AdminPanel/>}></Route>
             </Routes>
     )
Index: jobvista-frontend/src/redux/actionTypes.js
===================================================================
--- jobvista-frontend/src/redux/actionTypes.js	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-frontend/src/redux/actionTypes.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -18,3 +18,6 @@
 export const DOWNLOAD_RESUME = "DOWNLOAD_RESUME"
 
+export const FETCH_RECRUITERS = "FETCH_RECRUITERS"
+export const CHANGE_ACCESS = "CHANGE_ACCESS"
 
+
Index: jobvista-frontend/src/redux/actions/adminActions.js
===================================================================
--- jobvista-frontend/src/redux/actions/adminActions.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
+++ jobvista-frontend/src/redux/actions/adminActions.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -0,0 +1,36 @@
+import axios from "../../axios/axiosInstance";
+import {CHANGE_ACCESS, FETCH_RECRUITERS} from "../actionTypes";
+
+export const AdminActions = {
+    fetchRecruiters: (callback) => {
+        return dispatch => {
+            axios.get("/admin/recruiters")
+                .then(response => {
+                dispatch({
+                    type: FETCH_RECRUITERS,
+                    recruiters: response.data
+                })
+                callback(true, response)
+            }).catch((error) => {
+                callback(false, error)
+            })
+        }
+    },
+    changeAccess: (recruiterId, access, callback) => {
+        return dispatch => {
+            axios.post("/admin/change-access/" + recruiterId, access, {
+                headers: {
+                    'Content-Type': 'application/json'
+                }
+            }).then(response => {
+                dispatch({
+                    type: CHANGE_ACCESS,
+                    recruiter: response.data
+                })
+                callback(true, response)
+            }).catch((error) => {
+                callback(false, error)
+            })
+        }
+    }
+}
Index: jobvista-frontend/src/redux/actions/authActions.js
===================================================================
--- jobvista-frontend/src/redux/actions/authActions.js	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-frontend/src/redux/actions/authActions.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -48,5 +48,6 @@
                     email: response.email,
                     name: response.name,
-                    role: response.role
+                    role: response.role,
+                    access: response.hasAccess,
                 };
                 dispatch({
Index: jobvista-frontend/src/redux/reducers/adminReducer.js
===================================================================
--- jobvista-frontend/src/redux/reducers/adminReducer.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
+++ jobvista-frontend/src/redux/reducers/adminReducer.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -0,0 +1,31 @@
+import {CHANGE_ACCESS, FETCH_RECRUITERS} from "../actionTypes";
+import {sortElementsBy} from "../../utils/utils";
+
+const initialState = {
+    recruiters: [],
+}
+
+const AdminReducer = (state = initialState, action) => {
+    switch (action.type) {
+        case FETCH_RECRUITERS:
+            return {
+                ...state,
+                recruiters: sortElementsBy(action.recruiters, "registeredOn")
+            }
+        case CHANGE_ACCESS:
+            return {
+                ...state,
+                recruiters: state.recruiters.map(recruiter =>
+                recruiter.id === action.recruiter.id ?
+                    {...recruiter, hasAccess: action.recruiter.hasAccess} :
+                    recruiter
+                )
+            }
+        default:
+            return {
+                ...state,
+            };
+    }
+}
+
+export default AdminReducer
Index: jobvista-frontend/src/redux/reducers/jobAdvertisementReducer.js
===================================================================
--- jobvista-frontend/src/redux/reducers/jobAdvertisementReducer.js	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-frontend/src/redux/reducers/jobAdvertisementReducer.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -5,5 +5,5 @@
     FETCH_JOB_ADVERTISEMENTS_BY_RECRUITER, FILTER_JOB_ADVERTISEMENTS, FILTER_JOB_ADVERTISEMENTS_BY_RECRUITER
 } from "../actionTypes";
-import {sortElementsByDateCreated} from "../../utils/utils";
+import {sortElementsBy} from "../../utils/utils";
 import {useSelector} from "react-redux";
 
@@ -22,6 +22,6 @@
             return {
                 ...state,
-                jobAdvertisements: sortElementsByDateCreated([...state.jobAdvertisements, action.jobAdvertisement]),
-                jobAdvertisementsByRecruiter: sortElementsByDateCreated([...state.jobAdvertisementsByRecruiter, action.jobAdvertisement])
+                jobAdvertisements: sortElementsBy([...state.jobAdvertisements, action.jobAdvertisement]),
+                jobAdvertisementsByRecruiter: sortElementsBy([...state.jobAdvertisementsByRecruiter, action.jobAdvertisement], "postedOn")
             }
         case EDIT_JOB_ADVERTISEMENT:
@@ -30,6 +30,6 @@
 
             return {
-                jobAdvertisements: sortElementsByDateCreated([...jobAdvertisements, action.jobAdvertisement]),
-                jobAdvertisementsByRecruiter: sortElementsByDateCreated([...jobAdvertisementsByRecruiter, action.jobAdvertisement])
+                jobAdvertisements: sortElementsBy([...jobAdvertisements, action.jobAdvertisement], "postedOn"),
+                jobAdvertisementsByRecruiter: sortElementsBy([...jobAdvertisementsByRecruiter, action.jobAdvertisement], "postedOn")
             }
         case DELETE_JOB_ADVERTISEMENT:
@@ -38,6 +38,6 @@
 
             return {
-                jobAdvertisements: sortElementsByDateCreated([...jobAdvertisements]),
-                jobAdvertisementsByRecruiter: sortElementsByDateCreated([...jobAdvertisementsByRecruiter])
+                jobAdvertisements: sortElementsBy([...jobAdvertisements], "postedOn"),
+                jobAdvertisementsByRecruiter: sortElementsBy([...jobAdvertisementsByRecruiter], "postedOn")
             }
 
@@ -45,5 +45,5 @@
             return {
                 ...state,
-                jobAdvertisements: sortElementsByDateCreated(action.jobAdvertisements)
+                jobAdvertisements: sortElementsBy(action.jobAdvertisements, "postedOn")
             }
 
@@ -52,5 +52,5 @@
             return {
                 ...state,
-                jobAdvertisementsByRecruiter: sortElementsByDateCreated(action.jobAdvertisementsByRecruiter)
+                jobAdvertisementsByRecruiter: sortElementsBy(action.jobAdvertisementsByRecruiter, "postedOn")
             }
 
Index: jobvista-frontend/src/redux/store.js
===================================================================
--- jobvista-frontend/src/redux/store.js	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-frontend/src/redux/store.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -4,4 +4,6 @@
 import jobAdReducer from "./reducers/jobAdvertisementReducer";
 import applicationReducer from "./reducers/applicationReducer"
+import adminReducer from "./reducers/adminReducer"
+import {AdminActions} from "./actions/adminActions";
 
 // const rootReducer = combineReducers({
@@ -18,5 +20,6 @@
         auth: authReducer,
         jobAd: jobAdReducer,
-        appl: applicationReducer
+        appl: applicationReducer,
+        admin: adminReducer
     },
 });
Index: jobvista-frontend/src/utils/utils.js
===================================================================
--- jobvista-frontend/src/utils/utils.js	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-frontend/src/utils/utils.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -1,7 +1,7 @@
 
 
-export const sortElementsByDateCreated = (array) => {
+export const sortElementsBy = (array, column) => {
     return array.slice().sort((a, b) => {
-        return new Date(b.postedOn).getTime() - new Date(a.postedOn).getTime()
+        return new Date(b[column]).getTime() - new Date(a[column]).getTime()
     });
 }
@@ -9,5 +9,5 @@
 export const sortElementsBySubmissionDate = (array) => {
     return array.slice().sort((a, b) => {
-        return new Date(b.postedOn).getTime() - new Date(a.postedOn).getTime()
+        return new Date(b).getTime() - new Date(a.postedOn).getTime()
     });
 }
Index: jobvista-frontend/src/views/admin_panel/AdminPanel.css
===================================================================
--- jobvista-frontend/src/views/admin_panel/AdminPanel.css	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
+++ jobvista-frontend/src/views/admin_panel/AdminPanel.css	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -0,0 +1,54 @@
+.table {
+
+}
+
+/* The switch - the box around the slider */
+.switch {
+    font-size: 12px;
+    position: relative;
+    display: inline-block;
+    width: 3.5em;
+    height: 2em;
+}
+
+/* Hide default HTML checkbox */
+.switch input {
+    opacity: 0;
+    width: 0;
+    height: 0;
+}
+.slider {
+    position: absolute;
+    cursor: pointer;
+    inset: 0;
+    background: #DB5A57;
+    border-radius: 50px;
+    transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+}
+
+.slider:before {
+    position: absolute;
+    content: "";
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: 2em;
+    width: 2em;
+    inset: 0;
+    background-color: white;
+    border-radius: 50px;
+    box-shadow: 0 10px 20px rgba(0,0,0,0.3);
+    transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+}
+
+.switch input:checked + .slider {
+    background: #3DDC69;
+}
+
+.switch input:focus + .slider {
+    box-shadow: 0 0 1px #3DDC69;
+}
+
+.switch input:checked + .slider:before {
+    transform: translateX(1.6em);
+}
Index: jobvista-frontend/src/views/admin_panel/AdminPanel.js
===================================================================
--- jobvista-frontend/src/views/admin_panel/AdminPanel.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
+++ jobvista-frontend/src/views/admin_panel/AdminPanel.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -0,0 +1,91 @@
+import "./AdminPanel.css"
+
+import {useDispatch, useSelector} from "react-redux";
+import {useState, useEffect} from "react";
+import {AdminActions} from "../../redux/actions/adminActions";
+
+export const AdminPanel = () => {
+
+    const dispatch = useDispatch();
+    const [recruiters, setRecruiters] = useState([]);
+    let recruitersState = useSelector(state => state.admin.recruiters)
+    const [dispatched, setDispatched] = useState(false)
+
+    useEffect(() => {
+        if(!dispatched && recruitersState.length == 0) {
+            dispatch(AdminActions.fetchRecruiters((success, response) => {
+                if(success && response.data.length > 0) {
+                    setRecruiters(response.data)
+                }
+                setDispatched(true)
+                console.log("Fetch all recruiters GET")
+            }))
+        } else {
+            setRecruiters(recruitersState)
+            console.log("Fetch all recruiters STATE")
+        }
+    }, [recruitersState])
+
+    const formatDate = (dateString) => {
+        const options = { year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit' };
+        return new Date(dateString).toLocaleDateString('en-US', options);
+    };
+
+    const handleAccessChange = (recruiterId, newAccessStatus) => {
+        setRecruiters(prevState =>
+            prevState.map(recruiter =>
+                recruiter.id === recruiterId
+                    ? { ...recruiter, hasAccess: newAccessStatus }
+                    : recruiter
+            )
+        );
+
+        console.log(recruiterId + " " + newAccessStatus)
+
+        dispatch(AdminActions.changeAccess(recruiterId, newAccessStatus, (success, response) => {
+            if(success) {
+                console.log("Access changed")
+            }
+        }));
+    };
+
+    return (
+        <div className="applications-container mt-5">
+            <table className="table table-striped">
+                <thead>
+                <tr>
+                    <th scope="col">ID</th>
+                    <th scope="col">Registered on</th>
+                    <th scope="col">Email</th>
+                    <th scope="col">Company Name</th>
+                    <th scope="col">Phone Number</th>
+                    <th scope="col">Access</th>
+                </tr>
+                </thead>
+                <tbody>
+                {recruiters.map((recruiter) => (
+                    <tr key={recruiter.id}>
+                        <th scope="row">{recruiter.id}</th>
+                        <td>{formatDate(recruiter.registeredOn)}</td>
+                        <td>{recruiter.email}</td>
+                        <td>{recruiter.companyName}</td>
+                        <td>{recruiter.phoneNumber}</td>
+                        <td>
+                            <label className="switch">
+                                <input
+                                    type="checkbox"
+                                    checked={recruiter.hasAccess}
+                                    onChange={(e) => handleAccessChange(recruiter.id, e.target.checked)}
+                                />
+                                <span className="slider"></span>
+                            </label>
+                        </td>
+
+
+                    </tr>
+                ))}
+                </tbody>
+            </table>
+        </div>
+    )
+}
Index: jobvista-frontend/src/views/dashboard/Dashboard.js
===================================================================
--- jobvista-frontend/src/views/dashboard/Dashboard.js	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-frontend/src/views/dashboard/Dashboard.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -4,5 +4,5 @@
 import {useEffect, useState} from "react";
 import {JobAdvertisementActions} from "../../redux/actions/jobAdvertisementActions";
-import {formatRelativeTime, sortElementsByDateCreated} from "../../utils/utils";
+import {formatRelativeTime, sortElementsBy} from "../../utils/utils";
 import {dataRangeOptions, industryOptions, industryOptionsFilter, sortOptions} from "../selectOptions";
 import Select from "react-select";
@@ -10,6 +10,8 @@
 import {Link} from "react-router-dom";
 import JobType from "../../enumerations/JobType";
+import {AUTH_TOKEN} from "../../axios/axiosInstance";
+import {jwtDecode} from "jwt-decode";
 
-export const Dashboard = () => {
+export const Dashboard = (props) => {
 
     const dispatch = useDispatch();
@@ -17,7 +19,7 @@
     const [jobAdvertisements, setJobAdvertisements] = useState([]);
     let jobAdvertisementsState = useSelector(state => state.jobAd.jobAdvertisements)
-    const auth = useSelector(state => state.auth.currentUser);
+    const auth = useSelector(state => state.auth);
 
-    const [role, setRole] = useState("");
+    // const [role, setRole] = useState("");
     const [selectedSortOrder, setSelectedSortOrder] = useState("date_newest");
     const [selectedIndustry, setSelectedIndustry] = useState("all");
@@ -25,9 +27,29 @@
     const [dispatched, setDispatched] = useState(false)
 
-    useEffect(() => {
-        if (auth) {
-            setRole(auth.role);
-        }
-    }, [auth]);
+    // const [user, setUser] = useState(null);
+    //
+    // useEffect(() => {
+    //     const token = localStorage.getItem(AUTH_TOKEN);
+    //     if (token!=null) {
+    //         try {
+    //             const decodedToken = jwtDecode(token);
+    //             setUser({
+    //                 name: decodedToken.name,
+    //                 role: decodedToken.role,
+    //                 hasAccess: decodedToken.access,
+    //             });
+    //         } catch (error) {
+    //             console.error('Failed to decode token', error);
+    //         }
+    //     }
+    //     console.log(user)
+    // }, [auth]);
+
+    // useEffect(() => {
+    //     if (auth) {
+    //         setRole(auth.role);
+    //     }
+    //     console.log(props)
+    // }, [auth]);
 
     useEffect(() => {
@@ -35,5 +57,5 @@
             dispatch(JobAdvertisementActions.fetchJobAdvertisements((success, response) => {
                 if (success && response.data.length > 0) {
-                    setJobAdvertisements(sortElementsByDateCreated(response.data))
+                    setJobAdvertisements(sortElementsBy(response.data))
                 }
                 setDispatched(true)
@@ -62,4 +84,5 @@
 
     return (
+
         <div className="container">
             <div className="head-dashboard-box">
Index: jobvista-frontend/src/views/job_advertisements/JobAdvertisements.js
===================================================================
--- jobvista-frontend/src/views/job_advertisements/JobAdvertisements.js	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-frontend/src/views/job_advertisements/JobAdvertisements.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -5,5 +5,5 @@
 import {useEffect, useState} from "react";
 import {JobAdvertisementActions} from "../../redux/actions/jobAdvertisementActions";
-import {formatRelativeTime, sortElementsByDateCreated} from "../../utils/utils";
+import {formatRelativeTime, sortElementsBy} from "../../utils/utils";
 import {dataRangeOptions, industryOptions, industryOptionsFilter, sortOptions} from "../selectOptions";
 import Select from "react-select";
@@ -37,5 +37,5 @@
             dispatch(JobAdvertisementActions.fetchJobAdvertisementsByRecruiter((success, response) => {
                 if (success && response.data.length > 0) {
-                    setJobAdvertisementsByRecruiter(sortElementsByDateCreated(response.data))
+                    setJobAdvertisementsByRecruiter(sortElementsBy(response.data))
                 }
                 console.log("Fetch job advertisements by recruiter GET")
Index: jobvista-frontend/src/views/static/ErrorPage.js
===================================================================
--- jobvista-frontend/src/views/static/ErrorPage.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
+++ jobvista-frontend/src/views/static/ErrorPage.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -0,0 +1,17 @@
+import "./NoAccess.css"
+export const ErrorPage = () => {
+    return (
+        <div className="d-flex align-items-center justify-content-center vh-100 landing-page">
+            <div className="text-center">
+                <h1 className="display-1 fw-bold">404</h1>
+                <p className="fs-3"><span className="text-danger">Opps!</span> Page not found.</p>
+                <p className="lead">
+                    The page you’re looking for is not available or doesn’t exist.
+                </p>
+                {/*{user && <Link to="/dashboard" className="go-back-btn">Go back</Link>}*/}
+                {/*{!user && <Link to="/" className="go-back-btn">Go back</Link>}*/}
+
+            </div>
+        </div>
+    )
+}
Index: jobvista-frontend/src/views/static/Header.js
===================================================================
--- jobvista-frontend/src/views/static/Header.js	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-frontend/src/views/static/Header.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -1,4 +1,5 @@
 import {Link, NavLink} from "react-router-dom";
 import "./Header.css"
+import { jwtDecode } from "jwt-decode";
 import {useDispatch, useSelector} from 'react-redux';
 import {useEffect, useState} from "react";
@@ -6,4 +7,5 @@
 import Roles from "../../enumerations/Roles";
 import {useNavigate} from "react-router";
+import {AUTH_TOKEN} from "../../axios/axiosInstance";
 
 export const Header = (props) => {
@@ -16,8 +18,26 @@
     const [username, setUsername] = useState("");
 
+    const [user, setUser] = useState("");
+
     const signOut = () => {
         dispatch(AuthActions.signOut());
         window.location = "/";
     }
+
+    useEffect(() => {
+        const token = localStorage.getItem(AUTH_TOKEN);
+        if (token!=null) {
+            try {
+                const decodedToken = jwtDecode(token);
+                setUser({
+                    name: decodedToken.name,
+                    role: decodedToken.role,
+                    hasAccess: decodedToken.hasAccess,
+                });
+            } catch (error) {
+                console.error('Failed to decode token', error);
+            }
+        }
+    }, [auth]);
 
     useEffect(() => {
@@ -49,4 +69,10 @@
                             </>
                         }
+                        {role===Roles.ADMIN &&
+                            <>
+                                <NavLink to="/admin-panel" className="nav-item nav-link">Admin Panel</NavLink>
+                            </>
+
+                        }
                         <NavLink to="/about" className="nav-item nav-link">About</NavLink>
                         <NavLink to="/contact" className="nav-item nav-link">Support</NavLink>
@@ -57,6 +83,9 @@
                             <img src="/images/user.png" width="45" height="45"/>
                             <div className="auth-box">
-                                <p className="user"><b>{username}</b></p>
-                                <p className="role">{role==Roles.RECRUITER ? "Recruiter" : "Job Seeker"}</p>
+                                <p className="user"><b>{user.name}</b></p>
+                                {user.role==Roles.RECRUITER && <p className="role">Recruiter</p>}
+                                {user.role==Roles.JOBSEEKER && <p className="role">Job Seeker</p>}
+                                {user.role==Roles.ADMIN && <p className="role">Admin</p>}
+                                {/*<p className="role">{user.role==Roles.RECRUITER ? "Recruiter" : "Job Seeker"}</p>*/}
                             </div>
 
Index: jobvista-frontend/src/views/static/NoAccess.css
===================================================================
--- jobvista-frontend/src/views/static/NoAccess.css	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
+++ jobvista-frontend/src/views/static/NoAccess.css	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -0,0 +1,38 @@
+
+.landing-page {
+    background-color: #031c30;
+    background-image: url("https://www.gstatic.com/mobilesdk/190424_mobilesdk/nav_nachos@2x.png");
+    background-position: bottom 0;
+    background-size: 250vh 170vh;
+    background-repeat: no-repeat;
+    /*background-image: url("/public/wallet-images/proba3.jpg");*/
+    /*background-size: cover;*/
+    /*background-image: url("../../public/logo.png");*/
+    /*background-repeat: no-repeat;*/
+    /*background-position: center;*/
+    /*background-size: 25%;*/
+    width: 100%;
+    height: 100vh;
+    z-index: 9999;
+    position: fixed;
+}
+
+.text-center {
+    color: white;
+    transform: scale(1.5);
+}
+
+.go-back-btn {
+    text-decoration: none;
+    background-color: white;
+    border-radius: 12px;
+    padding: 5px 15px;
+    color: #C41E3A;
+    font-weight: bold;
+    border: none;
+    transition: 0.3s;
+}
+
+.go-back-btn:hover {
+    opacity: 0.6;
+}
Index: jobvista-frontend/src/views/static/NoAccess.js
===================================================================
--- jobvista-frontend/src/views/static/NoAccess.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
+++ jobvista-frontend/src/views/static/NoAccess.js	(revision b2488107b82c95e4bdfdfd18b76b44f023786601)
@@ -0,0 +1,28 @@
+import "./NoAccess.css"
+import {Link, NavLink} from "react-router-dom";
+import {AuthActions} from "../../redux/actions/authActions";
+import {useDispatch} from "react-redux";
+
+
+export const NoAccess = (props) => {
+
+    const dispatch = useDispatch();
+    const signOut = () => {
+        dispatch(AuthActions.signOut());
+        window.location = "/";
+    }
+
+    return (
+        <div className="d-flex align-items-center justify-content-center vh-100 landing-page">
+            <div className="text-center">
+                <p className="fs-3 fw-bold text-uppercase">Thank you for registering!</p>
+                <p className="lead">
+                    Your application has been received and is pending review. We will contact you soon for further authentication. <br/> Please check your email for updates.
+                </p>
+                {props.user && <button onClick={signOut} className="go-back-btn">Log out</button>}
+
+
+            </div>
+        </div>
+    )
+}
