-
- {props.course.facultyMeet.meetingTimes.buildingDescription}{" "}
- {props.course.facultyMeet.meetingTimes.room}
-
-
- {props.course.facultyMeet.meetingTimes ? (
-
-
- {" "}
- {props.course.facultyMeet.meetingTimes.beginTime.slice(0, 2) +
- ":" +
- props.course.facultyMeet.meetingTimes.beginTime.slice(2)}{" "}
- -{" "}
- {props.course.facultyMeet.meetingTimes.endTime.slice(0, 2) +
- ":" +
- props.course.facultyMeet.meetingTimes.endTime.slice(2)}
-
-
- ) : null}
+ {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(
+ 0,
+ 2
+ ) +
+ ":" +
+ props.course.facultyMeet.meetingTimes.beginTime.slice(
+ 2
+ )}{" "}
+ -{" "}
+ {props.course.facultyMeet.meetingTimes.endTime.slice(
+ 0,
+ 2
+ ) +
+ ":" +
+ props.course.facultyMeet.meetingTimes.endTime.slice(
+ 2
+ )}
+
+
+ ) : null}
+
-
) :
-
Contact your Professor for additional details.
-
}
-
-
- {coloredDays}
+ ) : (
+
+
+ Contact your Professor for additional details.
+
+ )}
+
-
Instructor
-
{props.course.instructor.displayName}
+
Instructor
+
+ {props.course.instructor.displayName.replace("'", "'")}
+
- {props.course.seatsAvailable >= 0 &&
-
No available seats left for this section
-
-
}
+ {props.course.seatsAvailable >= 0 && (
+
+
+ No available seats left for this section
+
+ {/*
+ */}
+
+ )}
diff --git a/package-lock.json b/package-lock.json
index dab83bd..a175baa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -55,6 +55,7 @@
"next-client-cookies": "^2.0.0",
"next-themes": "^0.3.0",
"postcss": "8.4.47",
+ "prisma": "^5.22.0",
"react": "18.3.1",
"react-dom": "18.3.1",
"swr": "^2.2.5",
@@ -3167,6 +3168,51 @@
}
}
},
+ "node_modules/@prisma/debug": {
+ "version": "5.22.0",
+ "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.22.0.tgz",
+ "integrity": "sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@prisma/engines": {
+ "version": "5.22.0",
+ "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.22.0.tgz",
+ "integrity": "sha512-UNjfslWhAt06kVL3CjkuYpHAWSO6L4kDCVPegV6itt7nD1kSJavd3vhgAEhjglLJJKEdJ7oIqDJ+yHk6qO8gPA==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "5.22.0",
+ "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2",
+ "@prisma/fetch-engine": "5.22.0",
+ "@prisma/get-platform": "5.22.0"
+ }
+ },
+ "node_modules/@prisma/engines-version": {
+ "version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2",
+ "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2.tgz",
+ "integrity": "sha512-2PTmxFR2yHW/eB3uqWtcgRcgAbG1rwG9ZriSvQw+nnb7c4uCr3RAcGMb6/zfE88SKlC1Nj2ziUvc96Z379mHgQ==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@prisma/fetch-engine": {
+ "version": "5.22.0",
+ "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.22.0.tgz",
+ "integrity": "sha512-bkrD/Mc2fSvkQBV5EpoFcZ87AvOgDxbG99488a5cexp5Ccny+UM6MAe/UFkUC0wLYD9+9befNOqGiIJhhq+HbA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "5.22.0",
+ "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2",
+ "@prisma/get-platform": "5.22.0"
+ }
+ },
+ "node_modules/@prisma/get-platform": {
+ "version": "5.22.0",
+ "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.22.0.tgz",
+ "integrity": "sha512-pHhpQdr1UPFpt+zFfnPazhulaZYCUqeIcPpJViYoq9R+D/yw4fjE+CtnsnKzPYm0ddUbeXUzjGVGIRVgPDCk4Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/debug": "5.22.0"
+ }
+ },
"node_modules/@react-aria/breadcrumbs": {
"version": "3.5.13",
"resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.13.tgz",
@@ -9125,6 +9171,25 @@
"integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==",
"license": "MIT"
},
+ "node_modules/prisma": {
+ "version": "5.22.0",
+ "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.22.0.tgz",
+ "integrity": "sha512-vtpjW3XuYCSnMsNVBjLMNkTj6OZbudcPPTPYHqX0CJfpcdWciI1dM8uHETwmDxxiqEwCIE6WvXucWUetJgfu/A==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@prisma/engines": "5.22.0"
+ },
+ "bin": {
+ "prisma": "build/index.js"
+ },
+ "engines": {
+ "node": ">=16.13"
+ },
+ "optionalDependencies": {
+ "fsevents": "2.3.3"
+ }
+ },
"node_modules/prop-types": {
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
diff --git a/package.json b/package.json
index 0b8d7dd..e01c71a 100644
--- a/package.json
+++ b/package.json
@@ -56,6 +56,7 @@
"next-client-cookies": "^2.0.0",
"next-themes": "^0.3.0",
"postcss": "8.4.47",
+ "prisma": "^5.22.0",
"react": "18.3.1",
"react-dom": "18.3.1",
"swr": "^2.2.5",
diff --git a/prisma/migrations/20241109035411_add_ratings/migration.sql b/prisma/migrations/20241109035411_add_ratings/migration.sql
new file mode 100644
index 0000000..48546e8
--- /dev/null
+++ b/prisma/migrations/20241109035411_add_ratings/migration.sql
@@ -0,0 +1,29 @@
+-- AlterTable
+ALTER TABLE "Course" ADD COLUMN "avgRating" DOUBLE PRECISION;
+
+-- AlterTable
+ALTER TABLE "Faculty" ADD COLUMN "avgRating" DOUBLE PRECISION;
+
+-- CreateTable
+CREATE TABLE "Rating" (
+ "id" SERIAL NOT NULL,
+ "courseID" INTEGER NOT NULL,
+ "facultyID" INTEGER NOT NULL,
+ "overallRating" INTEGER,
+ "quality" INTEGER,
+ "difficulty" INTEGER,
+ "takeAgain" BOOLEAN,
+ "review" TEXT,
+ "grade" TEXT,
+ "forCredit" BOOLEAN,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "Rating_pkey" PRIMARY KEY ("id")
+);
+
+-- AddForeignKey
+ALTER TABLE "Rating" ADD CONSTRAINT "Rating_facultyID_fkey" FOREIGN KEY ("facultyID") REFERENCES "Faculty"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Rating" ADD CONSTRAINT "Rating_courseID_fkey" FOREIGN KEY ("courseID") REFERENCES "Course"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
diff --git a/prisma/migrations/20241109040421_add_ratings1/migration.sql b/prisma/migrations/20241109040421_add_ratings1/migration.sql
new file mode 100644
index 0000000..9d1f188
--- /dev/null
+++ b/prisma/migrations/20241109040421_add_ratings1/migration.sql
@@ -0,0 +1,5 @@
+-- AlterTable
+ALTER TABLE "Rating" ADD COLUMN "userId" INTEGER;
+
+-- AddForeignKey
+ALTER TABLE "Rating" ADD CONSTRAINT "Rating_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 98731af..b217798 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -1,6 +1,6 @@
generator client {
provider = "prisma-client-js"
- previewFeatures = ["fullTextSearch", "relationJoins", "strictUndefinedChecks","fullTextIndex"]
+ previewFeatures = ["fullTextIndex", "fullTextSearch", "relationJoins", "strictUndefinedChecks"]
}
datasource db {
@@ -9,20 +9,21 @@ datasource db {
}
model User {
- id Int @id @default(autoincrement())
- uuid String @unique
- email String @unique
- name String?
- plans CoursePlan[]
+ 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?
- courses Course[]
- User User? @relation(fields: [userId], references: [id])
year String
+ User User? @relation(fields: [userId], references: [id])
+ courses Course[] @relation("CourseToCoursePlan")
}
model Course {
@@ -41,11 +42,14 @@ model Course {
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[]
- year String
+ CoursePlan CoursePlan[] @relation("CourseToCoursePlan")
+
@@index([subject, courseNumber], map: "subj_course")
}
@@ -55,8 +59,10 @@ model Faculty {
courseReferenceNumber String @unique
displayName String
emailAddress String
- courses Course[]
year String
+ avgRating Float?
+ courses Course[]
+ Rating Rating[]
}
model MeetingsFaculty {
@@ -64,21 +70,19 @@ model MeetingsFaculty {
category String
courseReferenceNumber String @unique
meetingTimeID Int
+ year String
courses Course[]
meetingTimes MeetingTime @relation(fields: [meetingTimeID], references: [id])
- year String
}
model MeetingTime {
id Int @id @default(autoincrement())
- beginTime String
building String
buildingDescription String
room String
category String
courseReferenceNumber String @unique
endDate String
- endTime String
startDate String
hoursWeek Float
meetingType String
@@ -90,16 +94,37 @@ model MeetingTime {
friday Boolean
saturday Boolean
sunday Boolean
- facultyMeet MeetingsFaculty[]
year String
+ beginTime String
+ endTime String
+ facultyMeet MeetingsFaculty[]
}
model sectionAttribute {
- id Int @id @default(autoincrement())
+ id Int @id @default(autoincrement())
code String
description String
- courseReferenceNumber String @unique
- courseId Int
- Course Course? @relation(fields: [courseId], references: [id])
+ 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?
+ quality Int?
+ difficulty Int?
+ takeAgain Boolean?
+ review String?
+ grade String?
+ forCredit Boolean?
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ course Course @relation(fields: [courseID], references: [id])
+ faculty Faculty @relation(fields: [facultyID], references: [id])
+ User User? @relation(fields: [userId], references: [id])
+ userId Int?
}
diff --git a/swatscraper b/swatscraper
index 32a5d97..6089f91 160000
--- a/swatscraper
+++ b/swatscraper
@@ -1 +1 @@
-Subproject commit 32a5d975a8cbe906764c553846d220de1f0ed4ab
+Subproject commit 6089f9194726570223d8d85018e2a4377925366b