85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
|
import { Document } from "asciidoctor";
|
||
|
import { DateTime } from "luxon";
|
||
|
|
||
|
type HeaderProps = {
|
||
|
asset(path: string): string;
|
||
|
};
|
||
|
|
||
|
const Header = ({ asset }: HeaderProps) => (
|
||
|
<header class="index-header">
|
||
|
<div style={{ flex: 1 }}>
|
||
|
<h1>Adædra</h1>
|
||
|
Software developer
|
||
|
<br />
|
||
|
Rust, Ruby, TypeScript, Linux
|
||
|
<br />
|
||
|
Paris, France
|
||
|
</div>
|
||
|
<img src={asset("cariboudev.avif")} alt="Adaedra's mascot" />
|
||
|
</header>
|
||
|
);
|
||
|
|
||
|
type ArticleProps = {
|
||
|
articles: [string, DateTime, Document][];
|
||
|
};
|
||
|
|
||
|
const Articles = ({ articles }: ArticleProps) => (
|
||
|
<>
|
||
|
<h2>Latest articles</h2>
|
||
|
<ul class="index-list">
|
||
|
{articles.map(([slug, date, article]) => (
|
||
|
<li>
|
||
|
{date.toISODate()}
|
||
|
<a
|
||
|
href={`/${slug}/`}
|
||
|
dangerouslySetInnerHTML={{
|
||
|
__html: article.getDocumentTitle() as string,
|
||
|
}}
|
||
|
/>
|
||
|
</li>
|
||
|
))}
|
||
|
</ul>
|
||
|
</>
|
||
|
);
|
||
|
|
||
|
type Props = HeaderProps & ArticleProps;
|
||
|
|
||
|
const SOCIALS: [string, string, string][] = [
|
||
|
["Gitea", "https://gitea.adaedra.eu", "git"],
|
||
|
["Mastodon", "https://nerdculture.de/@adaedra", "mastodon"],
|
||
|
["LinkedIn", "https://www.linkedin.com/in/thibault-hamel/", "linkedin"],
|
||
|
];
|
||
|
|
||
|
const Socials = () => (
|
||
|
<>
|
||
|
<h2>Find me elsewhere</h2>
|
||
|
<ul class="index-list">
|
||
|
{SOCIALS.map(([name, url, svgId]) => (
|
||
|
<li>
|
||
|
<a href={url} target="_blank" rel="noopener">
|
||
|
<svg
|
||
|
xmlns="http://www.w3.org/2000/svg"
|
||
|
viewBox="0 0 32 32"
|
||
|
aria-label={`${name} Logo`}
|
||
|
>
|
||
|
<use href={`/logos.svg#${svgId}`} />
|
||
|
</svg>
|
||
|
{name}
|
||
|
</a>
|
||
|
</li>
|
||
|
))}
|
||
|
</ul>
|
||
|
</>
|
||
|
);
|
||
|
|
||
|
const Footer = () => <footer class="index-footer"></footer>;
|
||
|
|
||
|
export default ({ asset, articles }: Props) => (
|
||
|
<>
|
||
|
<Header asset={asset} />
|
||
|
<Articles articles={articles} />
|
||
|
<Socials />
|
||
|
<Footer />
|
||
|
</>
|
||
|
);
|