From b0d012959e78753b4a881bda977ffbc29fe5f6af Mon Sep 17 00:00:00 2001 From: Damian <37555910+DCRepublic@users.noreply.github.com> Date: Sun, 10 Nov 2024 21:09:43 -0500 Subject: [PATCH 01/33] add rating average to profs --- app/api/getProfClasses/route.ts | 2 -- app/api/submitReview/route.ts | 50 ++++++++++++++++++++++++++++++++- app/login/layout.tsx | 2 +- app/rating/page.tsx | 1 - 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/app/api/getProfClasses/route.ts b/app/api/getProfClasses/route.ts index 3db68cb..2b79aab 100644 --- a/app/api/getProfClasses/route.ts +++ b/app/api/getProfClasses/route.ts @@ -18,7 +18,5 @@ export async function GET(request: NextRequest) { }, }); - //console.log(plans); - console.log(courses); return NextResponse.json(courses, { status: 200 }); } diff --git a/app/api/submitReview/route.ts b/app/api/submitReview/route.ts index caedabd..d98faa0 100644 --- a/app/api/submitReview/route.ts +++ b/app/api/submitReview/route.ts @@ -31,7 +31,55 @@ export async function POST(request: NextRequest) { review: data.review, }, }); - return NextResponse.json(newReview, { status: 200 }); + } + const profs = await prisma.faculty.findUnique({ + select: { Rating: { select: { overallRating: true } } }, + //include: { Rating: true }, + where: { id: facultyID }, + }); + + let count: any = { one: 0, two: 0, three: 0, four: 0, five: 0 }; + + if (profs.Rating.length > 0) { + for (const rating of profs.Rating) { + //@ts-ignore + if (rating.overallRating == 1) { + count.one += 1; + } + if (rating.overallRating == 2) { + count.two += 1; + } + if (rating.overallRating == 3) { + count.three += 1; + } + if (rating.overallRating == 4) { + count.four += 1; + } + if (rating.overallRating == 5) { + count.five += 1; + } + } + + let avg = parseInt( + ( + (count.one * 1 + + count.two * 2 + + count.three * 3 + + count.four * 4 + + count.five * 5) / + profs.Rating.length + ).toFixed(1) + ); + + const newAvg = await prisma.faculty.update({ + data: { + avgRating: avg, + }, + where: { + id: facultyID, + }, + }); + return NextResponse.json(newAvg, { status: 200 }); } //console.log(plans); diff --git a/app/login/layout.tsx b/app/login/layout.tsx index 5e425dc..18ec915 100644 --- a/app/login/layout.tsx +++ b/app/login/layout.tsx @@ -5,7 +5,7 @@ export default function DocsLayout({ }) { return (
-
+
{children}
diff --git a/app/rating/page.tsx b/app/rating/page.tsx index 3fe910f..600284a 100644 --- a/app/rating/page.tsx +++ b/app/rating/page.tsx @@ -116,7 +116,6 @@ export default function RatingPage() { setSelectedProf(key); }; const onClassSelectionChange = (key: any) => { - console.log(key); setSelectedClass(key); }; const handleSelectionChange = (e: React.ChangeEvent) => { From 81a581d93b1ab2f6f9e2b04d49bc53b3b7648a1e Mon Sep 17 00:00:00 2001 From: Damian <37555910+DCRepublic@users.noreply.github.com> Date: Sun, 10 Nov 2024 21:11:57 -0500 Subject: [PATCH 02/33] more changes --- app/api/submitReview/route.ts | 76 ++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/app/api/submitReview/route.ts b/app/api/submitReview/route.ts index d98faa0..8fe9d6a 100644 --- a/app/api/submitReview/route.ts +++ b/app/api/submitReview/route.ts @@ -40,46 +40,48 @@ export async function POST(request: NextRequest) { let count: any = { one: 0, two: 0, three: 0, four: 0, five: 0 }; - if (profs.Rating.length > 0) { - for (const rating of profs.Rating) { - //@ts-ignore - if (rating.overallRating == 1) { - count.one += 1; - } - if (rating.overallRating == 2) { - count.two += 1; - } - if (rating.overallRating == 3) { - count.three += 1; + if (profs) { + if (profs?.Rating?.length > 0) { + for (const rating of profs.Rating) { + //@ts-ignore + if (rating.overallRating == 1) { + count.one += 1; + } + if (rating.overallRating == 2) { + count.two += 1; + } + if (rating.overallRating == 3) { + count.three += 1; + } + if (rating.overallRating == 4) { + count.four += 1; + } + if (rating.overallRating == 5) { + count.five += 1; + } } - if (rating.overallRating == 4) { - count.four += 1; - } - if (rating.overallRating == 5) { - count.five += 1; - } - } - let avg = parseInt( - ( - (count.one * 1 + - count.two * 2 + - count.three * 3 + - count.four * 4 + - count.five * 5) / - profs.Rating.length - ).toFixed(1) - ); + let avg = parseInt( + ( + (count.one * 1 + + count.two * 2 + + count.three * 3 + + count.four * 4 + + count.five * 5) / + profs.Rating.length + ).toFixed(1) + ); - const newAvg = await prisma.faculty.update({ - data: { - avgRating: avg, - }, - where: { - id: facultyID, - }, - }); - return NextResponse.json(newAvg, { status: 200 }); + const newAvg = await prisma.faculty.update({ + data: { + avgRating: avg, + }, + where: { + id: facultyID, + }, + }); + return NextResponse.json(newAvg, { status: 200 }); + } } //console.log(plans); From 592277287aba881854688676fd89557762044f72 Mon Sep 17 00:00:00 2001 From: Damian <37555910+DCRepublic@users.noreply.github.com> Date: Sun, 10 Nov 2024 23:27:22 -0500 Subject: [PATCH 03/33] Fix seatsavailable, calendar ui --- app/page.tsx | 1 - components/Calendar.tsx | 6 ++- components/CourseCard.tsx | 9 ++++- components/CreatePlan.tsx | 2 +- components/FullCourseList.tsx | 76 ++++++++++++++++------------------- 5 files changed, 47 insertions(+), 47 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 1c4c220..042d20a 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -55,7 +55,6 @@ async function getUniquCodes() { daCodes.push(codes[i].code); } } - console.log(daCodes); return daCodes; } diff --git a/components/Calendar.tsx b/components/Calendar.tsx index 76c90ed..dd8b159 100644 --- a/components/Calendar.tsx +++ b/components/Calendar.tsx @@ -31,8 +31,10 @@ export default function Calendar(props: any) { /> */} - {eventInfo.timeText} -
{eventInfo.event.title}
+ {eventInfo.timeText} +
+ {eventInfo.event.title} +
); } diff --git a/components/CourseCard.tsx b/components/CourseCard.tsx index 29665ca..def22bb 100644 --- a/components/CourseCard.tsx +++ b/components/CourseCard.tsx @@ -30,7 +30,6 @@ async function updatePlan(course: any) { } export default function CourseCard(props: any) { - console.log(props.course); const color = generateColorFromName(props.course.subject); const color_mappings: { [key: string]: string } = { @@ -181,13 +180,19 @@ export default function CourseCard(props: any) { )} - {props.course.seatsAvailable >= 0 && ( + {props.course.seatsAvailable == 0 ? (
No available seats left for this section
+ ) : ( +
+
+ Seats Available: {props.course.seatsAvailable} +
+
)} diff --git a/components/CreatePlan.tsx b/components/CreatePlan.tsx index c790c3d..e754c09 100644 --- a/components/CreatePlan.tsx +++ b/components/CreatePlan.tsx @@ -33,7 +33,7 @@ export default function CreatePlan(props: any) { const fetcher = (url: any) => fetch(url).then((r) => r.json()); const { data, isLoading, error } = useSWR("/api/getplancourses", fetcher, { - refreshInterval: 1000, + refreshInterval: 800, }); const { diff --git a/components/FullCourseList.tsx b/components/FullCourseList.tsx index 6d3af19..9746fc5 100644 --- a/components/FullCourseList.tsx +++ b/components/FullCourseList.tsx @@ -38,15 +38,15 @@ async function getCourses( }, ], where: { - ...(query + ...(term ? { - ...(term - ? { - year: term, - } - : {}), - //year: term, + year: term, + } + : {}), + //year: term, + ...(query + ? { OR: [ { courseTitle: { @@ -85,42 +85,36 @@ async function getCourses( }, }, ], + } + : {}), - ...(startTime.length > 0 - ? { - facultyMeet: { - meetingTimes: { - beginTime: { - in: startTime, - }, - }, - }, - } - : {}), + ...(startTime.length > 0 + ? { + facultyMeet: { + meetingTimes: { + beginTime: { + in: startTime, + }, + }, + }, + } + : {}), - ...(dotw.length > 0 - ? { - facultyMeet: { - meetingTimes: { - is: { - monday: dotw.includes("monday") ? true : Prisma.skip, - tuesday: dotw.includes("tuesday") ? true : Prisma.skip, - wednesday: dotw.includes("wednesday") - ? true - : Prisma.skip, - thursday: dotw.includes("thursday") - ? true - : Prisma.skip, - friday: dotw.includes("friday") ? true : Prisma.skip, - saturday: dotw.includes("saturday") - ? true - : Prisma.skip, - sunday: dotw.includes("sunday") ? true : Prisma.skip, - }, - }, - }, - } - : {}), + ...(dotw.length > 0 + ? { + facultyMeet: { + meetingTimes: { + is: { + monday: dotw.includes("monday") ? true : Prisma.skip, + tuesday: dotw.includes("tuesday") ? true : Prisma.skip, + wednesday: dotw.includes("wednesday") ? true : Prisma.skip, + thursday: dotw.includes("thursday") ? true : Prisma.skip, + friday: dotw.includes("friday") ? true : Prisma.skip, + saturday: dotw.includes("saturday") ? true : Prisma.skip, + sunday: dotw.includes("sunday") ? true : Prisma.skip, + }, + }, + }, } : {}), }, From 59932e1d44f554548acb7526793d7a81947b120f Mon Sep 17 00:00:00 2001 From: Damian <37555910+DCRepublic@users.noreply.github.com> Date: Mon, 11 Nov 2024 12:19:32 -0500 Subject: [PATCH 04/33] Add admin dashboard, and ability to delete ratings --- app/admin/layout.tsx | 13 ++++ app/admin/page.tsx | 128 ++++++++++++++++++++++++++++++++++ app/api/deleteRating/route.ts | 20 ++++++ app/api/getRatings/route.ts | 18 +++++ components/navbar.tsx | 17 +++-- lib/auth.ts | 37 +++++++++- 6 files changed, 221 insertions(+), 12 deletions(-) create mode 100644 app/admin/layout.tsx create mode 100644 app/admin/page.tsx create mode 100644 app/api/deleteRating/route.ts create mode 100644 app/api/getRatings/route.ts diff --git a/app/admin/layout.tsx b/app/admin/layout.tsx new file mode 100644 index 0000000..4bb84a9 --- /dev/null +++ b/app/admin/layout.tsx @@ -0,0 +1,13 @@ +export default function DocsLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( +
+
+ {children} +
+
+ ); +} diff --git a/app/admin/page.tsx b/app/admin/page.tsx new file mode 100644 index 0000000..b1e7439 --- /dev/null +++ b/app/admin/page.tsx @@ -0,0 +1,128 @@ +"use client"; + +import useSWR from "swr"; +import { useState } from "react"; +import React from "react"; +import { signIn, signOut, useSession } from "next-auth/react"; +import { + Table, + TableHeader, + TableColumn, + TableBody, + TableRow, + TableCell, + getKeyValue, + Dropdown, + DropdownTrigger, + Button, + DropdownMenu, + DropdownItem, +} from "@nextui-org/react"; + +import { MoreVert } from "@mui/icons-material"; +import axios from "axios"; + +export default function AdminPage() { + const { data: session, status } = useSession(); + const fetcher = (url: any) => fetch(url).then((r) => r.json()); + + const { + data: ratings, + isLoading, + error, + } = useSWR("/api/getRatings", fetcher, { refreshInterval: 5000 }); + let columns = []; + let filtered_ratings: any = []; + + if (!isLoading) { + for (let rating of ratings) { + const name = rating.User?.name; + const email = rating.User?.email; + rating.name = name; + rating.email = email; + + filtered_ratings.push(rating); + } + + if (filtered_ratings.length > 0) { + for (let key in filtered_ratings[0]) { + if (key != "User") { + columns.push({ key: key, label: key }); + } + } + } + columns.push({ key: "actions", value: "actions" }); + } + + async function deleteRating(ratingID: any) { + console.log("Rating Gone, finito, finished"); + await axios + .post("/api/deleteRating", { + ratingID: ratingID, + }) + .then(function (response) { + // Handle response + console.log(response); + }) + .catch(function (error) { + console.log(error); + }); + } + + const renderCell = React.useCallback((user: any, columnKey: React.Key) => { + const cellValue = user[columnKey as keyof any]; + + switch (columnKey) { + case "actions": + return ( +
+ + + + + + deleteRating(user.id)}> + Delete + + + +
+ ); + default: + return cellValue; + } + }, []); + + if (status === "authenticated") { + // @ts-ignore + if (session.user?.role === "admin") { + return ( +
+ + + {(column) => ( + {column.label} + )} + + + {(item: any) => ( + + {(columnKey) => ( + {renderCell(item, columnKey)} + )} + + )} + +
+
+ ); + } + } +} diff --git a/app/api/deleteRating/route.ts b/app/api/deleteRating/route.ts new file mode 100644 index 0000000..98f493a --- /dev/null +++ b/app/api/deleteRating/route.ts @@ -0,0 +1,20 @@ +// api/test.ts +import { NextResponse, NextRequest } from "next/server"; + +import prisma from "../../../lib/prisma"; +import { auth } from "../../../lib/auth"; +import { getPlanCookie } from "../../../app/actions"; + +export async function POST(request: NextRequest) { + const data = await request.json(); + + const ratingID = data.ratingID; + + const courses = await prisma.rating.delete({ + where: { + id: parseInt(ratingID), + }, + }); + + return NextResponse.json(courses, { status: 200 }); +} diff --git a/app/api/getRatings/route.ts b/app/api/getRatings/route.ts new file mode 100644 index 0000000..4ded146 --- /dev/null +++ b/app/api/getRatings/route.ts @@ -0,0 +1,18 @@ +import { NextResponse, NextRequest } from "next/server"; + +import prisma from "../../../lib/prisma"; + +export async function GET(request: NextRequest) { + const profs = await prisma.rating.findMany({ + include: { + User: { + select: { + name: true, + email: true, + }, + }, + }, + }); + + return NextResponse.json(profs, { status: 200 }); +} diff --git a/components/navbar.tsx b/components/navbar.tsx index 946387a..14ff9ed 100644 --- a/components/navbar.tsx +++ b/components/navbar.tsx @@ -41,8 +41,8 @@ export const Navbar = (props: any) => { const { data: session, status } = useSession(); let authenticated; - let loginLink; - let adminDashLink; + let loginLink: any; + let adminDashLink: any; let nameButton; if (props.hasOwnProperty("login")) { @@ -68,16 +68,14 @@ export const Navbar = (props: any) => { ); // @ts-ignore - /* + if (session.user?.role === "admin") { adminDashLink = ( - - -
Admin
- -
+ +
Admin
+
); - }*/ + } nameButton = session.user?.name; } else { authenticated = false; @@ -184,6 +182,7 @@ export const Navbar = (props: any) => { {authenticated ? ( + {adminDashLink} {loginLink} ) : ( diff --git a/lib/auth.ts b/lib/auth.ts index 63a140a..7dc545d 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -4,10 +4,21 @@ import type { NextApiResponse, } from "next"; import type { NextAuthOptions } from "next-auth"; +import { getToken } from "next-auth/jwt"; -import KeycloakProvider from "next-auth/providers/keycloak"; +import KeycloakProvider, { + KeycloakProfileToken, +} from "next-auth/providers/keycloak"; import { getServerSession } from "next-auth"; +declare module "next-auth/providers/keycloak" { + export interface KeycloakProfileToken extends KeycloakProfile { + realm_access: { roles: [string] }; + } +} +function parseJwt(token: string) { + return JSON.parse(Buffer.from(token.split(".")[1], "base64").toString()); +} // You'll need to import and pass this // to `NextAuth` in `app/api/auth/[...nextauth]/route.ts` export const config = { @@ -22,15 +33,36 @@ export const config = { providers: [ KeycloakProvider({ profile(profile, tokens) { + const tokenData: KeycloakProfileToken = parseJwt( + //@ts-ignore + tokens.access_token + ); + + let theRole; + + if ("scheduler" in tokenData.resource_access) { + theRole = tokenData.resource_access.scheduler.roles.find( + (role: string) => role === "admin" || "user" + ); + } else { + theRole = "user"; + } + return { id: profile.sub, name: profile.name, email: profile.email, + ///THE DUMB OLD WAY BELOW //MAKE SURE TO ADD GROUPS UNDER client scopes ->[currentproject]-dedicated //If you don't it wont redirect + + //New way is to add a role under client scopes-> roles + // Then assign that role to your user specifically role: - profile.groups.find((group: string) => group === "admin") || "user", + //tokenData.resource_access.scheduler.roles.find( (role: string) => role === "admin" || "user"), + //profile.groups.find((group: string) => group === "admin") || "user", + theRole, }; }, clientId: process.env.KEYCLOAK_ID || "", @@ -53,7 +85,6 @@ export const config = { // @ts-ignore session.user.id = token.sub; } - return session; }, }, From cf32d34958ef8de5f2858d22c8c68dae5dcbc4c5 Mon Sep 17 00:00:00 2001 From: Thomas Makin Date: Tue, 12 Nov 2024 09:59:22 -0500 Subject: [PATCH 05/33] prisma: fieldReference is no longer preview --- prisma/schema.prisma | 196 +++++++++++++++++++++---------------------- 1 file changed, 98 insertions(+), 98 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index b0d4148..5bd6175 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1,128 +1,128 @@ generator client { - provider = "prisma-client-js" - previewFeatures = ["fieldReference", "fullTextIndex", "fullTextSearch", "relationJoins", "strictUndefinedChecks"] + provider = "prisma-client-js" + previewFeatures = ["fullTextIndex", "fullTextSearch", "relationJoins", "strictUndefinedChecks"] } datasource db { - provider = "postgresql" - url = env("DATABASE_URL") + provider = "postgresql" + url = env("DATABASE_URL") } model User { - id Int @id @default(autoincrement()) - email String @unique - name String? - uuid String @unique - plans CoursePlan[] - ratings Rating[] + id Int @id @default(autoincrement()) + email String @unique + name String? + uuid String @unique + plans CoursePlan[] + ratings Rating[] } model CoursePlan { - id Int @id @default(autoincrement()) - name String - userId Int? - year String - User User? @relation(fields: [userId], references: [id]) - courses Course[] @relation("CourseToCoursePlan") + id Int @id @default(autoincrement()) + name String + userId Int? + year String + User User? @relation(fields: [userId], references: [id]) + courses Course[] @relation("CourseToCoursePlan") } model Course { - id Int @id @default(autoincrement()) - courseId Int - courseReferenceNumber String @unique - courseNumber String - subject String - scheduleTypeDescription String - courseTitle String - descriptionUrl String - description String - creditHours Float - maximumEnrollment Int - enrollment Int - seatsAvailable Int - facultyId Int - facultyMeetId Int - year String - avgRating Float? - instructor Faculty @relation(fields: [facultyId], references: [id]) - facultyMeet MeetingsFaculty @relation(fields: [facultyMeetId], references: [id]) - Rating Rating[] - sectionAttributes sectionAttribute[] - CoursePlan CoursePlan[] @relation("CourseToCoursePlan") + id Int @id @default(autoincrement()) + courseId Int + courseReferenceNumber String @unique + courseNumber String + subject String + scheduleTypeDescription String + courseTitle String + descriptionUrl String + description String + creditHours Float + maximumEnrollment Int + enrollment Int + seatsAvailable Int + facultyId Int + facultyMeetId Int + year String + avgRating Float? + instructor Faculty @relation(fields: [facultyId], references: [id]) + facultyMeet MeetingsFaculty @relation(fields: [facultyMeetId], references: [id]) + Rating Rating[] + sectionAttributes sectionAttribute[] + CoursePlan CoursePlan[] @relation("CourseToCoursePlan") - @@index([subject, courseNumber], map: "subj_course") + @@index([subject, courseNumber], map: "subj_course") } model Faculty { - id Int @id @default(autoincrement()) - bannerId String @unique - displayName String - emailAddress String - year String - avgRating Float? - courses Course[] - Rating Rating[] + id Int @id @default(autoincrement()) + bannerId String @unique + displayName String + emailAddress String + year String + avgRating Float? + courses Course[] + Rating Rating[] } model MeetingsFaculty { - id Int @id @default(autoincrement()) - category String - courseReferenceNumber String @unique - meetingTimeID Int - year String - courses Course[] - meetingTimes MeetingTime @relation(fields: [meetingTimeID], references: [id]) + id Int @id @default(autoincrement()) + category String + courseReferenceNumber String @unique + meetingTimeID Int + year String + courses Course[] + meetingTimes MeetingTime @relation(fields: [meetingTimeID], references: [id]) } model MeetingTime { - id Int @id @default(autoincrement()) - building String - buildingDescription String - room String - category String - courseReferenceNumber String @unique - endDate String - startDate String - hoursWeek Float - meetingType String - meetingTypeDescription String - monday Boolean - tuesday Boolean - wednesday Boolean - thursday Boolean - friday Boolean - saturday Boolean - sunday Boolean - year String - beginTime String - endTime String - facultyMeet MeetingsFaculty[] + id Int @id @default(autoincrement()) + building String + buildingDescription String + room String + category String + courseReferenceNumber String @unique + endDate String + startDate String + hoursWeek Float + meetingType String + meetingTypeDescription String + monday Boolean + tuesday Boolean + wednesday Boolean + thursday Boolean + friday Boolean + saturday Boolean + sunday Boolean + year String + beginTime String + endTime String + facultyMeet MeetingsFaculty[] } model sectionAttribute { - id Int @id @default(autoincrement()) - code String - description String - courseReferenceNumber String @unique - year String - courseId Int - Course Course @relation(fields: [courseId], references: [id]) + id Int @id @default(autoincrement()) + code String + description String + courseReferenceNumber String @unique + year String + courseId Int + Course Course @relation(fields: [courseId], references: [id]) } model Rating { - id Int @id @default(autoincrement()) - courseID Int - facultyID Int - overallRating Int? - difficulty Int? - takeAgain Boolean? - review String? - grade String? - forCredit Boolean? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - userId Int - course Course @relation(fields: [courseID], references: [id]) - faculty Faculty @relation(fields: [facultyID], references: [id]) - User User? @relation(fields: [userId], references: [id]) + id Int @id @default(autoincrement()) + courseID Int + facultyID Int + overallRating Int? + difficulty Int? + takeAgain Boolean? + review String? + grade String? + forCredit Boolean? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + userId Int + course Course @relation(fields: [courseID], references: [id]) + faculty Faculty @relation(fields: [facultyID], references: [id]) + User User? @relation(fields: [userId], references: [id]) } From 6738479c1aaddad7a4f1213b86de169d8265d0be Mon Sep 17 00:00:00 2001 From: Thomas Makin Date: Tue, 12 Nov 2024 10:37:31 -0500 Subject: [PATCH 06/33] scheduler: auth and types overhaul - no more ts ignore - general cleanup - proper async callbacks - also bump packs --- app/actions.ts | 4 +- app/admin/page.tsx | 1 - app/api/createplan/route.ts | 11 +- app/api/deleteRating/route.ts | 2 - app/api/getcourseplans/route.ts | 2 - app/api/getplancourses/route.ts | 1 - app/api/submitReview/route.ts | 3 - app/api/updatePlan/route.ts | 8 +- app/api/user/route.ts | 7 +- components/navbar.tsx | 1 - lib/auth.ts | 19 +-- middleware.ts | 1 + package-lock.json | 274 +++++++++++++++++--------------- types/{index.ts => index.d.ts} | 0 types/next-auth.d.ts | 22 +++ 15 files changed, 177 insertions(+), 179 deletions(-) rename types/{index.ts => index.d.ts} (100%) create mode 100644 types/next-auth.d.ts diff --git a/app/actions.ts b/app/actions.ts index af32f63..039a52d 100644 --- a/app/actions.ts +++ b/app/actions.ts @@ -3,14 +3,12 @@ import { cookies } from "next/headers"; export async function setPlanCookie(plan: string) { - //@ts-ignore (await cookies()).set("plan", plan); } export async function getPlanCookie() { const cookieStore = await cookies(); - //@ts-ignore - const plan = await cookieStore.get("plan"); + const plan = cookieStore.get("plan"); const out = plan ? plan.value : undefined; diff --git a/app/admin/page.tsx b/app/admin/page.tsx index b1e7439..0780e01 100644 --- a/app/admin/page.tsx +++ b/app/admin/page.tsx @@ -96,7 +96,6 @@ export default function AdminPage() { }, []); if (status === "authenticated") { - // @ts-ignore if (session.user?.role === "admin") { return (
diff --git a/app/api/createplan/route.ts b/app/api/createplan/route.ts index 589ec6e..7307a50 100644 --- a/app/api/createplan/route.ts +++ b/app/api/createplan/route.ts @@ -8,17 +8,14 @@ export async function POST(request: NextRequest) { const data = await request.json(); const session = await auth(); - //@ts-ignore const user = await prisma.user.findUnique({ where: { - //@ts-ignore uuid: session?.user?.id, }, }); const plan = await prisma.coursePlan.create({ data: { - //@ts-ignore name: data.planName, year: "F2024", User: { @@ -36,15 +33,13 @@ export async function GET(request: NextRequest) { const session = await auth(); const user = await prisma.user.findUnique({ where: { - //@ts-ignore uuid: session?.user?.id, }, }); const courses = await prisma.coursePlan.findMany({ where: { User: { - //@ts-ignore - id: user.id, + id: user?.id, }, }, include: { @@ -59,10 +54,8 @@ export async function GET(request: NextRequest) { export async function DELETE(request: NextRequest) { const data = await request.json(); - //@ts-ignore const plan = await prisma.coursePlan.delete({ where: { - //@ts-ignore id: parseInt(data.planId), }, }); @@ -73,7 +66,7 @@ export async function DELETE(request: NextRequest) { // To handle a POST request to /api /* export async function POST(request: NextRequest) { - + return NextResponse.json(output, { status: 200 }); } */ diff --git a/app/api/deleteRating/route.ts b/app/api/deleteRating/route.ts index 98f493a..ac14853 100644 --- a/app/api/deleteRating/route.ts +++ b/app/api/deleteRating/route.ts @@ -2,8 +2,6 @@ import { NextResponse, NextRequest } from "next/server"; import prisma from "../../../lib/prisma"; -import { auth } from "../../../lib/auth"; -import { getPlanCookie } from "../../../app/actions"; export async function POST(request: NextRequest) { const data = await request.json(); diff --git a/app/api/getcourseplans/route.ts b/app/api/getcourseplans/route.ts index ec57edc..e0df034 100644 --- a/app/api/getcourseplans/route.ts +++ b/app/api/getcourseplans/route.ts @@ -7,7 +7,6 @@ export async function GET(request: NextRequest) { const session = await auth(); const user = await prisma.user.findUnique({ where: { - //@ts-ignore uuid: session?.user?.id, }, }); @@ -17,7 +16,6 @@ export async function GET(request: NextRequest) { courses = await prisma.coursePlan.findMany({ where: { User: { - //@ts-ignore id: user.id, }, }, diff --git a/app/api/getplancourses/route.ts b/app/api/getplancourses/route.ts index f454ccb..5fdd3d7 100644 --- a/app/api/getplancourses/route.ts +++ b/app/api/getplancourses/route.ts @@ -13,7 +13,6 @@ export async function GET(request: NextRequest) { where: { AND: { User: { - //@ts-ignore uuid: session?.user.id, }, //id: parseInt(planCookie), diff --git a/app/api/submitReview/route.ts b/app/api/submitReview/route.ts index 8fe9d6a..700da0f 100644 --- a/app/api/submitReview/route.ts +++ b/app/api/submitReview/route.ts @@ -10,10 +10,8 @@ export async function POST(request: NextRequest) { const session = await auth(); - //@ts-ignore const user = await prisma.user.findUnique({ where: { - //@ts-ignore uuid: session?.user?.id, }, }); @@ -43,7 +41,6 @@ export async function POST(request: NextRequest) { if (profs) { if (profs?.Rating?.length > 0) { for (const rating of profs.Rating) { - //@ts-ignore if (rating.overallRating == 1) { count.one += 1; } diff --git a/app/api/updatePlan/route.ts b/app/api/updatePlan/route.ts index c5177e6..239737f 100644 --- a/app/api/updatePlan/route.ts +++ b/app/api/updatePlan/route.ts @@ -35,15 +35,13 @@ export async function GET(request: NextRequest) { const session = await auth(); const user = await prisma.user.findUnique({ where: { - //@ts-ignore uuid: session?.user?.id, }, }); const courses = await prisma.coursePlan.findMany({ where: { User: { - //@ts-ignore - id: user.id, + id: user?.id, }, }, include: { @@ -59,10 +57,8 @@ export async function GET(request: NextRequest) { export async function DELETE(request: NextRequest) { const data = await request.json(); - //@ts-ignore const plan = await prisma.coursePlan.delete({ where: { - //@ts-ignore id: parseInt(data.planId), }, }); @@ -73,7 +69,7 @@ export async function DELETE(request: NextRequest) { // To handle a POST request to /api /* export async function POST(request: NextRequest) { - + return NextResponse.json(output, { status: 200 }); } */ diff --git a/app/api/user/route.ts b/app/api/user/route.ts index 5842a7d..8ad1469 100644 --- a/app/api/user/route.ts +++ b/app/api/user/route.ts @@ -5,22 +5,18 @@ import prisma from "../../../lib/prisma"; export async function POST(request: NextRequest) { const data = await request.json(); - //@ts-ignore const session = data?.session; const user = await prisma.user.upsert({ where: { - //@ts-ignore uuid: session?.user?.id, }, update: { - //@ts-ignore uuid: session?.user?.id, email: session?.user?.email, name: session?.user?.name, }, create: { - //@ts-ignore uuid: session?.user?.id, email: session?.user?.email, name: session?.user?.name, @@ -35,7 +31,6 @@ export async function GET(request: NextRequest) { const session = data.session; const user = await prisma.user.findUnique({ where: { - //@ts-ignore id: session?.user?.id, }, }); @@ -45,7 +40,7 @@ export async function GET(request: NextRequest) { // To handle a POST request to /api /* export async function POST(request: NextRequest) { - + return NextResponse.json(output, { status: 200 }); } */ diff --git a/components/navbar.tsx b/components/navbar.tsx index 14ff9ed..61ed7dc 100644 --- a/components/navbar.tsx +++ b/components/navbar.tsx @@ -67,7 +67,6 @@ export const Navbar = (props: any) => { Log out
); - // @ts-ignore if (session.user?.role === "admin") { adminDashLink = ( diff --git a/lib/auth.ts b/lib/auth.ts index 7dc545d..d71addb 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -4,7 +4,6 @@ import type { NextApiResponse, } from "next"; import type { NextAuthOptions } from "next-auth"; -import { getToken } from "next-auth/jwt"; import KeycloakProvider, { KeycloakProfileToken, @@ -25,7 +24,7 @@ export const config = { //Set custom redirect pages pages: { signIn: "/login", - //signOut: "/auth/signout", + signOut: "/logout", error: "/error", // Error code passed in query string as ?error= //verifyRequest: "/auth/verify-request", // (used for check email message) //newUser: "/auth/new-user", // New users will be directed here on first sign in (leave the property out if not of interest) @@ -34,8 +33,7 @@ export const config = { KeycloakProvider({ profile(profile, tokens) { const tokenData: KeycloakProfileToken = parseJwt( - //@ts-ignore - tokens.access_token + tokens.access_token || "" ); let theRole; @@ -72,19 +70,14 @@ export const config = { ], secret: process.env.NEXTAUTH_SECRET, callbacks: { - jwt({ token, user }) { - // @ts-ignore + async jwt({ token, user }) { if (user) token.role = user.role; return token; }, - session({ session, token }) { - if (session && session.user) { - // @ts-ignore - session.user.role = token.role; - // @ts-ignore - session.user.id = token.sub; - } + async session({ session, token }) { + session.role = token.role; + session.user.id = token.sub || ""; return session; }, }, diff --git a/middleware.ts b/middleware.ts index c7722a5..61e6997 100644 --- a/middleware.ts +++ b/middleware.ts @@ -4,6 +4,7 @@ export default withAuth({ // Matches the pages config in `[...nextauth]` pages: { signIn: "/login", + signOut: "/logout", error: "/error", }, }); diff --git a/package-lock.json b/package-lock.json index ce77e43..8d24809 100644 --- a/package-lock.json +++ b/package-lock.json @@ -511,9 +511,9 @@ } }, "node_modules/@formatjs/ecma402-abstract": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.2.tgz", - "integrity": "sha512-zReeOJo3gA6Lgk4gTsUUdCwwTBa+Tw0LcqKHD84JCAJdPSxsxKdKPAPXihVgKDZevIWFGi4UTpy7JJ3D5EWeSw==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.3.tgz", + "integrity": "sha512-aElGmleuReGnk2wtYOzYFmNWYoiWWmf1pPPCYg0oiIQSJj0mjc4eUfzUXaSOJ4S8WzI/cLqnCTWjqz904FT2OQ==", "license": "MIT", "dependencies": { "@formatjs/fast-memoize": "2.2.3", @@ -531,23 +531,23 @@ } }, "node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.2.tgz", - "integrity": "sha512-WAQ2zGbroadkWXUDDjbGUOBN0TeDUEC47lcXV8wTtFN1QYCI1T26AVWOHqvVMVBqXHheKa82myjEVaXWVTwBNA==", + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.3.tgz", + "integrity": "sha512-9L99QsH14XjOCIp4TmbT8wxuffJxGK8uLNO1zNhLtcZaVXvv626N0s4A2qgRCKG3dfYWx9psvGlFmvyVBa6u/w==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.2.2", - "@formatjs/icu-skeleton-parser": "1.8.6", + "@formatjs/ecma402-abstract": "2.2.3", + "@formatjs/icu-skeleton-parser": "1.8.7", "tslib": "2" } }, "node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.6.tgz", - "integrity": "sha512-rQXThZE7lxhw1eaOyu4mmFdKBYlh/dyYPSFB6hR3lZqPOm5vYdyHekQaxld9WIofZK2e3rxfel81RfAuy8kdIw==", + "version": "1.8.7", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.7.tgz", + "integrity": "sha512-fI+6SmS2g7h3srfAKSWa5dwreU5zNEfon2uFo99OToiLF6yxGE+WikvFSbsvMAYkscucvVmTYNlWlaDPp0n5HA==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.2.2", + "@formatjs/ecma402-abstract": "2.2.3", "tslib": "2" } }, @@ -650,9 +650,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.0.tgz", - "integrity": "sha512-xnRgu9DxZbkWak/te3fcytNyp8MTbuiZIaueg2rgEvBuN55n04nwLYLU9TX/VVlusc9L2ZNXi99nUFNkHXtr5g==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", "license": "Apache-2.0", "engines": { "node": ">=18.18" @@ -1363,9 +1363,9 @@ } }, "node_modules/@next/env": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/env/-/env-15.0.2.tgz", - "integrity": "sha512-c0Zr0ModK5OX7D4ZV8Jt/wqoXtitLNPwUfG9zElCZztdaZyNVnN40rDXVZ/+FGuR4CcNV5AEfM6N8f+Ener7Dg==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.0.3.tgz", + "integrity": "sha512-t9Xy32pjNOvVn2AS+Utt6VmyrshbpfUMhIjFO60gI58deSo/KgLOp31XZ4O+kY/Is8WAGYwA5gR7kOb1eORDBA==", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { @@ -1379,9 +1379,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.0.2.tgz", - "integrity": "sha512-GK+8w88z+AFlmt+ondytZo2xpwlfAR8U6CRwXancHImh6EdGfHMIrTSCcx5sOSBei00GyLVL0ioo1JLKTfprgg==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.0.3.tgz", + "integrity": "sha512-s3Q/NOorCsLYdCKvQlWU+a+GeAd3C8Rb3L1YnetsgwXzhc3UTWrtQpB/3eCjFOdGUj5QmXfRak12uocd1ZiiQw==", "cpu": [ "arm64" ], @@ -1395,9 +1395,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.0.2.tgz", - "integrity": "sha512-KUpBVxIbjzFiUZhiLIpJiBoelqzQtVZbdNNsehhUn36e2YzKHphnK8eTUW1s/4aPy5kH/UTid8IuVbaOpedhpw==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.0.3.tgz", + "integrity": "sha512-Zxl/TwyXVZPCFSf0u2BNj5sE0F2uR6iSKxWpq4Wlk/Sv9Ob6YCKByQTkV2y6BCic+fkabp9190hyrDdPA/dNrw==", "cpu": [ "x64" ], @@ -1411,9 +1411,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.0.2.tgz", - "integrity": "sha512-9J7TPEcHNAZvwxXRzOtiUvwtTD+fmuY0l7RErf8Yyc7kMpE47MIQakl+3jecmkhOoIyi/Rp+ddq7j4wG6JDskQ==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.0.3.tgz", + "integrity": "sha512-T5+gg2EwpsY3OoaLxUIofmMb7ohAUlcNZW0fPQ6YAutaWJaxt1Z1h+8zdl4FRIOr5ABAAhXtBcpkZNwUcKI2fw==", "cpu": [ "arm64" ], @@ -1427,9 +1427,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.0.2.tgz", - "integrity": "sha512-BjH4ZSzJIoTTZRh6rG+a/Ry4SW0HlizcPorqNBixBWc3wtQtj4Sn9FnRZe22QqrPnzoaW0ctvSz4FaH4eGKMww==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.0.3.tgz", + "integrity": "sha512-WkAk6R60mwDjH4lG/JBpb2xHl2/0Vj0ZRu1TIzWuOYfQ9tt9NFsIinI1Epma77JVgy81F32X/AeD+B2cBu/YQA==", "cpu": [ "arm64" ], @@ -1443,9 +1443,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.0.2.tgz", - "integrity": "sha512-i3U2TcHgo26sIhcwX/Rshz6avM6nizrZPvrDVDY1bXcLH1ndjbO8zuC7RoHp0NSK7wjJMPYzm7NYL1ksSKFreA==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.0.3.tgz", + "integrity": "sha512-gWL/Cta1aPVqIGgDb6nxkqy06DkwJ9gAnKORdHWX1QBbSZZB+biFYPFti8aKIQL7otCE1pjyPaXpFzGeG2OS2w==", "cpu": [ "x64" ], @@ -1459,9 +1459,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.0.2.tgz", - "integrity": "sha512-AMfZfSVOIR8fa+TXlAooByEF4OB00wqnms1sJ1v+iu8ivwvtPvnkwdzzFMpsK5jA2S9oNeeQ04egIWVb4QWmtQ==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.0.3.tgz", + "integrity": "sha512-QQEMwFd8r7C0GxQS62Zcdy6GKx999I/rTO2ubdXEe+MlZk9ZiinsrjwoiBL5/57tfyjikgh6GOU2WRQVUej3UA==", "cpu": [ "x64" ], @@ -1475,9 +1475,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.0.2.tgz", - "integrity": "sha512-JkXysDT0/hEY47O+Hvs8PbZAeiCQVxKfGtr4GUpNAhlG2E0Mkjibuo8ryGD29Qb5a3IOnKYNoZlh/MyKd2Nbww==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.0.3.tgz", + "integrity": "sha512-9TEp47AAd/ms9fPNgtgnT7F3M1Hf7koIYYWCMQ9neOwjbVWJsHZxrFbI3iEDJ8rf1TDGpmHbKxXf2IFpAvheIQ==", "cpu": [ "arm64" ], @@ -1491,9 +1491,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.0.2.tgz", - "integrity": "sha512-foaUL0NqJY/dX0Pi/UcZm5zsmSk5MtP/gxx3xOPyREkMFN+CTjctPfu3QaqrQHinaKdPnMWPJDKt4VjDfTBe/Q==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.0.3.tgz", + "integrity": "sha512-VNAz+HN4OGgvZs6MOoVfnn41kBzT+M+tB+OK4cww6DNyWS6wKaDpaAm/qLeOUbnMh0oVx1+mg0uoYARF69dJyA==", "cpu": [ "x64" ], @@ -5068,12 +5068,12 @@ "license": "Apache-2.0" }, "node_modules/@swc/helpers": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", - "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==", + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", "license": "Apache-2.0", "dependencies": { - "tslib": "^2.4.0" + "tslib": "^2.8.0" } }, "node_modules/@types/estree": { @@ -5160,16 +5160,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.13.0.tgz", - "integrity": "sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.14.0.tgz", + "integrity": "sha512-tqp8H7UWFaZj0yNO6bycd5YjMwxa6wIHOLZvWPkidwbgLCsBMetQoGj7DPuAlWa2yGO3H48xmPwjhsSPPCGU5w==", "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.13.0", - "@typescript-eslint/type-utils": "8.13.0", - "@typescript-eslint/utils": "8.13.0", - "@typescript-eslint/visitor-keys": "8.13.0", + "@typescript-eslint/scope-manager": "8.14.0", + "@typescript-eslint/type-utils": "8.14.0", + "@typescript-eslint/utils": "8.14.0", + "@typescript-eslint/visitor-keys": "8.14.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -5193,15 +5193,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.13.0.tgz", - "integrity": "sha512-w0xp+xGg8u/nONcGw1UXAr6cjCPU1w0XVyBs6Zqaj5eLmxkKQAByTdV/uGgNN5tVvN/kKpoQlP2cL7R+ajZZIQ==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.14.0.tgz", + "integrity": "sha512-2p82Yn9juUJq0XynBXtFCyrBDb6/dJombnz6vbo6mgQEtWHfvHbQuEa9kAOVIt1c9YFwi7H6WxtPj1kg+80+RA==", "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "8.13.0", - "@typescript-eslint/types": "8.13.0", - "@typescript-eslint/typescript-estree": "8.13.0", - "@typescript-eslint/visitor-keys": "8.13.0", + "@typescript-eslint/scope-manager": "8.14.0", + "@typescript-eslint/types": "8.14.0", + "@typescript-eslint/typescript-estree": "8.14.0", + "@typescript-eslint/visitor-keys": "8.14.0", "debug": "^4.3.4" }, "engines": { @@ -5221,13 +5221,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.13.0.tgz", - "integrity": "sha512-XsGWww0odcUT0gJoBZ1DeulY1+jkaHUciUq4jKNv4cpInbvvrtDoyBH9rE/n2V29wQJPk8iCH1wipra9BhmiMA==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.14.0.tgz", + "integrity": "sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw==", "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.13.0", - "@typescript-eslint/visitor-keys": "8.13.0" + "@typescript-eslint/types": "8.14.0", + "@typescript-eslint/visitor-keys": "8.14.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5238,13 +5238,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.13.0.tgz", - "integrity": "sha512-Rqnn6xXTR316fP4D2pohZenJnp+NwQ1mo7/JM+J1LWZENSLkJI8ID8QNtlvFeb0HnFSK94D6q0cnMX6SbE5/vA==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.14.0.tgz", + "integrity": "sha512-Xcz9qOtZuGusVOH5Uk07NGs39wrKkf3AxlkK79RBK6aJC1l03CobXjJbwBPSidetAOV+5rEVuiT1VSBUOAsanQ==", "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.13.0", - "@typescript-eslint/utils": "8.13.0", + "@typescript-eslint/typescript-estree": "8.14.0", + "@typescript-eslint/utils": "8.14.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -5262,9 +5262,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.13.0.tgz", - "integrity": "sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.14.0.tgz", + "integrity": "sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5275,13 +5275,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.13.0.tgz", - "integrity": "sha512-v7SCIGmVsRK2Cy/LTLGN22uea6SaUIlpBcO/gnMGT/7zPtxp90bphcGf4fyrCQl3ZtiBKqVTG32hb668oIYy1g==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.14.0.tgz", + "integrity": "sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ==", "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "8.13.0", - "@typescript-eslint/visitor-keys": "8.13.0", + "@typescript-eslint/types": "8.14.0", + "@typescript-eslint/visitor-keys": "8.14.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -5355,15 +5355,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.13.0.tgz", - "integrity": "sha512-A1EeYOND6Uv250nybnLZapeXpYMl8tkzYUxqmoKAWnI4sei3ihf2XdZVd+vVOmHGcp3t+P7yRrNsyyiXTvShFQ==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.14.0.tgz", + "integrity": "sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.13.0", - "@typescript-eslint/types": "8.13.0", - "@typescript-eslint/typescript-estree": "8.13.0" + "@typescript-eslint/scope-manager": "8.14.0", + "@typescript-eslint/types": "8.14.0", + "@typescript-eslint/typescript-estree": "8.14.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5377,12 +5377,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.13.0.tgz", - "integrity": "sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz", + "integrity": "sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ==", "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.13.0", + "@typescript-eslint/types": "8.14.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -5888,9 +5888,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001677", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz", - "integrity": "sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==", + "version": "1.0.30001680", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", "funding": [ { "type": "opencollective", @@ -6086,9 +6086,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", + "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -6307,9 +6307,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.50", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz", - "integrity": "sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw==", + "version": "1.5.56", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.56.tgz", + "integrity": "sha512-7lXb9dAvimCFdvUMTyucD4mnIndt/xhRKFAlky0CyFogdnNmdPQNoHI23msF/2V4mpTxMzgMdjK4+YRlFlRQZw==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -6422,9 +6422,9 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz", - "integrity": "sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.0.tgz", + "integrity": "sha512-tpxqxncxnpw3c93u8n3VOzACmRFoVmWJqbWXvX/JfKbkhBw1oslgPrUfeSt2psuqyEJFD6N/9lg5i7bsKpoq+Q==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -6435,6 +6435,7 @@ "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "globalthis": "^1.0.4", + "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", "has-symbols": "^1.0.3", @@ -7299,9 +7300,9 @@ } }, "node_modules/framer-motion": { - "version": "11.11.11", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.11.tgz", - "integrity": "sha512-tuDH23ptJAKUHGydJQII9PhABNJBpB+z0P1bmgKK9QFIssHGlfPd6kxMq00LSKwE27WFsb2z0ovY0bpUyMvfRw==", + "version": "11.11.12", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.12.tgz", + "integrity": "sha512-FC+efAcn62h6tXpeclgsekrpATdkIAa3+MffG2W2OLae0c7MV2NKgOcrwmScPKDg7qgyZC8Rqu36/4n5inMBtA==", "license": "MIT", "dependencies": { "tslib": "^2.4.0" @@ -7684,14 +7685,14 @@ } }, "node_modules/intl-messageformat": { - "version": "10.7.4", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.4.tgz", - "integrity": "sha512-D4wGk8/XAp/5YMLtTXR+BUyGeSl4+28N43cwXXmIGQ8Tt+STA/oUsz9KUerzgiwBlJ+2dRDsQ3qQvvlVF6jzFA==", + "version": "10.7.6", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.6.tgz", + "integrity": "sha512-IsMU/hqyy3FJwNJ0hxDfY2heJ7MteSuFvcnCebxRp67di4Fhx1gKKE+qS0bBwUF8yXkX9SsPUhLeX/B6h5SKUA==", "license": "BSD-3-Clause", "dependencies": { - "@formatjs/ecma402-abstract": "2.2.2", + "@formatjs/ecma402-abstract": "2.2.3", "@formatjs/fast-memoize": "2.2.3", - "@formatjs/icu-messageformat-parser": "2.9.2", + "@formatjs/icu-messageformat-parser": "2.9.3", "tslib": "2" } }, @@ -8491,12 +8492,12 @@ "license": "MIT" }, "node_modules/next": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/next/-/next-15.0.2.tgz", - "integrity": "sha512-rxIWHcAu4gGSDmwsELXacqAPUk+j8dV/A9cDF5fsiCMpkBDYkO2AEaL1dfD+nNmDiU6QMCFN8Q30VEKapT9UHQ==", + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/next/-/next-15.0.3.tgz", + "integrity": "sha512-ontCbCRKJUIoivAdGB34yCaOcPgYXr9AAkV/IwqFfWWTXEPUgLYkSkqBhIk9KK7gGmgjc64B+RdoeIDM13Irnw==", "license": "MIT", "dependencies": { - "@next/env": "15.0.2", + "@next/env": "15.0.3", "@swc/counter": "0.1.3", "@swc/helpers": "0.5.13", "busboy": "1.6.0", @@ -8508,25 +8509,25 @@ "next": "dist/bin/next" }, "engines": { - "node": ">=18.18.0" + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "15.0.2", - "@next/swc-darwin-x64": "15.0.2", - "@next/swc-linux-arm64-gnu": "15.0.2", - "@next/swc-linux-arm64-musl": "15.0.2", - "@next/swc-linux-x64-gnu": "15.0.2", - "@next/swc-linux-x64-musl": "15.0.2", - "@next/swc-win32-arm64-msvc": "15.0.2", - "@next/swc-win32-x64-msvc": "15.0.2", + "@next/swc-darwin-arm64": "15.0.3", + "@next/swc-darwin-x64": "15.0.3", + "@next/swc-linux-arm64-gnu": "15.0.3", + "@next/swc-linux-arm64-musl": "15.0.3", + "@next/swc-linux-x64-gnu": "15.0.3", + "@next/swc-linux-x64-musl": "15.0.3", + "@next/swc-win32-arm64-msvc": "15.0.3", + "@next/swc-win32-x64-msvc": "15.0.3", "sharp": "^0.33.5" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", "babel-plugin-react-compiler": "*", - "react": "^18.2.0 || 19.0.0-rc-02c0e824-20241028", - "react-dom": "^18.2.0 || 19.0.0-rc-02c0e824-20241028", + "react": "^18.2.0 || 19.0.0-rc-66855b96-20241106", + "react-dom": "^18.2.0 || 19.0.0-rc-66855b96-20241106", "sass": "^1.3.0" }, "peerDependenciesMeta": { @@ -8599,6 +8600,15 @@ "react-dom": "^16.8 || ^17 || ^18" } }, + "node_modules/next/node_modules/@swc/helpers": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.13.tgz", + "integrity": "sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/next/node_modules/postcss": { "version": "8.4.31", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", @@ -8676,9 +8686,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -10389,15 +10399,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.13.0.tgz", - "integrity": "sha512-vIMpDRJrQd70au2G8w34mPps0ezFSPMEX4pXkTzUkrNbRX+36ais2ksGWN0esZL+ZMaFJEneOBHzCgSqle7DHw==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.14.0.tgz", + "integrity": "sha512-K8fBJHxVL3kxMmwByvz8hNdBJ8a0YqKzKDX6jRlrjMuNXyd5T2V02HIq37+OiWXvUUOXgOOGiSSOh26Mh8pC3w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.13.0", - "@typescript-eslint/parser": "8.13.0", - "@typescript-eslint/utils": "8.13.0" + "@typescript-eslint/eslint-plugin": "8.14.0", + "@typescript-eslint/parser": "8.14.0", + "@typescript-eslint/utils": "8.14.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" diff --git a/types/index.ts b/types/index.d.ts similarity index 100% rename from types/index.ts rename to types/index.d.ts diff --git a/types/next-auth.d.ts b/types/next-auth.d.ts new file mode 100644 index 0000000..8761cf6 --- /dev/null +++ b/types/next-auth.d.ts @@ -0,0 +1,22 @@ +import { Session } from "next-auth"; +import { JWT } from "next-auth/jwt"; + +declare module "next-auth" { + interface Session { + id: string; + role: string; + user: User; + } + + interface User { + id: string; + role: string; + } +} + +declare module "next-auth/jwt" { + interface JWT { + id: string; + role: string; + } +} From 1b326718e639a03ce945ffb424d2e15d951eb1b2 Mon Sep 17 00:00:00 2001 From: Thomas Makin Date: Tue, 12 Nov 2024 12:28:06 -0500 Subject: [PATCH 07/33] scheduler: ui overhaul - mobile ui set up - cards reduced in size --- app/admin/page.tsx | 2 +- app/layout.tsx | 4 +-- app/page.tsx | 12 +++---- components/CourseCard.tsx | 68 +++++++++++++++++++-------------------- components/CreatePlan.tsx | 26 +++++++++++---- components/Search.tsx | 10 +++--- components/navbar.tsx | 51 ++++++----------------------- package-lock.json | 13 ++++++++ package.json | 1 + tailwind.config.js | 6 ++++ 10 files changed, 96 insertions(+), 97 deletions(-) diff --git a/app/admin/page.tsx b/app/admin/page.tsx index 0780e01..1d0af0b 100644 --- a/app/admin/page.tsx +++ b/app/admin/page.tsx @@ -101,7 +101,7 @@ export default function AdminPage() {
diff --git a/app/layout.tsx b/app/layout.tsx index 5f90469..0cf892b 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -52,9 +52,9 @@ export default function RootLayout({ defaultTheme: "dark", }} > -
+
-
+
{children}
diff --git a/app/page.tsx b/app/page.tsx index 042d20a..be35fde 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -104,18 +104,18 @@ async function Home(props: any) { return ( <> -
-
-
-
+
+
+
+
-
+
{props.fullCourseList}
-
+
diff --git a/components/CourseCard.tsx b/components/CourseCard.tsx index def22bb..673e246 100644 --- a/components/CourseCard.tsx +++ b/components/CourseCard.tsx @@ -53,10 +53,10 @@ export default function CourseCard(props: any) { return (
-

{item[0]}

+

{item[0]}

); } @@ -87,47 +87,47 @@ export default function CourseCard(props: any) { updatePlan(props.course)}>
-

+

{props.course.courseTitle.replace("&", "&")}

-

+

{props.course.subject} {props.course.courseNumber} |{" "} - {props.course.creditHours} credit(s) |   + {props.course.creditHours} credit(s) {props.course.sectionAttributes.length > 0 && ( -
{attributeCodes}
+
 | {attributeCodes}
)}

-
- +
+
+ +
- updatePlan(props.course)} - > + updatePlan(props.course)}>
-
+
{props.course.facultyMeet.meetingTimes.room ? ( -
-
+
+
{props.course.facultyMeet.meetingTimes.buildingDescription}{" "} {props.course.facultyMeet.meetingTimes.room}
-
+
{props.course.facultyMeet.meetingTimes ? ( -
+
{" "} {props.course.facultyMeet.meetingTimes.beginTime.slice( @@ -153,21 +153,21 @@ export default function CourseCard(props: any) {
) : ( -
+

Contact your Professor for additional details.

)}
-
{coloredDays}
+
{coloredDays}
-
Instructor
-
+
Instructor
+
{props.course.instructor.displayName.replace("'", "'")}
@@ -181,15 +181,15 @@ export default function CourseCard(props: any) { )}
{props.course.seatsAvailable == 0 ? ( -
-
+
+
No available seats left for this section
) : ( -
-
+
+
Seats Available: {props.course.seatsAvailable}
diff --git a/components/CreatePlan.tsx b/components/CreatePlan.tsx index e754c09..ddabb33 100644 --- a/components/CreatePlan.tsx +++ b/components/CreatePlan.tsx @@ -10,12 +10,13 @@ import { import AddIcon from "@mui/icons-material/Add"; import DeleteIcon from "@mui/icons-material/Delete"; import IosShareIcon from "@mui/icons-material/IosShare"; +import ExpandLessIcon from '@mui/icons-material/ExpandLess'; import axios from "axios"; import { Select, SelectItem } from "@nextui-org/react"; import { useRouter } from "next/navigation"; import { usePathname } from "next/navigation"; import { useSession } from "next-auth/react"; -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import useSWR from "swr"; import { useCookies } from "next-client-cookies"; @@ -25,6 +26,7 @@ import { generateColorFromName } from "../components/primitives"; export default function CreatePlan(props: any) { const cookies = useCookies(); const router = useRouter(); + const scrollRef = useRef(null); const pathname = usePathname(); const { data: session, status } = useSession(); @@ -163,12 +165,22 @@ export default function CreatePlan(props: any) { return output; }; + const scrollToPlan = () => { + if (scrollRef.current) + scrollRef.current.scrollIntoView({behavior: 'smooth', inline: "start"}); + } + return ( <> - - -
-
Create a Plan
+ + +
+
+
Create a Plan
+ +
-
+
or
@@ -227,7 +239,7 @@ export default function CreatePlan(props: any) {
diff --git a/components/Search.tsx b/components/Search.tsx index f0d8efb..f608ec1 100644 --- a/components/Search.tsx +++ b/components/Search.tsx @@ -134,10 +134,10 @@ export default function Search(props: any) { }; return ( -
+
{ - setCoursePlanName(event.target.value); - }} - /> - -
+
+ {/*
+
Create a Plan
+ +
*/} +
+
+
Create a Plan
+
+ { + setCoursePlanName(event.target.value); + }} + /> + +
+
-
-
- -
or
- +
+ + {/* --------------------------------- or --------------------------- */} +
or
+
-
- {/* --------------------------------- or --------------------------- */} - -
Select a Plan
-
- - -
+
diff --git a/components/FullCourseList.tsx b/components/FullCourseList.tsx index af9e277..633d545 100644 --- a/components/FullCourseList.tsx +++ b/components/FullCourseList.tsx @@ -61,7 +61,7 @@ export function FullCourseList({ return ( <>
-
+
{courses?.map((course: any) => (
diff --git a/components/Search.tsx b/components/Search.tsx index f608ec1..19f9aa9 100644 --- a/components/Search.tsx +++ b/components/Search.tsx @@ -134,10 +134,10 @@ export default function Search(props: any) { }; return ( -
+
{ const pathname = usePathname(); + const [isMenuOpen, setIsMenuOpen] = React.useState(false); + const { data: session, status } = useSession(); + useEffect(() => { + setIsMenuOpen(false); // Close the navigation panel + }, [pathname]); + if (status === "authenticated") { axios .post("/api/user", { @@ -53,6 +59,8 @@ export const Navbar = (props: any) => { className="bg-inherit lg:py-2" maxWidth="full" position="sticky" + isMenuOpen={isMenuOpen} + onMenuOpenChange={setIsMenuOpen} > @@ -127,59 +135,53 @@ export const Navbar = (props: any) => { - + - + {/* Mobile?*/} - {/* -
- {siteConfig.navItems.map((item, index) => ( - - - {item.label} - - - ))} - - - - - {} - : () => signIn("keycloak", { callbackUrl: "/" }) - } - > - {nameButton} - - - - {authenticated ? ( - { - authenticated - ? signOut() - : signIn("keycloak", { callbackUrl: "/" }); - }} - > - Sign Out - - ) : ( - <> - )} - - -
-
*/} + +
+ {siteConfig.navItems.map((item, index) => ( + + + {item.label} + + + ))} +
+ + {status === "authenticated" ? ( + + + + + + {/* Causes an awful error if rendered conditionally */} + {/* + Admin + */} + signOut()}> + Sign Out + + + + ) : ( + + )} + +
); From e059baf4e632ed30bc6495d4c49f482eca854d5f Mon Sep 17 00:00:00 2001 From: George Fang <26337405+Spazzinq@users.noreply.github.com> Date: Wed, 13 Nov 2024 17:19:59 -0500 Subject: [PATCH 18/33] Fix spacing issues --- app/page.tsx | 4 +- components/CreatePlan.tsx | 126 +++++++++++++++++++------------------- components/Search.tsx | 3 +- 3 files changed, 65 insertions(+), 68 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 9860fbb..bd6b6c6 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -120,12 +120,12 @@ async function Home(props: any) {
-
+
{props.fullCourseList}
-
+
diff --git a/components/CreatePlan.tsx b/components/CreatePlan.tsx index aab9fe5..f024d06 100644 --- a/components/CreatePlan.tsx +++ b/components/CreatePlan.tsx @@ -130,7 +130,7 @@ export default function CreatePlan(props: any) { - +
{course.courseTitle.replace(/&/g, "&")}
@@ -171,79 +171,77 @@ export default function CreatePlan(props: any) { }; return ( - <> -
- {/*
+
+ {/*
Create a Plan
*/} -
-
-
Create a Plan
-
- { - setCoursePlanName(event.target.value); - }} - /> - -
+
+
+
Create a Plan
+
+ { + setCoursePlanName(event.target.value); + }} + /> +
+
-
- - {/* --------------------------------- or --------------------------- */} -
or
- -
+
+ + {/* --------------------------------- or --------------------------- */} +
or
+ +
-
-
Select a Plan
-
- - -
+
+
Select a Plan
+
+ + +
+
-
- -
+
+
- +
); } diff --git a/components/Search.tsx b/components/Search.tsx index 51a6427..b67c279 100644 --- a/components/Search.tsx +++ b/components/Search.tsx @@ -137,9 +137,8 @@ export default function Search(props: any) { }; return ( -
+
- Date: Thu, 14 Nov 2024 12:26:28 -0500 Subject: [PATCH 19/33] FullCourseList: fix take desync --- components/FullCourseList.tsx | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/components/FullCourseList.tsx b/components/FullCourseList.tsx index c1b1a69..39d30b1 100644 --- a/components/FullCourseList.tsx +++ b/components/FullCourseList.tsx @@ -1,12 +1,11 @@ "use client"; import { Course, Prisma } from "@prisma/client"; -import prisma from "../lib/prisma"; import { useEffect, useState } from "react"; import CourseCard from "./CourseCard"; import React from "react"; -import { getCourses, getInitialCourses } from "../app/actions/getCourses"; +import { getCourses } from "../app/actions/getCourses"; import { useInView } from "react-intersection-observer"; import { Skeleton } from "@nextui-org/react"; @@ -33,15 +32,18 @@ export function FullCourseList({ const { ref, inView } = useInView(); const loadMoreUsers = async () => { - if (inView) { - setCursor((cursor) => cursor + NUMBER_OF_USERS_TO_FETCH); - setTake((take) => take + NUMBER_OF_USERS_TO_FETCH); - } + // NOTE: if this isn't done every time we get a double take and a + // race condition desync, breaking isDone. Maybe we'll have better + // logic in the future. + setCursor((cursor) => cursor + NUMBER_OF_USERS_TO_FETCH); + setTake((take) => take + NUMBER_OF_USERS_TO_FETCH); const apiCourses = await getCourses(take, cursor, query, term, dotw, stime); - console.log("apiCourses"); - console.log(apiCourses); - if (apiCourses.length == 0 || apiCourses.length == courses.length) { + if ( + inView && + (apiCourses.length == 0 || apiCourses.length == courses.length) + ) { + console.log("setting isDone true"); setIsDone(true); } else { setIsDone(false); From d9a35c4dd6de1fb888990ba5b626948203672603 Mon Sep 17 00:00:00 2001 From: Thomas Makin Date: Thu, 14 Nov 2024 14:07:19 -0500 Subject: [PATCH 20/33] scheduler: further improve mobile --- app/layout.tsx | 2 +- app/page.tsx | 4 ++-- components/CourseCard.tsx | 22 +++++++++++++--------- components/FullCourseList.tsx | 2 +- components/Search.tsx | 2 +- components/navbar.tsx | 6 +++--- 6 files changed, 21 insertions(+), 17 deletions(-) diff --git a/app/layout.tsx b/app/layout.tsx index d3312c9..fd0fe63 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -54,7 +54,7 @@ export default function RootLayout({ >
-
+
{children}
diff --git a/app/page.tsx b/app/page.tsx index bd6b6c6..1a79d07 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -116,9 +116,9 @@ async function Home(props: any) { return ( <> -
+
-
+
{props.fullCourseList} diff --git a/components/CourseCard.tsx b/components/CourseCard.tsx index aa7c01a..0e31c7a 100644 --- a/components/CourseCard.tsx +++ b/components/CourseCard.tsx @@ -100,8 +100,8 @@ export default function CourseCard(props: any) { )}
-
-
+
+
updatePlan(props.course)}> -
-
+
+
{props.course.facultyMeet.meetingTimes.room ? (
@@ -156,7 +156,7 @@ export default function CourseCard(props: any) {
) : (
-

+

Contact your Professor for additional details.

@@ -165,7 +165,7 @@ export default function CourseCard(props: any) {
{coloredDays}
-
+
Instructor
@@ -183,15 +183,19 @@ export default function CourseCard(props: any) { )}
{props.course.seatsAvailable == 0 ? ( -
-
+
+
No available seats left for this section
+ {/* Use shorter msg for mobile */} +
+ No seats +
) : (
-
+
Seats Available: {props.course.seatsAvailable}
diff --git a/components/FullCourseList.tsx b/components/FullCourseList.tsx index 39d30b1..8a8ac76 100644 --- a/components/FullCourseList.tsx +++ b/components/FullCourseList.tsx @@ -62,7 +62,7 @@ export function FullCourseList({ //const courseList: Course[] = await getCourses(query, term, dotw, stime); return ( <> -
+
{courses?.map((course: any) => (
diff --git a/components/Search.tsx b/components/Search.tsx index b67c279..0f35480 100644 --- a/components/Search.tsx +++ b/components/Search.tsx @@ -137,7 +137,7 @@ export default function Search(props: any) { }; return ( -
+
{ @@ -135,7 +135,7 @@ export const Navbar = (props: any) => { - + { {/* Mobile?*/} - +
{siteConfig.navItems.map((item, index) => ( From 8b27b7b50cdfd19b35a473c4ab1478c39e431ee0 Mon Sep 17 00:00:00 2001 From: Thomas Makin Date: Thu, 14 Nov 2024 14:49:25 -0500 Subject: [PATCH 21/33] CreatePlan: add auto scroller --- components/CreatePlan.tsx | 154 ++++++++++++++++++++++---------------- tailwind.config.js | 1 + 2 files changed, 89 insertions(+), 66 deletions(-) diff --git a/components/CreatePlan.tsx b/components/CreatePlan.tsx index f024d06..9705eb7 100644 --- a/components/CreatePlan.tsx +++ b/components/CreatePlan.tsx @@ -34,6 +34,7 @@ export default function CreatePlan(props: any) { const { data: session, status } = useSession(); const [coursePlanName, setCoursePlanName]: any = useState(""); const [selectedCoursePlan, setSelectedCoursePlan]: any = useState([]); + const [isScrolled, setIsScrolled] = useState(false); const fetcher = (url: any) => fetch(url).then((r) => r.json()); const { data, isLoading, error } = useSWR("/api/getplancourses", fetcher, { @@ -166,82 +167,103 @@ export default function CreatePlan(props: any) { }; const scrollToPlan = () => { - if (scrollRef.current) + console.log("A"); + if (scrollRef.current) { + console.log("B"); scrollRef.current.scrollIntoView({ behavior: "smooth", inline: "start" }); + setIsScrolled(true); + } + }; + + const scrollToTop = () => { + console.log("C"); + window.scrollTo({ + top: 0, + behavior: "smooth", + }); + setIsScrolled(false); }; return ( -
- {/*
-
Create a Plan
- -
*/} -
-
-
Create a Plan
-
- { - setCoursePlanName(event.target.value); - }} - /> - + <> + +
+
+
+
Create a Plan
+
+ { + setCoursePlanName(event.target.value); + }} + /> + +
-
-
- - {/* --------------------------------- or --------------------------- */} -
or
- -
+
+ + {/* --------------------------------- or --------------------------- */} +
or
+ +
-
-
Select a Plan
-
- - -
-
-
- +
+ +
-
+ ); } diff --git a/tailwind.config.js b/tailwind.config.js index 4832ba3..3d455c7 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -35,6 +35,7 @@ module.exports = { DEFAULT: "#9FADBC", foreground: "#1D2125", }, + secondary: "#F46523", focus: "#BEF264", }, }, From 277963f97a99747be7cdf08e2bc1f6190ec65927 Mon Sep 17 00:00:00 2001 From: Thomas Makin Date: Thu, 14 Nov 2024 15:26:39 -0500 Subject: [PATCH 22/33] CourseCard: minor fixes --- components/CourseCard.tsx | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/components/CourseCard.tsx b/components/CourseCard.tsx index 0e31c7a..46d1c84 100644 --- a/components/CourseCard.tsx +++ b/components/CourseCard.tsx @@ -1,5 +1,5 @@ "use client"; -import { Card, CardBody, CardHeader, Chip } from "@nextui-org/react"; +import { Card, CardBody, CardHeader, Chip, Divider } from "@nextui-org/react"; import Image from "next/image"; import { tv } from "tailwind-variants"; import axios from "axios"; @@ -69,7 +69,7 @@ export default function CourseCard(props: any) { if (item) { return ( -

{item.code}

+ {" " + item.code + " "}
); } @@ -94,9 +94,11 @@ export default function CourseCard(props: any) { {props.course.subject} {props.course.courseNumber} |{" "} {props.course.creditHours} credit(s) {props.course.sectionAttributes.length > 0 && ( -
-  | {attributeCodes} -
+ <> +
+  | {attributeCodes} +
+ )}
@@ -165,11 +167,11 @@ export default function CourseCard(props: any) {
{coloredDays}
-
+
-
Instructor
-
+
Instructor
+
{props.course.instructor.displayName.replace("'", "'")}
@@ -184,7 +186,7 @@ export default function CourseCard(props: any) {
{props.course.seatsAvailable == 0 ? (
-
+
No available seats left for this section
{/* Use shorter msg for mobile */} @@ -195,7 +197,7 @@ export default function CourseCard(props: any) {
) : (
-
+
Seats Available: {props.course.seatsAvailable}
From 6d215b1871c184e8417fbf32a67a593fb47eab9c Mon Sep 17 00:00:00 2001 From: Damian <37555910+DCRepublic@users.noreply.github.com> Date: Sun, 17 Nov 2024 14:12:32 -0500 Subject: [PATCH 23/33] Calendar: Format for mobile, Fix events to show course number, Add Footer info Auth: change to allow admin access again --- app/admin/page.tsx | 7 ++-- app/calendar/page.tsx | 14 +++++-- app/layout.tsx | 30 ++----------- app/page.tsx | 4 +- components/Calendar.tsx | 9 +++- components/CreatePlan.tsx | 10 +++-- components/FooterInfo.tsx | 88 +++++++++++++++++++++++++++++++++++++++ lib/auth.ts | 2 +- 8 files changed, 123 insertions(+), 41 deletions(-) create mode 100644 components/FooterInfo.tsx diff --git a/app/admin/page.tsx b/app/admin/page.tsx index 1d0af0b..482a547 100644 --- a/app/admin/page.tsx +++ b/app/admin/page.tsx @@ -94,14 +94,15 @@ export default function AdminPage() { return cellValue; } }, []); - + console.log(status); + console.log(session?.user); if (status === "authenticated") { if (session.user?.role === "admin") { return ( -
+
diff --git a/app/calendar/page.tsx b/app/calendar/page.tsx index 8c04e77..46bc057 100644 --- a/app/calendar/page.tsx +++ b/app/calendar/page.tsx @@ -18,7 +18,11 @@ export default async function CalendarPage() { id: parseInt(planCookie), }, include: { - courses: true, + courses: { + include: { + instructor: true, + }, + }, }, }); @@ -42,6 +46,8 @@ export default async function CalendarPage() { title: courses[i]?.courseTitle, daColor: color, subject: courses[i]?.subject, + courseNumber: courses[i]?.courseNumber, + instructor: courses[i]?.instructor.displayName, color: "rgba(0,0,0,0)", borderWidth: "0px", @@ -104,11 +110,11 @@ export default async function CalendarPage() { //let times = await getUniqueStartEndTimes(); return ( -
-
+
+
-
+
diff --git a/app/layout.tsx b/app/layout.tsx index fd0fe63..72cafba 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -8,6 +8,7 @@ import { NextAuthProvider } from "../components/providers/NextAuthProvider"; import { siteConfig } from "../config/site"; import { fontSans } from "../config/fonts"; import { Navbar } from "../components/navbar"; +import FooterInfo from "../components/FooterInfo"; import { Providers } from "./providers"; @@ -54,35 +55,10 @@ export default function RootLayout({ >
-
+
{children}
-
-
- - The Course Planner is a student-run service, and displays - classes from the Tri-College course database. We recommend - confirming your schedule with the official course listings - just in case. If there are any issues, email us. - -
- -
- - - Usage & Data Policy - - - - © 2024 Swarthmore College Computer Society | v2.0.0 - -
-
-
+
diff --git a/app/page.tsx b/app/page.tsx index 1a79d07..744fbb1 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -100,7 +100,7 @@ export default async function Page(props: { homePageProps["createPlan"] = ( + } > @@ -125,7 +125,7 @@ async function Home(props: any) {
-
+
diff --git a/components/Calendar.tsx b/components/Calendar.tsx index dd8b159..9e3c35a 100644 --- a/components/Calendar.tsx +++ b/components/Calendar.tsx @@ -32,9 +32,16 @@ export default function Calendar(props: any) { */} {eventInfo.timeText} -
+
+ {eventInfo.event.extendedProps.subject} {""} + {eventInfo.event.extendedProps.courseNumber} +
+
{eventInfo.event.title}
+
+ {eventInfo.event.extendedProps.instructor.replace("'", "'")} +
); } diff --git a/components/CreatePlan.tsx b/components/CreatePlan.tsx index 9705eb7..e23bfc0 100644 --- a/components/CreatePlan.tsx +++ b/components/CreatePlan.tsx @@ -145,9 +145,13 @@ export default function CreatePlan(props: any) { /> -
- {course.courseTitle.replace(/&/g, "&")} +
+ {course.subject} {""} {course.courseNumber} +
+ {course.courseTitle.replace(/&/g, "&")} +
+
diff --git a/components/FooterInfo.tsx b/components/FooterInfo.tsx new file mode 100644 index 0000000..afa804b --- /dev/null +++ b/components/FooterInfo.tsx @@ -0,0 +1,88 @@ +"use client"; + +import FullCalendar from "@fullcalendar/react"; +import timeGridPlugin from "@fullcalendar/timegrid"; // a plugin! +import InfoIcon from "@mui/icons-material/Info"; +import { + Button, + Card, + Link, + Modal, + ModalBody, + ModalContent, + ModalFooter, + ModalHeader, + useDisclosure, +} from "@nextui-org/react"; +import moment from "moment"; + +export default function FooterInfo(props: any) { + const { isOpen, onOpen, onClose } = useDisclosure(); + + const handleOpen = () => { + onOpen(); + }; + return ( + <> +
handleOpen()} + > + +
+ + + {(onClose) => ( + <> + + Usage & Data Policy + + +
+ + The Course Planner is a student-run service, and displays + classes from the Tri-College course database. We recommend + confirming your schedule with the official course listings + just in case. If there are any issues, + + + {" "} + + email us. + + +
+
+ +
+ + Usage & Data Policy + +
+
+ + © 2024 Swarthmore College Computer Society | v2.0.0 + +
+
+ + + + + )} +
+
+ + ); +} diff --git a/lib/auth.ts b/lib/auth.ts index d71addb..36790cd 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -76,7 +76,7 @@ export const config = { return token; }, async session({ session, token }) { - session.role = token.role; + session.user.role = token.role; session.user.id = token.sub || ""; return session; }, From a714f388793e50e8337b09f86b5a2aaa94a35bc6 Mon Sep 17 00:00:00 2001 From: Damian <37555910+DCRepublic@users.noreply.github.com> Date: Sun, 17 Nov 2024 14:42:45 -0500 Subject: [PATCH 24/33] Fix build error: --- components/FooterInfo.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/components/FooterInfo.tsx b/components/FooterInfo.tsx index afa804b..c50b958 100644 --- a/components/FooterInfo.tsx +++ b/components/FooterInfo.tsx @@ -25,6 +25,7 @@ export default function FooterInfo(props: any) { return ( <>
handleOpen()} > From 8257c44f2d26b21cafcccb64fa965f4bb3d68713 Mon Sep 17 00:00:00 2001 From: Damian <37555910+DCRepublic@users.noreply.github.com> Date: Sun, 17 Nov 2024 16:21:55 -0500 Subject: [PATCH 25/33] fix cal formatting --- app/calendar/page.tsx | 15 ++++++++++++--- components/Calendar.tsx | 17 +++++++++-------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/app/calendar/page.tsx b/app/calendar/page.tsx index 46bc057..03fc762 100644 --- a/app/calendar/page.tsx +++ b/app/calendar/page.tsx @@ -21,6 +21,11 @@ export default async function CalendarPage() { courses: { include: { instructor: true, + facultyMeet: { + include: { + meetingTimes: true, + }, + }, }, }, }, @@ -48,6 +53,10 @@ export default async function CalendarPage() { subject: courses[i]?.subject, courseNumber: courses[i]?.courseNumber, instructor: courses[i]?.instructor.displayName, + room: + courses[i]?.facultyMeet.meetingTimes.building + + " " + + courses[i]?.facultyMeet.meetingTimes.room, color: "rgba(0,0,0,0)", borderWidth: "0px", @@ -110,11 +119,11 @@ export default async function CalendarPage() { //let times = await getUniqueStartEndTimes(); return ( -
-
+
+
-
+
diff --git a/components/Calendar.tsx b/components/Calendar.tsx index 83b44df..2274217 100644 --- a/components/Calendar.tsx +++ b/components/Calendar.tsx @@ -15,7 +15,7 @@ export default function Calendar(props: any) { return ( {/* @@ -31,14 +31,15 @@ export default function Calendar(props: any) { /> */} - {eventInfo.timeText} -
- {eventInfo.event.extendedProps.subject} {""} - {eventInfo.event.extendedProps.courseNumber} -
-
- {eventInfo.event.title} + + {eventInfo.timeText} {"|"} {eventInfo.event.extendedProps.room} + +
+ {eventInfo.event.extendedProps.subject} + {eventInfo.event.extendedProps.courseNumber} : +

{eventInfo.event.title}

+
{eventInfo.event.extendedProps.instructor.replace("'", "'")}
From dc700a387f55115d254f8588677b7caa291235cc Mon Sep 17 00:00:00 2001 From: Thomas Makin Date: Mon, 18 Nov 2024 11:38:25 -0500 Subject: [PATCH 26/33] calendar: make start/end dynamic also fix ts --- app/calendar/page.tsx | 185 ++++++++++++++++++++-------------------- components/Calendar.tsx | 51 ++++++----- 2 files changed, 115 insertions(+), 121 deletions(-) diff --git a/app/calendar/page.tsx b/app/calendar/page.tsx index 03fc762..5acf8c8 100644 --- a/app/calendar/page.tsx +++ b/app/calendar/page.tsx @@ -5,123 +5,120 @@ import Calendar from "../../components/Calendar"; import prisma from "../../lib/prisma"; import { getPlanCookie } from "../actions/actions"; import { generateColorFromName } from "../../components/primitives"; -export default async function CalendarPage() { - async function getEvents() { - const output: any = []; - const planCookie: any = await getPlanCookie(); - let courses; +interface Event { + classNames: string; + textColor: string; + title: string; + daColor: string; + subject: string; + courseNumber: string; + instructor: string; + room: string; + color: string; + borderWidth: string; + daysOfWeek: (false | "0" | "1" | "2" | "3" | "4" | "5" | "6" | undefined)[]; + startTime: string; + endTime: string; +} - if (planCookie) { - const plan = await prisma.coursePlan.findUnique({ - where: { - id: parseInt(planCookie), - }, - include: { - courses: { - include: { - instructor: true, - facultyMeet: { - include: { - meetingTimes: true, - }, +async function getEvents(): Promise { + "use server"; + const output: Event[] = []; + const planCookie: any = await getPlanCookie(); + + let courses; + + if (planCookie) { + const plan = await prisma.coursePlan.findUnique({ + where: { + id: parseInt(planCookie), + }, + include: { + courses: { + include: { + instructor: true, + facultyMeet: { + include: { + meetingTimes: true, }, }, }, }, - }); + }, + }); - courses = plan?.courses; - } + courses = plan?.courses; + } - if (courses) { - for (let i = 0; i < courses.length; i++) { - const color = generateColorFromName(courses[i].subject); + if (courses) { + for (let i = 0; i < courses.length; i++) { + const color = generateColorFromName(courses[i].subject); - const num: string = courses[i].courseReferenceNumber; - const meetingTimes = await prisma.meetingTime.findFirst({ - where: { - courseReferenceNumber: num, - }, - }); + const num: string = courses[i].courseReferenceNumber; + const meetingTimes = await prisma.meetingTime.findFirst({ + where: { + courseReferenceNumber: num, + }, + }); - output.push({ - classNames: "font-sans", - textColor: "white", - title: courses[i]?.courseTitle, - daColor: color, - subject: courses[i]?.subject, - courseNumber: courses[i]?.courseNumber, - instructor: courses[i]?.instructor.displayName, - room: - courses[i]?.facultyMeet.meetingTimes.building + - " " + - courses[i]?.facultyMeet.meetingTimes.room, - color: "rgba(0,0,0,0)", + output.push({ + classNames: "font-sans", + textColor: "white", + title: courses[i]?.courseTitle, + daColor: color, + subject: courses[i]?.subject, + courseNumber: courses[i]?.courseNumber, + instructor: courses[i]?.instructor.displayName, + room: + courses[i]?.facultyMeet.meetingTimes.building + + " " + + courses[i]?.facultyMeet.meetingTimes.room, + color: "rgba(0,0,0,0)", - borderWidth: "0px", - daysOfWeek: [ - meetingTimes?.sunday && "0", - meetingTimes?.monday && "1", - meetingTimes?.tuesday && "2", - meetingTimes?.wednesday && "3", - meetingTimes?.thursday && "4", - meetingTimes?.friday && "5", - meetingTimes?.saturday && "6", - ], + borderWidth: "0px", + daysOfWeek: [ + meetingTimes?.sunday && "0", + meetingTimes?.monday && "1", + meetingTimes?.tuesday && "2", + meetingTimes?.wednesday && "3", + meetingTimes?.thursday && "4", + meetingTimes?.friday && "5", + meetingTimes?.saturday && "6", + ], - startTime: - meetingTimes?.beginTime.slice(0, 2) + - ":" + - meetingTimes?.beginTime.slice(2), - endTime: - meetingTimes?.endTime.slice(0, 2) + - ":" + - meetingTimes?.endTime.slice(2), - }); - } + startTime: + meetingTimes?.beginTime.slice(0, 2) + + ":" + + meetingTimes?.beginTime.slice(2), + endTime: + meetingTimes?.endTime.slice(0, 2) + + ":" + + meetingTimes?.endTime.slice(2), + }); } - - return output; } - async function getUniqueStartEndTimes() { - const maxstart = await prisma.meetingTime.findFirst({ - where: { - beginTime: { not: "" }, - }, - orderBy: { - beginTime: "desc", - }, - }); - const maxend = await prisma.meetingTime.findFirst({ - where: { - endTime: { not: "" }, - }, - orderBy: { - beginTime: "desc", - }, - }); + return output; +} - /* - let times = { - minTime: - maxstart?.beginTime.slice(0, 2) + ":" + maxstart?.beginTime.slice(2), - maxTime: - maxstart?.endTime.slice(0, 2) + ":" + maxstart?.beginTime.slice(2), - };*/ - console.log(maxstart); +export default async function CalendarPage() { + const events: Event[] = await getEvents(); + let endTime = "17:00"; + let startTime = "09:00"; - return maxstart; + for (const event of events) { + if (event.startTime < startTime && event.startTime != ":") + startTime = event.startTime; + if (event.endTime > endTime && event.endTime != ":") + endTime = event.endTime; } - const events = await getEvents(); - //let times = await getUniqueStartEndTimes(); return (
- +
diff --git a/components/Calendar.tsx b/components/Calendar.tsx index 2274217..4150c36 100644 --- a/components/Calendar.tsx +++ b/components/Calendar.tsx @@ -1,49 +1,46 @@ "use client"; +import { + DayHeaderContentArg, + EventContentArg, + EventSourceInput, +} from "@fullcalendar/core"; import FullCalendar from "@fullcalendar/react"; import timeGridPlugin from "@fullcalendar/timegrid"; // a plugin! import { Card } from "@nextui-org/react"; import moment from "moment"; -export default function Calendar(props: any) { - function dayHeaderContent(args: any) { +export default function Calendar({ + events, + startTime, + endTime, +}: { + events: EventSourceInput | undefined; + startTime: string; + endTime: string; +}) { + function dayHeaderContent(args: DayHeaderContentArg) { return moment(args.date).format("ddd"); } - function renderEventContent(eventInfo: any) { - console.log(eventInfo); - + function renderEventContent(eventInfo: EventContentArg) { return ( - {/* - - -
- */} - - + {eventInfo.timeText} {"|"} {eventInfo.event.extendedProps.room} -
+
{eventInfo.event.extendedProps.subject} {eventInfo.event.extendedProps.courseNumber} :

{eventInfo.event.title}

-
+
{eventInfo.event.extendedProps.instructor.replace("'", "'")}
- ); } @@ -52,17 +49,17 @@ export default function Calendar(props: any) { ); From 5f2b138d80ab9aa94ed2a250a54b4eb682499a95 Mon Sep 17 00:00:00 2001 From: Thomas Makin Date: Mon, 18 Nov 2024 11:43:43 -0500 Subject: [PATCH 27/33] FooterInfo: update spec Also rebrand and bump packs --- components/FooterInfo.tsx | 14 ++- package-lock.json | 211 ++++++++++++++++++-------------------- package.json | 4 +- 3 files changed, 110 insertions(+), 119 deletions(-) diff --git a/components/FooterInfo.tsx b/components/FooterInfo.tsx index c50b958..6ac8dd9 100644 --- a/components/FooterInfo.tsx +++ b/components/FooterInfo.tsx @@ -1,11 +1,8 @@ "use client"; -import FullCalendar from "@fullcalendar/react"; -import timeGridPlugin from "@fullcalendar/timegrid"; // a plugin! import InfoIcon from "@mui/icons-material/Info"; import { Button, - Card, Link, Modal, ModalBody, @@ -14,9 +11,9 @@ import { ModalHeader, useDisclosure, } from "@nextui-org/react"; -import moment from "moment"; +import packageInfo from "../package.json"; -export default function FooterInfo(props: any) { +export default function FooterInfo() { const { isOpen, onOpen, onClose } = useDisclosure(); const handleOpen = () => { @@ -52,7 +49,7 @@ export default function FooterInfo(props: any) { isExternal className="text-[#f46523]" href="mailto:staff@sccs.swarthmore.edu" - title="Sccs Staff Email" + title="SCCS Staff Email" > email us. @@ -70,8 +67,9 @@ export default function FooterInfo(props: any) {

- - © 2024 Swarthmore College Computer Society | v2.0.0 + + © 2024 Swarthmore College Computer Society | v + {packageInfo.version}
diff --git a/package-lock.json b/package-lock.json index e16419f..9b6347f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { - "name": "next-app-template", - "version": "0.0.1", + "name": "scheduler", + "version": "2.0.0-beta", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "next-app-template", - "version": "0.0.1", + "name": "scheduler", + "version": "2.0.0-beta", "dependencies": { "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", @@ -425,9 +425,9 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", - "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.0.tgz", + "integrity": "sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==", "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^2.1.4", @@ -439,18 +439,18 @@ } }, "node_modules/@eslint/core": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", - "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.0.tgz", + "integrity": "sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==", "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", "license": "MIT", "dependencies": { "ajv": "^6.12.4", @@ -483,9 +483,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.14.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.14.0.tgz", - "integrity": "sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==", + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.15.0.tgz", + "integrity": "sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -501,9 +501,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.2.tgz", - "integrity": "sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", + "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", "license": "Apache-2.0", "dependencies": { "levn": "^0.4.1" @@ -513,13 +513,13 @@ } }, "node_modules/@formatjs/ecma402-abstract": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.3.tgz", - "integrity": "sha512-aElGmleuReGnk2wtYOzYFmNWYoiWWmf1pPPCYg0oiIQSJj0mjc4eUfzUXaSOJ4S8WzI/cLqnCTWjqz904FT2OQ==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.2.4.tgz", + "integrity": "sha512-lFyiQDVvSbQOpU+WFd//ILolGj4UgA/qXrKeZxdV14uKiAUiPAtX6XAn7WBCRi7Mx6I7EybM9E5yYn4BIpZWYg==", "license": "MIT", "dependencies": { "@formatjs/fast-memoize": "2.2.3", - "@formatjs/intl-localematcher": "0.5.7", + "@formatjs/intl-localematcher": "0.5.8", "tslib": "2" } }, @@ -533,30 +533,30 @@ } }, "node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.3.tgz", - "integrity": "sha512-9L99QsH14XjOCIp4TmbT8wxuffJxGK8uLNO1zNhLtcZaVXvv626N0s4A2qgRCKG3dfYWx9psvGlFmvyVBa6u/w==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.9.4.tgz", + "integrity": "sha512-Tbvp5a9IWuxUcpWNIW6GlMQYEc4rwNHR259uUFoKWNN1jM9obf9Ul0e+7r7MvFOBNcN+13K7NuKCKqQiAn1QEg==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.2.3", - "@formatjs/icu-skeleton-parser": "1.8.7", + "@formatjs/ecma402-abstract": "2.2.4", + "@formatjs/icu-skeleton-parser": "1.8.8", "tslib": "2" } }, "node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.7", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.7.tgz", - "integrity": "sha512-fI+6SmS2g7h3srfAKSWa5dwreU5zNEfon2uFo99OToiLF6yxGE+WikvFSbsvMAYkscucvVmTYNlWlaDPp0n5HA==", + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.8.tgz", + "integrity": "sha512-vHwK3piXwamFcx5YQdCdJxUQ1WdTl6ANclt5xba5zLGDv5Bsur7qz8AD7BevaKxITwpgDeU0u8My3AIibW9ywA==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.2.3", + "@formatjs/ecma402-abstract": "2.2.4", "tslib": "2" } }, "node_modules/@formatjs/intl-localematcher": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.7.tgz", - "integrity": "sha512-GGFtfHGQVFe/niOZp24Kal5b2i36eE2bNL0xi9Sg/yd0TR8aLjcteApZdHmismP5QQax1cMnZM9yWySUUjJteA==", + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.8.tgz", + "integrity": "sha512-I+WDNWWJFZie+jkfkiK5Mp4hEDyRSEvmyfYadflOno/mmKJKcB17fEpEH0oJu/OWhhCJ8kJBDz2YMd/6cDl7Mg==", "license": "MIT", "dependencies": { "tslib": "2" @@ -1128,9 +1128,9 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.6.tgz", - "integrity": "sha512-nz1SlR9TdBYYPz4qKoNasMPRiGb4PaIHFkzLzhju0YVYS5QSuFF2+n7CsiHMIDcHv3piPu/xDWI53ruhOqvZwQ==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.7.tgz", + "integrity": "sha512-POuIBi80BZBogQkG4PQKIGwy4QFwB+kOr+OI4k7Znh7LqMAIhwB9OC00l6M+w1GrZJYj3T8R5WX8G6QAIvoVEw==", "license": "MIT", "peer": true, "funding": { @@ -1139,9 +1139,9 @@ } }, "node_modules/@mui/icons-material": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.1.6.tgz", - "integrity": "sha512-5r9urIL2lxXb/sPN3LFfFYEibsXJUb986HhhIeu1gOcte460pwdSiEhBSxkAuyT8Dj7jvu9MjqSBmSumQELo8A==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-6.1.7.tgz", + "integrity": "sha512-RGzkeHNArIVy5ZQ12bq/8VYNeICEyngngsFskTJ/2hYKhIeIII3iRGtaZaSvLpXh7h3Fg3VKTulT+QU0w5K4XQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.26.0" @@ -1154,7 +1154,7 @@ "url": "https://opencollective.com/mui-org" }, "peerDependencies": { - "@mui/material": "^6.1.6", + "@mui/material": "^6.1.7", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0" }, @@ -1165,17 +1165,17 @@ } }, "node_modules/@mui/material": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.6.tgz", - "integrity": "sha512-1yvejiQ/601l5AK3uIdUlAVElyCxoqKnl7QA+2oFB/2qYPWfRwDgavW/MoywS5Y2gZEslcJKhe0s2F3IthgFgw==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-6.1.7.tgz", + "integrity": "sha512-KsjujQL/A2hLd1PV3QboF+W6SSL5QqH6ZlSuQoeYz9r69+TnyBFIevbYLxdjJcJmGBjigL5pfpn7hTGop+vhSg==", "license": "MIT", "peer": true, "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/core-downloads-tracker": "^6.1.6", - "@mui/system": "^6.1.6", + "@mui/core-downloads-tracker": "^6.1.7", + "@mui/system": "^6.1.7", "@mui/types": "^7.2.19", - "@mui/utils": "^6.1.6", + "@mui/utils": "^6.1.7", "@popperjs/core": "^2.11.8", "@types/react-transition-group": "^4.4.11", "clsx": "^2.1.1", @@ -1194,7 +1194,7 @@ "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material-pigment-css": "^6.1.6", + "@mui/material-pigment-css": "^6.1.7", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" @@ -1215,14 +1215,14 @@ } }, "node_modules/@mui/private-theming": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.6.tgz", - "integrity": "sha512-ioAiFckaD/fJSnTrUMWgjl9HYBWt7ixCh7zZw7gDZ+Tae7NuprNV6QJK95EidDT7K0GetR2rU3kAeIR61Myttw==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-6.1.7.tgz", + "integrity": "sha512-uLbfUSsug5K0LVkv0PI6Flste3le8+6WSL2omdTiYde93P89Qr7pKr8TA6d2yXfr+Bm+SvD8/fGnkaRwFkryuQ==", "license": "MIT", "peer": true, "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/utils": "^6.1.6", + "@mui/utils": "^6.1.7", "prop-types": "^15.8.1" }, "engines": { @@ -1243,9 +1243,9 @@ } }, "node_modules/@mui/styled-engine": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.6.tgz", - "integrity": "sha512-I+yS1cSuSvHnZDBO7e7VHxTWpj+R7XlSZvTC4lS/OIbUNJOMMSd3UDP6V2sfwzAdmdDNBi7NGCRv2SZ6O9hGDA==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-6.1.7.tgz", + "integrity": "sha512-Ou4CxN7MQmwrfG1Pu6EYjPgPChQXxPDJrwgizLXlRPOad5qAq4gYXRuzrGQ2DfGjjwmJhjI8T6A0SeapAZPGig==", "license": "MIT", "peer": true, "dependencies": { @@ -1278,17 +1278,17 @@ } }, "node_modules/@mui/system": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.6.tgz", - "integrity": "sha512-qOf1VUE9wK8syiB0BBCp82oNBAVPYdj4Trh+G1s+L+ImYiKlubWhhqlnvWt3xqMevR+D2h1CXzA1vhX2FvA+VQ==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-6.1.7.tgz", + "integrity": "sha512-qbMGgcC/FodpuRSfjXlEDdbNQaW++eATh0vNBcPUv2/YXSpReoOpoT9FhogxEBNks+aQViDXBRZKh6HX2fVmwg==", "license": "MIT", "peer": true, "dependencies": { "@babel/runtime": "^7.26.0", - "@mui/private-theming": "^6.1.6", - "@mui/styled-engine": "^6.1.6", + "@mui/private-theming": "^6.1.7", + "@mui/styled-engine": "^6.1.7", "@mui/types": "^7.2.19", - "@mui/utils": "^6.1.6", + "@mui/utils": "^6.1.7", "clsx": "^2.1.1", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -1334,9 +1334,9 @@ } }, "node_modules/@mui/utils": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.6.tgz", - "integrity": "sha512-sBS6D9mJECtELASLM+18WUcXF6RH3zNxBRFeyCRg8wad6NbyNrdxLuwK+Ikvc38sTZwBzAz691HmSofLqHd9sQ==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-6.1.7.tgz", + "integrity": "sha512-Gr7cRZxBoZ0BIa3Xqf/2YaUrBLyNPJvXPQH3OsD9WMZukI/TutibbQBVqLYpgqJn8pKSjbD50Yq2auG0wI1xOw==", "license": "MIT", "peer": true, "dependencies": { @@ -6088,9 +6088,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", - "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -6309,9 +6309,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.56", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.56.tgz", - "integrity": "sha512-7lXb9dAvimCFdvUMTyucD4mnIndt/xhRKFAlky0CyFogdnNmdPQNoHI23msF/2V4mpTxMzgMdjK4+YRlFlRQZw==", + "version": "1.5.62", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.62.tgz", + "integrity": "sha512-t8c+zLmJHa9dJy96yBZRXGQYoiCEnHYgFwn1asvSPZSUdVxnB62A4RASd7k41ytG3ErFBA0TpHlKg9D9SQBmLg==", "license": "ISC" }, "node_modules/emoji-regex": { @@ -6343,9 +6343,9 @@ } }, "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "version": "1.23.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.5.tgz", + "integrity": "sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==", "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", @@ -6363,7 +6363,7 @@ "function.prototype.name": "^1.1.6", "get-intrinsic": "^1.2.4", "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", + "globalthis": "^1.0.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", @@ -6379,10 +6379,10 @@ "is-string": "^1.0.7", "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "object-inspect": "^1.13.3", "object-keys": "^1.1.1", "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", + "regexp.prototype.flags": "^1.5.3", "safe-array-concat": "^1.1.2", "safe-regex-test": "^1.0.3", "string.prototype.trim": "^1.2.9", @@ -6523,26 +6523,26 @@ } }, "node_modules/eslint": { - "version": "9.14.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.14.0.tgz", - "integrity": "sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==", + "version": "9.15.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.15.0.tgz", + "integrity": "sha512-7CrWySmIibCgT1Os28lUU6upBshZ+GxybLOrmRzi08kS8MBuO8QA7pXEgYgY5W8vK3e74xv0lpjo9DbaGU9Rkw==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.18.0", - "@eslint/core": "^0.7.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.14.0", - "@eslint/plugin-kit": "^0.2.0", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.9.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.15.0", + "@eslint/plugin-kit": "^0.2.3", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.0", + "@humanwhocodes/retry": "^0.4.1", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.5", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", @@ -6561,8 +6561,7 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" @@ -7224,9 +7223,9 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", "license": "ISC" }, "node_modules/follow-redirects": { @@ -7302,9 +7301,9 @@ } }, "node_modules/framer-motion": { - "version": "11.11.12", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.12.tgz", - "integrity": "sha512-FC+efAcn62h6tXpeclgsekrpATdkIAa3+MffG2W2OLae0c7MV2NKgOcrwmScPKDg7qgyZC8Rqu36/4n5inMBtA==", + "version": "11.11.17", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.17.tgz", + "integrity": "sha512-O8QzvoKiuzI5HSAHbcYuL6xU+ZLXbrH7C8Akaato4JzQbX2ULNeniqC2Vo5eiCtFktX9XsJ+7nUhxcl2E2IjpA==", "license": "MIT", "dependencies": { "tslib": "^2.4.0" @@ -7687,14 +7686,14 @@ } }, "node_modules/intl-messageformat": { - "version": "10.7.6", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.6.tgz", - "integrity": "sha512-IsMU/hqyy3FJwNJ0hxDfY2heJ7MteSuFvcnCebxRp67di4Fhx1gKKE+qS0bBwUF8yXkX9SsPUhLeX/B6h5SKUA==", + "version": "10.7.7", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.7.tgz", + "integrity": "sha512-F134jIoeYMro/3I0h08D0Yt4N9o9pjddU/4IIxMMURqbAtI2wu70X8hvG1V48W49zXHXv3RKSF/po+0fDfsGjA==", "license": "BSD-3-Clause", "dependencies": { - "@formatjs/ecma402-abstract": "2.2.3", + "@formatjs/ecma402-abstract": "2.2.4", "@formatjs/fast-memoize": "2.2.3", - "@formatjs/icu-messageformat-parser": "2.9.3", + "@formatjs/icu-messageformat-parser": "2.9.4", "tslib": "2" } }, @@ -9417,9 +9416,9 @@ } }, "node_modules/react-textarea-autosize": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.4.tgz", - "integrity": "sha512-eSSjVtRLcLfFwFcariT77t9hcbVJHQV76b51QjQGarQIHml2+gM2lms0n3XrhnDmgK5B+/Z7TmQk5OHNzqYm/A==", + "version": "8.5.5", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.5.tgz", + "integrity": "sha512-CVA94zmfp8m4bSHtWwmANaBR8EPsKy2aZ7KwqhoS4Ftib87F9Kvi7XQhOixypPLMc6kVYgOXvKFuuzZDpHGRPg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.20.13", @@ -10248,12 +10247,6 @@ "node": ">=6" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "license": "MIT" - }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", diff --git a/package.json b/package.json index cec1232..46fab0b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "next-app-template", - "version": "0.0.1", + "name": "scheduler", + "version": "2.0.0-beta", "private": true, "scripts": { "dev": "next dev", From 1da470823d2fe828486ca5b26b7392e567b890af Mon Sep 17 00:00:00 2001 From: Thomas Makin Date: Mon, 18 Nov 2024 11:48:41 -0500 Subject: [PATCH 28/33] CreatePlan: align text in cards --- components/CreatePlan.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/components/CreatePlan.tsx b/components/CreatePlan.tsx index f19f2db..9e8772d 100644 --- a/components/CreatePlan.tsx +++ b/components/CreatePlan.tsx @@ -131,7 +131,7 @@ export default function CreatePlan(props: any) { -
{course.subject} {""} {course.courseNumber}
{course.courseTitle.replace(/&/g, "&")}
-