diff --git a/client/src/App.js b/client/src/App.js
index 67991b7c..16c2d527 100644
--- a/client/src/App.js
+++ b/client/src/App.js
@@ -8,4 +8,4 @@ function App() {
return ;
}
-export default App;
+export default App;
\ No newline at end of file
diff --git a/client/src/pages/SupervisorDashboard.js b/client/src/pages/SupervisorDashboard.js
index 077cdeef..8d3a692b 100644
--- a/client/src/pages/SupervisorDashboard.js
+++ b/client/src/pages/SupervisorDashboard.js
@@ -1,4 +1,3 @@
-
import React, { useEffect, useState } from "react";
import axios from "axios";
import "../styles/SupervisorDashboard.css";
@@ -9,31 +8,54 @@ const SupervisorDashboard = () => {
const [selectedForm, setSelectedForm] = useState(null);
const [loading, setLoading] = useState(true);
const [message, setMessage] = useState("");
+
+ useEffect(() => {
- useEffect(() => {
- const fetchRequests = async () => {
+ // Token used for authentication for future
+ // Now it will only be empty
+ const token = localStorage.getItem("token") || "";
+
+ const fetchRequests = async () => {
try {
- const res = await axios.get(`${process.env.REACT_APP_API_URL}/api/form/internshiprequests`);
- console.log("Fetched internship requests:", res.data); // debug log
+ const res = await axios.get(`${process.env.REACT_APP_API_URL}/api/supervisor/forms`,
+ {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ });
- const formatted = res.data
- .map(item => ({
+ const formatted = res.data.map(item => ({
_id: item._id,
- name: item.student?.userName || item.student?.name || "N/A",
+ name: item.student_id?.userName || item.student_id?.name || "N/A",
student_id: item.student?._id || item._id,
-
- form_type: "A1",
+ form_type: item.form_type,
createdAt: item.createdAt,
supervisor_status: item.supervisor_status || "pending",
- fullForm: item
- }))
- .sort((a, b) => new Date(a.createdAt) - new Date(b.createdAt)); // oldest first
+ fullForm: item,
+ workplace: {
+ name: item.workplace?.name || "N/A",
+ website: item.workplace?.website || "N/A",
+ phone: item.workplace?.phone || "N/A",
+ },
+ internshipAdvisor: {
+ name: item.internshipAdvisor?.name || "N/A",
+ jobTitle: item.internshipAdvisor?.jobTitle || "N/A",
+ email: item.internshipAdvisor?.email || "N/A",
+ },
+ creditHours: item.creditHours || 0,
+ startDate: item.startDate || "N/A",
+ endDate: item.endDate || "N/A",
+ tasks: item.tasks || [],
+ status: item.status || "pending",
+ supervisor_comment: item.supervisor_comment || "N/A"
+ }));
+
setRequests(formatted);
setLoading(false);
} catch (err) {
- console.error("Error fetching Internship A1 forms:", err);
- setMessage("Error fetching Internship A1 forms.");
+ console.error("Error fetching forms:", err);
+ setMessage("Error fetching forms.", err);
setLoading(false);
}
};
@@ -41,82 +63,111 @@ const SupervisorDashboard = () => {
fetchRequests();
}, []);
- const handleAction = async (id, action, comment) => {
- const confirmed = window.confirm(`Are you sure you want to ${action} this request?`);
- if (!confirmed) return;
+ const handleAction = async (id, form_type, action, comment) => {
+
+ const token = localStorage.getItem("token");
+
+ const confirmed = window.confirm(`Are you sure you want to ${action} this request?`);
+ if (!confirmed) return;
try {
const res = await axios.post(
- `${process.env.REACT_APP_API_URL}/api/form/internshiprequests/${id}/${action}`,
- { comment }
+ `${process.env.REACT_APP_API_URL}/api/supervisor/form/${form_type}/${id}/${action}`,
+ { comment },
+ {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ }
);
setMessage(res.data.message || `${action} successful`);
- setRequests(prev => prev.filter(req => req._id !== id));
- setSelectedForm(null);
+ setRequests(prev => prev.filter(req => req._id !== id)); // remove from table
+ return true;
} catch (err) {
console.error(`Failed to ${action} request:`, err);
setMessage(`Failed to ${action} request.`);
+ return false;
}
};
+
const openFormView = (form) => setSelectedForm(form);
const closeFormView = () => setSelectedForm(null);
const formatDate = (date) => new Date(date).toLocaleDateString();
- return (
-
-
Supervisor Dashboard
- {message &&
{message}
}
+ const sortedRequests = [...requests]
+ .filter((res) => res.supervisor_status?.toLowerCase() === "pending")
+ .sort((a, b) => new Date(a.createdAt) - new Date(b.createdAt));
+
+ let content;
- {loading ? (
-
Loading...
- ) : requests.length === 0 ? (
+ if (loading) {
+ content =
Loading...
;
+ } else if (sortedRequests.length === 0) {
+ content = (
- ) : (
+ );
+ } else {
+ content = (
| Student Name |
- Student ID |
+ Sooner ID |
+ Student Email |
Form Type |
- Date Submitted |
+ Submitted |
Status |
- {requests.map((req) => (
-
- | {req.name} |
-
-
- |
- {req.form_type} |
- {formatDate(req.createdAt)} |
-
-
- {req.supervisor_status}
-
- |
-
- ))}
+ {sortedRequests.map((req) => {
+ console.log(req); // Log the entire request object
+ console.log(req.Name); // Log the student's full name if populated
+
+ return (
+
+ | {req.interneeName || "N/A"} |
+
+
+ |
+ {req.interneeEmail || req.ouEmail || "N/A"} |
+ {req.form_type} |
+ {formatDate(req.createdAt)} |
+
+
+ {req.supervisor_status || req.status}
+
+ |
+
+ );
+ })}
- )}
-
- {selectedForm && (
-
- )}
-
- );
+ );
+ }
+
+ return (
+
+
Supervisor Dashboard
+ {message &&
{message}
}
+ {content}
+ {selectedForm && (
+
+ handleAction(selectedForm.form_type, id, action, comment, signature)
+ }
+ />
+ )}
+
+ );
};
-export default SupervisorDashboard;
+export default SupervisorDashboard;
\ No newline at end of file
diff --git a/client/src/pages/ViewFormModal.js b/client/src/pages/ViewFormModal.js
index 55cc551e..a83a3fa3 100644
--- a/client/src/pages/ViewFormModal.js
+++ b/client/src/pages/ViewFormModal.js
@@ -7,42 +7,37 @@ const ViewFormModal = ({ formData, onClose, onAction }) => {
const [error, setError] = useState("");
const handleDecision = (action) => {
- if (!comment.trim()) {
- setError("Comment is required before taking action.");
- return;
- }
- if (!signature.trim()) {
- setError("Signature is required before approval/rejection.");
- return;
- }
-
- const payloadComment = `${comment.trim()} | Supervisor Signature: ${signature.trim()}`;
+ if (!comment.trim()) return setError("Comment is required.");
+ if (!signature.trim()) return setError("Signature is required.");
setError("");
- onAction(formData._id, action, payloadComment);
+ onAction(formData._id, action, comment.trim(), signature.trim());
};
- return (
-
-
-
A.1 Internship Request Form
-
-
-
+ // ✅ Inserted rendering helpers
+ const renderA1 = () => (
+ <>
+ A1 – Internship Request Form
+
+
- | Student Name: {formData.interneeName} |
- Sooner ID: {formData.soonerId} |
+ |
+ |
+
+
- | Email: {formData.interneeEmail} |
- Phone: {formData.phone} |
+ Student Name: {formData.interneeName || "N/A"} |
+ Student ID: {formData.soonerId || "N/A"} |
+ Email: {formData.interneeEmail || "N/A"} |
- | Workplace Name: {formData.workplaceName} |
- Website: {formData.website} |
+ Workplace Name: {formData.workplace?.name || "N/A"} |
+ Phone: {formData.workplace?.phone || "N/A"} |
+ Website: {formData.workplace?.website || "N/A"} |
- | Advisor Name: {formData.advisorName} |
- Advisor Email: {formData.advisorEmail} |
+ Advisor Name: {formData.internshipAdvisor?.name || "N/A"} |
+ Advisor Email: {formData.internshipAdvisor?.email || "N/A"} |
| Credit Hours: {formData.creditHours} |
@@ -67,42 +62,72 @@ const ViewFormModal = ({ formData, onClose, onAction }) => {
))}
+ >
+ );
-
-
- setSignature(e.target.value)}
- placeholder="Enter your full name"
- style={{ width: "100%", padding: "6px", marginTop: "5px", borderRadius: "4px" }}
- />
-
-
-
-
-
+ const renderA3 = () => (
+ <>
+ A3 – Final Job Performance Evaluation
+ Name: {formData.interneeName}
+ Email: {formData.interneeEmail}
+ Sooner ID: {formData.interneeID}
- {error && {error}
}
+ Evaluation Items
+
+
+
+ | Category |
+ Rating |
+ Comment |
+
+
+
+ {formData.evaluations?.map((item, i) => (
+
+ | {item.category} |
+ {item.rating} |
+ {item.comment || "-"} |
+
+ ))}
+
+
+ >
+ );
-
-
-
-
+ const renderSignaturesAndActions = () => (
+ <>
+ Supervisor Review
+
+ setSignature(e.target.value)}
+ style={{ width: "100%", marginBottom: "8px" }}
+ />
+
+