Convert resume into events calendar

This commit is contained in:
Tony Grosinger 2023-11-29 20:21:12 -08:00
parent 982a376264
commit 879a56d98e

View File

@ -1,20 +1,10 @@
import Image, { type ImageProps } from 'next/image'
import Link from 'next/link'
import clsx from 'clsx'
import { Button } from '@/components/Button'
import { Card } from '@/components/Card'
import { Container } from '@/components/Container'
import {
GitHubIcon,
InstagramIcon,
LinkedInIcon,
TwitterIcon,
} from '@/components/SocialIcons'
import logoAirbnb from '@/images/logos/airbnb.svg'
import logoFacebook from '@/images/logos/facebook.svg'
import logoPlanetaria from '@/images/logos/planetaria.svg'
import logoStarbucks from '@/images/logos/starbucks.svg'
import { CalendarDaysIcon, EnvelopeIcon } from '@heroicons/react/24/solid'
import image1 from '@/images/photos/image-1.jpg'
import image2 from '@/images/photos/image-2.jpg'
import image3 from '@/images/photos/image-3.jpg'
@ -23,65 +13,6 @@ import image5 from '@/images/photos/image-5.jpg'
import { type BlogPostWithSlug, getAllBlogPosts } from '@/lib/articles'
import { formatDate } from '@/lib/formatDate'
function MailIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
return (
<svg
viewBox="0 0 24 24"
fill="none"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
{...props}
>
<path
d="M2.75 7.75a3 3 0 0 1 3-3h12.5a3 3 0 0 1 3 3v8.5a3 3 0 0 1-3 3H5.75a3 3 0 0 1-3-3v-8.5Z"
className="fill-zinc-100 stroke-zinc-400 dark:fill-zinc-100/10 dark:stroke-zinc-500"
/>
<path
d="m4 6 6.024 5.479a2.915 2.915 0 0 0 3.952 0L20 6"
className="stroke-zinc-400 dark:stroke-zinc-500"
/>
</svg>
)
}
function BriefcaseIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
return (
<svg
viewBox="0 0 24 24"
fill="none"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
{...props}
>
<path
d="M2.75 9.75a3 3 0 0 1 3-3h12.5a3 3 0 0 1 3 3v8.5a3 3 0 0 1-3 3H5.75a3 3 0 0 1-3-3v-8.5Z"
className="fill-zinc-100 stroke-zinc-400 dark:fill-zinc-100/10 dark:stroke-zinc-500"
/>
<path
d="M3 14.25h6.249c.484 0 .952-.002 1.316.319l.777.682a.996.996 0 0 0 1.316 0l.777-.682c.364-.32.832-.319 1.316-.319H21M8.75 6.5V4.75a2 2 0 0 1 2-2h2.5a2 2 0 0 1 2 2V6.5"
className="stroke-zinc-400 dark:stroke-zinc-500"
/>
</svg>
)
}
function ArrowDownIcon(props: React.ComponentPropsWithoutRef<'svg'>) {
return (
<svg viewBox="0 0 16 16" fill="none" aria-hidden="true" {...props}>
<path
d="M4.75 8.75 8 12.25m0 0 3.25-3.5M8 12.25v-8.5"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
)
}
function Article({ article }: { article: BlogPostWithSlug }) {
return (
<Card as="article">
@ -97,19 +28,6 @@ function Article({ article }: { article: BlogPostWithSlug }) {
)
}
function SocialLink({
icon: Icon,
...props
}: React.ComponentPropsWithoutRef<typeof Link> & {
icon: React.ComponentType<{ className?: string }>
}) {
return (
<Link className="group -m-1 p-1" {...props}>
<Icon className="h-6 w-6 fill-zinc-500 transition group-hover:fill-zinc-600 dark:fill-zinc-400 dark:group-hover:fill-zinc-300" />
</Link>
)
}
function Newsletter() {
return (
<form
@ -117,11 +35,11 @@ function Newsletter() {
className="rounded-2xl border border-zinc-100 p-6 dark:border-zinc-700/40"
>
<h2 className="flex text-sm font-semibold text-zinc-900 dark:text-zinc-100">
<MailIcon className="h-6 w-6 flex-none" />
<EnvelopeIcon className="h-6 w-6 flex-none fill-zinc-100 stroke-zinc-400 dark:fill-zinc-100/10 dark:stroke-zinc-500" />
<span className="ml-3">Stay up to date</span>
</h2>
<p className="mt-2 text-sm text-zinc-600 dark:text-zinc-400">
Get notified when I publish something new, and unsubscribe at any time.
Get notified about upcoming events and stay in touch with the community.
</p>
<div className="mt-6 flex">
<input
@ -139,100 +57,77 @@ function Newsletter() {
)
}
interface Role {
company: string
interface Meeting {
title: string
logo: ImageProps['src']
start: string | { label: string; dateTime: string }
end: string | { label: string; dateTime: string }
date: string
startTime: string
endTime?: string
notes?: string
}
function Role({ role }: { role: Role }) {
let startLabel =
typeof role.start === 'string' ? role.start : role.start.label
let startDate =
typeof role.start === 'string' ? role.start : role.start.dateTime
let endLabel = typeof role.end === 'string' ? role.end : role.end.label
let endDate = typeof role.end === 'string' ? role.end : role.end.dateTime
function MeetingListItem({ meeting }: { meeting: Meeting }) {
return (
<li className="flex gap-4">
<div className="relative mt-1 flex h-10 w-10 flex-none items-center justify-center rounded-full shadow-md shadow-zinc-800/5 ring-1 ring-zinc-900/5 dark:border dark:border-zinc-700/50 dark:bg-zinc-800 dark:ring-0">
<Image src={role.logo} alt="" className="h-7 w-7" unoptimized />
</div>
<dl className="flex flex-auto flex-wrap gap-x-2">
<dt className="sr-only">Company</dt>
<dt className="sr-only">Title</dt>
<dd className="w-full flex-none text-sm font-medium text-zinc-900 dark:text-zinc-100">
{role.company}
</dd>
<dt className="sr-only">Role</dt>
<dd className="text-xs text-zinc-500 dark:text-zinc-400">
{role.title}
{meeting.title}
</dd>
<dt className="sr-only">Date</dt>
<dd
className="ml-auto text-xs text-zinc-400 dark:text-zinc-500"
aria-label={`${startLabel} until ${endLabel}`}
>
<time dateTime={startDate}>{startLabel}</time>{' '}
<span aria-hidden="true"></span>{' '}
<time dateTime={endDate}>{endLabel}</time>
<dd className="text-xs text-zinc-500 dark:text-zinc-400">
{meeting.date}
</dd>
<dt className="sr-only">Time</dt>
{meeting.endTime
? <dd
className="ml-auto text-xs text-zinc-400 dark:text-zinc-500"
aria-label={`${meeting.startTime} until ${meeting.endTime}`}
>
<time dateTime={meeting.date + ' ' + meeting.startTime}>{meeting.startTime}</time>{' '}
<span aria-hidden="true"></span>{' '}
<time dateTime={meeting.date + ' ' + meeting.endTime}>{meeting.endTime}</time>{' '}
</dd>
: <dd
className="ml-auto text-xs text-zinc-400 dark:text-zinc-500"
aria-label={`${meeting.startTime}`}
>
<time dateTime={meeting.date + ' ' + meeting.startTime}>{meeting.startTime}</time>{' '}
</dd>
}
</dl>
</li>
)
}
function Resume() {
let resume: Array<Role> = [
function Events() {
let events: Array<Meeting> = [
{
company: 'Planetaria',
title: 'CEO',
logo: logoPlanetaria,
start: '2019',
end: {
label: 'Present',
dateTime: new Date().getFullYear().toString(),
},
title: 'Christmas Potluck',
date: '2023-12-16',
startTime: '6:00pm',
},
{
company: 'Airbnb',
title: 'Product Designer',
logo: logoAirbnb,
start: '2014',
end: '2019',
},
{
company: 'Facebook',
title: 'iOS Software Engineer',
logo: logoFacebook,
start: '2011',
end: '2014',
},
{
company: 'Starbucks',
title: 'Shift Supervisor',
logo: logoStarbucks,
start: '2008',
end: '2011',
title: 'Member Meeting',
date: '2023-12-20',
startTime: '6:00pm',
endTime: '8:00pm',
notes: 'Bring your own chair.'
},
]
return (
<div className="rounded-2xl border border-zinc-100 p-6 dark:border-zinc-700/40">
<h2 className="flex text-sm font-semibold text-zinc-900 dark:text-zinc-100">
<BriefcaseIcon className="h-6 w-6 flex-none" />
<span className="ml-3">Work</span>
<CalendarDaysIcon className="h-6 w-6 flex-none fill-zinc-100 stroke-zinc-400 dark:fill-zinc-100/10 dark:stroke-zinc-500" />
<span className="ml-3">Upcoming Events</span>
</h2>
<ol className="mt-6 space-y-4">
{resume.map((role, roleIndex) => (
<Role key={roleIndex} role={role} />
{events.map((meeting, idx) => (
<MeetingListItem key={idx} meeting={meeting} />
))}
</ol>
<Button href="#" variant="secondary" className="group mt-6 w-full">
Download CV
<ArrowDownIcon className="h-4 w-4 stroke-zinc-400 transition group-active:stroke-zinc-600 dark:group-hover:stroke-zinc-50 dark:group-active:stroke-zinc-50" />
Full Calendar
</Button>
</div>
)
@ -276,33 +171,14 @@ export default async function Home() {
West Sound Community Hall
</h1>
<p className="mt-6 text-base text-zinc-600 dark:text-zinc-400">
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.
The West Sound Community Hall is located in the hamlet of West Sound
on Orcas Island, about 10 minutes from the ferry landing and
Eastsound. It 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
href="https://twitter.com"
aria-label="Follow on Twitter"
icon={TwitterIcon}
/>
<SocialLink
href="https://instagram.com"
aria-label="Follow on Instagram"
icon={InstagramIcon}
/>
<SocialLink
href="https://github.com"
aria-label="Follow on GitHub"
icon={GitHubIcon}
/>
<SocialLink
href="https://linkedin.com"
aria-label="Follow on LinkedIn"
icon={LinkedInIcon}
/>
</div>
</div>
</Container>
<Photos />
@ -315,7 +191,7 @@ export default async function Home() {
</div>
<div className="space-y-10 lg:pl-16 xl:pl-24">
<Newsletter />
<Resume />
<Events />
</div>
</div>
</Container>