[FEATURE] Add Resume, Contact, Routing Fix, and About sections (#9)

Co-authored-by: dunemask <dunemask@gmail.com>
Co-authored-by: Dunemask <dunemask@gmail.com>
Reviewed-on: https://gitea.dunemask.net/elysium/nile/pulls/9
This commit is contained in:
dunemask 2023-09-25 20:49:09 +00:00
parent cc360597f8
commit 7d3c264b30
17 changed files with 500 additions and 64 deletions

View file

@ -26,7 +26,7 @@ keepalive_timeout 65;
location / { location / {
root /usr/share/nginx/html; root /usr/share/nginx/html;
index index.html index.htm; index index.html index.htm;
try_files $uri $uri/ /index.html; try_files $uri /index.html;
} }
location ~ ^/$ { location ~ ^/$ {

BIN
public/resume/About.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View file

@ -17,10 +17,12 @@ import { useTheme } from "@mui/material/styles";
import MenuIcon from "@mui/icons-material/Menu"; import MenuIcon from "@mui/icons-material/Menu";
const links = [ const links = [
// { url: "/", title: "Home" },
{ url: "/#portfolio", title: "Portfolio" }, { url: "/#portfolio", title: "Portfolio" },
{ url: "/#achievements", title: "Achivements" }, // { url: "/#achievements", title: "Achievements" },
{ url: "/#about", title: "About" },
{ url: "/#contact", title: "Contact" }, { url: "/#contact", title: "Contact" },
//{ url: "/references", title: "References" }, // { url: "/resume", title: "Resume" },
]; ];
export default function Navbar() { export default function Navbar() {

View file

@ -1,8 +1,14 @@
import { Routes, Route, Navigate } from "react-router-dom"; import { Routes, Route, Navigate } from "react-router-dom";
import Toolbar from "@mui/material/Toolbar"; import Toolbar from "@mui/material/Toolbar";
import Delta from "./pages/delta/Delta.jsx"; import Delta from "./pages/delta/Delta.jsx";
import References from "./pages/references/References.jsx"; import Resume from "./pages/resume/Resume.jsx";
import { useScrollToLocation } from "./hooks.jsx"; import { useScrollToLocation } from "./hooks.jsx";
const redirects = [
{ path: "/r1", rewrite: "/resume" },
{ path: "/r2", rewrite: "/resume" },
{ path: "/r3", rewrite: "/resume" },
];
export default function Routing() { export default function Routing() {
useScrollToLocation(); useScrollToLocation();
return ( return (
@ -10,7 +16,10 @@ export default function Routing() {
<Toolbar disableGutters /> <Toolbar disableGutters />
<Routes> <Routes>
<Route path="/" element={<Delta />} /> <Route path="/" element={<Delta />} />
{/*<Route path="/references" element={<References />} />*/} {/* <Route path="/resume" element={<Resume />} /> */}
{redirects.map((r, i) => (
<Route key={i} path={r.path} element={<Navigate to={r.rewrite} />} />
))}
<Route path="*" element={<Navigate to="/" replace />} /> <Route path="*" element={<Navigate to="/" replace />} />
<Route path="/*" element={<Navigate to="/" replace />} /> <Route path="/*" element={<Navigate to="/" replace />} />
</Routes> </Routes>

View file

@ -0,0 +1,18 @@
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import "@css/experience-display.css";
export default function ExperienceDisplay(props) {
const { title, subtitle, children } = props;
return (
<Box
className="experience-display"
sx={{ borderLeft: "2px solid #F3AC20", paddingLeft: "20px", mt: "1rem" }}
>
<Typography variant="h6">{title}</Typography>
<Typography variant="body2" sx={{ opacity: 0.7 }}>
{subtitle}
</Typography>
<Box className="experience-display-content">{children}</Box>
</Box>
);
}

View file

@ -0,0 +1,3 @@
export default function PageNav(props) {
const { links } = props;
}

View file

@ -0,0 +1,9 @@
.experience-display::before {
content: "";
position: absolute;
padding: 6px;
border: 2px solid #f3ac20;
border-radius: 50%;
margin-left: -28px;
margin-top: -16px;
}

View file

@ -19,7 +19,11 @@ export function useScrollToLocation() {
const id = hash.replace("#", ""); const id = hash.replace("#", "");
const element = document.getElementById(id); const element = document.getElementById(id);
if (!element) return; if (!element) return;
element.scrollIntoView({ behavior: "smooth", block: "start" }); element.scrollIntoView({
behavior: "smooth",
block: "start",
inline: "nearest",
});
scrolledRef.current = true; scrolledRef.current = true;
}); });
} }

View file

@ -1,28 +1,135 @@
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import useMediaQuery from "@mui/material/useMediaQuery";
import { useTheme } from "@mui/material/styles";
export default function Projects() { const dob = new Date(2002, 4, 3);
const age = Math.abs(
new Date(Date.now() - dob.getTime()).getUTCFullYear() - 1970,
);
function AboutContact(props) {
const { title, info } = props;
return (
<Typography sx={{ fontWeight: 600 }}>
{`${title}:`}
<span
style={{
fontFamily: "inherit",
paddingLeft: ".5rem",
fontSize: "14px",
}}
>
{info}
</span>
</Typography>
);
}
export default function About() {
const theme = useTheme();
const fullSizePhoto = useMediaQuery(theme.breakpoints.down("md"));
return ( return (
<Box> <Box>
<Box sx={{ maxWidth: 570, margin: "4rem auto", padding: "2rem" }}> <Box
<Typography variant="h4" component="div" sx={{ fontWeight: 600 }}> sx={{
React Fullstack Software Engineer m: "0rem 0 2rem 0",
</Typography> padding: "0 2rem",
<Typography variant="body1"> textAlign: "left",
Specializing in DevOps tools and code reliability. If you're a }}
business seeking to improve developer velocity or are looking to hire, style={{ scrollMarginTop: "4rem" }}
contact me{" "} id="about"
<a >
href="https://www.linkedin.com/in/elijah-parker-dunemask" <div style={{ display: "flex" }}>
style={{ <Typography variant="h2" sx={{ margin: "2rem auto", fontSize: 30 }}>
textDecoration: "none", About
fontSize: "inherit", </Typography>
fontFamily: "inherit", </div>
<Box sx={{ display: "flex", flexWrap: "wrap" }}>
{!fullSizePhoto && (
<img
src="/resume/About.jpeg"
style={{
width: "100%",
maxWidth: "400px",
height: "100%",
padding: "0 1rem",
borderRadius: "10%",
}}
/>
)}
{fullSizePhoto && (
<img
src="/resume/About.jpeg"
style={{
width: "90%",
height: "90%",
margin: "0 auto",
borderRadius: "10%",
}}
/>
)}
<Box
sx={{
minWidth: "180px",
maxWidth: fullSizePhoto ? "100%" : "700px",
width: "100%",
display: fullSizePhoto ? "flex" : "block",
flex: "1 1 180px",
flexWrap: "wrap",
margin: fullSizePhoto ? "0" : "0 0 0 1rem",
pt: fullSizePhoto ? "2rem" : "0",
}} }}
> >
here <Typography variant="h6" component="div" sx={{ fontWeight: 600 }}>
</a> React Fullstack Software Engineer
</Typography> </Typography>
<Typography variant="body1">
Hello! I'm Elijah Parker, a fullstack software engineer from Utah.
I have a passion for developing software that achieves "the
impossible". I have experience using a wide variety of
technologies including React, Python, Java, and Kubernetes. I'm
currently seeking an entry-level part time position or internship
with flexible hours to accommodate pursuit of a bachelorette
degree.
</Typography>
<Box
className="about-contacts"
sx={{
pt: "2rem",
display: "flex",
flexWrap: "wrap",
width: "100%",
overflow: "hidden",
}}
>
<Box className="about-contacts-left" sx={{ minWidth: "50%" }}>
<AboutContact
title="Email"
info={
<a
href="mailto:elijahglennparker@outlook.com"
style={{ textDecoration: "none", fontSize: "14px" }}
>
elijahglennparker@outlook.com
</a>
}
/>
<AboutContact title="From" info="Utah, USA" />
</Box>
<Box className="about-contacts-right" sx={{ minWidth: "50%" }}>
<AboutContact title="Age" info={age} />
<AboutContact title="Freelance" info="Available" />
</Box>
</Box>
<Typography variant="body1" sx={{ mt: "2rem" }}>
Additionally, I have worked with a wide range of tools and
frameworks including Git, PostgreSQL, MongoDB, Docker, Kubernetes,
Garden, JavaFX, MaterialUI, Spring Boot, Express, Gitlab, Gitea
CI/CD.
</Typography>
</Box>
</Box>
</Box> </Box>
</Box> </Box>
); );

View file

@ -1,12 +1,39 @@
import { useState } from "react";
import { Link } from "react-router-dom";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import TextField from "@mui/material/TextField"; import TextField from "@mui/material/TextField";
import MailIcon from "@mui/icons-material/Mail"; import MailIcon from "@mui/icons-material/Mail";
import LocationOnIcon from "@mui/icons-material/LocationOn"; import LocationOnIcon from "@mui/icons-material/LocationOn";
import PhoneIphoneIcon from "@mui/icons-material/PhoneIphone"; import PhoneIphoneIcon from "@mui/icons-material/PhoneIphone";
import ContactStrip from "./ContactStrip.jsx"; import ContactStrip from "./ContactStrip.jsx";
import useMediaQuery from "@mui/material/useMediaQuery";
import { useTheme, styled } from "@mui/material/styles";
import "@css/contact.css"; import "@css/contact.css";
const ContactMessageButton = styled(Button)({
backgroundColor: "white",
color: "#F3AC20",
borderColor: "#F3AC20",
"&:hover": {
backgroundColor: "#F3AC20",
color: "white",
borderColor: "#F3AC20",
},
});
export default function Contact() { export default function Contact() {
const theme = useTheme();
const minifyContact = useMediaQuery(theme.breakpoints.down("md"));
const [contactName, setContactName] = useState();
const [contactEmail, setContactEmail] = useState();
const [contactSubject, setContactSubject] = useState();
const [contactBody, setContactBody] = useState();
const fillForm = (form) => (e) => form(e.target.value);
return ( return (
<Box style={{ padding: 10, scrollMarginTop: "4rem" }} id="contact"> <Box style={{ padding: 10, scrollMarginTop: "4rem" }} id="contact">
<Box <Box
@ -47,12 +74,79 @@ export default function Contact() {
info="+1 (234) 456 7890" info="+1 (234) 456 7890"
/>*/} />*/}
</Box> </Box>
{/*<Box className="messaging"> <Box
<TextField label="Name" size="small" /> className="messaging"
<TextField label="Subject" size="small"/> sx={{
<TextField label="Email" size="small"/> display: "flex",
<TextField label="Message" size="small" multiline/> flexWrap: "wrap",
</Box>*/} gap: "1.5rem",
maxWidth: "42em",
width: "100%",
m: "0 auto",
}}
>
<Box
className="messaging-head"
sx={{
display: "flex",
justifyContent: "center",
gap: "1.5rem",
width: "100%",
flexWrap: "wrap",
}}
>
<TextField
label="Name"
size="small"
sx={{
maxWidth: minifyContact ? "100%" : "20em",
width: "100%",
}}
onChange={fillForm(setContactName)}
required
type="name"
/>
<TextField
label="Email"
size="small"
sx={{
maxWidth: minifyContact ? "100%" : "20em",
width: "100%",
}}
onChange={fillForm(setContactEmail)}
required
type="email"
/>
</Box>
<TextField
label="Subject"
size="small"
sx={{ width: "100%" }}
onChange={fillForm(setContactSubject)}
required
/>
<TextField
label="Message"
size="small"
multiline
sx={{ width: "100%" }}
maxRows={5}
minRows={3}
onChange={fillForm(setContactBody)}
required
/>
<ContactMessageButton
variant="outlined"
sx={{ m: "0 auto", width: "100%", maxWidth: "16em" }}
component={Link}
to={`mailto:elijahglennparker@outlook.com?subject=${contactSubject} | ${contactName} | ${contactEmail}&body=${contactBody}`}
disabled={
!(contactSubject && contactBody && contactName && contactEmail)
}
>
Send Message
</ContactMessageButton>
</Box>
</Box> </Box>
</Box> </Box>
</Box> </Box>

View file

@ -1,23 +1,33 @@
import React, { Suspense } from "react"; import React, { Suspense } from "react";
import About from "./About.jsx"; import Box from "@mui/material/Box";
import Header from "./Header.jsx";
import Projects from "./Projects.jsx"; import Projects from "./Projects.jsx";
import Contact from "./Contact.jsx";
//import Environments from "./Environments.jsx"; //import Environments from "./Environments.jsx";
import ContentWrapper from "@components/ContentWrapper.jsx"; import ContentWrapper from "@components/ContentWrapper.jsx";
const Skills = React.lazy(() => import("./Skills.jsx")); const Skills = React.lazy(() => import("./Skills.jsx"));
const Social = React.lazy(() => import("./Social.jsx")); const Social = React.lazy(() => import("./Social.jsx"));
const Contact = React.lazy(() => import("./Contact.jsx")); const Education = React.lazy(() => import("./Education.jsx"));
const Experience = React.lazy(() => import("./Experience.jsx"));
const About = React.lazy(() => import("./About.jsx"));
export default function Delta() { export default function Delta() {
return ( return (
<ContentWrapper id="delta"> <ContentWrapper id="delta">
<About /> <Header />
<Projects /> <Projects />
<Suspense> <Suspense>
<About />
<Box style={{ display: "flex", flexWrap: "wrap" }}>
<Education />
<Experience />
</Box>
<Skills /> <Skills />
<Social /> <Social />
<Contact />
</Suspense> </Suspense>
<Contact />
</ContentWrapper> </ContentWrapper>
); );
} }

View file

@ -0,0 +1,67 @@
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import ExperienceDisplay from "@components/ExperienceDisplay.jsx";
export default function Education() {
return (
<Box
style={{
padding: 10,
scrollMarginTop: "4rem",
maxWidth: "500px",
margin: "0 auto",
textAlign: "left",
width: "100%",
}}
id="education"
>
<Typography
variant="h2"
sx={{ margin: "1rem auto", fontSize: 30, pb: ".5rem" }}
>
Education
</Typography>
<Box className="education-list">
<ExperienceDisplay
title="Computer Science Student"
subtitle="Jan 2024 - Present"
>
<Typography sx={{ pt: "1rem" }}>
Pursuing B.S. in Computer Science: Software Engineering program,
completed 7 credits. Anticipated graduation December 2027
</Typography>
</ExperienceDisplay>
<ExperienceDisplay
title="Full Stack Web Development"
subtitle="Dec 2018 - May 2020 | Bottega devCamp"
>
<Typography sx={{ pt: "1rem" }}>
Certificate of Competency in advanced Python, database foundations,
system analysis, UML, and advanced web development using HTML,
JavaScript, React, XML, and JSON
</Typography>
</ExperienceDisplay>
<ExperienceDisplay
title="High School Diploma"
subtitle="Aug 2017 - May 2020 | American Fork Highschool"
>
<Typography sx={{ pt: "1rem" }}>
GPA 3.9, CS Department Choice Award, Co-founder and President
Computer Science Club, 4 years programming, student tutor, AP
courses in Computer Science, Calculus, Mechanics, and Government
</Typography>
</ExperienceDisplay>
<ExperienceDisplay
title="Cyber Security and Networking"
subtitle="Jan 2019 - May 2019 | AFAs CyberPatriot"
>
<Typography sx={{ pt: "1rem" }}>
2nd Place state networking security challenge, curriculum included
Ubuntu security policies and PAM, networking, init systems, advanced
command line, processes, and scheduled tasks
</Typography>
</ExperienceDisplay>
</Box>
</Box>
);
}

View file

@ -0,0 +1,74 @@
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import ExperienceDisplay from "@components/ExperienceDisplay.jsx";
export default function Experience() {
return (
<Box
style={{
padding: 10,
scrollMarginTop: "4rem",
maxWidth: "500px",
margin: "0 auto",
textAlign: "left",
width: "100%",
}}
id="experience"
>
<Typography
variant="h2"
sx={{ margin: "1rem auto", fontSize: 30, pb: ".5rem" }}
>
Experience
</Typography>
<Box className="experience-list">
<ExperienceDisplay
title="Software Engineer Intern"
subtitle="Jun - Nov 2021 | Podium, Lehi UT"
>
<Typography variant="body1" sx={{ fontWeight: 600, pt: "1rem" }}>
Technologies used:{" "}
<span
style={{
fontFamily: "inherit",
fontSize: "14px",
}}
>
React, Python, Java, RabbitMQ
</span>
</Typography>
<ul style={{ paddingLeft: "25px" }}>
<li>
<Typography>
Developed automated end to end UI & API tests and automated
collection of test coverage
</Typography>
</li>
<li>
<Typography>
Modularized API testing resources as project lead
</Typography>
</li>
<li>
<Typography>
Automated scripting framework to gauge product reliability as
project lead
</Typography>
</li>
<li>
<Typography>
Improved performance of core QA services by 20%
</Typography>
</li>
<li>
<Typography>
Created fullstack application using React and Express to manage
QA data as solo developer
</Typography>
</li>
</ul>
</ExperienceDisplay>
</Box>
</Box>
);
}

View file

@ -0,0 +1,29 @@
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
export default function Header() {
return (
<Box>
<Box sx={{ maxWidth: 570, margin: "4rem auto", padding: "2rem" }}>
<Typography variant="h4" component="div" sx={{ fontWeight: 600 }}>
React Fullstack Software Engineer
</Typography>
<Typography variant="body1">
Specializing in DevOps tools and code reliability. If you're a
business seeking to improve developer velocity or are looking to hire,
contact me{" "}
<a
href="/#contact"
style={{
textDecoration: "none",
fontSize: "inherit",
fontFamily: "inherit",
}}
>
here
</a>
</Typography>
</Box>
</Box>
);
}

View file

@ -1,7 +1,6 @@
import React from "react"; import React from "react";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import ContentWrapper from "../../components/ContentWrapper";
import ContactCard from "./ContactCard.jsx"; import ContactCard from "./ContactCard.jsx";
const people = [ const people = [
@ -36,35 +35,32 @@ const people = [
export default function References() { export default function References() {
return ( return (
<Box id="references"> <Box style={{ padding: 10, scrollMarginTop: "4rem" }} id="references">
<ContentWrapper> <div style={{ display: "flex" }}>
<Box className="references-list"> <Typography variant="h2" sx={{ margin: "2rem auto", fontSize: 30 }}>
<Box sx={{ maxWidth: 570, margin: "4rem auto", padding: "2rem" }}> References
<Typography variant="h4" sx={{ fontWeight: 600 }}> </Typography>
References{" "} </div>
</Typography>{" "}
</Box> <Box
<Box sx={{
sx={{ display: "flex",
display: "flex", flexWrap: "wrap",
flexWrap: "wrap", justifyContent: "center",
justifyContent: "center", }}
}} >
> {people.map((p, i) => (
{people.map((p, i) => ( <ContactCard
<ContactCard key={i}
key={i} name={p.name}
name={p.name} title={p.title}
title={p.title} email={p.email}
email={p.email} linkedin={p.linkedin}
linkedin={p.linkedin} description={p.description}
description={p.description} avatar={p.avatar}
avatar={p.avatar} />
/> ))}
))} </Box>
</Box>
</Box>
</ContentWrapper>
</Box> </Box>
); );
} }

View file

@ -0,0 +1,14 @@
import React from "react";
import Box from "@mui/material/Box";
import ContentWrapper from "../../components/ContentWrapper";
import References from "./References.jsx";
export default function Resume() {
return (
<Box id="resume">
<ContentWrapper>
<References />
</ContentWrapper>
</Box>
);
}