5.5 KB
raw
import React, { useState, useEffect, useRef } from "react";
import { TransitionGroup, CSSTransition } from "react-transition-group";
import Page from "../components/page";
import styles from "@styles/pages/about.module.css";
const INITIAL_WORDS = [
"AI Agents",
"DevOps",
"Full-Stack",
"Testing",
"Cloud",
"Security",
"Developer",
"Automation",
"Architecture",
];
const About = () => {
const [words, setWords] = useState(INITIAL_WORDS);
const wordsRef = useRef(words);
wordsRef.current = words;
const slots = useRef(
Object.fromEntries(INITIAL_WORDS.map((word, i) => [word, i]))
);
const wordRefs = useRef(new Map());
const getWordRef = (key) => {
if (!wordRefs.current.has(key)) {
wordRefs.current.set(key, React.createRef());
}
return wordRefs.current.get(key);
};
useEffect(() => {
const getRandomWordIndex = () => {
return Math.floor(Math.random() * wordsRef.current.length);
};
const wordsInterval = setInterval(() => {
let firstWordIndex = getRandomWordIndex();
let secondWordIndex = getRandomWordIndex();
while (firstWordIndex === secondWordIndex) {
firstWordIndex = getRandomWordIndex();
secondWordIndex = getRandomWordIndex();
}
const firstWord = wordsRef.current[firstWordIndex];
const secondWord = wordsRef.current[secondWordIndex];
const firstSlot = slots.current[firstWord];
const secondSlot = slots.current[secondWord];
slots.current[firstWord] = secondSlot;
slots.current[secondWord] = firstSlot;
setWords(
wordsRef.current.filter((word, index) => {
return index !== firstWordIndex && index !== secondWordIndex;
})
);
setTimeout(() => {
let newWords = [...wordsRef.current];
newWords.splice(secondWordIndex, 0, firstWord);
newWords.splice(firstWordIndex, 0, secondWord);
setWords(newWords);
}, 1000);
}, 4000);
return () => {
clearInterval(wordsInterval);
};
}, []);
return (
<Page title="About" description="A brief professional history of myself.">
<div className={styles.background} />
<div className={styles.words}>
<TransitionGroup component={null}>
{words.map((word) => {
const nodeRef = getWordRef(word);
return (
<CSSTransition
key={word}
timeout={1000}
appear
classNames={{
appearActive: styles.wordAppearActive,
appearDone: styles.wordAppearDone,
enterActive: styles.wordEnterActive,
enterDone: styles.wordEnterDone,
exitActive: styles.wordExitActive,
}}
nodeRef={nodeRef}
>
<h2
className={styles.word}
ref={nodeRef}
style={{ top: `${slots.current[word] * 11}vh` }}
>
<span className={styles.wordText}>{word}</span>
</h2>
</CSSTransition>
);
})}
</TransitionGroup>
</div>
<p className={styles.paragraph}>
I am a{" "}
<span className={styles.strong}>senior solutions architect</span>{" "}
at Craftmaster Furniture with{" "}
<span className={styles.strong}>two decades in tech</span>.{" "}
I got my start{" "}
<span className={styles.strong}>modifying kernel modules</span>{" "}
for Digium Telephony Cards on CentOS and have been building across the{" "}
<span className={styles.strong}>full stack</span>{" "}
ever since, from DevOps and server infrastructure to{" "}
<span className={styles.strong}>highly regulated</span>{" "}
healthcare environments, leading teams through tight deadlines and
demanding delivery schedules. Today I focus on{" "}
<span className={styles.strong}>AI agent workflows</span>,{" "}
automated testing infrastructure, and tooling that keeps release cycles
fast without sacrificing stability or security.
<a
className={styles.resume}
href="/static/pdfs/resume-isaac-bythewood.pdf"
target="_blank"
rel="noopener noreferrer"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="currentColor"
viewBox="0 0 16 16"
>
<path
fillRule="evenodd"
d="M14 4.5V14a2 2 0 0 1-2 2h-1v-1h1a1 1 0 0 0 1-1V4.5h-2A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v9H2V2a2 2 0 0 1 2-2h5.5L14 4.5ZM1.6 11.85H0v3.999h.791v-1.342h.803c.287 0 .531-.057.732-.173.203-.117.358-.275.463-.474a1.42 1.42 0 0 0 .161-.677c0-.25-.053-.476-.158-.677a1.176 1.176 0 0 0-.46-.477c-.2-.12-.443-.179-.732-.179Zm.545 1.333a.795.795 0 0 1-.085.38.574.574 0 0 1-.238.241.794.794 0 0 1-.375.082H.788V12.48h.66c.218 0 .389.06.512.181.123.122.185.296.185.522Zm1.217-1.333v3.999h1.46c.401 0 .734-.08.998-.237a1.45 1.45 0 0 0 .595-.689c.13-.3.196-.662.196-1.084 0-.42-.065-.778-.196-1.075a1.426 1.426 0 0 0-.589-.68c-.264-.156-.599-.234-1.005-.234H3.362Zm.791.645h.563c.248 0 .45.05.609.152a.89.89 0 0 1 .354.454c.079.201.118.452.118.753a2.3 2.3 0 0 1-.068.592 1.14 1.14 0 0 1-.196.422.8.8 0 0 1-.334.252 1.298 1.298 0 0 1-.483.082h-.563v-2.707Zm3.743 1.763v1.591h-.79V11.85h2.548v.653H7.896v1.117h1.606v.638H7.896Z"
/>
</svg>
My Resume
</a>
</p>
</Page>
);
};
export default About;