my website built with vue, plus lexicon definitions for moe.wlo.gallery.* vt3e.cat
at develop 2.5 kB view raw
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}