@@ -392,7 +395,7 @@ function SignUp() {
>
setAgreed(e.target.checked)}
required
diff --git a/client/src/pages/SubmittedReports.js b/client/src/pages/SubmittedReports.js
new file mode 100644
index 000000000..fb69be6e7
--- /dev/null
+++ b/client/src/pages/SubmittedReports.js
@@ -0,0 +1,70 @@
+import React, { useEffect, useState } from "react";
+import axios from "axios";
+import { useNavigate } from "react-router-dom";
+import "../styles/SubmittedReports.css";
+
+const SubmittedReports = () => {
+ const [reports, setReports] = useState([]);
+ const [loading, setLoading] = useState(true);
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ const fetchReports = async () => {
+ try {
+ const res = await axios.get(`${process.env.REACT_APP_API_URL}/api/reports/mine`);
+ if (res.data.success) {
+ setReports(res.data.reports);
+ }
+ } catch (err) {
+ console.error("Error fetching reports", err);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ fetchReports();
+ }, []);
+
+ return (
+
+
Previous Weekly Reports
+
+ {loading ? (
+
Loading...
+ ) : reports.length === 0 ? (
+
No reports found.
+ ) : (
+
+
+
+ | Week |
+ Hours |
+ Tasks |
+ Lessons |
+ Supervisor Comments |
+
+
+
+ {reports.map((report) => (
+ navigate(`/submitted-reports/view/${report._id}`)}
+ >
+ | {report.week} |
+ {report.hours} |
+ {report.tasks} |
+ {report.lessons} |
+
+ {report.supervisorComments || "—"}
+ |
+
+ ))}
+
+
+ )}
+
+ );
+};
+
+export default SubmittedReports;
diff --git a/client/src/pages/SupervisorDashboard.js b/client/src/pages/SupervisorDashboard.js
index 1f3ba4b9c..74198b254 100644
--- a/client/src/pages/SupervisorDashboard.js
+++ b/client/src/pages/SupervisorDashboard.js
@@ -6,6 +6,7 @@ import ViewFormModal from "./ViewFormModal";
const SupervisorDashboard = () => {
const [requests, setRequests] = useState([]);
+ // const [cumulativeReports, setCumulativeReports] = useState([]);
const [selectedForm, setSelectedForm] = useState(null);
const [loading, setLoading] = useState(true);
const [message, setMessage] = useState("");
@@ -19,7 +20,8 @@ const SupervisorDashboard = () => {
const fetchRequests = async () => {
try {
- const res = await axios.get(`${process.env.REACT_APP_API_URL}/api/supervisor/forms`,
+ const res = await axios.get(
+ `${process.env.REACT_APP_API_URL}/api/supervisor/forms`,
{
headers: {
Authorization: `Bearer ${token}`,
@@ -28,8 +30,8 @@ const SupervisorDashboard = () => {
const formatted = res.data.map(item => ({
_id: item._id,
- name: item.student_id?.userName || item.student_id?.name || "N/A",
- student_id: item.student?._id || item._id,
+ interneeName: item.interneeName || item.student_id?.userName || "N/A",
+ interneeEmail: item.interneeEmail || item.student_id?.email || "N/A",
form_type: item.form_type,
createdAt: item.createdAt || item.submittedAt,
supervisor_status: item.supervisor_status || "pending",
@@ -51,10 +53,8 @@ const SupervisorDashboard = () => {
status: item.status || "pending",
supervisor_comment: item.supervisor_comment || "N/A"
}));
-
setRequests(formatted);
- setLoading(false);
} catch (err) {
console.error("Error fetching A1 Internship forms:", err);
setMessage("Error fetching A1 Internship forms.", err);
@@ -63,7 +63,6 @@ const SupervisorDashboard = () => {
};
fetchRequests();
}, [token]);
-
// const handleFormActionComplete = () => {
// fetchRequests(); // Refresh table after Approve/Reject
// setSelectedForm(null);
@@ -85,15 +84,14 @@ const SupervisorDashboard = () => {
);
setMessage(res.data.message || `${action} successful`);
- setRequests(prev => prev.filter(req => req._id !== id)); // remove from table
+ setRequests((prev) => prev.filter((req) => req._id !== id));
return true;
} catch (err) {
- console.error(`Failed to ${action} request:`, err);
+ console.error(err);
setMessage(`Failed to ${action} request.`);
return false;
}
};
-
const openFormView = (form) => setSelectedForm(form);
const closeFormView = () => setSelectedForm(null);
@@ -172,4 +170,4 @@ const SupervisorDashboard = () => {
);
};
-export default SupervisorDashboard;
\ No newline at end of file
+export default SupervisorDashboard;
diff --git a/client/src/pages/WeeklyFourWeekReportForm.js b/client/src/pages/WeeklyFourWeekReportForm.js
new file mode 100644
index 000000000..440cfbab5
--- /dev/null
+++ b/client/src/pages/WeeklyFourWeekReportForm.js
@@ -0,0 +1,151 @@
+
+import React, { useState } from "react";
+import axios from "axios";
+import "../styles/WeeklyFourWeekReportForm.css";
+
+const WeeklyFourWeekReportForm = () => {
+ const userRole = localStorage.getItem("role") || "student"; // Default role is student
+
+ const isStudent = userRole === "student";
+ const isSupervisor = userRole === "supervisor";
+ const isCoordinator = userRole === "coordinator";
+
+ const [formData, setFormData] = useState({
+ week: "Week 1",
+ tasks: "",
+ lessons: "",
+ challenges: "",
+ supervisorComments: "",
+ coordinatorComments: "",
+ });
+
+ const [message, setMessage] = useState("");
+
+ const handleChange = (e) => {
+ const { name, value } = e.target;
+ setFormData((prev) => ({ ...prev, [name]: value }));
+ };
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+
+ const payload = {
+ studentId: "123456",
+ ...formData,
+ };
+
+ console.log("Payload Sending:", payload);
+
+ try {
+ await axios.post(`${process.env.REACT_APP_API_URL}/api/fourWeekReports`, payload);
+ setMessage("✅ Report Submitted Successfully!");
+
+ setFormData({
+ week: "Week 1",
+ tasks: "",
+ lessons: "",
+ challenges: "",
+ supervisorComments: "",
+ coordinatorComments: "",
+ });
+ } catch (error) {
+ console.error(error);
+ setMessage("❌ Submission Failed! Please try again.");
+ }
+ };
+
+ return (
+
+
4-Week Progress Report
+
+
+
+ );
+};
+
+export default WeeklyFourWeekReportForm;
\ No newline at end of file
diff --git a/client/src/pages/WeeklyProgressReportForm.css b/client/src/pages/WeeklyProgressReportForm.css
deleted file mode 100644
index b8b8989fa..000000000
--- a/client/src/pages/WeeklyProgressReportForm.css
+++ /dev/null
@@ -1,45 +0,0 @@
-/* WeeklyProgressReportForm.css */
-
-.a2-form-container {
- max-width: 700px;
- margin: auto;
- padding: 2rem;
- border: 1px solid #ccc;
- background: #f9f9f9;
- border-radius: 8px;
- }
-
- .form-row {
- display: flex;
- gap: 1rem;
- margin-bottom: 1rem;
- justify-content: space-between;
- }
-
- .form-row label {
- flex: 1;
- }
-
- .form-group {
- margin-bottom: 1rem;
- }
-
- textarea {
- width: 100%;
- height: 100px;
- }
-
- .submit-button {
- background: maroon;
- color: white;
- padding: 0.7rem 1.5rem;
- border: none;
- border-radius: 6px;
- cursor: pointer;
- }
-
- .form-message {
- margin-top: 1rem;
- color: green;
- }
-
\ No newline at end of file
diff --git a/client/src/pages/WeeklyProgressReportForm.js b/client/src/pages/WeeklyProgressReportForm.js
index 2e9b8c54e..b2bee0d99 100644
--- a/client/src/pages/WeeklyProgressReportForm.js
+++ b/client/src/pages/WeeklyProgressReportForm.js
@@ -1,132 +1,272 @@
-
-
-import React, { useState } from "react";
+import React, { useEffect, useState } from "react";
import axios from "axios";
-import "./WeeklyProgressReportForm.css"; // optional: for clean styling
+import { useNavigate, useParams } from "react-router-dom";
+import "../styles/WeeklyProgressReportForm.css";
+
+const WeeklyProgressReportForm = ({ role = "student", readOnly = false }) => {
+ const navigate = useNavigate();
+ const { reportId } = useParams();
-const WeeklyProgressReportForm = () => {
const [formData, setFormData] = useState({
- week: "Week 1",
+ name: "",
+ email: "",
+ supervisorName: "",
+ supervisorEmail: "",
+ coordinatorName: "Naveena",
+ coordinatorEmail: "naveena.suddapalli-1@ou.edu",
+ creditHours: "",
+ completedHours: 0,
+ requiredHours: 0,
+ week: "",
hours: "",
tasks: "",
lessons: "",
supervisorComments: "",
+ coordinatorComments: "",
});
const [message, setMessage] = useState("");
+ // Load report data in read-only mode
+ useEffect(() => {
+ if (readOnly && reportId) {
+ axios
+ .get(`${process.env.REACT_APP_API_URL}/api/reports/${reportId}`)
+ .then((res) => {
+ if (res.data.success) {
+ setFormData((prev) => ({
+ ...prev,
+ ...res.data.report,
+ }));
+ }
+ })
+ .catch((err) => {
+ console.error("Failed to load report", err);
+ });
+ }
+ }, [readOnly, reportId]);
+
+ // Auto-fill A1 data
+ useEffect(() => {
+ const fetchA1Data = async () => {
+ try {
+ const email = "vikash@example.com"; // TODO: replace with real session email
+ const res = await axios.get(`${process.env.REACT_APP_API_URL}/api/reports/a1/${email}`);
+
+ if (res.data.success) {
+ const {
+ name,
+ email: userEmail,
+ supervisorName,
+ supervisorEmail,
+ creditHours,
+ completedHours,
+ requiredHours,
+ } = res.data.form;
+
+ setFormData((prev) => ({
+ ...prev,
+ name,
+ email: userEmail,
+ supervisorName,
+ supervisorEmail,
+ creditHours,
+ completedHours,
+ requiredHours: requiredHours || (creditHours ? creditHours * 60 : 0),
+ }));
+ }
+ } catch (err) {
+ console.error("A1 form not found or failed to fetch.");
+ setMessage("⚠️ You must submit the A1 form before submitting weekly reports.");
+ }
+ };
+
+ if (!readOnly) fetchA1Data();
+ }, [readOnly]);
+
const handleChange = (e) => {
const { name, value } = e.target;
+
+ if (readOnly && !(role === "coordinator" && name === "coordinatorComments")) return;
+
+ if (name === "hours") {
+ const num = parseInt(value);
+ if (num > 40) return setFormData((prev) => ({ ...prev, hours: 40 }));
+ if (num < 1 && value !== "") return setFormData((prev) => ({ ...prev, hours: 1 }));
+ }
+
setFormData((prev) => ({ ...prev, [name]: value }));
};
const handleSubmit = async (e) => {
e.preventDefault();
-
- // Get the user ID from localStorage (ensure it exists)
- // const user = JSON.parse(localStorage.getItem("user"));
- // const studentId = user?.user?._id;
-
- // // Check if studentId exists in localStorage
- // if (!studentId) {
- // setMessage("Student ID not found. Please log in again.");
- // return;
- // }
-
- // Check that all required fields are filled
- if (!formData.week || !formData.hours || !formData.tasks || !formData.lessons) {
- setMessage("Please fill in all the fields.");
- return;
+ const { week, hours, tasks, lessons, name, email, supervisorName, supervisorEmail } = formData;
+
+ if (!name || !email || !supervisorName || !supervisorEmail) {
+ return setMessage("Please complete the A1 form first.");
}
-
- //const payload = { studentId, ...formData };
- const payload = { ...formData };
-
+
+ if (!week || !hours || !tasks || !lessons) {
+ return setMessage("Please fill in all the required fields.");
+ }
+
try {
- // Sending the form data to the backend
- const res = await axios.post(`${process.env.REACT_APP_API_URL}/api/reports`, payload);
-
- // Display success message
- setMessage(res.data.message || "Report submitted!");
+ const res = await axios.post(`${process.env.REACT_APP_API_URL}/api/reports`, formData);
+ setMessage(res.data.message || "Report submitted successfully!");
setFormData({
- week: "Week 1",
+ name: "",
+ email: "",
+ supervisorName: "",
+ supervisorEmail: "",
+ coordinatorName: "Naveena",
+ coordinatorEmail: "naveena.suddapalli-1@ou.edu",
+ creditHours: "",
+ completedHours: 0,
+ requiredHours: 0,
+ week: "",
hours: "",
tasks: "",
lessons: "",
supervisorComments: "",
+ coordinatorComments: "",
});
} catch (err) {
console.error(err);
- setMessage("Submission failed. Try again.");
+ setMessage("Submission failed. Please try again.");
+ }
+ };
+
+ const handleCoordinatorSubmit = async () => {
+ try {
+ const res = await axios.put(
+ `${process.env.REACT_APP_API_URL}/api/reports/${reportId}/coordinator-comment`,
+ { coordinatorComments: formData.coordinatorComments }
+ );
+ setMessage(res.data.message || "Coordinator comment submitted!");
+ } catch (err) {
+ console.error(err);
+ setMessage("Failed to submit coordinator comment.");
}
};
-
return (
-
A.2 - Weekly Progress Report
+
Weekly Progress Report
+
+
+