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 = (
No pending approvals.
- ) : ( + ); + } else { + content = ( - + + - + - {requests.map((req) => ( - - - - - - - - ))} + {sortedRequests.map((req) => { + console.log(req); // Log the entire request object + console.log(req.Name); // Log the student's full name if populated + + return ( + + + + + + + + + ); + })}
Student NameStudent IDSooner IDStudent Email Form TypeDate SubmittedSubmitted Status
{req.name} - - {req.form_type}{formatDate(req.createdAt)} - - {req.supervisor_status} - -
{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

+
+ - - + + + + - - + + + - - + + + - - + + @@ -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" }} - /> -
- -
- -
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}