diff --git a/.gitignore b/.gitignore
index 1eae0cf..1f55cb0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
dist/
node_modules/
+*.swp
diff --git a/package-lock.json b/package-lock.json
index 9bb873f..11741e8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,9 @@
"name": "nile",
"version": "0.0.1",
"license": "LGPL-2.1-only",
+ "dependencies": {
+ "react-responsive-carousel": "^3.2.23"
+ },
"devDependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
@@ -1366,6 +1369,11 @@
"node": ">=0.8.0"
}
},
+ "node_modules/classnames": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz",
+ "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
+ },
"node_modules/clsx": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz",
@@ -1687,8 +1695,7 @@
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"node_modules/jsesc": {
"version": "2.5.2",
@@ -1730,7 +1737,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "dev": true,
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
@@ -1781,7 +1787,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -1896,7 +1901,6 @@
"version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
- "dev": true,
"dependencies": {
"loose-envify": "^1.4.0",
"object-assign": "^4.1.1",
@@ -1906,8 +1910,7 @@
"node_modules/prop-types/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
- "dev": true
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react": {
"version": "18.2.0",
@@ -1934,6 +1937,17 @@
"react": "^18.2.0"
}
},
+ "node_modules/react-easy-swipe": {
+ "version": "0.0.21",
+ "resolved": "https://registry.npmjs.org/react-easy-swipe/-/react-easy-swipe-0.0.21.tgz",
+ "integrity": "sha512-OeR2jAxdoqUMHIn/nS9fgreI5hSpgGoL5ezdal4+oO7YSSgJR8ga+PkYGJrSrJ9MKlPcQjMQXnketrD7WNmNsg==",
+ "dependencies": {
+ "prop-types": "^15.5.8"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/react-icons": {
"version": "4.10.1",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.10.1.tgz",
@@ -1981,6 +1995,16 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-responsive-carousel": {
+ "version": "3.2.23",
+ "resolved": "https://registry.npmjs.org/react-responsive-carousel/-/react-responsive-carousel-3.2.23.tgz",
+ "integrity": "sha512-pqJLsBaKHWJhw/ItODgbVoziR2z4lpcJg+YwmRlSk4rKH32VE633mAtZZ9kDXjy4wFO+pgUZmDKPsPe1fPmHCg==",
+ "dependencies": {
+ "classnames": "^2.2.5",
+ "prop-types": "^15.5.8",
+ "react-easy-swipe": "^0.0.21"
+ }
+ },
"node_modules/react-router": {
"version": "6.15.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.15.0.tgz",
diff --git a/package.json b/package.json
index 6de4567..1ac7d5a 100644
--- a/package.json
+++ b/package.json
@@ -35,5 +35,8 @@
"react-material-ui-carousel": "^3.4.2",
"react-router-dom": "^6.15.0",
"vite": "4.4.9"
+ },
+ "dependencies": {
+ "react-responsive-carousel": "^3.2.23"
}
}
diff --git a/public/portfolio/bottega-cert-full.png b/public/portfolio/bottega-cert-full.png
new file mode 100644
index 0000000..ac77c64
Binary files /dev/null and b/public/portfolio/bottega-cert-full.png differ
diff --git a/public/portfolio/bottega-cert.png b/public/portfolio/bottega-cert.png
index ac77c64..54f1716 100644
Binary files a/public/portfolio/bottega-cert.png and b/public/portfolio/bottega-cert.png differ
diff --git a/public/portfolio/linux-cert-full.png b/public/portfolio/linux-cert-full.png
new file mode 100644
index 0000000..8766927
Binary files /dev/null and b/public/portfolio/linux-cert-full.png differ
diff --git a/public/portfolio/linux-cert.png b/public/portfolio/linux-cert.png
index 8766927..6ee7bd8 100644
Binary files a/public/portfolio/linux-cert.png and b/public/portfolio/linux-cert.png differ
diff --git a/public/portfolio/projects/codepen.png b/public/portfolio/projects/codepen.png
index 47eb9b3..54988a9 100644
Binary files a/public/portfolio/projects/codepen.png and b/public/portfolio/projects/codepen.png differ
diff --git a/public/portfolio/projects/khufu.png b/public/portfolio/projects/khufu.png
index bb30d01..4fb6910 100644
Binary files a/public/portfolio/projects/khufu.png and b/public/portfolio/projects/khufu.png differ
diff --git a/public/portfolio/projects/minecluster.png b/public/portfolio/projects/minecluster.png
new file mode 100644
index 0000000..af14175
Binary files /dev/null and b/public/portfolio/projects/minecluster.png differ
diff --git a/public/portfolio/projects/movieplayer.png b/public/portfolio/projects/movieplayer.png
index a08025d..0bc80f3 100644
Binary files a/public/portfolio/projects/movieplayer.png and b/public/portfolio/projects/movieplayer.png differ
diff --git a/public/portfolio/projects/qualiteer.png b/public/portfolio/projects/qualiteer.png
index 57238df..d4a1213 100644
Binary files a/public/portfolio/projects/qualiteer.png and b/public/portfolio/projects/qualiteer.png differ
diff --git a/public/portfolio/skills/html.png b/public/portfolio/skills/html.png
index 47d7cb5..67a77e8 100644
Binary files a/public/portfolio/skills/html.png and b/public/portfolio/skills/html.png differ
diff --git a/public/portfolio/skills/java.png b/public/portfolio/skills/java.png
index d800d41..a440f6f 100644
Binary files a/public/portfolio/skills/java.png and b/public/portfolio/skills/java.png differ
diff --git a/public/portfolio/skills/javascript.png b/public/portfolio/skills/javascript.png
index 8298dd0..31c17a6 100644
Binary files a/public/portfolio/skills/javascript.png and b/public/portfolio/skills/javascript.png differ
diff --git a/public/portfolio/skills/python.png b/public/portfolio/skills/python.png
index 7128613..5cb91d0 100644
Binary files a/public/portfolio/skills/python.png and b/public/portfolio/skills/python.png differ
diff --git a/public/portfolio/skills/react.png b/public/portfolio/skills/react.png
index ee1d3a3..31c17a6 100644
Binary files a/public/portfolio/skills/react.png and b/public/portfolio/skills/react.png differ
diff --git a/src/App.jsx b/src/App.jsx
index 51f6baa..6175e21 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,8 +1,5 @@
import { createRoot } from "react-dom/client";
import Nile from "./Nile.jsx";
-import Footer from "./pages/delta/Footer.jsx";
const nileRoot = createRoot(document.getElementById("root"));
nileRoot.render();
-/*const footerRoot = createRoot(document.getElementById("footer"))
-footerRoot.render();*/
diff --git a/src/Loading.jsx b/src/Loading.jsx
deleted file mode 100644
index ca6958a..0000000
--- a/src/Loading.jsx
+++ /dev/null
@@ -1,4 +0,0 @@
-import React from "react";
-export default function Loading() {
- return
They see me loading, they hating...
;
-}
diff --git a/src/Navbar.jsx b/src/Navbar.jsx
index 64bf345..abfded3 100644
--- a/src/Navbar.jsx
+++ b/src/Navbar.jsx
@@ -1,19 +1,60 @@
// React
+import { useState } from "react";
import { Link } from "react-router-dom";
import AppBar from "@mui/material/AppBar";
+import Drawer from "@mui/material/Drawer";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import Toolbar from "@mui/material/Toolbar";
import IconButton from "@mui/material/IconButton";
-import { Button } from "@mui/material";
+import Button from "@mui/material/Button";
+import ListItemText from "@mui/material/ListItemText";
+import List from "@mui/material/List";
+import ListItemButton from "@mui/material/ListItemButton";
import useMediaQuery from "@mui/material/useMediaQuery";
import { useTheme } from "@mui/material/styles";
+import MenuIcon from "@mui/icons-material/Menu";
+
+const links = [
+ { url: "/#portfolio", title: "Portfolio" },
+ { url: "/#achievements", title: "Achivements" },
+ { url: "/#contact", title: "Contact" },
+ //{ url: "/references", title: "References" },
+];
+
export default function Navbar() {
const theme = useTheme();
- const hideNavLinks = useMediaQuery(theme.breakpoints.down("md"));
+ const [miniNavOpen, setMiniNavOpen] = useState();
+ const miniNav = useMediaQuery(theme.breakpoints.down("md"));
+ const toggleMiniNavOpen = () => setMiniNavOpen(!miniNavOpen);
+
return (
+
+
+
+
+
+ {" "}
+ Back
+
+ {links.map((l, i) => (
+
+
+
+ ))}
+
+
+
Dunemask
- {!hideNavLinks && (
+ {miniNav && (
-
-
-
-
-
-
-
-
-
+
+
+
+
+ )}
+ {!miniNav && (
+
+ {links.map((l, i) => (
+
+
+
+ ))}
)}
diff --git a/src/Nile.jsx b/src/Nile.jsx
index 8307daf..3ea074a 100644
--- a/src/Nile.jsx
+++ b/src/Nile.jsx
@@ -1,7 +1,10 @@
-import { MemoryRouter } from "react-router-dom";
+import { useEffect } from "react";
+import { BrowserRouter /*MemoryRouter*/ } from "react-router-dom";
import Routing from "./Routing.jsx";
import Navbar from "./Navbar.jsx";
-import { useEffect } from "react";
+import Footer from "@components/Footer.jsx";
+import "./css/common.css";
+
export default function Nile() {
useEffect(() => {
const loadingElements = document.getElementById("loading");
@@ -9,9 +12,12 @@ export default function Nile() {
loadingElements.remove();
});
return (
-
+
+ {/**/}
-
+
+ {/**/}
+
);
}
diff --git a/src/Routing.jsx b/src/Routing.jsx
index 026c81d..19725ed 100644
--- a/src/Routing.jsx
+++ b/src/Routing.jsx
@@ -1,7 +1,7 @@
import { Routes, Route, Navigate } from "react-router-dom";
import Toolbar from "@mui/material/Toolbar";
import Delta from "./pages/delta/Delta.jsx";
-// import NotFound from "./pages/handlers/NotFound.jsx";
+import References from "./pages/references/References.jsx";
import { useScrollToLocation } from "./hooks.jsx";
export default function Routing() {
useScrollToLocation();
@@ -10,8 +10,9 @@ export default function Routing() {
} />
- {/*} /> */}
+ {/*} />*/}
} />
+ } />
);
diff --git a/src/components/ContentWrapper.jsx b/src/components/ContentWrapper.jsx
new file mode 100644
index 0000000..04f4a9b
--- /dev/null
+++ b/src/components/ContentWrapper.jsx
@@ -0,0 +1,20 @@
+import Box from "@mui/material/Box";
+import LogoBackground from "@components/LogoBackground.jsx";
+export default function ContentWrapper(props) {
+ const { id, children, noWrapper } = props;
+ return (
+
+ {!noWrapper && }
+
+ {children}
+
+
+ );
+}
diff --git a/src/pages/delta/Footer.jsx b/src/components/Footer.jsx
similarity index 96%
rename from src/pages/delta/Footer.jsx
rename to src/components/Footer.jsx
index 31aba69..3899cf8 100644
--- a/src/pages/delta/Footer.jsx
+++ b/src/components/Footer.jsx
@@ -1,6 +1,6 @@
import GitHubIcon from "@mui/icons-material/GitHub";
import LinkedInIcon from "@mui/icons-material/LinkedIn";
-import "../../css/footer.css";
+import "../css/footer.css";
export default function Footer() {
return (
diff --git a/src/components/LogoBackground.jsx b/src/components/LogoBackground.jsx
new file mode 100644
index 0000000..5b932a7
--- /dev/null
+++ b/src/components/LogoBackground.jsx
@@ -0,0 +1,25 @@
+export default function LogoBackground() {
+ return (
+
+
+

+
+
+ );
+}
diff --git a/src/css/common.css b/src/css/common.css
new file mode 100644
index 0000000..01d90f1
--- /dev/null
+++ b/src/css/common.css
@@ -0,0 +1,3 @@
+a:hover {
+ opacity: 0.8;
+}
diff --git a/src/css/footer.css b/src/css/footer.css
index 0581736..3a322e0 100644
--- a/src/css/footer.css
+++ b/src/css/footer.css
@@ -20,16 +20,12 @@ footer {
.connections a {
text-decoration: none;
color: white;
- padding: 0px 4px;
+ padding: 0px 5px;
width: 40;
height: 40;
margin: auto;
}
-.connections a:hover {
- opacity: 0.7;
-}
-
.copyright {
display: flex;
margin: auto 0;
diff --git a/src/hooks.jsx b/src/hooks.jsx
index 60238e5..ec39ce1 100644
--- a/src/hooks.jsx
+++ b/src/hooks.jsx
@@ -7,12 +7,14 @@ export function useScrollToLocation() {
const hashRef = React.useRef(hash);
React.useEffect(() => {
- if (!hash) return;
+ if (!hash) {
+ window.scrollTo(0, 0);
+ return;
+ }
if (hashRef.current !== hash) {
hashRef.current = hash;
scrolledRef.current = false;
}
- navigate();
if (scrolledRef.current) return;
const id = hash.replace("#", "");
const element = document.getElementById(id);
diff --git a/src/pages/delta/Delta.jsx b/src/pages/delta/Delta.jsx
index 3acf539..e822715 100644
--- a/src/pages/delta/Delta.jsx
+++ b/src/pages/delta/Delta.jsx
@@ -1,45 +1,21 @@
-import React from "react";
-import Box from "@mui/material/Box";
+import React, { Suspense } from "react";
import About from "./About.jsx";
import Projects from "./Projects.jsx";
//import Environments from "./Environments.jsx";
-import Footer from "./Footer.jsx";
+import ContentWrapper from "@components/ContentWrapper.jsx";
const Skills = React.lazy(() => import("./Skills.jsx"));
const Social = React.lazy(() => import("./Social.jsx"));
export default function Delta() {
return (
-
-
-
-

-
-
-
-
-
+
+
);
}
diff --git a/src/pages/delta/Environments.jsx b/src/pages/delta/Environments.jsx
index a02ceed..8a9bde9 100644
--- a/src/pages/delta/Environments.jsx
+++ b/src/pages/delta/Environments.jsx
@@ -4,6 +4,7 @@ import AccordionSummary from "@mui/material/AccordionSummary";
import AccordionDetails from "@mui/material/AccordionDetails";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import Box from "@mui/material/Box";
+import Typography from "@mui/material/Typography";
export default function Environments() {
return (
@@ -19,7 +20,7 @@ export default function Environments() {
expandIcon={}
style={{ margin: 0 }}
>
- Environments
+ Environment
setGitHov(!gitHov);
const imageClick = () => openPhoto(image);
return (
@@ -48,6 +54,7 @@ export default function ProjectTile({
display: "inline-flex",
width: "100%",
justifyContent: smallMode ? "center" : "",
+ flexWrap: "wrap",
}}
>
@@ -65,6 +72,25 @@ export default function ProjectTile({
>
{year}
+
+
+
Portfolio
+
+ Deploy and monitor MInecraft servers in your kubernetes cluster. Easily
+ scales and provides a stateful experience to make managing multiple
+ servers simple.
+
Manage failing tests and silence unecessary alerts. Check the state of
@@ -38,6 +50,7 @@ export default function Projects() {
image="/portfolio/projects/khufu.png"
title="Khufu"
year="2021"
+ link="https://gitea.dunemask.net/elysium/khufu"
openPhoto={openPhoto}
>
Basic cloud file management built on React class components. Simple
@@ -47,12 +60,13 @@ export default function Projects() {
image="/portfolio/projects/codepen.png"
title="Codepen"
year="2020"
+ link="https://gitea.dunemask.net/dunemask/codepen"
openPhoto={openPhoto}
>
Visual replication of the website{" "}
codepen.io
{" "}
@@ -62,6 +76,7 @@ export default function Projects() {
image="/portfolio/projects/movieplayer.png"
title="Media Player"
year="2018"
+ link="https://legacy-21.dunemask.net/files/java/MoviePlayer.jar"
openPhoto={openPhoto}
>
Simple media player built on javafx. Player supports media seeking,
@@ -71,6 +86,7 @@ export default function Projects() {
image="/portfolio/projects/voxelcraft.png"
title="Voxelcraft"
year="2018"
+ link="https://gitea.dunemask.net/dunemask/voxelcraft"
openPhoto={openPhoto}
>
Voxel game built on a simple rendering engine written with JavaFX.
diff --git a/src/pages/delta/SkillPaper.jsx b/src/pages/delta/SkillPaper.jsx
index cce9481..a8ff474 100644
--- a/src/pages/delta/SkillPaper.jsx
+++ b/src/pages/delta/SkillPaper.jsx
@@ -23,7 +23,6 @@ export default function SkillPaper({
>
diff --git a/src/pages/delta/Skills.jsx b/src/pages/delta/Skills.jsx
index d807386..882ffc1 100644
--- a/src/pages/delta/Skills.jsx
+++ b/src/pages/delta/Skills.jsx
@@ -1,4 +1,4 @@
-import React, { Suspense, useState, useEffect } from "react";
+import React, { Suspense, useState } from "react";
import { FaReact, FaPython, FaJava, FaHtml5 } from "react-icons/fa";
import { SiJavascript } from "react-icons/si";
import Typography from "@mui/material/Typography";
@@ -9,14 +9,14 @@ import SkillPaper from "./SkillPaper.jsx";
import PhotoHover from "./PhotoHover.jsx";
import Skeleton from "@mui/material/Skeleton";
-const Carousel = React.lazy(() => import("react-material-ui-carousel"));
+import "react-responsive-carousel/lib/styles/carousel.min.css";
+import { Carousel } from "react-responsive-carousel";
+
export default function Skills() {
+ const carouselInterval = 7000;
const [image, setImage] = useState();
const [open, setOpen] = useState(false);
- const [carouselInterval, setCarouselInterval] = useState(200);
- useEffect(()=>{setTimeout(()=>setCarouselInterval(7000),500)},[]); // Mitigates bug where height doesn't load properly
-
function openPhoto(image) {
setImage(image);
setOpen(true);
@@ -27,7 +27,6 @@ export default function Skills() {
const skills = [
,
,
,
,
,
];
+ const openSkill = (skillIndex) => openPhoto(skills[skillIndex].props.src);
+
return (
-
+
Certifications
-
+
-
+
-
- Pluralsight Scores
-
+
+ Pluralsight IQ
+
{skills.map((skill, i) => (
{skill}
diff --git a/src/pages/delta/Social.jsx b/src/pages/delta/Social.jsx
index 082d2f9..f918ceb 100644
--- a/src/pages/delta/Social.jsx
+++ b/src/pages/delta/Social.jsx
@@ -3,6 +3,7 @@ import MailIcon from "@mui/icons-material/Mail";
import GitHubIcon from "@mui/icons-material/GitHub";
import LinkedInIcon from "@mui/icons-material/LinkedIn";
import { FaGitlab } from "react-icons/fa";
+import { SiGitea } from "react-icons/si";
const socialLinks = [
{
@@ -13,9 +14,13 @@ const socialLinks = [
url: "mailto: elijahglennparker@outlook.com",
icon: ,
},
+ {
+ url: "https://gitea.dunemask.net/dunemask",
+ icon: ,
+ },
{
url: "https://gitlab.com/dunemask",
- icon: ,
+ icon: ,
},
{
url: "https://github.com/dunemask",
@@ -33,7 +38,7 @@ export default function Social() {
{v.icon}
diff --git a/src/pages/handlers/NotFound.jsx b/src/pages/handlers/NotFound.jsx
deleted file mode 100644
index 05ec911..0000000
--- a/src/pages/handlers/NotFound.jsx
+++ /dev/null
@@ -1,3 +0,0 @@
-export default function NotFound() {
- return Page not found!
;
-}
diff --git a/src/pages/references/References.jsx b/src/pages/references/References.jsx
new file mode 100644
index 0000000..da7a2fd
--- /dev/null
+++ b/src/pages/references/References.jsx
@@ -0,0 +1,13 @@
+import React from "react";
+import Box from "@mui/material/Box";
+import ContentWrapper from "../../components/ContentWrapper";
+
+export default function References() {
+ return (
+
+
+ References
+
+
+ );
+}
diff --git a/vite.config.js b/vite.config.js
index da2170d..7f96f33 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -17,6 +17,8 @@ export default () => {
resolve: {
alias: {
"@": path.resolve("./src"),
+ "@components": path.resolve("./src/components"),
+ "@images": path.resolve("./src/images")
},
},
});