diff --git a/src/app/api/get_assignments_current/route.ts b/src/app/api/get_assignments_current/route.ts index 71906ea..89c26ee 100644 --- a/src/app/api/get_assignments_current/route.ts +++ b/src/app/api/get_assignments_current/route.ts @@ -2,9 +2,8 @@ import { NextRequest, NextResponse } from "next/server"; import { cookies } from "next/headers"; import cheerio from "cheerio"; import { Assignment } from "@/types"; -import { parse } from "path"; -import zlib from "zlib"; import { getCurrentQuarterOid } from "@/utils/getCurrentQuarter"; +import { processAssignments } from "@/utils/processData"; export async function GET(req: NextRequest, res: NextResponse) { try { @@ -22,42 +21,42 @@ export async function GET(req: NextRequest, res: NextResponse) { Cookie: `JSESSIONID=${sessionId}` }, }).then(res => res.text()).then(html => { - const $ = cheerio.load(html); - - const assignments: Assignment[] = []; - - const tableRows = $("#dataGrid > table > tbody > tr.listCell"); - - tableRows.each((index, row) => { - const assignmentName = $(row).children("td:nth-child(3)").text(); - const dueDate = $(row).children("td:nth-child(5)").text(); - const category = $(row).children("td:nth-child(2)").text(); - const points = $(row).find("td:nth-child(6) > table > tbody > tr > td:nth-child(2)").text().split("/")[1]; - const earned = $(row).find("td:nth-child(6) > table > tbody > tr > td:nth-child(2)").text().split("/")[0]; - const feedback = $(row).children("td:nth-child(7)").text(); - - if (assignmentName) { - - const assignment = { - name: assignmentName, - dueDate: dueDate ? dueDate : null, - gradeCategory: category ? category : null, - points: points ? parseFloat(points) : null, - earned: earned ? parseFloat(earned) : null, - feedback: feedback ? feedback : null - }; - - assignments.push(assignment); - } + const { assignments, more } = processAssignments(html); + + if (more) { + fetch("https://aspen.cpsd.us/aspen/portalAssignmentList.do?navkey=academics.classes.list.gcd", { + headers: { + Cookie: `JSESSIONID=${sessionId}` + }, + method: "POST", + body: new URLSearchParams({ + "org.apache.struts.taglib.html.TOKEN": apacheToken ? apacheToken : "", + "userEvent": "10", + "gradeTermOid": getCurrentQuarterOid(), + }), + }).then(async res => { + const html = await res.text(); + + assignments.push(...processAssignments(html).assignments); + }); - }) + fetch("https://aspen.cpsd.us/aspen/portalAssignmentList.do?navkey=academics.classes.list.gcd", { + headers: { + Cookie: `JSESSIONID=${sessionId}` + }, + method: "POST", + body: new URLSearchParams({ + "org.apache.struts.taglib.html.TOKEN": apacheToken ? apacheToken : "", + "userEvent": "20", + "gradeTermOid": getCurrentQuarterOid(), + }), + }); + } assingmentsList.push(assignments); }); for (let i = 0; i < classes - 1; i++) { - const assignments: Assignment[] = []; - await fetch("https://aspen.cpsd.us/aspen/portalAssignmentList.do?navkey=academics.classes.list.gcd", { headers: { Cookie: `JSESSIONID=${sessionId}` @@ -69,38 +68,10 @@ export async function GET(req: NextRequest, res: NextResponse) { "gradeTermOid": getCurrentQuarterOid(), }), }).then(res => res.text()).then(async html => { - const $ = cheerio.load(html); - - const tableRows = $("#dataGrid > table > tbody > tr.listCell"); - - tableRows.each((index, row) => { - const assignmentName = $(row).children("td:nth-child(3)").text(); - const dueDate = $(row).children("td:nth-child(5)").text(); - const category = $(row).children("td:nth-child(2)").text(); - const points = $(row).find("td:nth-child(6) > table > tbody > tr > td:nth-child(2)").text().split("/")[1]; - const earned = $(row).find("td:nth-child(6) > table > tbody > tr > td:nth-child(2)").text().split("/")[0]; - const feedback = $(row).children("td:nth-child(7)").text(); + const { assignments, more } = processAssignments(html); - if (assignmentName) { - - const assignment = { - name: assignmentName, - dueDate: dueDate ? dueDate : null, - gradeCategory: category ? category : null, - points: points ? parseFloat(points) : null, - earned: earned ? parseFloat(earned) : null, - feedback: feedback ? feedback : null - }; - - assignments.push(assignment); - } - - }); - - const recordsCount = parseInt($("#totalRecordsCount")?.text() || "0"); - - if (recordsCount > 25) { - await fetch("https://aspen.cpsd.us/aspen/portalAssignmentList.do?navkey=academics.classes.list.gcd", { + if (more) { + fetch("https://aspen.cpsd.us/aspen/portalAssignmentList.do?navkey=academics.classes.list.gcd", { headers: { Cookie: `JSESSIONID=${sessionId}` }, @@ -112,38 +83,15 @@ export async function GET(req: NextRequest, res: NextResponse) { }), }).then(async res => { const html = await res.text(); - const $ = cheerio.load(html); - - const tableRows = $("#dataGrid > table > tbody > tr.listCell"); - - tableRows.each((index, row) => { - const assignmentName = $(row).children("td:nth-child(3)").text(); - const dueDate = $(row).children("td:nth-child(5)").text(); - const category = $(row).children("td:nth-child(2)").text(); - const points = $(row).find("td:nth-child(6) > table > tbody > tr > td:nth-child(2)").text().split("/")[1]; - const earned = $(row).find("td:nth-child(6) > table > tbody > tr > td:nth-child(2)").text().split("/")[0]; - const feedback = $(row).children("td:nth-child(7)").text(); - - if (assignmentName) { - - const assignment = { - name: assignmentName, - dueDate: dueDate ? dueDate : null, - gradeCategory: category ? category : null, - points: points ? parseFloat(points) : null, - earned: earned ? parseFloat(earned) : null, - feedback: feedback ? feedback : null - }; - - assignments.push(assignment); - } - }); + assignments.push(...processAssignments(html).assignments); }); + fetch("https://aspen.cpsd.us/aspen/portalAssignmentList.do?navkey=academics.classes.list.gcd", { headers: { Cookie: `JSESSIONID=${sessionId}` - }, method: "POST", + }, + method: "POST", body: new URLSearchParams({ "org.apache.struts.taglib.html.TOKEN": apacheToken ? apacheToken : "", "userEvent": "20", @@ -151,9 +99,9 @@ export async function GET(req: NextRequest, res: NextResponse) { }), }); } - }); - assingmentsList.push(assignments); + assingmentsList.push(assignments); + }); } await fetch("https://aspen.cpsd.us/aspen/portalAssignmentList.do?navkey=academics.classes.list.gcd", { @@ -168,6 +116,8 @@ export async function GET(req: NextRequest, res: NextResponse) { }), }) + console.log(assingmentsList); + const elapsedTime = new Date().getTime() - startTime.getTime(); console.log("\x1b[32m ✓\x1b[0m scraped assignments in", elapsedTime, "ms"); return new Response(JSON.stringify(assingmentsList), { status: 200 }); diff --git a/src/app/globals.css b/src/app/globals.css index 17bfec4..3a218dc 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -2,7 +2,8 @@ --background-color: #000000; --text-color: #ffffff; --alt-background-color: #1f1f1f; - --inside-padding: 15px; + --alt-text-color: #c0c0c0; + --inside-padding: 20px; --link-hightlight: rgb(68, 255, 49); --link-hightlightTrans: #8d7cff40; --uniMargin: 20px; @@ -20,7 +21,7 @@ body { align-items: center; padding: var(--inside-padding); background-color: var(--alt-background-color); - border-radius: 20px; + border-radius: 10px; } .navlinks a { @@ -113,19 +114,22 @@ body { .grades-table { width: 100%; + padding-bottom: 20px; + margin-bottom: 20px; + border-bottom: #ffffff 1px solid; } -.grades-table tr td:nth-child(3) { +.grades-table tr td:nth-child(2) { text-align: right; font-weight: 700; } -.grades-table tr td:nth-child(5) { +.grades-table tr td:nth-child(4) { text-align: right; width: 0%; } -.grades-table tr td:nth-child(4) { +.grades-table tr td:nth-child(3) { text-align: center; width: 0%; padding: 0 20px; @@ -136,29 +140,18 @@ body { padding: 10px 0; } -.grades-table tr th:nth-child(3) { +.grades-table tr th:nth-child(2) { text-align: right; } -.grades-table tr th:nth-child(4) { +.grades-table tr th:nth-child(3) { text-align: center; } -.grades-table tr th:nth-child(5) { +.grades-table tr th:nth-child(4) { text-align: right; } -.dropdown-icon { - cursor: pointer; - -moz-user-select: -moz-none; - -khtml-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; - width: 0%; - padding-right: 8px; -} - .gpa-container { display: flex; justify-content: space-between; @@ -314,4 +307,20 @@ a { .checkbox-container label { margin-top: 100px; +} + +.placeholder-text { + text-align: center; + font-style: italic; + width: 100%; + margin-top: 20px; + color: var(--alt-text-color); +} + +.assignments-table { + width: 100%; +} + +.class-row { + cursor: not-allowed; } \ No newline at end of file diff --git a/src/app/gradebook/page.tsx b/src/app/gradebook/page.tsx index 39d246b..f1479cb 100644 --- a/src/app/gradebook/page.tsx +++ b/src/app/gradebook/page.tsx @@ -12,6 +12,9 @@ export default function Home() { const [assignmentData, setAssignmentData] = useState([]); const [loading, setLoading] = useState(true); const [loadingAssignment, setLoadingAssignment] = useState(true); + const [assignmentsTableContent, setAssignmentsTableContent] = useState([ +

click on a class to show assignments

+ ]); useEffect(() => { setClassData(JSON.parse( @@ -51,23 +54,27 @@ export default function Home() { }, ["/api/get_schedule_data/", "/api/get_assignments_current/", setAssignmentData]) function handleRowClick(index: number) { - const element = document.getElementById(`a${index}`); - const row = document.getElementById(`c${index}`); - const arrow = row?.children[0]; + const assignments = assignmentData[index] || []; - if (arrow) { - if (arrow.textContent === "▶") { - arrow.textContent = "▼"; - } else { - arrow.textContent = "▶"; - } - } - - if (element) { - element.hidden = !element.hidden; - } - - return; + if (assignments) { + setAssignmentsTableContent( + [ + + + {assignments.map((assignment, index) => ( + + + + + + ))} + +
{assignment.name}{assignment.gradeCategory}{assignment.earned} / {assignment.points}
+ ] + ); + } else { +

no assignments in this class

+ } } return ( @@ -89,7 +96,6 @@ export default function Home() { - @@ -97,10 +103,11 @@ export default function Home() { {classData.map((data, index) => ( <> - - + handleRowClick(index)} + style={!loadingAssignment ? { + cursor: "pointer" + } : {}} + > - {assignmentData[index] && ( - - - - )} ))}
TEACHERS CLASS GRADE
handleRowClick(index)} className="dropdown-icon"> - ▶ -
{data.teacher} {data.name} = 100 ? "hGrade" : "") : ""}> @@ -108,41 +115,13 @@ export default function Home() { {data.room}
+ + {loadingAssignment ? (

fetching assignments...

) : assignmentsTableContent} +
); diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 13ff838..09b64ac 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -131,7 +131,7 @@ export default function Home() { This is actively being worked on,
check out the{" "} - + repository on our github ! diff --git a/src/utils/processData.ts b/src/utils/processData.ts new file mode 100644 index 0000000..32367a4 --- /dev/null +++ b/src/utils/processData.ts @@ -0,0 +1,44 @@ +import { Assignment } from '@/types'; +import { load } from 'cheerio'; + +export function processAssignments(html: string): { + assignments: Assignment[], + more: boolean +} { + const $ = load(html); + + const assignments: Assignment[] = []; + + const tableRows = $("#dataGrid > table > tbody > tr.listCell"); + + tableRows.each((index, row) => { + const assignmentName = $(row).children("td:nth-child(3)").text(); + const dueDate = $(row).children("td:nth-child(5)").text(); + const category = $(row).children("td:nth-child(2)").text(); + const points = $(row).find("td:nth-child(6) > table > tbody > tr > td:nth-child(2)").text().split("/")[1]; + const earned = $(row).find("td:nth-child(6) > table > tbody > tr > td:nth-child(2)").text().split("/")[0]; + const feedback = $(row).children("td:nth-child(7)").text(); + + if (assignmentName) { + + const assignment = { + name: assignmentName, + dueDate: dueDate ? dueDate : null, + gradeCategory: category ? category : null, + points: points ? parseFloat(points) : null, + earned: earned ? parseFloat(earned) : null, + feedback: feedback ? feedback : null + }; + + assignments.push(assignment); + } + + }) + + const recordsCount = parseInt($("#totalRecordsCount")?.text() || "0"); + + return { + assignments, + more: recordsCount > 25 + } +} \ No newline at end of file