()
+ const [color, setColor] = useState("text-secondary")
+ const [timeColor, setTimeColor] = useState("text-muted-foreground")
+
+ useEffect(() => {
+ if (loading && (error || Object.values(grades.periods).length > 0)) {
+ setLoading(false)
+ if (error) return
+
+ const periods = Object.values(grades.periods)
+ const current = periods.find(p => {
+ const now = Date.now() / 1000
+ return p.start <= now && now <= p.end
+ }) || periods[0]
+
+ if (current) {
+ setGrade(current.grade)
+ }
+ if (grades.assignments) {
+ const latest = Object
+ .values(grades.assignments)
+ .reduce((max, a) => Math.max(max, a.updated), 0)
+ if (latest > 0) setTimestamp(latest)
+ else if (grades.timestamp) setTimestamp(grades.timestamp / 1000)
+ } else if (grades.timestamp) {
+ setTimestamp(grades.timestamp / 1000)
+ }
+ }
+ }, [grades, error, loading])
+
+ useEffect(() => {
+ if (grade === undefined) return
+ setColor(grade >= 90 ? "text-green-500"
+ : grade >= 80 ? "text-blue-500"
+ : grade >= 70 ? "text-yellow-500"
+ : grade >= 60 ? "text-orange-500"
+ : "text-red-500")
+
+ if (!timestamp) return
+
+ const diff = Date.now() - timestamp * 1000
+ const hours = diff / (1000 * 60 * 60)
+ const days = hours / 24
+
+ setTimeColor(
+ hours < 24 ? "text-green-600"
+ : hours < 48 ? "text-lime-500"
+ : days < 4 ? "text-yellow-500"
+ : days < 14 ? "text-black dark:text-white"
+ : "text-gray-500"
+ )
+
+ }, [grade, timestamp])
+
+ if (error === "No grades found!") return null
+
+ return (
+
+ {!loading && grade !== undefined && (
+
+
+ {grade}%
+
+ {timestamp && (
+
+
+ Updated {DateTime.fromSeconds(timestamp).toRelative()}
+
+
+ {DateTime.fromSeconds(timestamp).toFormat("cccc, MMMM d, yyyy h:mm a")}
+
+
+ )}
+
+ )}
+ {loading && (
+
+
+
+ )}
+
+ )
+}
diff --git a/src/server/index.ts b/src/server/index.ts
index 96e5ac0..8e85f1e 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -2,10 +2,8 @@
// 2025.10.05 update - Wow I should really rewrite this entire thing
const url = process.env.NODE_ENV === "development"
- ? typeof window !== "undefined"
- ? window.location.origin.replace("3000", "5000")
- : "http://localhost:5000"
- : `${process.env.NEXT_PUBLIC_API_URL}`
+ ? "/api"
+ : (process.env.NEXT_PUBLIC_API_URL || "https://api.gunn.one")
export default function server(uri: string, options?: RequestInit) {
return fetch(`${url}${uri}`, {
From ead5ad66b9490a1be69481b981f345ed3f0520c1 Mon Sep 17 00:00:00 2001
From: Cfrolich13 <80122013+Cfrolich13@users.noreply.github.com>
Date: Wed, 4 Feb 2026 16:05:13 -0600
Subject: [PATCH 2/3] Fixed timestamp formatting
---
src/components/Grade.tsx | 10 +++++++++-
src/contexts/ThemeContext.tsx | 3 +++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/components/Grade.tsx b/src/components/Grade.tsx
index 21ef54d..614bf9d 100644
--- a/src/components/Grade.tsx
+++ b/src/components/Grade.tsx
@@ -86,7 +86,15 @@ export default function Grade({ id, period, delay }: { id: string, period: numbe
transition={{ delay: delay + 0.3 }}
className={`text-center text-xs font-medium ${timeColor} cursor-default`}
>
- Updated {DateTime.fromSeconds(timestamp).toRelative()}
+ Updated {(() => {
+ const relative = DateTime.fromSeconds(timestamp).toRelative()
+ if (relative === "1 day ago") return "yesterday"
+ const diff = Date.now() - timestamp * 1000
+ const days = diff / (1000 * 60 * 60 * 24)
+ if (days > 6.5 && days < 29.5)
+ return `${Math.round(days / 7)} week${Math.round(days / 7) === 1 ? "" : "s"} ago`
+ return relative
+ })()}
{DateTime.fromSeconds(timestamp).toFormat("cccc, MMMM d, yyyy h:mm a")}
diff --git a/src/contexts/ThemeContext.tsx b/src/contexts/ThemeContext.tsx
index 663469c..9e04848 100644
--- a/src/contexts/ThemeContext.tsx
+++ b/src/contexts/ThemeContext.tsx
@@ -118,6 +118,9 @@ export const ThemeProvider = ({ children }: Readonly<{ children: React.ReactNode
for (const [variable, value] of Object.entries(theme).slice(1))
document.documentElement.style.setProperty(`--${variable}`, value)
+ if (theme.name === "Dark") document.documentElement.classList.add("dark")
+ else document.documentElement.classList.remove("dark")
+
const canvas = document.createElement("canvas")
canvas.width = 64
canvas.height = 64
From 34841f5e752d0c206ca11bb9ef9f5ad213736fd9 Mon Sep 17 00:00:00 2001
From: Cfrolich13 <80122013+Cfrolich13@users.noreply.github.com>
Date: Wed, 4 Feb 2026 22:25:25 -0600
Subject: [PATCH 3/3] Improve relative time formatting
---
src/components/Grade.tsx | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/src/components/Grade.tsx b/src/components/Grade.tsx
index 614bf9d..c0ad4fa 100644
--- a/src/components/Grade.tsx
+++ b/src/components/Grade.tsx
@@ -87,12 +87,11 @@ export default function Grade({ id, period, delay }: { id: string, period: numbe
className={`text-center text-xs font-medium ${timeColor} cursor-default`}
>
Updated {(() => {
- const relative = DateTime.fromSeconds(timestamp).toRelative()
- if (relative === "1 day ago") return "yesterday"
- const diff = Date.now() - timestamp * 1000
- const days = diff / (1000 * 60 * 60 * 24)
- if (days > 6.5 && days < 29.5)
- return `${Math.round(days / 7)} week${Math.round(days / 7) === 1 ? "" : "s"} ago`
+ const updateTime = DateTime.fromSeconds(timestamp)
+ let relative = updateTime.toRelative()
+ if (Math.abs(updateTime.diffNow("hours").hours) >= 24) {
+ relative = updateTime.toRelativeCalendar();
+ }
return relative
})()}