diff --git a/initdb/schema.sql b/initdb/schema.sql
index 55c417cd4d5f6794e2a2b4e3b5a4f6fd1d7e871b..21ea3825609294f1dac2eaf526906aea8eddc050 100644
--- a/initdb/schema.sql
+++ b/initdb/schema.sql
@@ -7,6 +7,8 @@ CREATE TABLE users (
     email VARCHAR(50) UNIQUE,
     password VARCHAR(250),
     role VARCHAR(10),
+    isVerified BOOLEAN DEFAULT FALSE,
+    verificationToken VARCHAR(255),  -- This column stores the verification token
     dateCreated TIMESTAMP DEFAULT CURRENT_TIMESTAMP
 );
 CREATE TABLE videos(
diff --git a/login-server.js b/login-server.js
index d2fa6f99c3989b49cf2fad8bc12a280965e5fcbb..9e529bb35ce8391ca5ddb497d738df13658bf30f 100644
--- a/login-server.js
+++ b/login-server.js
@@ -3,7 +3,9 @@ import express from "express";
 import cors from "cors";
 import bcrypt from "bcryptjs"; // For hashing passwords
 import jwt from "jsonwebtoken"; // For generating tokens
-
+import nodemailer from "nodemailer";
+import dotenv from "dotenv";
+dotenv.config();
 const app = express();
 const port = 8081;
 
@@ -12,6 +14,11 @@ if (process.env.DATABASE_HOST) {
   dbHost = process.env.DATABASE_HOST;
 }
 
+let frontendUrl = "http://localhost:8081"; // Default for development
+if (process.env.VITE_FRONTEND_URL) {
+  frontendUrl = process.env.VITE_FRONTEND_URL; // Use environment variable in production
+}
+
 // Middleware to parse incoming JSON requests
 app.use(express.json());
 
@@ -20,6 +27,19 @@ app.use(cors());
 
 import dbRequest from "./db.js";
 
+
+// Nodemailer setup
+const emailUser = process.env.VITE_EMAIL_USER;
+const emailPassword = process.env.VITE_EMAIL_PASSWORD;
+
+const transporter = nodemailer.createTransport({
+  service: "gmail",
+  auth: {
+    user: emailUser, // Replace with your email
+    pass: emailPassword, // Replace with your app password( watch the video to know how to get app password)
+  },
+});
+
 // Signup Route
 export const signup = async (req, res) => {
   const db = dbRequest(dbHost);
@@ -65,10 +85,22 @@ export const signup = async (req, res) => {
           return res.status(500).json({ message: "Server error" });
         }
 
+        // Generate a verification token
+        const verificationToken = jwt.sign({ email }, "secretkey", {
+          expiresIn: "1d",
+        });
+
         // Insert new user into the database
         const query =
-          "INSERT INTO users (username, email, password, role) VALUES (?, ?, ?, ?)";
-        const values = [username, email, hashedPassword, "user"];
+          "INSERT INTO users (username, email, password, role, isVerified, verificationToken) VALUES (?, ?, ?, ?, ?, ?)";
+        const values = [
+          username,
+          email,
+          hashedPassword,
+          "user",
+          false,
+          verificationToken,
+        ];
 
         db.query(query, values, (err, result) => {
           if (err) {
@@ -78,9 +110,25 @@ export const signup = async (req, res) => {
               .status(500)
               .json({ message: "Database error", error: err });
           }
-          db.destroy();
-          return res.status(201).json({
-            message: "User signed up successfully",
+          // Send verification email
+          const verificationLink = `${frontendUrl}/verify-email?token=${verificationToken}`; // Change to your frontend URL when deploying
+          const mailOptions = {
+            from: emailUser, // your email
+            to: email,
+            subject: "Verify Your Email",
+            text: `Click this link to verify your email: ${verificationLink}`,
+          };
+
+          transporter.sendMail(mailOptions, (error, info) => {
+            if (error) {
+              console.error("Error sending email: ", error);
+              return res.status(500).json({ message: "Error sending email" });
+            }
+            db.destroy();
+            return res.status(201).json({
+              message:
+                "User signed up successfully. Please check your email to verify your account.",
+            });
           });
         });
       });
@@ -97,6 +145,38 @@ export const signup = async (req, res) => {
       return res.status(500).json({ message: "Database error", error });
     });
 };
+// Email Verification Route
+app.get("/verify-email", (req, res) => {
+  const db = dbRequest(dbHost);
+  const { token } = req.query;
+
+  if (!token) {
+    db.destroy();
+    return res.status(400).json({ message: "Missing token" });
+  }
+
+  jwt.verify(token, "secretkey", (err, decoded) => {
+    if (err) {
+      db.destroy();
+      return res.status(400).json({ message: "Invalid or expired token" });
+    }
+
+    const email = decoded.email;
+    const updateQuery =
+      "UPDATE users SET isVerified = true, verificationToken = NULL WHERE email = ?";
+
+    db.query(updateQuery, [email], (err, result) => {
+      if (err) {
+        db.destroy();
+        return res.status(500).json({ message: "Database error" });
+      }
+      db.destroy();
+      return res
+        .status(200)
+        .json({ message: "Email verified successfully! You can now log in." });
+    });
+  });
+});
 
 const authenticateTokenGet = (req, res, next) => {
   const { auth: token } = req.query;
@@ -143,6 +223,13 @@ app.post("/login", (req, res) => {
 
     const user = results[0];
 
+    // Check if user is verified
+    if (!user.isVerified) {
+      return res
+        .status(403)
+        .json({ message: "Please verify your email before logging in." });
+    }
+
     // Compare passwords
     bcrypt.compare(password, user.password, (err, isMatch) => {
       if (err) {
diff --git a/package-lock.json b/package-lock.json
index 21a8965f95fe370f96e2d94b4c32db82c10ebe0e..27ce9ac5ad2a363bffa0f1853a69b24312f878a5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -25,6 +25,7 @@
         "fs": "^0.0.1-security",
         "get-all-files": "^5.0.0",
         "i": "^0.3.7",
+        "jest-mock": "^29.7.0",
         "jsonwebtoken": "^9.0.2",
         "jwt-decode": "^4.0.0",
         "mkdirp": "^3.0.1",
@@ -33,6 +34,7 @@
         "mysql": "^2.18.1",
         "mysql2": "^3.12.0",
         "node": "^18.20.6",
+        "nodemailer": "^6.10.0",
         "nodemon": "^3.1.9",
         "path-browserify": "^1.0.1",
         "react": "^18.3.1",
@@ -69,7 +71,7 @@
         "typescript": "~5.6.2",
         "typescript-eslint": "^8.18.2",
         "vite": "^6.0.5",
-        "vitest": "^3.0.5"
+        "vitest": "^3.0.8"
       }
     },
     "node_modules/@adobe/css-tools": {
@@ -1335,6 +1337,35 @@
         }
       }
     },
+    "node_modules/@jest/schemas": {
+      "version": "29.6.3",
+      "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+      "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+      "license": "MIT",
+      "dependencies": {
+        "@sinclair/typebox": "^0.27.8"
+      },
+      "engines": {
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+      }
+    },
+    "node_modules/@jest/types": {
+      "version": "29.6.3",
+      "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
+      "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+      "license": "MIT",
+      "dependencies": {
+        "@jest/schemas": "^29.6.3",
+        "@types/istanbul-lib-coverage": "^2.0.0",
+        "@types/istanbul-reports": "^3.0.0",
+        "@types/node": "*",
+        "@types/yargs": "^17.0.8",
+        "chalk": "^4.0.0"
+      },
+      "engines": {
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+      }
+    },
     "node_modules/@jridgewell/gen-mapping": {
       "version": "0.3.8",
       "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
@@ -2053,6 +2084,12 @@
         "win32"
       ]
     },
+    "node_modules/@sinclair/typebox": {
+      "version": "0.27.8",
+      "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
+      "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
+      "license": "MIT"
+    },
     "node_modules/@socket.io/component-emitter": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz",
@@ -2236,6 +2273,30 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/@types/istanbul-lib-coverage": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+      "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+      "license": "MIT"
+    },
+    "node_modules/@types/istanbul-lib-report": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
+      "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/istanbul-lib-coverage": "*"
+      }
+    },
+    "node_modules/@types/istanbul-reports": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+      "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/istanbul-lib-report": "*"
+      }
+    },
     "node_modules/@types/json-schema": {
       "version": "7.0.15",
       "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
@@ -2338,6 +2399,21 @@
       "license": "MIT",
       "optional": true
     },
+    "node_modules/@types/yargs": {
+      "version": "17.0.33",
+      "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
+      "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/yargs-parser": "*"
+      }
+    },
+    "node_modules/@types/yargs-parser": {
+      "version": "21.0.3",
+      "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
+      "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
+      "license": "MIT"
+    },
     "node_modules/@typescript-eslint/eslint-plugin": {
       "version": "8.24.1",
       "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.1.tgz",
@@ -2578,15 +2654,15 @@
       }
     },
     "node_modules/@vitest/expect": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.5.tgz",
-      "integrity": "sha512-nNIOqupgZ4v5jWuQx2DSlHLEs7Q4Oh/7AYwNyE+k0UQzG7tSmjPXShUikn1mpNGzYEN2jJbTvLejwShMitovBA==",
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.8.tgz",
+      "integrity": "sha512-Xu6TTIavTvSSS6LZaA3EebWFr6tsoXPetOWNMOlc7LO88QVVBwq2oQWBoDiLCN6YTvNYsGSjqOO8CAdjom5DCQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@vitest/spy": "3.0.5",
-        "@vitest/utils": "3.0.5",
-        "chai": "^5.1.2",
+        "@vitest/spy": "3.0.8",
+        "@vitest/utils": "3.0.8",
+        "chai": "^5.2.0",
         "tinyrainbow": "^2.0.0"
       },
       "funding": {
@@ -2594,13 +2670,13 @@
       }
     },
     "node_modules/@vitest/mocker": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.5.tgz",
-      "integrity": "sha512-CLPNBFBIE7x6aEGbIjaQAX03ZZlBMaWwAjBdMkIf/cAn6xzLTiM3zYqO/WAbieEjsAZir6tO71mzeHZoodThvw==",
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.8.tgz",
+      "integrity": "sha512-n3LjS7fcW1BCoF+zWZxG7/5XvuYH+lsFg+BDwwAz0arIwHQJFUEsKBQ0BLU49fCxuM/2HSeBPHQD8WjgrxMfow==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@vitest/spy": "3.0.5",
+        "@vitest/spy": "3.0.8",
         "estree-walker": "^3.0.3",
         "magic-string": "^0.30.17"
       },
@@ -2621,9 +2697,9 @@
       }
     },
     "node_modules/@vitest/pretty-format": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.5.tgz",
-      "integrity": "sha512-CjUtdmpOcm4RVtB+up8r2vVDLR16Mgm/bYdkGFe3Yj/scRfCpbSi2W/BDSDcFK7ohw8UXvjMbOp9H4fByd/cOA==",
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.8.tgz",
+      "integrity": "sha512-BNqwbEyitFhzYMYHUVbIvepOyeQOSFA/NeJMIP9enMntkkxLgOcgABH6fjyXG85ipTgvero6noreavGIqfJcIg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -2634,38 +2710,38 @@
       }
     },
     "node_modules/@vitest/runner": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.5.tgz",
-      "integrity": "sha512-BAiZFityFexZQi2yN4OX3OkJC6scwRo8EhRB0Z5HIGGgd2q+Nq29LgHU/+ovCtd0fOfXj5ZI6pwdlUmC5bpi8A==",
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.8.tgz",
+      "integrity": "sha512-c7UUw6gEcOzI8fih+uaAXS5DwjlBaCJUo7KJ4VvJcjL95+DSR1kova2hFuRt3w41KZEFcOEiq098KkyrjXeM5w==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@vitest/utils": "3.0.5",
-        "pathe": "^2.0.2"
+        "@vitest/utils": "3.0.8",
+        "pathe": "^2.0.3"
       },
       "funding": {
         "url": "https://opencollective.com/vitest"
       }
     },
     "node_modules/@vitest/snapshot": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.5.tgz",
-      "integrity": "sha512-GJPZYcd7v8QNUJ7vRvLDmRwl+a1fGg4T/54lZXe+UOGy47F9yUfE18hRCtXL5aHN/AONu29NGzIXSVFh9K0feA==",
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.8.tgz",
+      "integrity": "sha512-x8IlMGSEMugakInj44nUrLSILh/zy1f2/BgH0UeHpNyOocG18M9CWVIFBaXPt8TrqVZWmcPjwfG/ht5tnpba8A==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@vitest/pretty-format": "3.0.5",
+        "@vitest/pretty-format": "3.0.8",
         "magic-string": "^0.30.17",
-        "pathe": "^2.0.2"
+        "pathe": "^2.0.3"
       },
       "funding": {
         "url": "https://opencollective.com/vitest"
       }
     },
     "node_modules/@vitest/spy": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.5.tgz",
-      "integrity": "sha512-5fOzHj0WbUNqPK6blI/8VzZdkBlQLnT25knX0r4dbZI9qoZDf3qAdjoMmDcLG5A83W6oUUFJgUd0EYBc2P5xqg==",
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.8.tgz",
+      "integrity": "sha512-MR+PzJa+22vFKYb934CejhR4BeRpMSoxkvNoDit68GQxRLSf11aT6CTj3XaqUU9rxgWJFnqicN/wxw6yBRkI1Q==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -2676,14 +2752,14 @@
       }
     },
     "node_modules/@vitest/utils": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.5.tgz",
-      "integrity": "sha512-N9AX0NUoUtVwKwy21JtwzaqR5L5R5A99GAbrHfCCXK1lp593i/3AZAXhSP43wRQuxYsflrdzEfXZFo1reR1Nkg==",
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.8.tgz",
+      "integrity": "sha512-nkBC3aEhfX2PdtQI/QwAWp8qZWwzASsU4Npbcd5RdMPBSSLCpkZp52P3xku3s3uA0HIEhGvEcF8rNkBsz9dQ4Q==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@vitest/pretty-format": "3.0.5",
-        "loupe": "^3.1.2",
+        "@vitest/pretty-format": "3.0.8",
+        "loupe": "^3.1.3",
         "tinyrainbow": "^2.0.0"
       },
       "funding": {
@@ -3203,6 +3279,21 @@
         "node": ">= 16"
       }
     },
+    "node_modules/ci-info": {
+      "version": "3.9.0",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
+      "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/sibiraj-s"
+        }
+      ],
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/cli-width": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
@@ -4727,6 +4818,12 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/graceful-fs": {
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+      "license": "ISC"
+    },
     "node_modules/graphemer": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
@@ -5157,6 +5254,37 @@
       "dev": true,
       "license": "ISC"
     },
+    "node_modules/jest-mock": {
+      "version": "29.7.0",
+      "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
+      "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
+      "license": "MIT",
+      "dependencies": {
+        "@jest/types": "^29.6.3",
+        "@types/node": "*",
+        "jest-util": "^29.7.0"
+      },
+      "engines": {
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+      }
+    },
+    "node_modules/jest-util": {
+      "version": "29.7.0",
+      "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
+      "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
+      "license": "MIT",
+      "dependencies": {
+        "@jest/types": "^29.6.3",
+        "@types/node": "*",
+        "chalk": "^4.0.0",
+        "ci-info": "^3.2.0",
+        "graceful-fs": "^4.2.9",
+        "picomatch": "^2.2.3"
+      },
+      "engines": {
+        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+      }
+    },
     "node_modules/js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -6118,6 +6246,15 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/nodemailer": {
+      "version": "6.10.0",
+      "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.0.tgz",
+      "integrity": "sha512-SQ3wZCExjeSatLE/HBaXS5vqUOQk6GtBdIIKxiFdmm01mOQZX/POJkO3SUX1wDiYcwUOJwT23scFSC9fY2H8IA==",
+      "license": "MIT-0",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
     "node_modules/nodemon": {
       "version": "3.1.9",
       "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz",
@@ -8481,16 +8618,16 @@
       }
     },
     "node_modules/vite-node": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.5.tgz",
-      "integrity": "sha512-02JEJl7SbtwSDJdYS537nU6l+ktdvcREfLksk/NDAqtdKWGqHl+joXzEubHROmS3E6pip+Xgu2tFezMu75jH7A==",
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.8.tgz",
+      "integrity": "sha512-6PhR4H9VGlcwXZ+KWCdMqbtG649xCPZqfI9j2PsK1FcXgEzro5bGHcVKFCTqPLaNKZES8Evqv4LwvZARsq5qlg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "cac": "^6.7.14",
         "debug": "^4.4.0",
         "es-module-lexer": "^1.6.0",
-        "pathe": "^2.0.2",
+        "pathe": "^2.0.3",
         "vite": "^5.0.0 || ^6.0.0"
       },
       "bin": {
@@ -8523,31 +8660,31 @@
       }
     },
     "node_modules/vitest": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.5.tgz",
-      "integrity": "sha512-4dof+HvqONw9bvsYxtkfUp2uHsTN9bV2CZIi1pWgoFpL1Lld8LA1ka9q/ONSsoScAKG7NVGf2stJTI7XRkXb2Q==",
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.8.tgz",
+      "integrity": "sha512-dfqAsNqRGUc8hB9OVR2P0w8PZPEckti2+5rdZip0WIz9WW0MnImJ8XiR61QhqLa92EQzKP2uPkzenKOAHyEIbA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@vitest/expect": "3.0.5",
-        "@vitest/mocker": "3.0.5",
-        "@vitest/pretty-format": "^3.0.5",
-        "@vitest/runner": "3.0.5",
-        "@vitest/snapshot": "3.0.5",
-        "@vitest/spy": "3.0.5",
-        "@vitest/utils": "3.0.5",
-        "chai": "^5.1.2",
+        "@vitest/expect": "3.0.8",
+        "@vitest/mocker": "3.0.8",
+        "@vitest/pretty-format": "^3.0.8",
+        "@vitest/runner": "3.0.8",
+        "@vitest/snapshot": "3.0.8",
+        "@vitest/spy": "3.0.8",
+        "@vitest/utils": "3.0.8",
+        "chai": "^5.2.0",
         "debug": "^4.4.0",
         "expect-type": "^1.1.0",
         "magic-string": "^0.30.17",
-        "pathe": "^2.0.2",
+        "pathe": "^2.0.3",
         "std-env": "^3.8.0",
         "tinybench": "^2.9.0",
         "tinyexec": "^0.3.2",
         "tinypool": "^1.0.2",
         "tinyrainbow": "^2.0.0",
         "vite": "^5.0.0 || ^6.0.0",
-        "vite-node": "3.0.5",
+        "vite-node": "3.0.8",
         "why-is-node-running": "^2.3.0"
       },
       "bin": {
@@ -8563,8 +8700,8 @@
         "@edge-runtime/vm": "*",
         "@types/debug": "^4.1.12",
         "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
-        "@vitest/browser": "3.0.5",
-        "@vitest/ui": "3.0.5",
+        "@vitest/browser": "3.0.8",
+        "@vitest/ui": "3.0.8",
         "happy-dom": "*",
         "jsdom": "*"
       },
diff --git a/package.json b/package.json
index d1d0cf963b7d9c4a9c3631d8d3daa1fe4fc21aec..496a026c223d167beabedbd1be8d5bde47756846 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
     "fs": "^0.0.1-security",
     "get-all-files": "^5.0.0",
     "i": "^0.3.7",
+    "jest-mock": "^29.7.0",
     "jsonwebtoken": "^9.0.2",
     "jwt-decode": "^4.0.0",
     "mkdirp": "^3.0.1",
@@ -40,6 +41,7 @@
     "mysql": "^2.18.1",
     "mysql2": "^3.12.0",
     "node": "^18.20.6",
+    "nodemailer": "^6.10.0",
     "nodemon": "^3.1.9",
     "path-browserify": "^1.0.1",
     "react": "^18.3.1",
@@ -76,6 +78,6 @@
     "typescript": "~5.6.2",
     "typescript-eslint": "^8.18.2",
     "vite": "^6.0.5",
-    "vitest": "^3.0.5"
+    "vitest": "^3.0.8"
   }
 }
diff --git a/src/App.tsx b/src/App.tsx
index 8b6cae354b71c76bd6498789fb2f3337bf7f8e58..66f388f32bce4002ff5feea9fa45c7a0a3b280ac 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -14,8 +14,10 @@ import ReactPlayer from "react-player"; // Library for embedding and playing vid
 import User from "./User";
 import path from "path-browserify"; // Path library to work with file paths in the browser
 import Upload from "./upload.tsx";
+import VerifyEmail from "./VerifyEmail.tsx";
 import axios from "axios";
 import Terms from "./terms.tsx";
+import LikeButton from "./components/likeButton.tsx";
 import TopBar from "./components/TopBar.tsx";
 // import { createContext, useContext } from 'react';
 // import VideoPlayer from './components/VideoPlayerUser.tsx';
@@ -150,14 +152,10 @@ function Home() {
     // Only fetch like data if there's a valid video
     if (currentVideo) {
       console.log("Video changed to:", currentVideo.split("/").pop());
-      getLikeCount();
       getViewCount();
       // Only check if user has liked if they're logged in
-      if (loggedIn && userID) {
-        checkIfLiked();
-      }
     }
-  }, [currentVideo, loggedIn, userID]);
+  }, [currentVideo]);
 
   // Switch to the next video in the array
   const handleNext = () => {
@@ -279,106 +277,6 @@ function Home() {
   }
   assignUsername();
 
-  async function getLikeCount() {
-    try {
-      const fileName = currentVideo.split("/").pop();
-      if (!fileName) {
-        console.error("Error: fileName is missing.");
-        return;
-      }
-
-      const response = await axios.get(
-        `${loginServer}/video-likes-by-filename/${fileName}`
-      );
-      setLikeCount(response.data.likeCount);
-    } catch (error) {
-      console.error("Error fetching like count:", error);
-      setLikeCount(0); // Default to 0 if there's an error
-    }
-  }
-
-  async function checkIfLiked() {
-    // console.log("Checking if liked for:", currentVideo.split("/").pop());
-
-    if (!loggedIn) {
-      // console.log("Not logged in, setting liked to false");
-      setLiked(false);
-      return;
-    }
-
-    const token = localStorage.getItem("authToken");
-    if (!token) {
-      // console.log("No token, setting liked to false");
-      setLiked(false);
-      return;
-    }
-
-    const fileName = currentVideo.split("/").pop();
-    if (!fileName) {
-      // No fileName, setting liked to false
-      setLiked(false);
-      return;
-    }
-
-    try {
-      console.log("Making API request to check like status for:", fileName);
-      const response = await axios.get(`${loginServer}/check-like-status`, {
-        params: {
-          auth: token,
-          fileName: fileName,
-        },
-      });
-
-      console.log("Like status response:", response.data);
-      setLiked(response.data.liked);
-    } catch (error) {
-      console.error("Error checking like status:", error);
-      setLiked(false);
-    }
-  }
-
-  async function handleLike() {
-    if (!userID || !loggedIn) {
-      alert("You must be logged in to like videos.");
-      return;
-    }
-
-    const fileName = currentVideo.split("/").pop();
-    if (!fileName) {
-      console.error("Error: fileName is missing.");
-      return;
-    }
-
-    const token = localStorage.getItem("authToken");
-    if (!token) {
-      alert("Authentication error. Please log in again.");
-      setLoggedIn(false);
-      return;
-    }
-
-    try {
-      const response = await axios.post(
-        `${loginServer}/like-video`,
-        { fileName: fileName }, // Send fileName in the request body
-        {
-          params: { auth: token }, // Send token as a query parameter
-        }
-      );
-
-      // Update UI based on the response message
-      if (response.data.message.includes("unliked")) {
-        setLiked(false);
-        setLikeCount((prev) => Math.max(0, prev - 1));
-      } else {
-        setLiked(true);
-        setLikeCount((prev) => prev + 1);
-      }
-    } catch (error) {
-      console.error("Error liking/unliking video:", error);
-      alert("Failed to process like. Please try again.");
-    }
-  }
-
   async function getViewCount() {
     try {
       const fileName = currentVideo.split("/").pop();
@@ -457,12 +355,16 @@ function Home() {
           height="60vh"
           onStart={handleVideoStart}
         />
-        {/* 1. Video control buttons */}
       <div className="controls">
         <div className="video-stats">
-        <a onClick={handleLike} className={ liked ? "button liked" : "button not-liked" }>
-          <i className="fa-solid fa-heart"></i> {likeCount}<span className="desktop__text"> Likes</span>
-        </a>
+        <LikeButton
+          fileName={currentVideo ? currentVideo.split("/").pop() || "" : ""}
+          loggedIn={loggedIn}
+          userId={userID}
+          initialLikeCount={likeCount}
+          initialLiked={liked}
+          loginServer={loginServer}
+        />
         <span className="views">
           <i className="fa-solid fa-eye"></i> {viewCount}<span className="desktop__text"> Views</span>
         </span>
@@ -558,7 +460,8 @@ function App() {
           <Route path="/signup" element={<Signup />} />
           <Route path="/terms" element={<Terms />} />
           <Route path="/reset-password" element={<ResetPassword />} />
-          {/* User Page Route */}
+          <Route path="/verify-email" element={<VerifyEmail />} />
+        {/* User Page Route */}
 
           {/* Protected Route for Dashboard and Video Player */}
           <Route element={<PrivateRoute />}>
diff --git a/src/App.tsx.bkp b/src/App.tsx.bkp
deleted file mode 100644
index d317bfcb777ff3510d2cf8a056c838bef378a601..0000000000000000000000000000000000000000
--- a/src/App.tsx.bkp
+++ /dev/null
@@ -1,107 +0,0 @@
-function Home() {
-    return (
-    
-    <div className="app">
-      {TopBar()}
-      <div className="app-container">
-      <div className="video-container">
-      <div className="video-player">
-        <ReactPlayer
-          id="video"
-          url={currentVideo || ""}
-          playing={true}
-          muted={true}
-          controls={true}
-          loop={true}
-          playsinline={true}
-          width="80vw"
-          height="60vh"
-          onStart={handleVideoStart}
-        />
-      </div>
-      <div className="video-stats">
-        <button onClick={handleLike} style={{ color: liked ? "red" : "black" }}>
-          <i className="fa-solid fa-heart"></i> {likeCount} Likes
-        </button>
-        <span className="view-count">
-          <i className="fa-solid fa-eye"></i> {viewCount} Views
-        </span>
-      </div>
-
-      </div>
-
-      {/* 1. Video control buttons */}
-      <div className="controls">
-        {/* Download button */}
-        <a className="control-button" href={currentVideo} download>
-          <i className="fa-solid fa-download"></i> DOWNLOAD
-        </a>
-
-        {/* 2. Navigate to User page */}
-        {/* <button className="control-button user-button" onClick={() => navigate('/user')}>
-          ENGAGER <i className="fa-solid fa-user"></i>
-        </button> */}
-
-        {/*3. Next video button */}
-        <button className="control-button" onClick={handleNext}>
-          NEXT <i className="fa-solid fa-arrow-right"></i>
-        </button>
-      </div>
-
-      {/*4. Upload button */}
-      <div className="upload-section">
-        <button className="upload-button" onClick={() => navigate("/upload")}>
-          ENGAGE <i className="fa-solid fa-upload"></i>
-        </button>
-      </div>
-
-        <div className="control-button" onClick={getVideoInfo}>
-          <i className="fas fa-info-circle"></i> VIDEO INFO
-        </div>
-      <div className="login-button-section">
-        <button
-          className="control-button"
-          onClick={loggedIn ? () => navigate("/user") : handleBackToLogin}
-        >
-          {loggedIn ? (
-            <>
-              <i className="fa-solid fa-user"></i> {username}
-            </>
-          ) : (
-            <>
-              <i className="fa solid fa-right-to-bracket"></i> Log In
-            </>
-          )}
-        </button>
-        {/* <button className="control-button" onClick={async () => {
-          const userId = await getLoggedInUserId();
-          if (userId !== null) {
-            const username = await getUsername(userId);
-            alert(username);
-          } else {
-            alert("User is not logged in.");
-          }
-        }}>
-          Engager <i className="fa-solid fa-user"></i>
-        </button>  */}
-        {}
-        {/* <button className="control-button" onClick={handleBackToLogin}>
-          
-          Log In <i className="fa solid fa-right-to-bracket"></i>
-        </button>
-        <button className="control-button" onClick={async () => {
-          const userId = await getLoggedInUserId();
-          if (userId !== null) {
-            const username = await getUsername(userId);
-            alert(username);
-          } else {
-            alert("User is not logged in.");
-          }
-        }}>
-          Engager <i className="fa-solid fa-user"></i>
-        </button>  */}
-      </div>
-      </div>
-    </div>
-  );
-}
\ No newline at end of file
diff --git a/src/VerifyEmail.tsx b/src/VerifyEmail.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..e838a0aade5f285676b248fcdde3e620afc07d20
--- /dev/null
+++ b/src/VerifyEmail.tsx
@@ -0,0 +1,44 @@
+import { useEffect, useState } from "react";
+import { useNavigate, useLocation } from "react-router-dom";
+import axios from "axios";
+
+let loginServer = "http://localhost:8081";
+if (import.meta.env.VITE_LOGIN_SERVER !== undefined) {
+  // console.log(import.meta.env.VITE_UPLOAD_SERVER);
+  loginServer = import.meta.env.VITE_LOGIN_SERVER;
+}
+
+const VerifyEmail: React.FC = () => {
+  const [message, setMessage] = useState<string>("Verifying...");
+  const navigate = useNavigate();
+  const location = useLocation();
+
+  useEffect(() => {
+    const token = localStorage.getItem("authToken");
+
+    if (token) {
+      axios
+        .get(`${loginServer}/verify-email?token=${token}`)
+        .then((res) => {
+          setMessage(res.data.message);
+          setTimeout(() => navigate("/login"), 3000); // Redirect after 3 seconds
+        })
+        .catch((err) => {
+          setMessage(
+            err.response?.data?.message || "Invalid or expired token."
+          );
+        });
+    } else {
+      setMessage("Invalid request.");
+    }
+  }, [location, navigate]);
+
+  return (
+    <div className="verify-email__container">
+      <h2>Email Verification</h2>
+      <p>{message}</p>
+    </div>
+  );
+};
+
+export default VerifyEmail;
diff --git a/src/components/likeButton.tsx b/src/components/likeButton.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..7bfc79d3012857724b437cca26200a363d46a9a6
--- /dev/null
+++ b/src/components/likeButton.tsx
@@ -0,0 +1,133 @@
+import React, { useState, useEffect } from "react";
+import axios from "axios";
+import "../styles/App.scss";
+interface LikeButtonProps {
+  fileName: string;
+  loggedIn: boolean;
+  userId: number;
+  initialLikeCount?: number;
+  initialLiked?: boolean;
+  loginServer: string;
+}
+
+const LikeButton: React.FC<LikeButtonProps> = ({
+  fileName,
+  loggedIn,
+  userId,
+  initialLikeCount = 0,
+  initialLiked = false,
+  loginServer,
+}) => {
+  const [likeCount, setLikeCount] = useState(initialLikeCount);
+  const [liked, setLiked] = useState(initialLiked);
+
+  useEffect(() => {
+    getLikeCount();
+    if (loggedIn && userId) {
+      checkIfLiked();
+    }
+  }, [fileName, loggedIn, userId]);
+
+  async function getLikeCount() {
+    try {
+      if (!fileName) {
+        console.error("Error: fileName is missing.");
+        return;
+      }
+
+      const response = await axios.get(
+        `${loginServer}/video-likes-by-filename/${fileName}`
+      );
+      setLikeCount(response.data.likeCount);
+    } catch (error) {
+      console.error("Error fetching like count:", error);
+      setLikeCount(initialLikeCount);
+    }
+  }
+
+  async function checkIfLiked() {
+    if (!loggedIn) {
+      setLiked(false);
+      return;
+    }
+
+    const token = localStorage.getItem("authToken");
+    if (!token) {
+      setLiked(false);
+      return;
+    }
+
+    if (!fileName) {
+      setLiked(false);
+      return;
+    }
+
+    try {
+      const response = await axios.get(`${loginServer}/check-like-status`, {
+        params: {
+          auth: token,
+          fileName: fileName,
+        },
+      });
+
+      setLiked(response.data.liked);
+    } catch (error) {
+      console.error("Error checking like status:", error);
+      setLiked(false);
+    }
+  }
+
+  async function handleLike() {
+    if (!userId || !loggedIn) {
+      alert("You must be logged in to like videos.");
+      return;
+    }
+
+    if (!fileName) {
+      console.error("Error: fileName is missing.");
+      return;
+    }
+
+    const token = localStorage.getItem("authToken");
+    if (!token) {
+      alert("Authentication error. Please log in again.");
+      return;
+    }
+
+    try {
+      const response = await axios.post(
+        `${loginServer}/like-video`,
+        { fileName: fileName },
+        {
+          params: { auth: token },
+        }
+      );
+
+      if (response.data.message.includes("unliked")) {
+        setLiked(false);
+        setLikeCount((prev) => Math.max(0, prev - 1));
+      } else {
+        setLiked(true);
+        setLikeCount((prev) => prev + 1);
+      }
+    } catch (error) {
+      console.error("Error liking/unliking video:", error);
+      alert("Failed to process like. Please try again.");
+    }
+  }
+
+  return (
+    <a onClick={handleLike} className={ liked ? "button liked" : "button not-liked" }>
+          <i className="fa-solid fa-heart"></i> {likeCount}<span className="desktop__text"> Likes</span>
+        </a>
+    // <button
+    //   onClick={handleLike}
+    //   style={{ color: liked ? "red" : "black" }}
+    //   data-testid="like-button"
+    // >
+    //   <i className="fa-solid fa-heart"></i> {likeCount} Likes
+    // </button>
+  );
+};
+
+export default LikeButton;
diff --git a/src/signupValidation.tsx b/src/components/signupValidation.tsx
similarity index 100%
rename from src/signupValidation.tsx
rename to src/components/signupValidation.tsx
diff --git a/src/login.tsx b/src/login.tsx
index 03049d779ab9d5e4126519525698395439aec695..f9c95ee0971a0a320eff30bfc6d025e8c889456a 100644
--- a/src/login.tsx
+++ b/src/login.tsx
@@ -92,6 +92,9 @@ const Login: React.FC = () => {
           } else if (error.response && error.response.status === 401) {
             // Invalid password
             setErrors({ password: "Incorrect password! Please try again!" });
+              } else if (error.response && error.response.status === 403) {
+              // Forbidden error
+              setErrors({ password: "Account is not verified! Please check your email." });
           } else {
             // General error
             setErrors({ password: "An error occurred during login" });
diff --git a/src/signup.tsx b/src/signup.tsx
index a2845be35b7617a6e760304a0db9702d67af23d2..497b78c9e83b9ee8980b71040ee865f92b4b480c 100644
--- a/src/signup.tsx
+++ b/src/signup.tsx
@@ -1,7 +1,7 @@
 import React, { useState } from "react";
 import { Link, useNavigate } from "react-router-dom";
 import "./styles/auth.scss";
-import validation from "./signupValidation";
+import validation from "./components/signupValidation";
 import axios from "axios";
 
 // let uploadServer = "http://localhost:3001";
@@ -51,10 +51,12 @@ const Signup: React.FC = () => {
       axios
         .post(`${loginServer}/signup`, formValues)
         .then(() => {
-          setSuccessMessage("You have successfully signed up! Redirecting...");
+          setSuccessMessage(
+            "You have successfully signed up! Please verify your email."
+          );
           setTimeout(() => {
-            navigate("/login"); // Redirect after 1.5 seconds
-          }, 1500);
+            navigate("/login"); // Redirect after 3 seconds
+          }, 3000);
           setName("");
           setEmail("");
           setPassword("");
diff --git a/tests/like.test.tsx b/tests/like.test.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..1cb118206f50d053adf51cbec7a76bbd4d8d97dd
--- /dev/null
+++ b/tests/like.test.tsx
@@ -0,0 +1,152 @@
+import React from "react";
+import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
+import "@testing-library/jest-dom";
+import { render, screen, fireEvent, waitFor } from "@testing-library/react";
+import axios from "axios";
+import LikeButton from "../src/likeButton";
+
+// Mock axios
+vi.mock("axios");
+
+describe("Like Functionality", () => {
+  const originalEnv = process.env;
+  const mockLoginServer = "http://test-login-server";
+
+  beforeEach(() => {
+    // Mock environment variables
+    vi.stubEnv("VITE_UPLOAD_SERVER", "http://test-upload-server");
+    vi.stubEnv("VITE_LOGIN_SERVER", mockLoginServer);
+
+    // Mock localStorage
+    Object.defineProperty(window, "localStorage", {
+      value: {
+        getItem: vi.fn(),
+        setItem: vi.fn(),
+        removeItem: vi.fn(),
+      },
+      writable: true,
+    });
+
+    // Mock localStorage for logged-in user
+    vi.spyOn(window.localStorage, "getItem").mockImplementation((key) => {
+      if (key === "authToken") return "mock-token";
+      return null;
+    });
+  });
+
+  afterEach(() => {
+    vi.clearAllMocks();
+    process.env = originalEnv;
+  });
+  // Test 1: Test case for like functionality for logged-in user
+  it("should call like-video API when like button is clicked by logged-in user", async () => {
+    // Mock responses for API calls
+    vi.mocked(axios.get).mockImplementation((url) => {
+      if (url.includes("/video-likes-by-filename/")) {
+        return Promise.resolve({ data: { likeCount: 5 } });
+      } else if (url.includes("/check-like-status")) {
+        return Promise.resolve({ data: { liked: false } });
+      }
+      return Promise.resolve({ data: {} });
+    });
+
+    vi.mocked(axios.post).mockImplementation((url) => {
+      if (url.includes("/like-video")) {
+        return Promise.resolve({
+          data: { message: "Video liked successfully" },
+        });
+      }
+      return Promise.resolve({ data: {} });
+    });
+
+    // Render just the LikeButton component (avoiding the whole App with router)
+    render(
+      <LikeButton
+        fileName="video1.mp4"
+        loggedIn={true}
+        userId={123}
+        initialLikeCount={5}
+        loginServer={mockLoginServer}
+      />
+    );
+
+    // Find and click the like button
+    const likeButton = screen.getByTestId("like-button");
+    fireEvent.click(likeButton);
+
+    // Verify that the like API was called
+    await waitFor(() => {
+      expect(axios.post).toHaveBeenCalledWith(
+        `${mockLoginServer}/like-video`,
+        { fileName: "video1.mp4" },
+        { params: { auth: "mock-token" } }
+      );
+    });
+  });
+  // Test 2: Test case for like functionality for logged-out user
+  it("should show alert if user is not logged in", async () => {
+    // Mock alert
+    const alertMock = vi.spyOn(window, "alert").mockImplementation(() => {});
+
+    render(
+      <LikeButton
+        fileName="video1.mp4"
+        loggedIn={false}
+        userId={0}
+        initialLikeCount={5}
+        loginServer={mockLoginServer}
+      />
+    );
+
+    // Find and click the like button
+    const likeButton = screen.getByTestId("like-button");
+    fireEvent.click(likeButton);
+
+    // Verify alert was shown
+    expect(alertMock).toHaveBeenCalledWith(
+      "You must be logged in to like videos."
+    );
+  });
+
+  // Test 3: Test case for updating UI after liking a video
+  it("should update UI after liking a video", async () => {
+    // Mock responses
+    vi.mocked(axios.get).mockImplementation((url) => {
+      if (url.includes("/video-likes-by-filename/")) {
+        return Promise.resolve({ data: { likeCount: 5 } });
+      } else if (url.includes("/check-like-status")) {
+        return Promise.resolve({ data: { liked: false } });
+      }
+      return Promise.resolve({ data: {} });
+    });
+
+    vi.mocked(axios.post).mockImplementation((url) => {
+      if (url.includes("/like-video")) {
+        return Promise.resolve({
+          data: { message: "Video liked successfully" },
+        });
+      }
+      return Promise.resolve({ data: {} });
+    });
+
+    render(
+      <LikeButton
+        fileName="video1.mp4"
+        loggedIn={true}
+        userId={123}
+        initialLikeCount={5}
+        loginServer={mockLoginServer}
+      />
+    );
+
+    // Find and click the like button
+    const likeButton = screen.getByTestId("like-button");
+    fireEvent.click(likeButton);
+
+    // Verify that the UI updates
+    await waitFor(() => {
+      expect(likeButton).toHaveStyle("color: rgb(255, 0, 0)");
+      expect(likeButton).toHaveTextContent("6 Likes");
+    });
+  });
+});