From 7ce0153a763ef9db8b66934a4a3bc9a990edf51b Mon Sep 17 00:00:00 2001
From: Peter Harrison <16875803+palisadoes@users.noreply.github.com>
Date: Thu, 9 Jan 2025 19:23:04 -0800
Subject: [PATCH] Merge from `develop-postgres` prior to code freeze (#3234)

* 20250109190418 Deleted all files in the develop branch in anticipation of merging develop-postgres into develop cleanly

* 20250109190422 Merge develop-postgres into develop
---
 .husky/pre-commit                             |   2 -
 jest.config.js                                |   4 +-
 package.json                                  |   2 +-
 public/locales/en/translation.json            |   1 +
 public/locales/fr/translation.json            |   1 +
 public/locales/hi/translation.json            |   1 +
 public/locales/sp/translation.json            |   1 +
 public/locales/zh/translation.json            |   1 +
 setup.ts                                      | 203 ++---
 src/assets/css/app.css                        |  21 +
 .../EventCalendar/EventCalendar.module.css    |   0
 .../EventCalendar/EventHeader.spec.tsx        |   2 +-
 src/components/EventCalendar/EventHeader.tsx  |  77 +-
 .../EventListCard/EventListCard.tsx           |   5 +-
 .../EventAttendance/EventAttendance.spec.tsx  |  15 +-
 .../EventAttendance/EventAttendance.tsx       | 106 +--
 .../EventStats/Statistics/AverageRating.tsx   |  14 +-
 src/components/LeftDrawer/LeftDrawer.tsx      |   8 +-
 src/components/OrgListCard/OrgListCard.tsx    |  21 +-
 src/components/OrgListCard/TruncatedText.tsx  |  80 ++
 src/components/OrgListCard/useDebounce.tsx    |  42 +
 .../OrgPeopleListCard.spec.tsx                |  48 +-
 .../OrgPeopleListCard/OrgPeopleListCard.tsx   |   5 +-
 .../OrgActionItemCategories.spec.tsx          |  12 +-
 .../OrgActionItemCategories.tsx               | 107 ++-
 .../RequestsTableItem.spec.tsx                |   2 -
 .../RequestsTableItem/RequestsTableItem.tsx   |   4 -
 .../UsersTableItem/UsersTableItem.tsx         |   1 +
 src/components/Venues/VenueModal.spec.tsx     |  85 ++
 src/components/Venues/VenueModal.tsx          |   4 -
 src/screens/BlockUser/BlockUser.spec.tsx      |  12 +-
 src/screens/BlockUser/BlockUser.tsx           |  95 +--
 .../EventManagement/EventManagement.spec.tsx  | 253 ++++++
 .../EventManagement/EventManagement.test.tsx  | 143 ----
 .../EventManagement/EventManagement.tsx       |  16 +-
 .../EventVolunteers/Requests/Requests.tsx     |  41 +-
 .../VolunteerGroups/VolunteerGroups.tsx       |  78 +-
 .../Volunteers/Volunteers.spec.tsx            |  12 +-
 .../EventVolunteers/Volunteers/Volunteers.tsx | 100 +--
 src/screens/ForgotPassword/ForgotPassword.tsx |   2 +-
 ...e.test.tsx => FundCampaignPledge.spec.tsx} |  52 +-
 .../FundCampaignPledge/FundCampaignPledge.tsx |  64 +-
 ...al.test.tsx => PledgeDeleteModal.spec.tsx} |  11 +-
 src/screens/Leaderboard/Leaderboard.spec.tsx  |   8 +-
 src/screens/Leaderboard/Leaderboard.tsx       |  97 +--
 src/screens/ManageTag/ManageTag.spec.tsx      |  10 +-
 src/screens/ManageTag/ManageTag.tsx           |  44 +-
 .../{OrgList.test.tsx => OrgList.spec.tsx}    |  20 +-
 src/screens/OrgList/OrgList.tsx               |  67 +-
 src/screens/OrgList/OrgListMocks.ts           |   1 -
 src/screens/OrgPost/OrgPost.test.tsx          |   2 +-
 src/screens/OrgPost/OrgPost.tsx               |  87 +--
 src/screens/OrgSettings/OrgSettings.spec.tsx  |  92 +--
 src/screens/OrgSettings/OrgSettings.tsx       |  30 +-
 .../OrganizationActionItems.spec.tsx          |  12 +-
 .../OrganizationActionItems.tsx               | 152 ++--
 ...nModal.test.tsx => CampaignModal.spec.tsx} |  26 +-
 .../OrganizationFundCampagins.tsx             |  61 +-
 ....tsx => OrganizationFundCampaign.spec.tsx} |  59 +-
 .../OrganizationFunds/OrganizationFunds.tsx   |  49 +-
 src/screens/OrganizationPeople/AddMember.tsx  |  58 +-
 .../OrganizationPeople/OrganizationPeople.tsx | 152 ++--
 .../OrganizationTags/OrganizationTags.tsx     |  50 +-
 .../OrganizationVenues/OrganizationVenues.tsx | 107 +--
 src/screens/SubTags/SubTags.spec.tsx          |   8 +-
 src/screens/SubTags/SubTags.tsx               |  44 +-
 .../UserPortal/Campaigns/Campaigns.tsx        |  63 +-
 src/screens/UserPortal/Pledges/Pledges.tsx    | 106 +--
 .../Posts/{Posts.test.tsx => Posts.spec.tsx}  |  67 +-
 .../UserPortal/Settings/Settings.spec.tsx     | 153 ++++
 src/screens/UserPortal/Settings/Settings.tsx  |   3 -
 .../UserPortal/UserScreen/UserScreen.spec.tsx |  19 +
 .../UserPortal/UserScreen/UserScreen.tsx      |   1 +
 .../UserPortal/Volunteer/Actions/Actions.tsx  |  76 +-
 .../UserPortal/Volunteer/Groups/Groups.tsx    |  80 +-
 .../Invitations/Invitations.spec.tsx          |   6 +-
 .../Volunteer/Invitations/Invitations.tsx     |  93 +--
 .../UpcomingEvents/UpcomingEvents.tsx         |  44 +-
 src/screens/Users/Users.tsx                   |  97 +--
 .../askAndSetDockerOption.spec.ts             |  61 ++
 .../askAndSetDockerOption.ts                  |  35 +
 .../askAndUpdatePort/askAndUpdatePort.ts      |  25 +
 .../askAndUpdatePort/askForUpdatePort.spec.ts |  55 ++
 src/setup/askForDocker/askForDocker.spec.ts   |  69 ++
 src/setup/askForDocker/askForDocker.ts        |  99 +++
 src/setup/updateEnvFile/updateEnvFile.spec.ts |  88 +++
 src/setup/updateEnvFile/updateEnvFile.ts      |  21 +
 ...tcha.test.ts => validateRecaptcha.spec.ts} |   1 +
 src/style/app.module.css                      | 126 ++-
 src/subComponents/SortingButton.tsx           | 100 +++
 src/utils/StaticMockLink.spec.ts              | 725 ++++++++++++++++++
 91 files changed, 3186 insertions(+), 2017 deletions(-)
 create mode 100644 src/components/EventCalendar/EventCalendar.module.css
 create mode 100644 src/components/OrgListCard/TruncatedText.tsx
 create mode 100644 src/components/OrgListCard/useDebounce.tsx
 create mode 100644 src/screens/EventManagement/EventManagement.spec.tsx
 delete mode 100644 src/screens/EventManagement/EventManagement.test.tsx
 rename src/screens/FundCampaignPledge/{FundCampaignPledge.test.tsx => FundCampaignPledge.spec.tsx} (92%)
 rename src/screens/FundCampaignPledge/{PledgeDeleteModal.test.tsx => PledgeDeleteModal.spec.tsx} (95%)
 rename src/screens/OrgList/{OrgList.test.tsx => OrgList.spec.tsx} (98%)
 rename src/screens/OrganizationFundCampaign/{CampaignModal.test.tsx => CampaignModal.spec.tsx} (95%)
 rename src/screens/OrganizationFundCampaign/{OrganizationFundCampaign.test.tsx => OrganizationFundCampaign.spec.tsx} (88%)
 rename src/screens/UserPortal/Posts/{Posts.test.tsx => Posts.spec.tsx} (89%)
 create mode 100644 src/setup/askAndSetDockerOption/askAndSetDockerOption.spec.ts
 create mode 100644 src/setup/askAndSetDockerOption/askAndSetDockerOption.ts
 create mode 100644 src/setup/askAndUpdatePort/askAndUpdatePort.ts
 create mode 100644 src/setup/askAndUpdatePort/askForUpdatePort.spec.ts
 create mode 100644 src/setup/askForDocker/askForDocker.spec.ts
 create mode 100644 src/setup/askForDocker/askForDocker.ts
 create mode 100644 src/setup/updateEnvFile/updateEnvFile.spec.ts
 create mode 100644 src/setup/updateEnvFile/updateEnvFile.ts
 rename src/setup/validateRecaptcha/{validateRecaptcha.test.ts => validateRecaptcha.spec.ts} (95%)
 create mode 100644 src/subComponents/SortingButton.tsx
 create mode 100644 src/utils/StaticMockLink.spec.ts

diff --git a/.husky/pre-commit b/.husky/pre-commit
index 77ecddae25..8a0ce26aa2 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,5 +1,3 @@
-#!/usr/bin/env sh
-. "$(dirname -- "$0")/_/husky.sh"
 
 npm run format:fix
 # npm run lint:fix
diff --git a/jest.config.js b/jest.config.js
index 75e0cc5b4d..dffec5db18 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -72,8 +72,8 @@ export default {
   ],
   coverageThreshold: {
     global: {
-      lines: 20,
-      statements: 20,
+      lines: 1,
+      statements: 1,
     },
   },
   testPathIgnorePatterns: [
diff --git a/package.json b/package.json
index cd52ff6453..7fd2f550eb 100644
--- a/package.json
+++ b/package.json
@@ -87,7 +87,7 @@
     "format:check": "prettier --check \"**/*.{ts,tsx,json,scss,css}\"",
     "check-tsdoc": "node .github/workflows/check-tsdoc.js",
     "typecheck": "tsc --project tsconfig.json --noEmit",
-    "prepare": "husky install",
+    "prepare": "husky",
     "jest-preview": "jest-preview",
     "update:toc": "node scripts/githooks/update-toc.js",
     "lint-staged": "lint-staged --concurrent false",
diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json
index a6cb90d3d1..fc445a708e 100644
--- a/public/locales/en/translation.json
+++ b/public/locales/en/translation.json
@@ -1262,6 +1262,7 @@
     "endOfResults": "endOfResults"
   },
   "userChat": {
+    "title": "Chats",
     "add": "Add",
     "chat": "Chat",
     "search": "Search",
diff --git a/public/locales/fr/translation.json b/public/locales/fr/translation.json
index 416d00c4b4..0ac5728872 100644
--- a/public/locales/fr/translation.json
+++ b/public/locales/fr/translation.json
@@ -1262,6 +1262,7 @@
     "endOfResults": "Fin des résultats"
   },
   "userChat": {
+    "title": "Discussions",
     "add": "Ajouter",
     "chat": "Chat",
     "contacts": "Contacts",
diff --git a/public/locales/hi/translation.json b/public/locales/hi/translation.json
index 6abb8abefc..d791c0d9e8 100644
--- a/public/locales/hi/translation.json
+++ b/public/locales/hi/translation.json
@@ -1262,6 +1262,7 @@
     "endOfResults": "परिणाम समाप्त"
   },
   "userChat": {
+    "title": "चैट्स",
     "add": "जोड़ें",
     "chat": "बात करना",
     "contacts": "संपर्क",
diff --git a/public/locales/sp/translation.json b/public/locales/sp/translation.json
index 79d7436c39..814da7334b 100644
--- a/public/locales/sp/translation.json
+++ b/public/locales/sp/translation.json
@@ -1265,6 +1265,7 @@
     "createAdvertisement": "Crear publicidad"
   },
   "userChat": {
+    "title": "Chats",
     "add": "Agregar",
     "chat": "Charlar",
     "search": "Buscar",
diff --git a/public/locales/zh/translation.json b/public/locales/zh/translation.json
index 32a4f953be..2a8a2753a8 100644
--- a/public/locales/zh/translation.json
+++ b/public/locales/zh/translation.json
@@ -1262,6 +1262,7 @@
     "endOfResults": "结果结束"
   },
   "userChat": {
+    "title": "聊天",
     "add": "添加",
     "chat": "聊天",
     "contacts": "联系方式",
diff --git a/setup.ts b/setup.ts
index 2a6c437fa3..2c39924be8 100644
--- a/setup.ts
+++ b/setup.ts
@@ -1,165 +1,48 @@
 import dotenv from 'dotenv';
 import fs from 'fs';
 import inquirer from 'inquirer';
-import { checkConnection } from './src/setup/checkConnection/checkConnection';
-import { askForTalawaApiUrl } from './src/setup/askForTalawaApiUrl/askForTalawaApiUrl';
 import { checkEnvFile } from './src/setup/checkEnvFile/checkEnvFile';
 import { validateRecaptcha } from './src/setup/validateRecaptcha/validateRecaptcha';
-import { askForCustomPort } from './src/setup/askForCustomPort/askForCustomPort';
-
-export async function main(): Promise<void> {
-  console.log('Welcome to the Talawa Admin setup! 🚀');
-
-  if (!fs.existsSync('.env')) {
-    fs.openSync('.env', 'w');
-    const config = dotenv.parse(fs.readFileSync('.env.example'));
-    for (const key in config) {
-      fs.appendFileSync('.env', `${key}=${config[key]}\n`);
-    }
-  } else {
-    checkEnvFile();
-  }
-
-  let shouldSetCustomPort: boolean;
-
-  if (process.env.PORT) {
-    console.log(
-      `\nCustom port for development server already exists with the value:\n${process.env.PORT}`,
-    );
-    shouldSetCustomPort = true;
-  } else {
-    const { shouldSetCustomPortResponse } = await inquirer.prompt({
+import askAndSetDockerOption from './src/setup/askAndSetDockerOption/askAndSetDockerOption';
+import updateEnvFile from './src/setup/updateEnvFile/updateEnvFile';
+import askAndUpdatePort from './src/setup/askAndUpdatePort/askAndUpdatePort';
+import { askAndUpdateTalawaApiUrl } from './src/setup/askForDocker/askForDocker';
+
+// Ask and set up reCAPTCHA
+const askAndSetRecaptcha = async (): Promise<void> => {
+  try {
+    const { shouldUseRecaptcha } = await inquirer.prompt({
       type: 'confirm',
-      name: 'shouldSetCustomPortResponse',
-      message: 'Would you like to set up a custom port?',
+      name: 'shouldUseRecaptcha',
+      message: 'Would you like to set up reCAPTCHA?',
       default: true,
     });
-    shouldSetCustomPort = shouldSetCustomPortResponse;
-  }
-
-  if (shouldSetCustomPort) {
-    const customPort = await askForCustomPort();
-
-    const port = dotenv.parse(fs.readFileSync('.env')).PORT;
-
-    fs.readFile('.env', 'utf8', (err, data) => {
-      const result = data.replace(`PORT=${port}`, `PORT=${customPort}`);
-      fs.writeFileSync('.env', result, 'utf8');
-    });
-  }
-
-  let shouldSetTalawaApiUrl: boolean;
-
-  if (process.env.REACT_APP_TALAWA_URL) {
-    console.log(
-      `\nEndpoint for accessing talawa-api graphql service already exists with the value:\n${process.env.REACT_APP_TALAWA_URL}`,
-    );
-    shouldSetTalawaApiUrl = true;
-  } else {
-    const { shouldSetTalawaApiUrlResponse } = await inquirer.prompt({
-      type: 'confirm',
-      name: 'shouldSetTalawaApiUrlResponse',
-      message: 'Would you like to set up talawa-api endpoint?',
-      default: true,
-    });
-    shouldSetTalawaApiUrl = shouldSetTalawaApiUrlResponse;
-  }
-
-  if (shouldSetTalawaApiUrl) {
-    let isConnected = false,
-      endpoint = '';
-
-    while (!isConnected) {
-      endpoint = await askForTalawaApiUrl();
-      const url = new URL(endpoint);
-      isConnected = await checkConnection(url.origin);
-    }
-    const envPath = '.env';
-    const currentEnvContent = fs.readFileSync(envPath, 'utf8');
-    const talawaApiUrl = dotenv.parse(currentEnvContent).REACT_APP_TALAWA_URL;
-
-    const updatedEnvContent = currentEnvContent.replace(
-      `REACT_APP_TALAWA_URL=${talawaApiUrl}`,
-      `REACT_APP_TALAWA_URL=${endpoint}`,
-    );
-
-    fs.writeFileSync(envPath, updatedEnvContent, 'utf8');
-    const websocketUrl = endpoint.replace(/^http(s)?:\/\//, 'ws$1://');
-    const currentWebSocketUrl =
-      dotenv.parse(updatedEnvContent).REACT_APP_BACKEND_WEBSOCKET_URL;
-
-    const finalEnvContent = updatedEnvContent.replace(
-      `REACT_APP_BACKEND_WEBSOCKET_URL=${currentWebSocketUrl}`,
-      `REACT_APP_BACKEND_WEBSOCKET_URL=${websocketUrl}`,
-    );
-
-    fs.writeFileSync(envPath, finalEnvContent, 'utf8');
-  }
-
-  const { shouldUseRecaptcha } = await inquirer.prompt({
-    type: 'confirm',
-    name: 'shouldUseRecaptcha',
-    message: 'Would you like to set up ReCAPTCHA?',
-    default: true,
-  });
-
-  if (shouldUseRecaptcha) {
-    const useRecaptcha = dotenv.parse(
-      fs.readFileSync('.env'),
-    ).REACT_APP_USE_RECAPTCHA;
-
-    fs.readFile('.env', 'utf8', (err, data) => {
-      const result = data.replace(
-        `REACT_APP_USE_RECAPTCHA=${useRecaptcha}`,
-        `REACT_APP_USE_RECAPTCHA=yes`,
-      );
-      fs.writeFileSync('.env', result, 'utf8');
-    });
-    let shouldSetRecaptchaSiteKey: boolean;
-    if (process.env.REACT_APP_RECAPTCHA_SITE_KEY) {
-      console.log(
-        `\nreCAPTCHA site key already exists with the value ${process.env.REACT_APP_RECAPTCHA_SITE_KEY}`,
-      );
-      shouldSetRecaptchaSiteKey = true;
-    } else {
-      const { shouldSetRecaptchaSiteKeyResponse } = await inquirer.prompt({
-        type: 'confirm',
-        name: 'shouldSetRecaptchaSiteKeyResponse',
-        message: 'Would you like to set up a reCAPTCHA site key?',
-        default: true,
-      });
-      shouldSetRecaptchaSiteKey = shouldSetRecaptchaSiteKeyResponse;
-    }
 
-    if (shouldSetRecaptchaSiteKey) {
+    if (shouldUseRecaptcha) {
       const { recaptchaSiteKeyInput } = await inquirer.prompt([
         {
           type: 'input',
           name: 'recaptchaSiteKeyInput',
           message: 'Enter your reCAPTCHA site key:',
-          validate: async (input: string): Promise<boolean | string> => {
-            if (validateRecaptcha(input)) {
-              return true;
-            }
-            return 'Invalid reCAPTCHA site key. Please try again.';
+          validate: (input: string): boolean | string => {
+            return (
+              validateRecaptcha(input) ||
+              'Invalid reCAPTCHA site key. Please try again.'
+            );
           },
         },
       ]);
 
-      const recaptchaSiteKey = dotenv.parse(
-        fs.readFileSync('.env'),
-      ).REACT_APP_RECAPTCHA_SITE_KEY;
-
-      fs.readFile('.env', 'utf8', (err, data) => {
-        const result = data.replace(
-          `REACT_APP_RECAPTCHA_SITE_KEY=${recaptchaSiteKey}`,
-          `REACT_APP_RECAPTCHA_SITE_KEY=${recaptchaSiteKeyInput}`,
-        );
-        fs.writeFileSync('.env', result, 'utf8');
-      });
+      updateEnvFile('REACT_APP_RECAPTCHA_SITE_KEY', recaptchaSiteKeyInput);
     }
+  } catch (error) {
+    console.error('Error setting up reCAPTCHA:', error);
+    throw new Error(`Failed to set up reCAPTCHA: ${(error as Error).message}`);
   }
+};
 
+// Ask and set up logging errors in the console
+const askAndSetLogErrors = async (): Promise<void> => {
   const { shouldLogErrors } = await inquirer.prompt({
     type: 'confirm',
     name: 'shouldLogErrors',
@@ -169,17 +52,37 @@ export async function main(): Promise<void> {
   });
 
   if (shouldLogErrors) {
-    const logErrors = dotenv.parse(fs.readFileSync('.env')).ALLOW_LOGS;
-
-    fs.readFile('.env', 'utf8', (err, data) => {
-      const result = data.replace(`ALLOW_LOGS=${logErrors}`, 'ALLOW_LOGS=YES');
-      fs.writeFileSync('.env', result, 'utf8');
-    });
+    updateEnvFile('ALLOW_LOGS', 'YES');
   }
+};
 
-  console.log(
-    '\nCongratulations! Talawa Admin has been successfully setup! 🥂🎉',
-  );
+// Main function to run the setup process
+export async function main(): Promise<void> {
+  try {
+    console.log('Welcome to the Talawa Admin setup! 🚀');
+
+    checkEnvFile();
+    await askAndSetDockerOption();
+    const envConfig = dotenv.parse(fs.readFileSync('.env', 'utf8'));
+    const useDocker = envConfig.USE_DOCKER === 'YES';
+
+    // Only run these commands if Docker is NOT used
+    if (!useDocker) {
+      await askAndUpdatePort();
+      await askAndUpdateTalawaApiUrl();
+    }
+
+    await askAndSetRecaptcha();
+    await askAndSetLogErrors();
+
+    console.log(
+      '\nCongratulations! Talawa Admin has been successfully set up! 🥂🎉',
+    );
+  } catch (error) {
+    console.error('\n❌ Setup failed:', error);
+    console.log('\nPlease try again or contact support if the issue persists.');
+    process.exit(1);
+  }
 }
 
 main();
diff --git a/src/assets/css/app.css b/src/assets/css/app.css
index b3a8613975..bd34d56907 100644
--- a/src/assets/css/app.css
+++ b/src/assets/css/app.css
@@ -3442,6 +3442,7 @@ textarea.form-control.is-invalid {
   }
 }
 
+/* To remove the green and replace by greyish hover , make changes here */
 .btn:hover {
   color: var(--bs-btn-hover-color);
   background-color: var(--bs-btn-hover-bg);
@@ -14066,6 +14067,7 @@ fieldset:disabled .btn {
 .btn-warning,
 .btn-info {
   color: #fff;
+  /* isolation: isolate; */
 }
 
 .btn-primary:hover,
@@ -14079,8 +14081,27 @@ fieldset:disabled .btn {
 .btn-info:hover,
 .btn-info:active {
   color: #fff !important;
+  box-shadow: inset 50px 50px 40px rgba(0, 0, 0, 0.5);
+  background-blend-mode: multiply;
+  /* background-color: #6c757d ; */
+  /* filter: brightness(0.85); */
 }
 
+/* .btn-primary{
+  --hover-bg: #6c757d !important; 
+}
+
+
+.btn-primary:hover,
+.btn-primary:active{
+  --hover-bg: hsl(var(--button-hue, 0), 100%, 60%) !important;
+}
+
+.btn-primary:hover,
+.btn-primary:active{
+  --hover-bg: hsl(var(--button-hue, 0), 100%, 0%) !important;
+} */
+
 .btn-outline-primary:hover,
 .btn-outline-primary:active,
 .btn-outline-secondary:hover,
diff --git a/src/components/EventCalendar/EventCalendar.module.css b/src/components/EventCalendar/EventCalendar.module.css
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/src/components/EventCalendar/EventHeader.spec.tsx b/src/components/EventCalendar/EventHeader.spec.tsx
index be1ba4bd78..84b8ceafec 100644
--- a/src/components/EventCalendar/EventHeader.spec.tsx
+++ b/src/components/EventCalendar/EventHeader.spec.tsx
@@ -69,7 +69,7 @@ describe('EventHeader Component', () => {
     fireEvent.click(getByTestId('eventType'));
 
     await act(async () => {
-      fireEvent.click(getByTestId('events'));
+      fireEvent.click(getByTestId('Events'));
     });
 
     expect(handleChangeView).toHaveBeenCalledTimes(1);
diff --git a/src/components/EventCalendar/EventHeader.tsx b/src/components/EventCalendar/EventHeader.tsx
index d8f949ca97..9201e8b696 100644
--- a/src/components/EventCalendar/EventHeader.tsx
+++ b/src/components/EventCalendar/EventHeader.tsx
@@ -1,9 +1,10 @@
 import React, { useState } from 'react';
-import { Button, Dropdown, Form } from 'react-bootstrap';
+import { Button, Form } from 'react-bootstrap';
 import { Search } from '@mui/icons-material';
 import styles from '../../style/app.module.css';
 import { ViewType } from '../../screens/OrganizationEvents/OrganizationEvents';
 import { useTranslation } from 'react-i18next';
+import SortingButton from 'subComponents/SortingButton';
 
 /**
  * Props for the EventHeader component.
@@ -63,56 +64,30 @@ function eventHeader({
         </div>
         <div className={styles.flex_grow}></div>
         <div className={styles.space}>
-          <div>
-            <Dropdown
-              onSelect={handleChangeView}
-              className={styles.selectTypeEventHeader}
-            >
-              <Dropdown.Toggle
-                id="dropdown-basic"
-                className={styles.dropdown}
-                data-testid="selectViewType"
-              >
-                {viewType}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  eventKey={ViewType.MONTH}
-                  data-testid="selectMonth"
-                >
-                  {ViewType.MONTH}
-                </Dropdown.Item>
-                <Dropdown.Item eventKey={ViewType.DAY} data-testid="selectDay">
-                  {ViewType.DAY}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  eventKey={ViewType.YEAR}
-                  data-testid="selectYear"
-                >
-                  {ViewType.YEAR}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-          </div>
-          <div>
-            <Dropdown className={styles.selectTypeEventHeader}>
-              <Dropdown.Toggle
-                id="dropdown-basic"
-                className={styles.dropdown}
-                data-testid="eventType"
-              >
-                {t('eventType')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item eventKey="Events" data-testid="events">
-                  Events
-                </Dropdown.Item>
-                <Dropdown.Item eventKey="Workshops" data-testid="workshop">
-                  Workshops
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-          </div>
+          <SortingButton
+            title={t('viewType')}
+            sortingOptions={[
+              { label: ViewType.MONTH, value: 'selectMonth' },
+              { label: ViewType.DAY, value: 'selectDay' },
+              { label: ViewType.YEAR, value: 'selectYear' },
+            ]}
+            selectedOption={viewType}
+            onSortChange={handleChangeView}
+            dataTestIdPrefix="selectViewType"
+            className={styles.dropdown}
+          />
+          <SortingButton
+            title={t('eventType')}
+            sortingOptions={[
+              { label: 'Events', value: 'Events' },
+              { label: 'Workshops', value: 'Workshops' },
+            ]}
+            selectedOption={t('eventType')}
+            onSortChange={(value) => console.log(`Selected: ${value}`)}
+            dataTestIdPrefix="eventType"
+            className={styles.dropdown}
+            buttonLabel={t('eventType')}
+          />
           <Button
             variant="success"
             className={styles.createButtonEventHeader}
diff --git a/src/components/EventListCard/EventListCard.tsx b/src/components/EventListCard/EventListCard.tsx
index dba2ef4541..759e432628 100644
--- a/src/components/EventListCard/EventListCard.tsx
+++ b/src/components/EventListCard/EventListCard.tsx
@@ -75,9 +75,6 @@ function eventListCard(props: InterfaceEventListCardProps): JSX.Element {
     <>
       <div
         className={styles.cardsEventListCard}
-        style={{
-          backgroundColor: '#d9d9d9',
-        }}
         onClick={showViewModal}
         data-testid="card"
       >
@@ -98,5 +95,5 @@ function eventListCard(props: InterfaceEventListCardProps): JSX.Element {
     </>
   );
 }
-export {};
+
 export default eventListCard;
diff --git a/src/components/EventManagement/EventAttendance/EventAttendance.spec.tsx b/src/components/EventManagement/EventAttendance/EventAttendance.spec.tsx
index bff1553cc0..7dc767e232 100644
--- a/src/components/EventManagement/EventAttendance/EventAttendance.spec.tsx
+++ b/src/components/EventManagement/EventAttendance/EventAttendance.spec.tsx
@@ -103,11 +103,14 @@ describe('Event Attendance Component', () => {
     await wait();
 
     const sortDropdown = screen.getByTestId('sort-dropdown');
-    userEvent.click(sortDropdown);
-    userEvent.click(screen.getByText('Sort'));
+    userEvent.click(sortDropdown); // Open the sort dropdown
+
+    const sortOption = screen.getByText('Ascending'); // Assuming 'Ascending' is the option you choose for sorting
+    userEvent.click(sortOption);
 
     await waitFor(() => {
       const attendees = screen.getAllByTestId('attendee-name-0');
+      // Check if the first attendee is 'Bruce Garza' after sorting
       expect(attendees[0]).toHaveTextContent('Bruce Garza');
     });
   });
@@ -117,10 +120,14 @@ describe('Event Attendance Component', () => {
 
     await wait();
 
-    userEvent.click(screen.getByText('Filter: All'));
-    userEvent.click(screen.getByText('This Month'));
+    const filterDropdown = screen.getByTestId('filter-dropdown');
+    userEvent.click(filterDropdown); // Open the filter dropdown
+
+    const filterOption = screen.getByText('This Month'); // Assuming 'This Month' is the option you choose for filtering
+    userEvent.click(filterOption);
 
     await waitFor(() => {
+      // Check if the message 'Attendees not Found' is displayed
       expect(screen.getByText('Attendees not Found')).toBeInTheDocument();
     });
   });
diff --git a/src/components/EventManagement/EventAttendance/EventAttendance.tsx b/src/components/EventManagement/EventAttendance/EventAttendance.tsx
index 57ce357835..3f3f140497 100644
--- a/src/components/EventManagement/EventAttendance/EventAttendance.tsx
+++ b/src/components/EventManagement/EventAttendance/EventAttendance.tsx
@@ -9,13 +9,7 @@ import {
   TableRow,
   Tooltip,
 } from '@mui/material';
-import {
-  Button,
-  Dropdown,
-  DropdownButton,
-  Table,
-  FormControl,
-} from 'react-bootstrap';
+import { Button, Table, FormControl } from 'react-bootstrap';
 import styles from '../../../style/app.module.css';
 import { useLazyQuery } from '@apollo/client';
 import { EVENT_ATTENDEES } from 'GraphQl/Queries/Queries';
@@ -24,11 +18,14 @@ import { useTranslation } from 'react-i18next';
 import { AttendanceStatisticsModal } from './EventStatistics';
 import AttendedEventList from './AttendedEventList';
 import type { InterfaceMember } from './InterfaceEvents';
+import SortingButton from 'subComponents/SortingButton';
+
 enum FilterPeriod {
   ThisMonth = 'This Month',
   ThisYear = 'This Year',
   All = 'All',
 }
+
 /**
  * Component to manage and display event attendance information
  * Includes filtering and sorting functionality for attendees
@@ -153,18 +150,16 @@ function EventAttendance(): JSX.Element {
         memberData={filteredAttendees}
         t={t}
       />
-      <div className="d-flex justify-content-between">
-        <div className="d-flex w-100">
-          <Button
-            className={`border-1 bg-white text-success ${styles.actionBtn}`}
-            onClick={showModal}
-            data-testid="stats-modal"
-          >
-            {t('historical_statistics')}
-          </Button>
-        </div>
-        <div className="d-flex justify-content-between align-items-end w-100 ">
-          <div className={styles.input}>
+      <div className="d-flex justify-content-between align-items-center mb-3">
+        <Button
+          className={`border-1 bg-white text-success ${styles.actionBtn}`}
+          onClick={showModal}
+          data-testid="stats-modal"
+        >
+          {t('historical_statistics')}
+        </Button>
+        <div className="d-flex align-items-center">
+          <div className={`${styles.input} me-3`}>
             <FormControl
               type="text"
               id="posttitle"
@@ -182,54 +177,37 @@ function EventAttendance(): JSX.Element {
               <Search size={20} />
             </Button>
           </div>
-
-          <DropdownButton
-            data-testid="filter-dropdown"
-            className={`border-1 mx-4`}
-            title={
-              <>
-                <img
-                  src="/images/svg/up-down.svg"
-                  width={20}
-                  height={20}
-                  alt="Sort"
-                  className={styles.sortImg}
-                />
-                <span className="ms-2">Filter: {filteringBy}</span>
-              </>
-            }
-            onSelect={(eventKey) => setFilteringBy(eventKey as FilterPeriod)}
-          >
-            <Dropdown.Item eventKey="This Month">This Month</Dropdown.Item>
-            <Dropdown.Item eventKey="This Year">This Year</Dropdown.Item>
-            <Dropdown.Item eventKey="All">All</Dropdown.Item>
-          </DropdownButton>
-          <DropdownButton
-            data-testid="sort-dropdown"
-            className={`border-1 `}
-            title={
-              <>
-                <img
-                  src="/images/svg/up-down.svg"
-                  width={20}
-                  height={20}
-                  alt="Sort"
-                  className={styles.sortImg}
-                />
-                <span className="ms-2">Sort</span>
-              </>
-            }
-            onSelect={
-              /*istanbul ignore next*/
-              (eventKey) => setSortOrder(eventKey as 'ascending' | 'descending')
+          <SortingButton
+            title="Filter"
+            sortingOptions={[
+              {
+                label: FilterPeriod.ThisMonth,
+                value: FilterPeriod.ThisMonth,
+              },
+              { label: FilterPeriod.ThisYear, value: FilterPeriod.ThisYear },
+              { label: FilterPeriod.All, value: 'Filter: All' },
+            ]}
+            selectedOption={filteringBy}
+            onSortChange={(value) => setFilteringBy(value as FilterPeriod)}
+            dataTestIdPrefix="filter-dropdown"
+            className={`${styles.dropdown} mx-4`}
+            buttonLabel="Filter"
+          />
+          <SortingButton
+            title="Sort"
+            sortingOptions={[
+              { label: 'Ascending', value: 'ascending' },
+              { label: 'Descending', value: 'descending' },
+            ]}
+            selectedOption={sortOrder}
+            onSortChange={(value) =>
+              setSortOrder(value as 'ascending' | 'descending')
             }
-          >
-            <Dropdown.Item eventKey="ascending">Ascending</Dropdown.Item>
-            <Dropdown.Item eventKey="descending">Descending</Dropdown.Item>
-          </DropdownButton>
+            dataTestIdPrefix="sort-dropdown"
+            buttonLabel="Sort"
+          />
         </div>
       </div>
-      {/* <h3>{totalMembers}</h3> */}
       <TableContainer component={Paper} className="mt-3">
         <Table aria-label={t('event_attendance_table')} role="grid">
           <TableHead>
diff --git a/src/components/EventStats/Statistics/AverageRating.tsx b/src/components/EventStats/Statistics/AverageRating.tsx
index 9f1a157e01..f2e22338ec 100644
--- a/src/components/EventStats/Statistics/AverageRating.tsx
+++ b/src/components/EventStats/Statistics/AverageRating.tsx
@@ -4,7 +4,7 @@ import Rating from '@mui/material/Rating';
 import FavoriteIcon from '@mui/icons-material/Favorite';
 import FavoriteBorderIcon from '@mui/icons-material/FavoriteBorder';
 import Typography from '@mui/material/Typography';
-
+import styles from '../../../style/app.module.css';
 // Props for the AverageRating component
 type ModalPropType = {
   data: {
@@ -33,7 +33,7 @@ type FeedbackType = {
 export const AverageRating = ({ data }: ModalPropType): JSX.Element => {
   return (
     <>
-      <Card style={{ width: '300px' }}>
+      <Card className={styles.cardContainer}>
         <Card.Body>
           <Card.Title>
             <h4>Average Review Score</h4>
@@ -50,13 +50,9 @@ export const AverageRating = ({ data }: ModalPropType): JSX.Element => {
             icon={<FavoriteIcon fontSize="inherit" />}
             size="medium"
             emptyIcon={<FavoriteBorderIcon fontSize="inherit" />}
-            sx={{
-              '& .MuiRating-iconFilled': {
-                color: '#ff6d75', // Color for filled stars
-              },
-              '& .MuiRating-iconHover': {
-                color: '#ff3d47', // Color for star on hover
-              },
+            classes={{
+              iconFilled: styles.ratingFilled,
+              iconHover: styles.ratingHover,
             }}
           />
         </Card.Body>
diff --git a/src/components/LeftDrawer/LeftDrawer.tsx b/src/components/LeftDrawer/LeftDrawer.tsx
index eabf9722f8..1ef8192ae1 100644
--- a/src/components/LeftDrawer/LeftDrawer.tsx
+++ b/src/components/LeftDrawer/LeftDrawer.tsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useEffect } from 'react';
 import Button from 'react-bootstrap/Button';
 import { useTranslation } from 'react-i18next';
 import { NavLink } from 'react-router-dom';
@@ -31,6 +31,12 @@ const leftDrawer = ({
   const { getItem } = useLocalStorage();
   const superAdmin = getItem('SuperAdmin');
 
+  useEffect(() => {
+    if (hideDrawer === null) {
+      setHideDrawer(false);
+    }
+  }, []);
+
   /**
    * Handles link click to hide the drawer on smaller screens.
    */
diff --git a/src/components/OrgListCard/OrgListCard.tsx b/src/components/OrgListCard/OrgListCard.tsx
index 10365d2364..cf651e9dfe 100644
--- a/src/components/OrgListCard/OrgListCard.tsx
+++ b/src/components/OrgListCard/OrgListCard.tsx
@@ -1,4 +1,6 @@
 import React from 'react';
+import TruncatedText from './TruncatedText';
+// import {useState} from 'react';
 import FlaskIcon from 'assets/svgs/flask.svg?react';
 import Button from 'react-bootstrap/Button';
 import { useTranslation } from 'react-i18next';
@@ -94,17 +96,18 @@ function orgListCard(props: InterfaceOrgListCardProps): JSX.Element {
               <h4 className={`${styles.orgName} fw-semibold`}>{name}</h4>
             </Tooltip>
             {/* Description of the organization */}
-            <h6 className={`${styles.orgdesc} fw-semibold`}>
-              <span>{userData?.organizations[0].description}</span>
-            </h6>
+            <div className={`${styles.orgdesc} fw-semibold`}>
+              <TruncatedText
+                text={userData?.organizations[0]?.description || ''}
+              />
+            </div>
+
             {/* Display the organization address if available */}
-            {address && address.city && (
+            {address?.city && (
               <div className={styles.address}>
-                <h6 className="text-secondary">
-                  <span className="address-line">{address.line1}, </span>
-                  <span className="address-line">{address.city}, </span>
-                  <span className="address-line">{address.countryCode}</span>
-                </h6>
+                <TruncatedText
+                  text={`${address?.line1}, ${address?.city}, ${address?.countryCode}`}
+                />
               </div>
             )}
             {/* Display the number of admins and members */}
diff --git a/src/components/OrgListCard/TruncatedText.tsx b/src/components/OrgListCard/TruncatedText.tsx
new file mode 100644
index 0000000000..94617178cb
--- /dev/null
+++ b/src/components/OrgListCard/TruncatedText.tsx
@@ -0,0 +1,80 @@
+import React, { useState, useEffect, useRef } from 'react';
+import useDebounce from './useDebounce';
+
+/**
+ * Props for the `TruncatedText` component.
+ *
+ * Includes the text to be displayed and an optional maximum width override.
+ */
+interface InterfaceTruncatedTextProps {
+  /** The full text to display. It may be truncated if it exceeds the maximum width. */
+  text: string;
+  /** Optional: Override the maximum width for truncation. */
+  maxWidthOverride?: number;
+}
+
+/**
+ * A React functional component that displays text and truncates it with an ellipsis (`...`)
+ * if the text exceeds the available width or the `maxWidthOverride` value.
+ *
+ * The component adjusts the truncation dynamically based on the available space
+ * or the `maxWidthOverride` value. It also listens for window resize events to reapply truncation.
+ *
+ * @param props - The props for the component.
+ * @returns A heading element (`<h6>`) containing the truncated or full text.
+ *
+ * @example
+ * ```tsx
+ * <TruncatedText text="This is a very long text" maxWidthOverride={150} />
+ * ```
+ */
+const TruncatedText: React.FC<InterfaceTruncatedTextProps> = ({
+  text,
+  maxWidthOverride,
+}) => {
+  const [truncatedText, setTruncatedText] = useState<string>('');
+  const textRef = useRef<HTMLHeadingElement>(null);
+
+  const { debouncedCallback, cancel } = useDebounce(() => {
+    truncateText();
+  }, 100);
+
+  /**
+   * Truncate the text based on the available width or the `maxWidthOverride` value.
+   */
+  const truncateText = (): void => {
+    const element = textRef.current;
+    if (element) {
+      const maxWidth = maxWidthOverride || element.offsetWidth;
+      const fullText = text;
+
+      const computedStyle = getComputedStyle(element);
+      const fontSize = parseFloat(computedStyle.fontSize);
+      const charPerPx = 0.065 + fontSize * 0.002;
+      const maxChars = Math.floor(maxWidth * charPerPx);
+
+      setTruncatedText(
+        fullText.length > maxChars
+          ? `${fullText.slice(0, maxChars - 3)}...`
+          : fullText,
+      );
+    }
+  };
+
+  useEffect(() => {
+    truncateText();
+    window.addEventListener('resize', debouncedCallback);
+    return () => {
+      cancel();
+      window.removeEventListener('resize', debouncedCallback);
+    };
+  }, [text, maxWidthOverride, debouncedCallback, cancel]);
+
+  return (
+    <h6 ref={textRef} className="text-secondary">
+      {truncatedText}
+    </h6>
+  );
+};
+
+export default TruncatedText;
diff --git a/src/components/OrgListCard/useDebounce.tsx b/src/components/OrgListCard/useDebounce.tsx
new file mode 100644
index 0000000000..8ad30386e0
--- /dev/null
+++ b/src/components/OrgListCard/useDebounce.tsx
@@ -0,0 +1,42 @@
+import { useRef, useCallback } from 'react';
+
+/**
+ * A custom React hook for debouncing a callback function.
+ * It delays the execution of the callback until after a specified delay has elapsed
+ * since the last time the debounced function was invoked.
+ *
+ * @param callback - The function to debounce.
+ * @param delay - The delay in milliseconds to wait before invoking the callback.
+ * @returns An object with the `debouncedCallback` function and a `cancel` method to clear the timeout.
+ */
+function useDebounce<T extends (...args: unknown[]) => void>(
+  callback: T,
+  delay: number,
+): { debouncedCallback: (...args: Parameters<T>) => void; cancel: () => void } {
+  const timeoutRef = useRef<number | undefined>();
+
+  /**
+   * The debounced version of the provided callback function.
+   * This function resets the debounce timer on each call, ensuring the callback
+   * is invoked only after the specified delay has elapsed without further calls.
+   *
+   * @param args - The arguments to pass to the callback when invoked.
+   */
+  const debouncedCallback = useCallback(
+    (...args: Parameters<T>) => {
+      if (timeoutRef.current) clearTimeout(timeoutRef.current);
+      timeoutRef.current = window.setTimeout(() => {
+        callback(...args);
+      }, delay);
+    },
+    [callback, delay],
+  );
+
+  const cancel = useCallback(() => {
+    if (timeoutRef.current) clearTimeout(timeoutRef.current);
+  }, []);
+
+  return { debouncedCallback, cancel };
+}
+
+export default useDebounce;
diff --git a/src/components/OrgPeopleListCard/OrgPeopleListCard.spec.tsx b/src/components/OrgPeopleListCard/OrgPeopleListCard.spec.tsx
index 3023c82319..485ad1ae11 100644
--- a/src/components/OrgPeopleListCard/OrgPeopleListCard.spec.tsx
+++ b/src/components/OrgPeopleListCard/OrgPeopleListCard.spec.tsx
@@ -83,6 +83,45 @@ describe('Testing Organization People List Card', () => {
     });
   });
 
+  const NULL_DATA_MOCKS = [
+    {
+      request: {
+        query: REMOVE_MEMBER_MUTATION,
+        variables: {
+          userid: '1',
+          orgid: '456',
+        },
+      },
+      result: {
+        data: null,
+      },
+    },
+  ];
+
+  test('should handle null data response from mutation', async () => {
+    const link = new StaticMockLink(NULL_DATA_MOCKS, true);
+
+    render(
+      <MockedProvider addTypename={false} link={link}>
+        <BrowserRouter>
+          <I18nextProvider i18n={i18nForTest}>
+            <OrgPeopleListCard {...props} />
+          </I18nextProvider>
+        </BrowserRouter>
+      </MockedProvider>,
+    );
+
+    // Click remove button
+    const removeButton = screen.getByTestId('removeMemberBtn');
+    await userEvent.click(removeButton);
+
+    // Verify that success toast and toggleRemoveModal were not called
+    await waitFor(() => {
+      expect(toast.success).not.toHaveBeenCalled();
+      expect(props.toggleRemoveModal).not.toHaveBeenCalled();
+    });
+  });
+
   test('should render modal and handle successful member removal', async () => {
     const link = new StaticMockLink(MOCKS, true);
 
@@ -123,14 +162,7 @@ describe('Testing Organization People List Card', () => {
     await waitFor(
       () => {
         expect(toast.success).toHaveBeenCalled();
-      },
-      { timeout: 3000 },
-    );
-
-    // Check if page reload is triggered after delay
-    await waitFor(
-      () => {
-        expect(window.location.reload).toHaveBeenCalled();
+        expect(props.toggleRemoveModal).toHaveBeenCalled();
       },
       { timeout: 3000 },
     );
diff --git a/src/components/OrgPeopleListCard/OrgPeopleListCard.tsx b/src/components/OrgPeopleListCard/OrgPeopleListCard.tsx
index 8a028227f1..e7171bff71 100644
--- a/src/components/OrgPeopleListCard/OrgPeopleListCard.tsx
+++ b/src/components/OrgPeopleListCard/OrgPeopleListCard.tsx
@@ -55,12 +55,9 @@ function orgPeopleListCard(
           orgid: currentUrl,
         },
       });
-      // If the mutation is successful, show a success message and reload the page
       if (data) {
         toast.success(t('memberRemoved') as string);
-        setTimeout(() => {
-          window.location.reload();
-        }, 2000);
+        props.toggleRemoveModal();
       }
     } catch (error: unknown) {
       errorHandler(t, error);
diff --git a/src/components/OrgSettings/ActionItemCategories/OrgActionItemCategories.spec.tsx b/src/components/OrgSettings/ActionItemCategories/OrgActionItemCategories.spec.tsx
index 27eec94851..90c2a105ce 100644
--- a/src/components/OrgSettings/ActionItemCategories/OrgActionItemCategories.spec.tsx
+++ b/src/components/OrgSettings/ActionItemCategories/OrgActionItemCategories.spec.tsx
@@ -125,9 +125,9 @@ describe('Testing Organisation Action Item Categories', () => {
     // Filter by All
     fireEvent.click(filterBtn);
     await waitFor(() => {
-      expect(screen.getByTestId('statusAll')).toBeInTheDocument();
+      expect(screen.getByTestId('all')).toBeInTheDocument();
     });
-    fireEvent.click(screen.getByTestId('statusAll'));
+    fireEvent.click(screen.getByTestId('all'));
 
     await waitFor(() => {
       expect(screen.getByText('Category 1')).toBeInTheDocument();
@@ -137,9 +137,9 @@ describe('Testing Organisation Action Item Categories', () => {
     // Filter by Disabled
     fireEvent.click(filterBtn);
     await waitFor(() => {
-      expect(screen.getByTestId('statusDisabled')).toBeInTheDocument();
+      expect(screen.getByTestId('disabled')).toBeInTheDocument();
     });
-    fireEvent.click(screen.getByTestId('statusDisabled'));
+    fireEvent.click(screen.getByTestId('disabled'));
     await waitFor(() => {
       expect(screen.queryByText('Category 1')).toBeNull();
       expect(screen.getByText('Category 2')).toBeInTheDocument();
@@ -154,9 +154,9 @@ describe('Testing Organisation Action Item Categories', () => {
 
     fireEvent.click(filterBtn);
     await waitFor(() => {
-      expect(screen.getByTestId('statusActive')).toBeInTheDocument();
+      expect(screen.getByTestId('active')).toBeInTheDocument();
     });
-    fireEvent.click(screen.getByTestId('statusActive'));
+    fireEvent.click(screen.getByTestId('active'));
     await waitFor(() => {
       expect(screen.getByText('Category 1')).toBeInTheDocument();
       expect(screen.queryByText('Category 2')).toBeNull();
diff --git a/src/components/OrgSettings/ActionItemCategories/OrgActionItemCategories.tsx b/src/components/OrgSettings/ActionItemCategories/OrgActionItemCategories.tsx
index 3f1001c88b..a1f31e6da1 100644
--- a/src/components/OrgSettings/ActionItemCategories/OrgActionItemCategories.tsx
+++ b/src/components/OrgSettings/ActionItemCategories/OrgActionItemCategories.tsx
@@ -1,6 +1,6 @@
 import type { FC } from 'react';
 import React, { useCallback, useEffect, useState } from 'react';
-import { Button, Dropdown, Form } from 'react-bootstrap';
+import { Button, Form } from 'react-bootstrap';
 import styles from '../../../style/app.module.css';
 import { useTranslation } from 'react-i18next';
 
@@ -8,13 +8,7 @@ import { useQuery } from '@apollo/client';
 import { ACTION_ITEM_CATEGORY_LIST } from 'GraphQl/Queries/Queries';
 import type { InterfaceActionItemCategoryInfo } from 'utils/interfaces';
 import Loader from 'components/Loader/Loader';
-import {
-  Circle,
-  Search,
-  Sort,
-  WarningAmberRounded,
-  FilterAltOutlined,
-} from '@mui/icons-material';
+import { Circle, Search, WarningAmberRounded } from '@mui/icons-material';
 import {
   DataGrid,
   type GridCellParams,
@@ -23,6 +17,7 @@ import {
 import dayjs from 'dayjs';
 import { Chip, Stack } from '@mui/material';
 import CategoryModal from './CategoryModal';
+import SortingButton from 'subComponents/SortingButton';
 
 enum ModalState {
   SAME = 'same',
@@ -311,63 +306,47 @@ const OrgActionItemCategories: FC<InterfaceActionItemCategoryProps> = ({
         </div>
         <div className="d-flex gap-4 mb-1">
           <div className="d-flex justify-space-between align-items-center gap-4">
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdown}
-                data-testid="sort"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSortBy('createdAt_DESC')}
-                  data-testid="createdAt_DESC"
-                >
-                  {tCommon('createdLatest')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('createdAt_ASC')}
-                  data-testid="createdAt_ASC"
-                >
-                  {tCommon('createdEarliest')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdown}
-                data-testid="filter"
-              >
-                <FilterAltOutlined className={'me-1'} />
-                {t('status')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setStatus(null)}
-                  data-testid="statusAll"
-                >
-                  {tCommon('all')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setStatus(CategoryStatus.Active)}
-                  data-testid="statusActive"
-                >
-                  {tCommon('active')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setStatus(CategoryStatus.Disabled)}
-                  data-testid="statusDisabled"
-                >
-                  {tCommon('disabled')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              title={tCommon('sort')}
+              sortingOptions={[
+                { label: tCommon('createdLatest'), value: 'createdAt_DESC' },
+                { label: tCommon('createdEarliest'), value: 'createdAt_ASC' },
+              ]}
+              selectedOption={
+                sortBy === 'createdAt_DESC'
+                  ? tCommon('createdLatest')
+                  : tCommon('createdEarliest')
+              }
+              onSortChange={(value) =>
+                setSortBy(value as 'createdAt_DESC' | 'createdAt_ASC')
+              }
+              dataTestIdPrefix="sort"
+              buttonLabel={tCommon('sort')}
+              className={styles.dropdown}
+            />
+            <SortingButton
+              title={t('status')}
+              sortingOptions={[
+                { label: tCommon('all'), value: 'all' },
+                { label: tCommon('active'), value: CategoryStatus.Active },
+                { label: tCommon('disabled'), value: CategoryStatus.Disabled },
+              ]}
+              selectedOption={
+                status === null
+                  ? tCommon('all')
+                  : status === CategoryStatus.Active
+                    ? tCommon('active')
+                    : tCommon('disabled')
+              }
+              onSortChange={(value) =>
+                setStatus(value === 'all' ? null : (value as CategoryStatus))
+              }
+              dataTestIdPrefix="filter"
+              buttonLabel={t('status')}
+              className={styles.dropdown}
+            />
           </div>
+
           <div>
             <Button
               variant="success"
diff --git a/src/components/RequestsTableItem/RequestsTableItem.spec.tsx b/src/components/RequestsTableItem/RequestsTableItem.spec.tsx
index b5194fcdce..737b0fa926 100644
--- a/src/components/RequestsTableItem/RequestsTableItem.spec.tsx
+++ b/src/components/RequestsTableItem/RequestsTableItem.spec.tsx
@@ -12,7 +12,6 @@ const link = new StaticMockLink(MOCKS, true);
 import useLocalStorage from 'utils/useLocalstorage';
 import userEvent from '@testing-library/user-event';
 import { vi } from 'vitest';
-
 const { setItem } = useLocalStorage();
 
 async function wait(ms = 100): Promise<void> {
@@ -23,7 +22,6 @@ async function wait(ms = 100): Promise<void> {
   });
 }
 const resetAndRefetchMock = vi.fn();
-
 vi.mock('react-toastify', () => ({
   toast: {
     success: vi.fn(),
diff --git a/src/components/RequestsTableItem/RequestsTableItem.tsx b/src/components/RequestsTableItem/RequestsTableItem.tsx
index 07feb5d289..cd688a2966 100644
--- a/src/components/RequestsTableItem/RequestsTableItem.tsx
+++ b/src/components/RequestsTableItem/RequestsTableItem.tsx
@@ -65,13 +65,11 @@ const RequestsTableItem = (props: Props): JSX.Element => {
           id: membershipRequestId,
         },
       });
-      /* istanbul ignore next */
       if (data) {
         toast.success(t('acceptedSuccessfully') as string);
         resetAndRefetch();
       }
     } catch (error: unknown) {
-      /* istanbul ignore next */
       errorHandler(t, error);
     }
   };
@@ -93,13 +91,11 @@ const RequestsTableItem = (props: Props): JSX.Element => {
           id: membershipRequestId,
         },
       });
-      /* istanbul ignore next */
       if (data) {
         toast.success(t('rejectedSuccessfully') as string);
         resetAndRefetch();
       }
     } catch (error: unknown) {
-      /* istanbul ignore next */
       errorHandler(t, error);
     }
   };
diff --git a/src/components/UsersTableItem/UsersTableItem.tsx b/src/components/UsersTableItem/UsersTableItem.tsx
index 9e94b8a9f5..6da3c1d6f4 100644
--- a/src/components/UsersTableItem/UsersTableItem.tsx
+++ b/src/components/UsersTableItem/UsersTableItem.tsx
@@ -161,6 +161,7 @@ const UsersTableItem = (props: Props): JSX.Element => {
         <td>{user.user.email}</td>
         <td>
           <Button
+            className="btn btn-success"
             onClick={() => setShowJoinedOrganizations(true)}
             data-testid={`showJoinedOrgsBtn${user.user._id}`}
           >
diff --git a/src/components/Venues/VenueModal.spec.tsx b/src/components/Venues/VenueModal.spec.tsx
index 45560c40cb..c840b6de53 100644
--- a/src/components/Venues/VenueModal.spec.tsx
+++ b/src/components/Venues/VenueModal.spec.tsx
@@ -292,3 +292,88 @@ describe('VenueModal', () => {
     );
   });
 });
+
+describe('VenueModal with error scenarios', () => {
+  test('displays error toast when creating a venue fails', async () => {
+    const errorMocks = [
+      {
+        request: {
+          query: CREATE_VENUE_MUTATION,
+          variables: {
+            name: 'Error Venue',
+            description: 'This should fail',
+            capacity: 50,
+            organizationId: 'orgId',
+            file: '',
+          },
+        },
+        error: new Error('Failed to create venue'),
+      },
+    ];
+
+    const errorLink = new StaticMockLink(errorMocks, true);
+    renderVenueModal(props[0], errorLink);
+
+    const nameInput = screen.getByPlaceholderText('Enter Venue Name');
+    fireEvent.change(nameInput, { target: { value: 'Error Venue' } });
+
+    const descriptionInput = screen.getByPlaceholderText(
+      'Enter Venue Description',
+    );
+    fireEvent.change(descriptionInput, {
+      target: { value: 'This should fail' },
+    });
+
+    const capacityInput = screen.getByPlaceholderText('Enter Venue Capacity');
+    fireEvent.change(capacityInput, { target: { value: 50 } });
+
+    const submitButton = screen.getByTestId('createVenueBtn');
+    fireEvent.click(submitButton);
+
+    await wait();
+
+    expect(toast.error).toHaveBeenCalledWith('Failed to create venue');
+  });
+
+  test('displays error toast when updating a venue fails', async () => {
+    const errorMocks = [
+      {
+        request: {
+          query: UPDATE_VENUE_MUTATION,
+          variables: {
+            capacity: 150,
+            description: 'Failed update description',
+            file: 'image1',
+            id: 'venue1',
+            name: 'Failed Update Venue',
+            organizationId: 'orgId',
+          },
+        },
+        error: new Error('Failed to update venue'),
+      },
+    ];
+
+    const errorLink = new StaticMockLink(errorMocks, true);
+    renderVenueModal(props[1], errorLink);
+
+    const nameInput = screen.getByDisplayValue('Venue 1');
+    fireEvent.change(nameInput, { target: { value: 'Failed Update Venue' } });
+
+    const descriptionInput = screen.getByDisplayValue(
+      'Updated description for venue 1',
+    );
+    fireEvent.change(descriptionInput, {
+      target: { value: 'Failed update description' },
+    });
+
+    const capacityInput = screen.getByDisplayValue('100');
+    fireEvent.change(capacityInput, { target: { value: 150 } });
+
+    const submitButton = screen.getByTestId('updateVenueBtn');
+    fireEvent.click(submitButton);
+
+    await wait();
+
+    expect(toast.error).toHaveBeenCalledWith('Failed to update venue');
+  });
+});
diff --git a/src/components/Venues/VenueModal.tsx b/src/components/Venues/VenueModal.tsx
index 0e3ab48466..73aa0e49c5 100644
--- a/src/components/Venues/VenueModal.tsx
+++ b/src/components/Venues/VenueModal.tsx
@@ -98,7 +98,6 @@ const VenueModal = ({
           ...(edit && { id: venueData?._id }),
         },
       });
-      /* istanbul ignore next */
       if (data) {
         toast.success(
           edit ? (t('venueUpdated') as string) : (t('venueAdded') as string),
@@ -114,7 +113,6 @@ const VenueModal = ({
         setVenueImage(false);
       }
     } catch (error) {
-      /* istanbul ignore next */
       errorHandler(t, error);
     }
   }, [
@@ -136,7 +134,6 @@ const VenueModal = ({
   const clearImageInput = useCallback(() => {
     setFormState((prevState) => ({ ...prevState, imageURL: '' }));
     setVenueImage(false);
-    /* istanbul ignore next */
     if (fileInputRef.current) {
       fileInputRef.current.value = '';
     }
@@ -236,7 +233,6 @@ const VenueModal = ({
               }));
               setVenueImage(true);
               const file = e.target.files?.[0];
-              /* istanbul ignore next */
               if (file) {
                 setFormState({
                   ...formState,
diff --git a/src/screens/BlockUser/BlockUser.spec.tsx b/src/screens/BlockUser/BlockUser.spec.tsx
index dff4ec955e..6f787ce71d 100644
--- a/src/screens/BlockUser/BlockUser.spec.tsx
+++ b/src/screens/BlockUser/BlockUser.spec.tsx
@@ -353,7 +353,7 @@ describe('Testing Block/Unblock user screen', () => {
     );
 
     userEvent.click(screen.getByTestId('userFilter'));
-    userEvent.click(screen.getByTestId('showMembers'));
+    userEvent.click(screen.getByTestId('allMembers'));
     await wait();
 
     expect(screen.getByTestId('unBlockUser123')).toBeInTheDocument();
@@ -383,7 +383,7 @@ describe('Testing Block/Unblock user screen', () => {
       </MockedProvider>,
     );
     userEvent.click(screen.getByTestId('userFilter'));
-    userEvent.click(screen.getByTestId('showMembers'));
+    userEvent.click(screen.getByTestId('allMembers'));
 
     await wait();
 
@@ -415,14 +415,14 @@ describe('Testing Block/Unblock user screen', () => {
     );
 
     userEvent.click(screen.getByTestId('userFilter'));
-    userEvent.click(screen.getByTestId('showBlockedMembers'));
+    userEvent.click(screen.getByTestId('blockedUsers'));
     await wait();
 
     expect(screen.getByText('John Doe')).toBeInTheDocument();
     expect(screen.queryByText('Sam Smith')).not.toBeInTheDocument();
 
     userEvent.click(screen.getByTestId('userFilter'));
-    userEvent.click(screen.getByTestId('showMembers'));
+    userEvent.click(screen.getByTestId('allMembers'));
     await wait();
 
     expect(screen.getByText('John Doe')).toBeInTheDocument();
@@ -459,7 +459,7 @@ describe('Testing Block/Unblock user screen', () => {
     );
 
     userEvent.click(screen.getByTestId('userFilter'));
-    userEvent.click(screen.getByTestId('showMembers'));
+    userEvent.click(screen.getByTestId('allMembers'));
     await wait();
 
     expect(screen.getByText('John Doe')).toBeInTheDocument();
@@ -508,7 +508,7 @@ describe('Testing Block/Unblock user screen', () => {
     );
 
     userEvent.click(screen.getByTestId('userFilter'));
-    userEvent.click(screen.getByTestId('showMembers'));
+    userEvent.click(screen.getByTestId('allMembers'));
     await wait();
 
     userEvent.click(screen.getByTestId('blockUser456'));
diff --git a/src/screens/BlockUser/BlockUser.tsx b/src/screens/BlockUser/BlockUser.tsx
index ddea104662..b7bee8fbfa 100644
--- a/src/screens/BlockUser/BlockUser.tsx
+++ b/src/screens/BlockUser/BlockUser.tsx
@@ -1,11 +1,10 @@
 import { useMutation, useQuery } from '@apollo/client';
 import React, { useEffect, useState, useCallback } from 'react';
-import { Dropdown, Form, Table } from 'react-bootstrap';
+import { Form, Table } from 'react-bootstrap';
 import Button from 'react-bootstrap/Button';
 import { toast } from 'react-toastify';
 
 import { Search } from '@mui/icons-material';
-import SortIcon from '@mui/icons-material/Sort';
 import {
   BLOCK_USER_MUTATION,
   UNBLOCK_USER_MUTATION,
@@ -16,6 +15,7 @@ import { useTranslation } from 'react-i18next';
 import { errorHandler } from 'utils/errorHandler';
 import styles from '../../style/app.module.css';
 import { useParams } from 'react-router-dom';
+import SortingButton from 'subComponents/SortingButton';
 
 interface InterfaceMember {
   _id: string;
@@ -216,66 +216,39 @@ const Requests = (): JSX.Element => {
           </div>
           <div className={styles.btnsBlockBlockAndUnblock}>
             <div className={styles.largeBtnsWrapper}>
-              {/* Dropdown for filtering members */}
-              <Dropdown aria-expanded="false" title="Sort organizations">
-                <Dropdown.Toggle
-                  variant="success"
-                  data-testid="userFilter"
-                  className={`${styles.createButton} mt-2`}
-                >
-                  <SortIcon className={'me-1'} />
-                  {showBlockedMembers ? t('blockedUsers') : t('allMembers')}
-                </Dropdown.Toggle>
-                <Dropdown.Menu>
-                  <Dropdown.Item
-                    active={!showBlockedMembers}
-                    className={styles.dropdownItem}
-                    data-testid="showMembers"
-                    onClick={(): void => setShowBlockedMembers(false)}
-                  >
-                    {t('allMembers')}
-                  </Dropdown.Item>
-                  <Dropdown.Item
-                    active={showBlockedMembers}
-                    className={styles.dropdownItem}
-                    data-testid="showBlockedMembers"
-                    onClick={(): void => setShowBlockedMembers(true)}
-                  >
-                    {t('blockedUsers')}
-                  </Dropdown.Item>
-                </Dropdown.Menu>
-              </Dropdown>
-              {/* Dropdown for sorting by name */}
-              <Dropdown aria-expanded="false">
-                <Dropdown.Toggle
-                  variant="success"
-                  data-testid="nameFilter"
-                  className={`${styles.createButton} mt-2`}
-                >
-                  <SortIcon className={'me-1'} />
-                  {searchByFirstName
+              <SortingButton
+                title={t('sortOrganizations')}
+                sortingOptions={[
+                  { label: t('allMembers'), value: 'allMembers' },
+                  { label: t('blockedUsers'), value: 'blockedUsers' },
+                ]}
+                selectedOption={
+                  showBlockedMembers ? t('blockedUsers') : t('allMembers')
+                }
+                onSortChange={(value) =>
+                  setShowBlockedMembers(value === 'blockedUsers')
+                }
+                dataTestIdPrefix="userFilter"
+                className={`${styles.createButton} mt-2`}
+              />
+
+              <SortingButton
+                title={t('sortByName')}
+                sortingOptions={[
+                  { label: t('searchByFirstName'), value: 'searchByFirstName' },
+                  { label: t('searchByLastName'), value: 'searchByLastName' },
+                ]}
+                selectedOption={
+                  searchByFirstName
                     ? t('searchByFirstName')
-                    : t('searchByLastName')}
-                </Dropdown.Toggle>
-                <Dropdown.Menu>
-                  <Dropdown.Item
-                    active={searchByFirstName}
-                    data-testid="searchByFirstName"
-                    className={styles.dropdownItem}
-                    onClick={(): void => setSearchByFirstName(true)}
-                  >
-                    {t('searchByFirstName')}
-                  </Dropdown.Item>
-                  <Dropdown.Item
-                    active={!searchByFirstName}
-                    className={styles.dropdownItem}
-                    data-testid="searchByLastName"
-                    onClick={(): void => setSearchByFirstName(false)}
-                  >
-                    {t('searchByLastName')}
-                  </Dropdown.Item>
-                </Dropdown.Menu>
-              </Dropdown>
+                    : t('searchByLastName')
+                }
+                onSortChange={(value) =>
+                  setSearchByFirstName(value === 'searchByFirstName')
+                }
+                dataTestIdPrefix="nameFilter"
+                className={`${styles.createButton} mt-2`}
+              />
             </div>
           </div>
         </div>
diff --git a/src/screens/EventManagement/EventManagement.spec.tsx b/src/screens/EventManagement/EventManagement.spec.tsx
new file mode 100644
index 0000000000..49b50e4b36
--- /dev/null
+++ b/src/screens/EventManagement/EventManagement.spec.tsx
@@ -0,0 +1,253 @@
+import React, { act } from 'react';
+import type { RenderResult } from '@testing-library/react';
+import { render, screen, waitFor } from '@testing-library/react';
+import { MockedProvider } from '@apollo/react-testing';
+import { I18nextProvider } from 'react-i18next';
+import i18nForTest from 'utils/i18nForTest';
+import { MemoryRouter, Route, Routes, useParams } from 'react-router-dom';
+import { Provider } from 'react-redux';
+import { store } from 'state/store';
+import EventManagement from './EventManagement';
+import userEvent from '@testing-library/user-event';
+import { StaticMockLink } from 'utils/StaticMockLink';
+import { MOCKS_WITH_TIME } from 'components/EventManagement/Dashboard/EventDashboard.mocks';
+import useLocalStorage from 'utils/useLocalstorage';
+import { vi } from 'vitest';
+const { setItem } = useLocalStorage();
+
+const mockWithTime = new StaticMockLink(MOCKS_WITH_TIME, true);
+
+const renderEventManagement = (): RenderResult => {
+  return render(
+    <MockedProvider
+      addTypename={false}
+      link={mockWithTime}
+      mocks={MOCKS_WITH_TIME}
+    >
+      <MemoryRouter initialEntries={['/event/orgId/eventId']}>
+        <Provider store={store}>
+          <I18nextProvider i18n={i18nForTest}>
+            <Routes>
+              <Route
+                path="/event/:orgId/:eventId"
+                element={<EventManagement />}
+              />
+              <Route
+                path="/orglist"
+                element={<div data-testid="paramsError">paramsError</div>}
+              />
+              <Route
+                path="/orgevents/:orgId"
+                element={<div data-testid="eventsScreen">eventsScreen</div>}
+              />
+              <Route
+                path="/user/events/:orgId"
+                element={
+                  <div data-testid="userEventsScreen">userEventsScreen</div>
+                }
+              />
+            </Routes>
+          </I18nextProvider>
+        </Provider>
+      </MemoryRouter>
+    </MockedProvider>,
+  );
+};
+
+describe('Event Management', () => {
+  beforeAll(() => {
+    vi.mock('react-router-dom', async () => {
+      const actual = await vi.importActual('react-router-dom');
+      return {
+        ...actual,
+        useParams: vi.fn(),
+      };
+    });
+  });
+
+  afterEach(() => {
+    vi.clearAllMocks();
+    localStorage.clear();
+  });
+
+  describe('Navigation Tests', () => {
+    beforeEach(() => {
+      vi.mocked(useParams).mockReturnValue({
+        orgId: 'orgId',
+        eventId: 'eventId',
+      });
+    });
+
+    it('Testing back button navigation when userType is SuperAdmin', async () => {
+      setItem('SuperAdmin', true);
+      renderEventManagement();
+
+      const backButton = screen.getByTestId('backBtn');
+      userEvent.click(backButton);
+      await waitFor(() => {
+        const eventsScreen = screen.getByTestId('eventsScreen');
+        expect(eventsScreen).toBeInTheDocument();
+      });
+    });
+
+    it('Testing back button navigation when userType is USER', async () => {
+      setItem('SuperAdmin', false);
+      setItem('AdminFor', []);
+
+      renderEventManagement();
+
+      const backButton = screen.getByTestId('backBtn');
+      userEvent.click(backButton);
+
+      await waitFor(() => {
+        const userEventsScreen = screen.getByTestId('userEventsScreen');
+        expect(userEventsScreen).toBeInTheDocument();
+      });
+    });
+
+    it('Testing back button navigation when userType is ADMIN', async () => {
+      setItem('SuperAdmin', false);
+      setItem('AdminFor', ['someOrg']);
+
+      renderEventManagement();
+
+      const backButton = screen.getByTestId('backBtn');
+      userEvent.click(backButton);
+
+      await waitFor(() => {
+        const eventsScreen = screen.getByTestId('eventsScreen');
+        expect(eventsScreen).toBeInTheDocument();
+      });
+    });
+    it('redirects to orglist when params are missing', async () => {
+      vi.mocked(useParams).mockReturnValue({});
+
+      renderEventManagement();
+
+      await waitFor(() => {
+        const paramsError = screen.getByTestId('paramsError');
+        expect(paramsError).toBeInTheDocument();
+      });
+    });
+  });
+
+  describe('Tab Management Tests', () => {
+    beforeEach(() => {
+      vi.mocked(useParams).mockReturnValue({
+        orgId: 'orgId',
+        eventId: 'event123',
+      });
+    });
+
+    it('renders dashboard tab by default', async () => {
+      renderEventManagement();
+      expect(screen.getByTestId('eventDashboardTab')).toBeInTheDocument();
+    });
+
+    it('switches between all available tabs', async () => {
+      renderEventManagement();
+
+      const tabsToTest = [
+        { button: 'registrantsBtn', tab: 'eventRegistrantsTab' },
+        { button: 'attendanceBtn', tab: 'eventAttendanceTab' },
+        { button: 'actionsBtn', tab: 'eventActionsTab' },
+        { button: 'agendasBtn', tab: 'eventAgendasTab' },
+        { button: 'statisticsBtn', tab: 'eventStatsTab' },
+        { button: 'volunteersBtn', tab: 'eventVolunteersTab' },
+      ];
+
+      for (const { button, tab } of tabsToTest) {
+        userEvent.click(screen.getByTestId(button));
+        expect(screen.getByTestId(tab)).toBeInTheDocument();
+      }
+    });
+
+    it('returns dashboard tab for an invalid tab selection', async () => {
+      const setTab = vi.fn();
+      const useStateSpy = vi.spyOn(React, 'useState');
+      useStateSpy.mockReturnValueOnce(['invalid', setTab]);
+      await act(async () => {
+        renderEventManagement();
+      });
+
+      expect(screen.queryByTestId('eventDashboardTab')).toBeInTheDocument();
+      expect(
+        screen.queryByTestId('eventRegistrantsTab'),
+      ).not.toBeInTheDocument();
+      expect(
+        screen.queryByTestId('eventAttendanceTab'),
+      ).not.toBeInTheDocument();
+      expect(screen.queryByTestId('eventActionsTab')).not.toBeInTheDocument();
+      expect(
+        screen.queryByTestId('eventVolunteersTab'),
+      ).not.toBeInTheDocument();
+      expect(screen.queryByTestId('eventAgendasTab')).not.toBeInTheDocument();
+      expect(screen.queryByTestId('eventStatsTab')).not.toBeInTheDocument();
+    });
+  });
+
+  describe('Responsive Dropdown Tests', () => {
+    beforeEach(() => {
+      vi.mocked(useParams).mockReturnValue({
+        orgId: 'orgId',
+        eventId: 'event123',
+      });
+    });
+
+    it('renders dropdown with all options', async () => {
+      await act(async () => {
+        renderEventManagement();
+      });
+
+      const dropdownContainer = screen.getByTestId('tabsDropdownContainer');
+      expect(dropdownContainer).toBeInTheDocument();
+
+      await act(async () => {
+        userEvent.click(screen.getByTestId('tabsDropdownToggle'));
+      });
+
+      const tabOptions = [
+        'dashboard',
+        'registrants',
+        'attendance',
+        'agendas',
+        'actions',
+        'volunteers',
+        'statistics',
+      ];
+
+      tabOptions.forEach((option) => {
+        expect(screen.getByTestId(`${option}DropdownItem`)).toBeInTheDocument();
+      });
+    });
+
+    it('switches tabs through dropdown selection', async () => {
+      await act(async () => {
+        renderEventManagement();
+      });
+      await act(async () => {
+        userEvent.click(screen.getByTestId('tabsDropdownToggle'));
+      });
+
+      const tabOptions = [
+        'dashboard',
+        'registrants',
+        'attendance',
+        'agendas',
+        'actions',
+        'volunteers',
+        'statistics',
+      ];
+
+      for (const option of tabOptions) {
+        act(() => {
+          userEvent.click(screen.getByTestId(`${option}DropdownItem`));
+        });
+
+        expect(screen.getByTestId(`${option}DropdownItem`)).toHaveClass(
+          'text-secondary',
+        );
+      }
+    });
+  });
+});
diff --git a/src/screens/EventManagement/EventManagement.test.tsx b/src/screens/EventManagement/EventManagement.test.tsx
deleted file mode 100644
index a119caad42..0000000000
--- a/src/screens/EventManagement/EventManagement.test.tsx
+++ /dev/null
@@ -1,143 +0,0 @@
-import React from 'react';
-import type { RenderResult } from '@testing-library/react';
-import { render, screen, waitFor } from '@testing-library/react';
-import { MockedProvider } from '@apollo/react-testing';
-import { I18nextProvider } from 'react-i18next';
-import i18nForTest from 'utils/i18nForTest';
-import { MemoryRouter, Route, Routes } from 'react-router-dom';
-import { Provider } from 'react-redux';
-import { store } from 'state/store';
-import EventManagement from './EventManagement';
-import userEvent from '@testing-library/user-event';
-import { StaticMockLink } from 'utils/StaticMockLink';
-import { MOCKS_WITH_TIME } from 'components/EventManagement/Dashboard/EventDashboard.mocks';
-import useLocalStorage from 'utils/useLocalstorage';
-const { setItem } = useLocalStorage();
-
-const mockWithTime = new StaticMockLink(MOCKS_WITH_TIME, true);
-
-const renderEventManagement = (): RenderResult => {
-  return render(
-    <MockedProvider addTypename={false} link={mockWithTime}>
-      <MemoryRouter initialEntries={['/event/orgId/eventId']}>
-        <Provider store={store}>
-          <I18nextProvider i18n={i18nForTest}>
-            <Routes>
-              <Route
-                path="/event/:orgId/:eventId"
-                element={<EventManagement />}
-              />
-              <Route
-                path="/orglist"
-                element={<div data-testid="paramsError">paramsError</div>}
-              />
-              <Route
-                path="/orgevents/:orgId"
-                element={<div data-testid="eventsScreen">eventsScreen</div>}
-              />
-              <Route
-                path="/user/events/:orgId"
-                element={
-                  <div data-testid="userEventsScreen">userEventsScreen</div>
-                }
-              />
-            </Routes>
-          </I18nextProvider>
-        </Provider>
-      </MemoryRouter>
-    </MockedProvider>,
-  );
-};
-
-describe('Event Management', () => {
-  beforeAll(() => {
-    jest.mock('react-router-dom', () => ({
-      ...jest.requireActual('react-router-dom'),
-      useParams: () => ({ orgId: 'orgId', eventId: 'eventId' }),
-    }));
-  });
-
-  afterAll(() => {
-    jest.clearAllMocks();
-  });
-
-  test('Testing back button navigation when userType is SuperAdmin', async () => {
-    setItem('SuperAdmin', true);
-    renderEventManagement();
-
-    const backButton = screen.getByTestId('backBtn');
-    userEvent.click(backButton);
-    await waitFor(() => {
-      const eventsScreen = screen.getByTestId('eventsScreen');
-      expect(eventsScreen).toBeInTheDocument();
-    });
-  });
-
-  test('Testing event management tab switching', async () => {
-    renderEventManagement();
-
-    const registrantsButton = screen.getByTestId('registrantsBtn');
-    userEvent.click(registrantsButton);
-
-    const registrantsTab = screen.getByTestId('eventRegistrantsTab');
-    expect(registrantsTab).toBeInTheDocument();
-    const eventAttendanceButton = screen.getByTestId('attendanceBtn');
-    userEvent.click(eventAttendanceButton);
-    const eventAttendanceTab = screen.getByTestId('eventAttendanceTab');
-    expect(eventAttendanceTab).toBeInTheDocument();
-    const eventActionsButton = screen.getByTestId('actionsBtn');
-    userEvent.click(eventActionsButton);
-
-    const eventActionsTab = screen.getByTestId('eventActionsTab');
-    expect(eventActionsTab).toBeInTheDocument();
-
-    const eventAgendasButton = screen.getByTestId('agendasBtn');
-    userEvent.click(eventAgendasButton);
-
-    const eventAgendasTab = screen.getByTestId('eventAgendasTab');
-    expect(eventAgendasTab).toBeInTheDocument();
-
-    const eventStatsButton = screen.getByTestId('statisticsBtn');
-    userEvent.click(eventStatsButton);
-
-    const eventStatsTab = screen.getByTestId('eventStatsTab');
-    expect(eventStatsTab).toBeInTheDocument();
-
-    const volunteerButton = screen.getByTestId('volunteersBtn');
-    userEvent.click(volunteerButton);
-
-    const eventVolunteersTab = screen.getByTestId('eventVolunteersTab');
-    expect(eventVolunteersTab).toBeInTheDocument();
-  });
-  test('renders nothing when invalid tab is selected', () => {
-    render(
-      <MockedProvider addTypename={false} link={mockWithTime}>
-        <MemoryRouter initialEntries={['/event/orgId/eventId']}>
-          <Provider store={store}>
-            <I18nextProvider i18n={i18nForTest}>
-              <Routes>
-                <Route
-                  path="/event/:orgId/:eventId"
-                  element={<EventManagement />}
-                />
-              </Routes>
-            </I18nextProvider>
-          </Provider>
-        </MemoryRouter>
-      </MockedProvider>,
-    );
-
-    // Force an invalid tab state
-    const setTab = jest.fn();
-    React.useState = jest.fn().mockReturnValue(['invalidTab', setTab]);
-
-    // Verify nothing is rendered
-    expect(screen.queryByTestId('eventDashboardTab')).toBeInTheDocument();
-    expect(screen.queryByTestId('eventRegistrantsTab')).not.toBeInTheDocument();
-    expect(screen.queryByTestId('eventAttendanceTab')).not.toBeInTheDocument();
-    expect(screen.queryByTestId('eventActionsTab')).not.toBeInTheDocument();
-    expect(screen.queryByTestId('eventVolunteersTab')).not.toBeInTheDocument();
-    expect(screen.queryByTestId('eventAgendasTab')).not.toBeInTheDocument();
-    expect(screen.queryByTestId('eventStatsTab')).not.toBeInTheDocument();
-  });
-});
diff --git a/src/screens/EventManagement/EventManagement.tsx b/src/screens/EventManagement/EventManagement.tsx
index e355ac1acc..21c23c5bb3 100644
--- a/src/screens/EventManagement/EventManagement.tsx
+++ b/src/screens/EventManagement/EventManagement.tsx
@@ -100,7 +100,6 @@ const EventManagement = (): JSX.Element => {
   // Determine user role based on local storage
   const superAdmin = getItem('SuperAdmin');
   const adminFor = getItem('AdminFor');
-  /*istanbul ignore next*/
   const userRole = superAdmin
     ? 'SUPERADMIN'
     : adminFor?.length > 0
@@ -109,7 +108,6 @@ const EventManagement = (): JSX.Element => {
 
   // Extract event and organization IDs from URL parameters
   const { eventId, orgId } = useParams();
-  /*istanbul ignore next*/
   if (!eventId || !orgId) {
     // Redirect if event ID or organization ID is missing
     return <Navigate to={'/orglist'} />;
@@ -159,7 +157,6 @@ const EventManagement = (): JSX.Element => {
   };
 
   const handleBack = (): void => {
-    /*istanbul ignore next*/
     if (userRole === 'USER') {
       navigate(`/user/events/${orgId}`);
     } else {
@@ -203,11 +200,9 @@ const EventManagement = (): JSX.Element => {
               {eventDashboardTabs.map(({ value, icon }, index) => (
                 <Dropdown.Item
                   key={index}
-                  onClick={
-                    /* istanbul ignore next */
-                    () => setTab(value)
-                  }
+                  onClick={() => setTab(value)}
                   className={`d-flex gap-2 ${tab === value ? 'text-secondary' : ''}`}
+                  data-testid={`${value}DropdownItem`}
                 >
                   {icon} {t(value)}
                 </Dropdown.Item>
@@ -272,10 +267,9 @@ const EventManagement = (): JSX.Element => {
                 <h2>Statistics</h2>
               </div>
             );
-          /*istanbul ignore next*/
-          default:
-            /*istanbul ignore next*/
-            return null;
+          // no use of default here as the default tab is the dashboard selected in useState code wont reach here
+          // default:
+          //   return null;
         }
       })()}
     </div>
diff --git a/src/screens/EventVolunteers/Requests/Requests.tsx b/src/screens/EventVolunteers/Requests/Requests.tsx
index b19be3d2a0..d8efd92a90 100644
--- a/src/screens/EventVolunteers/Requests/Requests.tsx
+++ b/src/screens/EventVolunteers/Requests/Requests.tsx
@@ -1,9 +1,9 @@
 import React, { useMemo, useState } from 'react';
 import { useTranslation } from 'react-i18next';
-import { Button, Dropdown, Form } from 'react-bootstrap';
+import { Button, Form } from 'react-bootstrap';
 import { Navigate, useParams } from 'react-router-dom';
 import { FaXmark } from 'react-icons/fa6';
-import { Search, Sort, WarningAmberRounded } from '@mui/icons-material';
+import { Search, WarningAmberRounded } from '@mui/icons-material';
 
 import { useMutation, useQuery } from '@apollo/client';
 import Loader from 'components/Loader/Loader';
@@ -20,6 +20,7 @@ import dayjs from 'dayjs';
 import { UPDATE_VOLUNTEER_MEMBERSHIP } from 'GraphQl/Mutations/EventVolunteerMutation';
 import { toast } from 'react-toastify';
 import { debounce } from '@mui/material';
+import SortingButton from 'subComponents/SortingButton';
 
 const dataGridStyle = {
   '&.MuiDataGrid-root .MuiDataGrid-cell:focus-within': {
@@ -279,30 +280,18 @@ function requests(): JSX.Element {
         </div>
         <div className="d-flex gap-3 mb-1">
           <div className="d-flex justify-space-between align-items-center gap-3">
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                className={styles.dropdowns}
-                data-testid="sort"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSortBy('createdAt_DESC')}
-                  data-testid="createdAt_DESC"
-                >
-                  {t('latest')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('createdAt_ASC')}
-                  data-testid="createdAt_ASC"
-                >
-                  {t('earliest')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              sortingOptions={[
+                { label: t('latest'), value: 'createdAt_DESC' },
+                { label: t('earliest'), value: 'createdAt_ASC' },
+              ]}
+              selectedOption={sortBy ?? ''}
+              onSortChange={(value) =>
+                setSortBy(value as 'createdAt_DESC' | 'createdAt_ASC')
+              }
+              dataTestIdPrefix="sort"
+              buttonLabel={tCommon('sort')}
+            />
           </div>
         </div>
       </div>
diff --git a/src/screens/EventVolunteers/VolunteerGroups/VolunteerGroups.tsx b/src/screens/EventVolunteers/VolunteerGroups/VolunteerGroups.tsx
index 3c70b1db49..b8577acaac 100644
--- a/src/screens/EventVolunteers/VolunteerGroups/VolunteerGroups.tsx
+++ b/src/screens/EventVolunteers/VolunteerGroups/VolunteerGroups.tsx
@@ -1,9 +1,9 @@
 import React, { useCallback, useMemo, useState } from 'react';
 import { useTranslation } from 'react-i18next';
-import { Button, Dropdown, Form } from 'react-bootstrap';
+import { Button, Form } from 'react-bootstrap';
 import { Navigate, useParams } from 'react-router-dom';
 
-import { Search, Sort, WarningAmberRounded } from '@mui/icons-material';
+import { Search, WarningAmberRounded } from '@mui/icons-material';
 
 import { useQuery } from '@apollo/client';
 
@@ -21,6 +21,7 @@ import { EVENT_VOLUNTEER_GROUP_LIST } from 'GraphQl/Queries/EventVolunteerQuerie
 import VolunteerGroupModal from './VolunteerGroupModal';
 import VolunteerGroupDeleteModal from './VolunteerGroupDeleteModal';
 import VolunteerGroupViewModal from './VolunteerGroupViewModal';
+import SortingButton from 'subComponents/SortingButton';
 
 enum ModalState {
   SAME = 'same',
@@ -321,56 +322,29 @@ function volunteerGroups(): JSX.Element {
         </div>
         <div className="d-flex gap-3 mb-1">
           <div className="d-flex justify-space-between align-items-center gap-3">
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdowns}
-                data-testid="searchByToggle"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('searchBy', { item: '' })}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSearchBy('leader')}
-                  data-testid="leader"
-                >
-                  {t('leader')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSearchBy('group')}
-                  data-testid="group"
-                >
-                  {t('group')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdowns}
-                data-testid="sort"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSortBy('volunteers_DESC')}
-                  data-testid="volunteers_DESC"
-                >
-                  {t('mostVolunteers')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('volunteers_ASC')}
-                  data-testid="volunteers_ASC"
-                >
-                  {t('leastVolunteers')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              sortingOptions={[
+                { label: t('leader'), value: 'leader' },
+                { label: t('group'), value: 'group' },
+              ]}
+              selectedOption={searchBy}
+              onSortChange={(value) => setSearchBy(value as 'leader' | 'group')}
+              dataTestIdPrefix="searchByToggle"
+              buttonLabel={tCommon('searchBy', { item: '' })}
+            />
+            <SortingButton
+              title={tCommon('sort')}
+              sortingOptions={[
+                { label: t('mostVolunteers'), value: 'volunteers_DESC' },
+                { label: t('leastVolunteers'), value: 'volunteers_ASC' },
+              ]}
+              selectedOption={sortBy ?? ''}
+              onSortChange={(value) =>
+                setSortBy(value as 'volunteers_DESC' | 'volunteers_ASC')
+              }
+              dataTestIdPrefix="sort"
+              buttonLabel={tCommon('sort')}
+            />
           </div>
           <div>
             <Button
diff --git a/src/screens/EventVolunteers/Volunteers/Volunteers.spec.tsx b/src/screens/EventVolunteers/Volunteers/Volunteers.spec.tsx
index be08ec61fb..cc3291274a 100644
--- a/src/screens/EventVolunteers/Volunteers/Volunteers.spec.tsx
+++ b/src/screens/EventVolunteers/Volunteers/Volunteers.spec.tsx
@@ -162,9 +162,9 @@ describe('Testing Volunteers Screen', () => {
     // Filter by All
     fireEvent.click(filterBtn);
     await waitFor(() => {
-      expect(screen.getByTestId('statusAll')).toBeInTheDocument();
+      expect(screen.getByTestId('all')).toBeInTheDocument();
     });
-    fireEvent.click(screen.getByTestId('statusAll'));
+    fireEvent.click(screen.getByTestId('all'));
 
     const volunteerName = await screen.findAllByTestId('volunteerName');
     expect(volunteerName).toHaveLength(2);
@@ -183,9 +183,9 @@ describe('Testing Volunteers Screen', () => {
     // Filter by Pending
     fireEvent.click(filterBtn);
     await waitFor(() => {
-      expect(screen.getByTestId('statusPending')).toBeInTheDocument();
+      expect(screen.getByTestId('pending')).toBeInTheDocument();
     });
-    fireEvent.click(screen.getByTestId('statusPending'));
+    fireEvent.click(screen.getByTestId('pending'));
 
     const volunteerName = await screen.findAllByTestId('volunteerName');
     expect(volunteerName[0]).toHaveTextContent('Bruce Graza');
@@ -204,9 +204,9 @@ describe('Testing Volunteers Screen', () => {
     // Filter by Accepted
     fireEvent.click(filterBtn);
     await waitFor(() => {
-      expect(screen.getByTestId('statusAccepted')).toBeInTheDocument();
+      expect(screen.getByTestId('accepted')).toBeInTheDocument();
     });
-    fireEvent.click(screen.getByTestId('statusAccepted'));
+    fireEvent.click(screen.getByTestId('accepted'));
 
     const volunteerName = await screen.findAllByTestId('volunteerName');
     expect(volunteerName[0]).toHaveTextContent('Teresa Bradley');
diff --git a/src/screens/EventVolunteers/Volunteers/Volunteers.tsx b/src/screens/EventVolunteers/Volunteers/Volunteers.tsx
index 875431ad6f..1cd7a19e88 100644
--- a/src/screens/EventVolunteers/Volunteers/Volunteers.tsx
+++ b/src/screens/EventVolunteers/Volunteers/Volunteers.tsx
@@ -1,15 +1,9 @@
 import React, { useCallback, useMemo, useState } from 'react';
 import { useTranslation } from 'react-i18next';
-import { Button, Dropdown, Form } from 'react-bootstrap';
+import { Button, Form } from 'react-bootstrap';
 import { Navigate, useParams } from 'react-router-dom';
 
-import {
-  Circle,
-  FilterAltOutlined,
-  Search,
-  Sort,
-  WarningAmberRounded,
-} from '@mui/icons-material';
+import { Circle, Search, WarningAmberRounded } from '@mui/icons-material';
 
 import { useQuery } from '@apollo/client';
 import Loader from 'components/Loader/Loader';
@@ -26,6 +20,7 @@ import type { InterfaceEventVolunteerInfo } from 'utils/interfaces';
 import VolunteerCreateModal from './VolunteerCreateModal';
 import VolunteerDeleteModal from './VolunteerDeleteModal';
 import VolunteerViewModal from './VolunteerViewModal';
+import SortingButton from 'subComponents/SortingButton';
 
 enum VolunteerStatus {
   All = 'all',
@@ -61,7 +56,7 @@ const dataGridStyle = {
 };
 
 /**
- * Component for managing and displaying event volunteers realted to an event.
+ * Component for managing and displaying event volunteers related to an event.
  *
  * This component allows users to view, filter, sort, and create volunteers. It also handles fetching and displaying related data such as volunteer acceptance status, etc.
  *
@@ -338,60 +333,39 @@ function volunteers(): JSX.Element {
         </div>
         <div className="d-flex gap-3 mb-1">
           <div className="d-flex justify-space-between align-items-center gap-3">
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                className={styles.dropdowns}
-                data-testid="sort"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSortBy('hoursVolunteered_DESC')}
-                  data-testid="hoursVolunteered_DESC"
-                >
-                  {t('mostHoursVolunteered')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('hoursVolunteered_ASC')}
-                  data-testid="hoursVolunteered_ASC"
-                >
-                  {t('leastHoursVolunteered')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                className={styles.dropdowns}
-                data-testid="filter"
-              >
-                <FilterAltOutlined className={'me-1'} />
-                {t('status')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setStatus(VolunteerStatus.All)}
-                  data-testid="statusAll"
-                >
-                  {tCommon('all')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setStatus(VolunteerStatus.Pending)}
-                  data-testid="statusPending"
-                >
-                  {tCommon('pending')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setStatus(VolunteerStatus.Accepted)}
-                  data-testid="statusAccepted"
-                >
-                  {t('accepted')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              sortingOptions={[
+                {
+                  label: t('mostHoursVolunteered'),
+                  value: 'hoursVolunteered_DESC',
+                },
+                {
+                  label: t('leastHoursVolunteered'),
+                  value: 'hoursVolunteered_ASC',
+                },
+              ]}
+              selectedOption={sortBy ?? ''}
+              onSortChange={(value) =>
+                setSortBy(
+                  value as 'hoursVolunteered_DESC' | 'hoursVolunteered_ASC',
+                )
+              }
+              dataTestIdPrefix="sort"
+              buttonLabel={tCommon('sort')}
+            />
+
+            <SortingButton
+              type="filter"
+              sortingOptions={[
+                { label: tCommon('all'), value: VolunteerStatus.All },
+                { label: tCommon('pending'), value: VolunteerStatus.Pending },
+                { label: t('accepted'), value: VolunteerStatus.Accepted },
+              ]}
+              selectedOption={status}
+              onSortChange={(value) => setStatus(value as VolunteerStatus)}
+              dataTestIdPrefix="filter"
+              buttonLabel={t('status')}
+            />
           </div>
           <div>
             <Button
diff --git a/src/screens/ForgotPassword/ForgotPassword.tsx b/src/screens/ForgotPassword/ForgotPassword.tsx
index 00fdb77c3b..49c0a2af6e 100644
--- a/src/screens/ForgotPassword/ForgotPassword.tsx
+++ b/src/screens/ForgotPassword/ForgotPassword.tsx
@@ -16,7 +16,7 @@ import { Form } from 'react-bootstrap';
 import Button from 'react-bootstrap/Button';
 import { useTranslation } from 'react-i18next';
 import { errorHandler } from 'utils/errorHandler';
-import styles from 'style/app.module.css';
+import styles from '../../style/app.module.css';
 import useLocalStorage from 'utils/useLocalstorage';
 
 /**
diff --git a/src/screens/FundCampaignPledge/FundCampaignPledge.test.tsx b/src/screens/FundCampaignPledge/FundCampaignPledge.spec.tsx
similarity index 92%
rename from src/screens/FundCampaignPledge/FundCampaignPledge.test.tsx
rename to src/screens/FundCampaignPledge/FundCampaignPledge.spec.tsx
index 3fb5993775..3e6ecb74ae 100644
--- a/src/screens/FundCampaignPledge/FundCampaignPledge.test.tsx
+++ b/src/screens/FundCampaignPledge/FundCampaignPledge.spec.tsx
@@ -2,13 +2,7 @@ import { MockedProvider } from '@apollo/react-testing';
 import { LocalizationProvider } from '@mui/x-date-pickers';
 import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
 import type { RenderResult } from '@testing-library/react';
-import {
-  cleanup,
-  fireEvent,
-  render,
-  screen,
-  waitFor,
-} from '@testing-library/react';
+import { fireEvent, render, screen, waitFor } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
 import { I18nextProvider } from 'react-i18next';
 import { Provider } from 'react-redux';
@@ -24,18 +18,19 @@ import {
 } from './PledgesMocks';
 import React from 'react';
 import type { ApolloLink } from '@apollo/client';
+import { vi } from 'vitest';
 
-jest.mock('react-toastify', () => ({
+vi.mock('react-toastify', () => ({
   toast: {
-    success: jest.fn(),
-    error: jest.fn(),
+    success: vi.fn(),
+    error: vi.fn(),
   },
 }));
-jest.mock('@mui/x-date-pickers/DateTimePicker', () => {
+vi.mock('@mui/x-date-pickers/DateTimePicker', () => {
   return {
-    DateTimePicker: jest.requireActual(
-      '@mui/x-date-pickers/DesktopDateTimePicker',
-    ).DesktopDateTimePicker,
+    DateTimePicker: vi
+      .importActual('@mui/x-date-pickers/DesktopDateTimePicker')
+      .then((module) => module.DesktopDateTimePicker),
   };
 });
 
@@ -46,6 +41,11 @@ const translations = JSON.parse(
   JSON.stringify(i18nForTest.getDataByLanguage('en')?.translation.pledges),
 );
 
+const mockParamsState = {
+  orgId: 'orgId',
+  fundCampaignId: 'fundCampaignId',
+};
+
 const renderFundCampaignPledge = (link: ApolloLink): RenderResult => {
   return render(
     <MockedProvider addTypename={false} link={link}>
@@ -74,18 +74,30 @@ const renderFundCampaignPledge = (link: ApolloLink): RenderResult => {
 };
 
 describe('Testing Campaign Pledge Screen', () => {
-  beforeAll(() => {
-    jest.mock('react-router-dom', () => ({
-      ...jest.requireActual('react-router-dom'),
-      useParams: () => ({ orgId: 'orgId', fundCampaignId: 'fundCampaignId' }),
-    }));
+  const mockNavigate = vi.fn();
+
+  vi.mock('react-router-dom', async () => {
+    const actual = await vi.importActual('react-router-dom');
+    return {
+      ...actual,
+      useParams: () => ({ ...mockParamsState }),
+      useNavigate: () => mockNavigate,
+    };
+  });
+
+  beforeEach(() => {
+    mockParamsState.orgId = 'orgId';
+    mockParamsState.fundCampaignId = 'fundCampaignId';
   });
 
   afterAll(() => {
-    jest.clearAllMocks();
+    vi.clearAllMocks();
   });
 
   it('should redirect to fallback URL if URL params are undefined', async () => {
+    mockParamsState.orgId = '';
+    mockParamsState.fundCampaignId = '';
+
     render(
       <MockedProvider addTypename={false} link={link1}>
         <MemoryRouter initialEntries={['/fundCampaignPledge/']}>
diff --git a/src/screens/FundCampaignPledge/FundCampaignPledge.tsx b/src/screens/FundCampaignPledge/FundCampaignPledge.tsx
index 8942265eea..323f30aa67 100644
--- a/src/screens/FundCampaignPledge/FundCampaignPledge.tsx
+++ b/src/screens/FundCampaignPledge/FundCampaignPledge.tsx
@@ -1,11 +1,11 @@
 import { useQuery, type ApolloQueryResult } from '@apollo/client';
-import { Search, Sort, WarningAmberRounded } from '@mui/icons-material';
+import { Search, WarningAmberRounded } from '@mui/icons-material';
 import { FUND_CAMPAIGN_PLEDGE } from 'GraphQl/Queries/fundQueries';
 import Loader from 'components/Loader/Loader';
 import { Unstable_Popup as BasePopup } from '@mui/base/Unstable_Popup';
 import dayjs from 'dayjs';
 import React, { useCallback, useEffect, useMemo, useState } from 'react';
-import { Button, Dropdown, Form } from 'react-bootstrap';
+import { Button, Form } from 'react-bootstrap';
 import { useTranslation } from 'react-i18next';
 import { Navigate, useParams } from 'react-router-dom';
 import { currencySymbols } from 'utils/currency';
@@ -23,6 +23,8 @@ import type {
 } from 'utils/interfaces';
 import ProgressBar from 'react-bootstrap/ProgressBar';
 
+import SortingButton from 'subComponents/SortingButton';
+
 interface InterfaceCampaignInfo {
   name: string;
   goal: number;
@@ -56,6 +58,7 @@ const dataGridStyle = {
     borderRadius: '0.5rem',
   },
 };
+
 const fundCampaignPledge = (): JSX.Element => {
   const { t } = useTranslation('translation', {
     keyPrefix: 'pledges',
@@ -492,43 +495,26 @@ const fundCampaignPledge = (): JSX.Element => {
         </div>
         <div className="d-flex gap-4 mb-1">
           <div className="d-flex justify-space-between">
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdown}
-                data-testid="filter"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSortBy('amount_ASC')}
-                  data-testid="amount_ASC"
-                >
-                  {t('lowestAmount')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('amount_DESC')}
-                  data-testid="amount_DESC"
-                >
-                  {t('highestAmount')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('endDate_DESC')}
-                  data-testid="endDate_DESC"
-                >
-                  {t('latestEndDate')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('endDate_ASC')}
-                  data-testid="endDate_ASC"
-                >
-                  {t('earliestEndDate')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              sortingOptions={[
+                { label: t('lowestAmount'), value: 'amount_ASC' },
+                { label: t('highestAmount'), value: 'amount_DESC' },
+                { label: t('latestEndDate'), value: 'endDate_DESC' },
+                { label: t('earliestEndDate'), value: 'endDate_ASC' },
+              ]}
+              selectedOption={sortBy ?? ''}
+              onSortChange={(value) =>
+                setSortBy(
+                  value as
+                    | 'amount_ASC'
+                    | 'amount_DESC'
+                    | 'endDate_ASC'
+                    | 'endDate_DESC',
+                )
+              }
+              dataTestIdPrefix="filter"
+              buttonLabel={tCommon('sort')}
+            />
           </div>
           <div>
             <Button
diff --git a/src/screens/FundCampaignPledge/PledgeDeleteModal.test.tsx b/src/screens/FundCampaignPledge/PledgeDeleteModal.spec.tsx
similarity index 95%
rename from src/screens/FundCampaignPledge/PledgeDeleteModal.test.tsx
rename to src/screens/FundCampaignPledge/PledgeDeleteModal.spec.tsx
index dbaae76504..34b743973f 100644
--- a/src/screens/FundCampaignPledge/PledgeDeleteModal.test.tsx
+++ b/src/screens/FundCampaignPledge/PledgeDeleteModal.spec.tsx
@@ -15,11 +15,12 @@ import i18nForTest from '../../utils/i18nForTest';
 import { MOCKS_DELETE_PLEDGE_ERROR, MOCKS } from './PledgesMocks';
 import { StaticMockLink } from 'utils/StaticMockLink';
 import { toast } from 'react-toastify';
+import { vi } from 'vitest';
 
-jest.mock('react-toastify', () => ({
+vi.mock('react-toastify', () => ({
   toast: {
-    success: jest.fn(),
-    error: jest.fn(),
+    success: vi.fn(),
+    error: vi.fn(),
   },
 }));
 
@@ -31,7 +32,7 @@ const translations = JSON.parse(
 
 const pledgeProps: InterfaceDeletePledgeModal = {
   isOpen: true,
-  hide: jest.fn(),
+  hide: vi.fn(),
   pledge: {
     _id: '1',
     amount: 100,
@@ -47,7 +48,7 @@ const pledgeProps: InterfaceDeletePledgeModal = {
       },
     ],
   },
-  refetchPledge: jest.fn(),
+  refetchPledge: vi.fn(),
 };
 
 const renderPledgeDeleteModal = (
diff --git a/src/screens/Leaderboard/Leaderboard.spec.tsx b/src/screens/Leaderboard/Leaderboard.spec.tsx
index b4c73bef5c..3ef73835a6 100644
--- a/src/screens/Leaderboard/Leaderboard.spec.tsx
+++ b/src/screens/Leaderboard/Leaderboard.spec.tsx
@@ -173,7 +173,7 @@ describe('Testing Leaderboard Screen', () => {
     expect(filter).toBeInTheDocument();
 
     fireEvent.click(filter);
-    const timeFrameAll = await screen.findByTestId('timeFrameAll');
+    const timeFrameAll = await screen.findByTestId('allTime');
     expect(timeFrameAll).toBeInTheDocument();
 
     fireEvent.click(timeFrameAll);
@@ -196,7 +196,7 @@ describe('Testing Leaderboard Screen', () => {
     expect(filter).toBeInTheDocument();
     fireEvent.click(filter);
 
-    const timeFrameWeekly = await screen.findByTestId('timeFrameWeekly');
+    const timeFrameWeekly = await screen.findByTestId('weekly');
     expect(timeFrameWeekly).toBeInTheDocument();
     fireEvent.click(timeFrameWeekly);
 
@@ -217,7 +217,7 @@ describe('Testing Leaderboard Screen', () => {
     expect(filter).toBeInTheDocument();
     fireEvent.click(filter);
 
-    const timeFrameMonthly = await screen.findByTestId('timeFrameMonthly');
+    const timeFrameMonthly = await screen.findByTestId('monthly');
     expect(timeFrameMonthly).toBeInTheDocument();
     fireEvent.click(timeFrameMonthly);
 
@@ -238,7 +238,7 @@ describe('Testing Leaderboard Screen', () => {
     expect(filter).toBeInTheDocument();
     fireEvent.click(filter);
 
-    const timeFrameYearly = await screen.findByTestId('timeFrameYearly');
+    const timeFrameYearly = await screen.findByTestId('yearly');
     expect(timeFrameYearly).toBeInTheDocument();
     fireEvent.click(timeFrameYearly);
 
diff --git a/src/screens/Leaderboard/Leaderboard.tsx b/src/screens/Leaderboard/Leaderboard.tsx
index e0ea513e9c..f83d7e273d 100644
--- a/src/screens/Leaderboard/Leaderboard.tsx
+++ b/src/screens/Leaderboard/Leaderboard.tsx
@@ -1,14 +1,9 @@
 import React, { useMemo, useState } from 'react';
 import { useTranslation } from 'react-i18next';
-import { Button, Dropdown, Form } from 'react-bootstrap';
+import { Button, Form } from 'react-bootstrap';
 import { Navigate, useNavigate, useParams } from 'react-router-dom';
 
-import {
-  FilterAltOutlined,
-  Search,
-  Sort,
-  WarningAmberRounded,
-} from '@mui/icons-material';
+import { Search, WarningAmberRounded } from '@mui/icons-material';
 import gold from 'assets/images/gold.png';
 import silver from 'assets/images/silver.png';
 import bronze from 'assets/images/bronze.png';
@@ -25,6 +20,7 @@ import { debounce, Stack } from '@mui/material';
 import Avatar from 'components/Avatar/Avatar';
 import { VOLUNTEER_RANKING } from 'GraphQl/Queries/EventVolunteerQueries';
 import { useQuery } from '@apollo/client';
+import SortingButton from 'subComponents/SortingButton';
 
 enum TimeFrame {
   All = 'allTime',
@@ -275,68 +271,31 @@ function leaderboard(): JSX.Element {
         </div>
         <div className="d-flex gap-3 mb-1">
           <div className="d-flex justify-space-between align-items-center gap-3">
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-sort"
-                className={styles.dropdown}
-                data-testid="sort"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSortBy('hours_DESC')}
-                  data-testid="hours_DESC"
-                >
-                  {t('mostHours')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('hours_ASC')}
-                  data-testid="hours_ASC"
-                >
-                  {t('leastHours')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-timeFrame"
-                className={styles.dropdown}
-                data-testid="timeFrame"
-              >
-                <FilterAltOutlined className={'me-1'} />
-                {t('timeFrame')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setTimeFrame(TimeFrame.All)}
-                  data-testid="timeFrameAll"
-                >
-                  {t('allTime')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setTimeFrame(TimeFrame.Weekly)}
-                  data-testid="timeFrameWeekly"
-                >
-                  {t('weekly')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setTimeFrame(TimeFrame.Monthly)}
-                  data-testid="timeFrameMonthly"
-                >
-                  {t('monthly')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setTimeFrame(TimeFrame.Yearly)}
-                  data-testid="timeFrameYearly"
-                >
-                  {t('yearly')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              sortingOptions={[
+                { label: t('mostHours'), value: 'hours_DESC' },
+                { label: t('leastHours'), value: 'hours_ASC' },
+              ]}
+              selectedOption={sortBy}
+              onSortChange={(value) =>
+                setSortBy(value as 'hours_DESC' | 'hours_ASC')
+              }
+              dataTestIdPrefix="sort"
+              buttonLabel={tCommon('sort')}
+            />
+            <SortingButton
+              sortingOptions={[
+                { label: t('allTime'), value: TimeFrame.All },
+                { label: t('weekly'), value: TimeFrame.Weekly },
+                { label: t('monthly'), value: TimeFrame.Monthly },
+                { label: t('yearly'), value: TimeFrame.Yearly },
+              ]}
+              selectedOption={timeFrame}
+              onSortChange={(value) => setTimeFrame(value as TimeFrame)}
+              dataTestIdPrefix="timeFrame"
+              buttonLabel={t('timeFrame')}
+              type="filter"
+            />
           </div>
         </div>
       </div>
diff --git a/src/screens/ManageTag/ManageTag.spec.tsx b/src/screens/ManageTag/ManageTag.spec.tsx
index 5d86ed3c17..03c7eea393 100644
--- a/src/screens/ManageTag/ManageTag.spec.tsx
+++ b/src/screens/ManageTag/ManageTag.spec.tsx
@@ -50,7 +50,6 @@ vi.mock('react-toastify', () => ({
   },
 }));
 
-/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports */
 vi.mock('../../components/AddPeopleToTag/AddPeopleToTag', async () => {
   return await import('./ManageTagMockComponents/MockAddPeopleToTag');
 });
@@ -58,7 +57,6 @@ vi.mock('../../components/AddPeopleToTag/AddPeopleToTag', async () => {
 vi.mock('../../components/TagActions/TagActions', async () => {
   return await import('./ManageTagMockComponents/MockTagActions');
 });
-/* eslint-enable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports */
 
 const renderManageTag = (link: ApolloLink): RenderResult => {
   return render(
@@ -372,9 +370,9 @@ describe('Manage Tag Page', () => {
     userEvent.click(screen.getByTestId('sortPeople'));
 
     await waitFor(() => {
-      expect(screen.getByTestId('oldest')).toBeInTheDocument();
+      expect(screen.getByTestId('ASCENDING')).toBeInTheDocument();
     });
-    userEvent.click(screen.getByTestId('oldest'));
+    userEvent.click(screen.getByTestId('ASCENDING'));
 
     // returns the tags in reverse order
     await waitFor(() => {
@@ -389,9 +387,9 @@ describe('Manage Tag Page', () => {
     userEvent.click(screen.getByTestId('sortPeople'));
 
     await waitFor(() => {
-      expect(screen.getByTestId('latest')).toBeInTheDocument();
+      expect(screen.getByTestId('DESCENDING')).toBeInTheDocument();
     });
-    userEvent.click(screen.getByTestId('latest'));
+    userEvent.click(screen.getByTestId('DESCENDING'));
 
     // reverse the order again
     await waitFor(() => {
diff --git a/src/screens/ManageTag/ManageTag.tsx b/src/screens/ManageTag/ManageTag.tsx
index 38466f6f11..0832b2ab3e 100644
--- a/src/screens/ManageTag/ManageTag.tsx
+++ b/src/screens/ManageTag/ManageTag.tsx
@@ -2,13 +2,11 @@ import type { FormEvent } from 'react';
 import React, { useEffect, useState } from 'react';
 import { useMutation, useQuery } from '@apollo/client';
 import { Search, WarningAmberRounded } from '@mui/icons-material';
-import SortIcon from '@mui/icons-material/Sort';
 import Loader from 'components/Loader/Loader';
 import IconComponent from 'components/IconComponent/IconComponent';
 import { useNavigate, useParams, Link } from 'react-router-dom';
 import { Col, Form } from 'react-bootstrap';
 import Button from 'react-bootstrap/Button';
-import Dropdown from 'react-bootstrap/Dropdown';
 import Row from 'react-bootstrap/Row';
 import { useTranslation } from 'react-i18next';
 import { toast } from 'react-toastify';
@@ -39,6 +37,7 @@ import InfiniteScrollLoader from 'components/InfiniteScrollLoader/InfiniteScroll
 import EditUserTagModal from './EditUserTagModal';
 import RemoveUserTagModal from './RemoveUserTagModal';
 import UnassignUserTagModal from './UnassignUserTagModal';
+import SortingButton from 'subComponents/SortingButton';
 
 /**
  * Component that renders the Manage Tag screen when the app navigates to '/orgtags/:orgId/manageTag/:tagId'.
@@ -378,36 +377,19 @@ function ManageTag(): JSX.Element {
               </Button>
             </div>
             <div className={styles.btnsBlock}>
-              <Dropdown
-                aria-expanded="false"
+              <SortingButton
                 title="Sort People"
-                data-testid="sort"
-              >
-                <Dropdown.Toggle
-                  variant="outline-success"
-                  data-testid="sortPeople"
-                  className={styles.dropdown}
-                >
-                  <SortIcon className={'me-1'} />
-                  {assignedMemberSortOrder === 'DESCENDING'
-                    ? tCommon('Latest')
-                    : tCommon('Oldest')}
-                </Dropdown.Toggle>
-                <Dropdown.Menu>
-                  <Dropdown.Item
-                    data-testid="latest"
-                    onClick={() => setAssignedMemberSortOrder('DESCENDING')}
-                  >
-                    {tCommon('Latest')}
-                  </Dropdown.Item>
-                  <Dropdown.Item
-                    data-testid="oldest"
-                    onClick={() => setAssignedMemberSortOrder('ASCENDING')}
-                  >
-                    {tCommon('Oldest')}
-                  </Dropdown.Item>
-                </Dropdown.Menu>
-              </Dropdown>
+                sortingOptions={[
+                  { label: tCommon('Latest'), value: 'DESCENDING' },
+                  { label: tCommon('Oldest'), value: 'ASCENDING' },
+                ]}
+                selectedOption={assignedMemberSortOrder}
+                onSortChange={(value) =>
+                  setAssignedMemberSortOrder(value as SortedByType)
+                }
+                dataTestIdPrefix="sortPeople"
+                buttonLabel={tCommon('sort')}
+              />
               <Button
                 variant="success"
                 onClick={() => redirectToSubTags(currentTagId as string)}
diff --git a/src/screens/OrgList/OrgList.test.tsx b/src/screens/OrgList/OrgList.spec.tsx
similarity index 98%
rename from src/screens/OrgList/OrgList.test.tsx
rename to src/screens/OrgList/OrgList.spec.tsx
index 2b2809c7c9..80a0bf1233 100644
--- a/src/screens/OrgList/OrgList.test.tsx
+++ b/src/screens/OrgList/OrgList.spec.tsx
@@ -10,8 +10,6 @@ import {
   waitFor,
 } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
-import 'jest-localstorage-mock';
-import 'jest-location-mock';
 import { I18nextProvider } from 'react-i18next';
 import { Provider } from 'react-redux';
 import { BrowserRouter } from 'react-router-dom';
@@ -27,9 +25,10 @@ import {
   MOCKS_WITH_ERROR,
 } from './OrgListMocks';
 import { ToastContainer, toast } from 'react-toastify';
-
-jest.setTimeout(30000);
 import useLocalStorage from 'utils/useLocalstorage';
+import { vi } from 'vitest';
+
+vi.setConfig({ testTimeout: 30000 });
 
 const { setItem } = useLocalStorage();
 
@@ -41,10 +40,14 @@ async function wait(ms = 100): Promise<void> {
   });
 }
 
+beforeEach(() => {
+  vi.spyOn(Storage.prototype, 'setItem');
+});
+
 afterEach(() => {
   localStorage.clear();
   cleanup();
-  jest.clearAllMocks();
+  vi.clearAllMocks();
 });
 
 describe('Organisations Page testing as SuperAdmin', () => {
@@ -162,7 +165,6 @@ describe('Organisations Page testing as SuperAdmin', () => {
     expect(
       screen.queryByText('Please create an organization through dashboard'),
     ).toBeInTheDocument();
-    expect(window.location).toBeAt('/');
   });
 
   test('Testing Organization data is not present', async () => {
@@ -451,7 +453,7 @@ describe('Organisations Page testing as SuperAdmin', () => {
     setItem('SuperAdmin', true);
     setItem('AdminFor', [{ name: 'adi', _id: '1234', image: '' }]);
 
-    jest.spyOn(toast, 'error');
+    vi.spyOn(toast, 'error');
     render(
       <MockedProvider addTypename={false} link={link3}>
         <BrowserRouter>
@@ -523,7 +525,7 @@ describe('Organisations Page testing as Admin', () => {
       fireEvent.click(sortToggle);
     });
 
-    const latestOption = screen.getByTestId('latest');
+    const latestOption = screen.getByTestId('Latest');
 
     await act(async () => {
       fireEvent.click(latestOption);
@@ -535,7 +537,7 @@ describe('Organisations Page testing as Admin', () => {
       fireEvent.click(sortToggle);
     });
 
-    const oldestOption = await waitFor(() => screen.getByTestId('oldest'));
+    const oldestOption = await waitFor(() => screen.getByTestId('Earliest'));
 
     await act(async () => {
       fireEvent.click(oldestOption);
diff --git a/src/screens/OrgList/OrgList.tsx b/src/screens/OrgList/OrgList.tsx
index 2d53425d2e..880dccf98d 100644
--- a/src/screens/OrgList/OrgList.tsx
+++ b/src/screens/OrgList/OrgList.tsx
@@ -1,6 +1,5 @@
 import { useMutation, useQuery } from '@apollo/client';
 import { Search } from '@mui/icons-material';
-import SortIcon from '@mui/icons-material/Sort';
 import {
   CREATE_ORGANIZATION_MUTATION,
   CREATE_SAMPLE_ORGANIZATION_MUTATION,
@@ -13,7 +12,7 @@ import {
 import OrgListCard from 'components/OrgListCard/OrgListCard';
 import type { ChangeEvent } from 'react';
 import React, { useEffect, useState } from 'react';
-import { Dropdown, Form } from 'react-bootstrap';
+import { Form } from 'react-bootstrap';
 import Button from 'react-bootstrap/Button';
 import Modal from 'react-bootstrap/Modal';
 import { useTranslation } from 'react-i18next';
@@ -29,6 +28,7 @@ import type {
 import useLocalStorage from 'utils/useLocalstorage';
 import styles from '../../style/app.module.css';
 import OrganizationModal from './OrganizationModal';
+import SortingButton from 'subComponents/SortingButton';
 
 function orgList(): JSX.Element {
   const { t } = useTranslation('translation', { keyPrefix: 'orgList' });
@@ -48,8 +48,10 @@ function orgList(): JSX.Element {
   function closeDialogModal(): void {
     setdialogModalIsOpen(false);
   }
+
   const toggleDialogModal = (): void =>
     setdialogModalIsOpen(!dialogModalisOpen);
+
   document.title = t('title');
 
   const perPageResult = 8;
@@ -58,6 +60,7 @@ function orgList(): JSX.Element {
     option: '',
     selectedOption: t('sort'),
   });
+
   const [hasMore, sethasMore] = useState(true);
   const [isLoadingMore, setIsLoadingMore] = useState(false);
   const [searchByName, setSearchByName] = useState('');
@@ -81,9 +84,7 @@ function orgList(): JSX.Element {
   });
 
   const toggleModal = (): void => setShowModal(!showModal);
-
   const [create] = useMutation(CREATE_ORGANIZATION_MUTATION);
-
   const [createSampleOrganization] = useMutation(
     CREATE_SAMPLE_ORGANIZATION_MUTATION,
   );
@@ -277,7 +278,6 @@ function orgList(): JSX.Element {
   };
 
   const loadMoreOrganizations = (): void => {
-    console.log('loadMoreOrganizations');
     setIsLoadingMore(true);
     fetchMore({
       variables: {
@@ -312,14 +312,12 @@ function orgList(): JSX.Element {
     });
   };
 
-  const handleSorting = (option: string): void => {
+  const handleSortChange = (value: string): void => {
     setSortingState({
-      option,
-      selectedOption: t(option),
+      option: value,
+      selectedOption: t(value),
     });
-
-    const orderBy = option === 'Latest' ? 'createdAt_DESC' : 'createdAt_ASC';
-
+    const orderBy = value === 'Latest' ? 'createdAt_DESC' : 'createdAt_ASC';
     refetchOrgs({
       first: perPageResult,
       skip: 0,
@@ -345,7 +343,6 @@ function orgList(): JSX.Element {
           />
           <Button
             tabIndex={-1}
-            // className={`position-absolute z-10 bottom-0 end-0 h-100 d-flex justify-content-center align-items-center`}
             className={styles.searchButtonOrgList}
             onClick={handleSearchByBtnClick}
             data-testid="searchBtn"
@@ -354,38 +351,17 @@ function orgList(): JSX.Element {
           </Button>
         </div>
         <div className={styles.btnsBlockOrgList}>
-          <div className="d-flex">
-            <Dropdown
-              aria-expanded="false"
-              title="Sort organizations"
-              data-testid="sort"
-            >
-              <Dropdown.Toggle
-                // className={styles.dropdown}
-                variant={
-                  sortingState.option === '' ? 'outline-success' : 'success'
-                }
-                data-testid="sortOrgs"
-              >
-                <SortIcon className={'me-1'} />
-                {sortingState.selectedOption}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={(): void => handleSorting('Latest')}
-                  data-testid="latest"
-                >
-                  {t('Latest')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={(): void => handleSorting('Earliest')}
-                  data-testid="oldest"
-                >
-                  {t('Earliest')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-          </div>
+          <SortingButton
+            title="Sort organizations"
+            sortingOptions={[
+              { label: t('Latest'), value: 'Latest' },
+              { label: t('Earliest'), value: 'Earliest' },
+            ]}
+            selectedOption={sortingState.selectedOption}
+            onSortChange={handleSortChange}
+            dataTestIdPrefix="sortOrgs"
+            dropdownTestId="sort"
+          />
           {superAdmin && (
             <Button
               variant="success"
@@ -398,7 +374,9 @@ function orgList(): JSX.Element {
           )}
         </div>
       </div>
+
       {/* Text Infos for list */}
+
       {!isLoading &&
       (!orgsData?.organizationsConnection ||
         orgsData.organizationsConnection.length === 0) &&
@@ -485,6 +463,7 @@ function orgList(): JSX.Element {
                       <div
                         className={`${styles.orgImgContainer} shimmer`}
                       ></div>
+
                       <div className={styles.content}>
                         <h5 className="shimmer" title="Org name"></h5>
                         <h6 className="shimmer" title="Location"></h6>
diff --git a/src/screens/OrgList/OrgListMocks.ts b/src/screens/OrgList/OrgListMocks.ts
index 380313ffd5..fd8794d969 100644
--- a/src/screens/OrgList/OrgListMocks.ts
+++ b/src/screens/OrgList/OrgListMocks.ts
@@ -6,7 +6,6 @@ import {
   ORGANIZATION_CONNECTION_LIST,
   USER_ORGANIZATION_LIST,
 } from 'GraphQl/Queries/Queries';
-import 'jest-location-mock';
 import type {
   InterfaceOrgConnectionInfoType,
   InterfaceUserType,
diff --git a/src/screens/OrgPost/OrgPost.test.tsx b/src/screens/OrgPost/OrgPost.test.tsx
index 9829589350..e9952db7bd 100644
--- a/src/screens/OrgPost/OrgPost.test.tsx
+++ b/src/screens/OrgPost/OrgPost.test.tsx
@@ -308,7 +308,7 @@ describe('Organisation Post Page', () => {
     await act(async () => {
       fireEvent.click(inputText);
     });
-    const toggleTite = screen.getByTestId('searchTitle');
+    const toggleTite = screen.getByTestId('Title');
     await act(async () => {
       fireEvent.click(toggleTite);
     });
diff --git a/src/screens/OrgPost/OrgPost.tsx b/src/screens/OrgPost/OrgPost.tsx
index e9cb4d4ca2..8ccdb47692 100644
--- a/src/screens/OrgPost/OrgPost.tsx
+++ b/src/screens/OrgPost/OrgPost.tsx
@@ -1,6 +1,5 @@
 import { useMutation, useQuery, type ApolloError } from '@apollo/client';
 import { Search } from '@mui/icons-material';
-import SortIcon from '@mui/icons-material/Sort';
 import { CREATE_POST_MUTATION } from 'GraphQl/Mutations/mutations';
 import { ORGANIZATION_POST_LIST } from 'GraphQl/Queries/Queries';
 import Loader from 'components/Loader/Loader';
@@ -11,7 +10,6 @@ import type { ChangeEvent } from 'react';
 import React, { useEffect, useState } from 'react';
 import { Form } from 'react-bootstrap';
 import Button from 'react-bootstrap/Button';
-import Dropdown from 'react-bootstrap/Dropdown';
 import Modal from 'react-bootstrap/Modal';
 import Row from 'react-bootstrap/Row';
 import { useTranslation } from 'react-i18next';
@@ -20,6 +18,7 @@ import convertToBase64 from 'utils/convertToBase64';
 import { errorHandler } from 'utils/errorHandler';
 import type { InterfaceQueryOrganizationPostListItem } from 'utils/interfaces';
 import styles from '../../style/app.module.css';
+import SortingButton from '../../subComponents/SortingButton';
 
 interface InterfaceOrgPost {
   _id: string;
@@ -303,69 +302,31 @@ function orgPost(): JSX.Element {
             </div>
             <div className={styles.btnsBlockOrgPost}>
               <div className="d-flex">
-                <Dropdown
-                  aria-expanded="false"
+                <SortingButton
                   title="SearchBy"
-                  data-testid="sea"
-                >
-                  <Dropdown.Toggle
-                    data-testid="searchBy"
-                    className={styles.dropdown}
-                  >
-                    <SortIcon className={'me-1'} />
-                    {t('searchBy')}
-                  </Dropdown.Toggle>
-                  <Dropdown.Menu>
-                    <Dropdown.Item
-                      id="searchText"
-                      onClick={(e): void => {
-                        setShowTitle(false);
-                        e.preventDefault();
-                      }}
-                      data-testid="Text"
-                    >
-                      {t('Text')}
-                    </Dropdown.Item>
-                    <Dropdown.Item
-                      id="searchTitle"
-                      onClick={(e): void => {
-                        setShowTitle(true);
-                        e.preventDefault();
-                      }}
-                      data-testid="searchTitle"
-                    >
-                      {t('Title')}
-                    </Dropdown.Item>
-                  </Dropdown.Menu>
-                </Dropdown>
-                <Dropdown
-                  aria-expanded="false"
+                  sortingOptions={[
+                    { label: t('Text'), value: 'Text' },
+                    { label: t('Title'), value: 'Title' },
+                  ]}
+                  selectedOption={showTitle ? t('Title') : t('Text')}
+                  onSortChange={(value) => setShowTitle(value === 'Title')}
+                  dataTestIdPrefix="searchBy"
+                  buttonLabel={t('searchBy')}
+                  className={`${styles.dropdown} `}
+                />
+                <SortingButton
                   title="Sort Post"
-                  data-testid="sort"
-                >
-                  <Dropdown.Toggle
-                    variant="outline-success"
-                    data-testid="sortpost"
-                    className={styles.dropdown}
-                  >
-                    <SortIcon className={'me-1'} />
-                    {t('sortPost')}
-                  </Dropdown.Toggle>
-                  <Dropdown.Menu>
-                    <Dropdown.Item
-                      onClick={(): void => handleSorting('latest')}
-                      data-testid="latest"
-                    >
-                      {t('Latest')}
-                    </Dropdown.Item>
-                    <Dropdown.Item
-                      onClick={(): void => handleSorting('oldest')}
-                      data-testid="oldest"
-                    >
-                      {t('Oldest')}
-                    </Dropdown.Item>
-                  </Dropdown.Menu>
-                </Dropdown>
+                  sortingOptions={[
+                    { label: t('Latest'), value: 'latest' },
+                    { label: t('Oldest'), value: 'oldest' },
+                  ]}
+                  selectedOption={sortingOption}
+                  onSortChange={handleSorting}
+                  dataTestIdPrefix="sortpost"
+                  dropdownTestId="sort"
+                  className={`${styles.dropdown} `}
+                  buttonLabel={t('sortPost')}
+                />
               </div>
 
               <Button
diff --git a/src/screens/OrgSettings/OrgSettings.spec.tsx b/src/screens/OrgSettings/OrgSettings.spec.tsx
index a98fface20..e7d417e179 100644
--- a/src/screens/OrgSettings/OrgSettings.spec.tsx
+++ b/src/screens/OrgSettings/OrgSettings.spec.tsx
@@ -130,50 +130,50 @@ describe('Organisation Settings Page', () => {
     });
   });
 
-  it('should handle dropdown item selection correctly', async () => {
-    renderOrganisationSettings();
-
-    await waitFor(() => {
-      expect(
-        screen.getByTestId('settingsDropdownContainer'),
-      ).toBeInTheDocument();
-    });
-
-    const dropdownToggle = screen.getByTestId('settingsDropdownToggle');
-    userEvent.click(dropdownToggle);
-
-    // Find all dropdown items
-    const dropdownItems = screen.getAllByRole('menuitem');
-    expect(dropdownItems).toHaveLength(3);
-
-    for (const item of dropdownItems) {
-      userEvent.click(item);
-
-      if (item.textContent?.includes('general')) {
-        await waitFor(() => {
-          expect(screen.getByTestId('generalTab')).toBeInTheDocument();
-        });
-      } else if (item.textContent?.includes('actionItemCategories')) {
-        await waitFor(() => {
-          expect(
-            screen.getByTestId('actionItemCategoriesTab'),
-          ).toBeInTheDocument();
-        });
-      } else if (item.textContent?.includes('agendaItemCategories')) {
-        await waitFor(() => {
-          expect(
-            screen.getByTestId('agendaItemCategoriesTab'),
-          ).toBeInTheDocument();
-        });
-      }
-
-      if (item !== dropdownItems[dropdownItems.length - 1]) {
-        userEvent.click(dropdownToggle);
-      }
-    }
-
-    expect(dropdownToggle).toHaveTextContent(
-      screen.getByTestId('agendaItemCategoriesSettings').textContent || '',
-    );
-  });
+  // it('should handle dropdown item selection correctly', async () => {
+  //   renderOrganisationSettings();
+
+  //   await waitFor(() => {
+  //     expect(
+  //       screen.getByTestId('settingsDropdownContainer'),
+  //     ).toBeInTheDocument();
+  //   });
+
+  //   const dropdownToggle = screen.getByTestId('settingsDropdownToggle');
+  //   userEvent.click(dropdownToggle);
+
+  //   // Find all dropdown items
+  //   const dropdownItems = screen.getAllByRole('menuitem');
+  //   expect(dropdownItems).toHaveLength(3);
+
+  //   for (const item of dropdownItems) {
+  //     userEvent.click(item);
+
+  //     if (item.textContent?.includes('general')) {
+  //       await waitFor(() => {
+  //         expect(screen.getByTestId('generalTab')).toBeInTheDocument();
+  //       });
+  //     } else if (item.textContent?.includes('actionItemCategories')) {
+  //       await waitFor(() => {
+  //         expect(
+  //           screen.getByTestId('actionItemCategoriesTab'),
+  //         ).toBeInTheDocument();
+  //       });
+  //     } else if (item.textContent?.includes('agendaItemCategories')) {
+  //       await waitFor(() => {
+  //         expect(
+  //           screen.getByTestId('agendaItemCategoriesTab'),
+  //         ).toBeInTheDocument();
+  //       });
+  //     }
+
+  //     if (item !== dropdownItems[dropdownItems.length - 1]) {
+  //       userEvent.click(dropdownToggle);
+  //     }
+  //   }
+
+  //   expect(dropdownToggle).toHaveTextContent(
+  //     screen.getByTestId('agendaItemCategoriesSettings').textContent || '',
+  //   );
+  // });
 });
diff --git a/src/screens/OrgSettings/OrgSettings.tsx b/src/screens/OrgSettings/OrgSettings.tsx
index 641bc27c7d..57758d2867 100644
--- a/src/screens/OrgSettings/OrgSettings.tsx
+++ b/src/screens/OrgSettings/OrgSettings.tsx
@@ -1,5 +1,5 @@
 import React, { useState } from 'react';
-import { Button, Dropdown, Row, Col } from 'react-bootstrap';
+import { Button, Row, Col } from 'react-bootstrap';
 import { useTranslation } from 'react-i18next';
 import styles from 'style/app.module.css';
 import OrgActionItemCategories from 'components/OrgSettings/ActionItemCategories/OrgActionItemCategories';
@@ -62,34 +62,6 @@ function OrgSettings(): JSX.Element {
               </Button>
             ))}
           </div>
-
-          {/* Dropdown menu for selecting settings category */}
-          <Dropdown
-            className={styles.settingsDropdown}
-            data-testid="settingsDropdownContainer"
-            drop="down"
-          >
-            <Dropdown.Toggle
-              variant="success"
-              id="dropdown-basic"
-              data-testid="settingsDropdownToggle"
-            >
-              <span className="me-1">{t(tab)}</span>
-            </Dropdown.Toggle>
-            <Dropdown.Menu>
-              {/* Render dropdown items for each settings category */}
-              {settingtabs.map((setting, index) => (
-                <Dropdown.Item
-                  key={index}
-                  role="menuitem"
-                  onClick={() => setTab(setting)}
-                  className={tab === setting ? 'text-secondary' : ''}
-                >
-                  {t(setting)}
-                </Dropdown.Item>
-              ))}
-            </Dropdown.Menu>
-          </Dropdown>
         </Col>
 
         <Row className="mt-3">
diff --git a/src/screens/OrganizationActionItems/OrganizationActionItems.spec.tsx b/src/screens/OrganizationActionItems/OrganizationActionItems.spec.tsx
index 7ae0fc58eb..89bcc5d824 100644
--- a/src/screens/OrganizationActionItems/OrganizationActionItems.spec.tsx
+++ b/src/screens/OrganizationActionItems/OrganizationActionItems.spec.tsx
@@ -252,11 +252,11 @@ describe('Testing Organization Action Items Screen', () => {
     });
 
     await waitFor(() => {
-      expect(screen.getByTestId('statusAll')).toBeInTheDocument();
+      expect(screen.getByTestId('all')).toBeInTheDocument();
     });
 
     await act(() => {
-      fireEvent.click(screen.getByTestId('statusAll'));
+      fireEvent.click(screen.getByTestId('all'));
     });
 
     await waitFor(() => {
@@ -269,11 +269,11 @@ describe('Testing Organization Action Items Screen', () => {
     });
 
     await waitFor(() => {
-      expect(screen.getByTestId('statusPending')).toBeInTheDocument();
+      expect(screen.getByTestId('pending')).toBeInTheDocument();
     });
 
     await act(() => {
-      fireEvent.click(screen.getByTestId('statusPending'));
+      fireEvent.click(screen.getByTestId('pending'));
     });
 
     await waitFor(() => {
@@ -314,11 +314,11 @@ describe('Testing Organization Action Items Screen', () => {
     });
 
     await waitFor(() => {
-      expect(screen.getByTestId('statusCompleted')).toBeInTheDocument();
+      expect(screen.getByTestId('completed')).toBeInTheDocument();
     });
 
     await act(() => {
-      fireEvent.click(screen.getByTestId('statusCompleted'));
+      fireEvent.click(screen.getByTestId('completed'));
     });
 
     await waitFor(() => {
diff --git a/src/screens/OrganizationActionItems/OrganizationActionItems.tsx b/src/screens/OrganizationActionItems/OrganizationActionItems.tsx
index 6061ba7e7d..e3d55648b0 100644
--- a/src/screens/OrganizationActionItems/OrganizationActionItems.tsx
+++ b/src/screens/OrganizationActionItems/OrganizationActionItems.tsx
@@ -1,15 +1,9 @@
-import React, { useCallback, useMemo, useState } from 'react';
+import React, { useCallback, useMemo, useState, useEffect } from 'react';
 import { useTranslation } from 'react-i18next';
-import { Button, Dropdown, Form } from 'react-bootstrap';
+import { Button, Form } from 'react-bootstrap';
 import { Navigate, useParams } from 'react-router-dom';
 
-import {
-  Circle,
-  FilterAltOutlined,
-  Search,
-  Sort,
-  WarningAmberRounded,
-} from '@mui/icons-material';
+import { Circle, Search, WarningAmberRounded } from '@mui/icons-material';
 import dayjs from 'dayjs';
 
 import { useQuery } from '@apollo/client';
@@ -32,6 +26,7 @@ import ItemModal from './ItemModal';
 import ItemDeleteModal from './ItemDeleteModal';
 import Avatar from 'components/Avatar/Avatar';
 import ItemUpdateStatusModal from './ItemUpdateStatusModal';
+import SortingButton from 'subComponents/SortingButton';
 
 enum ItemStatus {
   Pending = 'pending',
@@ -141,6 +136,11 @@ function organizationActionItems(): JSX.Element {
     [],
   );
 
+  // Trigger refetch on sortBy or status change
+  useEffect(() => {
+    actionItemsRefetch();
+  }, [sortBy, status, actionItemsRefetch]);
+
   if (actionItemsLoading) {
     return <Loader size="xl" />;
   }
@@ -388,89 +388,57 @@ function organizationActionItems(): JSX.Element {
           </Button>
         </div>
         <div className="d-flex gap-3 mb-1">
-          <div className="d-flex justify-space-between align-items-center gap-3 overflow-y-auto">
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdown}
-                data-testid="searchByToggle"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('searchBy', { item: '' })}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSearchBy('assignee')}
-                  data-testid="assignee"
-                >
-                  {t('assignee')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSearchBy('category')}
-                  data-testid="category"
-                >
-                  {t('category')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdown}
-                data-testid="sort"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSortBy('dueDate_DESC')}
-                  data-testid="dueDate_DESC"
-                >
-                  {t('latestDueDate')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('dueDate_ASC')}
-                  data-testid="dueDate_ASC"
-                >
-                  {t('earliestDueDate')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdown}
-                data-testid="filter"
-              >
-                <FilterAltOutlined className={'me-1'} />
-                {t('status')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setStatus(null)}
-                  data-testid="statusAll"
-                >
-                  {tCommon('all')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setStatus(ItemStatus.Pending)}
-                  data-testid="statusPending"
-                >
-                  {tCommon('pending')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setStatus(ItemStatus.Completed)}
-                  data-testid="statusCompleted"
-                >
-                  {tCommon('completed')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-          </div>
+          <SortingButton
+            title={tCommon('searchBy')}
+            sortingOptions={[
+              { label: t('assignee'), value: 'assignee' },
+              { label: t('category'), value: 'category' },
+            ]}
+            selectedOption={t(searchBy)}
+            onSortChange={(value) =>
+              setSearchBy(value as 'assignee' | 'category')
+            }
+            dataTestIdPrefix="searchByToggle"
+            buttonLabel={tCommon('searchBy', { item: '' })}
+            className={styles.dropdown} // Pass a custom class name if needed
+          />
+          <SortingButton
+            title={tCommon('sort')}
+            sortingOptions={[
+              { label: t('latestDueDate'), value: 'dueDate_DESC' },
+              { label: t('earliestDueDate'), value: 'dueDate_ASC' },
+            ]}
+            selectedOption={t(
+              sortBy === 'dueDate_DESC' ? 'latestDueDate' : 'earliestDueDate',
+            )}
+            onSortChange={(value) =>
+              setSortBy(value as 'dueDate_DESC' | 'dueDate_ASC')
+            }
+            dataTestIdPrefix="sort"
+            buttonLabel={tCommon('sort')}
+            className={styles.dropdown} // Pass a custom class name if needed
+          />
+          <SortingButton
+            title={t('status')}
+            sortingOptions={[
+              { label: tCommon('all'), value: 'all' },
+              { label: tCommon('pending'), value: ItemStatus.Pending },
+              { label: tCommon('completed'), value: ItemStatus.Completed },
+            ]}
+            selectedOption={t(
+              status === null
+                ? 'all'
+                : status === ItemStatus.Pending
+                  ? 'pending'
+                  : 'completed',
+            )}
+            onSortChange={(value) =>
+              setStatus(value === 'all' ? null : (value as ItemStatus))
+            }
+            dataTestIdPrefix="filter"
+            buttonLabel={t('status')}
+            className={styles.dropdown} // Pass a custom class name if needed
+          />
           <div>
             <Button
               variant="success"
diff --git a/src/screens/OrganizationFundCampaign/CampaignModal.test.tsx b/src/screens/OrganizationFundCampaign/CampaignModal.spec.tsx
similarity index 95%
rename from src/screens/OrganizationFundCampaign/CampaignModal.test.tsx
rename to src/screens/OrganizationFundCampaign/CampaignModal.spec.tsx
index 2a5a61a22b..f20b1ace3d 100644
--- a/src/screens/OrganizationFundCampaign/CampaignModal.test.tsx
+++ b/src/screens/OrganizationFundCampaign/CampaignModal.spec.tsx
@@ -21,19 +21,21 @@ import { toast } from 'react-toastify';
 import { MOCKS, MOCK_ERROR } from './OrganizationFundCampaignMocks';
 import type { InterfaceCampaignModal } from './CampaignModal';
 import CampaignModal from './CampaignModal';
+import { vi } from 'vitest';
 
-jest.mock('react-toastify', () => ({
+vi.mock('react-toastify', () => ({
   toast: {
-    success: jest.fn(),
-    error: jest.fn(),
+    success: vi.fn(),
+    error: vi.fn(),
   },
 }));
 
-jest.mock('@mui/x-date-pickers/DateTimePicker', () => {
+vi.mock('@mui/x-date-pickers/DateTimePicker', async () => {
+  const actual = await vi.importActual(
+    '@mui/x-date-pickers/DesktopDateTimePicker',
+  );
   return {
-    DateTimePicker: jest.requireActual(
-      '@mui/x-date-pickers/DesktopDateTimePicker',
-    ).DesktopDateTimePicker,
+    DateTimePicker: actual.DesktopDateTimePicker,
   };
 });
 
@@ -46,7 +48,7 @@ const translations = JSON.parse(
 const campaignProps: InterfaceCampaignModal[] = [
   {
     isOpen: true,
-    hide: jest.fn(),
+    hide: vi.fn(),
     fundId: 'fundId',
     orgId: 'orgId',
     campaign: {
@@ -58,12 +60,12 @@ const campaignProps: InterfaceCampaignModal[] = [
       currency: 'USD',
       createdAt: '2021-01-01',
     },
-    refetchCampaign: jest.fn(),
+    refetchCampaign: vi.fn(),
     mode: 'create',
   },
   {
     isOpen: true,
-    hide: jest.fn(),
+    hide: vi.fn(),
     fundId: 'fundId',
     orgId: 'orgId',
     campaign: {
@@ -75,7 +77,7 @@ const campaignProps: InterfaceCampaignModal[] = [
       currency: 'USD',
       createdAt: '2021-01-01',
     },
-    refetchCampaign: jest.fn(),
+    refetchCampaign: vi.fn(),
     mode: 'edit',
   },
 ];
@@ -100,7 +102,7 @@ const renderCampaignModal = (
 
 describe('CampaignModal', () => {
   afterEach(() => {
-    jest.clearAllMocks();
+    vi.clearAllMocks();
     cleanup();
   });
 
diff --git a/src/screens/OrganizationFundCampaign/OrganizationFundCampagins.tsx b/src/screens/OrganizationFundCampaign/OrganizationFundCampagins.tsx
index 8a5455c663..184794bb17 100644
--- a/src/screens/OrganizationFundCampaign/OrganizationFundCampagins.tsx
+++ b/src/screens/OrganizationFundCampaign/OrganizationFundCampagins.tsx
@@ -1,12 +1,12 @@
 import { useQuery } from '@apollo/client';
-import { Search, Sort, WarningAmberRounded } from '@mui/icons-material';
+import { Search, WarningAmberRounded } from '@mui/icons-material';
 import { Stack, Typography, Breadcrumbs, Link } from '@mui/material';
 import {
   DataGrid,
   type GridCellParams,
   type GridColDef,
 } from '@mui/x-data-grid';
-import { Button, Dropdown, Form } from 'react-bootstrap';
+import { Button, Form } from 'react-bootstrap';
 import { useTranslation } from 'react-i18next';
 import { Navigate, useNavigate, useParams } from 'react-router-dom';
 import React, { useCallback, useMemo, useState } from 'react';
@@ -20,6 +20,7 @@ import type {
   InterfaceCampaignInfo,
   InterfaceQueryOrganizationFundCampaigns,
 } from 'utils/interfaces';
+import SortingButton from 'subComponents/SortingButton';
 
 const dataGridStyle = {
   '&.MuiDataGrid-root .MuiDataGrid-cell:focus-within': {
@@ -360,43 +361,25 @@ const orgFundCampaign = (): JSX.Element => {
         </div>
         <div className={styles.btnsBbtnsBlockOrganizationFundCampaignlock}>
           <div className="d-flex justify-space-between">
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdownOrganizationFundCampaign}
-                data-testid="filter"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSortBy('fundingGoal_ASC')}
-                  data-testid="fundingGoal_ASC"
-                >
-                  {t('lowestGoal')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('fundingGoal_DESC')}
-                  data-testid="fundingGoal_DESC"
-                >
-                  {t('highestGoal')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('endDate_DESC')}
-                  data-testid="endDate_DESC"
-                >
-                  {t('latestEndDate')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('endDate_ASC')}
-                  data-testid="endDate_ASC"
-                >
-                  {t('earliestEndDate')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              sortingOptions={[
+                { label: t('lowestGoal'), value: 'fundingGoal_ASC' },
+                { label: t('highestGoal'), value: 'fundingGoal_DESC' },
+                { label: t('latestEndDate'), value: 'endDate_DESC' },
+                { label: t('earliestEndDate'), value: 'endDate_ASC' },
+              ]}
+              onSortChange={(value) =>
+                setSortBy(
+                  value as
+                    | 'fundingGoal_ASC'
+                    | 'fundingGoal_DESC'
+                    | 'endDate_ASC'
+                    | 'endDate_DESC',
+                )
+              }
+              dataTestIdPrefix="filter"
+              buttonLabel={tCommon('sort')}
+            />
           </div>
           <div>
             <Button
diff --git a/src/screens/OrganizationFundCampaign/OrganizationFundCampaign.test.tsx b/src/screens/OrganizationFundCampaign/OrganizationFundCampaign.spec.tsx
similarity index 88%
rename from src/screens/OrganizationFundCampaign/OrganizationFundCampaign.test.tsx
rename to src/screens/OrganizationFundCampaign/OrganizationFundCampaign.spec.tsx
index 9c169e355a..68bbc325b0 100644
--- a/src/screens/OrganizationFundCampaign/OrganizationFundCampaign.test.tsx
+++ b/src/screens/OrganizationFundCampaign/OrganizationFundCampaign.spec.tsx
@@ -3,17 +3,11 @@ import { MockedProvider } from '@apollo/react-testing';
 import { LocalizationProvider } from '@mui/x-date-pickers';
 import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
 import type { RenderResult } from '@testing-library/react';
-import {
-  cleanup,
-  fireEvent,
-  render,
-  screen,
-  waitFor,
-} from '@testing-library/react';
+import { fireEvent, render, screen, waitFor } from '@testing-library/react';
 import userEvent from '@testing-library/user-event';
 import { I18nextProvider } from 'react-i18next';
 import { Provider } from 'react-redux';
-import { MemoryRouter, Route, Routes } from 'react-router-dom';
+import { MemoryRouter, Route, Routes, useParams } from 'react-router-dom';
 import { store } from '../../state/store';
 import { StaticMockLink } from '../../utils/StaticMockLink';
 import i18nForTest from '../../utils/i18nForTest';
@@ -24,19 +18,21 @@ import {
   MOCK_ERROR,
 } from './OrganizationFundCampaignMocks';
 import type { ApolloLink } from '@apollo/client';
+import { vi } from 'vitest';
 
-jest.mock('react-toastify', () => ({
+vi.mock('react-toastify', () => ({
   toast: {
-    success: jest.fn(),
-    error: jest.fn(),
+    success: vi.fn(),
+    error: vi.fn(),
   },
 }));
 
-jest.mock('@mui/x-date-pickers/DateTimePicker', () => {
+vi.mock('@mui/x-date-pickers/DateTimePicker', async () => {
+  const actual = await vi.importActual(
+    '@mui/x-date-pickers/DesktopDateTimePicker',
+  );
   return {
-    DateTimePicker: jest.requireActual(
-      '@mui/x-date-pickers/DesktopDateTimePicker',
-    ).DesktopDateTimePicker,
+    DateTimePicker: actual.DesktopDateTimePicker,
   };
 });
 
@@ -83,21 +79,25 @@ const renderFundCampaign = (link: ApolloLink): RenderResult => {
 
 describe('FundCampaigns Screen', () => {
   beforeEach(() => {
-    jest.mock('react-router-dom', () => ({
-      ...jest.requireActual('react-router-dom'),
-      useParams: () => ({ orgId: 'orgId', fundId: 'fundId' }),
-    }));
+    vi.mock('react-router-dom', async () => {
+      const actualDom = await vi.importActual('react-router-dom');
+      return {
+        ...actualDom,
+        useParams: vi.fn(),
+      };
+    });
   });
 
   afterEach(() => {
-    cleanup();
+    vi.clearAllMocks();
   });
 
-  afterAll(() => {
-    jest.clearAllMocks();
-  });
+  const mockRouteParams = (orgId = 'orgId', fundId = 'fundId'): void => {
+    vi.mocked(useParams).mockReturnValue({ orgId, fundId });
+  };
 
   it('should render the Campaign Pledge screen', async () => {
+    mockRouteParams();
     renderFundCampaign(link1);
     await waitFor(() => {
       expect(screen.getByTestId('searchFullName')).toBeInTheDocument();
@@ -108,6 +108,7 @@ describe('FundCampaigns Screen', () => {
   });
 
   it('should redirect to fallback URL if URL params are undefined', async () => {
+    mockRouteParams('', '');
     render(
       <MockedProvider addTypename={false} link={link1}>
         <MemoryRouter initialEntries={['/orgfundcampaign/']}>
@@ -136,6 +137,7 @@ describe('FundCampaigns Screen', () => {
   });
 
   it('open and close Create Campaign modal', async () => {
+    mockRouteParams();
     renderFundCampaign(link1);
 
     const addCampaignBtn = await screen.findByTestId('addCampaignBtn');
@@ -152,6 +154,7 @@ describe('FundCampaigns Screen', () => {
   });
 
   it('open and close update campaign modal', async () => {
+    mockRouteParams();
     renderFundCampaign(link1);
 
     await waitFor(() => {
@@ -174,6 +177,7 @@ describe('FundCampaigns Screen', () => {
   });
 
   it('Search the Campaigns list by Name', async () => {
+    mockRouteParams();
     renderFundCampaign(link1);
     const searchField = await screen.findByTestId('searchFullName');
     fireEvent.change(searchField, {
@@ -187,6 +191,7 @@ describe('FundCampaigns Screen', () => {
   });
 
   it('should render the Campaign screen with error', async () => {
+    mockRouteParams();
     renderFundCampaign(link2);
     await waitFor(() => {
       expect(screen.getByTestId('errorMsg')).toBeInTheDocument();
@@ -194,6 +199,7 @@ describe('FundCampaigns Screen', () => {
   });
 
   it('renders the empty campaign component', async () => {
+    mockRouteParams();
     renderFundCampaign(link3);
     await waitFor(() =>
       expect(
@@ -203,6 +209,7 @@ describe('FundCampaigns Screen', () => {
   });
 
   it('Sort the Campaigns list by Latest end Date', async () => {
+    mockRouteParams();
     renderFundCampaign(link1);
 
     const sortBtn = await screen.findByTestId('filter');
@@ -224,6 +231,7 @@ describe('FundCampaigns Screen', () => {
   });
 
   it('Sort the Campaigns list by Earliest end Date', async () => {
+    mockRouteParams();
     renderFundCampaign(link1);
 
     const sortBtn = await screen.findByTestId('filter');
@@ -245,6 +253,7 @@ describe('FundCampaigns Screen', () => {
   });
 
   it('Sort the Campaigns list by lowest goal', async () => {
+    mockRouteParams();
     renderFundCampaign(link1);
 
     const sortBtn = await screen.findByTestId('filter');
@@ -264,6 +273,7 @@ describe('FundCampaigns Screen', () => {
   });
 
   it('Sort the Campaigns list by highest goal', async () => {
+    mockRouteParams();
     renderFundCampaign(link1);
 
     const sortBtn = await screen.findByTestId('filter');
@@ -283,6 +293,7 @@ describe('FundCampaigns Screen', () => {
   });
 
   it('Click on Campaign Name', async () => {
+    mockRouteParams();
     renderFundCampaign(link1);
 
     const campaignName = await screen.findAllByTestId('campaignName');
@@ -295,6 +306,7 @@ describe('FundCampaigns Screen', () => {
   });
 
   it('Click on View Pledge', async () => {
+    mockRouteParams();
     renderFundCampaign(link1);
 
     const viewBtn = await screen.findAllByTestId('viewBtn');
@@ -307,6 +319,7 @@ describe('FundCampaigns Screen', () => {
   });
 
   it('should render the Fund screen on fund breadcrumb click', async () => {
+    mockRouteParams();
     renderFundCampaign(link1);
 
     const fundBreadcrumb = await screen.findByTestId('fundsLink');
diff --git a/src/screens/OrganizationFunds/OrganizationFunds.tsx b/src/screens/OrganizationFunds/OrganizationFunds.tsx
index 1935e5306e..6af889ab83 100644
--- a/src/screens/OrganizationFunds/OrganizationFunds.tsx
+++ b/src/screens/OrganizationFunds/OrganizationFunds.tsx
@@ -1,12 +1,12 @@
 import { useQuery } from '@apollo/client';
-import { Search, Sort, WarningAmberRounded } from '@mui/icons-material';
+import { Search, WarningAmberRounded } from '@mui/icons-material';
 import { Stack } from '@mui/material';
 import {
   DataGrid,
   type GridCellParams,
   type GridColDef,
 } from '@mui/x-data-grid';
-import { Button, Dropdown, Form } from 'react-bootstrap';
+import { Button, Form } from 'react-bootstrap';
 import { useTranslation } from 'react-i18next';
 import { Navigate, useNavigate, useParams } from 'react-router-dom';
 import React, { useCallback, useMemo, useState } from 'react';
@@ -16,6 +16,7 @@ import FundModal from './FundModal';
 import { FUND_LIST } from 'GraphQl/Queries/fundQueries';
 import styles from '../../style/app.module.css';
 import type { InterfaceFundInfo } from 'utils/interfaces';
+import SortingButton from 'subComponents/SortingButton';
 
 const dataGridStyle = {
   borderRadius: '20px',
@@ -307,33 +308,23 @@ const organizationFunds = (): JSX.Element => {
           </Button>
         </div>
         <div className="d-flex gap-4 mb-1">
-          <div className="d-flex justify-space-between align-items-center">
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdowns}
-                data-testid="filter"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSortBy('createdAt_DESC')}
-                  data-testid="createdAt_DESC"
-                >
-                  {t('createdLatest')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('createdAt_ASC')}
-                  data-testid="createdAt_ASC"
-                >
-                  {t('createdEarliest')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-          </div>
+          <SortingButton
+            title={tCommon('sort')}
+            sortingOptions={[
+              { label: t('createdLatest'), value: 'createdAt_DESC' },
+              { label: t('createdEarliest'), value: 'createdAt_ASC' },
+            ]}
+            selectedOption={
+              sortBy === 'createdAt_DESC'
+                ? t('createdLatest')
+                : t('createdEarliest')
+            }
+            onSortChange={(value) =>
+              setSortBy(value as 'createdAt_DESC' | 'createdAt_ASC')
+            }
+            dataTestIdPrefix="filter"
+            buttonLabel={tCommon('sort')}
+          />
           <div>
             <Button
               variant="success"
diff --git a/src/screens/OrganizationPeople/AddMember.tsx b/src/screens/OrganizationPeople/AddMember.tsx
index 3bdbc72c21..7743768611 100644
--- a/src/screens/OrganizationPeople/AddMember.tsx
+++ b/src/screens/OrganizationPeople/AddMember.tsx
@@ -21,7 +21,7 @@ import {
 import Loader from 'components/Loader/Loader';
 import type { ChangeEvent } from 'react';
 import React, { useEffect, useState } from 'react';
-import { Button, Dropdown, Form, InputGroup, Modal } from 'react-bootstrap';
+import { Button, Form, InputGroup, Modal } from 'react-bootstrap';
 import { useTranslation } from 'react-i18next';
 import { Link, useParams } from 'react-router-dom';
 import { toast } from 'react-toastify';
@@ -32,6 +32,7 @@ import type {
 } from 'utils/interfaces';
 import styles from '../../style/app.module.css';
 import Avatar from 'components/Avatar/Avatar';
+import SortingButton from 'subComponents/SortingButton';
 
 const StyledTableCell = styled(TableCell)(() => ({
   [`&.${tableCellClasses.head}`]: {
@@ -270,44 +271,27 @@ function AddMember(): JSX.Element {
     });
   };
 
+  const handleSortChange = (value: string): void => {
+    if (value === 'existingUser') {
+      openAddUserModal();
+    } else if (value === 'newUser') {
+      openCreateNewUserModal();
+    }
+  };
+
   return (
     <>
-      <Dropdown>
-        <Dropdown.Toggle
-          variant="success"
-          id="dropdown-basic"
-          className={styles.dropdown}
-          data-testid="addMembers"
-        >
-          {translateOrgPeople('addMembers')}
-        </Dropdown.Toggle>
-        <Dropdown.Menu>
-          <Dropdown.Item
-            id="existingUser"
-            data-value="existingUser"
-            data-name="existingUser"
-            data-testid="existingUser"
-            onClick={(): void => {
-              openAddUserModal();
-            }}
-          >
-            <Form.Label htmlFor="existingUser">
-              {translateOrgPeople('existingUser')}
-            </Form.Label>
-          </Dropdown.Item>
-          <Dropdown.Item
-            id="newUser"
-            data-value="newUser"
-            data-name="newUser"
-            data-testid="newUser"
-            onClick={(): void => {
-              openCreateNewUserModal();
-            }}
-          >
-            <label htmlFor="memberslist">{translateOrgPeople('newUser')}</label>
-          </Dropdown.Item>
-        </Dropdown.Menu>
-      </Dropdown>
+      <SortingButton
+        title={translateOrgPeople('addMembers')}
+        sortingOptions={[
+          { label: translateOrgPeople('existingUser'), value: 'existingUser' },
+          { label: translateOrgPeople('newUser'), value: 'newUser' },
+        ]}
+        selectedOption={translateOrgPeople('addMembers')}
+        onSortChange={handleSortChange}
+        dataTestIdPrefix="addMembers"
+        className={styles.dropdown}
+      />
 
       {/* Existing User Modal */}
       <Modal
diff --git a/src/screens/OrganizationPeople/OrganizationPeople.tsx b/src/screens/OrganizationPeople/OrganizationPeople.tsx
index 3bab1dda8b..4198cadaef 100644
--- a/src/screens/OrganizationPeople/OrganizationPeople.tsx
+++ b/src/screens/OrganizationPeople/OrganizationPeople.tsx
@@ -1,5 +1,5 @@
 import { useLazyQuery } from '@apollo/client';
-import { Delete, Search, Sort } from '@mui/icons-material';
+import { Delete, Search } from '@mui/icons-material';
 import {
   ORGANIZATIONS_LIST,
   ORGANIZATIONS_MEMBER_CONNECTION_LIST,
@@ -10,7 +10,7 @@ import OrgAdminListCard from 'components/OrgAdminListCard/OrgAdminListCard';
 import OrgPeopleListCard from 'components/OrgPeopleListCard/OrgPeopleListCard';
 import dayjs from 'dayjs';
 import React, { useEffect, useState } from 'react';
-import { Button, Dropdown, Form } from 'react-bootstrap';
+import { Button, Form } from 'react-bootstrap';
 import Row from 'react-bootstrap/Row';
 import { useTranslation } from 'react-i18next';
 import { Link, useLocation, useParams } from 'react-router-dom';
@@ -21,7 +21,7 @@ import { DataGrid } from '@mui/x-data-grid';
 import type { GridColDef, GridCellParams } from '@mui/x-data-grid';
 import { Stack } from '@mui/material';
 import Avatar from 'components/Avatar/Avatar';
-
+import SortingButton from 'subComponents/SortingButton';
 /**
  * OrganizationPeople component is used to display the list of members, admins and users of the organization.
  * It also provides the functionality to search the members, admins and users by their full name.
@@ -57,6 +57,7 @@ function organizationPeople(): JSX.Element {
   const [selectedMemId, setSelectedMemId] = React.useState<
     string | undefined
   >();
+
   const toggleRemoveModal = (): void => {
     setShowRemoveModal((prev) => !prev);
   };
@@ -139,7 +140,6 @@ function organizationPeople(): JSX.Element {
 
   const handleFullNameSearchChange = (e: React.FormEvent): void => {
     e.preventDefault();
-    /* istanbul ignore next */
     const [firstName, lastName] = userName.split(' ');
     const newFilterData = {
       firstName_contains: firstName || '',
@@ -184,18 +184,52 @@ function organizationPeople(): JSX.Element {
       headerAlign: 'center',
       headerClassName: `${styles.tableHeader}`,
       sortable: false,
+
       renderCell: (params: GridCellParams) => {
-        return params.row?.image ? (
-          <img
-            src={params.row?.image}
-            alt="avatar"
-            className={styles.TableImage}
-          />
-        ) : (
-          <Avatar
-            avatarStyle={styles.TableImage}
-            name={`${params.row.firstName} ${params.row.lastName}`}
-          />
+        // Fallback to a fixed width if computedWidth is unavailable
+        const columnWidth = params.colDef.computedWidth || 150;
+        const imageSize = Math.min(columnWidth * 0.6, 60); // Max size 40px, responsive scaling
+
+        return (
+          <div
+            style={{
+              display: 'flex',
+              justifyContent: 'center',
+              alignItems: 'center',
+              height: '100%',
+              width: '100%',
+            }}
+          >
+            {params.row?.image ? (
+              <img
+                src={params.row?.image}
+                alt="avatar"
+                style={{
+                  width: `${imageSize}px`,
+                  height: `${imageSize}px`,
+                  borderRadius: '50%',
+                  objectFit: 'cover',
+                }}
+              />
+            ) : (
+              <div
+                style={{
+                  width: `${imageSize}px`,
+                  height: `${imageSize}px`,
+                  fontSize: `${imageSize * 0.4}px`,
+                  display: 'flex',
+                  alignItems: 'center',
+                  justifyContent: 'center',
+                  borderRadius: '50%',
+                  backgroundColor: '#ccc',
+                }}
+              >
+                <Avatar
+                  name={`${params.row.firstName} ${params.row.lastName}`}
+                />
+              </div>
+            )}
+          </div>
         );
       },
     },
@@ -275,6 +309,11 @@ function organizationPeople(): JSX.Element {
       },
     },
   ];
+
+  const handleSortChange = (value: string): void => {
+    setState(value === 'users' ? 2 : value === 'members' ? 0 : 1);
+  };
+
   return (
     <>
       <Row className={styles.head}>
@@ -295,7 +334,7 @@ function organizationPeople(): JSX.Element {
                 />
                 <Button
                   type="submit"
-                  className={`${styles.searchButton} `}
+                  className={`${styles.searchButton}`}
                   data-testid={'searchbtn'}
                 >
                   <Search className={styles.searchIcon} />
@@ -303,70 +342,27 @@ function organizationPeople(): JSX.Element {
               </Form>
             </div>
             <div className={styles.btnsBlock}>
-              <Dropdown>
-                <Dropdown.Toggle
-                  variant="success"
-                  id="dropdown-basic"
-                  className={styles.dropdown}
-                  data-testid="role"
-                >
-                  <Sort />
-                  {t('sort')}
-                </Dropdown.Toggle>
-                <Dropdown.Menu>
-                  <Dropdown.Item
-                    d-inline
-                    id="userslist"
-                    data-value="userslist"
-                    className={styles.dropdownItem}
-                    data-name="displaylist"
-                    data-testid="users"
-                    defaultChecked={state == 2 ? true : false}
-                    onClick={(): void => {
-                      setState(2);
-                    }}
-                  >
-                    <Form.Label htmlFor="userslist">
-                      {tCommon('users')}
-                    </Form.Label>
-                  </Dropdown.Item>
-                  <Dropdown.Item
-                    d-inline
-                    id="memberslist"
-                    data-value="memberslist"
-                    className={styles.dropdownItem}
-                    data-name="displaylist"
-                    data-testid="members"
-                    defaultChecked={state == 0 ? true : false}
-                    onClick={(): void => {
-                      setState(0);
-                    }}
-                  >
-                    <Form.Label htmlFor="memberslist">
-                      {tCommon('members')}
-                    </Form.Label>
-                  </Dropdown.Item>
-                  <Dropdown.Item
-                    d-inline
-                    id="adminslist"
-                    data-value="adminslist"
-                    data-name="displaylist"
-                    className={styles.dropdownItem}
-                    data-testid="admins"
-                    defaultChecked={state == 1 ? true : false}
-                    onClick={(): void => {
-                      setState(1);
-                    }}
-                  >
-                    <Form.Label htmlFor="adminslist">
-                      {tCommon('admins')}
-                    </Form.Label>
-                  </Dropdown.Item>
-                </Dropdown.Menu>
-              </Dropdown>
+              <SortingButton
+                className={styles.dropdown}
+                title={tCommon('sort')}
+                sortingOptions={[
+                  { label: tCommon('users'), value: 'users' },
+                  { label: tCommon('members'), value: 'members' },
+                  { label: tCommon('admins'), value: 'admins' },
+                ]}
+                selectedOption={
+                  state === 2
+                    ? tCommon('users')
+                    : state === 0
+                      ? tCommon('members')
+                      : tCommon('admins')
+                }
+                onSortChange={handleSortChange}
+                dataTestIdPrefix="role"
+              />
             </div>
             <div className={styles.btnsBlock}>
-              <AddMember></AddMember>
+              <AddMember />
             </div>
           </div>
         </div>
diff --git a/src/screens/OrganizationTags/OrganizationTags.tsx b/src/screens/OrganizationTags/OrganizationTags.tsx
index 558eb4eaf8..0b233cfaef 100644
--- a/src/screens/OrganizationTags/OrganizationTags.tsx
+++ b/src/screens/OrganizationTags/OrganizationTags.tsx
@@ -1,13 +1,11 @@
 import { useMutation, useQuery } from '@apollo/client';
 import { WarningAmberRounded } from '@mui/icons-material';
-import SortIcon from '@mui/icons-material/Sort';
 import Loader from 'components/Loader/Loader';
 import { useNavigate, useParams, Link } from 'react-router-dom';
 import type { ChangeEvent } from 'react';
 import React, { useEffect, useState } from 'react';
 import { Form } from 'react-bootstrap';
 import Button from 'react-bootstrap/Button';
-import Dropdown from 'react-bootstrap/Dropdown';
 import Modal from 'react-bootstrap/Modal';
 import Row from 'react-bootstrap/Row';
 import { useTranslation } from 'react-i18next';
@@ -30,7 +28,7 @@ import { ORGANIZATION_USER_TAGS_LIST } from 'GraphQl/Queries/OrganizationQueries
 import { CREATE_USER_TAG } from 'GraphQl/Mutations/TagMutations';
 import InfiniteScroll from 'react-infinite-scroll-component';
 import InfiniteScrollLoader from 'components/InfiniteScrollLoader/InfiniteScrollLoader';
-
+import SortingButton from 'subComponents/SortingButton';
 /**
  * Component that renders the Organization Tags screen when the app navigates to '/orgtags/:orgId'.
  *
@@ -294,6 +292,10 @@ function OrganizationTags(): JSX.Element {
     },
   ];
 
+  const handleSortChange = (value: string): void => {
+    setTagSortOrder(value === 'latest' ? 'DESCENDING' : 'ASCENDING');
+  };
+
   return (
     <>
       <Row>
@@ -312,40 +314,24 @@ function OrganizationTags(): JSX.Element {
               />
             </div>
             <div className={styles.btnsBlock}>
-              <Dropdown
-                aria-expanded="false"
+              <SortingButton
                 title="Sort Tags"
-                data-testid="sort"
-              >
-                <Dropdown.Toggle
-                  variant="outline-success"
-                  data-testid="sortTags"
-                  className={styles.dropdown}
-                >
-                  <SortIcon className={'me-1'} />
-                  {tagSortOrder === 'DESCENDING'
+                sortingOptions={[
+                  { label: tCommon('Latest'), value: 'latest' },
+                  { label: tCommon('Oldest'), value: 'oldest' },
+                ]}
+                selectedOption={
+                  tagSortOrder === 'DESCENDING'
                     ? tCommon('Latest')
-                    : tCommon('Oldest')}
-                </Dropdown.Toggle>
-                <Dropdown.Menu>
-                  <Dropdown.Item
-                    data-testid="latest"
-                    onClick={() => setTagSortOrder('DESCENDING')}
-                  >
-                    {tCommon('Latest')}
-                  </Dropdown.Item>
-                  <Dropdown.Item
-                    data-testid="oldest"
-                    onClick={() => setTagSortOrder('ASCENDING')}
-                  >
-                    {tCommon('Oldest')}
-                  </Dropdown.Item>
-                </Dropdown.Menu>
-              </Dropdown>
+                    : tCommon('Oldest')
+                }
+                onSortChange={handleSortChange}
+                dataTestIdPrefix="sortTags"
+                className={styles.dropdown}
+              />
             </div>
             <div>
               <Button
-                // variant="success"
                 onClick={showCreateTagModal}
                 data-testid="createTagBtn"
                 className={`${styles.createButton} mb-2`}
diff --git a/src/screens/OrganizationVenues/OrganizationVenues.tsx b/src/screens/OrganizationVenues/OrganizationVenues.tsx
index 3914ed5748..82b30f3035 100644
--- a/src/screens/OrganizationVenues/OrganizationVenues.tsx
+++ b/src/screens/OrganizationVenues/OrganizationVenues.tsx
@@ -9,11 +9,12 @@ import { VENUE_LIST } from 'GraphQl/Queries/OrganizationQueries';
 import Loader from 'components/Loader/Loader';
 import { Navigate, useParams } from 'react-router-dom';
 import VenueModal from 'components/Venues/VenueModal';
-import { Dropdown, Form } from 'react-bootstrap';
-import { Search, Sort } from '@mui/icons-material';
+import { Form } from 'react-bootstrap';
+import { Search } from '@mui/icons-material';
 import { DELETE_VENUE_MUTATION } from 'GraphQl/Mutations/VenueMutations';
 import type { InterfaceQueryVenueListItem } from 'utils/interfaces';
 import VenueCard from 'components/Venues/VenueCard';
+import SortingButton from 'subComponents/SortingButton';
 
 /**
  * Component to manage and display the list of organization venues.
@@ -92,12 +93,16 @@ function organizationVenues(): JSX.Element {
     setSearchTerm(event.target.value);
   };
 
+  const handleSearchByChange = (value: string): void => {
+    setSearchBy(value as 'name' | 'desc');
+  };
+
   /**
    * Updates the sort order state when the user selects a sort option.
-   * @param order - The order to sort venues by (highest or lowest capacity).
+   * @param value - The order to sort venues by (highest or lowest capacity).
    */
-  const handleSortChange = (order: 'highest' | 'lowest'): void => {
-    setSortOrder(order);
+  const handleSortChange = (value: string): void => {
+    setSortOrder(value as 'highest' | 'lowest');
   };
 
   /**
@@ -157,73 +162,31 @@ function organizationVenues(): JSX.Element {
             <Search />
           </Button>
         </div>
-        <div className="d-flex gap-3 flex-wrap ">
-          <div className="d-flex gap-3 justify-content-between ">
-            <Dropdown
-              aria-expanded="false"
-              title="SearchBy"
-              data-tesid="searchByToggle"
-            >
-              <Dropdown.Toggle
-                data-testid="searchByDrpdwn"
-                variant="outline-success"
-                className={styles.dropdown}
-              >
-                <Sort className={'me-1'} />
-                {t('searchBy')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  id="searchName"
-                  onClick={(e): void => {
-                    setSearchBy('name');
-                    e.preventDefault();
-                  }}
-                  data-testid="name"
-                >
-                  {tCommon('name')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  id="searchDesc"
-                  onClick={(e): void => {
-                    setSearchBy('desc');
-                    e.preventDefault();
-                  }}
-                  data-testid="desc"
-                >
-                  {tCommon('description')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-            <Dropdown
-              aria-expanded="false"
-              title="Sort Venues"
-              data-testid="sort"
-            >
-              <Dropdown.Toggle
-                variant="outline-success"
-                data-testid="sortVenues"
-                className={styles.dropdown}
-              >
-                <Sort className={'me-1'} />
-                {t('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={(): void => handleSortChange('highest')}
-                  data-testid="highest"
-                >
-                  {t('highestCapacity')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={(): void => handleSortChange('lowest')}
-                  data-testid="lowest"
-                >
-                  {t('lowestCapacity')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-          </div>
+        <div className="d-flex gap-3 flex-wrap">
+          <SortingButton
+            title="SearchBy"
+            sortingOptions={[
+              { label: tCommon('name'), value: 'name' },
+              { label: tCommon('description'), value: 'desc' },
+            ]}
+            selectedOption={tCommon(searchBy)}
+            onSortChange={handleSearchByChange}
+            dataTestIdPrefix="searchByDrpdwn"
+            className={styles.dropdown} // Pass a custom class name if needed
+          />
+          <SortingButton
+            title="Sort Venues"
+            sortingOptions={[
+              { label: t('highestCapacity'), value: 'highest' },
+              { label: t('lowestCapacity'), value: 'lowest' },
+            ]}
+            selectedOption={t(
+              sortOrder === 'highest' ? 'highestCapacity' : 'lowestCapacity',
+            )}
+            onSortChange={handleSortChange}
+            dataTestIdPrefix="sortVenues"
+            className={styles.dropdown} // Pass a custom class name if needed
+          />
           <Button
             variant="success"
             className={styles.dropdown}
diff --git a/src/screens/SubTags/SubTags.spec.tsx b/src/screens/SubTags/SubTags.spec.tsx
index 6db92bcab6..e61d3c98db 100644
--- a/src/screens/SubTags/SubTags.spec.tsx
+++ b/src/screens/SubTags/SubTags.spec.tsx
@@ -284,9 +284,9 @@ describe('Organisation Tags Page', () => {
     userEvent.click(screen.getByTestId('sortTags'));
 
     await waitFor(() => {
-      expect(screen.getByTestId('oldest')).toBeInTheDocument();
+      expect(screen.getByTestId('ASCENDING')).toBeInTheDocument();
     });
-    userEvent.click(screen.getByTestId('oldest'));
+    userEvent.click(screen.getByTestId('ASCENDING'));
 
     // returns the tags in reverse order
     await waitFor(() => {
@@ -301,9 +301,9 @@ describe('Organisation Tags Page', () => {
     userEvent.click(screen.getByTestId('sortTags'));
 
     await waitFor(() => {
-      expect(screen.getByTestId('latest')).toBeInTheDocument();
+      expect(screen.getByTestId('DESCENDING')).toBeInTheDocument();
     });
-    userEvent.click(screen.getByTestId('latest'));
+    userEvent.click(screen.getByTestId('DESCENDING'));
 
     // reverse the order again
     await waitFor(() => {
diff --git a/src/screens/SubTags/SubTags.tsx b/src/screens/SubTags/SubTags.tsx
index 6a20e875ec..034c7dfea9 100644
--- a/src/screens/SubTags/SubTags.tsx
+++ b/src/screens/SubTags/SubTags.tsx
@@ -1,6 +1,5 @@
 import { useMutation, useQuery } from '@apollo/client';
 import { Search, WarningAmberRounded } from '@mui/icons-material';
-import SortIcon from '@mui/icons-material/Sort';
 import Loader from 'components/Loader/Loader';
 import IconComponent from 'components/IconComponent/IconComponent';
 import { useNavigate, useParams, Link } from 'react-router-dom';
@@ -8,7 +7,6 @@ import type { ChangeEvent } from 'react';
 import React, { useState } from 'react';
 import { Form } from 'react-bootstrap';
 import Button from 'react-bootstrap/Button';
-import Dropdown from 'react-bootstrap/Dropdown';
 import Modal from 'react-bootstrap/Modal';
 import Row from 'react-bootstrap/Row';
 import { useTranslation } from 'react-i18next';
@@ -30,6 +28,7 @@ import { CREATE_USER_TAG } from 'GraphQl/Mutations/TagMutations';
 import { USER_TAG_SUB_TAGS } from 'GraphQl/Queries/userTagQueries';
 import InfiniteScroll from 'react-infinite-scroll-component';
 import InfiniteScrollLoader from 'components/InfiniteScrollLoader/InfiniteScrollLoader';
+import SortingButton from 'subComponents/SortingButton';
 
 /**
  * Component that renders the SubTags screen when the app navigates to '/orgtags/:orgId/subtags/:tagId'.
@@ -301,37 +300,16 @@ function SubTags(): JSX.Element {
               </Button>
             </div>
 
-            <Dropdown
-              title="Sort Tag"
-              // className={styles.dropdown}
-              // className="ms-4 mb-4"
-              data-testid="sort"
-            >
-              <Dropdown.Toggle
-                data-testid="sortTags"
-                // className="color-red"
-                className={styles.dropdown}
-              >
-                <SortIcon className={'me-1'} />
-                {tagSortOrder === 'DESCENDING'
-                  ? tCommon('Latest')
-                  : tCommon('Oldest')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  data-testid="latest"
-                  onClick={() => setTagSortOrder('DESCENDING')}
-                >
-                  {tCommon('Latest')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  data-testid="oldest"
-                  onClick={() => setTagSortOrder('ASCENDING')}
-                >
-                  {tCommon('Oldest')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              sortingOptions={[
+                { label: tCommon('Latest'), value: 'DESCENDING' },
+                { label: tCommon('Oldest'), value: 'ASCENDING' },
+              ]}
+              selectedOption={tagSortOrder}
+              onSortChange={(value) => setTagSortOrder(value as SortedByType)}
+              dataTestIdPrefix="sortTags"
+              buttonLabel={tCommon('sort')}
+            />
 
             <Button
               onClick={() => redirectToManageTag(parentTagId as string)}
diff --git a/src/screens/UserPortal/Campaigns/Campaigns.tsx b/src/screens/UserPortal/Campaigns/Campaigns.tsx
index e4483f87fe..cf6af795d3 100644
--- a/src/screens/UserPortal/Campaigns/Campaigns.tsx
+++ b/src/screens/UserPortal/Campaigns/Campaigns.tsx
@@ -1,9 +1,9 @@
 import React, { useEffect, useState } from 'react';
-import { Dropdown, Form, Button, ProgressBar } from 'react-bootstrap';
+import { Form, Button, ProgressBar } from 'react-bootstrap';
 import styles from './Campaigns.module.css';
 import { useTranslation } from 'react-i18next';
 import { Navigate, useNavigate, useParams } from 'react-router-dom';
-import { Circle, Search, Sort, WarningAmberRounded } from '@mui/icons-material';
+import { Circle, Search, WarningAmberRounded } from '@mui/icons-material';
 import {
   Accordion,
   AccordionDetails,
@@ -19,6 +19,7 @@ import { useQuery } from '@apollo/client';
 import type { InterfaceUserCampaign } from 'utils/interfaces';
 import { currencySymbols } from 'utils/currency';
 import Loader from 'components/Loader/Loader';
+import SortingButton from 'subComponents/SortingButton';
 
 /**
  * The `Campaigns` component displays a list of fundraising campaigns for a specific organization.
@@ -150,44 +151,26 @@ const Campaigns = (): JSX.Element => {
         </div>
         <div className="d-flex gap-4 mb-1">
           <div className="d-flex justify-space-between">
-            {/* Dropdown menu for sorting campaigns */}
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdown}
-                data-testid="filter"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSortBy('fundingGoal_ASC')}
-                  data-testid="fundingGoal_ASC"
-                >
-                  {t('lowestGoal')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('fundingGoal_DESC')}
-                  data-testid="fundingGoal_DESC"
-                >
-                  {t('highestGoal')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('endDate_DESC')}
-                  data-testid="endDate_DESC"
-                >
-                  {t('latestEndDate')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('endDate_ASC')}
-                  data-testid="endDate_ASC"
-                >
-                  {t('earliestEndDate')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              sortingOptions={[
+                { label: t('lowestGoal'), value: 'fundingGoal_ASC' },
+                { label: t('highestGoal'), value: 'fundingGoal_DESC' },
+                { label: t('latestEndDate'), value: 'endDate_DESC' },
+                { label: t('earliestEndDate'), value: 'endDate_ASC' },
+              ]}
+              selectedOption={sortBy}
+              onSortChange={(value) =>
+                setSortBy(
+                  value as
+                    | 'fundingGoal_ASC'
+                    | 'fundingGoal_DESC'
+                    | 'endDate_ASC'
+                    | 'endDate_DESC',
+                )
+              }
+              dataTestIdPrefix="filter"
+              buttonLabel={tCommon('sort')}
+            />
           </div>
           <div>
             {/* Button to navigate to the user's pledges */}
diff --git a/src/screens/UserPortal/Pledges/Pledges.tsx b/src/screens/UserPortal/Pledges/Pledges.tsx
index 33e8bf63c2..2ab8214265 100644
--- a/src/screens/UserPortal/Pledges/Pledges.tsx
+++ b/src/screens/UserPortal/Pledges/Pledges.tsx
@@ -1,8 +1,8 @@
 import React, { useCallback, useEffect, useState } from 'react';
-import { Dropdown, Form, Button, ProgressBar } from 'react-bootstrap';
+import { Form, Button, ProgressBar } from 'react-bootstrap';
 import styles from './Pledges.module.css';
 import { useTranslation } from 'react-i18next';
-import { Search, Sort, WarningAmberRounded } from '@mui/icons-material';
+import { Search, WarningAmberRounded } from '@mui/icons-material';
 import useLocalStorage from 'utils/useLocalstorage';
 import type { InterfacePledgeInfo, InterfaceUserInfo } from 'utils/interfaces';
 import { Unstable_Popup as BasePopup } from '@mui/base/Unstable_Popup';
@@ -21,6 +21,7 @@ import { currencySymbols } from 'utils/currency';
 import PledgeDeleteModal from 'screens/FundCampaignPledge/PledgeDeleteModal';
 import { Navigate, useParams } from 'react-router-dom';
 import PledgeModal from '../Campaigns/PledgeModal';
+import SortingButton from 'subComponents/SortingButton';
 
 const dataGridStyle = {
   '&.MuiDataGrid-root .MuiDataGrid-cell:focus-within': {
@@ -393,75 +394,40 @@ const Pledges = (): JSX.Element => {
             <Search />
           </Button>
         </div>
-        <div className="d-flex gap-4 mb-1">
-          <Dropdown
-            aria-expanded="false"
-            title="SearchBy"
-            data-tesid="searchByToggle"
-            className="flex-fill"
-          >
-            <Dropdown.Toggle
-              data-testid="searchByDrpdwn"
-              variant="outline-success"
-            >
-              <Sort className={'me-1'} />
-              {t('searchBy')}
-            </Dropdown.Toggle>
-            <Dropdown.Menu>
-              <Dropdown.Item
-                id="searchPledgers"
-                onClick={(): void => setSearchBy('pledgers')}
-                data-testid="pledgers"
-              >
-                {t('pledgers')}
-              </Dropdown.Item>
-              <Dropdown.Item
-                id="searchCampaigns"
-                onClick={(): void => setSearchBy('campaigns')}
-                data-testid="campaigns"
-              >
-                {t('campaigns')}
-              </Dropdown.Item>
-            </Dropdown.Menu>
-          </Dropdown>
+        <div className="d-flex gap-4 ">
+          <SortingButton
+            sortingOptions={[
+              { label: t('pledgers'), value: 'pledgers' },
+              { label: t('campaigns'), value: 'campaigns' },
+            ]}
+            selectedOption={searchBy}
+            onSortChange={(value) =>
+              setSearchBy(value as 'pledgers' | 'campaigns')
+            }
+            dataTestIdPrefix="searchByDrpdwn"
+            buttonLabel={t('searchBy')}
+          />
 
-          <Dropdown>
-            <Dropdown.Toggle
-              variant="success"
-              id="dropdown-basic"
-              className={styles.dropdown}
-              data-testid="filter"
-            >
-              <Sort className={'me-1'} />
-              {tCommon('sort')}
-            </Dropdown.Toggle>
-            <Dropdown.Menu>
-              <Dropdown.Item
-                onClick={() => setSortBy('amount_ASC')}
-                data-testid="amount_ASC"
-              >
-                {t('lowestAmount')}
-              </Dropdown.Item>
-              <Dropdown.Item
-                onClick={() => setSortBy('amount_DESC')}
-                data-testid="amount_DESC"
-              >
-                {t('highestAmount')}
-              </Dropdown.Item>
-              <Dropdown.Item
-                onClick={() => setSortBy('endDate_DESC')}
-                data-testid="endDate_DESC"
-              >
-                {t('latestEndDate')}
-              </Dropdown.Item>
-              <Dropdown.Item
-                onClick={() => setSortBy('endDate_ASC')}
-                data-testid="endDate_ASC"
-              >
-                {t('earliestEndDate')}
-              </Dropdown.Item>
-            </Dropdown.Menu>
-          </Dropdown>
+          <SortingButton
+            sortingOptions={[
+              { label: t('lowestAmount'), value: 'amount_ASC' },
+              { label: t('highestAmount'), value: 'amount_DESC' },
+              { label: t('latestEndDate'), value: 'endDate_DESC' },
+              { label: t('earliestEndDate'), value: 'endDate_ASC' },
+            ]}
+            selectedOption={sortBy}
+            onSortChange={(value) =>
+              setSortBy(
+                value as
+                  | 'amount_ASC'
+                  | 'amount_DESC'
+                  | 'endDate_ASC'
+                  | 'endDate_DESC',
+              )
+            }
+            dataTestIdPrefix="filter"
+            buttonLabel={tCommon('sort')}
+          />
         </div>
       </div>
 
diff --git a/src/screens/UserPortal/Posts/Posts.test.tsx b/src/screens/UserPortal/Posts/Posts.spec.tsx
similarity index 89%
rename from src/screens/UserPortal/Posts/Posts.test.tsx
rename to src/screens/UserPortal/Posts/Posts.spec.tsx
index 433e36f94a..83b626ba20 100644
--- a/src/screens/UserPortal/Posts/Posts.test.tsx
+++ b/src/screens/UserPortal/Posts/Posts.spec.tsx
@@ -16,17 +16,29 @@ import i18nForTest from 'utils/i18nForTest';
 import Home from './Posts';
 import useLocalStorage from 'utils/useLocalstorage';
 import { DELETE_POST_MUTATION } from 'GraphQl/Mutations/mutations';
+import { expect, describe, it, vi } from 'vitest';
 
 const { setItem } = useLocalStorage();
 
-jest.mock('react-toastify', () => ({
+vi.mock('react-toastify', () => ({
   toast: {
-    error: jest.fn(),
-    info: jest.fn(),
-    success: jest.fn(),
+    error: vi.fn(),
+    info: vi.fn(),
+    success: vi.fn(),
   },
 }));
 
+const mockUseParams = vi.fn().mockReturnValue({ orgId: 'orgId' });
+
+vi.mock('react-router-dom', async () => {
+  const actual = await vi.importActual('react-router-dom');
+  return {
+    ...actual,
+    useParams: () => mockUseParams(),
+    useNavigate: () => vi.fn(),
+  };
+});
+
 const MOCKS = [
   {
     request: {
@@ -262,31 +274,27 @@ const renderHomeScreen = (): RenderResult =>
 
 Object.defineProperty(window, 'matchMedia', {
   writable: true,
-  value: jest.fn().mockImplementation((query) => ({
+  value: vi.fn().mockImplementation((query) => ({
     matches: false,
     media: query,
     onchange: null,
-    addListener: jest.fn(), // Deprecated
-    removeListener: jest.fn(), // Deprecated
-    addEventListener: jest.fn(),
-    removeEventListener: jest.fn(),
-    dispatchEvent: jest.fn(),
+    addListener: vi.fn(), // Deprecated
+    removeListener: vi.fn(), // Deprecated
+    addEventListener: vi.fn(),
+    removeEventListener: vi.fn(),
+    dispatchEvent: vi.fn(),
   })),
 });
 
 describe('Testing Home Screen: User Portal', () => {
-  beforeAll(() => {
-    jest.mock('react-router-dom', () => ({
-      ...jest.requireActual('react-router-dom'),
-      useParams: () => ({ orgId: 'orgId' }),
-    }));
+  beforeEach(() => {
+    mockUseParams.mockReturnValue({ orgId: 'orgId' });
   });
-
   afterAll(() => {
-    jest.clearAllMocks();
+    vi.clearAllMocks();
   });
 
-  test('Check if HomeScreen renders properly', async () => {
+  it('Check if HomeScreen renders properly', async () => {
     renderHomeScreen();
 
     await wait();
@@ -294,7 +302,7 @@ describe('Testing Home Screen: User Portal', () => {
     expect(startPostBtn).toBeInTheDocument();
   });
 
-  test('StartPostModal should render on click of StartPost btn', async () => {
+  it('StartPostModal should render on click of StartPost btn', async () => {
     renderHomeScreen();
 
     await wait();
@@ -306,7 +314,7 @@ describe('Testing Home Screen: User Portal', () => {
     expect(startPostModal).toBeInTheDocument();
   });
 
-  test('StartPostModal should close on clicking the close button', async () => {
+  it('StartPostModal should close on clicking the close button', async () => {
     renderHomeScreen();
 
     await wait();
@@ -325,7 +333,6 @@ describe('Testing Home Screen: User Portal', () => {
 
     userEvent.type(screen.getByTestId('postInput'), 'some content');
 
-    // Check that the content and image have been added
     expect(screen.getByTestId('postInput')).toHaveValue('some content');
     await screen.findByAltText('Post Image Preview');
     expect(screen.getByAltText('Post Image Preview')).toBeInTheDocument();
@@ -342,7 +349,7 @@ describe('Testing Home Screen: User Portal', () => {
     expect(screen.getByTestId('postImageInput')).toHaveValue('');
   });
 
-  test('Check whether Posts render in PostCard', async () => {
+  it('Check whether Posts render in PostCard', async () => {
     setItem('userId', '640d98d9eb6a743d75341067');
     renderHomeScreen();
     await wait();
@@ -359,7 +366,7 @@ describe('Testing Home Screen: User Portal', () => {
     expect(screen.queryByText('This is the post two')).toBeInTheDocument();
   });
 
-  test('Checking if refetch works after deleting this post', async () => {
+  it('Checking if refetch works after deleting this post', async () => {
     setItem('userId', '640d98d9eb6a743d75341067');
     renderHomeScreen();
     expect(screen.queryAllByTestId('dropdown')).not.toBeNull();
@@ -371,11 +378,15 @@ describe('Testing Home Screen: User Portal', () => {
 });
 
 describe('HomeScreen with invalid orgId', () => {
-  test('Redirect to /user when organizationId is falsy', async () => {
-    jest.mock('react-router-dom', () => ({
-      ...jest.requireActual('react-router-dom'),
-      useParams: () => ({ orgId: undefined }),
-    }));
+  beforeEach(() => {
+    mockUseParams.mockReturnValue({ orgId: undefined });
+  });
+
+  afterEach(() => {
+    vi.clearAllMocks();
+  });
+
+  it('Redirect to /user when organizationId is falsy', async () => {
     render(
       <MockedProvider addTypename={false} link={link}>
         <MemoryRouter initialEntries={['/user/organization/']}>
diff --git a/src/screens/UserPortal/Settings/Settings.spec.tsx b/src/screens/UserPortal/Settings/Settings.spec.tsx
index 184789ab04..f24c59d50a 100644
--- a/src/screens/UserPortal/Settings/Settings.spec.tsx
+++ b/src/screens/UserPortal/Settings/Settings.spec.tsx
@@ -12,6 +12,21 @@ import { StaticMockLink } from 'utils/StaticMockLink';
 import Settings from './Settings';
 import userEvent from '@testing-library/user-event';
 import { CHECK_AUTH } from 'GraphQl/Queries/Queries';
+import { toast } from 'react-toastify';
+import { errorHandler } from 'utils/errorHandler';
+
+vi.mock('react-toastify', () => ({
+  toast: {
+    success: vi.fn(),
+    warn: vi.fn(),
+    error: vi.fn(),
+  },
+}));
+
+vi.mock('utils/errorHandler', () => ({
+  errorHandler: vi.fn(),
+}));
+
 const MOCKS = [
   {
     request: {
@@ -109,9 +124,71 @@ const Mocks2 = [
   },
 ];
 
+const updateMock = [
+  {
+    request: {
+      query: UPDATE_USER_MUTATION,
+      variables: {
+        firstName: 'John',
+        lastName: 'randomUpdated',
+        createdAt: '2021-03-01T00:00:00.000Z',
+        gender: 'MALE',
+        email: 'johndoe@gmail.com',
+        phoneNumber: '+174567890',
+        birthDate: '2024-03-01',
+        grade: 'GRADUATE',
+        empStatus: 'PART_TIME',
+        maritalStatus: 'SINGLE',
+        address: 'random',
+        state: 'random',
+        country: 'IN',
+        eventsAttended: [{ _id: 'event1' }, { _id: 'event2' }],
+        image: '',
+      },
+    },
+    result: {
+      data: {
+        updateUserProfile: {
+          _id: '65ba1621b7b00c20e5f1d8d2',
+        },
+      },
+    },
+  },
+  ...Mocks1,
+];
+
+const errorMock = [
+  {
+    request: {
+      query: UPDATE_USER_MUTATION,
+      variables: {
+        firstName: 'John',
+        lastName: 'Doe2',
+        createdAt: '2021-03-01T00:00:00.000Z',
+        gender: 'MALE',
+        email: 'johndoe@gmail.com',
+        phoneNumber: '4567890',
+        birthDate: '2024-03-01',
+        grade: 'GRADUATE',
+        empStatus: 'PART_TIME',
+        maritalStatus: 'SINGLE',
+        address: 'random',
+        state: 'random',
+        country: 'IN',
+        eventsAttended: [{ _id: 'event1' }, { _id: 'event2' }],
+        image: '',
+      },
+    },
+    error: new Error('Please enter a valid phone number'),
+  },
+  ...Mocks1,
+];
+
 const link = new StaticMockLink(MOCKS, true);
 const link1 = new StaticMockLink(Mocks1, true);
 const link2 = new StaticMockLink(Mocks2, true);
+const link3 = new StaticMockLink(updateMock, true);
+const link4 = new StaticMockLink(errorMock, true);
 
 const resizeWindow = (width: number): void => {
   window.innerWidth = width;
@@ -443,3 +520,79 @@ it('prevents selecting future dates for birth date', async () => {
   fireEvent.change(birthDateInput, { target: { value: today } });
   expect(birthDateInput.value).toBe(today);
 });
+
+it('should update user profile successfully', async () => {
+  const toastSuccessSpy = vi.spyOn(toast, 'success');
+  await act(async () => {
+    render(
+      <MockedProvider link={link3} addTypename={false}>
+        <BrowserRouter>
+          <Provider store={store}>
+            <I18nextProvider i18n={i18nForTest}>
+              <Settings />
+            </I18nextProvider>
+          </Provider>
+        </BrowserRouter>
+      </MockedProvider>,
+    );
+  });
+
+  await wait();
+
+  const lastNameInput = screen.getByTestId('inputLastName');
+  expect(lastNameInput).toHaveValue('Doe');
+  await act(async () => {
+    fireEvent.change(lastNameInput, { target: { value: 'randomUpdated' } });
+  });
+
+  const saveButton = screen.getByTestId('updateUserBtn');
+  expect(saveButton).toBeInTheDocument();
+  await act(async () => {
+    fireEvent.click(saveButton);
+  });
+  await wait();
+
+  expect(lastNameInput).toHaveValue('randomUpdated');
+  expect(toastSuccessSpy).toHaveBeenCalledWith('Profile updated Successfully');
+
+  toastSuccessSpy.mockRestore();
+});
+
+it('should call errorHandler when updating profile with an invalid phone number', async () => {
+  await act(async () => {
+    render(
+      <MockedProvider link={link4} addTypename={false}>
+        <BrowserRouter>
+          <Provider store={store}>
+            <I18nextProvider i18n={i18nForTest}>
+              <Settings />
+            </I18nextProvider>
+          </Provider>
+        </BrowserRouter>
+      </MockedProvider>,
+    );
+  });
+
+  await wait(200);
+
+  const lastNameInput = screen.getByTestId('inputLastName');
+  await act(async () => {
+    fireEvent.change(lastNameInput, { target: { value: 'Doe2' } });
+  });
+
+  const phoneNumberInput = screen.getByTestId('inputPhoneNumber');
+
+  await act(async () => {
+    fireEvent.change(phoneNumberInput, { target: { value: '4567890' } });
+  });
+  await wait(200);
+
+  const saveButton = screen.getByTestId('updateUserBtn');
+  expect(saveButton).toBeInTheDocument();
+
+  await act(async () => {
+    fireEvent.click(saveButton);
+  });
+  await wait();
+  expect(errorHandler).toHaveBeenCalled();
+});
diff --git a/src/screens/UserPortal/Settings/Settings.tsx b/src/screens/UserPortal/Settings/Settings.tsx
index 385c3d639e..5f1313784c 100644
--- a/src/screens/UserPortal/Settings/Settings.tsx
+++ b/src/screens/UserPortal/Settings/Settings.tsx
@@ -92,7 +92,6 @@ export default function settings(): JSX.Element {
    * and reloads the page on success.
    */
 
-  /*istanbul ignore next*/
   const handleUpdateUserDetails = async (): Promise<void> => {
     try {
       let updatedUserDetails = { ...userDetails };
@@ -102,7 +101,6 @@ export default function settings(): JSX.Element {
       const { data } = await updateUserDetails({
         variables: updatedUserDetails,
       });
-      /* istanbul ignore next */
       if (data) {
         toast.success(
           tCommon('updatedSuccessfully', { item: 'Profile' }) as string,
@@ -114,7 +112,6 @@ export default function settings(): JSX.Element {
         setItem('name', userFullName);
       }
     } catch (error: unknown) {
-      /*istanbul ignore next*/
       errorHandler(t, error);
     }
   };
diff --git a/src/screens/UserPortal/UserScreen/UserScreen.spec.tsx b/src/screens/UserPortal/UserScreen/UserScreen.spec.tsx
index 65c5e6a650..95a1f633da 100644
--- a/src/screens/UserPortal/UserScreen/UserScreen.spec.tsx
+++ b/src/screens/UserPortal/UserScreen/UserScreen.spec.tsx
@@ -130,6 +130,25 @@ describe('UserScreen tests with LeftDrawer functionality', () => {
     expect(titleElement).toHaveTextContent('People');
   });
 
+  it('renders the correct title for chat', () => {
+    mockLocation = '/user/chat/123';
+
+    render(
+      <MockedProvider addTypename={false} link={link}>
+        <BrowserRouter>
+          <Provider store={store}>
+            <I18nextProvider i18n={i18nForTest}>
+              <UserScreen />
+            </I18nextProvider>
+          </Provider>
+        </BrowserRouter>
+      </MockedProvider>,
+    );
+
+    const titleElement = screen.getByRole('heading', { level: 1 });
+    expect(titleElement).toHaveTextContent('Chats');
+  });
+
   it('toggles LeftDrawer correctly based on window size and user interaction', () => {
     render(
       <MockedProvider addTypename={false} link={link}>
diff --git a/src/screens/UserPortal/UserScreen/UserScreen.tsx b/src/screens/UserPortal/UserScreen/UserScreen.tsx
index 39b422858f..5a877865c3 100644
--- a/src/screens/UserPortal/UserScreen/UserScreen.tsx
+++ b/src/screens/UserPortal/UserScreen/UserScreen.tsx
@@ -17,6 +17,7 @@ const map: InterfaceMapType = {
   people: 'people',
   events: 'userEvents',
   donate: 'donate',
+  chat: 'userChat',
   campaigns: 'userCampaigns',
   pledges: 'userPledges',
   volunteer: 'userVolunteer',
diff --git a/src/screens/UserPortal/Volunteer/Actions/Actions.tsx b/src/screens/UserPortal/Volunteer/Actions/Actions.tsx
index 9bc23969c2..9fc2c44884 100644
--- a/src/screens/UserPortal/Volunteer/Actions/Actions.tsx
+++ b/src/screens/UserPortal/Volunteer/Actions/Actions.tsx
@@ -1,9 +1,9 @@
 import React, { useCallback, useMemo, useState } from 'react';
 import { useTranslation } from 'react-i18next';
-import { Button, Dropdown, Form } from 'react-bootstrap';
+import { Button, Form } from 'react-bootstrap';
 import { Navigate, useParams } from 'react-router-dom';
 
-import { Circle, Search, Sort, WarningAmberRounded } from '@mui/icons-material';
+import { Circle, Search, WarningAmberRounded } from '@mui/icons-material';
 import dayjs from 'dayjs';
 
 import { useQuery } from '@apollo/client';
@@ -22,6 +22,7 @@ import Avatar from 'components/Avatar/Avatar';
 import ItemUpdateStatusModal from 'screens/OrganizationActionItems/ItemUpdateStatusModal';
 import { ACTION_ITEMS_BY_USER } from 'GraphQl/Queries/ActionItemQueries';
 import useLocalStorage from 'utils/useLocalstorage';
+import SortingButton from 'subComponents/SortingButton';
 
 enum ModalState {
   VIEW = 'view',
@@ -373,54 +374,29 @@ function actions(): JSX.Element {
         </div>
         <div className="d-flex gap-3 mb-1">
           <div className="d-flex justify-space-between align-items-center gap-3">
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                className={styles.dropdown}
-                data-testid="searchByToggle"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('searchBy', { item: '' })}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSearchBy('assignee')}
-                  data-testid="assignee"
-                >
-                  {t('assignee')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSearchBy('category')}
-                  data-testid="category"
-                >
-                  {t('category')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                className={styles.dropdown}
-                data-testid="sort"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSortBy('dueDate_DESC')}
-                  data-testid="dueDate_DESC"
-                >
-                  {t('latestDueDate')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('dueDate_ASC')}
-                  data-testid="dueDate_ASC"
-                >
-                  {t('earliestDueDate')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              sortingOptions={[
+                { label: t('assignee'), value: 'assignee' },
+                { label: t('category'), value: 'category' },
+              ]}
+              selectedOption={searchBy}
+              onSortChange={(value) =>
+                setSearchBy(value as 'assignee' | 'category')
+              }
+              dataTestIdPrefix="searchByToggle"
+              buttonLabel={tCommon('searchBy', { item: '' })}
+            />
+            <SortingButton
+              sortingOptions={[
+                { label: t('latestDueDate'), value: 'dueDate_DESC' },
+                { label: t('earliestDueDate'), value: 'dueDate_ASC' },
+              ]}
+              onSortChange={(value) =>
+                setSortBy(value as 'dueDate_DESC' | 'dueDate_ASC')
+              }
+              dataTestIdPrefix="sort"
+              buttonLabel={tCommon('sort')}
+            />
           </div>
         </div>
       </div>
diff --git a/src/screens/UserPortal/Volunteer/Groups/Groups.tsx b/src/screens/UserPortal/Volunteer/Groups/Groups.tsx
index 160dc0b23a..4cd2470010 100644
--- a/src/screens/UserPortal/Volunteer/Groups/Groups.tsx
+++ b/src/screens/UserPortal/Volunteer/Groups/Groups.tsx
@@ -1,11 +1,10 @@
 import React, { useCallback, useMemo, useState } from 'react';
 import { useTranslation } from 'react-i18next';
-import { Button, Dropdown, Form } from 'react-bootstrap';
+import { Button, Form } from 'react-bootstrap';
 import { Navigate, useParams } from 'react-router-dom';
-
-import { Search, Sort, WarningAmberRounded } from '@mui/icons-material';
-
+import { Search, WarningAmberRounded } from '@mui/icons-material';
 import { useQuery } from '@apollo/client';
+import { debounce, Stack } from '@mui/material';
 
 import type { InterfaceVolunteerGroupInfo } from 'utils/interfaces';
 import Loader from 'components/Loader/Loader';
@@ -14,13 +13,13 @@ import {
   type GridCellParams,
   type GridColDef,
 } from '@mui/x-data-grid';
-import { debounce, Stack } from '@mui/material';
 import Avatar from 'components/Avatar/Avatar';
 import styles from '../../../../style/app.module.css';
 import { EVENT_VOLUNTEER_GROUP_LIST } from 'GraphQl/Queries/EventVolunteerQueries';
 import VolunteerGroupViewModal from 'screens/EventVolunteers/VolunteerGroups/VolunteerGroupViewModal';
 import useLocalStorage from 'utils/useLocalstorage';
 import GroupModal from './GroupModal';
+import SortingButton from 'subComponents/SortingButton';
 
 enum ModalState {
   EDIT = 'edit',
@@ -313,56 +312,27 @@ function groups(): JSX.Element {
         </div>
         <div className="d-flex gap-3 mb-1">
           <div className="d-flex justify-space-between align-items-center gap-3">
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdown}
-                data-testid="searchByToggle"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('searchBy', { item: '' })}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSearchBy('leader')}
-                  data-testid="leader"
-                >
-                  {t('leader')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSearchBy('group')}
-                  data-testid="group"
-                >
-                  {t('group')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdown}
-                data-testid="sort"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSortBy('volunteers_DESC')}
-                  data-testid="volunteers_DESC"
-                >
-                  {t('mostVolunteers')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('volunteers_ASC')}
-                  data-testid="volunteers_ASC"
-                >
-                  {t('leastVolunteers')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              sortingOptions={[
+                { label: t('leader'), value: 'leader' },
+                { label: t('group'), value: 'group' },
+              ]}
+              selectedOption={searchBy}
+              onSortChange={(value) => setSearchBy(value as 'leader' | 'group')}
+              dataTestIdPrefix="searchByToggle"
+              buttonLabel={tCommon('searchBy', { item: '' })}
+            />
+            <SortingButton
+              sortingOptions={[
+                { label: t('mostVolunteers'), value: 'volunteers_DESC' },
+                { label: t('leastVolunteers'), value: 'volunteers_ASC' },
+              ]}
+              onSortChange={(value) =>
+                setSortBy(value as 'volunteers_DESC' | 'volunteers_ASC')
+              }
+              dataTestIdPrefix="sort"
+              buttonLabel={tCommon('sort')}
+            />
           </div>
         </div>
       </div>
diff --git a/src/screens/UserPortal/Volunteer/Invitations/Invitations.spec.tsx b/src/screens/UserPortal/Volunteer/Invitations/Invitations.spec.tsx
index 867f95c1aa..2c8d0835ca 100644
--- a/src/screens/UserPortal/Volunteer/Invitations/Invitations.spec.tsx
+++ b/src/screens/UserPortal/Volunteer/Invitations/Invitations.spec.tsx
@@ -171,7 +171,7 @@ describe('Testing Invvitations Screen', () => {
     expect(filter).toBeInTheDocument();
 
     fireEvent.click(filter);
-    const filterAll = await screen.findByTestId('filterAll');
+    const filterAll = await screen.findByTestId('all');
     expect(filterAll).toBeInTheDocument();
 
     fireEvent.click(filterAll);
@@ -189,7 +189,7 @@ describe('Testing Invvitations Screen', () => {
     expect(filter).toBeInTheDocument();
 
     fireEvent.click(filter);
-    const filterGroup = await screen.findByTestId('filterGroup');
+    const filterGroup = await screen.findByTestId('group');
     expect(filterGroup).toBeInTheDocument();
 
     fireEvent.click(filterGroup);
@@ -210,7 +210,7 @@ describe('Testing Invvitations Screen', () => {
     expect(filter).toBeInTheDocument();
 
     fireEvent.click(filter);
-    const filterIndividual = await screen.findByTestId('filterIndividual');
+    const filterIndividual = await screen.findByTestId('individual');
     expect(filterIndividual).toBeInTheDocument();
 
     fireEvent.click(filterIndividual);
diff --git a/src/screens/UserPortal/Volunteer/Invitations/Invitations.tsx b/src/screens/UserPortal/Volunteer/Invitations/Invitations.tsx
index a79b64251d..35dbe67264 100644
--- a/src/screens/UserPortal/Volunteer/Invitations/Invitations.tsx
+++ b/src/screens/UserPortal/Volunteer/Invitations/Invitations.tsx
@@ -1,14 +1,9 @@
 import React, { useMemo, useState } from 'react';
-import { Dropdown, Form, Button } from 'react-bootstrap';
+import { Form, Button } from 'react-bootstrap';
 import styles from '../VolunteerManagement.module.css';
 import { useTranslation } from 'react-i18next';
 import { Navigate, useParams } from 'react-router-dom';
-import {
-  FilterAltOutlined,
-  Search,
-  Sort,
-  WarningAmberRounded,
-} from '@mui/icons-material';
+import { Search, WarningAmberRounded } from '@mui/icons-material';
 import { TbCalendarEvent } from 'react-icons/tb';
 import { FaUserGroup } from 'react-icons/fa6';
 import { debounce, Stack } from '@mui/material';
@@ -21,6 +16,7 @@ import Loader from 'components/Loader/Loader';
 import { USER_VOLUNTEER_MEMBERSHIP } from 'GraphQl/Queries/EventVolunteerQueries';
 import { UPDATE_VOLUNTEER_MEMBERSHIP } from 'GraphQl/Mutations/EventVolunteerMutation';
 import { toast } from 'react-toastify';
+import SortingButton from 'subComponents/SortingButton';
 
 enum ItemFilter {
   Group = 'group',
@@ -120,7 +116,7 @@ const Invitations = (): JSX.Element => {
   // loads the invitations when the component mounts
   if (invitationLoading) return <Loader size="xl" />;
   if (invitationError) {
-    // Displays an error message if there is an issue loading the invvitations
+    // Displays an error message if there is an issue loading the invitations
     return (
       <div className={`${styles.container} bg-white rounded-4 my-3`}>
         <div className={styles.message} data-testid="errorMsg">
@@ -162,63 +158,30 @@ const Invitations = (): JSX.Element => {
         </div>
         <div className="d-flex gap-4 mb-1">
           <div className="d-flex gap-3 justify-space-between">
-            {/* Dropdown menu for sorting invitations */}
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                className={styles.dropdown}
-                data-testid="sort"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('sort')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSortBy('createdAt_DESC')}
-                  data-testid="createdAt_DESC"
-                >
-                  {t('receivedLatest')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSortBy('createdAt_ASC')}
-                  data-testid="createdAt_ASC"
-                >
-                  {t('receivedEarliest')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdown}
-                data-testid="filter"
-              >
-                <FilterAltOutlined className={'me-1'} />
-                {t('filter')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setFilter(null)}
-                  data-testid="filterAll"
-                >
-                  {tCommon('all')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setFilter(ItemFilter.Group)}
-                  data-testid="filterGroup"
-                >
-                  {t('groupInvite')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setFilter(ItemFilter.Individual)}
-                  data-testid="filterIndividual"
-                >
-                  {t('individualInvite')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              sortingOptions={[
+                { label: t('receivedLatest'), value: 'createdAt_DESC' },
+                { label: t('receivedEarliest'), value: 'createdAt_ASC' },
+              ]}
+              onSortChange={(value) =>
+                setSortBy(value as 'createdAt_DESC' | 'createdAt_ASC')
+              }
+              dataTestIdPrefix="sort"
+              buttonLabel={tCommon('sort')}
+            />
+            <SortingButton
+              sortingOptions={[
+                { label: tCommon('all'), value: 'all' },
+                { label: t('groupInvite'), value: 'group' },
+                { label: t('individualInvite'), value: 'individual' },
+              ]}
+              onSortChange={(value) =>
+                setFilter(value === 'all' ? null : (value as ItemFilter))
+              }
+              dataTestIdPrefix="filter"
+              buttonLabel={t('filter')}
+              type="filter"
+            />
           </div>
         </div>
       </div>
diff --git a/src/screens/UserPortal/Volunteer/UpcomingEvents/UpcomingEvents.tsx b/src/screens/UserPortal/Volunteer/UpcomingEvents/UpcomingEvents.tsx
index bd61ca97e0..eecb874210 100644
--- a/src/screens/UserPortal/Volunteer/UpcomingEvents/UpcomingEvents.tsx
+++ b/src/screens/UserPortal/Volunteer/UpcomingEvents/UpcomingEvents.tsx
@@ -1,5 +1,5 @@
 import React, { useMemo, useState } from 'react';
-import { Dropdown, Form, Button } from 'react-bootstrap';
+import { Form, Button } from 'react-bootstrap';
 import styles from '../VolunteerManagement.module.css';
 import { useTranslation } from 'react-i18next';
 import { Navigate, useParams } from 'react-router-dom';
@@ -19,7 +19,7 @@ import {
   Stack,
   debounce,
 } from '@mui/material';
-import { Circle, Search, Sort, WarningAmberRounded } from '@mui/icons-material';
+import { Circle, Search, WarningAmberRounded } from '@mui/icons-material';
 
 import { GridExpandMoreIcon } from '@mui/x-data-grid';
 import useLocalStorage from 'utils/useLocalstorage';
@@ -31,6 +31,7 @@ import { USER_EVENTS_VOLUNTEER } from 'GraphQl/Queries/PlugInQueries';
 import { CREATE_VOLUNTEER_MEMBERSHIP } from 'GraphQl/Mutations/EventVolunteerMutation';
 import { toast } from 'react-toastify';
 import { FaCheck } from 'react-icons/fa';
+import SortingButton from 'subComponents/SortingButton';
 
 /**
  * The `UpcomingEvents` component displays list of upcoming events for the user to volunteer.
@@ -90,7 +91,7 @@ const UpcomingEvents = (): JSX.Element => {
     }
   };
 
-  // Fetches upcomin events based on the organization ID, search term, and sorting order
+  // Fetches upcoming events based on the organization ID, search term, and sorting order
   const {
     data: eventsData,
     loading: eventsLoading,
@@ -169,31 +170,18 @@ const UpcomingEvents = (): JSX.Element => {
         </div>
         <div className="d-flex gap-4 mb-1">
           <div className="d-flex justify-space-between align-items-center gap-3">
-            <Dropdown>
-              <Dropdown.Toggle
-                variant="success"
-                id="dropdown-basic"
-                className={styles.dropdown}
-                data-testid="searchByToggle"
-              >
-                <Sort className={'me-1'} />
-                {tCommon('searchBy', { item: '' })}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={() => setSearchBy('title')}
-                  data-testid="title"
-                >
-                  {t('name')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={() => setSearchBy('location')}
-                  data-testid="location"
-                >
-                  {tCommon('location')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              sortingOptions={[
+                { label: t('name'), value: 'title' },
+                { label: tCommon('location'), value: 'location' },
+              ]}
+              selectedOption={searchBy}
+              onSortChange={(value) =>
+                setSearchBy(value as 'title' | 'location')
+              }
+              dataTestIdPrefix="searchByToggle"
+              buttonLabel={tCommon('searchBy', { item: '' })}
+            />
           </div>
         </div>
       </div>
diff --git a/src/screens/Users/Users.tsx b/src/screens/Users/Users.tsx
index 936807f1ec..ef9f001f4d 100644
--- a/src/screens/Users/Users.tsx
+++ b/src/screens/Users/Users.tsx
@@ -1,13 +1,11 @@
 import { useQuery } from '@apollo/client';
 import React, { useEffect, useState } from 'react';
-import { Dropdown, Form, Table } from 'react-bootstrap';
+import { Form, Table } from 'react-bootstrap';
 import Button from 'react-bootstrap/Button';
 import { useTranslation } from 'react-i18next';
 import { toast } from 'react-toastify';
 
 import { Search } from '@mui/icons-material';
-import FilterListIcon from '@mui/icons-material/FilterList';
-import SortIcon from '@mui/icons-material/Sort';
 import {
   ORGANIZATION_CONNECTION_LIST,
   USER_LIST,
@@ -19,6 +17,8 @@ import type { InterfaceQueryUserListItem } from 'utils/interfaces';
 import styles from '../../style/app.module.css';
 import useLocalStorage from 'utils/useLocalstorage';
 import type { ApolloError } from '@apollo/client';
+import SortingButton from 'subComponents/SortingButton';
+
 /**
  * The `Users` component is responsible for displaying a list of users in a paginated and sortable format.
  * It supports search functionality, filtering, and sorting of users. The component integrates with GraphQL
@@ -372,74 +372,29 @@ const Users = (): JSX.Element => {
         </div>
         <div className={styles.btnsBlock}>
           <div className="d-flex">
-            <Dropdown
-              aria-expanded="false"
-              title="Sort Users"
-              data-testid="sort"
-            >
-              <Dropdown.Toggle variant="success" data-testid="sortUsers">
-                <SortIcon className={'me-1'} />
-                {sortingOption === 'newest' ? t('Newest') : t('Oldest')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  onClick={(): void => {
-                    handleSorting('newest');
-                  }}
-                  data-testid="newest"
-                >
-                  {t('Newest')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  onClick={(): void => {
-                    handleSorting('oldest');
-                  }}
-                  data-testid="oldest"
-                >
-                  {t('Oldest')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
-            <Dropdown
-              aria-expanded="false"
-              title="Filter organizations"
-              data-testid="filter"
-            >
-              <Dropdown.Toggle
-                variant="outline-success"
-                data-testid="filterUsers"
-              >
-                <FilterListIcon className={'me-1'} />
-                {tCommon('filter')}
-              </Dropdown.Toggle>
-              <Dropdown.Menu>
-                <Dropdown.Item
-                  data-testid="admin"
-                  onClick={(): void => handleFiltering('admin')}
-                >
-                  {tCommon('admin')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  data-testid="superAdmin"
-                  onClick={(): void => handleFiltering('superAdmin')}
-                >
-                  {tCommon('superAdmin')}
-                </Dropdown.Item>
-
-                <Dropdown.Item
-                  data-testid="user"
-                  onClick={(): void => handleFiltering('user')}
-                >
-                  {tCommon('user')}
-                </Dropdown.Item>
-                <Dropdown.Item
-                  data-testid="cancel"
-                  onClick={(): void => handleFiltering('cancel')}
-                >
-                  {tCommon('cancel')}
-                </Dropdown.Item>
-              </Dropdown.Menu>
-            </Dropdown>
+            <SortingButton
+              sortingOptions={[
+                { label: t('Newest'), value: 'newest' },
+                { label: t('Oldest'), value: 'oldest' },
+              ]}
+              selectedOption={sortingOption}
+              onSortChange={handleSorting}
+              dataTestIdPrefix="sortUsers"
+            />
+            <SortingButton
+              sortingOptions={[
+                { label: tCommon('admin'), value: 'admin' },
+                { label: tCommon('superAdmin'), value: 'superAdmin' },
+                { label: tCommon('user'), value: 'user' },
+                { label: tCommon('cancel'), value: 'cancel' },
+              ]}
+              selectedOption={filteringOption}
+              onSortChange={handleFiltering}
+              dataTestIdPrefix="filterUsers"
+              buttonLabel={tCommon('filter')}
+              type="filter"
+              dropdownTestId="filter"
+            />
           </div>
         </div>
       </div>
diff --git a/src/setup/askAndSetDockerOption/askAndSetDockerOption.spec.ts b/src/setup/askAndSetDockerOption/askAndSetDockerOption.spec.ts
new file mode 100644
index 0000000000..6efc8a7a1d
--- /dev/null
+++ b/src/setup/askAndSetDockerOption/askAndSetDockerOption.spec.ts
@@ -0,0 +1,61 @@
+import { describe, it, expect, vi, beforeEach } from 'vitest';
+
+// Mock modules
+vi.mock('inquirer', () => ({
+  default: {
+    prompt: vi.fn(),
+  },
+}));
+
+vi.mock('setup/updateEnvFile/updateEnvFile', () => ({
+  default: vi.fn(),
+}));
+
+vi.mock('setup/askForDocker/askForDocker', () => ({
+  askForDocker: vi.fn(),
+}));
+
+// Import after mocking
+import askAndSetDockerOption from './askAndSetDockerOption';
+import inquirer from 'inquirer';
+import updateEnvFile from 'setup/updateEnvFile/updateEnvFile';
+import { askForDocker } from 'setup/askForDocker/askForDocker';
+
+describe('askAndSetDockerOption', () => {
+  beforeEach(() => {
+    vi.clearAllMocks();
+  });
+
+  it('should set up Docker when user selects yes', async () => {
+    (inquirer.prompt as unknown as jest.Mock).mockResolvedValueOnce({
+      useDocker: true,
+    });
+    (askForDocker as jest.Mock).mockResolvedValueOnce(8080);
+
+    await askAndSetDockerOption();
+
+    expect(updateEnvFile).toHaveBeenCalledWith('USE_DOCKER', 'YES');
+    expect(updateEnvFile).toHaveBeenCalledWith('DOCKER_PORT', 8080);
+  });
+
+  it('should set up without Docker when user selects no', async () => {
+    (inquirer.prompt as unknown as jest.Mock).mockResolvedValueOnce({
+      useDocker: false,
+    });
+
+    await askAndSetDockerOption();
+
+    expect(updateEnvFile).toHaveBeenCalledWith('USE_DOCKER', 'NO');
+  });
+
+  it('should handle errors when askForDocker fails', async () => {
+    (inquirer.prompt as unknown as jest.Mock).mockResolvedValueOnce({
+      useDocker: true,
+    });
+    (askForDocker as jest.Mock).mockRejectedValueOnce(
+      new Error('Docker error'),
+    );
+
+    await expect(askAndSetDockerOption()).rejects.toThrow('Docker error');
+  });
+});
diff --git a/src/setup/askAndSetDockerOption/askAndSetDockerOption.ts b/src/setup/askAndSetDockerOption/askAndSetDockerOption.ts
new file mode 100644
index 0000000000..877ef92faf
--- /dev/null
+++ b/src/setup/askAndSetDockerOption/askAndSetDockerOption.ts
@@ -0,0 +1,35 @@
+import inquirer from 'inquirer';
+import updateEnvFile from 'setup/updateEnvFile/updateEnvFile';
+import { askForDocker } from 'setup/askForDocker/askForDocker';
+
+// Function to manage Docker setup
+const askAndSetDockerOption = async (): Promise<void> => {
+  const { useDocker } = await inquirer.prompt({
+    type: 'confirm',
+    name: 'useDocker',
+    message: 'Would you like to set up with Docker?',
+    default: false,
+  });
+
+  if (useDocker) {
+    console.log('Setting up with Docker...');
+    updateEnvFile('USE_DOCKER', 'YES');
+    const answers = await askForDocker();
+    const DOCKER_PORT_NUMBER = answers;
+    updateEnvFile('DOCKER_PORT', DOCKER_PORT_NUMBER);
+
+    const DOCKER_NAME = 'talawa-admin';
+    console.log(`
+        
+          Run the commands below after setup:-
+                1. docker build -t ${DOCKER_NAME} .
+                2. docker run -d -p ${DOCKER_PORT_NUMBER}:${DOCKER_PORT_NUMBER} ${DOCKER_NAME}
+                
+       `);
+  } else {
+    console.log('Setting up without Docker...');
+    updateEnvFile('USE_DOCKER', 'NO');
+  }
+};
+
+export default askAndSetDockerOption;
diff --git a/src/setup/askAndUpdatePort/askAndUpdatePort.ts b/src/setup/askAndUpdatePort/askAndUpdatePort.ts
new file mode 100644
index 0000000000..5dfe997288
--- /dev/null
+++ b/src/setup/askAndUpdatePort/askAndUpdatePort.ts
@@ -0,0 +1,25 @@
+import updateEnvFile from 'setup/updateEnvFile/updateEnvFile';
+import { askForCustomPort } from 'setup/askForCustomPort/askForCustomPort';
+import inquirer from 'inquirer';
+
+// Ask and update the custom port
+const askAndUpdatePort = async (): Promise<void> => {
+  const { shouldSetCustomPortResponse } = await inquirer.prompt({
+    type: 'confirm',
+    name: 'shouldSetCustomPortResponse',
+    message:
+      'Would you like to set up a custom port for running Talawa Admin without Docker?',
+    default: true,
+  });
+
+  if (shouldSetCustomPortResponse) {
+    const customPort = await askForCustomPort();
+    if (customPort < 1024 || customPort > 65535) {
+      throw new Error('Port must be between 1024 and 65535');
+    }
+
+    updateEnvFile('PORT', String(customPort));
+  }
+};
+
+export default askAndUpdatePort;
diff --git a/src/setup/askAndUpdatePort/askForUpdatePort.spec.ts b/src/setup/askAndUpdatePort/askForUpdatePort.spec.ts
new file mode 100644
index 0000000000..3f01605a55
--- /dev/null
+++ b/src/setup/askAndUpdatePort/askForUpdatePort.spec.ts
@@ -0,0 +1,55 @@
+import { describe, it, expect, vi } from 'vitest';
+import askAndUpdatePort from './askAndUpdatePort';
+import { askForCustomPort } from 'setup/askForCustomPort/askForCustomPort';
+import updateEnvFile from 'setup/updateEnvFile/updateEnvFile';
+import inquirer from 'inquirer';
+
+vi.mock('setup/askForCustomPort/askForCustomPort');
+vi.mock('setup/updateEnvFile/updateEnvFile');
+vi.mock('inquirer');
+
+describe('askAndUpdatePort', () => {
+  afterEach(() => {
+    vi.clearAllMocks();
+  });
+
+  it('should update the port when user confirms and provides a valid port', async () => {
+    // Mock user confirmation and valid port
+    vi.mocked(inquirer.prompt).mockResolvedValueOnce({
+      shouldSetCustomPortResponse: true,
+    });
+    vi.mocked(askForCustomPort).mockResolvedValueOnce(3000);
+
+    // Act
+    await askAndUpdatePort();
+
+    // Assert
+    expect(updateEnvFile).toHaveBeenCalledWith('PORT', '3000');
+  });
+
+  it('should not update the port when user declines', async () => {
+    // Mock user declining by returning false
+    vi.mocked(inquirer.prompt).mockResolvedValueOnce({
+      shouldSetCustomPortResponse: false,
+    });
+
+    // Act
+    await askAndUpdatePort();
+
+    // Assert
+    expect(updateEnvFile).not.toHaveBeenCalled();
+  });
+
+  it('should throw an error for an invalid port', async () => {
+    // Mock user confirmation and invalid port
+    vi.mocked(inquirer.prompt).mockResolvedValueOnce({
+      shouldSetCustomPortResponse: true,
+    });
+    vi.mocked(askForCustomPort).mockResolvedValueOnce(800);
+
+    // Act & Assert
+    await expect(askAndUpdatePort()).rejects.toThrowError(
+      'Port must be between 1024 and 65535',
+    );
+  });
+});
diff --git a/src/setup/askForDocker/askForDocker.spec.ts b/src/setup/askForDocker/askForDocker.spec.ts
new file mode 100644
index 0000000000..a791b67da9
--- /dev/null
+++ b/src/setup/askForDocker/askForDocker.spec.ts
@@ -0,0 +1,69 @@
+import inquirer from 'inquirer';
+import { askForDocker } from './askForDocker';
+import { describe, test, expect, vi } from 'vitest';
+
+vi.mock('inquirer');
+
+describe('askForDocker', () => {
+  test('should return default Docker port if user provides no input', async () => {
+    vi.spyOn(inquirer, 'prompt').mockResolvedValueOnce({
+      dockerAppPort: '4321',
+    });
+
+    const result = await askForDocker();
+    expect(result).toBe('4321');
+  });
+
+  test('should return user-provided valid port', async () => {
+    vi.spyOn(inquirer, 'prompt').mockResolvedValueOnce({
+      dockerAppPort: '8080',
+    });
+
+    const result = await askForDocker();
+    expect(result).toBe('8080');
+  });
+
+  test('should reject non-numeric input with validation error', async () => {
+    // Mock the validation function to simulate an error for non-numeric input
+    vi.spyOn(inquirer, 'prompt').mockImplementationOnce(() => {
+      throw new Error(
+        'Please enter a valid port number between 1024 and 65535',
+      );
+    });
+
+    await expect(askForDocker()).rejects.toThrow(
+      'Please enter a valid port number between 1024 and 65535',
+    );
+  });
+
+  test('should reject port outside valid range with validation error', async () => {
+    // Mock the validation function to simulate an error for an out-of-range port
+    vi.spyOn(inquirer, 'prompt').mockImplementationOnce(() => {
+      throw new Error(
+        'Please enter a valid port number between 1024 and 65535',
+      );
+    });
+
+    await expect(askForDocker()).rejects.toThrow(
+      'Please enter a valid port number between 1024 and 65535',
+    );
+  });
+
+  test('should handle edge case: maximum valid port', async () => {
+    vi.spyOn(inquirer, 'prompt').mockResolvedValueOnce({
+      dockerAppPort: '65535',
+    });
+
+    const result = await askForDocker();
+    expect(result).toBe('65535');
+  });
+
+  test('should handle edge case: minimum valid port', async () => {
+    vi.spyOn(inquirer, 'prompt').mockResolvedValueOnce({
+      dockerAppPort: '1024',
+    });
+
+    const result = await askForDocker();
+    expect(result).toBe('1024');
+  });
+});
diff --git a/src/setup/askForDocker/askForDocker.ts b/src/setup/askForDocker/askForDocker.ts
new file mode 100644
index 0000000000..fa926839d4
--- /dev/null
+++ b/src/setup/askForDocker/askForDocker.ts
@@ -0,0 +1,99 @@
+import inquirer from 'inquirer';
+import { askForTalawaApiUrl } from '../askForTalawaApiUrl/askForTalawaApiUrl';
+import updateEnvFile from '../updateEnvFile/updateEnvFile';
+
+// Mock implementation of checkConnection
+const checkConnection = async (): Promise<boolean> => {
+  // Simulate checking connection
+  return true; // Replace with actual connection check logic
+};
+
+// Function to ask for Docker port
+export const askForDocker = async (): Promise<string> => {
+  const answers = await inquirer.prompt<{ dockerAppPort: string }>([
+    {
+      type: 'input',
+      name: 'dockerAppPort',
+      message: 'Enter the port to expose Docker (default: 4321):',
+      default: '4321',
+      validate: (input: string) => {
+        const port = Number(input);
+        if (Number.isNaN(port) || port < 1024 || port > 65535) {
+          return 'Please enter a valid port number between 1024 and 65535';
+        }
+        return true;
+      },
+    },
+  ]);
+
+  return answers.dockerAppPort;
+};
+
+// Function to ask and update Talawa API URL
+export const askAndUpdateTalawaApiUrl = async (): Promise<void> => {
+  try {
+    const { shouldSetTalawaApiUrlResponse } = await inquirer.prompt({
+      type: 'confirm',
+      name: 'shouldSetTalawaApiUrlResponse',
+      message: 'Would you like to set up Talawa API endpoint?',
+      default: true,
+    });
+
+    if (shouldSetTalawaApiUrlResponse) {
+      let endpoint = '';
+      let isConnected = false;
+      let retryCount = 0;
+      const MAX_RETRIES = 3;
+      while (!isConnected && retryCount < MAX_RETRIES) {
+        try {
+          endpoint = await askForTalawaApiUrl();
+          const url = new URL(endpoint);
+          if (!['http:', 'https:'].includes(url.protocol)) {
+            throw new Error('Invalid URL protocol. Must be http or https');
+          }
+          isConnected = await checkConnection();
+          if (!isConnected) {
+            console.log(
+              `Connection attempt ${retryCount + 1}/${MAX_RETRIES} failed`,
+            );
+          }
+        } catch (error) {
+          console.error('Error checking connection:', error);
+          isConnected = false;
+        }
+        retryCount++;
+      }
+      if (!isConnected) {
+        throw new Error(
+          'Failed to establish connection after maximum retry attempts',
+        );
+      }
+      updateEnvFile('REACT_APP_TALAWA_URL', endpoint);
+      const websocketUrl = endpoint.replace(/^http(s)?:\/\//, 'ws$1://');
+      try {
+        const wsUrl = new URL(websocketUrl);
+        if (!['ws:', 'wss:'].includes(wsUrl.protocol)) {
+          throw new Error('Invalid WebSocket protocol');
+        }
+        updateEnvFile('REACT_APP_BACKEND_WEBSOCKET_URL', websocketUrl);
+      } catch {
+        throw new Error('Invalid WebSocket URL generated: ');
+      }
+
+      if (endpoint.includes('localhost')) {
+        const dockerUrl = endpoint.replace('localhost', 'host.docker.internal');
+        try {
+          const url = new URL(dockerUrl);
+          if (!['http:', 'https:'].includes(url.protocol)) {
+            throw new Error('Invalid Docker URL protocol');
+          }
+        } catch {
+          throw new Error('Invalid Docker URL generated');
+        }
+        updateEnvFile('REACT_APP_DOCKER_TALAWA_URL', dockerUrl);
+      }
+    }
+  } catch (error) {
+    console.error('Error setting up Talawa API URL:', error);
+  }
+};
diff --git a/src/setup/updateEnvFile/updateEnvFile.spec.ts b/src/setup/updateEnvFile/updateEnvFile.spec.ts
new file mode 100644
index 0000000000..c3ff4a5242
--- /dev/null
+++ b/src/setup/updateEnvFile/updateEnvFile.spec.ts
@@ -0,0 +1,88 @@
+import fs from 'fs';
+import updateEnvFile from './updateEnvFile';
+import { vi, describe, it, expect, beforeEach } from 'vitest';
+
+/**
+ * Unit tests for the `updateEnvFile` function.
+ *
+ * These tests verify:
+ * - Updating an existing key in the `.env` file.
+ * - Appending a new key if it does not exist in the `.env` file.
+ * - Handling an empty `.env` file.
+ */
+
+vi.mock('fs');
+
+describe('updateEnvFile', () => {
+  beforeEach(() => {
+    vi.resetAllMocks();
+  });
+
+  it('should update an existing key in the .env file', () => {
+    const envContent = 'EXISTING_KEY=old_value\nANOTHER_KEY=another_value\n';
+    const updatedEnvContent =
+      'EXISTING_KEY=new_value\nANOTHER_KEY=another_value\n';
+
+    // Mock file system read and write operations
+    vi.spyOn(fs, 'readFileSync').mockReturnValueOnce(envContent);
+    const writeMock = vi.spyOn(fs, 'writeFileSync');
+
+    updateEnvFile('EXISTING_KEY', 'new_value');
+
+    // Verify that the updated content is written to the file
+    expect(writeMock).toHaveBeenCalledWith('.env', updatedEnvContent, 'utf8');
+  });
+
+  it('should append a new key if it does not exist in the .env file', () => {
+    const envContent = 'EXISTING_KEY=existing_value\n';
+    const newKey = 'NEW_KEY=new_value';
+
+    // Mock file system read and append operations
+    vi.spyOn(fs, 'readFileSync').mockReturnValueOnce(envContent);
+    const appendMock = vi.spyOn(fs, 'appendFileSync');
+
+    updateEnvFile('NEW_KEY', 'new_value');
+
+    // Verify that the new key is appended to the file
+    expect(appendMock).toHaveBeenCalledWith('.env', `\n${newKey}`, 'utf8');
+  });
+
+  it('should handle an empty .env file and append the new key', () => {
+    const envContent = '';
+    const newKey = 'NEW_KEY=new_value';
+
+    // Mock file system read and append operations
+    vi.spyOn(fs, 'readFileSync').mockReturnValueOnce(envContent);
+    const appendMock = vi.spyOn(fs, 'appendFileSync');
+
+    updateEnvFile('NEW_KEY', 'new_value');
+
+    // Verify that the new key is appended to the file
+    expect(appendMock).toHaveBeenCalledWith('.env', `\n${newKey}`, 'utf8');
+  });
+
+  it('should not throw errors when .env file does not exist and create the file with the key', () => {
+    const newKey = 'NEW_KEY=new_value';
+
+    const appendMock = vi.spyOn(fs, 'appendFileSync');
+
+    updateEnvFile('NEW_KEY', 'new_value');
+
+    // Verify that the new key is appended to the file
+    expect(appendMock).toHaveBeenCalledWith('.env', `\n${newKey}`, 'utf8');
+  });
+
+  it('should correctly handle keys with special characters', () => {
+    const envContent = 'EXISTING_KEY=old_value\n';
+    const updatedEnvContent = 'EXISTING_KEY=value_with=special_characters\n';
+
+    // Mock file system read and write operations
+    vi.spyOn(fs, 'readFileSync').mockReturnValueOnce(envContent);
+    const writeMock = vi.spyOn(fs, 'writeFileSync');
+
+    updateEnvFile('EXISTING_KEY', 'value_with=special_characters');
+
+    // Verify that the updated content is written to the file
+    expect(writeMock).toHaveBeenCalledWith('.env', updatedEnvContent, 'utf8');
+  });
+});
diff --git a/src/setup/updateEnvFile/updateEnvFile.ts b/src/setup/updateEnvFile/updateEnvFile.ts
new file mode 100644
index 0000000000..93ba918749
--- /dev/null
+++ b/src/setup/updateEnvFile/updateEnvFile.ts
@@ -0,0 +1,21 @@
+import fs from 'fs';
+
+const updateEnvFile = (key: string, value: string): void => {
+  try {
+    const currentEnvContent = fs.readFileSync('.env', 'utf8');
+    const keyRegex = new RegExp(`^${key}=.*$`, 'm');
+    if (keyRegex.test(currentEnvContent)) {
+      const updatedEnvContent = currentEnvContent.replace(
+        keyRegex,
+        `${key}=${value}`,
+      );
+      fs.writeFileSync('.env', updatedEnvContent, 'utf8');
+    } else {
+      fs.appendFileSync('.env', `\n${key}=${value}`, 'utf8');
+    }
+  } catch (error) {
+    console.error('Error updating the .env file:', error);
+  }
+};
+
+export default updateEnvFile;
diff --git a/src/setup/validateRecaptcha/validateRecaptcha.test.ts b/src/setup/validateRecaptcha/validateRecaptcha.spec.ts
similarity index 95%
rename from src/setup/validateRecaptcha/validateRecaptcha.test.ts
rename to src/setup/validateRecaptcha/validateRecaptcha.spec.ts
index c77c9ed62b..cd1ff7125a 100644
--- a/src/setup/validateRecaptcha/validateRecaptcha.test.ts
+++ b/src/setup/validateRecaptcha/validateRecaptcha.spec.ts
@@ -1,3 +1,4 @@
+import { describe, it, expect } from 'vitest';
 import { validateRecaptcha } from './validateRecaptcha';
 
 describe('validateRecaptcha', () => {
diff --git a/src/style/app.module.css b/src/style/app.module.css
index b9f7d49328..d9645b2bdd 100644
--- a/src/style/app.module.css
+++ b/src/style/app.module.css
@@ -48,7 +48,8 @@
   --subtle-blue-grey-hover: #5f7e91;
   --white: #fff;
   --black: black;
-
+  --rating-star-filled: #ff6d75;
+  --rating-star-hover: #ff3d47;
   /* Background and Border */
   --table-bg: #eaebef;
   --tablerow-bg: #eff1f7;
@@ -90,9 +91,11 @@
   --bs-gray-400: #9ca3af;
   --bs-gray-300: #d1d5db;
   --toggle-button-bg: #1e4e8c;
-  --table-head-bg: var(--bs-primary, var(--blue-color));
+
+  --table-head-bg: var(--blue-subtle, var(--blue-color));
   --table-head-color: var(--bs-white, var(--white-color));
-  --table-header-color: var(--bs-greyish-black, var(--black-color));
+
+  --table-header-color: var(--bs-white, var(--bs-gray-300));
   --input-area-color: #f1f3f6;
   --date-picker-background: #f2f2f2;
   --grey-bg-color-dark: #707070;
@@ -105,6 +108,7 @@
   --breakpoint-tablet: 768px;
   --breakpoint-desktop: 1024px;
 }
+
 .fonts {
   color: var(--grey-bg-color-dark);
 }
@@ -270,13 +274,13 @@
 }
 
 .dropdown {
-  background-color: var(--bs-white);
+  background-color: var(--bs-white) !important;
   border: 1px solid var(--brown-color);
-  color: var(--brown-color);
+  color: var(--brown-color) !important;
   position: relative;
   display: inline-block;
-  margin-top: 10px;
-  margin-bottom: 10px;
+  /* margin-top: 10px;
+  margin-bottom: 10px; */
 }
 
 .dropdown:is(:hover, :focus, :active, :focus-visible, .show) {
@@ -939,7 +943,17 @@ hr {
 .card {
   width: fit-content;
 }
+.cardContainer {
+  width: 300px;
+}
 
+.ratingFilled {
+  color: var(--rating-star-filled); /* Color for filled stars */
+}
+
+.ratingHover {
+  color: var(--rating-star-hover); /* Color for star on hover */
+}
 .cardHeader {
   padding: 1.25rem 1rem 1rem 1rem;
   border-bottom: 1px solid var(--bs-gray-200);
@@ -1005,7 +1019,7 @@ hr {
 }
 
 .justifyspOrganizationEvents {
-  display: flex;
+  /* display: flex; */
   justify-content: space-between;
   margin-top: 20px;
 }
@@ -1449,6 +1463,7 @@ hr {
     flex-direction: column;
     justify-content: center;
   }
+
   .btnsContainer .btnsBlock {
     display: block;
     margin-top: 1rem;
@@ -1486,13 +1501,27 @@ hr {
     margin: 1.5rem 0;
   }
 
+  .btn {
+    flex-direction: column;
+    justify-content: center;
+  }
+
+  .btnsContainer > div {
+    width: 100% !important;
+    max-width: 100% !important;
+    box-sizing: border-box;
+  }
+
   .btnsContainer .btnsBlock {
+    display: block;
     margin: 1.5rem 0 0 0;
     justify-content: space-between;
   }
 
   .btnsContainer .btnsBlock button {
-    margin: 0;
+    margin-bottom: 1rem;
+    margin-right: 0;
+    width: 100%;
   }
 
   .btnsContainer .btnsBlock div button {
@@ -1565,6 +1594,12 @@ hr {
   align-items: center;
 }
 
+@media (max-width: 1020px) {
+  .btnsContainer .btnsBlock button {
+    margin-left: 0;
+  }
+}
+
 .errorMessage {
   margin-top: 25%;
   display: flex;
@@ -1745,14 +1780,6 @@ input[type='radio']:checked + label:hover {
   box-shadow: 0 1px 1px var(--brand-primary);
 }
 
-.dropdowns {
-  background-color: var(--bs-white);
-  border: 1px solid var(--light-green);
-  position: relative;
-  display: inline-block;
-  color: var(--light-green);
-}
-
 .chipIcon {
   height: 0.9rem !important;
 }
@@ -4605,26 +4632,39 @@ button[data-testid='createPostBtn'] {
   display: flex;
   position: relative;
   width: 100%;
-  margin-top: 10px;
+  overflow: hidden; /* Ensures content doesn't overflow the card */
   justify-content: center;
+  border: 1px solid #ccc;
 }
 
 .previewVenueModal img {
   width: 400px;
   height: auto;
+  object-fit: cover; /* Ensures the image stays within the boundaries */
 }
 
 .closeButtonP {
   position: absolute;
   top: 0px;
   right: 0px;
+  width: 32px; /* Make the button circular */
+  height: 32px; /* Make the button circular */
   background: transparent;
   transform: scale(1.2);
   cursor: pointer;
+  border-radius: 50%;
   border: none;
   color: var(--grey-dark);
   font-weight: 600;
   font-size: 16px;
+  transition:
+    background-color 0.3s,
+    transform 0.3s;
+}
+
+.closeButtonP:hover {
+  transform: scale(1.1); /* Slightly enlarge on hover */
+  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); /* Add a shadow on hover */
 }
 
 /* YearlyEventCalender.tsx */
@@ -5060,12 +5100,15 @@ button[data-testid='createPostBtn'] {
   position: relative;
   width: 100%;
   margin-top: 10px;
+  overflow: hidden; /* Ensures content doesn't overflow the card */
   justify-content: center;
+  border: 1px solid #ccc;
 }
 
 .previewAdvertisementRegister img {
   width: 400px;
   height: auto;
+  object-fit: cover; /* Ensures the image stays within the boundaries */
 }
 
 .previewAdvertisementRegister video {
@@ -5074,14 +5117,27 @@ button[data-testid='createPostBtn'] {
 }
 
 .closeButtonAdvertisementRegister {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  width: 32px; /* Make the button circular */
+  height: 32px; /* Make the button circular */
   background: transparent;
+  transform: scale(1.2);
   cursor: pointer;
+  border-radius: 50%;
   border: none;
   color: var(--grey-dark);
   font-weight: 600;
   font-size: 16px;
-  margin-bottom: 10px;
-  cursor: pointer;
+  transition:
+    background-color 0.3s,
+    transform 0.3s;
+}
+
+.closeButtonAdvertisementRegister:hover {
+  transform: scale(1.1); /* Slightly enlarge on hover */
+  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.2); /* Add a shadow on hover */
 }
 
 .buttonAdvertisementRegister {
@@ -5419,7 +5475,7 @@ button[data-testid='createPostBtn'] {
 }
 
 .flex_grow {
-  flex-grow: 1;
+  flex-grow: 0.5;
 }
 
 .space {
@@ -5448,6 +5504,34 @@ button[data-testid='createPostBtn'] {
   margin-left: 5px;
 }
 
+@media (max-width: 520px) {
+  .calendar__header {
+    display: flex;
+    flex-direction: column;
+    align-items: stretch;
+    gap: 10px;
+  }
+
+  .space {
+    display: block !important;
+    text-align: center;
+  }
+
+  .space > * {
+    width: 100%;
+    margin-bottom: 10px;
+  }
+
+  /* .input {
+    width: 100%; 
+  }
+
+  .createButton {
+    margin: 0 auto;
+    width: 100%; 
+  } */
+}
+
 /* EventListCardModals.tsx */
 
 .dispflexEventListCardModals {
diff --git a/src/subComponents/SortingButton.tsx b/src/subComponents/SortingButton.tsx
new file mode 100644
index 0000000000..7ce7703d39
--- /dev/null
+++ b/src/subComponents/SortingButton.tsx
@@ -0,0 +1,100 @@
+import React from 'react';
+import { Dropdown } from 'react-bootstrap';
+import SortIcon from '@mui/icons-material/Sort';
+import FilterAltOutlined from '@mui/icons-material/FilterAltOutlined';
+import PropTypes from 'prop-types';
+import styles from '../style/app.module.css';
+
+interface InterfaceSortingOption {
+  /** The label to display for the sorting option */
+  label: string;
+  /** The value associated with the sorting option */
+  value: string;
+}
+
+interface InterfaceSortingButtonProps {
+  /** The title attribute for the Dropdown */
+  title?: string;
+  /** The list of sorting options to display in the Dropdown */
+  sortingOptions: InterfaceSortingOption[];
+  /** The currently selected sorting option */
+  selectedOption?: string;
+  /** Callback function to handle sorting option change */
+  onSortChange: (value: string) => void;
+  /** The prefix for data-testid attributes for testing */
+  dataTestIdPrefix: string;
+  /** The data-testid attribute for the Dropdown */
+  dropdownTestId?: string;
+  /** Custom class name for the Dropdown */
+  className?: string;
+  /** Optional prop for custom button label */
+  buttonLabel?: string;
+  /** Type to determine the icon to display: 'sort' or 'filter' */
+  type?: 'sort' | 'filter';
+}
+
+/**
+ * SortingButton component renders a Dropdown with sorting options.
+ * It allows users to select a sorting option and triggers a callback on selection.
+ *
+ * @param props - The properties for the SortingButton component.
+ * @returns The rendered SortingButton component.
+ */
+const SortingButton: React.FC<InterfaceSortingButtonProps> = ({
+  title,
+  sortingOptions,
+  selectedOption,
+  onSortChange,
+  dataTestIdPrefix,
+  dropdownTestId,
+  className = styles.dropdown,
+  buttonLabel,
+  type = 'sort',
+}) => {
+  // Determine the icon based on the type
+  const IconComponent = type === 'filter' ? FilterAltOutlined : SortIcon;
+
+  return (
+    <Dropdown aria-expanded="false" title={title} data-testid={dropdownTestId}>
+      <Dropdown.Toggle
+        variant={selectedOption === '' ? 'outline-success' : 'success'}
+        data-testid={`${dataTestIdPrefix}`}
+        className={className}
+      >
+        <IconComponent className={'me-1'} /> {/* Use the appropriate icon */}
+        {buttonLabel || selectedOption}
+        {/* Use buttonLabel if provided, otherwise use selectedOption */}
+      </Dropdown.Toggle>
+      <Dropdown.Menu>
+        {sortingOptions.map((option) => (
+          <Dropdown.Item
+            key={option.value}
+            onClick={() => onSortChange(option.value)}
+            data-testid={`${option.value}`}
+            className={styles.dropdownItem}
+          >
+            {option.label}
+          </Dropdown.Item>
+        ))}
+      </Dropdown.Menu>
+    </Dropdown>
+  );
+};
+
+SortingButton.propTypes = {
+  title: PropTypes.string,
+  sortingOptions: PropTypes.arrayOf(
+    PropTypes.exact({
+      label: PropTypes.string.isRequired,
+      value: PropTypes.string.isRequired,
+    }).isRequired,
+  ).isRequired,
+  selectedOption: PropTypes.string,
+  onSortChange: PropTypes.func.isRequired,
+  dataTestIdPrefix: PropTypes.string.isRequired,
+  dropdownTestId: PropTypes.string,
+  buttonLabel: PropTypes.string, // Optional prop for custom button label
+  type: PropTypes.oneOf(['sort', 'filter']), // Type to determine the icon
+};
+
+export default SortingButton;
diff --git a/src/utils/StaticMockLink.spec.ts b/src/utils/StaticMockLink.spec.ts
new file mode 100644
index 0000000000..15c5cc3443
--- /dev/null
+++ b/src/utils/StaticMockLink.spec.ts
@@ -0,0 +1,725 @@
+import { describe, test, expect, vi, beforeEach } from 'vitest';
+import { StaticMockLink, mockSingleLink } from './StaticMockLink';
+import type { Observer } from '@apollo/client';
+import type { MockedResponse } from '@apollo/react-testing';
+import { gql, Observable } from '@apollo/client';
+import { print } from 'graphql';
+import type { FetchResult } from '@apollo/client/link/core';
+import { equal } from '@wry/equality';
+class TestableStaticMockLink extends StaticMockLink {
+  public setErrorHandler(
+    handler: (error: unknown, observer?: Observer<FetchResult>) => false | void,
+  ): void {
+    this.onError = handler;
+  }
+}
+
+const TEST_QUERY = gql`
+  query TestQuery($id: ID!) {
+    item(id: $id) {
+      id
+      name
+    }
+  }
+`;
+const mockQuery = gql`
+  query TestQuery {
+    test {
+      id
+      name
+    }
+  }
+`;
+const sampleQuery = gql`
+  query SampleQuery($id: ID!) {
+    user(id: $id) {
+      id
+      name
+    }
+  }
+`;
+
+const sampleResponse = {
+  data: {
+    user: {
+      id: '1',
+      name: 'Test User',
+      __typename: 'User',
+    },
+  },
+};
+describe('StaticMockLink', () => {
+  const sampleQuery = gql`
+    query SampleQuery($id: ID!) {
+      user(id: $id) {
+        id
+        name
+      }
+    }
+  `;
+
+  const sampleVariables = { id: '1' };
+
+  const sampleResponse = {
+    data: {
+      user: {
+        id: '1',
+        name: 'John Doe',
+        __typename: 'User',
+      },
+    },
+  };
+
+  let mockLink: StaticMockLink;
+
+  beforeEach((): void => {
+    mockLink = new StaticMockLink([], true);
+  });
+
+  test('should create instance with empty mocked responses', () => {
+    expect(mockLink).toBeInstanceOf(StaticMockLink);
+    expect(mockLink.addTypename).toBe(true);
+  });
+
+  test('should add mocked response', () => {
+    const mockedResponse = {
+      request: {
+        query: sampleQuery,
+        variables: sampleVariables,
+      },
+      result: sampleResponse,
+    };
+
+    mockLink.addMockedResponse(mockedResponse);
+    // This is Mocked Response
+    return new Promise<void>((resolve) => {
+      const observable = mockLink.request({
+        query: sampleQuery,
+        variables: sampleVariables,
+      });
+
+      observable?.subscribe({
+        next: (response) => {
+          expect(response).toEqual(sampleResponse);
+        },
+        complete: () => {
+          resolve();
+        },
+      });
+    });
+  });
+
+  test('should handle delayed responses', () => {
+    vi.useFakeTimers(); // Start using fake timers
+    const delay = 100;
+    const mockedResponse = {
+      request: {
+        query: sampleQuery,
+        variables: sampleVariables,
+      },
+      result: sampleResponse,
+      delay,
+    };
+
+    mockLink.addMockedResponse(mockedResponse);
+
+    let completed = false;
+
+    return new Promise<void>((resolve) => {
+      const observable = mockLink.request({
+        query: sampleQuery,
+        variables: sampleVariables,
+      });
+
+      observable?.subscribe({
+        next: (response) => {
+          expect(response).toEqual(sampleResponse);
+          completed = true;
+        },
+        complete: () => {
+          expect(completed).toBe(true);
+          resolve();
+        },
+        error: (error) => {
+          throw error;
+        },
+      });
+
+      vi.advanceTimersByTime(delay); // Advance time by the delay
+    }).finally(() => {
+      vi.useRealTimers(); // Restore real timers
+    });
+  });
+
+  test('should handle errors in response', () => {
+    const errorResponse = {
+      request: {
+        query: sampleQuery,
+        variables: sampleVariables,
+      },
+      error: new Error('GraphQL Error'),
+    };
+
+    mockLink.addMockedResponse(errorResponse);
+
+    return new Promise<void>((resolve) => {
+      const observable = mockLink.request({
+        query: sampleQuery,
+        variables: sampleVariables,
+      });
+
+      observable?.subscribe({
+        error: (error) => {
+          expect(error.message).toBe('GraphQL Error');
+          resolve();
+        },
+      });
+    });
+  });
+
+  test('should handle dynamic results using newData', () => {
+    const dynamicResponse = {
+      request: {
+        query: sampleQuery,
+        variables: { id: '2' }, // Changed to match the request variables
+      },
+      result: sampleResponse,
+      newData: (variables: { id: string }) => ({
+        data: {
+          user: {
+            id: variables.id,
+            name: `User ${variables.id}`,
+            __typename: 'User',
+          },
+        },
+      }),
+    };
+
+    mockLink.addMockedResponse(dynamicResponse);
+
+    return new Promise<void>((resolve) => {
+      const observable = mockLink.request({
+        query: sampleQuery,
+        variables: { id: '2' }, // Matches the request variables in mocked response
+      });
+
+      observable?.subscribe({
+        next: (response) => {
+          expect(response).toEqual({
+            data: {
+              user: {
+                id: '2',
+                name: 'User 2',
+                __typename: 'User',
+              },
+            },
+          });
+        },
+        complete: () => {
+          resolve();
+        },
+        error: (error) => {
+          // Add error handling to help debug test failures
+          console.error('Test error:', error);
+          throw error;
+        },
+      });
+    });
+  });
+  test('should error when no matching response is found', () => {
+    return new Promise<void>((resolve) => {
+      const observable = mockLink.request({
+        query: sampleQuery,
+        variables: sampleVariables,
+      });
+
+      observable?.subscribe({
+        error: (error) => {
+          expect(error.message).toContain(
+            'No more mocked responses for the query',
+          );
+          resolve();
+        },
+      });
+    });
+  });
+});
+
+describe('mockSingleLink', () => {
+  test('should create StaticMockLink with default typename', () => {
+    const mockedResponse = {
+      request: {
+        query: gql`
+          query {
+            hello
+          }
+        `,
+        variables: {},
+      },
+      result: { data: { hello: 'world' } },
+    };
+
+    const link = mockSingleLink(mockedResponse);
+    expect(link).toBeInstanceOf(StaticMockLink);
+  });
+
+  test('should create StaticMockLink with specified typename setting', () => {
+    const mockedResponse = {
+      request: {
+        query: gql`
+          query {
+            hello
+          }
+        `,
+        variables: {},
+      },
+      result: { data: { hello: 'world' } },
+    };
+
+    const link = mockSingleLink(mockedResponse, false);
+    expect((link as StaticMockLink).addTypename).toBe(false);
+  });
+
+  test('should handle non-matching variables between request and mocked response', () => {
+    const mockLink = new StaticMockLink([]);
+    const mockedResponse = {
+      request: {
+        query: sampleQuery,
+        variables: { id: '1' },
+      },
+      result: sampleResponse,
+    };
+
+    mockLink.addMockedResponse(mockedResponse);
+
+    return new Promise<void>((resolve) => {
+      const observable = mockLink.request({
+        query: sampleQuery,
+        variables: { id: '2' }, // Different variables
+      });
+
+      observable?.subscribe({
+        error: (error) => {
+          expect(error.message).toContain('No more mocked responses');
+          resolve();
+        },
+      });
+    });
+  });
+
+  test('should handle matching query but mismatched variable structure', () => {
+    const mockLink = new StaticMockLink([]);
+    const mockedResponse = {
+      request: {
+        query: sampleQuery,
+        variables: { id: '1', extra: 'field' },
+      },
+      result: sampleResponse,
+    };
+
+    mockLink.addMockedResponse(mockedResponse);
+
+    return new Promise<void>((resolve) => {
+      const observable = mockLink.request({
+        query: sampleQuery,
+        variables: { id: '1' }, // Missing extra field
+      });
+
+      observable?.subscribe({
+        error: (error) => {
+          expect(error.message).toContain('No more mocked responses');
+          resolve();
+        },
+      });
+    });
+  });
+
+  test('should handle onError behavior correctly', async () => {
+    const mockLink = new TestableStaticMockLink([], true);
+    const handlerSpy = vi.fn().mockReturnValue(undefined); // Return undefined to trigger error throw
+
+    mockLink.setErrorHandler(handlerSpy);
+
+    await new Promise<void>((resolve) => {
+      const observable = mockLink.request({
+        query: gql`
+          query TestQuery {
+            field
+          }
+        `,
+        variables: {},
+      });
+
+      observable?.subscribe({
+        next: () => {
+          throw new Error('Should not succeed');
+        },
+        error: (error) => {
+          // Verify the error handler was called
+          expect(handlerSpy).toHaveBeenCalledTimes(1);
+
+          // Verify we got the expected error
+          expect(error.message).toContain('No more mocked responses');
+
+          resolve();
+        },
+      });
+    });
+  }, 10000);
+  it('should throw an error if a mocked response lacks result and error', () => {
+    const mockedResponses = [
+      {
+        request: { query: mockQuery },
+        // Missing `result` and `error`
+      },
+    ];
+
+    const link = new StaticMockLink(mockedResponses);
+
+    const operation = {
+      query: mockQuery,
+      variables: {},
+    };
+
+    const observable = link.request(operation);
+
+    expect(observable).toBeInstanceOf(Observable);
+
+    // Subscribe to the observable and expect an error
+    observable?.subscribe({
+      next: () => {
+        // This shouldn't be called
+        throw new Error('next() should not be called');
+      },
+      error: (err) => {
+        // Check the error message
+        expect(err.message).toContain(
+          'Mocked response should contain either result or error',
+        );
+      },
+      complete: () => {
+        // This shouldn't be called
+        throw new Error('complete() should not be called');
+      },
+    });
+  });
+
+  it('should return undefined when no mocked response matches operation variables', () => {
+    const mockedResponses = [
+      {
+        request: {
+          query: mockQuery,
+          variables: { id: '123' },
+        },
+        result: { data: { test: { id: '123', name: 'Test Name' } } },
+      },
+    ];
+
+    const link = new StaticMockLink(mockedResponses);
+
+    // Simulate operation with unmatched variables
+    const operation = {
+      query: mockQuery,
+      variables: { id: '999' },
+    };
+
+    const key = JSON.stringify({
+      query: link.addTypename
+        ? print(mockQuery) // Add typename if necessary
+        : print(mockQuery),
+    });
+
+    const mockedResponsesByKey = link['_mockedResponsesByKey'][key];
+
+    // Emulate the internal logic
+    let responseIndex = -1;
+    const response = (mockedResponsesByKey || []).find((res, index) => {
+      const requestVariables = operation.variables || {};
+      const mockedResponseVariables = res.request.variables || {};
+      if (equal(requestVariables, mockedResponseVariables)) {
+        responseIndex = index;
+        return true;
+      }
+      return false;
+    });
+
+    // Assertions
+    expect(response).toBeUndefined();
+    expect(responseIndex).toBe(-1);
+  });
+
+  test('should initialize with empty mocked responses array', () => {
+    // Test with null/undefined
+    const mockLinkNull = new StaticMockLink(
+      null as unknown as readonly MockedResponse[],
+    );
+    expect(mockLinkNull).toBeInstanceOf(StaticMockLink);
+
+    // Test with defined responses
+    const mockResponses: readonly MockedResponse[] = [
+      {
+        request: {
+          query: sampleQuery,
+          variables: { id: '1' },
+        },
+        result: {
+          data: {
+            user: {
+              id: '1',
+              name: 'Test User',
+              __typename: 'User',
+            },
+          },
+        },
+      },
+      {
+        request: {
+          query: sampleQuery,
+          variables: { id: '2' },
+        },
+        result: {
+          data: {
+            user: {
+              id: '2',
+              name: 'Test User 2',
+              __typename: 'User',
+            },
+          },
+        },
+      },
+    ];
+
+    const mockLink = new StaticMockLink(mockResponses, true);
+
+    // Verify responses were added via constructor
+    const observable1 = mockLink.request({
+      query: sampleQuery,
+      variables: { id: '1' },
+    });
+
+    const observable2 = mockLink.request({
+      query: sampleQuery,
+      variables: { id: '2' },
+    });
+
+    return Promise.all([
+      new Promise<void>((resolve) => {
+        observable1?.subscribe({
+          next: (response) => {
+            expect(response?.data?.user?.id).toBe('1');
+            resolve();
+          },
+        });
+      }),
+      new Promise<void>((resolve) => {
+        observable2?.subscribe({
+          next: (response) => {
+            expect(response?.data?.user?.id).toBe('2');
+            resolve();
+          },
+        });
+      }),
+    ]);
+  });
+
+  test('should handle undefined operation variables', () => {
+    const mockLink = new StaticMockLink([]);
+    const mockedResponse: MockedResponse = {
+      request: {
+        query: sampleQuery,
+      },
+      result: {
+        data: {
+          user: {
+            id: '1',
+            name: 'Test User',
+            __typename: 'User',
+          },
+        },
+      },
+    };
+
+    mockLink.addMockedResponse(mockedResponse);
+
+    const observable = mockLink.request({
+      query: sampleQuery,
+      // Intentionally omitting variables
+    });
+
+    return new Promise<void>((resolve) => {
+      observable?.subscribe({
+        next: (response) => {
+          expect(response?.data?.user?.id).toBe('1');
+          resolve();
+        },
+      });
+    });
+  });
+
+  test('should handle response with direct result value', async () => {
+    const mockResponse: MockedResponse = {
+      request: {
+        query: TEST_QUERY,
+        variables: { id: '1' },
+      },
+      result: {
+        data: {
+          item: {
+            id: '1',
+            name: 'Test Item',
+            __typename: 'Item',
+          },
+        },
+      },
+    };
+
+    const link = new StaticMockLink([mockResponse]);
+
+    return new Promise<void>((resolve, reject) => {
+      const observable = link.request({
+        query: TEST_QUERY,
+        variables: { id: '1' },
+      });
+
+      if (!observable) {
+        reject(new Error('Observable is null'));
+        return;
+      }
+
+      observable.subscribe({
+        next(response) {
+          expect(response).toEqual(mockResponse.result);
+          resolve();
+        },
+        error: reject,
+      });
+    });
+  });
+
+  test('should handle response with result function', async () => {
+    const mockResponse: MockedResponse = {
+      request: {
+        query: TEST_QUERY,
+        variables: { id: '1' },
+      },
+      result: (variables: { id: string }) => ({
+        data: {
+          item: {
+            id: variables.id,
+            name: `Test Item ${variables.id}`,
+            __typename: 'Item',
+          },
+        },
+      }),
+    };
+
+    const link = new StaticMockLink([mockResponse]);
+
+    return new Promise<void>((resolve, reject) => {
+      const observable = link.request({
+        query: TEST_QUERY,
+        variables: { id: '1' },
+      });
+
+      if (!observable) {
+        reject(new Error('Observable is null'));
+        return;
+      }
+
+      observable.subscribe({
+        next(response) {
+          expect(response).toEqual({
+            data: {
+              item: {
+                id: '1',
+                name: 'Test Item 1',
+                __typename: 'Item',
+              },
+            },
+          });
+          resolve();
+        },
+        error: reject,
+      });
+    });
+  });
+
+  test('should handle response with error', async () => {
+    const testError = new Error('Test error');
+    const mockResponse: MockedResponse = {
+      request: {
+        query: TEST_QUERY,
+        variables: { id: '1' },
+      },
+      error: testError,
+    };
+
+    const link = new StaticMockLink([mockResponse]);
+
+    return new Promise<void>((resolve, reject) => {
+      const observable = link.request({
+        query: TEST_QUERY,
+        variables: { id: '1' },
+      });
+
+      if (!observable) {
+        reject(new Error('Observable is null'));
+        return;
+      }
+
+      observable.subscribe({
+        next() {
+          reject(new Error('Should not have called next'));
+        },
+        error(error) {
+          expect(error).toBe(testError);
+          resolve();
+        },
+      });
+    });
+  });
+
+  test('should respect response delay', async () => {
+    const mockResponse: MockedResponse = {
+      request: {
+        query: TEST_QUERY,
+        variables: { id: '1' },
+      },
+      result: {
+        data: {
+          item: {
+            id: '1',
+            name: 'Test Item',
+            __typename: 'Item',
+          },
+        },
+      },
+      delay: 50,
+    };
+
+    const link = new StaticMockLink([mockResponse]);
+    const startTime = Date.now();
+
+    return new Promise<void>((resolve, reject) => {
+      const observable = link.request({
+        query: TEST_QUERY,
+        variables: { id: '1' },
+      });
+
+      if (!observable) {
+        reject(new Error('Observable is null'));
+        return;
+      }
+
+      observable.subscribe({
+        next(response) {
+          const elapsed = Date.now() - startTime;
+          expect(elapsed).toBeGreaterThanOrEqual(50);
+          expect(response).toEqual(mockResponse.result);
+          resolve();
+        },
+        error: reject,
+      });
+    });
+  });
+});