diff --git a/client/src/pages/Home.js b/client/src/pages/Home.js
index c8ed3df5..331a14cb 100644
--- a/client/src/pages/Home.js
+++ b/client/src/pages/Home.js
@@ -34,10 +34,10 @@ function Home() {
const handleSubmit = async (e) => {
e.preventDefault();
- console.log(`${formData.role} sign in attempted`, formData);
const { email: ouEmail, password, role } = formData;
+
if (!ouEmail || !password || !role) {
return Swal.fire({
icon: "warning",
@@ -61,20 +61,24 @@ function Home() {
const data = await response.json();
if (response.ok) {
- Swal.fire({
- icon: "success",
- title: "Login Successful 🌟",
- text: `Welcome back, ${role}!`,
- });
-
- // Redirect user based on role
- if (role === "coordinator") {
- navigate("/coordinator-dashboard");
- } else if (role === "student") {
- navigate("/student-dashboard");
- } else if (role === "supervisor") {
- navigate("/supervisor-dashboard");
- }
+ const user = data.user;
+
+ // Store only required fields
+ const limitedUserInfo = {
+ fullName: user.fullName,
+ id: user._id,
+ email:user.ouEmail
+ };
+
+ localStorage.setItem("ipmsUser", JSON.stringify(limitedUserInfo));
+
+ // Swal.fire({
+ // icon: "success",
+ // title: "Login Successful",
+ // text: `Welcome back, `,
+ // });
+
+ navigate("/student-dashboard");
} else {
Swal.fire({
icon: "error",
@@ -126,6 +130,7 @@ function Home() {
role: r,
})
}
+
>
diff --git a/client/src/pages/ProtectedRouteStudent.jsx b/client/src/pages/ProtectedRouteStudent.jsx
new file mode 100644
index 00000000..02a0396e
--- /dev/null
+++ b/client/src/pages/ProtectedRouteStudent.jsx
@@ -0,0 +1,16 @@
+// src/components/ProtectedRouteStudent.js
+import React from "react";
+import { Navigate } from "react-router-dom";
+
+const ProtectedRouteStudent = ({ children }) => {
+ const user = JSON.parse(localStorage.getItem("ipmsUser"));
+
+ // Check if user info is missing
+ if (!user || !user.id || !user.fullName) {
+ return ;
+ }
+
+ return children;
+ };
+
+export default ProtectedRouteStudent;
diff --git a/client/src/pages/StudentDashboard.jsx b/client/src/pages/StudentDashboard.jsx
new file mode 100644
index 00000000..af9f4614
--- /dev/null
+++ b/client/src/pages/StudentDashboard.jsx
@@ -0,0 +1,96 @@
+import React, { useEffect, useState } from "react";
+import { useNavigate } from "react-router-dom";
+import "../styles/StudentDashboard.css"; // Make sure you create this CSS
+
+const StudentDashboard = () => {
+ const navigate = useNavigate();
+
+ const user = JSON.parse(localStorage.getItem("ipmsUser"));
+ const backendUrl = process.env.REACT_APP_API_URL;
+ const ouEmail = user?.email;
+ const [approvalStatus, setApprovalStatus] = useState(false)
+
+
+ useEffect(() => {
+ const fetchData = async () => {
+ try {
+ const res = await fetch(`${backendUrl}/api/student`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify({ ouEmail }),
+ });
+
+ const data = await res.json();
+ setApprovalStatus(data.approvalStatus);
+
+ } catch (err) {
+ console.error("Error fetching internship data", err);
+ }
+ };
+
+ if (ouEmail) {
+ fetchData();
+ }
+ }, [ouEmail]);
+
+
+
+
+
+ return (
+
+
+
Welcome, {user.fullName}
+
+
+
+
+
+
Request Internship (FORM A1)
+
Track your internship journey
+
+
+
+
+
+
+
Weekly Report (Form A2)
+ {!approvalStatus && (
+
+ Finish your Form A1 first
+
+ )}
+
+
+
+
+
+
+ );
+};
+
+export default StudentDashboard;
diff --git a/client/src/router.js b/client/src/router.js
index db8aaf77..8fac8de1 100644
--- a/client/src/router.js
+++ b/client/src/router.js
@@ -18,9 +18,11 @@ import SupervisorDashboard from "./pages/SupervisorDashboard";
import CoordinatorDashboard from "./pages/CoordinatorDashboard";
import CoordinatorRequestDetailView from "./pages/CoordinatorRequestDetailView";
import TokenRenewal from "./pages/TokenRenewal";
+import StudentDashboard from "./pages/StudentDashboard";
+import ProtectedRouteStudent from "./pages/ProtectedRouteStudent";
// Create and export the router configuration
-const router = createBrowserRouter([
+const router = createBrowserRouter([
{
path: "/",
element: ,
@@ -33,11 +35,20 @@ const router = createBrowserRouter([
{
path: "signup",
element: ,
- },
+ },
{
path: "weekly-report",
element: ,
},
+ {
+ path: "/student-dashboard",
+ element: (
+
+
+
+ )
+ },
+
{
path: "a1-form",
element: ,
diff --git a/client/src/styles/StudentDashboard.css b/client/src/styles/StudentDashboard.css
new file mode 100644
index 00000000..71975b3e
--- /dev/null
+++ b/client/src/styles/StudentDashboard.css
@@ -0,0 +1,71 @@
+.student-dashboard {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 2rem 1rem;
+ background-color: #f7f7f7;
+ min-height: 90vh;
+ }
+
+ .dashboard-header {
+ width: 100%;
+ max-width: 900px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 2rem;
+ }
+
+ .user-role {
+ font-weight: bold;
+ font-size: 1rem;
+ color: #5c0a0a;
+ }
+
+ .dashboard-card {
+ background-color: white;
+ border-radius: 10px;
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
+ padding: 2rem;
+ width: 100%;
+ max-width: 900px;
+ }
+
+ .card-section {
+ background-color: #842020;
+ border-radius: 10px;
+ padding: 1.5rem;
+ margin-bottom: 1.5rem;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ color: white;
+ box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1);
+ }
+
+ .card-content h3 {
+ margin: 0;
+ font-size: 1.2rem;
+ font-weight: 600;
+ }
+
+ .card-content p {
+ margin: 5px 0 0;
+ font-size: 0.9rem;
+ }
+
+ .card-button {
+ background-color: white;
+ color: #842020;
+ border: none;
+ padding: 8px 16px;
+ border-radius: 6px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: 0.3s ease-in-out;
+ }
+
+ .card-button:hover {
+ background-color: #e6e6e6;
+ }
+
\ No newline at end of file
diff --git a/server/index.js b/server/index.js
index 45104393..c64c5d22 100644
--- a/server/index.js
+++ b/server/index.js
@@ -10,6 +10,7 @@ const formRoutes = require("./routes/formRoutes");
const emailRoutes = require("./routes/emailRoutes");
const tokenRoutes = require("./routes/token");
const approvalRoutes = require("./routes/approvalRoutes");
+const studentRoutes = require("./routes/studentRoutes")
const outcomeRoutes = require("./routes/outcomeRoutes");
@@ -78,6 +79,7 @@ app.use("/api/token", tokenRoutes);
app.use("/api", approvalRoutes);
app.use("/api/reports", weeklyReportRoutes);
+app.use("/api/student",studentRoutes)
app.post("/api/createUser", async (req, res) => {
try {
const { userName, email, password, role } = req.body;
diff --git a/server/routes/studentRoutes.js b/server/routes/studentRoutes.js
new file mode 100644
index 00000000..55714ef8
--- /dev/null
+++ b/server/routes/studentRoutes.js
@@ -0,0 +1,30 @@
+const express = require("express");
+const router = express.Router();
+const InternshipRequest = require("../models/InternshipRequest");
+const User = require("../models/User");
+
+// GET internship request by student's ouEmail
+router.post("/", async (req, res) => {
+ const { ouEmail } = req.body;
+ console.log(ouEmail)
+ try {
+ const studentUser = await User.findOne({ email: ouEmail });
+ if (!studentUser) {
+ return res.status(404).json({ message: "Student not found" });
+ }
+
+ const internshipData = await InternshipRequest.findOne({ student: studentUser._id });
+
+ if (!internshipData) {
+ return res.status(404).json({ message: "No internship request found for this student" });
+ }
+ const approvalStatus = internshipData.status == "approved" ? true : false
+ return res.status(200).json({ message: "Success" , approvalStatus });
+ } catch (error) {
+ console.error("Error fetching internship request:", error);
+ return res.status(500).json({ message: "Server error" });
+ }
+ });
+
+
+module.exports = router;
\ No newline at end of file
diff --git a/server/routes/token.js b/server/routes/token.js
index 4d82d42d..f83355ed 100644
--- a/server/routes/token.js
+++ b/server/routes/token.js
@@ -5,6 +5,7 @@ const crypto = require("crypto");
const bcrypt = require("bcrypt");
const TokenRequest = require("../models/TokenRequest");
const emailService = require("../services/emailService");
+const User = require("../models/User")
const JWT_SECRET = process.env.JWT_SECRET;
const FRONTEND_URL = process.env.FRONTEND_URL;
@@ -51,7 +52,10 @@ router.post("/request", async (req, res) => {
activationLinkSentAt: new Date(),
});
+
+
await request.save();
+
const activationLink = `${FRONTEND_URL}/activate/${plainToken}`;
const emailBody = `