feat(web): toggle footer images with theme

This commit is contained in:
Collin Barrett 2025-06-14 11:05:38 -05:00
parent 8b11845c88
commit 25ade37323
11 changed files with 93 additions and 53 deletions

View file

@ -3,6 +3,7 @@ import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import { ThemeProvider } from "@/components/theme-provider";
import { SiteHeader } from "@/components/site-header";
import { SiteFooter } from "@/components/site-footer";
const geistSans = Geist({
variable: "--font-geist-sans",
@ -37,7 +38,10 @@ export default function RootLayout({
disableTransitionOnChange
>
<SiteHeader />
{children}
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
{children}
<SiteFooter />
</div>
</ThemeProvider>
</body>
</html>

View file

@ -1,54 +1,5 @@
import Image from "next/image";
import { FileJson2 } from "lucide-react";
import CollinMBarrettIcon from "../assets/collinmbarrett-icon.png";
import GitHubMark from "../assets/github-mark.svg";
export default function Home() {
return (
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
<main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start"></main>
<footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
{/* TODO: toggle images in dark mode */}
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://collinmbarrett.com/"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src={CollinMBarrettIcon}
alt="Collin M. Barrett logo"
width={16}
height={16}
/>
by Collin M. Barrett
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://api.filterlists.com/"
target="_blank"
rel="noopener noreferrer"
>
<FileJson2 width={16} height={16} />
API
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://github.com/collinbarrett/FilterLists"
target="_blank"
rel="noopener noreferrer"
>
<Image
aria-hidden
src={GitHubMark}
alt="GitHub Logomark"
width={16}
height={16}
/>
GitHub
</a>
</footer>
</div>
<main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start"></main>
);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

View file

Before

Width:  |  Height:  |  Size: 960 B

After

Width:  |  Height:  |  Size: 960 B

View file

Before

Width:  |  Height:  |  Size: 963 B

After

Width:  |  Height:  |  Size: 963 B

View file

@ -0,0 +1,54 @@
import { FileJson2 } from "lucide-react";
import CollinMBarrettIconLight from "../assets/collinmbarrett-icon-light.png";
import CollinMBarrettIconDark from "../assets/collinmbarrett-icon-dark.png";
import GitHubMarkLight from "../assets/github-mark-light.svg";
import GitHubMarkDark from "../assets/github-mark-dark.svg";
import { ThemeImage } from "@/components/theme-image";
export function SiteFooter() {
return (
<footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://collinmbarrett.com/"
target="_blank"
rel="noopener noreferrer"
>
<ThemeImage
aria-hidden
srcLight={CollinMBarrettIconLight}
srcDark={CollinMBarrettIconDark}
alt="Collin M. Barrett logo"
width={16}
height={16}
/>
by Collin M. Barrett
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://api.filterlists.com/"
target="_blank"
rel="noopener noreferrer"
>
<FileJson2 width={16} height={16} />
API
</a>
<a
className="flex items-center gap-2 hover:underline hover:underline-offset-4"
href="https://github.com/collinbarrett/FilterLists"
target="_blank"
rel="noopener noreferrer"
>
<ThemeImage
aria-hidden
srcLight={GitHubMarkLight}
srcDark={GitHubMarkDark}
alt="GitHub Logomark"
width={16}
height={16}
/>
GitHub
</a>
</footer>
);
}

View file

@ -1,5 +1,3 @@
"use client";
import { ThemeModeToggle } from "./theme-mode-toggle";
export function SiteHeader() {

View file

@ -0,0 +1,33 @@
"use client";
import { useState, useEffect } from "react";
import Image, { type ImageProps, type StaticImageData } from "next/image";
import { useTheme } from "next-themes";
type ThemedImageProps = Omit<ImageProps, "src" | "alt"> & {
srcLight: string | StaticImageData;
srcDark: string | StaticImageData;
alt: string;
};
export function ThemeImage({
srcLight,
srcDark,
alt,
...props
}: ThemedImageProps) {
const { resolvedTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
const src = resolvedTheme === "dark" ? srcDark : srcLight;
if (!mounted) {
return <Image src={srcLight} alt={alt} {...props} unoptimized />;
}
return <Image src={src} alt={alt} {...props} />;
}