Add favicon, misc code changes

This commit is contained in:
Taevas 2025-04-10 22:05:49 +02:00
parent 89d7cab81f
commit 9b6c1649a7
Signed by: Taevas
SSH key fingerprint: SHA256:Y5Hv18xwPvUKSlgkx1sPnRO3L2mc03ehC7BzrnZVEyY
35 changed files with 91 additions and 103 deletions

View file

@ -28,7 +28,7 @@ export const kitsudev: Handler = async () => {
const info: KitsudevInfo = { const info: KitsudevInfo = {
url: kitsudev[0].html_url, url: kitsudev[0].html_url,
message: kitsudev[0].commit.message, message: kitsudev[0].commit.message.substring(0, kitsudev[0].commit.message.indexOf("\n")),
author: kitsudev[0].commit.author.name, author: kitsudev[0].commit.author.name,
date: kitsudev[0].commit.author.date, date: kitsudev[0].commit.author.date,
files_modified: kitsudev[0].files.length, files_modified: kitsudev[0].files.length,

BIN
assets/blobcatlain.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
bun.lockb

Binary file not shown.

View file

@ -1,6 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<title>Site - taevas.xyz</title>
<link rel="icon" type="image/x-icon" href="/assets/blobcatlain.png">
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta <meta
name="viewport" name="viewport"
@ -8,7 +10,6 @@
/> />
<link rel="stylesheet" href="./index.css"> <link rel="stylesheet" href="./index.css">
<script defer src="https://visitors.taevas.xyz/script.js" data-website-id="f196d626-e609-4841-9a80-0dc60f523ed5"></script> <script defer src="https://visitors.taevas.xyz/script.js" data-website-id="f196d626-e609-4841-9a80-0dc60f523ed5"></script>
<title>Site - taevas.xyz</title>
</head> </head>
<body class="bg-linear-to-tl from-amber-100 via-sky-300 to-amber-100 bg-fixed"> <body class="bg-linear-to-tl from-amber-100 via-sky-300 to-amber-100 bg-fixed">
<span id="links" style="display: none;"> <span id="links" style="display: none;">
@ -39,7 +40,7 @@
<span class="p-region">Brittany</span> <span class="p-region">Brittany</span>
<span class="p-country-name">France</span> <span class="p-country-name">France</span>
</div> </div>
<div id="root"> <div id="root" class="flex text-center">
</div> </div>
<script type="module" src="./src/App.tsx"></script> <script type="module" src="./src/App.tsx"></script>

View file

@ -8,7 +8,7 @@
}, },
"dependencies": { "dependencies": {
"@bachmacintosh/wanikani-api-types": "^1.8.0", "@bachmacintosh/wanikani-api-types": "^1.8.0",
"@carbon/icons-react": "^11.57.0", "@carbon/icons-react": "^11.58.0",
"@gitbeaker/rest": "^42.2.0", "@gitbeaker/rest": "^42.2.0",
"@octokit/rest": "^20.1.2", "@octokit/rest": "^20.1.2",
"osu-api-v2-js": "^1.1.2", "osu-api-v2-js": "^1.1.2",
@ -22,9 +22,9 @@
"@stylistic/eslint-plugin": "^3.1.0", "@stylistic/eslint-plugin": "^3.1.0",
"@tailwindcss/forms": "^0.5.10", "@tailwindcss/forms": "^0.5.10",
"@tailwindcss/postcss": "^4.1.3", "@tailwindcss/postcss": "^4.1.3",
"@types/bun": "^1.2.8", "@types/bun": "^1.2.9",
"@types/react": "^19.1.0", "@types/react": "^19.1.0",
"@types/react-dom": "^19.1.1", "@types/react-dom": "^19.1.2",
"dotenv": "^16.4.7", "dotenv": "^16.4.7",
"eslint": "^9.24.0", "eslint": "^9.24.0",
"eslint-config-xo-typescript": "^7.0.0", "eslint-config-xo-typescript": "^7.0.0",
@ -34,7 +34,7 @@
"tailwindcss": "^4.1.3", "tailwindcss": "^4.1.3",
"typescript": "^5.8.3", "typescript": "^5.8.3",
"typescript-eslint": "^8.29.1", "typescript-eslint": "^8.29.1",
"vite": "^6.2.5" "vite": "^6.2.6"
}, },
"imports": { "imports": {
"#Main/*": "./src/Main/*", "#Main/*": "./src/Main/*",

View file

@ -33,7 +33,7 @@
font-style: normal; font-style: normal;
} }
.App { body {
font-family: "IBMPlexMono", "Arial", sans-serif; font-family: "IBMPlexMono", "Arial", sans-serif;
} }

View file

@ -8,9 +8,7 @@ import Infos from "./Infos/index.tsx";
const root = createRoot(document.getElementById("root")!); const root = createRoot(document.getElementById("root")!);
root.render( root.render(
<React.StrictMode> <React.StrictMode>
<div className="App flex text-center bg-linear-to-tl from-amber-100 via-sky-300 to-amber-100 bg-fixed"> <MainContent/>
<MainContent/> <Infos/>
<Infos/>
</div>
</React.StrictMode>, </React.StrictMode>,
); );

View file

@ -24,13 +24,13 @@ export default function GitHub() {
if (data.private) { if (data.private) {
elms.push( elms.push(
<p key={"github-date-private"} className={data.public ? "mb-2" : ""}>Latest <strong>private</strong> push: <strong>{data.private.date}</strong></p>, <p key="github-date-private" className={data.public ? "mb-2" : ""}>Latest <strong>private</strong> push: <time>{data.private.date}</time></p>,
); );
} }
if (data.public) { if (data.public) {
elms.push( elms.push(
<p key={"github-date-public"}>Latest <strong>public</strong> push: <strong>{data.public.date}</strong></p>, <p key="github-date-public">Latest <strong>public</strong> push: <time>{data.public.date}</time></p>,
); );
elms.push( elms.push(
<Link classes="mt-1 px-1 py-2 inline-block w-full font-bold leading-[18px] bg-white text-blue-800" link={`https://github.com/${data.public.repo}`} text={data.public.repo}/> <Link classes="mt-1 px-1 py-2 inline-block w-full font-bold leading-[18px] bg-white text-blue-800" link={`https://github.com/${data.public.repo}`} text={data.public.repo}/>

View file

@ -14,7 +14,7 @@ export default function GitLab() {
if (data) { if (data) {
try { try {
setElements([ setElements([
<p key={"gitlab-date"}>Latest push: <strong>{data.date}</strong></p>, <p key="gitlab-date">Latest push: <time>{data.date}</time></p>,
]); ]);
} catch { } catch {
setError(true); setError(true);

View file

@ -17,8 +17,8 @@ export default function KitsuDev() {
if (data) { if (data) {
try { try {
setElements([ setElements([
<p key={"kitsudev-date"}>Latest activity: <strong>{data.date.substring(0, data.date.indexOf("T"))}</strong></p>, <p key="kitsudev-date">Latest activity: <time dateTime={data.date}>{data.date.substring(0, data.date.indexOf("T"))}</time></p>,
<Link key={"kitsudev-link"} classes="mt-1 px-1 py-2 inline-block w-full font-bold leading-[18px] bg-white text-blue-800" link={data.url} text={data.name}/> <Link key="kitsudev-link" classes="mt-1 px-1 py-2 inline-block w-full font-bold leading-[18px] bg-white text-blue-800" link={data.url} text={data.name}/>
]); ]);
} catch { } catch {
setError(true); setError(true);

View file

@ -5,9 +5,9 @@ import GitLab from "./GitLab.tsx";
import KitsuDev from "./KitsuDev.tsx"; import KitsuDev from "./KitsuDev.tsx";
export default function Coding() { export default function Coding() {
const github = <GitHub key={"github"}/>; const github = <GitHub key="github"/>;
const gitlab = <GitLab key={"gitlab"}/>; const gitlab = <GitLab key="gitlab"/>;
const kitsudev = <KitsuDev key={"kitsudev"}/>; const kitsudev = <KitsuDev key="kitsudev"/>;
return ( return (
<Info <Info

View file

@ -27,17 +27,17 @@ export default function KitsuClub() {
const date = new Date(data.date).toISOString(); const date = new Date(data.date).toISOString();
const images: React.JSX.Element[] = data.images.map((i, index) => <img className="mt-2" key={`img-${index}`} src={i.url} alt={i.alt}/>); const images: React.JSX.Element[] = data.images.map((i, index) => <img className="mt-2" key={`img-${index}`} src={i.url} alt={i.alt}/>);
setElements([ setElements([
<div key={"kitsuclub-details"} className="text-left mb-2"> <div key="kitsuclub-details" className="text-left mb-2">
<img key={"kitsuclub-avatar"} src={data.avatar} alt="avatar" className="float-left rounded-lg w-12 mr-2"/> <img key="kitsuclub-avatar" src={data.avatar} alt="avatar" className="float-left rounded-lg w-12 mr-2"/>
<strong key={"kitsuclub-username"} className="inline-flex">{...emojify(data.username, data.emojis)}</strong> <strong key="kitsuclub-username" className="inline-flex">{...emojify(data.username, data.emojis)}</strong>
<br/> <br/>
<time key={"kitsuclub-date"} className="inline-flex text-sm" dateTime={date}> <time key="kitsuclub-date" className="inline-flex text-sm" dateTime={date}>
{date.substring(0, date.indexOf("T")).concat(" " + date.substring(date.indexOf("T") + 1, date.indexOf(".")) + " UTC")} {date.substring(0, date.indexOf("T")).concat(" " + date.substring(date.indexOf("T") + 1, date.indexOf(".")) + " UTC")}
</time> </time>
</div>, </div>,
// emojis that are only in the post aren't in the response yet :( // emojis that are only in the post aren't in the response yet :(
<Link classes="mt-1 px-2 py-2 inline-block font-bold leading-[24px] bg-white text-blue-800 text-left text-sm" <Link classes="mt-1 px-2 py-2 inline-block font-bold leading-[24px] bg-white text-blue-800 text-left text-sm"
key={"link"} link={`https://kitsunes.club/notes/${data.note_id}`} text={<p>{ key="link" link={`https://kitsunes.club/notes/${data.note_id}`} text={<p>{
...data.text.split("\n").map((te) => emojify(te, data.emojis).concat(<br/>)) ...data.text.split("\n").map((te) => emojify(te, data.emojis).concat(<br/>))
.concat(images) .concat(images)
}</p>} }</p>}

View file

@ -3,7 +3,7 @@ import Info from "../Info.tsx";
import KitsuClub from "./KitsuClub.tsx"; import KitsuClub from "./KitsuClub.tsx";
export default function Hacking() { export default function Hacking() {
const kitsuclub = <KitsuClub key={"kitsuclub"}/>; const kitsuclub = <KitsuClub key="kitsuclub"/>;
return ( return (
<Info <Info

View file

@ -23,17 +23,17 @@ export default function Speedruncom() {
if (data) { if (data) {
try { try {
setElements([ setElements([
<div key={"data"} className="flex pb-2"> <div key="data" className="flex pb-2">
<img alt="game thumbnail" src={data.thumbnail} className="h-24 m-auto" /> <img alt="game thumbnail" src={data.thumbnail} className="h-24 m-auto" />
<div className="m-auto ml-4 w-full"> <div className="m-auto ml-4 w-full">
<Link key={"more"} classes="text-lg/6 inline-block px-1 py-2 w-full font-bold bg-white text-blue-800" link={data.link} <Link key="more" classes="text-lg/6 inline-block px-1 py-2 w-full font-bold bg-white text-blue-800" link={data.link}
text={`${data.game} (${data.details.toString()}) in ${data.time}`}/> text={`${data.game} (${data.details.toString()}) in ${data.time}`}/>
</div> </div>
</div>, </div>,
<p key="placement" className="mt-2">Placed <strong>#{data.place}</strong></p>, <p key="placement" className="mt-2">Placed <strong>#{data.place}</strong></p>,
<p key="date" className="font-bold">{data.date}</p>, <time key="date">{data.date}</time>,
<> { <> {
data.video ? <ButtonLink key={"youtube"} link={data.video} text="YouTube video"/> : "" data.video ? <ButtonLink key="youtube" link={data.video} text="YouTube video"/> : ""
} </> } </>
]); ]);

View file

@ -11,15 +11,15 @@ export default function RhythmGames() {
const [websites, setWebsites] = useState([] as React.JSX.Element[]); const [websites, setWebsites] = useState([] as React.JSX.Element[]);
useEffect(() => { useEffect(() => {
setWebsites([<Speedruncom key={"speedruncom"}/>]); setWebsites([<Speedruncom key="speedruncom"/>]);
}, []); }, []);
// useEffect(() => { // useEffect(() => {
// if (data) { // if (data) {
// const osu = <Osu ruleset={Ruleset.osu} key={"osu"}/>; // const osu = <Osu ruleset={Ruleset.osu} key="osu"/>;
// const taiko = <Osu ruleset={Ruleset.taiko} key={"taiko"}/>; // const taiko = <Osu ruleset={Ruleset.taiko} key="taiko"/>;
// const fruits = <Osu ruleset={Ruleset.fruits} key={"fruits"}/>; // const fruits = <Osu ruleset={Ruleset.fruits} key="fruits"/>;
// const mania = <Osu ruleset={Ruleset.mania} key={"mania"}/>; // const mania = <Osu ruleset={Ruleset.mania} key="mania"/>;
// setWebsites(websites.concat([osu, taiko, fruits, mania])); // setWebsites(websites.concat([osu, taiko, fruits, mania]));
// } // }
// }, [data]); // }, [data]);

View file

@ -21,7 +21,7 @@ export default function Hackthebox() {
if (data) { if (data) {
try { try {
setElements([ setElements([
<div key={"data"} className="flex"> <div key="data" className="flex">
{ {
data.type === "user" ? data.type === "user" ?
<img className="m-auto h-16 w-16" alt="machine thumbnail" src={data.machine_avatar}/> : <img className="m-auto h-16 w-16" alt="machine thumbnail" src={data.machine_avatar}/> :
@ -34,8 +34,8 @@ export default function Hackthebox() {
<p>({data.type})</p> <p>({data.type})</p>
</div> </div>
</div>, </div>,
<p key={"date"} className="mt-2 font-bold">{data.date}</p>, <time key="date" className="mt-2">{data.date}</time>,
<ButtonLink key={"more"} link={`https://app.hackthebox.com/machines/${data.name}`} text="Machine Link" />, <ButtonLink key="more" link={`https://app.hackthebox.com/machines/${data.name}`} text="Machine Link" />,
]); ]);
} catch { } catch {
setError(true); setError(true);

View file

@ -3,7 +3,7 @@ import Info from "../Info.tsx";
import Hackthebox from "./Hackthebox.tsx"; import Hackthebox from "./Hackthebox.tsx";
export default function Hacking() { export default function Hacking() {
const hackthebox = <Hackthebox key={"hackthebox"}/>; const hackthebox = <Hackthebox key="hackthebox"/>;
return ( return (
<Info <Info

View file

@ -1,5 +1,5 @@
import {MisuseOutline} from "@carbon/icons-react";
import React, {Component} from "react"; import React, {Component} from "react";
import {MisuseOutline} from "@carbon/icons-react";
export default class Info extends Component<{ export default class Info extends Component<{
type: string; type: string;
@ -10,7 +10,7 @@ export default class Info extends Component<{
const state = this.props.websites.length ? 1 : this.props.error ? 2 : 0; const state = this.props.websites.length ? 1 : this.props.error ? 2 : 0;
return ( return (
<div className="m-2.5 flex w-80 hover:scale-[1.02] active:scale-[1.02]"> <article className="m-2.5 flex w-80 hover:scale-[1.02] active:scale-[1.02]">
<h2 className={`[text-orientation:upright] [writing-mode:vertical-rl] <h2 className={`[text-orientation:upright] [writing-mode:vertical-rl]
uppercase text-start text-2xl tracking-[-.1em] font-bold pt-2 pb-2 uppercase text-start text-2xl tracking-[-.1em] font-bold pt-2 pb-2
rounded-l-xl bg-white select-none rounded-l-xl bg-white select-none
@ -43,7 +43,7 @@ export default class Info extends Component<{
</div> </div>
} }
</div> </div>
</div> </article>
); );
} }
} }

View file

@ -95,9 +95,9 @@ export default function Wanikani() {
setElements([ setElements([
resets, resets,
level, level,
<p key={"lessons"} className="text-xl font-bold">Available lessons ({filteredLessons.length})</p>, <p key="lessons" className="text-xl font-bold">Available lessons ({filteredLessons.length})</p>,
lessonsDiv, lessonsDiv,
<p key={"reviews"} className="mt-4 text-xl font-bold">Available reviews ({filteredReviews.length})</p>, <p key="reviews" className="mt-4 text-xl font-bold">Available reviews ({filteredReviews.length})</p>,
reviewsDiv, reviewsDiv,
whenNextToReview, whenNextToReview,
]); ]);

View file

@ -3,7 +3,7 @@ import Info from "../Info.tsx";
import Wanikani from "./Wanikani.tsx"; import Wanikani from "./Wanikani.tsx";
export default function Japanese() { export default function Japanese() {
const wanikani = <Wanikani key={"wanikani"}/>; const wanikani = <Wanikani key="wanikani"/>;
return ( return (
<Info <Info

View file

@ -25,16 +25,16 @@ export default function Anilist() {
if (data) { if (data) {
try { try {
setElements([ setElements([
<div key={"data"} className="flex mb-4"> <div key="data" className="flex mb-4">
<img className="mx-auto w-18 h-24" alt="anime cover" src={data.cover} /> <img className="mx-auto w-18 h-24" alt="anime cover" src={data.cover} />
<div className="m-auto ml-4 w-full"> <div className="m-auto ml-4 w-full">
<Link classes="text-lg/6 inline-block px-1 py-2 w-full font-bold bg-white text-blue-800" link={data.url} text={data.title}/> <Link classes="text-lg/6 inline-block px-1 py-2 w-full font-bold bg-white text-blue-800" link={data.url} text={data.title}/>
</div> </div>
</div>, </div>,
<p key="start" className="text-left">Started: <strong>{data.startDate}</strong></p>, <p key="start" className="text-left">Started: <time>{data.startDate}</time></p>,
<p key="last" className="text-left">{data.episodes.watched >= data.episodes.total ? <p key="last" className="text-left">{data.episodes.watched >= data.episodes.total ?
<>Finished: <strong>{data.endDate}</strong></> : <>Finished: <time>{data.endDate}</time></> :
<>Ep. {data.episodes.watched}: <strong>{data.updateDate}</strong></>}</p>, <>Ep. {data.episodes.watched}: <time>{data.updateDate}</time></>}</p>,
<p key="status" className="text-left">{data.episodes.watched >= data.episodes.total ? <p key="status" className="text-left">{data.episodes.watched >= data.episodes.total ?
<>I gave it a <strong>{data.score}/10</strong></> : <>I gave it a <strong>{data.score}/10</strong></> :
<><strong>{data.episodes.watched}/{data.episodes.total}</strong> episodes watched</>}</p>, <><strong>{data.episodes.watched}/{data.episodes.total}</strong> episodes watched</>}</p>,

View file

@ -34,7 +34,7 @@ export default function Lastfm() {
<>{ <>{
data.listening ? data.listening ?
<p key="date" className="mt-2 font-bold">Currently listening!</p> : <p key="date" className="mt-2 font-bold">Currently listening!</p> :
<p key="date" className="text-left">When: <strong>{format(date)}</strong></p> <p key="date" className="text-left">When: <time dateTime={date.toISOString()}>{format(date)}</time></p>
}</>, }</>,
]); ]);
} catch { } catch {

View file

@ -4,8 +4,8 @@ import Lastfm from "./Lastfm.tsx";
import Anilist from "./Anilist.tsx"; import Anilist from "./Anilist.tsx";
export default function Media() { export default function Media() {
const lastfm = <Lastfm key={"Lastfm"}/>; const lastfm = <Lastfm key="Lastfm"/>;
const anilist = <Anilist key={"Anilist"}/>; const anilist = <Anilist key="Anilist"/>;
return ( return (
<Info <Info

View file

@ -21,9 +21,9 @@ export default function KitsuDev() {
if (data) { if (data) {
try { try {
setElements([ setElements([
<Link key={"kitsudev-link"} classes="mb-1 px-1 py-2 inline-block w-full font-bold leading-[18px] bg-white text-blue-800" link={data.url} text={data.message}/>, <Link key="kitsudev-link" classes="mb-1 px-1 py-2 inline-block w-full font-bold leading-[18px] bg-white text-blue-800" link={data.url} text={data.message}/>,
<p key={"kitsudev-date"}><strong>{data.date.substring(0, data.date.indexOf("T"))}</strong></p>, <time key="kitsudev-date" dateTime={data.date}>{data.date.substring(0, data.date.indexOf("T"))}</time>,
<p key={"kitsudev-changes"}>{data.files_modified} files changed <span className="whitespace-nowrap">(<span className="text-green-400">+{data.lines_added}</span> <span className="text-red-400">-{data.lines_removed}</span>)</span></p> <p key="kitsudev-changes">{data.files_modified} files changed <span className="whitespace-nowrap">(<span className="text-green-400">+{data.lines_added}</span> <span className="text-red-400">-{data.lines_removed}</span>)</span></p>
]); ]);
} catch { } catch {
setError(true); setError(true);

View file

@ -20,7 +20,7 @@ export default function Umami() {
try { try {
const plural = data.visits.value !== 1; const plural = data.visits.value !== 1;
setElements([ setElements([
<p className="text-left" key={"info"}>Throughout <b>the last 7 days,</b> my website has been visited <b>{data.visits.value} time{plural ? "s" : ""}!</b></p>, <p className="text-left" key="info">Throughout <b>the last 7 days,</b> my website has been visited <b>{data.visits.value} time{plural ? "s" : ""}!</b></p>,
]); ]);
} catch { } catch {
setError(true); setError(true);

View file

@ -9,12 +9,12 @@ export default function Website() {
const [websites, setWebsites] = useState([] as React.JSX.Element[]); const [websites, setWebsites] = useState([] as React.JSX.Element[]);
useEffect(() => { useEffect(() => {
setWebsites([<KitsuDev key={"kitsudev"}/>]); setWebsites([<KitsuDev key="kitsudev"/>]);
}, []); }, []);
useEffect(() => { useEffect(() => {
if (data) { if (data) {
const umami = <Umami key={"umami"}/>; const umami = <Umami key="umami"/>;
setWebsites(websites.concat([umami])); setWebsites(websites.concat([umami]));
} }
}, [data]); }, [data]);

View file

@ -12,7 +12,7 @@ export default class Infos extends Component {
private readonly collection = React.createRef<HTMLDivElement>(); private readonly collection = React.createRef<HTMLDivElement>();
render() { render() {
return <div ref={this.collection} className="text-base z-110 lg:z-0 w-[27px] lg:w-[360px] fixed right-0 h-screen outline outline-4 outline-white overflow-y-auto return <aside ref={this.collection} className="text-base z-110 lg:z-0 w-[27px] lg:w-[360px] fixed right-0 h-screen outline outline-4 outline-white overflow-y-auto
bg-linear-to-r from-sky-600 to-indigo-600"> bg-linear-to-r from-sky-600 to-indigo-600">
<div draggable="false" ref={this.dragbar} className="z-100 h-full w-[25px] fixed right-[7px] lg:right-[340px] cursor-ew-resize select-none hover:bg-linear-to-r from-white/80 to-white/1 active:to-white/20"></div> <div draggable="false" ref={this.dragbar} className="z-100 h-full w-[25px] fixed right-[7px] lg:right-[340px] cursor-ew-resize select-none hover:bg-linear-to-r from-white/80 to-white/1 active:to-white/20"></div>
<div className="z-90 p-2.5 flex flex-wrap text-white"> <div className="z-90 p-2.5 flex flex-wrap text-white">
@ -24,7 +24,7 @@ export default class Infos extends Component {
{/*<Hacking/>*/} {/*<Hacking/>*/}
<Website/> <Website/>
</div> </div>
</div>; </aside>;
} }
componentDidMount(): void { componentDidMount(): void {

View file

@ -31,7 +31,7 @@ export default function TabButtons({
}; };
return ( return (
<div className="relative justify-center items-center"> <nav className="relative justify-center items-center">
<TabButton <TabButton
colors={"from-slate-500 to-slate-600 hover:from-slate-700 hover:to-slate-600"} colors={"from-slate-500 to-slate-600 hover:from-slate-700 hover:to-slate-600"}
onClick={() => { onClick={() => {
@ -46,8 +46,8 @@ export default function TabButtons({
}} }}
content={ content={
<Translatable <Translatable
en={"About me"} en="About me"
fr={"À propos de moi"} fr="À propos de moi"
/> />
} }
/> />
@ -58,8 +58,8 @@ export default function TabButtons({
}} }}
content={ content={
<Translatable <Translatable
en={"My projects"} en="My projects"
fr={"Mes projets"} fr="Mes projets"
/> />
} }
/> />
@ -70,8 +70,8 @@ export default function TabButtons({
}} }}
content={ content={
<Translatable <Translatable
en={"Contact me"} en="Contact me"
fr={"Me contacter"} fr="Me contacter"
/> />
} }
/> />
@ -82,8 +82,8 @@ export default function TabButtons({
}} }}
content={ content={
<Translatable <Translatable
en={"Support me"} en="Support me"
fr={"Me soutenir"} fr="Me soutenir"
/> />
} }
/> />
@ -92,13 +92,8 @@ export default function TabButtons({
onClick={() => { onClick={() => {
toggleTab("webrings"); toggleTab("webrings");
}} }}
content={ content="Webrings"
<Translatable
en={"Webrings"}
fr={"Webrings"}
/>
}
/> />
</div> </nav>
); );
} }

View file

@ -11,7 +11,7 @@ export default function About({
setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>; setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>;
}) { }) {
const elements = [( const elements = [(
<div className="m-4 text-white order-1" key={"about"}> <div className="m-4 text-white order-1" key="about">
<div className="ml-auto max-w-3xl text-left"> <div className="ml-auto max-w-3xl text-left">
<img className="m-4 float-right h-24" src="/assets/brittany.jpg" alt="Flag of Brittany" title="Flag of Brittany"/> <img className="m-4 float-right h-24" src="/assets/brittany.jpg" alt="Flag of Brittany" title="Flag of Brittany"/>
<Translatable <Translatable
@ -57,8 +57,8 @@ export default function About({
id="about" id="about"
name={ name={
<Translatable <Translatable
en={"About"} en="About"
fr={"À propos"} fr="À propos"
/> />
} }
elements={elements} elements={elements}

View file

@ -13,7 +13,7 @@ export default function Contact({
setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>; setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>;
}) { }) {
const elements = [( const elements = [(
<div className="m-4 text-white text-left" key={"contact"}> <div className="m-4 text-white text-left" key="contact">
<Translatable <Translatable
en={<p>It is my belief that it's actually difficult to communicate with the people you want on the internet, I find emails to be bad for real-time communication, some other platforms enshittify themselves too much, while others do not quite offer the best user experience in my honest opinion.</p>} en={<p>It is my belief that it's actually difficult to communicate with the people you want on the internet, I find emails to be bad for real-time communication, some other platforms enshittify themselves too much, while others do not quite offer the best user experience in my honest opinion.</p>}
fr={<p>Je pense en fait que c'est difficile de communiquer avec les gens qu'on veut sur internet, je trouve que les e-mails ne conviennent pas pour la communication en temps réel, certaines plateformes deviennent horribles, pendant que d'autres n'offrent pas vraiment une bonne expérience.</p>} fr={<p>Je pense en fait que c'est difficile de communiquer avec les gens qu'on veut sur internet, je trouve que les e-mails ne conviennent pas pour la communication en temps réel, certaines plateformes deviennent horribles, pendant que d'autres n'offrent pas vraiment une bonne expérience.</p>}
@ -42,8 +42,8 @@ export default function Contact({
id="contact" id="contact"
name={ name={
<Translatable <Translatable
en={"Contact"} en="Contact"
fr={"Contacter"} fr="Contacter"
/> />
} }
elements={elements} elements={elements}

View file

@ -11,7 +11,7 @@ export default function Projects({
setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>; setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>;
}) { }) {
const elements = [( const elements = [(
<div className="inline-block m-4 text-white text-left" key={"projects"}> <div className="inline-block m-4 text-white text-left" key="projects">
<div className="border-b-4 pb-4"> <div className="border-b-4 pb-4">
<a href="https://tttaevas.itch.io/swordventure" target="_blank" rel="noreferrer"><img className="m-4 float-right w-40" src="/assets/swordventure.png" alt="SwordVenture thumbnail"/></a> <a href="https://tttaevas.itch.io/swordventure" target="_blank" rel="noreferrer"><img className="m-4 float-right w-40" src="/assets/swordventure.png" alt="SwordVenture thumbnail"/></a>
<Translatable <Translatable
@ -114,8 +114,8 @@ export default function Projects({
id="projects" id="projects"
name={ name={
<Translatable <Translatable
en={"Projects"} en="Projects"
fr={"Projets"} fr="Projets"
/> />
} }
elements={elements} elements={elements}

View file

@ -11,7 +11,7 @@ export default function Support({
setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>; setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>;
}) { }) {
const elements = [( const elements = [(
<div className="m-4 pb-2 text-white" key={"support"}> <div className="m-4 pb-2 text-white" key="support">
<p> <p>
<b> <b>
<Translatable <Translatable
@ -45,8 +45,8 @@ export default function Support({
id="support" id="support"
name={ name={
<Translatable <Translatable
en={"Support"} en="Support"
fr={"Soutenir"} fr="Soutenir"
/> />
} }
elements={elements} elements={elements}

View file

@ -32,8 +32,8 @@ export default class Tab extends Component<{
<div ref={this.header} className="relative bg-white lg:rounded-xl h-12 hover:brightness-110 lg:hover:cursor-grab lg:active:cursor-move"> <div ref={this.header} className="relative bg-white lg:rounded-xl h-12 hover:brightness-110 lg:hover:cursor-grab lg:active:cursor-move">
{this.props.logo ? <div className="absolute start-0 h-0 ml-2 invisible lg:visible fill-gray-600">{this.props.logo}</div> : <></>} {this.props.logo ? <div className="absolute start-0 h-0 ml-2 invisible lg:visible fill-gray-600">{this.props.logo}</div> : <></>}
<div className="absolute end-0 w-0 sm:w-10 mr-1 mt-1 invisible lg:visible cursor-pointer <div className="absolute end-0 w-0 sm:w-10 mr-1 mt-1 invisible lg:visible cursor-pointer
rounded-full fill-red-500 hover:fill-black hover:bg-red-500 active:brightness-50" onClick={() => { rounded-full fill-red-500 hover:fill-black hover:bg-red-500 active:brightness-50" onClick={() => {
this.props.setTabs(tabs.filter((t) => t.id !== this.props.id)); this.props.setTabs(tabs.filter((t) => t.id !== this.props.id));
}}> }}>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<path d="M24 9.4L22.6 8L16 14.6L9.4 8L8 9.4l6.6 6.6L8 22.6L9.4 24l6.6-6.6l6.6 6.6l1.4-1.4l-6.6-6.6L24 9.4z"/> <path d="M24 9.4L22.6 8L16 14.6L9.4 8L8 9.4l6.6 6.6L8 22.6L9.4 24l6.6-6.6l6.6 6.6l1.4-1.4l-6.6-6.6L24 9.4z"/>
@ -44,14 +44,8 @@ export default class Tab extends Component<{
</h3> </h3>
</div> </div>
<div className="drop-shadow-2xl max-h-[500px] overflow-y-auto <div className="drop-shadow-2xl max-h-[500px] overflow-y-auto
[&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-track]:bg-gray-300 [&::-webkit-scrollbar-thumb]:bg-indigo-500 [&::-webkit-scrollbar-track]:rounded-full [&::-webkit-scrollbar-thumb]:rounded-full"> [&::-webkit-scrollbar]:w-2 [&::-webkit-scrollbar-track]:bg-gray-300 [&::-webkit-scrollbar-thumb]:bg-indigo-500 [&::-webkit-scrollbar-track]:rounded-full [&::-webkit-scrollbar-thumb]:rounded-full">
{ {...this.props.elements}
this.props.elements.map((e, i) =>
<div key={`element-${i}}`}>
{e}
</div>,
)
}
</div> </div>
</AnimateHeight> </AnimateHeight>
)} )}

View file

@ -10,7 +10,7 @@ export default function Webrings({
setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>; setTabs: React.Dispatch<React.SetStateAction<TabDetails[]>>;
}) { }) {
const elements = [( const elements = [(
<div className="m-4 pb-2 text-white" key={"webrings"}> <div className="m-4 pb-2 text-white" key="webrings">
<p> <p>
<b> <b>
<Translatable <Translatable
@ -28,8 +28,8 @@ export default function Webrings({
id="webrings" id="webrings"
name={ name={
<Translatable <Translatable
en={"Webrings"} en="Webrings"
fr={"Webrings"} fr="Webrings"
/> />
} }
elements={elements} elements={elements}

View file

@ -12,13 +12,13 @@ export default function MainContent() {
}, [lang]); }, [lang]);
return ( return (
<div className="text-lg/6 h-screen w-screen max-w-[1632px] m-auto lg:pl-[50px] lg:pr-[413px] lg:py-12"> <main className="text-lg/6 h-screen w-screen max-w-[1632px] m-auto lg:pl-[50px] lg:pr-[413px] lg:py-12">
<LanguageContext.Provider value={lang}> <LanguageContext.Provider value={lang}>
<TabContext.Provider value={tabs}> <TabContext.Provider value={tabs}>
<MainWindow setLang={setLang} setTabs={setTabs}/> <MainWindow setLang={setLang} setTabs={setTabs}/>
<Tabs setTabs={setTabs}/> <Tabs setTabs={setTabs}/>
</TabContext.Provider> </TabContext.Provider>
</LanguageContext.Provider> </LanguageContext.Provider>
</div> </main>
); );
} }