From 343978870774f81ecaa06d7f253020265f601fd2 Mon Sep 17 00:00:00 2001
From: Yuren Hao <97327730+YurenHao0426@users.noreply.github.com>
Date: Wed, 6 Aug 2025 01:39:08 -0700
Subject: feat: scaffold prereq graph project
---
src/App.tsx | 12 ++++++++++++
src/components/Graph.tsx | 49 ++++++++++++++++++++++++++++++++++++++++++++++
src/global.d.ts | 2 ++
src/hooks/useCourseData.ts | 14 +++++++++++++
src/main.tsx | 9 +++++++++
5 files changed, 86 insertions(+)
create mode 100644 src/App.tsx
create mode 100644 src/components/Graph.tsx
create mode 100644 src/global.d.ts
create mode 100644 src/hooks/useCourseData.ts
create mode 100644 src/main.tsx
(limited to 'src')
diff --git a/src/App.tsx b/src/App.tsx
new file mode 100644
index 0000000..9687afc
--- /dev/null
+++ b/src/App.tsx
@@ -0,0 +1,12 @@
+import Graph from "./components/Graph";
+import { useCourseData } from "./hooks/useCourseData";
+
+export default function App() {
+ const catalog = useCourseData("/data/catalog_2025_fall.json");
+ return (
+ <>
+
UIUC Course Prerequisite Graph
+
+ >
+ );
+}
diff --git a/src/components/Graph.tsx b/src/components/Graph.tsx
new file mode 100644
index 0000000..5e81b38
--- /dev/null
+++ b/src/components/Graph.tsx
@@ -0,0 +1,49 @@
+import CytoscapeComponent from "react-cytoscapejs";
+import cytoscape from "cytoscape";
+import dagre from "cytoscape-dagre";
+import { useMemo } from "react";
+
+cytoscape.use(dagre);
+
+type Catalog = Record;
+
+export default function Graph({ catalog }: { catalog: Catalog }) {
+ const elements = useMemo(() => {
+ const els: any[] = [];
+ Object.keys(catalog).forEach(id => {
+ els.push({ data: { id } });
+ catalog[id].forEach(p =>
+ els.push({
+ data: { id: `${p}->${id}`, source: p, target: id }
+ })
+ );
+ });
+ return els;
+ }, [catalog]);
+
+ return (
+
+ );
+}
diff --git a/src/global.d.ts b/src/global.d.ts
new file mode 100644
index 0000000..d2d9941
--- /dev/null
+++ b/src/global.d.ts
@@ -0,0 +1,2 @@
+declare module 'react-cytoscapejs';
+declare module 'cytoscape-dagre';
diff --git a/src/hooks/useCourseData.ts b/src/hooks/useCourseData.ts
new file mode 100644
index 0000000..74281fa
--- /dev/null
+++ b/src/hooks/useCourseData.ts
@@ -0,0 +1,14 @@
+import { useEffect, useState } from "react";
+
+export function useCourseData(file = "/data/catalog_2025_fall.json") {
+ const [catalog, setCatalog] = useState>({});
+
+ useEffect(() => {
+ fetch(file)
+ .then(r => r.json())
+ .then(setCatalog)
+ .catch(console.error);
+ }, [file]);
+
+ return catalog;
+}
diff --git a/src/main.tsx b/src/main.tsx
new file mode 100644
index 0000000..3fd3a69
--- /dev/null
+++ b/src/main.tsx
@@ -0,0 +1,9 @@
+import React from "react";
+import ReactDOM from "react-dom/client";
+import App from "./App";
+
+ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
+
+
+
+);
--
cgit v1.2.3