From df8e3799af2ba964a94ee17e526bf1be095b586a Mon Sep 17 00:00:00 2001 From: Blizzyboii Date: Fri, 5 Sep 2025 20:14:46 -0500 Subject: [PATCH 1/3] api integration --- src/app/components/courses.js | 53 ++++++++++++++++++++++++++++++----- src/app/utils/api.js | 18 ++++++++++++ 2 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 src/app/utils/api.js diff --git a/src/app/components/courses.js b/src/app/components/courses.js index 26f3139..70bafb3 100644 --- a/src/app/components/courses.js +++ b/src/app/components/courses.js @@ -1,17 +1,56 @@ -import React from 'react' +"use client"; +import React, {useState, useEffect} from 'react' import CourseCard from './coursecard' -import data from '../data.json' +import { nebulaFetch } from '../utils/api' function Courses() { + const [courses, setCourses] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + async function fetchCourses() { + try { + console.log("Starting fetch.."); + const apiResponse = await nebulaFetch('course/all'); // gets all courses + console.log("After fetch"); + console.log("API Response:" , apiResponse); + setCourses(apiResponse.data || []); + } catch (err) { + console.error("API error: ", err); + setError(err.message); + } finally { + setLoading(false); + } + } + fetchCourses(); + }, []); + + if (loading) return
Loading courses...
; + if (error) return
Error: {error}
; + + const relevantCourses = ["1337", "2305","2340","3341", "3345"]; + const filtered = courses.filter(course => course.subject_prefix == "CS" && relevantCourses.includes(course.course_number)) // filter for CS courses + + const unique = []; // remove duplicates (multiple sections I'm assuming) + const seen = new Set(); + + for (const course of filtered) { + if (!seen.has(course.course_number)) { + seen.add(course.course_number); + unique.push(course); + } + } + return (
- {data.courses.map((course, idx) => ( + {unique.map((course, idx) => (
))} diff --git a/src/app/utils/api.js b/src/app/utils/api.js new file mode 100644 index 0000000..ab5540e --- /dev/null +++ b/src/app/utils/api.js @@ -0,0 +1,18 @@ +const NEBULA_API_ENDPOINT = 'https://api.utdnebula.com/'; + +export async function nebulaFetch(path) { // fetch function that returns json response + const url = `${NEBULA_API_ENDPOINT}${path}`; + console.log(url); + const headers = { + 'x-api-key': process.env.NEXT_PUBLIC_NEBULA_API_KEY, + }; + const response = await fetch(url, { + headers, + }); + console.log(response); + if (!response.ok) { + throw new Error(`Nebula API error: ${response.status}`); + } + return response.json(); + +} From d7d5b25e57534a921b9b875145c22c0f8ea95ff6 Mon Sep 17 00:00:00 2001 From: Blizzyboii Date: Mon, 8 Sep 2025 18:20:25 -0500 Subject: [PATCH 2/3] changed loading screen --- src/app/components/courses.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/app/components/courses.js b/src/app/components/courses.js index 70bafb3..1104c82 100644 --- a/src/app/components/courses.js +++ b/src/app/components/courses.js @@ -26,8 +26,14 @@ function Courses() { fetchCourses(); }, []); - if (loading) return
Loading courses...
; - if (error) return
Error: {error}
; + if (loading) + return
+
+

Loading course data...

+
+ + if (error) + return
Error: {error}
; const relevantCourses = ["1337", "2305","2340","3341", "3345"]; const filtered = courses.filter(course => course.subject_prefix == "CS" && relevantCourses.includes(course.course_number)) // filter for CS courses From 3db31bc6452e40b82b2f45f37587c316bea3dd67 Mon Sep 17 00:00:00 2001 From: Blizzyboii Date: Fri, 12 Sep 2025 23:38:28 -0500 Subject: [PATCH 3/3] format --- src/app/components/courses.js | 8 +++++--- src/app/utils/api.js | 3 +-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/app/components/courses.js b/src/app/components/courses.js index 1104c82..d759bc0 100644 --- a/src/app/components/courses.js +++ b/src/app/components/courses.js @@ -28,7 +28,8 @@ function Courses() { if (loading) return
-
+

Loading course data...

@@ -36,9 +37,10 @@ function Courses() { return
Error: {error}
; const relevantCourses = ["1337", "2305","2340","3341", "3345"]; - const filtered = courses.filter(course => course.subject_prefix == "CS" && relevantCourses.includes(course.course_number)) // filter for CS courses + const filtered = courses.filter(course => + course.subject_prefix == "CS" && relevantCourses.includes(course.course_number)) - const unique = []; // remove duplicates (multiple sections I'm assuming) + const unique = []; // remove duplicates const seen = new Set(); for (const course of filtered) { diff --git a/src/app/utils/api.js b/src/app/utils/api.js index ab5540e..e1fd96a 100644 --- a/src/app/utils/api.js +++ b/src/app/utils/api.js @@ -1,8 +1,7 @@ const NEBULA_API_ENDPOINT = 'https://api.utdnebula.com/'; -export async function nebulaFetch(path) { // fetch function that returns json response +export async function nebulaFetch(path) { const url = `${NEBULA_API_ENDPOINT}${path}`; - console.log(url); const headers = { 'x-api-key': process.env.NEXT_PUBLIC_NEBULA_API_KEY, };