From 9dde7eda31a1d274b6c04383f7f0deee805999ba Mon Sep 17 00:00:00 2001 From: Rajatava Das Date: Wed, 14 Jan 2026 22:45:13 +0530 Subject: [PATCH 1/2] Team Img css fix --- src/components/TeamCard/styles/TeamCard.module.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/TeamCard/styles/TeamCard.module.scss b/src/components/TeamCard/styles/TeamCard.module.scss index 6253407a..ffe5f401 100644 --- a/src/components/TeamCard/styles/TeamCard.module.scss +++ b/src/components/TeamCard/styles/TeamCard.module.scss @@ -15,10 +15,11 @@ .teamMemberImg { - width: fit-content; border-radius: 10px 10px 0 0; width: 100%; height: 100%; + object-fit: cover; + object-position: center; } .ImgDiv{ @@ -27,6 +28,9 @@ background-color: #aeaeae; border-radius: 10px 10px 0 0; overflow: hidden; + display: flex; + align-items: center; + justify-content: center; } .ImgDiv span{ margin-left: 0; From aa3c8006acef723b37a65f5896cdbf2a537de10f Mon Sep 17 00:00:00 2001 From: Rajatava Das Date: Sat, 17 Jan 2026 21:05:25 +0530 Subject: [PATCH 2/2] Remove member --- .../TeamDetailsModal/TeamDetailsModal.jsx | 101 +++++++++++++++--- .../style/TeamDetailsModal.module.scss | 46 ++++++-- 2 files changed, 125 insertions(+), 22 deletions(-) diff --git a/src/features/Modals/Event/TeamDetailsModal/TeamDetailsModal.jsx b/src/features/Modals/Event/TeamDetailsModal/TeamDetailsModal.jsx index 0315153d..50690956 100644 --- a/src/features/Modals/Event/TeamDetailsModal/TeamDetailsModal.jsx +++ b/src/features/Modals/Event/TeamDetailsModal/TeamDetailsModal.jsx @@ -1,9 +1,10 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useContext } from "react"; import PropTypes from "prop-types"; -import { MdClose, MdGroups, MdPerson, MdEmail, MdSchool, MdCalendarToday } from "react-icons/md"; +import { MdClose, MdGroups, MdPerson, MdEmail, MdSchool, MdCalendarToday, MdPersonRemove } from "react-icons/md"; import { FaCopy, FaCheck } from "react-icons/fa"; import { api } from "../../../../services"; import { Alert, MicroLoading } from "../../../../microInteraction"; +import AuthContext from "../../../../context/AuthContext"; import styles from "./style/TeamDetailsModal.module.scss"; const TeamDetailsModal = ({ isOpen, onClose, formId, eventTitle }) => { @@ -11,6 +12,8 @@ const TeamDetailsModal = ({ isOpen, onClose, formId, eventTitle }) => { const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const [copiedCode, setCopiedCode] = useState(false); + const [removingMember, setRemovingMember] = useState(null); + const authCtx = useContext(AuthContext); useEffect(() => { if (isOpen && formId) { @@ -61,7 +64,7 @@ const TeamDetailsModal = ({ isOpen, onClose, formId, eventTitle }) => { await navigator.clipboard.writeText(teamDetails.teamCode); setCopiedCode(true); setTimeout(() => setCopiedCode(false), 2000); - + Alert({ type: "success", message: "Team code copied to clipboard!", @@ -74,6 +77,59 @@ const TeamDetailsModal = ({ isOpen, onClose, formId, eventTitle }) => { } }; + const handleRemoveMember = async (memberEmail, memberName) => { + // Confirm removal + const confirmed = window.confirm( + `Are you sure you want to remove ${memberName} from the team?` + ); + + if (!confirmed) return; + + try { + setRemovingMember(memberEmail); + + const response = await api.delete(`/api/form/removeMember/${formId}`, { + data: { memberEmail }, + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + }); + + if (response.status === 200) { + Alert({ + type: "success", + message: "Member removed successfully!", + position: "bottom-right", + duration: 3000, + }); + + // Update team details with the response data + setTeamDetails(response.data.data); + } else { + setError(response.data.message || "Failed to remove member"); + } + } catch (err) { + console.error("Error removing member:", err); + setError( + err.response?.data?.message || "Failed to remove member. Please try again." + ); + } finally { + setRemovingMember(null); + } + }; + + // Check if current user is team creator or admin + const canRemoveMembers = () => { + if (!teamDetails || !authCtx.user) return false; + + // Get the team creator email (first member who registered) + const teamCreatorEmail = teamDetails.members[0]?.email; + const currentUserEmail = authCtx.user.email; + const isAdmin = authCtx.user.access === "ADMIN"; + + return currentUserEmail === teamCreatorEmail || isAdmin; + }; + const handleBackdropClick = (e) => { if (e.target === e.currentTarget) { onClose(); @@ -109,19 +165,19 @@ const TeamDetailsModal = ({ isOpen, onClose, formId, eventTitle }) => {

Team Information

- +
Team Name: {teamDetails.teamName}
- +
Team Code:
{teamDetails.teamCode} -
- +
Team Size: @@ -144,10 +200,10 @@ const TeamDetailsModal = ({ isOpen, onClose, formId, eventTitle }) => {

Team Members ({teamDetails.members.length})

- +
{teamDetails.members.map((member, index) => ( -
+
{member.img ? ( {member.name} @@ -157,30 +213,30 @@ const TeamDetailsModal = ({ isOpen, onClose, formId, eventTitle }) => {
)}
- +
{member.name || "Unknown"}
- +
{member.email}
- + {member.rollNumber && (
Roll: {member.rollNumber}
)} - + {member.college && (
{member.college}
)} - + {member.year && (
@@ -189,6 +245,21 @@ const TeamDetailsModal = ({ isOpen, onClose, formId, eventTitle }) => { )}
+ + {canRemoveMembers() && teamDetails.members.length > 1 && ( + + )}
))}
diff --git a/src/features/Modals/Event/TeamDetailsModal/style/TeamDetailsModal.module.scss b/src/features/Modals/Event/TeamDetailsModal/style/TeamDetailsModal.module.scss index e82c50f0..b16e9bce 100644 --- a/src/features/Modals/Event/TeamDetailsModal/style/TeamDetailsModal.module.scss +++ b/src/features/Modals/Event/TeamDetailsModal/style/TeamDetailsModal.module.scss @@ -29,6 +29,7 @@ opacity: 0; transform: translateY(-20px) scale(0.95); } + to { opacity: 1; transform: translateY(0) scale(1); @@ -57,7 +58,7 @@ border: none; color: rgb(0, 0, 0); cursor: pointer; - padding: 8px ; + padding: 8px; border-radius: 50%; transition: background-color 0.2s; display: flex; @@ -97,12 +98,10 @@ h3 { margin: 0; - background: linear-gradient( - rgba(244, 43, 3, 0.84) 0%, - rgba(255, 190, 11, 0.84) 100% - ); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; + background: linear-gradient(rgba(244, 43, 3, 0.84) 0%, + rgba(255, 190, 11, 0.84) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; font-size: 1.25rem; font-weight: 600; } @@ -227,12 +226,45 @@ border-radius: 8px; border: 1px solid #e27100; transition: box-shadow 0.2s; + position: relative; &:hover { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } } +.removeMemberBtn { + position: absolute; + top: 12px; + right: 12px; + background: #dc2626; + color: white; + border: none; + padding: 8px; + border-radius: 6px; + cursor: pointer; + transition: all 0.2s; + display: flex; + align-items: center; + justify-content: center; + width: 36px; + height: 36px; + + &:hover:not(:disabled) { + background: #b91c1c; + transform: scale(1.05); + } + + &:active:not(:disabled) { + transform: scale(0.95); + } + + &:disabled { + opacity: 0.6; + cursor: not-allowed; + } +} + .memberAvatar { flex-shrink: 0; width: 60px;