commit
1c7a146fe0
5 changed files with 103 additions and 79 deletions
|
|
@ -126,6 +126,7 @@ const Navbar = () => {
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
to="/assignment"
|
to="/assignment"
|
||||||
|
state={{ userId: user.userId }}
|
||||||
className={`navbar__link ${
|
className={`navbar__link ${
|
||||||
activeLink === "/assignment" ? "navbar__link--active" : ""
|
activeLink === "/assignment" ? "navbar__link--active" : ""
|
||||||
}`}
|
}`}
|
||||||
|
|
@ -140,6 +141,7 @@ const Navbar = () => {
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
to="/editor"
|
to="/editor"
|
||||||
|
state={{ qrCodeNumber: user.userId || user.id}}
|
||||||
className={`navbar__link ${
|
className={`navbar__link ${
|
||||||
activeLink === "/editor" ? "navbar__link--active" : ""
|
activeLink === "/editor" ? "navbar__link--active" : ""
|
||||||
}`}
|
}`}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import "../scss/components/_assignment.scss";
|
import "../scss/components/_assignment.scss";
|
||||||
|
import {useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
const AssignmentPage = () => {
|
const AssignmentPage = () => {
|
||||||
const [assignmentId, setAssignmentId] = useState("");
|
const [assignmentId, setAssignmentId] = useState("");
|
||||||
|
|
@ -24,16 +25,20 @@ const AssignmentPage = () => {
|
||||||
const [showPassword, setShowPassword] = useState(false);
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.title = "Assignment";
|
document.title = "Assignment";
|
||||||
getCurrentUser();
|
|
||||||
fetchAssignments();
|
fetchAssignments();
|
||||||
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!appName) return; // Don't alert for empty name
|
if (!appName) return; // Don't alert for empty name
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
fetch(`${VITE_ASSIGNMENT_URL}/instructor/checkAssignmentByAppName/${appName}`)
|
fetch(
|
||||||
|
`${VITE_ASSIGNMENT_URL}/instructor/checkAssignmentByAppName/${appName}`
|
||||||
|
)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error("Failed to fetch assignment by app name");
|
throw new Error("Failed to fetch assignment by app name");
|
||||||
|
|
@ -42,7 +47,9 @@ const AssignmentPage = () => {
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data.exists) {
|
if (data.exists) {
|
||||||
alert("This app name already exists. Please choose a different one.");
|
alert(
|
||||||
|
"This app name already exists. Please choose a different one."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
|
@ -57,62 +64,60 @@ const AssignmentPage = () => {
|
||||||
if (!qrCodeNumber) return; // Don't alert for empty QR code number
|
if (!qrCodeNumber) return; // Don't alert for empty QR code number
|
||||||
console.log("Checking QR code number:", qrCodeNumber); // Added console log
|
console.log("Checking QR code number:", qrCodeNumber); // Added console log
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
fetch(`${VITE_ASSIGNMENT_URL}/instructor/checkAssignmentByQRCode/${qrCodeNumber}`)
|
fetch(
|
||||||
.then((response) => {
|
`${VITE_ASSIGNMENT_URL}/instructor/checkAssignmentByQRCode/${qrCodeNumber}`
|
||||||
if (!response.ok) {
|
)
|
||||||
throw new Error("Failed to fetch assignment by QR code number");
|
.then((response) => {
|
||||||
}
|
if (!response.ok) {
|
||||||
return response.json();
|
throw new Error("Failed to fetch assignment by QR code number");
|
||||||
})
|
}
|
||||||
.then((data) => {
|
return response.json();
|
||||||
console.log("QR code fetch result:", data); // Added console log
|
})
|
||||||
if (data.exists) {
|
.then((data) => {
|
||||||
alert("This QR code number already exists. Please choose a different one.");
|
console.log("QR code fetch result:", data); // Added console log
|
||||||
}
|
if (data.exists) {
|
||||||
})
|
alert(
|
||||||
.catch((error) => {
|
"This QR code number already exists. Please choose a different one."
|
||||||
console.error("Error fetching assignment by QR code number:", error);
|
);
|
||||||
});
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error fetching assignment by QR code number:", error);
|
||||||
|
});
|
||||||
}, 1000); // 1 second delay
|
}, 1000); // 1 second delay
|
||||||
|
|
||||||
return () => clearTimeout(timer); // Clear timeout on QR code number change
|
return () => clearTimeout(timer); // Clear timeout on QR code number change
|
||||||
}, [qrCodeNumber]);
|
}, [qrCodeNumber]);
|
||||||
|
|
||||||
const getCurrentUser = async () => {
|
const fetchAssignments = async () => {
|
||||||
try {
|
try {
|
||||||
const authResponse = await fetch(`${authUrl}/auth/current_user`, {
|
const authResponse = await fetch(`${authUrl}/auth/current_user`, {
|
||||||
credentials: "include",
|
credentials: "include",
|
||||||
});
|
});
|
||||||
|
|
||||||
const user = await authResponse.json();
|
const user = await authResponse.json();
|
||||||
setUser(user);
|
setUser(user);
|
||||||
} catch (error) {
|
console.log("User:", user);
|
||||||
console.error("Error fetching current user:", error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const fetchAssignments = async () => {
|
const res = await fetch(
|
||||||
try {
|
`${VITE_ASSIGNMENT_URL}/instructor/list/${user.userId}`,
|
||||||
// if (user) {
|
{
|
||||||
// console.log("Current user:", user, `${VITE_ASSIGNMENT_URL}/instructor/list/${user.userId}`);
|
method: "GET",
|
||||||
// const res = await fetch(`${VITE_ASSIGNMENT_URL}/instructor/list/${user.userId}`, {
|
}
|
||||||
// // credentials: "include",
|
);
|
||||||
// });
|
|
||||||
//replace this with commented code above to get the instructor id from the auth service
|
|
||||||
const res = await fetch(`${VITE_ASSIGNMENT_URL}/instructor/list/9`, {
|
|
||||||
// credentials: "include",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!res.ok) throw new Error("Failed to fetch");
|
if (!res.ok) throw new Error("Failed to fetch");
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
|
|
||||||
|
console.log("Fetched assignments data:", data);
|
||||||
|
|
||||||
// Optional: Remove duplicate assignment IDs if needed
|
// Optional: Remove duplicate assignment IDs if needed
|
||||||
const unique = Array.from(
|
const unique = Array.from(
|
||||||
new Map(data.map((item) => [item.assignmentid, item])).values()
|
new Map(data.map((item) => [item.assignmentid, item])).values()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
console.log("Unique assignments data:", unique);
|
||||||
|
|
||||||
setProjects(unique);
|
setProjects(unique);
|
||||||
// }
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching assignments:", error);
|
console.error("Error fetching assignments:", error);
|
||||||
}
|
}
|
||||||
|
|
@ -122,12 +127,19 @@ const AssignmentPage = () => {
|
||||||
setStudentName("");
|
setStudentName("");
|
||||||
setCampID("");
|
setCampID("");
|
||||||
setProgramID("");
|
setProgramID("");
|
||||||
|
setQrCodeNumber("");
|
||||||
|
setAppName("");
|
||||||
setPassword("");
|
setPassword("");
|
||||||
setDescription("");
|
setDescription("");
|
||||||
setFile(null);
|
setFile(null);
|
||||||
setEditingIndex(null);
|
setEditingIndex(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleEditClick = (qrCodeNumber) => {
|
||||||
|
console.log("Navigating to editor with QR Code Number:", qrCodeNumber);
|
||||||
|
navigate('/editor', { state: { qrCodeNumber: qrCodeNumber } });
|
||||||
|
};
|
||||||
|
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
@ -143,21 +155,6 @@ const AssignmentPage = () => {
|
||||||
formData.append("password", password);
|
formData.append("password", password);
|
||||||
formData.append("description", description);
|
formData.append("description", description);
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
//replace with api
|
|
||||||
// if (editingIndex !== null) {
|
|
||||||
// const updatedProjects = [...projects];
|
|
||||||
// updatedProjects[editingIndex] = newProject;
|
|
||||||
// setProjects(updatedProjects);
|
|
||||||
// } else {
|
|
||||||
// setProjects([...projects, newProject]);
|
|
||||||
// }
|
|
||||||
|
|
||||||
alert(editingIndex !== null ? "Assignment updated!" : "Assignment submitted!");
|
|
||||||
resetForm();
|
|
||||||
setShowModal(false);
|
|
||||||
setLoading(false);
|
|
||||||
}, 2000);
|
|
||||||
if (editingIndex !== null) {
|
if (editingIndex !== null) {
|
||||||
//edit mode
|
//edit mode
|
||||||
await fetch(`${VITE_ASSIGNMENT_URL}/instructor/update/${assignmentId}`, {
|
await fetch(`${VITE_ASSIGNMENT_URL}/instructor/update/${assignmentId}`, {
|
||||||
|
|
@ -165,7 +162,6 @@ const AssignmentPage = () => {
|
||||||
body: formData,
|
body: formData,
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.error("Failed to edit assignment:", response.statusText);
|
console.error("Failed to edit assignment:", response.statusText);
|
||||||
throw new Error("Failed to edit assignment");
|
throw new Error("Failed to edit assignment");
|
||||||
|
|
@ -181,7 +177,7 @@ const AssignmentPage = () => {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
//create mode
|
//create mode
|
||||||
formData.append("instructorid", 9);
|
formData.append("instructorid", user.userId);
|
||||||
formData.append("appname", appName);
|
formData.append("appname", appName);
|
||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
|
|
@ -214,6 +210,7 @@ const AssignmentPage = () => {
|
||||||
editingIndex !== null ? "Assignment updated!" : "Assignment submitted!"
|
editingIndex !== null ? "Assignment updated!" : "Assignment submitted!"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
fetchAssignments(); // Refresh the assignments list
|
fetchAssignments(); // Refresh the assignments list
|
||||||
resetForm();
|
resetForm();
|
||||||
setShowModal(false);
|
setShowModal(false);
|
||||||
|
|
@ -237,9 +234,12 @@ const AssignmentPage = () => {
|
||||||
const handleDelete = (index) => {
|
const handleDelete = (index) => {
|
||||||
const project = projects[index];
|
const project = projects[index];
|
||||||
if (window.confirm("Are you sure you want to delete this assignment?")) {
|
if (window.confirm("Are you sure you want to delete this assignment?")) {
|
||||||
fetch(`${VITE_ASSIGNMENT_URL}/instructor/delete/${project.assignmentid}`, {
|
fetch(
|
||||||
method: "DELETE",
|
`${VITE_ASSIGNMENT_URL}/instructor/delete/${project.assignmentid}`,
|
||||||
})
|
{
|
||||||
|
method: "DELETE",
|
||||||
|
}
|
||||||
|
)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
console.error("Failed to delete assignment:", response.statusText);
|
console.error("Failed to delete assignment:", response.statusText);
|
||||||
|
|
@ -331,6 +331,16 @@ const AssignmentPage = () => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label>QR Code Number</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
value={qrCodeNumber}
|
||||||
|
onChange={(e) => setQrCodeNumber(e.target.value)}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="password-field">
|
<div className="password-field">
|
||||||
<label>Password</label>
|
<label>Password</label>
|
||||||
<div className="input-wrapper">
|
<div className="input-wrapper">
|
||||||
|
|
@ -405,15 +415,17 @@ const AssignmentPage = () => {
|
||||||
<div key={index} className="project-item">
|
<div key={index} className="project-item">
|
||||||
<div className="project-meta">
|
<div className="project-meta">
|
||||||
<p><strong>Student Name:</strong> {project.studentname || project.studentName}</p>
|
<p><strong>Student Name:</strong> {project.studentname || project.studentName}</p>
|
||||||
<p><strong>CampID:</strong> {project.campid || project.campID}</p>
|
<p><strong>QR Number:</strong> {project.qrcodenumber || project.qrCodeNumber}</p>
|
||||||
<p><strong>ProgramID:</strong> {project.programid || project.programID}</p>
|
<p><strong>App Name:</strong> {project.appname || project.appName}</p>
|
||||||
|
<p><strong>Game Snake ID:</strong> {project.snakegameid || project.snakeGameId}</p>
|
||||||
|
<p><strong>URL:</strong> <a href={project.assignmenturl}>{project.assignmenturl || project.assignmentUrl}</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{project.title && <h4>{project.title}</h4>}
|
{/* {project.title && <h4>{project.title}</h4>}
|
||||||
{project.description && <p>{project.description}</p>}
|
{project.description && <p>{project.description}</p>}
|
||||||
{project.fileName && <p><strong>Uploaded File:</strong> {project.fileName}</p>}
|
{project.fileName && <p><strong>Uploaded File:</strong> {project.fileName}</p>} */}
|
||||||
|
|
||||||
{project.assignmenturl && (
|
{/* {project.assignmenturl && (
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
href={project.assignmenturl}
|
href={project.assignmenturl}
|
||||||
|
|
@ -423,7 +435,7 @@ const AssignmentPage = () => {
|
||||||
View Assignment
|
View Assignment
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
)}
|
)} */}
|
||||||
{project.originalfile && (
|
{project.originalfile && (
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
|
|
@ -444,13 +456,15 @@ const AssignmentPage = () => {
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="action-buttons">
|
<div className="action-buttons">
|
||||||
<button onClick={() => handleEdit(index)}>✏️ View Edit</button>
|
<button onClick={() => handleEdit(index)}>✏️ Edit</button>
|
||||||
<button onClick={() => handleDelete(index)}>🗑️ Delete</button>
|
<button onClick={() => handleDelete(index)}>🗑️ Delete</button>
|
||||||
<button onClick={() => alert("QR feature coming soon!")}>🧮 Editor</button>
|
<button key={project.qrcodenumber} onClick={() => handleEditClick(project.qrcodenumber)}>
|
||||||
</div>
|
📎 Editor
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
))}
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import EditorPanel from "../components/EditorPanel";
|
import EditorPanel from "../components/EditorPanel";
|
||||||
import PreviewPanel from "../components/PreviewPanel";
|
import PreviewPanel from "../components/PreviewPanel";
|
||||||
|
|
||||||
export default function PageCodeEditor() {
|
export default function PageCodeEditor() {
|
||||||
|
|
||||||
const { qrCodeNumber: routeId } = useParams();
|
const location = useLocation();
|
||||||
// console.log("Assignment ID:", assignmentId);
|
const qrCodeNumber = location.state?.qrCodeNumber;
|
||||||
const qrCodeNumber = routeId || "2256";
|
|
||||||
console.log("QR Code Number:", qrCodeNumber);
|
console.log("QR Code Number:", qrCodeNumber);
|
||||||
|
|
||||||
const [appName, setAppName] = useState("");
|
const [appName, setAppName] = useState("");
|
||||||
|
|
@ -18,7 +18,7 @@ export default function PageCodeEditor() {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch(`https://assignment-service.fly.dev/student/assignment/${qrCodeNumber}`)
|
fetch(`http://localhost:8082/student/assignment/${qrCodeNumber}`)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (!res.ok) throw new Error("Failed to fetch assignment");
|
if (!res.ok) throw new Error("Failed to fetch assignment");
|
||||||
return res.json();
|
return res.json();
|
||||||
|
|
@ -29,7 +29,7 @@ export default function PageCodeEditor() {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!appName) return;
|
if (!appName) return;
|
||||||
fetch(`https://assignment-service.fly.dev/notebook/${appName}`)
|
fetch(`http://localhost:8082/notebook/${appName}`)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (!res.ok) throw new Error("Failed to fetch notebook");
|
if (!res.ok) throw new Error("Failed to fetch notebook");
|
||||||
return res.json();
|
return res.json();
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
.assignment-page {
|
.assignment-page {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
margin-top: 90rem;
|
margin-top: 50rem;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
// min-height: 100vh;
|
min-height: 100vh;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
form {
|
form {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,18 @@
|
||||||
// Assignment Page Styling
|
// Assignment Page Styling
|
||||||
|
body {
|
||||||
|
justify-content: flex-starts;
|
||||||
|
}
|
||||||
|
|
||||||
.assignment-page {
|
.assignment-page {
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 2rem;
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #AAC5E5;
|
||||||
|
}
|
||||||
|
|
||||||
section {
|
section {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue