Renaming pages and adding content

This commit is contained in:
Tony Grosinger 2023-11-26 09:36:23 -08:00
parent e2e9ab6774
commit e0de86bb5a
16 changed files with 501 additions and 117 deletions

View File

@ -1,5 +1,5 @@
{
"name": "tailwindui-template",
"name": "wscc-website",
"version": "0.1.0",
"private": true,
"scripts": {
@ -40,4 +40,4 @@
"prettier-plugin-tailwindcss": "^0.5.2",
"sharp": "^0.32.0"
}
}
}

View File

@ -1,6 +1,6 @@
/** @type {import('prettier').Options} */
module.exports = {
singleQuote: true,
semi: false,
semi: true,
plugins: ['prettier-plugin-tailwindcss'],
}

View File

@ -2,14 +2,14 @@ import { type Metadata } from 'next'
import { Card } from '@/components/Card'
import { SimpleLayout } from '@/components/SimpleLayout'
import { type ArticleWithSlug, getAllArticles } from '@/lib/articles'
import { type BlogPostWithSlug, getAllBlogPosts } from '@/lib/articles'
import { formatDate } from '@/lib/formatDate'
function Article({ article }: { article: ArticleWithSlug }) {
function Article({ article }: { article: BlogPostWithSlug }) {
return (
<article className="md:grid md:grid-cols-4 md:items-baseline">
<Card className="md:col-span-3">
<Card.Title href={`/articles/${article.slug}`}>
<Card.Title href={`/blog/${article.slug}`}>
{article.title}
</Card.Title>
<Card.Eyebrow
@ -35,18 +35,17 @@ function Article({ article }: { article: ArticleWithSlug }) {
}
export const metadata: Metadata = {
title: 'Articles',
description:
'All of my long-form thoughts on programming, leadership, product design, and more, collected in chronological order.',
title: 'Blog',
description: 'History, Announcements, and more from the West Sound Hall and Community Club.',
}
export default async function ArticlesIndex() {
let articles = await getAllArticles()
let articles = await getAllBlogPosts()
return (
<SimpleLayout
title="Writing on software design, company building, and the aerospace industry."
intro="All of my long-form thoughts on programming, leadership, product design, and more, collected in chronological order."
title="West Sound Hall Blog"
intro="History, Announcements, and more from the West Sound Hall and Community Club."
>
<div className="md:border-l md:border-zinc-100 md:pl-6 md:dark:border-zinc-700/40">
<div className="flex max-w-3xl flex-col space-y-16">

101
src/app/club/page.tsx Normal file
View File

@ -0,0 +1,101 @@
import { type Metadata } from 'next'
import Image from 'next/image'
import Link from 'next/link'
import clsx from 'clsx'
import { Container } from '@/components/Container'
import {
InstagramIcon,
TwitterIcon,
} from '@/components/SocialIcons'
import portraitImage from '@/images/portrait.jpg'
function SocialLink({
className,
href,
children,
icon: Icon,
}: {
className?: string
href: string
icon: React.ComponentType<{ className?: string }>
children: React.ReactNode
}) {
return (
<li className={clsx(className, 'flex')}>
<Link
href={href}
className="group flex text-sm font-medium text-zinc-800 transition hover:text-teal-500 dark:text-zinc-200 dark:hover:text-teal-500"
>
<Icon className="h-6 w-6 flex-none fill-zinc-500 transition group-hover:fill-teal-500" />
<span className="ml-4">{children}</span>
</Link>
</li>
)
}
function MailIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
return (
<svg viewBox="0 0 24 24" aria-hidden="true" {...props}>
<path
fillRule="evenodd"
d="M6 5a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h12a3 3 0 0 0 3-3V8a3 3 0 0 0-3-3H6Zm.245 2.187a.75.75 0 0 0-.99 1.126l6.25 5.5a.75.75 0 0 0 .99 0l6.25-5.5a.75.75 0 0 0-.99-1.126L12 12.251 6.245 7.187Z"
/>
</svg>
)
}
export const metadata: Metadata = {
title: 'History',
description:
'The West Sound Community Club on Orcas Island.',
}
export default function Club() {
return (
<Container className="mt-16 sm:mt-32">
<div className="grid grid-cols-1 gap-y-16 lg:grid-cols-2 lg:grid-rows-[auto_1fr] lg:gap-y-12">
<div className="lg:pl-20">
<div className="max-w-xs px-2.5 lg:max-w-none">
<Image
src={portraitImage}
alt=""
sizes="(min-width: 1024px) 32rem, 20rem"
className="aspect-square rotate-3 rounded-2xl bg-zinc-100 object-cover dark:bg-zinc-800"
/>
</div>
</div>
<div className="lg:order-first lg:row-span-2">
<h1 className="text-4xl font-bold tracking-tight text-zinc-800 dark:text-zinc-100 sm:text-5xl">
West Sound Community Club
</h1>
<div className="mt-6 space-y-7 text-base text-zinc-600 dark:text-zinc-400">
<p>
The West Sound Community Club, a nonprofit, tax-exempt corporation
under Section 501(c)3 of the Internal Revenue Code, owns and manages
the Hall. The Club sponsors monthly community potlucks at the Hall
from September through May.
</p>
</div>
</div>
<div className="lg:pl-20">
<ul role="list">
<SocialLink href="#" icon={TwitterIcon}>
Membership Form
</SocialLink>
<SocialLink href="#" icon={InstagramIcon} className="mt-4">
Donations
</SocialLink>
<SocialLink
href="mailto:contact@westsoundhall.org"
icon={MailIcon}
className="mt-8 border-t border-zinc-100 pt-8 dark:border-zinc-700/40"
>
contact@westsoundhall.org
</SocialLink>
</ul>
</div>
</div>
</Container>
)
}

View File

@ -1,18 +1,18 @@
import assert from 'assert'
import * as cheerio from 'cheerio'
import { Feed } from 'feed'
import assert from 'assert';
import * as cheerio from 'cheerio';
import { Feed } from 'feed';
export async function GET(req: Request) {
let siteUrl = process.env.NEXT_PUBLIC_SITE_URL
let siteUrl = process.env.NEXT_PUBLIC_SITE_URL;
if (!siteUrl) {
throw Error('Missing NEXT_PUBLIC_SITE_URL environment variable')
throw Error('Missing NEXT_PUBLIC_SITE_URL environment variable');
}
let author = {
name: 'Spencer Sharp',
email: 'spencer@planetaria.tech',
}
};
let feed = new Feed({
title: author.name,
@ -26,28 +26,28 @@ export async function GET(req: Request) {
feedLinks: {
rss2: `${siteUrl}/feed.xml`,
},
})
});
let articleIds = require
.context('../articles', true, /\/page\.mdx$/)
.context('../blog', true, /\/page\.mdx$/)
.keys()
.filter((key) => key.startsWith('./'))
.map((key) => key.slice(2).replace(/\/page\.mdx$/, ''))
.map((key) => key.slice(2).replace(/\/page\.mdx$/, ''));
for (let id of articleIds) {
let url = String(new URL(`/articles/${id}`, req.url))
let html = await (await fetch(url)).text()
let $ = cheerio.load(html)
let url = String(new URL(`/blog/${id}`, req.url));
let html = await (await fetch(url)).text();
let $ = cheerio.load(html);
let publicUrl = `${siteUrl}/articles/${id}`
let article = $('article').first()
let title = article.find('h1').first().text()
let date = article.find('time').first().attr('datetime')
let content = article.find('[data-mdx-content]').first().html()
let publicUrl = `${siteUrl}/blog/${id}`;
let article = $('article').first();
let title = article.find('h1').first().text();
let date = article.find('time').first().attr('datetime');
let content = article.find('[data-mdx-content]').first().html();
assert(typeof title === 'string')
assert(typeof date === 'string')
assert(typeof content === 'string')
assert(typeof title === 'string');
assert(typeof date === 'string');
assert(typeof content === 'string');
feed.addItem({
title,
@ -57,7 +57,7 @@ export async function GET(req: Request) {
author: [author],
contributor: [author],
date: new Date(date),
})
});
}
return new Response(feed.rss2(), {
@ -66,5 +66,5 @@ export async function GET(req: Request) {
'content-type': 'application/xml',
'cache-control': 's-maxage=31556952',
},
})
});
}

View File

@ -0,0 +1,301 @@
import { type Metadata } from 'next'
import Image from 'next/image'
import Link from 'next/link'
import clsx from 'clsx'
import { Card } from '@/components/Card'
import { Container } from '@/components/Container'
import {
GitHubIcon,
InstagramIcon,
LinkedInIcon,
TwitterIcon,
} from '@/components/SocialIcons'
import portraitImage from '@/images/portrait.jpg'
function SocialLink({
className,
href,
children,
icon: Icon,
}: {
className?: string
href: string
icon: React.ComponentType<{ className?: string }>
children: React.ReactNode
}) {
return (
<li className={clsx(className, 'flex')}>
<Link
href={href}
className="group flex text-sm font-medium text-zinc-800 transition hover:text-teal-500 dark:text-zinc-200 dark:hover:text-teal-500"
>
<Icon className="h-6 w-6 flex-none fill-zinc-500 transition group-hover:fill-teal-500" />
<span className="ml-4">{children}</span>
</Link>
</li>
)
}
function MailIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
return (
<svg viewBox="0 0 24 24" aria-hidden="true" {...props}>
<path
fillRule="evenodd"
d="M6 5a3 3 0 0 0-3 3v8a3 3 0 0 0 3 3h12a3 3 0 0 0 3-3V8a3 3 0 0 0-3-3H6Zm.245 2.187a.75.75 0 0 0-.99 1.126l6.25 5.5a.75.75 0 0 0 .99 0l6.25-5.5a.75.75 0 0 0-.99-1.126L12 12.251 6.245 7.187Z"
/>
</svg>
)
}
function TimelineEntry({
title,
description,
event,
cta,
href,
children
}: {
title: string
description: string
event?: string
cta?: string
href?: string
children?: React.ReactNode
}) {
return (
<Card as="article">
<Card.Title as="h3" href={href}>
{title}
</Card.Title>
{event
? <Card.Eyebrow decorate>{event}</Card.Eyebrow>
: null}
<Card.Description>{description}</Card.Description>
{cta
? <Card.Cta>{cta}</Card.Cta>
: null}
{children}
</Card>
)
}
function DateListItem({
year, value
}: {
year?: string
value: string
}) {
return (
<div className='flex space-x-4'>
<div className='w-10'>{year}</div>
<div>{value}</div>
</div>
)
}
export const metadata: Metadata = {
title: 'History',
description:
'The history of the West Sound Community Hall on Orcas Island.',
}
export default function About() {
return (
<Container className="mt-16 sm:mt-32">
<div className="grid grid-cols-1 gap-y-16 lg:grid-cols-2 lg:grid-rows-[auto_1fr] lg:gap-y-12">
<div className="lg:pl-20">
<div className="max-w-xs px-2.5 lg:max-w-none">
<Image
src={portraitImage}
alt=""
sizes="(min-width: 1024px) 32rem, 20rem"
className="aspect-square rotate-3 rounded-2xl bg-zinc-100 object-cover dark:bg-zinc-800"
/>
</div>
</div>
<div className="lg:order-first lg:row-span-2">
<h1 className="text-4xl font-bold tracking-tight text-zinc-800 dark:text-zinc-100 sm:text-5xl">
Hall History
</h1>
<div className="mt-6 space-y-7 text-base text-zinc-600 dark:text-zinc-400">
<p>
The West Sound Community Hall represents the history and character
of Orcas Island. Members of the nonprofit West Sound Community Club,
as stewards of the Hall, strive to maintain the integrity of the
Hall as a unique gathering place for future generations.
</p>
<p>
In 1902 volunteers began building the Hall with materials supplied by George
Adkins. The building site was donated two years earlier by Alexander Chalmers.
The Hall was erected to serve as a central meeting place for residents of the
West Sound area.
</p>
<p>
Over the years the original one-room schoolhouse design has
changed to fit the times. A kitchen, stage, and entrance porch
were added to enhance the building&apos;s function.
</p>
<p>
Numerous organizations have used the Hall for meetings. In
addition, weddings, concerts, elections, parties, and other events
have been regularly held in the Hall since 1902.
</p>
</div>
<div className="mt-8 space-y-8">
<h2 className="text-2xl font-bold tracking-tight text-zinc-800 dark:text-zinc-100 sm:text-5xl">
Detailed History
</h2>
<TimelineEntry
title="Pre-1900"
description='A Lummi village named "Elelung" occupied the land. The property is part of a documented archaeological site as evidenced by a shell midden under the Hall.'
/>
<TimelineEntry
title="1900 - February 21st"
description='Alexander Chalmers donated "property to be used for a site for a public hall" to the West Sound Hall Company. The donated land was originally part of a large parcel homesteaded by Peter LaPlante in 1884.'
/>
<TimelineEntry
title='1902 - 1903'
description='The West Sound Community Hall was constructed. Funds for building materials were donated by George Adkins. The Hall was constructed by Adkins, Omer Freel, Joe Verrier, Peter LaPlante, Gus Smedberg and others. Mr. Adkins, who moved to West Sound in 1896, founded the West Sound Trading Company which was located on a wharf opposite the Hall.'
/>
<TimelineEntry
title='1904'
description='The Chase brothers, who owned the Chase Bros. Mill in West Sound, donated lumber and built an addition for a stage on the north end of the Hall.'
/>
<TimelineEntry
title='1903 - 1935'
description='During this period the following organizations were regular users of the Hall:'
>
<div className="relative z-10 ml-4 mt-2 text-sm text-zinc-600 dark:text-zinc-400">
<DateListItem
year='1903'
value='Women&apos;s Christian Temperance Union Woodmen Lodge'
/>
<DateListItem
value='West Sound Literary Society'
/>
<DateListItem
year='1911'
value='West Sound Boy&apos;s Band'
/>
<DateListItem
year='1912'
value='West Sound Grange (130 members in 1913)'
/>
<DateListItem
value='Odd Fellows'
/>
<DateListItem
value='West Sound Athletic Club'
/>
<DateListItem
year='1913'
value='West Sound Orchestra'
/>
<DateListItem
value='West Sound Baseball Team'
/>
<DateListItem
year='1922'
value='Farm Bureau'
/>
<DateListItem
year='1925'
value='Fidelis Circle'
/>
</div>
</TimelineEntry>
<TimelineEntry
title='1905 - 1910'
description='Sometime during this period the Hall was increased in size by adding twelve feet to the south end.'
/>
<TimelineEntry
title='1935'
description='West Sound Hall Company is reorganized as the West Sound Community Club.'
/>
<TimelineEntry
title='Sometime after 1935'
description='The stage, then located at the north end of the hall, was remodeled " to make it as wide as the Hall and 22 feet back providing room for stage, kitchen and rest room - cost $122.85." Logs were salvaged from local beaches and the Thatcher Mill sawed them into lumber for use in remodel.'
/>
<TimelineEntry
title='1940&apos;s'
description='During the Second World War, Fidelis Circle cared for and managed the Hall.'
/>
<TimelineEntry
title='Sometime after 1947'
description='When it was determined the foundation under the stage was failing, the stage was converted to a kitchen and the floor was lowered to match the level of the main Hall floor. The current stage on the east side of the Hall was probably added at the same time.'
/>
<TimelineEntry
title='1956'
description='The Orcas Island Yacht Club was founded and began using the Hall as a clubhouse.'
/>
<TimelineEntry
title='1957'
description='The south entry was moved to the present location on the east side of the Hall. The old entry and scaffolding for the new entry are shown in a photo taken in April 1957. This is the only known photo showing in detail how the exterior of the Hall looked prior to 1957.'
/>
<TimelineEntry
title='1972'
description='Members of the Orcas Island Yacht Club made major repairs to the building structure and the interior was completely remodeled. Prior to the remodel the interior walls were burlap cloth and there was no ceiling in the hall.'
/>
<TimelineEntry
title='1979'
description='The property on which the hall sits was increased in size by donation a strip of land surrounding the hall structure.'
/>
<TimelineEntry
title='1981'
description='Major foundation repairs of a temporary nature were made.'
/>
<TimelineEntry
title='1996'
description='The entry stairs and deck were rebuilt.'
/>
<TimelineEntry
title='1999'
description='Realizing a major renovation of the Hall was needed, the officers of the West Sound Community Club reorganized the club as a nonprofit corporation and applied for 501(c)(3) status. A Centennial Building Committee was created to manage the renovation. The goal was to complete the renovation prior to the 100th anniversary of the Hall&appos;s construction in 1902. Con Russell Construction was selected as the contractor and construction started in February 2000. Major repairs, including a new foundation, metal roof, insulation, and painting the exterior, were completed by October of 2000. To date, the Club has received contributions and pledges of more than $81,000 to pay for the renovation and establish an endowment for future maintenance of the Hall.'
/>
<TimelineEntry
title='1999 - October 18th'
description='The West Sound Community Hall was listed in the Washington Heritage Register.'
/>
<TimelineEntry
title='2000 - June 12th'
description='The Washington Department of Revenue approved the West Sound Community Club&apos;s application for property tax exemption for the West Sound Community Hall as a "public assembly hall".'
/>
<TimelineEntry
title='2000 - August 31st'
description='West Sound Community Hall web site first launched.'
/>
<TimelineEntry
title='2001 - April 21st'
description='A new "West Sound Community Hall" sign was placed on the front of the Hall in a ceremony attended by more than twenty members of the West Sound Community Club. Placement of the sign marked the completion of a major renovation of the Hall started in February 2000.'
/>
</div>
</div>
<div className="lg:pl-20">
<ul role="list">
<SocialLink href="#" icon={TwitterIcon}>
Follow on Twitter
</SocialLink>
<SocialLink href="#" icon={InstagramIcon} className="mt-4">
Follow on Instagram
</SocialLink>
<SocialLink href="#" icon={GitHubIcon} className="mt-4">
Follow on GitHub
</SocialLink>
<SocialLink href="#" icon={LinkedInIcon} className="mt-4">
Follow on LinkedIn
</SocialLink>
<SocialLink
href="mailto:contact@westsoundhall.org"
icon={MailIcon}
className="mt-8 border-t border-zinc-100 pt-8 dark:border-zinc-700/40"
>
contact@westsoundhall.org
</SocialLink>
</ul>
</div>
</div>
</Container>
)
}

View File

@ -20,7 +20,7 @@ import image2 from '@/images/photos/image-2.jpg'
import image3 from '@/images/photos/image-3.jpg'
import image4 from '@/images/photos/image-4.jpg'
import image5 from '@/images/photos/image-5.jpg'
import { type ArticleWithSlug, getAllArticles } from '@/lib/articles'
import { type BlogPostWithSlug, getAllBlogPosts } from '@/lib/articles'
import { formatDate } from '@/lib/formatDate'
function MailIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
@ -82,10 +82,10 @@ function ArrowDownIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
)
}
function Article({ article }: { article: ArticleWithSlug }) {
function Article({ article }: { article: BlogPostWithSlug }) {
return (
<Card as="article">
<Card.Title href={`/articles/${article.slug}`}>
<Card.Title href={`/blog/${article.slug}`}>
{article.title}
</Card.Title>
<Card.Eyebrow as="time" dateTime={article.date} decorate>
@ -266,20 +266,20 @@ function Photos() {
}
export default async function Home() {
let articles = (await getAllArticles()).slice(0, 4)
let articles = (await getAllBlogPosts()).slice(0, 4)
return (
<>
<Container className="mt-9">
<div className="max-w-2xl">
<h1 className="text-4xl font-bold tracking-tight text-zinc-800 dark:text-zinc-100 sm:text-5xl">
Software designer, founder, and amateur astronaut.
West Sound Community Hall
</h1>
<p className="mt-6 text-base text-zinc-600 dark:text-zinc-400">
Im Spencer, a software designer and entrepreneur based in New York
City. Im the founder and CEO of Planetaria, where we develop
technologies that empower regular people to explore space on their
own terms.
WestSound Community Hall, located at 884 Deer Harbor Road in the hamlet of West Sound, has served as a public assembly hall since it was built by volunteers in 1902.
</p>
<p className="mt-6 text-base text-zinc-600 dark:text-zinc-400">
Facing West Sound, the Hall is at the heart of the WestSound community.
</p>
<div className="mt-6 flex gap-6">
<SocialLink

View File

@ -48,12 +48,12 @@ function MailIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
}
export const metadata: Metadata = {
title: 'About',
title: 'History',
description:
'Im Spencer Sharp. I live in New York City, where I design the future.',
'The history of the West Sound Community Hall on Orcas Island.',
}
export default function About() {
export default function Rental() {
return (
<Container className="mt-16 sm:mt-32">
<div className="grid grid-cols-1 gap-y-16 lg:grid-cols-2 lg:grid-rows-[auto_1fr] lg:gap-y-12">
@ -69,58 +69,47 @@ export default function About() {
</div>
<div className="lg:order-first lg:row-span-2">
<h1 className="text-4xl font-bold tracking-tight text-zinc-800 dark:text-zinc-100 sm:text-5xl">
Im Spencer Sharp. I live in New York City, where I design the
future.
Hall Rental
</h1>
<div className="mt-6 space-y-7 text-base text-zinc-600 dark:text-zinc-400">
<p>
Ive loved making things for as long as I can remember, and wrote
my first program when I was 6 years old, just two weeks after my
mom brought home the brand new Macintosh LC 550 that I taught
myself to type on.
The WestSound Community Hall is a public assembly hall, which has
been in continuous operation since it was built in 1902. In 1999,
the Hall was listed on the Washington Heritage Register. The West
Sound Community Club, as steward of the Hall, makes the Hall
available for nonprofit purposes. Rental fees, shown below, are used
to pay Hall operating and maintenance expenses.
</p>
<p>
The only thing I loved more than computers as a kid was space.
When I was 8, I climbed the 40-foot oak tree at the back of our
yard while wearing my older sisters motorcycle helmet, counted
down from three, and jumped hoping the tree was tall enough that
with just a bit of momentum Id be able to get to orbit.
Rental and deposit fees must be paid prior to obtaining access for
set-up. Rental fees include use of the meeting room, projector
and stage, chairs and tables, kitchen, rest rooms, water, and
lights. It does not include trash removal. Cleanup of the Hall
including removal of trash from the property the same day as the
event are the responsibilities of the renter.
</p>
<p>
I spent the next few summers indoors working on a rocket design,
while I recovered from the multiple surgeries it took to fix my
badly broken legs. It took nine iterations, but when I was 15 I
sent my dads Blackberry into orbit and was able to transmit a
photo back down to our family computer from space.
</p>
<p>
Today, Im the founder of Planetaria, where were working on
civilian space suits and manned shuttle kits you can assemble at
home so that the next generation of kids really <em>can</em> make
it to orbit from the comfort of their own backyards.
Damage and cleanup deposits, paid in advance, are refundable upon
satisfactory inspection of the Hall after the event. If there is
damage to the Hall or cleaning is necessary, deductions will be
made at the discretion of the Board.
</p>
</div>
</div>
<div className="lg:pl-20">
<ul role="list">
<SocialLink href="#" icon={TwitterIcon}>
Follow on Twitter
Rental Application Form
</SocialLink>
<SocialLink href="#" icon={InstagramIcon} className="mt-4">
Follow on Instagram
</SocialLink>
<SocialLink href="#" icon={GitHubIcon} className="mt-4">
Follow on GitHub
</SocialLink>
<SocialLink href="#" icon={LinkedInIcon} className="mt-4">
Follow on LinkedIn
Rental Q&A
</SocialLink>
<SocialLink
href="mailto:spencer@planetaria.tech"
href="mailto:contact@westsoundhall.org"
icon={MailIcon}
className="mt-8 border-t border-zinc-100 pt-8 dark:border-zinc-700/40"
>
spencer@planetaria.tech
contact@westsoundhall.org
</SocialLink>
</ul>
</div>

View File

@ -6,7 +6,7 @@ import { useRouter } from 'next/navigation'
import { AppContext } from '@/app/providers'
import { Container } from '@/components/Container'
import { Prose } from '@/components/Prose'
import { type ArticleWithSlug } from '@/lib/articles'
import { type BlogPostWithSlug } from '@/lib/articles'
import { formatDate } from '@/lib/formatDate'
function ArrowLeftIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
@ -26,7 +26,7 @@ export function ArticleLayout({
article,
children,
}: {
article: ArticleWithSlug
article: BlogPostWithSlug
children: React.ReactNode
}) {
let router = useRouter()

View File

@ -27,10 +27,9 @@ export function Footer() {
<ContainerInner>
<div className="flex flex-col items-center justify-between gap-6 sm:flex-row">
<div className="flex flex-wrap justify-center gap-x-6 gap-y-1 text-sm font-medium text-zinc-800 dark:text-zinc-200">
<NavLink href="/about">About</NavLink>
<NavLink href="/projects">Projects</NavLink>
<NavLink href="/speaking">Speaking</NavLink>
<NavLink href="/uses">Uses</NavLink>
<NavLink href="/hall-history">History</NavLink>
<NavLink href="/rental">Rental</NavLink>
<NavLink href="/club">Club</NavLink>
</div>
<p className="text-sm text-zinc-400 dark:text-zinc-500">
&copy; {new Date().getFullYear()} Spencer Sharp. All rights

View File

@ -132,11 +132,10 @@ function MobileNavigation(
</div>
<nav className="mt-6">
<ul className="-my-2 divide-y divide-zinc-100 text-base text-zinc-800 dark:divide-zinc-100/5 dark:text-zinc-300">
<MobileNavItem href="/about">About</MobileNavItem>
<MobileNavItem href="/articles">Articles</MobileNavItem>
<MobileNavItem href="/projects">Projects</MobileNavItem>
<MobileNavItem href="/speaking">Speaking</MobileNavItem>
<MobileNavItem href="/uses">Uses</MobileNavItem>
<MobileNavItem href="/hall-history">Hall History</MobileNavItem>
<MobileNavItem href="/blog">Blog</MobileNavItem>
<MobileNavItem href="/rental">Rental</MobileNavItem>
<MobileNavItem href="/club">Club</MobileNavItem>
</ul>
</nav>
</Popover.Panel>
@ -179,11 +178,10 @@ function DesktopNavigation(props: React.ComponentPropsWithoutRef<'nav'>) {
return (
<nav {...props}>
<ul className="flex rounded-full bg-white/90 px-3 text-sm font-medium text-zinc-800 shadow-lg shadow-zinc-800/5 ring-1 ring-zinc-900/5 backdrop-blur dark:bg-zinc-800/90 dark:text-zinc-200 dark:ring-white/10">
<NavItem href="/about">About</NavItem>
<NavItem href="/articles">Articles</NavItem>
<NavItem href="/projects">Projects</NavItem>
<NavItem href="/speaking">Speaking</NavItem>
<NavItem href="/uses">Uses</NavItem>
<NavItem href="/hall-history">History</NavItem>
<NavItem href="/blog">Blog</NavItem>
<NavItem href="/rental">Rental</NavItem>
<NavItem href="/club">Club</NavItem>
</ul>
</nav>
)

View File

@ -1,36 +1,33 @@
import glob from 'fast-glob'
import glob from 'fast-glob';
interface Article {
title: string
description: string
author: string
date: string
interface BlogPost {
title: string;
description: string;
author: string;
date: string;
}
export interface ArticleWithSlug extends Article {
slug: string
export interface BlogPostWithSlug extends BlogPost {
slug: string;
}
async function importArticle(
articleFilename: string,
): Promise<ArticleWithSlug> {
let { article } = (await import(`../app/articles/${articleFilename}`)) as {
default: React.ComponentType
article: Article
}
async function importBlogPost(filename: string): Promise<BlogPostWithSlug> {
let { article } = (await import(`../app/blog/${filename}`)) as {
default: React.ComponentType;
article: BlogPost;
};
return {
slug: articleFilename.replace(/(\/page)?\.mdx$/, ''),
slug: filename.replace(/(\/page)?\.mdx$/, ''),
...article,
}
};
}
export async function getAllArticles() {
export async function getAllBlogPosts() {
let articleFilenames = await glob('*/page.mdx', {
cwd: './src/app/articles',
})
cwd: './src/app/blog',
});
let articles = await Promise.all(articleFilenames.map(importArticle))
return articles.sort((a, z) => +new Date(z.date) - +new Date(a.date))
const posts = await Promise.all(articleFilenames.map(importBlogPost));
return posts.sort((a, z) => +new Date(z.date) - +new Date(a.date));
}