diff options
Diffstat (limited to 'website/src/components')
| -rw-r--r-- | website/src/components/BaseHead.astro | 44 | ||||
| -rw-r--r-- | website/src/components/BlogFeed.astro | 76 | ||||
| -rw-r--r-- | website/src/components/FormattedDate.astro | 21 | ||||
| -rw-r--r-- | website/src/components/Me.astro | 43 |
4 files changed, 184 insertions, 0 deletions
diff --git a/website/src/components/BaseHead.astro b/website/src/components/BaseHead.astro new file mode 100644 index 0000000..e8e44ab --- /dev/null +++ b/website/src/components/BaseHead.astro @@ -0,0 +1,44 @@ +--- +interface Props { + title: string; + description: string; + image?: string; +} + +const canonicalURL = new URL(Astro.url.pathname, Astro.site); + +const { title, description, image = '/images/headshot.jpg' } = Astro.props; +--- + +<!-- Stylesheets --> +<link rel="stylesheet" href="/css/reset.css" /> +<link rel="stylesheet" href="/css/base.css" /> +<link rel="stylesheet" href="/css/hcard.css" /> + +<!-- Global Metadata --> +<meta charset="utf-8" /> +<meta name="viewport" content="width=device-width,initial-scale=1" /> +<link rel="icon" type="image/svg+xml" href="/favicon.svg" /> +<meta name="generator" content={Astro.generator} /> + +<!-- Canonical URL --> +<link rel="canonical" href={canonicalURL} /> + +<!-- Primary Meta Tags --> +<title>{title}</title> +<meta name="title" content={title} /> +<meta name="description" content={description} /> + +<!-- Open Graph / Facebook --> +<meta property="og:type" content="website" /> +<meta property="og:url" content={Astro.url} /> +<meta property="og:title" content={title} /> +<meta property="og:description" content={description} /> +<meta property="og:image" content={new URL(image, Astro.url)} /> + +<!-- Twitter --> +<meta property="twitter:card" content="summary_large_image" /> +<meta property="twitter:url" content={Astro.url} /> +<meta property="twitter:title" content={title} /> +<meta property="twitter:description" content={description} /> +<meta property="twitter:image" content={new URL(image, Astro.url)} /> diff --git a/website/src/components/BlogFeed.astro b/website/src/components/BlogFeed.astro new file mode 100644 index 0000000..b6f9d55 --- /dev/null +++ b/website/src/components/BlogFeed.astro @@ -0,0 +1,76 @@ +--- +import type { CollectionEntry } from 'astro:content'; +import { getCollection } from 'astro:content'; + +export interface Props { + headingLevel?: 1 | 2 | 3 | 4 | 5 | 6, + hideAuthor?: boolean, +}; + +const { headingLevel = 2, hideAuthor = false } = Astro.props; + +const posts = (await getCollection('blog')); + +const distinctYears: number[] = posts + .map(post => post.data.pubDate.year) + .reduce<number[]>((acc, curr) => acc.includes(curr) ? acc : [...acc, curr], []) + .sort((a, b) => b - a); + +function matchesYear(year: number) { + return (post: CollectionEntry<'blog'>) => post.data.pubDate.year === year; +} + +function sortByPubDateDescending(post1: CollectionEntry<'blog'>, post2: CollectionEntry<'blog'>) { + const year1 = post1.data.pubDate.year; + const year2 = post2.data.pubDate.year; + const month1 = post1.data.pubDate.month; + const month2 = post2.data.pubDate.month; + const day1 = post1.data.pubDate.day; + const day2 = post2.data.pubDate.day; + + if (year1 !== year2) { + return year2 - year1; + } else if (month1 !== month2) { + return month2 - month1; + } else { + return day2 - day1; + } +} + +const headingElem = `h${headingLevel}`; + +const canonicalBlogUrl = new URL('blog', Astro.site) +--- + +<section class="h-feed"> + <Fragment set:html={` + <${headingElem} class="p-name"> + My blog + </${headingElem}> + `} /> + + <aside> + <p class={hideAuthor ? 'hidden' : ''}> + This blog is written by <a class="p-author h-card" href="/">Joe Carstairs</a> + </p> + + <p> + <a class="u-url" href={canonicalBlogUrl}>Permalink</a> + </p> + </aside> + + <ul> + { distinctYears.map(year => ( + <li> + {year} + <ul> + { posts.filter(matchesYear(year)).sort(sortByPubDateDescending).map(post => ( + <li class="h-entry"> + <a class="u-url p-name" href={`/blog/${post.slug}`}>{post.data.title}</a> + </li> + )) } + </ul> + </li> + )) } + </ul> +</section>
\ No newline at end of file diff --git a/website/src/components/FormattedDate.astro b/website/src/components/FormattedDate.astro new file mode 100644 index 0000000..bb7a2c0 --- /dev/null +++ b/website/src/components/FormattedDate.astro @@ -0,0 +1,21 @@ +--- +interface Props { + className?: string; + date: Date | string; +} + +let { className, date } = Astro.props; +if (typeof(date) === 'string') { + date = new Date(date); +} +--- + +<time datetime={date.toISOString()} class={className ?? ''}> + { + date.toLocaleDateString('en-GB', { + year: 'numeric', + month: 'long', + day: 'numeric', + }) + } +</time> diff --git a/website/src/components/Me.astro b/website/src/components/Me.astro new file mode 100644 index 0000000..c9af587 --- /dev/null +++ b/website/src/components/Me.astro @@ -0,0 +1,43 @@ +--- +--- + +<section class="h-card"> + <img class="u-photo" src="/images/headshot.jpg" height="256" width="256" /> + + <div> + <h1> + <a class="p-name u-url u-uid" href="https://joeac.net" rel="me"> + Joe Carstairs + </a> + </h1> + + <p> + Hi! 👋 My name is <span class="p-given-name">Joe</span> + <span class="p-family-name">Carstairs</span>. I’m a + <span class="p-job-title">software developer</span> at + <a class="p-org" href="https://www.scottlogic.com">Scott Logic</a>, a + graduate of Philosophy and Mathematics at the University of Edinburgh, + a committed Christian and a pretty rubbish poet. + </p> + + <p> + I’m also the <span class="p-job-title">secretary</span> of the + <a class="p-org" href="https://scotsleidassocie.org">Scots Language Society</a>. + <a href="https://github.com/joeacarstairs/lallans-wabsteid-astro">Help me maintain our website!</a> + </p> + + <p> + Email me at + <a class="u-email" href="mailto:joeacarstairs@gmail.com">joeacarstairs@gmail.com</a> + with your thoughts on metaethics, Scots verse and eschatology. + </p> + + <p> + Or get me on + <a href="https://www.facebook.com/joe.carstairs.5" rel="me">Facebook</a>, + <a href="https://mastodon.social/@joe_carstairs" rel="me">Mastodon</a>, + <a href="https://www.linkedin.com/in/joe-carstairs-0aa936277" rel="me">LinkedIn</a>, + or <a href="https://github.com/joeacarstairs" rel="me">GitHub</a>. + </p> + </div> +</section>
\ No newline at end of file |
