Repository: TritonSE/Veteran-Sisters-Support-Website
Pull request #42: Veteran assigning in volunteer profile
Author: login: emmaz12
Created: 2025-04-11T03:17:38Z | Merged: 2025-04-17T20:15:35Z

## Tracking Info

Resolves #35

## Changes

Expanded functionality of volunteer assigning dialog to be user assigning dialog. eg) assign veteran to volunteer and vice versa. Updated backed to reflect that change. Implemented dialog to volunteer profile page view. Now, admin users are able to add volunteers if they are a veteran and vice versa through profile pages.


## Testing

Checked functionality locally. Walked through whole process of adding, removing, and ensuring correct users are fetch on the profile page.

- TODO

## Confirmation of Change


https://github.com/user-attachments/assets/f370f777-fe79-4d34-ad74-648397f1f382



Linked issue #35: [Small Feature] - Assigning Veteran to Volunteer through Volunteer Profile
Should be able to assign veterans to a volunteer through the volunteers profile, and the volunteer's profile should correctly populate with what veterans are assigned to them. Also, the volunteer dashboard should correctly populate with those veterans assigned to them, currently it doesn't work as the logic uses assignedUsers rather than activeVolunteers schema

Designer point of contact: Akira

<img width="631" alt="Image" src="https://github.com/user-attachments/assets/e5c40c7b-6565-4ba7-b063-cfe133708307" />

<img width="340" alt="Image" src="https://github.com/user-attachments/assets/b369c957-83cc-4251-b65f-95dc080a91e7" />

Diff:
diff --git a/backend/controllers/activeVolunteersController.js b/backend/controllers/activeVolunteersController.js
index 7df7d1e..40db3dd 100644
--- a/backend/controllers/activeVolunteersController.js
+++ b/backend/controllers/activeVolunteersController.js
@@ -3,7 +3,7 @@ import { ActiveVolunteers } from "../models/activeVolunteers.js";
 //query active volunteers by program, veteran, or get all active volunteers
 export const queryActiveVolunteers = async (req, res) => {
   try {
-    const { program, veteran } = req.query;
+    const { program, veteran, volunteer } = req.query;
     let query = {};
 
     if (program) {
@@ -15,8 +15,13 @@ export const queryActiveVolunteers = async (req, res) => {
       query.assignedVeteran = veteran;
     }
 
+    if (volunteer) {
+      query.volunteer = volunteer;
+    }
+
     const filteredVolunteers = await ActiveVolunteers.find(query)
       .populate("volunteerUser", "firstName lastName email")
+      .populate("veteranUser", "firstName lastName email")
       .exec();
 
     res.json(filteredVolunteers);
@@ -29,13 +34,14 @@ export const queryActiveVolunteers = async (req, res) => {
 //add a volunteer using their user email, program, and assigned veteran email
 export const addVolunteer = async (req, res) => {
   try {
-    const { userEmail, program, veteranEmail, userId } = req.body;
+    const { userEmail, program, veteranEmail, volunteerId, veteranId } = req.body;
 
     const existingVolunteer = await ActiveVolunteers.findOne({
       volunteer: userEmail,
       assignedProgram: program,
       assignedVeteran: veteranEmail,
-      volunteerUser: userId
+      volunteerUser: volunteerId,
+      veteranUser: veteranId,
     }).exec();
 
     if (existingVolunteer) {
@@ -48,7 +54,8 @@ export const addVolunteer = async (req, res) => {
       volunteer: userEmail,
       assignedProgram: program,
       assignedVeteran: veteranEmail,
-      volunteerUser: userId
+      volunteerUser: volunteerId,
+      veteranUser: veteranId,
     });
 
     res.status(201).json(newVolunteer);
@@ -81,7 +88,7 @@ export const removeVolunteer = async (req, res) => {
     }
 
     // If a specific entry is found, delete it
-    await ActiveVolunteers.deleteOne({ volunteer: volunteerEntry.volunteer}).exec();
+    await ActiveVolunteers.deleteOne({ volunteer: volunteerEntry.volunteer }).exec();
 
     return res.status(200).json({ message: "Volunteer assignment removed successfully" });
   } catch (error) {
diff --git a/backend/models/activeVolunteers.js b/backend/models/activeVolunteers.js
index 5f294b6..d21f72f 100644
--- a/backend/models/activeVolunteers.js
+++ b/backend/models/activeVolunteers.js
@@ -10,6 +10,7 @@ const activeVolunteersSchema = new Schema({
   assignedVeteran: String,
   volunteer: String,
   volunteerUser: { type: Schema.Types.ObjectId, ref: "User", required: true },
+  veteranUser: { type: Schema.Types.ObjectId, ref: "User", required: true },
 });
 
 export const ActiveVolunteers = model("ActiveVolunteers", activeVolunteersSchema);
diff --git a/backend/models/userModel.js b/backend/models/userModel.js
index 15a0824..56131e5 100644
--- a/backend/models/userModel.js
+++ b/backend/models/userModel.js
@@ -88,7 +88,7 @@ const userSchema = new Schema({
           "",
         ],
       },
-    ], 
+    ],
   },
   assignedPrograms: {
     type: [String],
diff --git a/backend/package-lock.json b/backend/package-lock.json
index 9909784..2d56312 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -1,11 +1,11 @@
 {
-  "name": "dfm-sideline-sidekick-app-backend",
+  "name": "veteran-sisters-website-backend",
   "version": "1.0.0",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
-      "name": "dfm-sideline-sidekick-app-backend",
+      "name": "veteran-sisters-website-backend",
       "version": "1.0.0",
       "dependencies": {
         "cors": "^2.8.5",
diff --git a/frontend/src/app/api/activeVolunteers.ts b/frontend/src/app/api/activeVolunteers.ts
index 139548a..814d223 100644
--- a/frontend/src/app/api/activeVolunteers.ts
+++ b/frontend/src/app/api/activeVolunteers.ts
@@ -1,4 +1,4 @@
-import { UserProfile } from "./profileApi";
+import { Role, UserProfile } from "./profileApi";
 import { APIResult, del, get, handleAPIError, post, put } from "./requests"; // Update path as needed
 
 export type ActiveVolunteer = {
@@ -6,6 +6,20 @@ export type ActiveVolunteer = {
   assignedVeteran: string;
   volunteer: string;
   volunteerUser: UserProfile;
+  veteranUser: UserProfile;
+};
+
+export const getVeteransByProgram = async (program: string): Promise<APIResult<UserProfile[]>> => {
+  try {
+    const response = await get(`/users?role=veteran&assignedProgram=${program}`);
+    if (!response.ok) {
+      return { success: false, error: response.statusText };
+    }
+    const data = (await response.json()) as UserProfile[];
+    return { success: true, data };
+  } catch (error: unknown) {
+    return handleAPIError(error);
+  }
 };
 
 export const getVolunteersByProgram = async (
@@ -23,18 +37,20 @@ export const getVolunteersByProgram = async (
   }
 };
 
-export const assignVolunteerToProgram = async (
+export const assignUserToProgram = async (
   volunteerEmail: string,
   veteranEmail: string,
   program: string,
   volunteerId: string,
+  veteranId: string,
 ): Promise<APIResult<ActiveVolunteer>> => {
   try {
     const requestBodyVolunteer = {
       userEmail: volunteerEmail,
       veteranEmail,
       program,
-      userId: volunteerId,
+      volunteerId,
+      veteranId,
     };
 
     // First request to add volunteer to activeVolunteer schema
@@ -94,11 +110,13 @@ export const removeVolunteerFromVeteran = async (
   }
 };
 
-export const getVolunteersByVeteran = async (
-  veteranEmail: string,
+export const getAssignedUsers = async (
+  user: UserProfile,
 ): Promise<APIResult<ActiveVolunteer[]>> => {
   try {
-    const response = await get(`/activeVolunteers?veteran=${veteranEmail}`);
+    //fetch volunteers if user is veteran and vice versa
+    const query = `?${user.role === Role.VETERAN ? `veteran=${user.email}` : `volunteer=${user.email}`}`;
+    const response = await get(`/activeVolunteers${query}`);
     if (!response.ok) {
       return handleAPIError(response);
     }
diff --git a/frontend/src/app/api/fileApi.ts b/frontend/src/app/api/fileApi.ts
index 25f9d61..a9d8cf3 100644
--- a/frontend/src/app/api/fileApi.ts
+++ b/frontend/src/app/api/fileApi.ts
@@ -1,10 +1,10 @@
+import { UserProfile } from "./profileApi";
 import { APIResult, del, get, handleAPIError, post, put } from "./requests";
-import { User } from "./userApi";
 
 export type Comment = {
   _id: string;
   comment: string;
-  commenterId: User;
+  commenterId: UserProfile;
   datePosted: string;
   edited?: boolean;
 };
diff --git a/frontend/src/app/api/userApi.ts b/frontend/src/app/api/userApi.ts
index 466a649..eacd802 100644
--- a/frontend/src/app/api/userApi.ts
+++ b/frontend/src/app/api/userApi.ts
@@ -1,3 +1,4 @@
+import { UserProfile } from "./profileApi";
 import { APIResult, get, handleAPIError, post } from "./requests";
 
 export type CreateUserRequest = {
@@ -55,20 +56,20 @@ export const createUser = async (
   }
 };
 
-export async function getUser(userId: string): Promise<APIResult<User>> {
+export async function getUser(userId: string): Promise<APIResult<UserProfile>> {
   try {
     const response = await get(`/users/id/${userId}`);
     if (!response.ok) {
       return handleAPIError(response);
     }
-    const data = (await response.json()) as User;
+    const data = (await response.json()) as UserProfile;
     return { success: true, data };
   } catch (error: unknown) {
     return { success: false, error: (error as Error).message };
   }
 }
 
-export async function getNonAdminUsers(program?: string): Promise<APIResult<User[]>> {
+export async function getNonAdminUsers(program?: string): Promise<APIResult<UserProfile[]>> {
   try {
     const response = program
       ? await get(`/nonAdminUsers?assignedProgram=${program}`)
@@ -76,20 +77,22 @@ export async function getNonAdminUsers(program?: string): Promise<APIResult<User
     if (!response.ok) {
       return handleAPIError(response);
     }
-    const users = (await response.json()) as User[];
+    const users = (await response.json()) as UserProfile[];
     return { success: true, data: users };
   } catch (error) {
     return handleAPIError(error);
   }
 }
 
-export async function getVeteransByVolunteer(volunteerId: string): Promise<APIResult<User[]>> {
+export async function getVeteransByVolunteer(
+  volunteerId: string,
+): Promise<APIResult<UserProfile[]>> {
   try {
     const response = await get(`/veterans/${volunteerId}`);
     if (!response.ok) {
       return handleAPIError(response);
     }
-    const users = (await response.json()) as User[];
+    const users = (await response.json()) as UserProfile[];
     return { success: true, data: users };
   } catch (error) {
     return handleAPIError(error);
diff --git a/frontend/src/app/components/AdminDashboard.tsx b/frontend/src/app/components/AdminDashboard.tsx
index d39c545..5552cd4 100644
--- a/frontend/src/app/components/AdminDashboard.tsx
+++ b/frontend/src/app/components/AdminDashboard.tsx
@@ -1,6 +1,7 @@
 import { useEffect, useState } from "react";
 
-import { User, getUser } from "../api/userApi";
+import { UserProfile } from "../api/profileApi";
+import { getUser } from "../api/userApi";
 import { AdminStaffUserTable } from "../components/AdminStaffUserTable";
 
 import styles from "./AdminDashboard.module.css";
@@ -10,7 +11,7 @@ type AdminDashboardProp = {
 };
 
 export function AdminDashboard({ adminId }: AdminDashboardProp) {
-  const [user, setUser] = useState<User>();
+  const [user, setUser] = useState<UserProfile>();
 
   useEffect(() => {
     getUser(adminId)
diff --git a/frontend/src/app/components/AdminStaffUserItem.tsx b/frontend/src/app/components/AdminStaffUserItem.tsx
index 75515b6..5af4628 100644
--- a/frontend/src/app/components/AdminStaffUserItem.tsx
+++ b/frontend/src/app/components/AdminStaffUserItem.tsx
@@ -1,25 +1,25 @@
 import Link from "next/link";
 
-import { User } from "../api/userApi";
+import { AssignedProgram as ProgramEnum, Role as RoleEnum, UserProfile } from "../api/profileApi";
 
 import styles from "./AdminStaffUserItem.module.css";
 import { Program } from "./Program";
 import { Role } from "./Role";
 
 type AdminStaffUserItemProp = {
-  user: User;
+  user: UserProfile;
 };
 
 export function AdminStaffUserItem({ user }: AdminStaffUserItemProp) {
   let assignedText;
   let assignedStyle = styles.assignedText;
-  const length = user.assignedUsers.length;
-  if (user.role === "staff") {
+  const length = user.assignedUsers ? user.assignedUsers.length : 0;
+  if (user.role === RoleEnum.STAFF) {
     assignedText = "Not applicable";
   } else if (length === 0) {
     assignedText = "Unassigned";
     assignedStyle = styles.unassignedText;
-  } else if (user.role === "volunteer") {
+  } else if (user.role === RoleEnum.VOLUNTEER) {
     assignedText = `${length.toString()} veteran${length === 1 ? "" : "s"}`;
   } else {
     assignedText = `${length.toString()} volunteer${length === 1 ? "" : "s"}`;
@@ -40,11 +40,13 @@ export function AdminStaffUserItem({ user }: AdminStaffUserItemProp) {
         </div>
         <div className={styles.program}>
           <div className={styles.programList}>
-            {user.assignedPrograms.includes("battle buddies") && (
+            {user.assignedPrograms?.includes(ProgramEnum.BATTLE_BUDDIES) && (
               <Program program="battle buddies" />
             )}
-            {user.assignedPrograms.includes("advocacy") && <Program program="advocacy" />}
-            {user.assignedPrograms.includes("operation wellness") && (
+            {user.assignedPrograms?.includes(ProgramEnum.ADVOCACY) && (
+              <Program program="advocacy" />
+            )}
+            {user.assignedPrograms?.includes(ProgramEnum.OPERATION_WELLNESS) && (
               <Program program="operation wellness" />
             )}
           </div>
diff --git a/frontend/src/app/components/AdminStaffUserTable.tsx b/frontend/src/app/components/AdminStaffUserTable.tsx
index 6a688a2..ba760ac 100644
--- a/frontend/src/app/components/AdminStaffUserTable.tsx
+++ b/frontend/src/app/components/AdminStaffUserTable.tsx
@@ -1,38 +1,44 @@
 import Image from "next/image";
 import { useEffect, useState } from "react";
 
-import { User, getNonAdminUsers } from "../api/userApi";
+import {
+  AssignedProgram,
+  AssignedProgram as ProgramEnum,
+  Role as RoleEnum,
+  UserProfile,
+} from "../api/profileApi";
+import { getNonAdminUsers } from "../api/userApi";
 
 import { AdminStaffUserItem } from "./AdminStaffUserItem";
 import styles from "./AdminStaffUserTable.module.css";
 import { Tabs } from "./Tabs";
 
 export function AdminStaffUserTable() {
-  const [users, setUsers] = useState<User[]>([]);
-  const [allUsers, setAllUsers] = useState<User[]>([]);
+  const [users, setUsers] = useState<UserProfile[]>([]);
+  const [allUsers, setAllUsers] = useState<UserProfile[]>([]);
   const [page, setPage] = useState<number>(0);
   const pageSize = 8;
 
-  const handleChangeProgram = (program: string) => {
-    if (program === "all") {
+  const handleChangeProgram = (program: ProgramEnum | undefined) => {
+    if (!program) {
       setUsers(allUsers);
     } else {
-      setUsers(allUsers.filter((user) => user.assignedPrograms.includes(program)));
+      setUsers(allUsers.filter((user) => user.assignedPrograms?.includes(program)));
     }
     setPage(0);
   };
 
-  const compare = (a: User, b: User) => {
+  const compare = (a: UserProfile, b: UserProfile) => {
     if (a.firstName < b.firstName) return -1;
     if (a.firstName > b.firstName) return 1;
     return 0;
   };
 
-  const sortUsers = (userList: User[]) => {
-    const unassigned: User[] = [];
-    const assigned: User[] = [];
+  const sortUsers = (userList: UserProfile[]) => {
+    const unassigned: UserProfile[] = [];
+    const assigned: UserProfile[] = [];
     userList.forEach((user) => {
-      if (user.assignedUsers.length === 0 && user.role !== "staff") {
+      if (user.assignedUsers?.length === 0 && user.role !== RoleEnum.STAFF) {
         unassigned.push(user);
       } else {
         assigned.push(user);
@@ -70,16 +76,16 @@ export function AdminStaffUserTable() {
       </div>
       <Tabs
         OnAll={() => {
-          handleChangeProgram("all");
+          handleChangeProgram(undefined);
         }}
         OnBattleBuddies={() => {
-          handleChangeProgram("battle buddies");
+          handleChangeProgram(AssignedProgram.BATTLE_BUDDIES);
         }}
         OnAdvocacy={() => {
-          handleChangeProgram("advocacy");
+          handleChangeProgram(AssignedProgram.ADVOCACY);
         }}
         OnOperationWellness={() => {
-          handleChangeProgram("operation wellness");
+          handleChangeProgram(AssignedProgram.OPERATION_WELLNESS);
         }}
       />
       <div className={styles.table}>
diff --git a/frontend/src/app/components/DocumentComment.tsx b/frontend/src/app/components/DocumentComment.tsx
index 3dd9434..0d9b126 100644
--- a/frontend/src/app/components/DocumentComment.tsx
+++ b/frontend/src/app/components/DocumentComment.tsx
@@ -10,7 +10,7 @@ import {
   editCommentObject,
   editFileObject,
 } from "../api/fileApi";
-import { User } from "../api/userApi";
+import { AssignedProgram as ProgramEnum, UserProfile } from "../api/profileApi";
 
 import styles from "./DocumentComment.module.css";
 import { Program } from "./Program";
@@ -19,7 +19,7 @@ import { Role } from "./Role";
 type DocumentCommentProps = {
   comment: Comment;
   file: FileObject;
-  user: User;
+  user: UserProfile;
   commentKey: number;
   selected: boolean;
   setSelected: (selected: boolean) => void;
@@ -36,9 +36,9 @@ export function DocumentComment({
   setFile,
 }: DocumentCommentProps) {
   const borderColor =
-    comment.commenterId.assignedPrograms[0] === "battle buddies"
+    comment.commenterId.assignedPrograms?.[0] === ProgramEnum.BATTLE_BUDDIES
       ? "#0093EB"
-      : comment.commenterId.assignedPrograms[0] === "advocacy"
+      : comment.commenterId.assignedPrograms?.[0] === ProgramEnum.ADVOCACY
         ? "#3730A3"
         : "#337357";
   const name = `${comment.commenterId.firstName} ${comment.commenterId.lastName}`;
@@ -75,7 +75,7 @@ export function DocumentComment({
   };
 
   const postCommentHandler = () => {
-    if (tempCommentBody?.trim() && file && user) {
+    if (tempCommentBody?.trim() && file && user._id) {
       if (currComment.comment !== "") {
         editCommentObject(comment._id, tempCommentBody)
           .then((response) => {
@@ -92,7 +92,7 @@ export function DocumentComment({
           });
       } else {
         const newComment: CreateCommentRequest = {
-          commenterId: user?._id,
+          commenterId: user._id,
           comment: tempCommentBody,
         };
         createCommentObject(newComment)
@@ -152,7 +152,7 @@ export function DocumentComment({
             <div className={styles.profileIcon}>{name.trim().substring(0, 1).toUpperCase()}</div>
             <div style={{ maxWidth: 100 }}>{name}</div>
             <Role role={comment.commenterId.role} />
-            {comment.commenterId.assignedPrograms.map((program, i) => {
+            {comment.commenterId.assignedPrograms?.map((program, i) => {
               return <Program key={i} program={program} iconOnly />;
             })}
           </div>
@@ -191,7 +191,7 @@ export function DocumentComment({
             <div className={styles.profileIcon}>{name.trim().substring(0, 1).toUpperCase()}</div>
             <div style={{ maxWidth: 100 }}>{name}</div>
             <Role role={comment.commenterId.role} />
-            {comment.commenterId.assignedPrograms.map((program, i) => {
+            {comment.commenterId.assignedPrograms?.map((program, i) => {
               return <Program key={i} program={program} iconOnly />;
             })}
           </div>
diff --git a/frontend/src/app/components/DocumentView.tsx b/frontend/src/app/components/DocumentView.tsx
index b39c6ad..7066eb9 100644
--- a/frontend/src/app/components/DocumentView.tsx
+++ b/frontend/src/app/components/DocumentView.tsx
@@ -11,7 +11,8 @@ import { storage } from "../../firebase/firebase";
 import "react-pdf/dist/Page/AnnotationLayer.css";
 import "react-pdf/dist/Page/TextLayer.css";
 import { Comment, FileObject, editFileObject, getFileById } from "../api/fileApi";
-import { User, getUser } from "../api/userApi";
+import { UserProfile } from "../api/profileApi";
+import { getUser } from "../api/userApi";
 import { useAuth } from "../contexts/AuthContext";
 
 import { DocumentComment } from "./DocumentComment";
@@ -36,7 +37,7 @@ export function DocumentView({ documentId }: DocumentViewProps) {
   const [editingTitle, setEditingTitle] = useState<boolean>();
   const [currTitle, setCurrTitle] = useState<string>();
 
-  const [currUser, setCurrUser] = useState<User>();
+  const [currUser, setCurrUser] = useState<UserProfile>();
   const { userId } = useAuth();
 
   useEffect(() => {
diff --git a/frontend/src/app/components/SignUpForm/SignUpForm.tsx b/frontend/src/app/components/SignUpForm/SignUpForm.tsx
index 7f7c76f..52394bb 100644
--- a/frontend/src/app/components/SignUpForm/SignUpForm.tsx
+++ b/frontend/src/app/components/SignUpForm/SignUpForm.tsx
@@ -6,6 +6,7 @@ import { useRouter } from "next/navigation";
 import React, { MouseEvent, useState } from "react";
 
 import { auth } from "../../../firebase/firebase";
+import { useAuth } from "../../contexts/AuthContext";
 
 import OnboardingInterests from "./OnboardingInterests";
 import RoleSelection from "./RoleSelection";
@@ -51,6 +52,7 @@ export default function SignUpForm() {
     service?: string; // On service page, all fields are required
     onboarding?: string; // At least one interest must be chosen on last page
   }>({});
+  const { setIsSigningUp } = useAuth();
 
   const handleNext = () => {
     setCurrentPage((prev) => {
@@ -91,6 +93,7 @@ export default function SignUpForm() {
     if (hasError) return;
 
     try {
+      setIsSigningUp(true);
       await createUserWithEmailAndPassword(auth, email, password);
       console.log("Firebase User created successfully!");
       // If successful, create user data in MongoDB
@@ -123,10 +126,12 @@ export default function SignUpForm() {
           assignedVeterans: [],
         };
         await createUserImported(newUser);
+        setIsSigningUp(false);
         router.push("/");
         console.log("User created successfully in MongoDB");
       } catch (error: unknown) {
         console.error("User creation failed:", error);
+        setIsSigningUp(false);
         alert("Something went wrong. Please try again.");
       }
     } catch (error: unknown) {
@@ -138,6 +143,7 @@ export default function SignUpForm() {
           }));
         }
       }
+      setIsSigningUp(false);
       return;
     }
   };
diff --git a/frontend/src/app/components/StaffDashboard.tsx b/frontend/src/app/components/StaffDashboard.tsx
index 516839c..ae465da 100644
--- a/frontend/src/app/components/StaffDashboard.tsx
+++ b/frontend/src/app/components/StaffDashboard.tsx
@@ -1,6 +1,7 @@
 import { useEffect, useState } from "react";
 
-import { User, getUser } from "../api/userApi";
+import { UserProfile } from "../api/profileApi";
+import { getUser } from "../api/userApi";
 import { AdminStaffUserTable } from "../components/AdminStaffUserTable";
 
 import styles from "./StaffDashboard.module.css";
@@ -10,7 +11,7 @@ type StaffDashboardProp = {
 };
 
 export function StaffDashboard({ staffId }: StaffDashboardProp) {
-  const [user, setUser] = useState<User>();
+  const [user, setUser] = useState<UserProfile>();
 
   useEffect(() => {
     getUser(staffId)
diff --git a/frontend/src/app/components/UserList.module.css b/frontend/src/app/components/UserList.module.css
index c84054b..344ae51 100644
--- a/frontend/src/app/components/UserList.module.css
+++ b/frontend/src/app/components/UserList.module.css
@@ -36,15 +36,12 @@
 
 .userList .addUser {
   display: flex;
-  height: 34px;
-  padding: var(--Spacing-sm, 16px) 12px;
+  height: 15px;
+  padding: var(--Spacing-sm, 16px) 9px;
   justify-content: center;
   align-items: center;
-  gap: 10px;
   width: fit-content;
-
   border-radius: var(--Spacing-sm, 16px);
-  border: 1px solid var(--Primary, #057e6f);
   background: var(--Primary, #057e6f);
 }
 
diff --git a/frontend/src/app/components/UserList.tsx b/frontend/src/app/components/UserList.tsx
index daa34cf..2a01314 100644
--- a/frontend/src/app/components/UserList.tsx
+++ b/frontend/src/app/components/UserList.tsx
@@ -1,18 +1,19 @@
 import Image from "next/image";
 import { useEffect, useState } from "react";
 
-import { getVolunteersByVeteran, removeVolunteerFromVeteran } from "../api/activeVolunteers";
-import { UserProfile as UserProfileType } from "../api/profileApi";
+import { getAssignedUsers, removeVolunteerFromVeteran } from "../api/activeVolunteers";
+import { Role, UserProfile as UserProfileType } from "../api/profileApi";
 
 import { Program } from "./Program";
 import styles from "./UserList.module.css";
-import VolunteerAssigningDialog from "./volunteerAssigningDialog";
+import UserAssigningDialog from "./userAssigningDialog";
 
 export function UserList(params: {
   userProfile: UserProfileType | undefined;
   title: string;
   editable: boolean;
   minimized: boolean;
+  setMessage: (message: string) => void;
 }) {
   const { title, userProfile, editable, minimized } = params;
   const userPrograms = Object.fromEntries(
@@ -20,9 +21,9 @@ export function UserList(params: {
   ) as Record<string, UserProfileType[]>;
 
   const [isDialogOpen, setIsDialogOpen] = useState(false);
+  const [refreshFlag, setRefreshFlag] = useState(false);
   const [dialogProgram, setDialogProgram] = useState("");
-  const [currentVolunteers, setCurrentVolunteers] =
-    useState<Record<string, UserProfileType[]>>(userPrograms);
+  const [currentUsers, setCurrentUsers] = useState<Record<string, UserProfileType[]>>(userPrograms);
 
   const openDialog = (program: string) => {
     setIsDialogOpen(true);
@@ -31,14 +32,17 @@ export function UserList(params: {
 
   const closeDialog = () => {
     setIsDialogOpen(false);
-    window.location.reload();
+    setRefreshFlag((prev) => !prev);
   };
 
-  const removeVolunteer = (volunteerEmail: string, program: string) => {
+  const removeVolunteer = (selectedEmail: string, program: string) => {
     if (userProfile) {
-      removeVolunteerFromVeteran(volunteerEmail, userProfile.email, program)
+      const vetEmail = userProfile.role === Role.VETERAN ? userProfile.email : selectedEmail;
+      const volEmail = userProfile.role === Role.VETERAN ? selectedEmail : userProfile.email;
+
+      removeVolunteerFromVeteran(volEmail, vetEmail, program)
         .then(() => {
-          window.location.reload();
+          setRefreshFlag((prev) => !prev);
         })
         .catch((err: unknown) => {
           console.error(err);
@@ -46,27 +50,29 @@ export function UserList(params: {
     }
   };
 
-  const fetchVolunteersProfiles = async (veteranEmail: string) => {
+  const fetchUserProfiles = async (user: UserProfileType) => {
     try {
-      const res = await getVolunteersByVeteran(veteranEmail);
+      const res = await getAssignedUsers(user);
       if (!res.success || !Array.isArray(res.data)) {
         throw new Error("Failed to fetch volunteers");
       }
 
-      const volunteerUsers: [string, UserProfileType][] = res.data.map((volunteer) => [
-        volunteer.assignedProgram,
-        volunteer.volunteerUser,
-      ]);
-
-      setCurrentVolunteers((prevVolunteers) => {
-        const updatedVolunteers = { ...prevVolunteers };
+      const users: [string, UserProfileType][] = res.data.map((profile) => {
+        const activeUser =
+          userProfile?.role === Role.VETERAN ? profile.volunteerUser : profile.veteranUser;
+        return [profile.assignedProgram, activeUser];
+      });
 
-        for (const [key, userObj] of volunteerUsers) {
-          if (!updatedVolunteers[key].some((user) => user.email === userObj.email)) {
-            updatedVolunteers[key].push(userObj);
+      setCurrentUsers(() => {
+        const updatedUsers = Object.fromEntries(
+          (userProfile?.assignedPrograms ?? []).map((program) => [program, []]),
+        ) as Record<string, UserProfileType[]>;
+        for (const [key, userObj] of users) {
+          if (!updatedUsers[key].some((vol) => vol.email === userObj.email)) {
+            updatedUsers[key].push(userObj);
           }
         }
-        return updatedVolunteers;
+        return updatedUsers;
       });
     } catch (error) {
       console.error("Error fetching volunteer profiles:", error);
@@ -77,61 +83,29 @@ export function UserList(params: {
   useEffect(() => {
     const fetchProfiles = async () => {
       if (userProfile?.email) {
-        await fetchVolunteersProfiles(userProfile.email);
+        await fetchUserProfiles(userProfile);
       }
     };
-
     void fetchProfiles();
-  }, []);
-
-  //Users for user list
-  // const emptyUserGroups: Record<string, UserProfileType[]> = (
-  //   userProfile?.assignedPrograms ?? []
-  // ).reduce((accumulator: Record<string, UserProfileType[]>, program: string) => {
-  //   accumulator[program] = [];
-  //   return accumulator;
-  // }, {});
-
-  // const assignedUsers = userProfile?.assignedUsers ?? [];
-  // const userGroups: Record<string, UserProfileType[]> = assignedUsers.reduce(
-  //   (accumulator, user) => {
-  //     (user?.assignedPrograms ?? []).forEach((program: string) => {
-  //       if (program in accumulator) {
-  //         accumulator[program].push(user);
-  //       }
-  //     });
-  //     return accumulator;
-  //   },
-  //   emptyUserGroups,
-  // );
+  }, [refreshFlag]);
 
-  const sortedUserGroups: [string, UserProfileType[]][] = Object.entries(currentVolunteers)
+  const sortedUserGroups: [string, UserProfileType[]][] = Object.entries(currentUsers)
     .slice()
     .sort();
-  // console.log(sortedUserGroups)
 
   return (
     <div className={`${styles.userList} ${minimized ? styles.minimized : ""}`}>
       {isDialogOpen && userProfile && (
-        <VolunteerAssigningDialog
+        <UserAssigningDialog
           isOpen={isDialogOpen}
           program={dialogProgram}
-          veteran={userProfile}
+          user={userProfile}
           closeDialog={closeDialog}
+          setMessage={params.setMessage}
         />
       )}
       <div className={styles.userListHeader}>
         <div className={styles.userListHeading}>{title}</div>
-        {editable && !minimized && (
-          <div className={styles.addUser}>
-            <Image
-              src="/pajamas_assignee_icon.svg"
-              width={16}
-              height={16}
-              alt="Assign User"
-            ></Image>
-          </div>
-        )}
       </div>
       <div className={styles.userListContent}>
         {sortedUserGroups.map(([program, users]) => {
@@ -141,12 +115,12 @@ export function UserList(params: {
                 <div className={styles.programSectionHeaderSectionInfo}>
                   <Program program={program} />
                 </div>
-                {editable && minimized && (
+                {editable && (
                   <div className={styles.addUser}>
                     <Image
-                      src="/pajamas_assignee_icon.svg"
-                      width={16}
-                      height={16}
+                      src="/add_icon.svg"
+                      width={14}
+                      height={14}
                       alt="Assign User"
                       onClick={() => {
                         openDialog(program);
diff --git a/frontend/src/app/components/UserProfile.module.css b/frontend/src/app/components/UserProfile.module.css
index 9b18357..c44d02f 100644
--- a/frontend/src/app/components/UserProfile.module.css
+++ b/frontend/src/app/components/UserProfile.module.css
@@ -42,3 +42,40 @@
   gap: var(--Spacing-md, 24px);
   align-self: stretch;
 }
+
+.messageContainer {
+  animation: fadeOut 5s forwards;
+  display: flex;
+  margin: auto;
+  padding: 8px;
+  font-size: 14px;
+  border-radius: 8px;
+  gap: 5px;
+  font-family: "Albert Sans";
+  font-weight: 500;
+}
+
+.messageError {
+  background-color: #851a1e1a;
+  border: 1px solid #851a1a33;
+}
+
+.messageSuccess {
+  background-color: #1a85381a;
+  border: 1px solid #1a853833;
+}
+
+.messageSuccess p {
+  color: #1a8538;
+}
+
+.messageError p {
+  color: #851a1a;
+}
+
+@keyframes fadeOut {
+  to {
+    opacity: 0;
+    visibility: hidden;
+  }
+}
diff --git a/frontend/src/app/components/UserProfile.tsx b/frontend/src/app/components/UserProfile.tsx
index 745bce1..3bc85ad 100644
--- a/frontend/src/app/components/UserProfile.tsx
+++ b/frontend/src/app/components/UserProfile.tsx
@@ -1,4 +1,5 @@
 "use client";
+import Image from "next/image";
 import { useEffect, useState } from "react";
 
 import {
@@ -117,6 +118,7 @@ export default function UserProfile({ profileUserId }: { profileUserId: string }
   );
   const [loading, setLoading] = useState(true);
   const [error, setError] = useState<string | null>(null);
+  const [message, setMessage] = useState("");
 
   useEffect(() => {
     const fetchUserProfile = async () => {
@@ -210,6 +212,7 @@ export default function UserProfile({ profileUserId }: { profileUserId: string }
                   title={profileRenderingContext.userListTitle}
                   editable={profileRenderingContext.userListEditable}
                   minimized={profileRenderingContext.showVolunteerNotes}
+                  setMessage={setMessage}
                 />
               )}
             </div>
@@ -218,6 +221,18 @@ export default function UserProfile({ profileUserId }: { profileUserId: string }
                 <VeteranDocuments uploader={profileUserId} />
               </div>
             )}
+            {message && (
+              <div
+                className={`${styles.messageContainer} ${message.includes("Successfully") ? styles.messageSuccess : styles.messageError}`}
+              >
+                {message.includes("Successfully") ? (
+                  <Image src="/check.svg" alt="Check Symbol" width={20} height={20}></Image>
+                ) : (
+                  <Image src="/error_symbol.svg" alt="Error Symbol" width={20} height={20}></Image>
+                )}
+                <p>{message}</p>
+              </div>
+            )}
           </div>
         </div>
       )}
diff --git a/frontend/src/app/components/VeteranDashboard.tsx b/frontend/src/app/components/VeteranDashboard.tsx
index a272eb3..2180105 100644
--- a/frontend/src/app/components/VeteranDashboard.tsx
+++ b/frontend/src/app/components/VeteranDashboard.tsx
@@ -1,7 +1,8 @@
 import Image from "next/image";
 import { useEffect, useState } from "react";
 
-import { User, getUser } from "../api/userApi";
+import { UserProfile } from "../api/profileApi";
+import { getUser } from "../api/userApi";
 import { FileUpload } from "../components/FileUpload";
 import { VeteranFilesTable } from "../components/VeteranFilesTable";
 import { useAuth } from "../contexts/AuthContext";
@@ -14,7 +15,7 @@ export function VeteranDashboard() {
   const [uploadPopup, setUploadPopup] = useState<boolean>(false);
   const [refreshDashboard, setRefreshDashboard] = useState<boolean>(false);
   const [showUploadConfirm, setShowUploadConfirm] = useState<boolean>(false);
-  const [currVeteran, setCurrVeteran] = useState<User>();
+  const [currVeteran, setCurrVeteran] = useState<UserProfile>();
   const [loading, setLoading] = useState(true);
 
   useEffect(() => {
@@ -53,7 +54,7 @@ export function VeteranDashboard() {
 
   return (
     <>
-      {currVeteran && (
+      {currVeteran?._id && (
         <div className={styles.page}>
           <div className={styles.topRow}>
             <h1>Welcome, {currVeteran?.firstName}!</h1>
@@ -70,12 +71,12 @@ export function VeteranDashboard() {
           <br />
           <br />
           <br />
-          <VeteranFilesTable veteranId={currVeteran?._id} refresh={refreshDashboard} />
+          <VeteranFilesTable veteranId={currVeteran._id} refresh={refreshDashboard} />
         </div>
       )}
-      {uploadPopup && currVeteran && (
+      {uploadPopup && currVeteran?._id && (
         <FileUpload
-          veteranId={currVeteran?._id}
+          veteranId={currVeteran._id}
           onClose={() => {
             setUploadPopup(false);
           }}
diff --git a/frontend/src/app/components/VeteranList.tsx b/frontend/src/app/components/VeteranList.tsx
index 2a84b30..156d912 100644
--- a/frontend/src/app/components/VeteranList.tsx
+++ b/frontend/src/app/components/VeteranList.tsx
@@ -1,19 +1,20 @@
 import { useEffect, useState } from "react";
 
-import { User, getVeteransByVolunteer } from "../api/userApi";
+import { ActiveVolunteer, getAssignedUsers } from "../api/activeVolunteers";
+import { UserProfile } from "../api/profileApi";
 
 import styles from "./VeteranList.module.css";
 import { VeteranProfileCard } from "./VeteranProfileCard";
 
 type VeteranListProp = {
-  volunteerId: string;
+  volunteer: UserProfile;
 };
 
-export function VeteranList({ volunteerId }: VeteranListProp) {
-  const [users, setUsers] = useState<User[]>([]);
+export function VeteranList({ volunteer }: VeteranListProp) {
+  const [users, setUsers] = useState<ActiveVolunteer[]>([]);
 
   useEffect(() => {
-    getVeteransByVolunteer(volunteerId)
+    getAssignedUsers(volunteer)
       .then((result) => {
         if (result.success) {
           setUsers(result.data);
@@ -33,15 +34,15 @@ export function VeteranList({ volunteerId }: VeteranListProp) {
       <div className={styles.table}>
         {users.map((user) => (
           <VeteranProfileCard
-            key={user._id}
+            key={user.veteranUser._id}
             user={{
-              _id: user._id,
-              email: user.email,
-              firstName: user.firstName,
-              lastName: user.lastName,
-              role: user.role,
-              assignedPrograms: user.assignedPrograms,
-              assignedUsers: user.assignedUsers,
+              _id: user.veteranUser._id,
+              email: user.veteranUser.email,
+              firstName: user.veteranUser.firstName,
+              lastName: user.veteranUser.lastName,
+              role: user.veteranUser.role,
+              assignedPrograms: user.veteranUser.assignedPrograms,
+              assignedUsers: user.veteranUser.assignedUsers,
             }}
           />
         ))}
diff --git a/frontend/src/app/components/VeteranProfileCard.tsx b/frontend/src/app/components/VeteranProfileCard.tsx
index 40f61d5..e9194e7 100644
--- a/frontend/src/app/components/VeteranProfileCard.tsx
+++ b/frontend/src/app/components/VeteranProfileCard.tsx
@@ -1,11 +1,11 @@
 import Link from "next/link";
 
-import { User } from "../api/userApi";
+import { UserProfile } from "../api/profileApi";
 
 import styles from "./VeteranProfileCard.module.css";
 
 type VeteranProfileCardProp = {
-  user: User;
+  user: UserProfile;
 };
 
 export function VeteranProfileCard({ user }: VeteranProfileCardProp) {
diff --git a/frontend/src/app/components/VolunteerDashboard.tsx b/frontend/src/app/components/VolunteerDashboard.tsx
index c96b149..f5a1725 100644
--- a/frontend/src/app/components/VolunteerDashboard.tsx
+++ b/frontend/src/app/components/VolunteerDashboard.tsx
@@ -1,6 +1,7 @@
 import { useEffect, useState } from "react";
 
-import { User, getUser } from "../api/userApi";
+import { UserProfile } from "../api/profileApi";
+import { getUser } from "../api/userApi";
 import { VeteranList } from "../components/VeteranList";
 
 import styles from "./VolunteerDashboard.module.css";
@@ -10,7 +11,7 @@ type VolunteerDashboardProp = {
 };
 
 export function VolunteerDashboard({ volunteerId }: VolunteerDashboardProp) {
-  const [user, setUser] = useState<User>();
+  const [user, setUser] = useState<UserProfile>();
 
   useEffect(() => {
     getUser(volunteerId)
@@ -31,7 +32,7 @@ export function VolunteerDashboard({ volunteerId }: VolunteerDashboardProp) {
           <div className={styles.welcome}>
             <span>Welcome, {user?.firstName}!</span>
           </div>
-          <VeteranList volunteerId={volunteerId} />
+          {user && <VeteranList volunteer={user} />}
         </div>
       </div>
     </div>
diff --git a/frontend/src/app/components/volunteerAssigningDialog.tsx b/frontend/src/app/components/userAssigningDialog.tsx
similarity index 54%
rename from frontend/src/app/components/volunteerAssigningDialog.tsx
rename to frontend/src/app/components/userAssigningDialog.tsx
index 93951b4..5f7b2f5 100644
--- a/frontend/src/app/components/volunteerAssigningDialog.tsx
+++ b/frontend/src/app/components/userAssigningDialog.tsx
@@ -3,18 +3,23 @@
 import { useEffect, useState } from "react";
 import Select from "react-select";
 
-import { assignVolunteerToProgram, getVolunteersByProgram } from "../api/activeVolunteers";
-import { UserProfile as UserProfileType } from "../api/profileApi";
-import { Program } from "../components/Program";
-import { Role } from "../components/Role";
-
+import {
+  assignUserToProgram,
+  getVeteransByProgram,
+  getVolunteersByProgram,
+} from "../api/activeVolunteers";
+import { Role as RoleEnum, UserProfile as UserProfileType } from "../api/profileApi";
+
+import { Program } from "./Program";
+import { Role } from "./Role";
 import styles from "./veteranProfile.module.css";
 
-type VolunteerAssigningDialogProps = {
+type UserAssigningDialogProps = {
   closeDialog: () => void;
   isOpen: boolean;
   program: string;
-  veteran: UserProfileType;
+  user: UserProfileType;
+  setMessage: (message: string) => void;
 };
 
 type OptionType = {
@@ -22,47 +27,70 @@ type OptionType = {
   label: string;
 };
 
-export default function VolunteerAssigningDialog(props: VolunteerAssigningDialogProps) {
+export default function UserAssigningDialog(props: UserAssigningDialogProps) {
   const [hasMounted, setHasMounted] = useState(false);
-  const [message, setMessage] = useState("");
   const [volunteers, setVolunteers] = useState<UserProfileType[]>([]);
   const [isLoading, setIsLoading] = useState<boolean>(false);
   const [selectedVolunteerOption, setSelectedVolunteerOption] = useState<OptionType | null>(null);
+  props.setMessage("");
 
   const availableVolunteers = () => {
     setIsLoading(true);
-    getVolunteersByProgram(props.program)
-      .then((response) => {
-        setIsLoading(false);
-        if (response.success) {
-          setVolunteers(response.data);
-        } else {
-          console.log(response.error);
-        }
-      })
-      .catch((err: unknown) => {
-        console.error(err);
-        setIsLoading(false);
-      });
+    //if user is veteran, the dialog will show volunteers
+    if (props.user.role === RoleEnum.VETERAN) {
+      getVolunteersByProgram(props.program)
+        .then((response) => {
+          setIsLoading(false);
+          if (response.success) {
+            setVolunteers(response.data);
+          } else {
+            console.log(response.error);
+          }
+        })
+        .catch((err: unknown) => {
+          console.error(err);
+          setIsLoading(false);
+        });
+    } else if (props.user.role === RoleEnum.VOLUNTEER) {
+      //if user is volunteer, the dialog will show veterans
+      getVeteransByProgram(props.program)
+        .then((response) => {
+          setIsLoading(false);
+          if (response.success) {
+            setVolunteers(response.data);
+          } else {
+            console.log(response.error);
+          }
+        })
+        .catch((err: unknown) => {
+          console.error(err);
+          setIsLoading(false);
+        });
+    }
   };
 
-  const assignVolunteer = () => {
-    if (!selectedVolunteerOption?.value._id) {
+  const assignVolunteer = async () => {
+    if (!selectedVolunteerOption?.value._id || !props.user._id) {
       return null;
     }
-
-    assignVolunteerToProgram(
-      selectedVolunteerOption.value.email,
-      props.veteran.email,
-      props.program,
-      selectedVolunteerOption.value._id,
-    )
+    const volunteerEmail =
+      props.user.role === RoleEnum.VETERAN ? selectedVolunteerOption.value.email : props.user.email;
+    const veteranEmail =
+      props.user.role === RoleEnum.VETERAN ? props.user.email : selectedVolunteerOption.value.email;
+    const volunteerId =
+      props.user.role === RoleEnum.VETERAN ? selectedVolunteerOption.value._id : props.user._id;
+    const veteranId =
+      props.user.role === RoleEnum.VETERAN ? props.user._id : selectedVolunteerOption.value._id;
+
+    await assignUserToProgram(volunteerEmail, veteranEmail, props.program, volunteerId, veteranId)
       .then((response) => {
         if (response.success) {
-          setMessage("Successfully assigned volunteer!");
+          props.setMessage(
+            `Successfully assigned ${selectedVolunteerOption?.value.firstName} to ${props.user.firstName}`,
+          );
         } else {
-          setMessage(
-            "Failed to assign volunteer. Ensure volunteer is not already assigned to veteran.",
+          props.setMessage(
+            "Failed to assign user. Ensure user is not already assigned to this person.",
           );
         }
       })
@@ -78,25 +106,15 @@ export default function VolunteerAssigningDialog(props: VolunteerAssigningDialog
     }
   }, []);
 
-  useEffect(() => {
-    if (message) {
-      const timer = setTimeout(() => {
-        setMessage("");
-      }, 2000);
-
-      return () => {
-        clearTimeout(timer);
-      };
-    }
-  }, [message]);
-
   if (!hasMounted || !props.isOpen) {
     return null;
   }
 
   const formattedOptions = volunteers.map((v) => ({
     value: v,
-    label: `${v.firstName} ${v.lastName} - ${String(v.assignedUsers?.length ?? 0)} veterans`,
+    label: `${v.firstName} ${v.lastName} - ${String(v.assignedUsers?.length ?? 0)} ${
+      props.user.role === RoleEnum.VETERAN ? "veterans" : "volunteers"
+    }`,
   }));
 
   const customLabel = (option: OptionType) => (
@@ -107,7 +125,7 @@ export default function VolunteerAssigningDialog(props: VolunteerAssigningDialog
   );
 
   if (isLoading || !formattedOptions.length) {
-    return <div>Loading...</div>;
+    return;
   }
 
   return (
@@ -115,19 +133,21 @@ export default function VolunteerAssigningDialog(props: VolunteerAssigningDialog
       <div className={styles.dialog}>
         <div className={styles.headerInfoContainer}>
           <div className={styles.headerInfo}>
-            {`Assign: ${props.veteran.firstName}`}
-            <Role role="veteran" />
+            {`Assign: ${props.user.firstName}`}
+            <Role role={props.user.role} />
             {selectedVolunteerOption
               ? ` to ${selectedVolunteerOption.value.firstName} ${selectedVolunteerOption.value.lastName}`
               : " to ..."}
-            {selectedVolunteerOption && <Role role="volunteer" />}
+            {selectedVolunteerOption && <Role role={selectedVolunteerOption.value.role} />}
           </div>
           <Program program={props.program} />
         </div>
 
         <div className={styles.searchBar}>
           <Select
-            placeholder="Choose a volunteer"
+            placeholder={
+              props.user.role === RoleEnum.VOLUNTEER ? "Choose a veteran" : "Choose a volunteer"
+            }
             options={formattedOptions}
             menuPortalTarget={document.body}
             formatOptionLabel={customLabel}
@@ -143,7 +163,7 @@ export default function VolunteerAssigningDialog(props: VolunteerAssigningDialog
             <div className={styles.volunteerInfo}>
               <div className={styles.headerInfo}>
                 {selectedVolunteerOption.value.firstName} {selectedVolunteerOption.value.lastName}
-                <Role role="volunteer" />
+                <Role role={selectedVolunteerOption.value.role} />
                 <Program program={props.program} />
               </div>
               <p>
@@ -164,8 +184,10 @@ export default function VolunteerAssigningDialog(props: VolunteerAssigningDialog
                 </span>
               </p>
             </div>
-            {/* TODO: link to volunteer profile page when done */}
-            <a className={styles.profileLink} href="google.com">
+            <a
+              className={styles.profileLink}
+              href={`/profile/${selectedVolunteerOption.value._id ?? ""}`}
+            >
               View Profile
             </a>
           </div>
@@ -177,14 +199,14 @@ export default function VolunteerAssigningDialog(props: VolunteerAssigningDialog
           </button>
           <button
             disabled={!selectedVolunteerOption}
-            onClick={assignVolunteer}
+            onClick={() => {
+              void assignVolunteer().then(props.closeDialog);
+            }}
             className={styles.save}
           >
             Save
           </button>
         </div>
-
-        {message && <p className={styles.message}>{message}</p>}
       </div>
     </div>
   );
diff --git a/frontend/src/app/contexts/AuthContext.tsx b/frontend/src/app/contexts/AuthContext.tsx
index 8f8a0a0..ee484f0 100644
--- a/frontend/src/app/contexts/AuthContext.tsx
+++ b/frontend/src/app/contexts/AuthContext.tsx
@@ -46,6 +46,7 @@ type AuthContextType = {
   userRole: string;
   loading: boolean;
   loggedIn: boolean;
+  setIsSigningUp: (value: boolean) => void;
 };
 
 const AuthContext = React.createContext<AuthContextType>({
@@ -54,6 +55,9 @@ const AuthContext = React.createContext<AuthContextType>({
   userRole: "",
   loading: true,
   loggedIn: false,
+  setIsSigningUp: () => {
+    console.warn("setIsSigningUp called outside of AuthProvider");
+  },
 });
 
 export const useAuth = () => useContext(AuthContext);
@@ -63,12 +67,13 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
   const [userId, setUserId] = useState("");
   const [userRole, setUserRole] = useState("");
   const [loading, setLoading] = useState(true);
+  const [isSigningUp, setIsSigningUp] = useState(false);
 
   useEffect(() => {
     const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
       setUser(currentUser);
-      if (currentUser?.email) {
-        // Only make the API request if the user is signed in with Firebase
+      if (currentUser?.email && !isSigningUp) {
+        // Only make the API request if the user is signed in with Firebase and not signing up
         void getUserIdAndRole(currentUser.email).then(({ id, role }) => {
           setUserId(id);
           setUserRole(role);
@@ -77,7 +82,7 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
           setCurrentUserInfo(id, role);
         });
       } else {
-        // If no user is signed in, reset the state
+        // If no user is signed in or is signing up, reset the state
         setUserId("");
         setUserRole("");
         setLoading(false);
@@ -89,7 +94,7 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
     return () => {
       unsubscribe();
     };
-  }, []);
+  }, [isSigningUp]);
 
   const value = useMemo(() => {
     return {
@@ -98,8 +103,9 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
       userRole,
       loading,
       loggedIn: !!user,
+      setIsSigningUp,
     };
-  }, [user, userId, userRole, loading]);
+  }, [user, userId, userRole, loading, setIsSigningUp]);
 
   return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
 };


Reviews:
user: login: Anthonyp0329
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-14T00:14:18Z
user: login: Anthonyp0329
body: Looks great!! Just make sure to merge main and make the changes I suggested, then we can test again, and merge! Thanks Emma!
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-14T00:17:04Z
user: login: Azhou2023
body: Looks good to me, everything works well! Just a few comments about the whole assigning flow; I feel that the window.location.reload() calls make the whole process feel not great to interact with; IMO, it's more cohesive to just explictly update whatever useState that tracks the current assigned users when an action is performed rather than reloading the entire window and implicitly triggering the useEffect that way. Also the small "Loading..." text that pops up when you click on the assign user button also bothers me a bit lol since it pushes the entire table down momentarily. This is very nitpicky but I think that the user experience smoothness is really important and I don't think the whole window reload() thing is the best way to approach the content updates, as it kind of disrupts the nice flow of the page interaction. Just some thoughts!


Edit from Emma: 
made those changes! lmk if that looks better
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-15T01:01:29Z
user: login: Anthonyp0329
body: Wait also could you make it so a volunteers assigned veterans properly show on the volunteers home page, the logic here is outdated for this:
<img width="1433" alt="image" src="https://github.com/user-attachments/assets/47bf33a4-bb7a-43d0-b623-9c727579869a" />

state: CHANGES_REQUESTED
author_association: COLLABORATOR
submitted_at: 2025-04-15T22:09:38Z
user: login: Anthonyp0329
body: swag looks awesome now! i see you removed all the uses of User, I also just pushed a commit to remove it from userApi entirely. thanks for the awesome work and also for catching the issue!!
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-16T04:33:24Z
user: login: jliu0140
body: All looks good to me! Just a small thought I had though is that exiting the assignment dialog might be a bit janky, especially if I just saved an assignment, but then have to click cancel to exit compared to it just exiting. I suppose there are also other considerations such as adding more or wanting to view the profile, so it's really just a small detail. Otherwise looks great!
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T19:19:43Z
user: login: Azhou2023
body: Thanks for changing the window reload stuff! Everything looks good
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-17T06:49:45Z

Review comments:
diff_hunk: @@ -30,6 +30,6 @@ router.delete("/users/:email", deleteUser);
 
 router.get("/users/role/:email", getUserRole);
 router.patch("/users/id/:id", updateUser);
-router.put("/users/:email", updateUser);
+router.put("/users/:email", updateUserAssignment);
path: backend/routes/userRoutes.js
user: login: Anthonyp0329
body: Once main is merged, make sure to add requireSignedIn here
created_at: 2025-04-14T00:14:18Z
author_association: COLLABORATOR
diff_hunk: @@ -1,13 +1,34 @@
 import { APIResult } from "./fileApi";
-import { UserProfile } from "./profileApi";
+import { Role, UserProfile } from "./profileApi";
 
 export type ActiveVolunteer = {
   assignedProgram: string;
   assignedVeteran: string;
   volunteer: string;
   volunteerUser: UserProfile;
+  veteranUser: UserProfile;
 };
 
+export const getVeteransByProgram = async (
+  program: string,
+): Promise<APIResult<UserProfile[]>> => {
+  try {
+    const response = await fetch(`http://localhost:4000/api/users?role=veteran&assignedProgram=${program}`, {
path: frontend/src/app/api/activeVolunteers.ts
user: login: Anthonyp0329
body: make sure to use the get method from requests.ts here, as this includes necessary headers and such
created_at: 2025-04-14T00:15:00Z
author_association: COLLABORATOR
diff_hunk: @@ -50,6 +73,7 @@ export const assignVolunteerToProgram = async (
       },
       body: JSON.stringify(requestBodyVolunteer),
     });
+    console.log(requestBodyVolunteer)
path: frontend/src/app/api/activeVolunteers.ts
user: login: Anthonyp0329
body: remove this console log
created_at: 2025-04-14T00:15:18Z
author_association: COLLABORATOR
diff_hunk: @@ -131,12 +155,14 @@ export const removeVolunteerFromVeteran = async (
   }
 };
 
-export const getVolunteersByVeteran = async (
-  veteranEmail: string,
+export const getAssignedUsers = async (
+  user: UserProfile
 ): Promise<APIResult<ActiveVolunteer[]>> => {
   try {
+    //fetch volunteers if user is veteran and vice versa
+    const query = `?${user.role === Role.VETERAN? `veteran=${user.email}` : `volunteer=${user.email}`}`;
     const response = await fetch(
-      `http://localhost:4000/api/activeVolunteers?veteran=${veteranEmail}`,
+      `http://localhost:4000/api/activeVolunteers${query}`,
path: frontend/src/app/api/activeVolunteers.ts
user: login: Anthonyp0329
body: make sure to use get method from requests.ts here, can reference the other api calls once main is merged
created_at: 2025-04-14T00:15:40Z
author_association: COLLABORATOR
diff_hunk: @@ -27,8 +27,7 @@ export function AdminStaffUserItem({ user }: AdminStaffUserItemProp) {
 
   return (
     <div className={styles.container}>
-      {/* Placeholder link  */}
-      <Link href="/profile" className={styles.link}>
+      <Link href={`/profile/${user._id}`} className={styles.link}>
path: frontend/src/app/components/AdminStaffUserItem.tsx
user: login: Anthonyp0329
body: once main is merged, make sure to make this link using search params, so should be /profile?userId=${user._id}
created_at: 2025-04-14T00:16:08Z
author_association: COLLABORATOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-04-15T18:59:31Z
body: Visit the preview URL for this PR (updated for commit 67830a2):

[https://veteran-sisters--pr42-emma-volunteerassign-y4yvscwh.web.app](https://veteran-sisters--pr42-emma-volunteerassign-y4yvscwh.web.app)

<sub>(expires Thu, 24 Apr 2025 20:12:59 GMT)</sub>

<sub>🔥 via [Firebase Hosting GitHub Action](https://github.com/marketplace/actions/deploy-to-firebase-hosting) 🌎</sub>

<sub>Sign: 5733395fbc8c640925aacedc473346f7e668d2c7</sub>
author_association: NONE
user: login: emmaz12
created_at: 2025-04-16T02:37:19Z
body: updated volunteer dashboard to show assigned veterans. 


<img width="482" alt="Screenshot 2025-04-15 at 7 36 04 PM" src="https://github.com/user-attachments/assets/bbb351a5-fadd-4c40-84d1-48b6e63780c9" />

Note: there is a type of UserProfile and User which are both defined for the user object. However, the userprofile one is more accurate compared to the user one. We should probably refactor all instances of user type to be userprofile type.
I change all the ones that cascaded from when I changed the type in the veterandashboard
author_association: CONTRIBUTOR
user: login: emmaz12
created_at: 2025-04-16T21:09:09Z
body: @Anthonyp0329 As an add on to jeffery's comment about exiting the dialog, maybe it might be better to change the cancel button to say close instead? I also thought it was suboptimal to be clicking cancel to close the dialog. 
author_association: CONTRIBUTOR
user: login: Anthonyp0329
created_at: 2025-04-16T21:21:41Z
body: > @Anthonyp0329 As an add on to jeffery's comment about exiting the dialog, maybe it might be better to change the cancel button to say close instead? I also thought it was suboptimal to be clicking cancel to close the dialog.

Ooh yes i'd agree. could we also maybe make the dialog close when you save?
author_association: COLLABORATOR
user: login: emmaz12
created_at: 2025-04-17T20:12:52Z
body: @Anthonyp0329 I changed the save to close the dialog and also display the status successful or not. 

https://github.com/user-attachments/assets/71154f4b-991c-4ffe-ac0c-c31a98dcab7e


author_association: CONTRIBUTOR
user: login: Anthonyp0329
created_at: 2025-04-17T20:14:46Z
body: Swag!! Good to merge imo, we can also double check with designers for frontend thoughts during meeting tmrw but i'm cool with you merging
author_association: COLLABORATOR