Renaming pages and adding content
This commit is contained in:
parent
e2e9ab6774
commit
e0de86bb5a
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "tailwindui-template",
|
||||
"name": "wscc-website",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
/** @type {import('prettier').Options} */
|
||||
module.exports = {
|
||||
singleQuote: true,
|
||||
semi: false,
|
||||
semi: true,
|
||||
plugins: ['prettier-plugin-tailwindcss'],
|
||||
}
|
||||
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
@ -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
101
src/app/club/page.tsx
Normal 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>
|
||||
)
|
||||
}
|
@ -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',
|
||||
},
|
||||
})
|
||||
});
|
||||
}
|
||||
|
301
src/app/hall-history/page.tsx
Normal file
301
src/app/hall-history/page.tsx
Normal 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'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's Christian Temperance Union Woodmen Lodge'
|
||||
/>
|
||||
<DateListItem
|
||||
value='West Sound Literary Society'
|
||||
/>
|
||||
<DateListItem
|
||||
year='1911'
|
||||
value='West Sound Boy'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'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'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>
|
||||
)
|
||||
}
|
@ -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">
|
||||
I’m Spencer, a software designer and entrepreneur based in New York
|
||||
City. I’m 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
|
||||
|
@ -48,12 +48,12 @@ function MailIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
|
||||
}
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'About',
|
||||
title: 'History',
|
||||
description:
|
||||
'I’m 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">
|
||||
I’m 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>
|
||||
I’ve 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 sister’s motorcycle helmet, counted
|
||||
down from three, and jumped — hoping the tree was tall enough that
|
||||
with just a bit of momentum I’d 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 dad’s Blackberry into orbit and was able to transmit a
|
||||
photo back down to our family computer from space.
|
||||
</p>
|
||||
<p>
|
||||
Today, I’m the founder of Planetaria, where we’re 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>
|
@ -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()
|
||||
|
@ -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">
|
||||
© {new Date().getFullYear()} Spencer Sharp. All rights
|
||||
|
@ -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>
|
||||
)
|
||||
|
@ -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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user