diff --git a/server/src/components/AddNewStudentPopup.tsx b/server/src/components/AddNewStudentPopup.tsx new file mode 100644 index 0000000..48520f8 --- /dev/null +++ b/server/src/components/AddNewStudentPopup.tsx @@ -0,0 +1,98 @@ +"use client"; + +import React, { useState } from "react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; + +interface AddNewStudentPopupProps { + isOpen: boolean; + onClose: () => void; +} + +const AddNewStudentPopup: React.FC = ({ isOpen, onClose }) => { + const [newStudent, setNewStudent] = useState({ + name: "", + email: "", + projects: "", + }); + + const handleInputChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + setNewStudent((prevState) => ({ + ...prevState, + [name]: value, + })); + }; + + const handleSelectChange = (e: React.ChangeEvent) => { + setNewStudent((prevState) => ({ + ...prevState, + projects: e.target.value, + })); + }; + + const handleAddStudent = () => { + // Logic to add the student to the list + console.log("New student added:", newStudent); + onClose(); + }; + + return ( + + + + 👤 Add New Student + + +
+
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ +
+
+
+ ); +}; + +export default AddNewStudentPopup; diff --git a/server/src/components/NewProjectPopup.tsx b/server/src/components/NewProjectPopup.tsx new file mode 100644 index 0000000..f347852 --- /dev/null +++ b/server/src/components/NewProjectPopup.tsx @@ -0,0 +1,134 @@ +import React, { useState } from 'react'; + +interface Student { + id: number; + name: string; + role: string; +} + +interface NewProjectPopupProps { + closePopup: () => void; +} + +const NewProjectPopup: React.FC = ({ closePopup }) => { + const [projectName, setProjectName] = useState(''); + const [teamId, setTeamId] = useState(''); + const [startDate, setStartDate] = useState(''); + const [endDate, setEndDate] = useState(''); + const [selectedStudent, setSelectedStudent] = useState(''); + const [selectedRole, setSelectedRole] = useState(''); + const [students, setStudents] = useState([]); + + const sampleStudents = [ + { id: 1, name: 'Nimal Perera' }, + { id: 2, name: 'Piyal Alwis' }, + { id: 3, name: 'Suneera Gamage' }, + { id: 4, name: 'Ryan Perera' }, + ]; + + const handleAddStudent = () => { + if (selectedStudent && selectedRole) { + const studentExists = students.some(student => student.name === selectedStudent); + if (!studentExists) { + setStudents([...students, { id: students.length + 1, name: selectedStudent, role: selectedRole }]); + setSelectedStudent(''); + setSelectedRole(''); + } + } + }; + + const handleRemoveStudent = (id: number) => { + setStudents(students.filter(student => student.id !== id)); + }; + + const handleCreate = () => { + console.log('New project created:', { projectName, teamId, startDate, endDate, students }); + closePopup(); + }; + + return ( +
+
+

📋 Create New Project

+ + {/* Project Name */} +
+ + setProjectName(e.target.value)} /> +
+ + {/* Team ID */} +
+ + setTeamId(e.target.value)} /> +
+ + {/* Start Date and End Date */} +
+
+ + setStartDate(e.target.value)} /> +
+
+ + setEndDate(e.target.value)} /> +
+
+ + {/* Add Student */} + +
+ + + +
+ + {/* Students Table */} +
+ + + + + + + + +
NameRoleAction
+
+ + + {students.map((student) => ( + + + + + + ))} + +
{student.name}{student.role} + +
+
+
+ + + {/* Buttons */} +
+ + +
+
+
+ ); +}; + +export default NewProjectPopup; diff --git a/server/src/components/StudentDetailsPopup.tsx b/server/src/components/StudentDetailsPopup.tsx new file mode 100644 index 0000000..e11ad21 --- /dev/null +++ b/server/src/components/StudentDetailsPopup.tsx @@ -0,0 +1,213 @@ +"use client"; + +import React, { useState, useMemo } from "react"; +import { + AlertDialog, + AlertDialogContent, + AlertDialogHeader, + AlertDialogTitle, +} from "@/components/ui/alert-dialog"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { Filter } from "lucide-react"; +import StudentPersonalDetails from "./StudentPersonalDetails"; // Importing the StudentPersonalDetails component +import AddNewStudentPopup from "./AddNewStudentPopup"; // Import AddNewStudentPopup + +interface Student { + id: number; + name: string; + projects: string; + approved: number; + rejected: number; + avatar: string; + location: string; + dob: string; + university: string; + academicYear: string; + linkedin: string; + github: string; + status: string; + enrolledDate: string; + endDate: string; +} + +interface StudentDetailsPopupProps { + isOpen: boolean; + onClose: () => void; +} + +const StudentDetailsPopup: React.FC = ({ isOpen, onClose }) => { + const [searchQuery, setSearchQuery] = useState(""); + const [projectQuery, setProjectQuery] = useState(""); // New search query for projects + const [selectedFilter, setSelectedFilter] = useState<"All" | "Active" | "Deactive">("All"); + const [selectedStudent, setSelectedStudent] = useState(null); + const [isStudentDetailOpen, setIsStudentDetailOpen] = useState(false); + const [isAddNewStudentOpen, setIsAddNewStudentOpen] = useState(false); // State for AddNewStudentPopup + + const students: Student[] = [ + { id: 1, name: "Chamoth Anuruddha", projects: "T2T Digital Diary", approved: 20, rejected: 10, avatar: "/avatar1.png", location: "Colombo", dob: "01/22/2003", university: "Colombo University", academicYear: "2nd Year", linkedin: "https://linkedin.com", github: "https://github.com", status: "Active", enrolledDate: "01/10/2024", endDate: "04/04/2025" }, + { id: 2, name: "John Doe", projects: "Task Management System", approved: 15, rejected: 5, avatar: "/avatar2.png", location: "Colombo", dob: "05/14/2000", university: "Colombo University", academicYear: "3rd Year", linkedin: "https://linkedin.com", github: "https://github.com", status: "Deactivate", enrolledDate: "02/01/2024", endDate: "05/01/2025" }, + { id: 3, name: "Yasindu Edirisnha", projects: "T2T Digital Diary", approved: 20, rejected: 10, avatar: "/avatar3.png", location: "Colombo", dob: "01/22/2003", university: "Colombo University", academicYear: "2nd Year", linkedin: "https://linkedin.com", github: "https://github.com", status: "Active", enrolledDate: "01/10/2024", endDate: "04/04/2025" }, + { id: 4, name: "Lakshitha Sadaruwan", projects: "T2T Digital Diary", approved: 20, rejected: 10, avatar: "/avatar3.png", location: "Colombo", dob: "01/22/2003", university: "Colombo University", academicYear: "2nd Year", linkedin: "https://linkedin.com", github: "https://github.com", status: "Active", enrolledDate: "01/10/2024", endDate: "04/04/2025" }, + { id: 5, name: "Saros", projects: "T2T Digital Diary", approved: 20, rejected: 10, avatar: "/avatar3.png", location: "Colombo", dob: "01/22/2003", university: "Colombo University", academicYear: "2nd Year", linkedin: "https://linkedin.com", github: "https://github.com", status: "Active", enrolledDate: "01/10/2024", endDate: "04/04/2025" }, + { id: 6, name: "Saiaf", projects: "T2T Digital Diary", approved: 20, rejected: 10, avatar: "/avatar3.png", location: "Colombo", dob: "01/22/2003", university: "Colombo University", academicYear: "2nd Year", linkedin: "https://linkedin.com", github: "https://github.com", status: "Active", enrolledDate: "01/10/2024", endDate: "04/04/2025" }, + ]; + + const filteredStudents = useMemo(() => { + return students.filter((student) => + student.name.toLowerCase().includes(searchQuery.toLowerCase()) && + student.projects.toLowerCase().includes(projectQuery.toLowerCase()) && // Added project search condition + (selectedFilter === "All" || selectedFilter === "Active" || selectedFilter === "Deactive") + ); + }, [students, searchQuery, projectQuery, selectedFilter]); + + const handleViewMore = (student: Student) => { + setSelectedStudent(student); + setIsStudentDetailOpen(true); + }; + + return ( + <> + + + {/* Header Section */} + +
+ 👨 Student Overview + + + +
+
+ + {/* Search and Filter Section */} +
+ {/* Search Bar for Students */} +
+ setSearchQuery(e.target.value)} + /> +
+ + {/* Search Bar for Projects */} +
+ setProjectQuery(e.target.value)} + /> +
+ + {/* Filter Buttons */} +
+ {["All", "Active", "Deactive"].map((filter) => ( + + ))} + {/* Filter Icon */} + +
+
+ + {/* Student List Section */} +
+ + + + + + + + + + + + + {filteredStudents.length > 0 ? ( + filteredStudents.map((student) => ( + + + + + + + + + )) + ) : ( + + + + )} + +
NameProjectsApprovedRejectedStatusActions
+
+ + + {student.name.charAt(0)} + + {student.name} +
+
{student.projects}{student.approved}{student.rejected}{student.status} + +
+ No students found. +
+
+
+
+ + {/* Show StudentPersonalDetails if a student is selected */} + {selectedStudent && ( + setIsStudentDetailOpen(false)} + student={selectedStudent} + /> + )} + {isAddNewStudentOpen && ( + setIsAddNewStudentOpen(false)} /> + )} + + ); +}; + +export default StudentDetailsPopup; diff --git a/server/src/components/StudentPersonalDetails.tsx b/server/src/components/StudentPersonalDetails.tsx new file mode 100644 index 0000000..94998d6 --- /dev/null +++ b/server/src/components/StudentPersonalDetails.tsx @@ -0,0 +1,111 @@ +import React from "react"; +import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog"; +import { Button } from "@/components/ui/button"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; + +interface Student { + id: number; + name: string; + projects: string; + approved: number; + rejected: number; + avatar: string; + location: string; + dob: string; + university: string; + academicYear: string; + linkedin: string; + github: string; + status: string; + enrolledDate: string; + endDate: string; +} + +interface StudentPersonalDetailsProps { + isOpen: boolean; + onClose: () => void; + student: Student | null; // Allow student to be null +} + +const StudentPersonalDetails: React.FC = ({ isOpen, onClose, student }) => { + if (!student) return null; // Avoid rendering if student is null + + return ( + + + {/* Header */} + + 👤 Student Details + + + + {/* Main Content Grid */} +
+ {/* Left Column - Personal Details */} +
+

Personal Details

+
+ + + {student.name.charAt(0)} + +
+

{student.name}

+

Location: {student.location}

+

DOB: {student.dob}

+

University: {student.university}

+

Academic Year: {student.academicYear}

+
+
+
+

+ 🔗 Linkedin:{" "} + + {student.linkedin} + +

+

+ 🐙 Github:{" "} + + {student.github} + +

+
+
+ + {/* Right Column - Project Details */} +
+

Project Details

+

Projects: {student.projects}

+

+ Status:{" "} + + {student.status} + +

+

Approved: {student.approved}

+

Rejected: {student.rejected}

+

Enrolled Date: {student.enrolledDate}

+

End Date: {student.endDate}

+ + {/* Action Buttons */} +
+ + +
+
+
+
+
+ ); +}; + +export default StudentPersonalDetails; diff --git a/server/src/components/UpdateProjectPopup.tsx b/server/src/components/UpdateProjectPopup.tsx new file mode 100644 index 0000000..68d322d --- /dev/null +++ b/server/src/components/UpdateProjectPopup.tsx @@ -0,0 +1,190 @@ +import React, { useState } from 'react'; + +interface Student { + id: number; + name: string; + role: string; +} + +interface UpdateProjectPopupProps { + closePopup: () => void; + projectName: string; +} + +const UpdateProjectPopup: React.FC = ({ closePopup, projectName }) => { + const [teamId, setTeamId] = useState(''); + const [startDate, setStartDate] = useState(''); + const [endDate, setEndDate] = useState(''); + const [students, setStudents] = useState([ + { id: 1, name: 'Saiaf', role: 'Team Leader' }, + { id: 2, name: 'Chamoth', role: 'Member' }, + { id: 3, name: 'Lakshitha', role: 'Member' }, + { id: 4, name: 'Saros', role: 'Member' }, + ]); + const [availableStudents, setAvailableStudents] = useState([ + { id: 5, name: 'Nimal Perera', role: '' }, + { id: 6, name: 'Piyal Alwis', role: '' }, + { id: 7, name: 'Suneera Gamage', role: '' }, + { id: 8, name: 'Ryan Perera', role: '' }, + ]); + const [selectedStudent, setSelectedStudent] = useState(''); + const [selectedRole, setSelectedRole] = useState(''); + + const handleRoleChange = (id: number, newRole: string) => { + setStudents((prevStudents) => + prevStudents.map((student) => + student.id === id ? { ...student, role: newRole } : student + ) + ); + }; + + const handleAddStudent = () => { + const studentToAdd = availableStudents.find((s) => s.name === selectedStudent); + if (studentToAdd && selectedRole) { + setStudents([...students, { ...studentToAdd, role: selectedRole }]); + setAvailableStudents(availableStudents.filter((s) => s.id !== studentToAdd.id)); + setSelectedStudent(''); + setSelectedRole(''); + } + }; + + const handleRemoveStudent = (id: number) => { + const studentToRemove = students.find((s) => s.id === id); + if (studentToRemove) { + setStudents(students.filter((s) => s.id !== id)); + setAvailableStudents([...availableStudents, { ...studentToRemove, role: '' }]); + } + }; + + return ( +
+
+

📊 Update {projectName}

+ + {/* Project Name */} +
+ + +
+ + {/* Team ID */} +
+ + setTeamId(e.target.value)} + /> +
+ + {/* Start Date and End Date */} +
+
+ + setStartDate(e.target.value)} + /> +
+
+ + setEndDate(e.target.value)} + /> +
+
+ + {/* Students List */} +
+ +
+ + + + + + + + +
NameRoleAction
+
{/* Added max height and scroll */} + + + {students.map((student) => ( + + + + + + ))} + +
{student.name}{student.role} + +
+
+
+
+ + + {/* Add Student Section */} +
+ + + + +
+ + {/* Buttons */} +
+ + + +
+
+
+ ); +}; + +export default UpdateProjectPopup; diff --git a/server/src/components/activeProjects.tsx b/server/src/components/activeProjects.tsx index 8318837..001fdce 100644 --- a/server/src/components/activeProjects.tsx +++ b/server/src/components/activeProjects.tsx @@ -1,8 +1,47 @@ -// components/ActiveProjects.tsx -import React from 'react'; +import React, { useState } from 'react'; import { Filter } from 'lucide-react'; +import UpdateProjectPopup from './UpdateProjectPopup'; +import NewProjectPopup from './NewProjectPopup'; +import ProjectDetailsPopUp from './projectDetailsPopUp'; // Import the ProjectDetailsPopUp component + +const ActiveProjects: React.FC = () => { + const [isPopupVisible, setIsPopupVisible] = useState(false); + const [isNewProjectPopupVisible, setIsNewProjectPopupVisible] = useState(false); + const [isProjectDetailsVisible, setIsProjectDetailsVisible] = useState(false); // State for ProjectDetailsPopUp + const [currentProject, setCurrentProject] = useState(''); + + // Open Update Project Popup + const handleEditClick = (projectName: string) => { + setCurrentProject(projectName); + setIsPopupVisible(true); + }; + + // Open New Project Popup + const handleNewProjectClick = () => { + setIsNewProjectPopupVisible(true); + }; + + // Open Project Details Popup + const handleViewDetailClick = (projectName: string) => { + setCurrentProject(projectName); + setIsProjectDetailsVisible(true); + }; + + // Close Popups + const closePopup = () => { + setIsPopupVisible(false); + setCurrentProject(''); + }; + + const closeNewProjectPopup = () => { + setIsNewProjectPopupVisible(false); + }; + + const closeProjectDetailsPopup = () => { + setIsProjectDetailsVisible(false); + setCurrentProject(''); + }; -const ActiveProjects = () => { return (
@@ -12,53 +51,78 @@ const ActiveProjects = () => { Filter - +
-
- {["Mobile Application Development", "Digital Diary", "Forms Management", "T2T Platform"].map((project, index) => { - const projectData = [ - { total: 18, pending: 4, approved: 12, rejected: 2 }, - { total: 22, pending: 3, approved: 16, rejected: 3 }, - { total: 15, pending: 5, approved: 8, rejected: 2 }, - { total: 20, pending: 2, approved: 15, rejected: 3 }, - ]; - const { total, pending, approved, rejected } = projectData[index]; +
+ {["Mobile App", "Digital Diary", "Forms Management", "T2T Platform"].map( + (project, index) => { + const projectData = [ + { total: 18, pending: 4, approved: 12, rejected: 2 }, + { total: 22, pending: 3, approved: 16, rejected: 3 }, + { total: 15, pending: 5, approved: 8, rejected: 2 }, + { total: 20, pending: 2, approved: 15, rejected: 3 }, + ]; - return ( -
+ const { total, pending, approved, rejected } = projectData[index]; - -

{project}

-

Team {String.fromCharCode(65 + index)}

-
-
-

{total}

-

Total

-
-
-

{pending}

-

Pending

-
-
-

{approved}

-

Approved

-
-
-

{rejected}

-

Rejected

+ return ( +
+ + +

{project}

+

Team {String.fromCharCode(65 + index)}

+
+
+

{total}

+

Total

+
+
+

{pending}

+

Pending

+
+
+

{approved}

+

Approved

+
+
+

{rejected}

+

Rejected

+
+
- -
- ); - })} + ); + } + )}
+ + {/* Conditionally render the update project popup */} + {isPopupVisible && } + + {/* Conditionally render the new project popup */} + {isNewProjectPopupVisible && } + + {/* Conditionally render the project details popup */} + {isProjectDetailsVisible && }
); }; diff --git a/server/src/components/mentorDashboard.tsx b/server/src/components/mentorDashboard.tsx index 9e74fdf..3b667a3 100644 --- a/server/src/components/mentorDashboard.tsx +++ b/server/src/components/mentorDashboard.tsx @@ -8,20 +8,20 @@ import Footer from '@/components/footer'; const MentorDashboard = () => { return ( -
+
{/* Navbar */} - + {/* Main Content */} -
+
{/* Left Panel - Dashboard Overview & Active Projects */} -
+
-
+
{/* Right Panel - Calendar & Journal */} -
+
diff --git a/server/src/components/navBar.tsx b/server/src/components/navBar.tsx index 3937d99..5155bbf 100644 --- a/server/src/components/navBar.tsx +++ b/server/src/components/navBar.tsx @@ -1,51 +1,126 @@ // components/Navbar.tsx -import React from 'react'; -import Image from 'next/image'; -import { Bell } from 'lucide-react'; +import React, { useState, useEffect, useRef } from "react"; +import Image from "next/image"; +import { Bell } from "lucide-react"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import StudentDetailsPopup from "./StudentDetailsPopup"; -const Navbar = () => { - return ( -
- {/* Logo & Navigation */} -
- Logo - - -
- - {/* User Profile & Notifications */} -
- -
-
- Jhon -

Senior Mentor

-
- - - JH - +interface NavbarProps { + userType: "mentor" | "student"; // Determines dashboard type + userName: string; // User's name +} + +const Navbar: React.FC = ({ userType, userName }) => { + const [isStudentPopupOpen, setIsStudentPopupOpen] = useState(false); + const [isLogoutPopupOpen, setIsLogoutPopupOpen] = useState(false); + const logoutPopupRef = useRef(null); + + const openStudentPopup = () => setIsStudentPopupOpen(true); + const closeStudentPopup = () => setIsStudentPopupOpen(false); + const toggleLogoutPopup = () => setIsLogoutPopupOpen((prev) => !prev); + + const handleLogout = () => { + // Clear authentication data + localStorage.removeItem("authToken"); + sessionStorage.removeItem("authToken"); + document.cookie = "authToken=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;"; + + // Redirect to login page + window.location.href = "/login"; + }; + + // Close logout popup when clicking outside + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if ( + logoutPopupRef.current && + event.target instanceof Node && + !logoutPopupRef.current.contains(event.target) + ) { + setIsLogoutPopupOpen(false); + } + }; + + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, []); + + return ( +
+ {/* Logo & Navigation */} +
+ Logo + {/* Show navigation only for mentors */} + {userType === "mentor" && ( + + )} +
+ + {/* User Profile & Notifications */} +
+ +
+
+ {userName} +

+ {userType === "mentor" ? "Senior Mentor" : "Student"} +

+
+ + + {userName.charAt(0)} + + {/* Logout Popup */} + {isLogoutPopupOpen && ( +
+ +
+ + + +
+

Are you sure you want to logout?

+ +
+ + + + )} +
+
+ {/* Conditionally render the StudentDetailsPopup */} + {isStudentPopupOpen && }
-
-
- ); + ); }; export default Navbar; diff --git a/server/src/components/personalJournal.tsx b/server/src/components/personalJournal.tsx index 2477c94..cea5ae7 100644 --- a/server/src/components/personalJournal.tsx +++ b/server/src/components/personalJournal.tsx @@ -7,21 +7,32 @@ const PersonalJournal = () => { { color: "blue", text: "Had a productive meeting with the team." }, { color: "green", text: "Completed the UI design for the dashboard." }, { color: "yellow", text: "Reviewed code changes from the team." }, - { color: "pink", text: "Tested new API integration successfully." } - + { color: "red", text: "Started working on a new project." }, + { color: "blue", text: "Had a productive meeting with the team." }, + { color: "pink", text: "Tested new API integration successfully." }, + { color: "red", text: "Refactored authentication logic." }, + { color: "blue", text: "Fixed a bug in the payment gateway." }, + { color: "red", text: "Updated documentation for the API." }, + { color: "green", text: "Started working on a new project." }, + { color: "pink", text: "Implemented a new caching strategy." } ]; return (
+ {/* Header Section */}

📁 Personal Journal

- +
-
    - {journalEntries.map((entry, index) => ( -
  • - -

    {entry.text}

    + + {/* Journal List - Most Recent 10 Entries Always Visible */} +
      + {journalEntries.slice(-10).map((entry, index) => ( // Shows only last 7 entries +
    • + +

      {entry.text}

    • ))}
    diff --git a/server/src/components/projectDetailsPopUp.tsx b/server/src/components/projectDetailsPopUp.tsx index 09d9dca..4b35d47 100644 --- a/server/src/components/projectDetailsPopUp.tsx +++ b/server/src/components/projectDetailsPopUp.tsx @@ -1,6 +1,6 @@ "use client"; -import React, { useState } from "react"; +import React, { useState, useMemo } from "react"; import { AlertDialog, AlertDialogTrigger, @@ -11,6 +11,7 @@ import { import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; +import Popup from "./viewSubmition"; // Import the Popup component interface ProjectDetailsPopUpProps { isOpen: boolean; @@ -20,6 +21,7 @@ interface ProjectDetailsPopUpProps { const ProjectDetailsPopUp: React.FC = ({ isOpen, onClose }) => { const [selectedStatus, setSelectedStatus] = useState("All"); const [searchQuery, setSearchQuery] = useState(""); + const [isSubmissionOpen, setIsSubmissionOpen] = useState(false); // State for View Submission Popup const submissions = [ { id: 1, name: "Sarose", title: "Implemented real-time password validation", date: "Jan 11, 2025", status: "Pending" }, @@ -28,37 +30,47 @@ const ProjectDetailsPopUp: React.FC = ({ isOpen, onClo { id: 4, name: "Chamoth", title: "Improved UI/UX", date: "Jan 13, 2025", status: "Approved" }, ]; - const filteredSubmissions = submissions.filter( - (sub) => - (selectedStatus === "All" || sub.status === selectedStatus) && - sub.name.toLowerCase().includes(searchQuery.toLowerCase()) + // Memoize filtered submissions to prevent re-renders + const filteredSubmissions = useMemo( + () => + submissions.filter( + (sub) => + (selectedStatus === "All" || sub.status === selectedStatus) && + sub.name.toLowerCase().includes(searchQuery.toLowerCase()) + ), + [selectedStatus, searchQuery] ); + const handleViewSubmission = () => { + setIsSubmissionOpen(true); // Open the View Submission Popup + }; + + const handleCloseSubmission = () => { + setIsSubmissionOpen(false); // Close the View Submission Popup + }; + return ( - {/* Header Section - Project Title and Mentor Info */} + {/* Header Section */}
    - {/* Left side: Project Title, Mentor Info, Team Info */} + {/* Left Side: Project Title & Mentor Info */}
    Project Digital Diary
    - {/* Mentor Avatar and Name */} M
    - {/* Mentor's Name */}

    Mentor: Jhon

    - {/* Team Name */}

    Team: Web Development Rangers 2025

    - {/* Right side: Close button */} + {/* Right Side: Close Button */}
    + {/* Search & Filter Section */}
    - {/* Search Bar - Search for Student Name */} + {/* Search Input */}
    = ({ isOpen, onClo />
    - {/* Filter Buttons - Filter by Submission Status */} + {/* Filter Buttons */}
    {["All", "Pending", "Approved", "Rejected"].map((status) => (
    - {/* Submissions List - List of Student Submissions */} + {/* Submissions List */}
    {filteredSubmissions.length > 0 ? ( filteredSubmissions.map((sub) => (
    - {/* Student Avatar */} {sub.name.charAt(0)}
    - {/* Student Name */}

    {sub.name}

    - {/* Activity Title (Project Title) */}

    {sub.title}

    - {/* Submission Date */}

    Submitted on {sub.date}

    - {/* Status Indicator */} {sub.status} {/* View Submission Button */} - - - - - +
    )) @@ -139,8 +152,9 @@ const ProjectDetailsPopUp: React.FC = ({ isOpen, onClo
    )}
- + {/* View Submission Popup */} + {}} /> ); }; diff --git a/server/src/components/viewSubmition.tsx b/server/src/components/viewSubmition.tsx index cb0df81..3b28515 100644 --- a/server/src/components/viewSubmition.tsx +++ b/server/src/components/viewSubmition.tsx @@ -100,4 +100,4 @@ const Popup: React.FC = ({ isOpen, onClose, handleSubmit }) => { ); }; -export default Popup; +export default Popup; \ No newline at end of file