1import { html } from "../html";
2import { aboutString, router } from "../main";
3import { OptionsSection } from "./OptionsSection";
4
5type FooterColumn =
6 | {
7 type: "main";
8 title: string;
9 content?: string;
10 }
11 | {
12 type: "links";
13 title: string;
14 links: {
15 text: string;
16 link: string;
17 hint?: string;
18 internal?: boolean;
19 }[];
20 };
21
22function footerColumns(): FooterColumn[] {
23 const links: { text: string; link: string; hint?: string }[] = [
24 { text: "git", link: "https://tangled.sh/@wlo.moe/www" },
25 { text: "bluesky", link: "https://bsky.app/profile/wlo.moe" },
26 { text: "email", link: "mailto:hai@wlo.moe", hint: "hai@wlo.moe" },
27 { text: "discuit", link: "https://discuit.org/@sillowww" },
28 {
29 text: "discord",
30 link: "https://discord.com/users/1357056975812301013",
31 hint: "you might only be able to use this link if you share a server with me, my username is @_sillowww",
32 },
33 ];
34
35 const footerColumns: FooterColumn[] = [
36 {
37 type: "main",
38 title: "willow.",
39 content: html`
40 <p>${aboutString}</p>
41 <p>
42 this site is licensed under the gnu affero general public license
43 version 3.
44 </p>
45 <p>
46 source code is available on tangled.sh <a href="https://tangled.sh/@wlo.moe/www">here</a>.
47 </p>
48 `,
49 },
50 {
51 type: "links",
52 title: "links.",
53 links,
54 },
55 {
56 type: "links",
57 title: "pages.",
58 links: router.routes.map((route) => ({
59 text: route.title || "unknown",
60 link: route.path,
61 internal: true,
62 })),
63 },
64 ];
65
66 return footerColumns;
67}
68
69function FooterLink(props: {
70 text: string;
71 link: string;
72 hint?: string;
73 internal?: boolean;
74}) {
75 return html`<li>
76 <a href="${props.link}" class="footer__link" data-link="${props.internal ? "true" : undefined}">
77 ${props.text}
78 ${props.hint ? html`<span class="hint">${props.hint}</span>` : ""}
79 </a>
80 </li>`;
81}
82
83function FooterColumn(props: FooterColumn) {
84 if (props.type === "main") {
85 return html`<div class="footer__column footer__column-main">
86 <h2>${props.title}</h2>
87 ${props.content || html`<p>no content provided.</p>`}
88 ${OptionsSection()}
89 </div>`;
90 }
91
92 return html`<div class="footer__column footer__column-links">
93 <h3>${props.title}</h3>
94 <ul>
95 ${props.links.map((link) => FooterLink(link))}
96 </ul>
97 </div>`;
98}
99
100export function Footer() {
101 const columns = footerColumns();
102
103 return html`<footer className="footer">
104 ${columns.map((column) => FooterColumn(column))}
105 </footer>`;
106}