diff --git a/public/css/styles.css b/public/css/styles.css
index 4259dfe96c46c1adc272a44aac7b596191dc64ba..7f44689ac04710bfd68c91096225d08c97c6664d 100644
--- a/public/css/styles.css
+++ b/public/css/styles.css
@@ -197,6 +197,97 @@ textarea {
   text-decoration: none;
 }
 
+.overlay {
+  /* Position the overlay to cover the entire viewport */
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  /* Add background image or color for the overlay */
+  background: rgba(0, 0, 0, 0.5); /* Semi-transparent black overlay */
+  backdrop-filter: blur(5px); /* Apply a blur effect to the background */
+  display: flex;
+  justify-content: center; /* Center content horizontally */
+  align-items: center; /* Center content vertically */
+}
+
+.overlay .form {
+  position: fixed;
+  top: 0;
+  left: 0;
+}
+
+.popup {
+  display: flex;
+  flex-direction: column;
+  background: white;
+  padding: 30px 40px 30px 40px;
+  width: 30%;
+  border-radius: 8px;
+  background: var(--neutral-grey-dark, #21252C);
+  margin-top: 5%;
+  margin-bottom: 5%;
+}
+
+.popup p {
+  color: var(--neutral-grey-light, #BABDC3);
+  font-style: normal;
+  font-weight: 400;
+  text-align: center;
+}
+
+.popup div {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  gap: 30px;
+}
+
+.button-delete {
+  border:none;
+  border-radius: 8px;
+  background: #eb5050;
+  color: white;
+  width: 100%;
+  padding-top: 10px;
+  padding-bottom: 10px;
+  transition: all 0.5s;
+  cursor: pointer;
+  font-weight: bold;
+  margin-top: 20px;
+  margin-bottom: 20px;
+  align-self: stretch;
+}
+
+.button-delete:hover {background-color: #ff9898}
+
+.button-delete:active {
+  background-color: #b63131;
+}
+
+.button-cancel {
+  border:none;
+  border-radius: 8px;
+  background: var(--primary-base, #5360DC);
+  color: white;
+  width: 100%;
+  padding-top: 10px;
+  padding-bottom: 10px;
+  transition: all 0.5s;
+  cursor: pointer;
+  font-weight: bold;
+  margin-top: 20px;
+  margin-bottom: 20px;
+  align-self: stretch;
+}
+
+.button-cancel:hover {background-color: #7580e3}
+
+.button-cancel:active {
+  background-color: #313c9f;
+}
+
 @media only screen and (max-width: 800px) {
   .form-container {
     width: 100%;
diff --git a/src/App.php b/src/App.php
index 4967f24232620d06799e260999f890b7fd9d87e8..dc25c013d8dcfd306eb7b1f60a8491608ba1367a 100644
--- a/src/App.php
+++ b/src/App.php
@@ -12,6 +12,7 @@ use app\controllers\ProfileController;
 use app\controllers\ReviewController;
 use app\controllers\RegisterController;
 use app\controllers\UpdateFilmController;
+use app\controllers\UserDashboardController;
 use app\repositories\UserRepository;
 use app\repositories\ReviewRepository;
 use app\services\UserService;
@@ -41,5 +42,6 @@ class App
     $this->router->addRoute('/add-film', CreateFilmController::class);
     $this->router->addRoute('/update-film', UpdateFilmController::class);
     $this->router->addRoute('/profile', ProfileController::class);
+    $this->router->addRoute('/user-dashboard', UserDashboardController::class);
   }
 }
diff --git a/src/base/BaseRepository.php b/src/base/BaseRepository.php
index 9b38df918b0939e2f420d31139d5d874f0200bfb..88b5930e65a2bf08099207e1d1760aa41717ff95 100644
--- a/src/base/BaseRepository.php
+++ b/src/base/BaseRepository.php
@@ -242,7 +242,8 @@ abstract class BaseRepository
     $sql .= "$primaryKey = :primaryKey";
 
     $stmt = $this->pdo->prepare($sql);
-    $stmt->bindValue(":primaryKey", $model->get('$primaryKey'), PDO::PARAM_INT);
+    $stmt->bindValue(":primaryKey", $model->get($primaryKey), PDO::PARAM_INT);
+
 
     $stmt->execute();
     return $stmt->rowCount();
diff --git a/src/controllers/ProfileController.php b/src/controllers/ProfileController.php
index fc9f2daff2c8a7fc1e2ac74d5372934161fc1a55..aa4e92abb1c41d38944267e24f47a408e6a06ded 100644
--- a/src/controllers/ProfileController.php
+++ b/src/controllers/ProfileController.php
@@ -57,11 +57,12 @@ class ProfileController extends BaseController
 
       // Call service
       $response = $this->service->update($user);
-      echo $response;
       $msg = "";
 
-      $_SESSION['username'] = $username;
-      $msg = "Successfully updated profile!";
+      if ($response != null) {
+        $_SESSION['username'] = $username;
+        $msg = "Successfully updated profile!";
+      }
 
       // Render response
       parent::redirect("/", ["Msg" => $msg]);
diff --git a/src/controllers/UserDashboardController.php b/src/controllers/UserDashboardController.php
new file mode 100644
index 0000000000000000000000000000000000000000..0e15cea28304fbc1369be961d94a637629481d05
--- /dev/null
+++ b/src/controllers/UserDashboardController.php
@@ -0,0 +1,142 @@
+<?php
+
+namespace app\controllers;
+
+use app\base\BaseController;
+use app\exceptions\BadRequestException;
+use app\services\UserService;
+use Exception;
+
+class UserDashboardController extends BaseController
+{
+  public function __construct()
+  {
+    parent::__construct(UserService::getInstance());
+  }
+
+  protected function get($urlParams)
+  {
+    if (!isset($_SESSION['role']) or $_SESSION['role'] != 'admin') {
+      // TODO: make error controller
+      parent::redirect("/error", [], 401);
+      return;
+    }
+    $urlParams['users'] = $this->service->getAllUser();
+    if (isset($urlParams['context']) and $urlParams['context'] == 'update') {
+      $user = $this->service->getById($urlParams['user_id']);
+      if ($urlParams['action'] == 'edit') {
+        $urlParams['email'] = $user->email;
+        $urlParams['username'] = $user->username;
+        parent::render($urlParams, "update-user", "layouts/base");
+      }
+      if ($urlParams['action'] == 'delete') {
+        $urlParams['username'] = $user->username;
+        parent::render($urlParams, "delete-user", "layouts/base");
+      }
+      unset($urlParams['context']);
+    } else {
+
+      parent::render($urlParams, "user-dashboard", "layouts/base");
+    }
+  }
+
+  protected function post($urlParams)
+  {
+    if (!isset($_SESSION['role']) or $_SESSION['role'] != 'admin') {
+      parent::redirect("/error", [], 401);
+      return;
+    }
+    if (isset($urlParams['context']) and $urlParams['context'] == 'update') {
+      if ($urlParams['action'] == 'edit') {
+        try {
+          $user = $this->service->getById($urlParams['user_id']);
+          $old_pass = $user->password;
+
+          // Get data
+          $email = $_POST['email'];
+          $username = $_POST['username'];
+          $password = $_POST['password'] ? $_POST['password'] : $old_pass;
+          $confirm_password = $_POST['confirm-password'] ? $_POST['confirm-password'] : $old_pass;
+
+          if ($this->service->isEmailExist($email) and $user->email != $email) {
+            throw new BadRequestException("Email Already Exists!");
+          }
+
+          if ($this->service->isUsernameExist($username) and $user->username != $username) {
+            throw new BadRequestException("Username Already Exists!");
+          }
+
+          if ($password != $confirm_password) {
+            throw new BadRequestException("Password does not match!");
+          }
+
+          $user
+            ->set('email', $email)
+            ->set('username', $username)
+            ->set('password', $_POST['password'] ? password_hash($password, PASSWORD_DEFAULT) : $password);
+
+          // Call service
+          $response = $this->service->update($user);
+
+          if ($response == 1) {
+            $msg = "User updated successfully!";
+            $urlParams['msg'] = $msg;
+          }
+
+          // Unset the parameters
+          unset($urlParams['context']);
+          unset($urlParams['action']);
+          unset($urlParams['user_id']);
+          // Redirect to own link, but with no params
+          parent::redirect("/user-dashboard", $urlParams);
+        } catch (Exception $e) {
+          $msg = $e->getMessage();
+          $urlParams['errorMsg'] = $msg;
+          parent::redirect("/user-dashboard", $urlParams);
+        }
+      }
+      if ($urlParams['action'] == 'delete') {
+        try {
+          $user = $this->service->getById($urlParams['user_id']);
+          $confirm_delete = $_POST['delete_confirm'];
+
+          if ($confirm_delete == 'yes') {
+            $response = $this->service->deleteById($user->user_id);
+            if ($response == 1) {
+              $msg = "User $user->username deleted successfully";
+              $urlParams['msg'] = $msg;
+            }
+            // Unset the parameters
+            unset($urlParams['context']);
+            unset($urlParams['action']);
+            unset($urlParams['user_id']);
+            unset($urlParams['delete_confirm']);
+            // Redirect to own link, but with no params
+            parent::redirect("/user-dashboard", $urlParams);
+          } else {
+            // Unset the parameters
+            unset($urlParams['context']);
+            unset($urlParams['action']);
+            unset($urlParams['user_id']);
+            unset($urlParams['delete_confirm']);
+            // Redirect to own link, but with no params
+            parent::redirect("/user-dashboard", $urlParams);
+          }
+        } catch (Exception $e) {
+          $msg = $e->getMessage();
+          $urlParams['errorMsg'] = $msg;
+          parent::redirect("/user-dashboard", $urlParams);
+        }
+      }
+    } else {
+      $action = $_POST['action'];
+      $user_id = $_POST['user_id'];
+
+      $urlParams = ['context' => 'update'];
+      $urlParams['action'] = $action;
+      $urlParams['user_id'] = $user_id;
+
+      parent::redirect("/user-dashboard", $urlParams);
+    }
+  }
+}
diff --git a/src/repositories/UserRepository.php b/src/repositories/UserRepository.php
index b72034e63f37bb7d05d32be09de6dd0fd381e4ed..ac11ac52baa060f15f90cadd4932f0bd9ec510e2 100644
--- a/src/repositories/UserRepository.php
+++ b/src/repositories/UserRepository.php
@@ -3,6 +3,7 @@
 namespace app\repositories;
 
 use app\base\BaseRepository;
+use app\models\UserModel;
 use PDO;
 
 class UserRepository extends BaseRepository
@@ -36,4 +37,12 @@ class UserRepository extends BaseRepository
   {
     return $this->findOne(['username' => [$username, PDO::PARAM_STR]]);
   }
+
+  public function deleteById($user_id)
+  {
+    $user = $this->getById($user_id);
+    $userModel = new UserModel();
+    $userModel->constructFromArray($user);
+    return $this->delete($userModel);
+  }
 }
diff --git a/src/services/UserService.php b/src/services/UserService.php
index f3dccab139ba0b3adac590fee428c3b641dbba8f..d92c14fbe0b4e9834d92318425f6fb67b2ec1c06 100644
--- a/src/services/UserService.php
+++ b/src/services/UserService.php
@@ -202,4 +202,9 @@ class UserService extends BaseService
     $arrParams['role'] = PDO::PARAM_STR;
     $this->repository->update($user, $arrParams);
   }
+
+  public function deleteById($user_id)
+  {
+    $this->repository->deleteById($user_id);
+  }
 }
diff --git a/views/delete-user.php b/views/delete-user.php
new file mode 100644
index 0000000000000000000000000000000000000000..41a47cfebcbc7a39d53122a781fb6ca4c08f6249
--- /dev/null
+++ b/views/delete-user.php
@@ -0,0 +1,63 @@
+<div>
+  <table class='user-list'>
+    <tr>
+      <th>User Id</th>
+      <th>Username</th>
+      <th>Email</th>
+      <th>Role</th>
+      <th>Actions</th>
+    </tr>
+    <?
+    foreach ($users as $user) {
+      echo
+      "<tr class='user-card'>
+        <td>
+          $user->user_id
+        </td>
+        <td>
+          $user->username
+        </td>
+        <td>
+          $user->email
+        </td>
+        <td>
+          $user->role
+        </td>
+        <td>
+          <form method='post'>
+            <input type='hidden' name='action' value='edit'>
+            <input type='hidden' name='user_id' value='$user->user_id'>
+            <button type='submit'>edit</button>
+          </form>
+        </td>
+        <td>
+          <form method='post'>
+            <input type='hidden' name='action' value='delete'>
+            <input type='hidden' name='user_id' value='$user->user_id'>
+            <button type='submit'>delete</button>
+          </form>
+        </td>
+      </tr>";
+    }
+    ?>
+
+</div>
+<div class="overlay">
+  <div class="popup">
+    <h1 class="header-title">Are you sure?</h1>
+    <p class="error-msg"><?php if (isset($errorMsg)) {
+                            echo "$errorMsg";
+                          } ?></p>
+    <p>User <?= $username ?> will be deleted forever!</p>
+    <div>
+      <form method='post' enctype="multipart/form-data">
+        <input type='hidden' name='delete_confirm' value='yes'>
+        <button type="submit" class="button-delete">Delete</button>
+      </form>
+      <form method='post' enctype="multipart/form-data">
+        <input type='hidden' name='delete_confirm' value='no'>
+        <button type="submit" class="button-cancel">Cancel</button>
+      </form>
+    </div>
+  </div>
+</div>
\ No newline at end of file
diff --git a/views/update-film.php b/views/update-film.php
index 19bf090b2e3da8ff61bf2d29462bfbfbbd03ffcb..5d08719393416882f738073956e447b54df2ac09 100644
--- a/views/update-film.php
+++ b/views/update-film.php
@@ -1,5 +1,5 @@
 <div class="form-container">
-  <h2 class="header-title">Add Film</h2>
+  <h2 class="header-title">Update Film</h2>
   <p class="error-msg"><?php if (isset($errorMsg)) {
                           echo "$errorMsg";
                         } ?></p>
diff --git a/views/update-user.php b/views/update-user.php
new file mode 100644
index 0000000000000000000000000000000000000000..40e482c75338f1b0d2f6dd9ac15bf9409ac42373
--- /dev/null
+++ b/views/update-user.php
@@ -0,0 +1,31 @@
+<div class="form-container">
+  <h2 class="header-title">Update User</h2>
+  <p class="error-msg"><?php if (isset($errorMsg)) {
+                          echo "$errorMsg";
+                        } ?></p>
+  <form class="form" method="post" enctype="multipart/form-data">
+    <div class="form-group">
+      <label for="email">Email</label>
+      <br>
+      <input class="input" type="text" id="email" name="email" value="<?= $email ?>" required>
+    </div>
+    <div class="form-group">
+      <label for="username">Username</label>
+      <br>
+      <input class="input" type="text" id="username" name="username" value="<?= $username ?>" required>
+    </div>
+    <div class="form-group">
+      <label for="password">Password</label>
+      <br>
+      <input class="input" type="password" id="password" name="password">
+    </div>
+    <div class="form-group">
+      <label for="confirm-password">Confirm Password</label>
+      <br>
+      <input class="input" type="password" id="confirm-password" name="confirm-password">
+    </div>
+    <div class="form-group">
+      <button class="button" ctype="submit">Update</button>
+    </div>
+  </form>
+</div>
\ No newline at end of file
diff --git a/views/user-dashboard.php b/views/user-dashboard.php
new file mode 100644
index 0000000000000000000000000000000000000000..1f56ad88939d03af741308e21c6919172920a7a4
--- /dev/null
+++ b/views/user-dashboard.php
@@ -0,0 +1,46 @@
+<div>
+  <p class="error-msg"><?php if (isset($errorMsg)) {
+                          echo "$errorMsg";
+                        } ?></p>
+  <table class='user-list'>
+    <tr>
+      <th>User Id</th>
+      <th>Username</th>
+      <th>Email</th>
+      <th>Role</th>
+      <th>Actions</th>
+    </tr>
+    <?
+    foreach ($users as $user) {
+      echo
+      "<tr class='user-card'>
+        <td>
+          $user->user_id
+        </td>
+        <td>
+          $user->username
+        </td>
+        <td>
+          $user->email
+        </td>
+        <td>
+          $user->role
+        </td>
+        <td>
+          <form method='post'>
+            <input type='hidden' name='action' value='edit'>
+            <input type='hidden' name='user_id' value='$user->user_id'>
+            <button type='submit'>edit</button>
+          </form>
+        </td>
+        <td>
+          <form method='post'>
+            <input type='hidden' name='action' value='delete'>
+            <input type='hidden' name='user_id' value='$user->user_id'>
+            <button type='submit'>delete</button>
+          </form>
+        </td>
+      </tr>";
+    }
+    ?>
+</div>
\ No newline at end of file