diff --git a/app/[slug]/page.tsx b/app/[slug]/page.tsx
index aecc9b6..cda6d6c 100644
--- a/app/[slug]/page.tsx
+++ b/app/[slug]/page.tsx
@@ -9,7 +9,7 @@ import { MenuItemActivator } from '@/app/menu'
export async function generateStaticParams() {
return allPages.map(page => ({
slug: page.slug,
- })).filter(slug => slug)
+ })).filter(({ slug }) => slug)
}
export default function Page({ params }: { params: { slug: string } }) {
diff --git a/app/assignments/assessment/[slug]/page.tsx b/app/assignments/assessment/[slug]/page.tsx
index 3ee7e5a..ec30701 100644
--- a/app/assignments/assessment/[slug]/page.tsx
+++ b/app/assignments/assessment/[slug]/page.tsx
@@ -1,15 +1,16 @@
-import { allAssessments, allHomework } from 'contentlayer/generated'
+import { allAssessments } from 'contentlayer/generated'
import { notFound } from 'next/navigation'
import { useMDXComponent } from 'next-contentlayer/hooks'
import { mdxComponents } from '@/components/mdx'
import { Card } from '@/components/Card'
import { Prose } from '@/components/Prose'
-import { MenuItemActivator } from '@/app/menu'
export async function generateStaticParams() {
+ if (!allAssessments.length) return [{ slug: "dummy" }]
+
return allAssessments.map(page => ({
slug: page.slug,
- })).filter(slug => slug)
+ }))
}
export default function Assessment({ params }: { params: { slug: string } }) {
diff --git a/app/assignments/hw/[slug]/page.tsx b/app/assignments/hw/[slug]/page.tsx
index f99e6a4..d7c9a2f 100644
--- a/app/assignments/hw/[slug]/page.tsx
+++ b/app/assignments/hw/[slug]/page.tsx
@@ -4,12 +4,13 @@ import { useMDXComponent } from 'next-contentlayer/hooks'
import { mdxComponents } from '@/components/mdx'
import { Card } from '@/components/Card'
import { Prose } from '@/components/Prose'
-import { MenuItemActivator } from '@/app/menu'
export async function generateStaticParams() {
+ if (!allHomework.length) return [{ slug: "dummy" }]
+
return allHomework.map(page => ({
slug: page.slug,
- })).filter(slug => slug)
+ }))
}
export default function Homework({ params }: { params: { slug: string } }) {
diff --git a/app/assignments/page.tsx b/app/assignments/page.tsx
index c8ea255..13f801d 100644
--- a/app/assignments/page.tsx
+++ b/app/assignments/page.tsx
@@ -1,8 +1,7 @@
import { allHomework, allAssessments } from 'contentlayer/generated'
import { Card } from '@/components/Card'
-import { MenuItemActivator } from '@/app/menu'
import Link from 'next/link'
-import { format } from 'date-fns'
+import { FormattedDate } from '@/components/FormattedDate'
type Assignment = {
title: string
@@ -70,11 +69,11 @@ function AssignmentRow({ title, href, isReleased, releaseDate, dates }: Assignme
{isReleased ?
{title} :
- {title}{releaseDate && <> (available {format(releaseDate, "M/d")})>}}
+ {title}{releaseDate && <> (available )>}}
|
{dates.map((item, index) =>
- {item.name} {format(item.date, item.specifyTime ? "E, M/d @ h:mmaa" : "E, M/d")}
+ {item.name}
)}
|
diff --git a/app/layout.tsx b/app/layout.tsx
index 21760fd..9045335 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -1,6 +1,7 @@
import "@/styles/global.css"
import "prism-themes/themes/prism-atom-dark.css"
import { Menu, MenuContextProvider } from "./menu"
+import { TimezoneNotice } from "@/components/TimezoneNotice"
export const metadata = {
title: 'Next.js',
@@ -24,7 +25,12 @@ export default function RootLayout({
- {children}
+
diff --git a/app/menu.tsx b/app/menu.tsx
index 212c90e..9b1b9e8 100644
--- a/app/menu.tsx
+++ b/app/menu.tsx
@@ -55,15 +55,10 @@ export function MenuContextProvider({ children }: { children: ReactNode }) {
const pathname = usePathname()
const [activeState, setActiveState] = useState<{ item: string | null, pathname: string }>({ item: null, pathname })
- useEffect(() => {
- if (activeState.pathname !== pathname) {
- setActiveState({ item: null, pathname })
- }
- }, [pathname])
-
return
diff --git a/components/FormattedDate.tsx b/components/FormattedDate.tsx
new file mode 100644
index 0000000..8ddae19
--- /dev/null
+++ b/components/FormattedDate.tsx
@@ -0,0 +1,25 @@
+"use client"
+
+import { useEffect, useState } from "react"
+import locale from "date-fns/locale/en-US"
+import { formatInTimeZone } from "date-fns-tz"
+import { format } from "date-fns"
+
+export type FormattedDateProps = {
+ date: Date
+ format: string
+}
+
+const defaultTimezone = "America/New_York"
+
+export function FormattedDate({ date, format: formatStr }: FormattedDateProps) {
+ const [value, setValue] = useState(formatInTimeZone(date, defaultTimezone, formatStr, {
+ locale,
+ }))
+
+ useEffect(() => {
+ setValue(format(date, formatStr))
+ }, [date, formatStr])
+
+ return value
+}
\ No newline at end of file
diff --git a/components/TimezoneNotice.tsx b/components/TimezoneNotice.tsx
new file mode 100644
index 0000000..953eb6c
--- /dev/null
+++ b/components/TimezoneNotice.tsx
@@ -0,0 +1,13 @@
+"use client"
+
+import { useEffect, useState } from "react";
+
+export function TimezoneNotice() {
+ const [isUsingLocalTimezone, setUsingLocalTimezone] = useState(false)
+ useEffect(() => {
+ setUsingLocalTimezone(true)
+ }, [])
+
+ if (isUsingLocalTimezone) return "Dates and times are displayed in your local time zone."
+ return "Dates and times are displayed in EST."
+}
\ No newline at end of file
diff --git a/content/pages/index.mdx b/content/pages/index.mdx
index eeb8047..863bea8 100644
--- a/content/pages/index.mdx
+++ b/content/pages/index.mdx
@@ -11,6 +11,8 @@ customLayout: true
Upcoming Assignments} margin>
+ **NOTE:** This component is currently broken. It only shows upcoming assignments at page build time, not at view time.
+
diff --git a/package-lock.json b/package-lock.json
index 1f5fad9..df94109 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,8 @@
"@next/mdx": "^14.0.4",
"@types/mdx": "^2.0.10",
"contentlayer": "^0.3.4",
- "date-fns": "^3.0.6",
+ "date-fns": "^2.30.0",
+ "date-fns-tz": "^2.0.0",
"next": "^14.0.4",
"next-contentlayer": "^0.3.4",
"prism-themes": "^1.9.0"
@@ -3523,12 +3524,26 @@
}
},
"node_modules/date-fns": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.0.6.tgz",
- "integrity": "sha512-W+G99rycpKMMF2/YD064b2lE7jJGUe+EjOES7Q8BIGY8sbNdbgcs9XFTZwvzc9Jx1f3k7LB7gZaZa7f8Agzljg==",
+ "version": "2.30.0",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
+ "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
+ "dependencies": {
+ "@babel/runtime": "^7.21.0"
+ },
+ "engines": {
+ "node": ">=0.11"
+ },
"funding": {
- "type": "github",
- "url": "https://github.com/sponsors/kossnocorp"
+ "type": "opencollective",
+ "url": "https://opencollective.com/date-fns"
+ }
+ },
+ "node_modules/date-fns-tz": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-2.0.0.tgz",
+ "integrity": "sha512-OAtcLdB9vxSXTWHdT8b398ARImVwQMyjfYGkKD2zaGpHseG2UPHbHjXELReErZFxWdSLph3c2zOaaTyHfOhERQ==",
+ "peerDependencies": {
+ "date-fns": ">=2.0.0"
}
},
"node_modules/debug": {
diff --git a/package.json b/package.json
index f8c4ce8..4488278 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,8 @@
"@next/mdx": "^14.0.4",
"@types/mdx": "^2.0.10",
"contentlayer": "^0.3.4",
- "date-fns": "^3.0.6",
+ "date-fns": "^2.30.0",
+ "date-fns-tz": "^2.0.0",
"next": "^14.0.4",
"next-contentlayer": "^0.3.4",
"prism-themes": "^1.9.0"