Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ const TagChip = styled((props: React.ComponentProps<typeof Chip>) => (
))({ border: "none", borderRadius: 0 });
```

## GitHub Comments & Reviews

When posting any comment, review, or reply on GitHub (PRs, issues, etc.), always append the following signature on a new line at the end:

```
— 🤖 Claude
```

This applies to PR review comments, inline code comments, issue comments, and review summaries — anything posted via `gh` CLI or GitHub API.

Comment thread
kaltepeter marked this conversation as resolved.
Comment thread
kaltepeter marked this conversation as resolved.
## Dependency Notes

- **`tss-react` is removed.** It does not support MUI v9. Do not re-add it.
Expand Down
45 changes: 41 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"version": "0.1.0",
"author": "Kayla Altepeter",
"engines": {
"node": ">=18.16.1",
"node": ">=24.15.0",
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bumping the supported Node engine from >=18.16.1 to >=24.15.0 is a major operational change and is significantly stricter than what Gatsby 5 itself declares (it supports >=18 <26 per the lockfile). If the project truly requires Node 24.15 specifically (vs 24.x / >=24), it would help to justify this in the PR or relax it to the minimum actually required so CI/deploy environments don’t break unnecessarily.

Suggested change
"node": ">=24.15.0",
"node": ">=18.16.1",

Copilot uses AI. Check for mistakes.
"npm": ">=9.5.1"
},
"dependencies": {
Expand All @@ -29,13 +29,16 @@
"gatsby-source-filesystem": "^5.11.0",
"gatsby-transformer-remark": "^6.11.0",
"gatsby-transformer-sharp": "^5.11.0",
"js-search": "^2.0.1",
"postcss": "^8.4.26",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@emotion/cache": "^11.14.0",
"@eslint/js": "^10.0.1",
"@graphql-eslint/eslint-plugin": "^4.0.0",
"@types/js-search": "^1.4.4",
"@types/node": "^24.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
Expand Down
62 changes: 6 additions & 56 deletions src/components/header.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
import {
AppBar,
alpha,
Box,
IconButton,
InputBase,
Toolbar,
Typography,
useScrollTrigger,
} from "@mui/material";
import { styled } from "@mui/material/styles";
import MenuIcon from "@mui/icons-material/Menu";
import SearchIcon from "@mui/icons-material/Search";
import { Link } from "gatsby";
import React, { ReactElement, useState } from "react";
import React, { ReactElement, useCallback, useState } from "react";
import NotesLogo from "../images/logo.svg";
import NotesIcon from "../images/notes-icon.svg";
import ElevationScroll from "./elevation-scroll";
import HideOnScroll from "./hide-on-scroll";
import { Navigation } from "./navigation";
import SearchInput from "./search-input";

const StyledAppBar = styled(AppBar, {
shouldForwardProp: (prop) => prop !== "drawerWidth" && prop !== "scrolled",
Expand Down Expand Up @@ -65,46 +63,6 @@ const NavLogo = styled("img")({
height: "20px",
});

const Search = styled(Box)(({ theme }) => ({
position: "relative",
borderRadius: theme.shape.borderRadius,
backgroundColor: alpha(theme.palette.common.white, 0.15),
"&:hover": {
backgroundColor: alpha(theme.palette.common.white, 0.25),
},
marginLeft: 0,
width: "100%",
[theme.breakpoints.up("sm")]: {
marginLeft: theme.spacing(1),
width: "auto",
},
}));

const SearchIconWrapper = styled(Box)(({ theme }) => ({
padding: theme.spacing(0, 2),
height: "100%",
position: "absolute",
pointerEvents: "none",
display: "flex",
alignItems: "center",
justifyContent: "center",
}));

const StyledInputBase = styled(InputBase)(({ theme }) => ({
color: "inherit",
"& .MuiInputBase-input": {
padding: theme.spacing(1, 1, 1, 0),
paddingLeft: `calc(1em + ${theme.spacing(4)})`,
transition: theme.transitions.create("width"),
width: "100%",
[theme.breakpoints.up("sm")]: {
width: "12ch",
"&:focus": {
width: "20ch",
},
},
},
}));

type HeaderProps = {
siteTitle?: string;
Expand All @@ -117,9 +75,9 @@ const Header = ({ siteTitle = "", window, drawerWidth }: HeaderProps): ReactElem
const trigger = useScrollTrigger({ target: window ? window() : undefined });
const [drawerOpen, setDrawerOpen] = useState<boolean>(false);

const handleDrawerToggle = () => {
setDrawerOpen(!drawerOpen);
};
const handleDrawerToggle = useCallback(() => {
setDrawerOpen((open) => !open);
}, []);

return (
<>
Expand Down Expand Up @@ -150,15 +108,7 @@ const Header = ({ siteTitle = "", window, drawerWidth }: HeaderProps): ReactElem
</Link>
</HeaderTitle>
<HideOnScroll>
<Search>
<SearchIconWrapper>
<SearchIcon />
</SearchIconWrapper>
<StyledInputBase
placeholder="Search…"
inputProps={{ "aria-label": "search" }}
/>
</Search>
<SearchInput />
</HideOnScroll>
</Toolbar>
</StyledAppBar>
Expand Down
80 changes: 80 additions & 0 deletions src/components/note-list-entry.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Chip, ListItem, ListItemText, Typography } from "@mui/material";
import { styled } from "@mui/material/styles";
import { Link } from "gatsby";
import React from "react";
import { Note } from "../models/note";

const NoteItemContainer = styled(ListItem)({
"& .head": {
display: "flex",
justifyContent: "space-between",
alignItems: "baseline",
},
});

const TagList = styled("ul")(({ theme }) => ({
display: "flex",
justifyContent: "left",
flexWrap: "wrap",
listStyle: "none",
padding: theme.spacing(0.5),
margin: 0,
}));

const TagChip = styled((props: React.ComponentProps<typeof Chip>) => (
<Chip component="span" {...props} />
))({
border: "none",
borderRadius: 0,
});

type NoteListEntryProps = {
note: Note;
titleComponent?: "h2" | "h3";
};

const NoteListEntry: React.FC<NoteListEntryProps> = ({
note,
titleComponent = "h3",
}) => (
<NoteItemContainer divider>
<ListItemText
inset={false}
slotProps={{
primary: { className: "head" },
secondary: { component: "div" },
}}
primary={
<>
<Typography component={titleComponent} variant="h6">
<Link to={note.fields.slug}>
{note.frontmatter.title}
</Link>
</Typography>
<Typography variant="overline">{note.frontmatter.date}</Typography>
</>
}
secondary={
<>
<TagList>
{note.frontmatter.tags?.map((tag) => (
<Typography component="li" variant="subtitle1" key={tag}>
<TagChip
size="medium"
variant="outlined"
color="secondary"
label={`#${tag}`}
/>
</Typography>
))}
</TagList>
<Typography component="p" variant="body1" color="text.primary">
{note.excerpt}
</Typography>
</>
}
/>
</NoteItemContainer>
);

export default NoteListEntry;
Loading