feat: use global package for headers (#61)

### Explanation

_No response_

### Issue

_No response_

### Attestations

- [ ] I have read and agree to the [Code of Conduct](https://docs.nhcarrigan.com/community/coc/)
- [ ] I have read and agree to the [Community Guidelines](https://docs.nhcarrigan.com/community/guide/).
- [ ] My contribution complies with the [Contributor Covenant](https://docs.nhcarrigan.com/dev/covenant/).

### Dependencies

- [ ] I have pinned the dependencies to a specific patch version.

### Style

- [ ] I have run the linter and resolved any errors.
- [ ] My pull request uses an appropriate title, matching the conventional commit standards.
- [ ] My scope of feat/fix/chore/etc. correctly matches the nature of changes in my pull request.

### Tests

- [ ] My contribution adds new code, and I have added tests to cover it.
- [ ] My contribution modifies existing code, and I have updated the tests to reflect these changes.
- [ ] All new and existing tests pass locally with my changes.
- [ ] Code coverage remains at or above the configured threshold.

### Documentation

_No response_

### Versioning

_No response_

Reviewed-on: https://codeberg.org/nhcarrigan/portfolio/pulls/61
Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com>
Co-committed-by: Naomi Carrigan <commits@nhcarrigan.com>
This commit is contained in:
Naomi Carrigan 2024-12-21 00:57:53 +00:00 committed by Naomi the Technomancer
parent c9166a3321
commit d4c3c4dfca
5 changed files with 23 additions and 148 deletions

View File

@ -2,53 +2,21 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
@font-face {
font-family: "OpenDyslexic Mono";
src: url(../assets/OpenDyslexicMono-Regular.otf);
}
:root { :root {
--foreground: #04624f; --current: #995c00;
--background: #abfcecdd; --former: #99004d;
--current: #00a86b;
--former: #ff69b4;
} }
.dark { * {
--foreground: #abfcec; font-family: "OpenDyslexic";
--background: #04624fdd;
--current: rgb(140, 255, 152);
--former: rgb(255, 148, 253);
} }
body::before {
background: url(https://cdn.nhcarrigan.com/background.png);
background-size: cover;
background-position: center;
width: 100%;
height: 100%;
z-index: -1;
content: "";
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 1;
pointer-events: none;
}
main,
nav { nav {
color: var(--foreground); color: var(--foreground);
background-color: var(--background); background-color: var(--background);
font-family: "OpenDyslexic Mono", monospace; font-family: "OpenDyslexic Mono", monospace;
} }
a {
color: unset;
}
@layer utilities { @layer utilities {
.text-balance { .text-balance {
text-wrap: balance; text-wrap: balance;

View File

@ -5,9 +5,6 @@
*/ */
import { Inter } from "next/font/google"; import { Inter } from "next/font/google";
import Script from "next/script"; import Script from "next/script";
// eslint-disable-next-line import/default, import/no-named-as-default, import/no-named-as-default-member
import PlausibleProvider from "next-plausible";
import { Footer } from "../components/footer";
import { Navigation } from "../components/navigation"; import { Navigation } from "../components/navigation";
import type { Metadata } from "next"; import type { Metadata } from "next";
import type { JSX, ReactNode } from "react"; import type { JSX, ReactNode } from "react";
@ -46,43 +43,24 @@ const RootLayout = ({
}>): JSX.Element => { }>): JSX.Element => {
return ( return (
<html lang="en"> <html lang="en">
<PlausibleProvider <Script
customDomain="https://analytics.nhcarrigan.com" async={true}
domain="nhcarrigan.com" defer={true}
trackFileDownloads={true} src="https://cdn.nhcarrigan.com/headers/index.js"
trackOutboundLinks={true} strategy={"afterInteractive"}
> type="text/javascript"
<link ></Script>
href="https://cdn.nhcarrigan.com/logo.png" <link
rel="icon" href="https://cdn.nhcarrigan.com/logo.png"
sizes="any" rel="icon"
/> sizes="any"
<body className={inter.className}> />
<header> <body className={inter.className}>
<Navigation /> <header>
</header> <Navigation />
{children} </header>
<video {children}
autoPlay={true} </body>
className="fixed top-0 left-0 w-full h-full object-cover opacity-25"
loop={true}
muted={true}
playsInline={true}
src="https://cdn.nhcarrigan.com/overlay.webm"
style={{ pointerEvents: "none" }}
/>
<footer>
<Footer />
</footer>
</body>
<Script
async={true}
defer={true}
id="hs-script-loader"
src="//js.hs-scripts.com/47086586.js"
type="text/javascript"
></Script>
</PlausibleProvider>
</html> </html>
); );
}; };

View File

@ -1,44 +0,0 @@
/**
* @copyright nhcarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
"use client";
import { faComments } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Crisp } from "crisp-sdk-web";
import Script from "next/script";
import React, { type JSX } from "react";
/**
* Conditionally renders the footer component when
* not on the home page.
* @returns A JSX element.
*/
export const Footer = (): JSX.Element | null => {
if (typeof window !== "undefined") {
Crisp.configure("5398ce41-4ceb-4e31-9049-4c784a70179a");
}
return (
<div
className="fixed w-full bottom-0 z-50 flex
justify-between items-center h-14 px-4
bg-[--background] text-[--foreground]"
style={{ fontFamily: "OpenDyslexic Mono" }}
>
<p>{`© Naomi Carrigan`}</p>
<a href="https://chat.nhcarrigan.com" rel="noreferrer" target="_blank">
<FontAwesomeIcon icon={faComments} size="lg" />
</a>
<div className="h-4/5" id="tree-nation-offset-website"></div>
<Script
src="https://widgets.tree-nation.com/js/widgets/v1/widgets.min.js?v=1.0"
strategy="beforeInteractive"
></Script>
<Script
id="tree-nation"
strategy="afterInteractive"
>{`TreeNationOffsetWebsite({code: 'a17464e0cd351220', lang: 'en', theme: 'dark'}).render('#tree-nation-offset-website');`}</Script>
</div>
);
};

View File

@ -7,12 +7,10 @@
import { import {
faBars, faBars,
faTimes, faTimes,
faSun,
faMoon,
} from "@fortawesome/free-solid-svg-icons"; } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import Image from "next/image"; import Image from "next/image";
import React, { type JSX, useState, useEffect, useCallback } from "react"; import React, { type JSX, useState, useCallback } from "react";
import { NavItems } from "../config/NavItems"; import { NavItems } from "../config/NavItems";
import { Rule } from "./rule"; import { Rule } from "./rule";
@ -23,31 +21,11 @@ import { Rule } from "./rule";
*/ */
export const Navigation = (): JSX.Element | null => { export const Navigation = (): JSX.Element | null => {
const [ isOpen, setIsOpen ] = useState(false); const [ isOpen, setIsOpen ] = useState(false);
const [ isDarkMode, setIsDarkMode ] = useState(false);
useEffect(() => {
const storedTheme = localStorage.getItem("theme");
if (storedTheme === "dark") {
document.documentElement.classList.add("dark");
setIsDarkMode(true);
} else {
document.documentElement.classList.remove("dark");
setIsDarkMode(false);
}
}, []);
const toggleMenu = useCallback((): void => { const toggleMenu = useCallback((): void => {
setIsOpen(!isOpen); setIsOpen(!isOpen);
}, [ isOpen ]); }, [ isOpen ]);
const toggleDarkMode = useCallback((): void => {
document.documentElement.classList.toggle("dark", !isDarkMode);
localStorage.setItem("theme", isDarkMode
? "light"
: "dark");
setIsDarkMode(!isDarkMode);
}, [ isDarkMode ]);
return ( return (
<div className="fixed w-full top-0 z-50" <div className="fixed w-full top-0 z-50"
style={{ fontFamily: "OpenDyslexic Mono" }}> style={{ fontFamily: "OpenDyslexic Mono" }}>
@ -64,11 +42,6 @@ export const Navigation = (): JSX.Element | null => {
/> />
</a> </a>
<div className="flex items-center"> <div className="flex items-center">
<button className="mr-4" onClick={toggleDarkMode} type="button">
<FontAwesomeIcon icon={isDarkMode
? faSun
: faMoon} size="lg" />
</button>
<button onClick={toggleMenu} type="button"> <button onClick={toggleMenu} type="button">
<FontAwesomeIcon icon={isOpen <FontAwesomeIcon icon={isOpen
? faTimes ? faTimes