diff --git a/package-lock.json b/package-lock.json
index a1a16e7fb..16a1ec727 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,6 +22,8 @@
"react": "^17.0.1",
"react-bootstrap": "^1.2.2",
"react-dom": "^17.0.1",
+ "react-helmet-async": "^1.3.0",
+ "react-is": "^19.2.7",
"react-router-dom": "^5.2.0",
"react-scripts": "^5.0.1",
"styled-components": "^5.1.1"
@@ -44851,6 +44853,35 @@
"integrity": "sha512-SN/U6Ytxf1QGkw/9ve5Y+NxBbZM6Ht95tuXNMKs8EJyFa/Vy/+Co3stop3KBHARfn/giv+Lj1uUnTfOJ3moFEQ==",
"license": "MIT"
},
+ "node_modules/react-fast-compare": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
+ "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==",
+ "license": "MIT"
+ },
+ "node_modules/react-helmet-async": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz",
+ "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "invariant": "^2.2.4",
+ "prop-types": "^15.7.2",
+ "react-fast-compare": "^3.2.0",
+ "shallowequal": "^1.1.0"
+ },
+ "peerDependencies": {
+ "react": "^16.6.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^16.6.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "19.2.7",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.7.tgz",
+ "integrity": "sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==",
+ "license": "MIT"
+ },
"node_modules/react-is-18": {
"name": "react-is",
"version": "18.3.1",
diff --git a/package.json b/package.json
index 5cf734521..aa17ef965 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,8 @@
"react": "^17.0.1",
"react-bootstrap": "^1.2.2",
"react-dom": "^17.0.1",
+ "react-helmet-async": "^1.3.0",
+ "react-is": "^19.2.7",
"react-router-dom": "^5.2.0",
"react-scripts": "^5.0.1",
"styled-components": "^5.1.1"
diff --git a/src/404.js b/src/404.js
index cbac1058b..05a4c3377 100644
--- a/src/404.js
+++ b/src/404.js
@@ -1,12 +1,13 @@
-import React, { useEffect } from 'react';
+import React from 'react';
+import { Helmet } from 'react-helmet-async';
export const NoMatch = () => {
- useEffect(() => {
- document.title = '404 Error';
- }, []);
-
return (
+
+ 404 Error
+
+
-
-
-
- Recently while going through Godot documentation I came across a tutorial for building your own state machine with Python.
- I continued working on that state machine to emulate a locked/unlocked device.
- View the project.
-
-
-
-
-
-
-
- In an image processing course I replicated multiple skin detection algorithms in Python.
- I cleaned up the original assignment and made it compatible with Python 3.
- View the project.
-
-
- Before the algorithm.
-
- After the HSV algorithm.
-
-
-
-
-
- This C program checks whether a graph is Eulerian by reading a text file and analyzing graph structure.
- It repeats the process until end-of-file and reports whether the graph is Eulerian.
- View the project.
-
-
- Example of a graph from euler-graphs.txt.
-
- Output from running the algorithm.
-
-
-
-
-
- A legacy programming course project to update a Fortran 77 hangman game to Fortran 95 and improve the code.
- Use the executable or Makefile to run the game.
-
-
- A very quick hangman game.
-
-
-
-
-
- A program that solves the knight's tour problem in Ada.
- It generates a solution for small boards and shows the move sequence.
-
-
- Knights tour output for a 5x5 chessboard starting at position (1,1).
-
-
-
-
-
- A modernized COBOL text analyzer updated from a legacy script.
- It analyzes fixed data and reports text statistics.
-
-
-
-
-
-
-
- A comparison of C, Fortran, and Ada implementations of the KMP search algorithm.
- The project generates executables for each language to compare performance.
-
-
-
-
-
-
-
- I have built a collection of games using Unity and Godot, including endless runners, turn-based combat puzzles, and game jam projects.
-
-
-
-
-
-
+ {projects.map((p) => (
+
+ ))}
);
};
diff --git a/src/Resume.js b/src/Resume.js
index d3b866ba1..d8d7642c6 100644
--- a/src/Resume.js
+++ b/src/Resume.js
@@ -1,14 +1,16 @@
-import React, { useEffect } from 'react';
+import React from 'react';
+import { Helmet } from 'react-helmet-async';
import pdf from './assets/Gregory Campbell Resume.pdf';
import pic from './assets/Resume.png';
export const Resume = () => {
- useEffect(() => {
- document.title = 'The Resume of Gregory Campbell';
- }, []);
-
return (
+
+ The Resume of Gregory Campbell
+
+
+