implemented responsive portfolio and adjusted font sizes globally.

This commit is contained in:
Joshua Ashton
2025-01-08 21:26:33 -07:00
parent 7fe060c096
commit d83699380f
5 changed files with 233 additions and 183 deletions
+2 -109
View File
@@ -8,119 +8,12 @@ import "./main.css";
/* /*
* Primary portfolio application. Utilizes swiper.js (via /components/VerticalSlider.jsx) to * Primary portfolio application. Utilizes swiper.js (via /components/VerticalSlider.jsx) to
* have a scrolling section to section effect. * have a scrolling section to section effect.
*
* This is the primary place where (currently) application data is stored. This information will be read in
* from plain-text files in the future for ease of future editing. In the meantime, generated components,
* specifically the Skill Card and Project Card (see /components/SkillCard.jsx and /components/ProjectCard.jsx)
* get their data from here and thus any additions are made in this file.
*
* TODO: Read in data from a plain text file for easier editing in the future, and to separate domains.
*/ */
const App = () => { const App = ({ projectData, skillData }) => {
// DATA VARIABLES
const projectData = [
{
title: "One AI",
description:
"An end-to-end self-hosted Artificial Intelligence solution, using Meta's Ollama platform to run Large Language Models. Go was used for the backend as a wrapper API and the frontend is Flutter. Here are some of the implemented features:",
featureList: [
"AES encryption of messages between client and server",
"SHA-256 hashing for message validation",
"Base64 encoding for file uploads to the server",
"Docker container for isolation and security",
],
image: "/images/one-ai-cropped.png",
imageGallery: null,
url: "https://github.com/quaxlyqueen/one-ai",
},
{
title: "Snake",
description:
"A Snake clone in the command line, written in C#. Utilized a Queue data structure to keep track of the snake's body. Implemented features include:",
featureList: [
"basic pseudo-randomized obstacle generation",
"difficulty selection by adjusting the frequency of obstacle generation",
"keyboard input to move the snake",
"ASCII art for the menu and game over state",
],
image: "/images/snake.gif",
imageGallery: null,
url: "https://github.com/quaxlyqueen/2410-Snake",
},
{
title: "Battery Monitor",
description:
"A battery monitor, written in C with a GUI written in Python. Utilizes the acpi Unix command to gather battery information. Implemented features incldue:",
featureList: [
"embed Unix commands in C to get the date, time, battery percentage, and battery status",
"basic file I/O to store historical battery data",
"daemonize to run as a background process",
"script to install as a SystemD service",
"basic Python GUI in TKinter to provide graph of data",
],
image: "/images/battery-mon.png",
imageGallery: null,
url: "https://github.com/quaxlyqueen/battery-mon",
},
{
title: "D&D Character Builder",
description:
"A Dungeons and Dragons character builder, following the 5th edition rules and creation process. A collaborative project creating a GUI in Java with Swing. Features include:",
featureList: [
"serialization of character data into custom filetype",
"global styling and custom font import",
"button hover effects",
],
image: "/images/dnd.png",
imageGallery: null,
url: "https://github.com/quaxlyqueen/dnd",
},
{
title: "Calculator",
description:
"A simple and themable calculator written in Python. This uses CustomTKinter for the GUI and the eva CLI package for the actual calculator functionality. Supports MacOS and Linux. Implemented features include:",
featureList: [
"custom theming read in from a global .theme file",
"button hover effects",
"keyboard input",
],
image: "/images/calculator.gif",
imageGallery: null,
url: "https://github.com/quaxlyqueen/calculator",
},
];
const skillsData = {
languages: [
"C & C#",
"HTML & CSS",
"Go",
"Java",
"JavaScript & Dart",
"Python",
],
tools: [
"Git & GitHub",
"Docker",
"Flutter & React",
"Linux & NeoVim",
"Cloudflare",
"Microsoft Intune",
],
other: [
"Written Communication",
"Conflict Resolution",
"Project Management",
"Event Planning",
"Electronics Repair",
"Soldering",
],
};
const slides = [ const slides = [
<Home <Home
image="/images/profile.jpg" image="/images/profile.jpg"
skills={skillsData} skills={skillData}
/>, />,
<Projects cardData={projectData} />, <Projects cardData={projectData} />,
<Contact />, <Contact />,
+43 -51
View File
@@ -6,7 +6,7 @@ import React from "react";
* TODO: Rework resume to make it one page * TODO: Rework resume to make it one page
* TODO: Convert resume to a React component, with a link to save as PDF * TODO: Convert resume to a React component, with a link to save as PDF
*/ */
export default function Resume() { export default function Resume({ jobData, eduData, skillData }) {
/* /*
* *
{ {
@@ -21,57 +21,47 @@ export default function Resume() {
}, },
*/ */
const jobData = [
{
company: "SLC Public Library",
title: "Technology & Digital Equity Assistant",
start: "Aug. 2023",
end: "Present",
location: "Salt Lake City, UT",
responsibilities: [
"Assist library patrons with using technology, on devices such as publicly available PCs, laptops, mobile devices, and more.",
"Teach fundamental computer usage skills.",
"Expose patrons to the importance of digital security, password management, and two-factor authentication.",
"Developing workshop curriculum for Raspberry Pi’s."
],
},
{
company: "Trust Lands Administration",
title: "IT Intern",
start: "Aug. 2023",
end: "Aug. 2024",
location: "Salt Lake City, UT",
responsibilities: [
"Orchestrated Microsoft Intune setup and deployment to multiple platforms.",
"Streamlined IT equipment inventory process",
"Provided training to optimize the usage of hardware and software.",
"Troubleshoot and repair hardware and software on a variety of devices.",
"Developed automation scripts for use in various parts of the business.",
],
},
];
const eduData = [
{
institution: "",
degree: "",
gpa: "",
start: "",
end: "",
}
];
return ( return (
<> <>
<div id="resume-section"> <div id="resume-section">
<h1>Josh Ashton</h1> <h1>Josh Ashton</h1>
<h2>Junior Full-Stack Developer</h2> <h3>Junior Full-Stack Developer</h3>
<h3>Work Experience</h3> <h3>Work Experience</h3>
{jobData.map((job, index) => ( <div className="jobs">
<Job key={index} company={job.company} title={job.title} start={job.start} end={job.end} location={job.location} responsibilities={job.responsibilities} /> {jobData.map((job, index) => (
))} <Job key={index} company={job.company} title={job.title} start={job.start} end={job.end} location={job.location} responsibilities={job.responsibilities} />
))}
</div>
<h3>Education</h3> <h3>Education</h3>
<div className="education-section">
{eduData.map((edu, index) => (
<Education key={index} institution={edu.institution} degree={edu.degree} gpa={edu.gpa} start={edu.start} end={edu.end} />
))}
</div>
<h3>Skills</h3>
<Skill languages={skillData.languages} tools={skillData.tools} other={skillData.other} />
</div>
</>
);
}
<a href="/"><h3>Click here for my coding experience & skills!</h3></a> function Skill({ languages, tools, other }) {
return (
<>
<div className="resume-skills">
<div className="resume-skills-skill">
<h4>Languages:</h4>
<p>{languages.join(", ")}</p>
</div>
<div className="resume-skills-skill">
<h4>Tools:</h4>
<p>{tools.join(", ")}</p>
</div>
<div className="resume-skills-skill">
<h4>Other:</h4>
<p>{other.join(", ")}</p>
</div>
</div> </div>
</> </>
); );
@@ -81,16 +71,18 @@ function Education({ institution, degree, gpa, start, end }) {
return ( return (
<> <>
<div className="edu-header"> <div className="edu">
<div className="edu-header-row"> <div className="edu-header">
<div className="edu-and-degree"> <div className="edu-header-row">
<h4>{institution}</h4> <div className="edu-and-degree">
<h6>- {degree}</h6> <h4>{institution}</h4>
<h6>- {degree}</h6>
</div>
<h6 className="edu-time">{start} - {end}</h6>
</div> </div>
<h6 className="edu-time">{start} - {end}</h6> <h5>{gpa}</h5>
</div> </div>
</div> </div>
</> </>
); );
} }
+1 -1
View File
@@ -32,7 +32,7 @@ const SkillCard = ({ header, symbol, list, isActive, onToggle }) => {
<div className="card shadow"> <div className="card shadow">
<div className="skill-card-header" onClick={() => onToggle()}> <div className="skill-card-header" onClick={() => onToggle()}>
<span className="material-icons skill-symbol">{symbol}</span> <span className="material-icons skill-symbol">{symbol}</span>
<h3>{header}</h3> <h4>{header}</h4>
</div> </div>
{(isActive || !isMobile) && ( {(isActive || !isMobile) && (
<ul> <ul>
+44 -20
View File
@@ -53,7 +53,7 @@ li {
} }
h1 { h1 {
font-size: clamp(4.25rem, 5.5vw, 10rem); font-size: clamp(4rem, 5vw, 10rem);
font-weight: 600; font-weight: 600;
letter-spacing: 2px; letter-spacing: 2px;
width: max-content; width: max-content;
@@ -67,11 +67,11 @@ h3 {
} }
h2 { h2 {
font-size: clamp(2rem, 3vw, 4rem); font-size: clamp(3rem, 4vw, 7rem);
} }
h3 { h3 {
font-size: clamp(1.5rem, 2rem, 3rem); font-size: clamp(2rem, 3rem, 6rem);
} }
h4 { h4 {
@@ -85,20 +85,21 @@ h6 {
} }
h4 { h4 {
font-size: clamp(1rem, 1.5vw, 2rem); font-size: clamp(1rem, 1.5vw, 4rem);
} }
h5 { h5 {
font-size: clamp(1rem, 1.25vw, 1.5rem); font-size: clamp(1rem, 1.25vw, 3.5rem);
} }
h6 { h6 {
font-size: clamp(1rem, 1.125vw, 1.25rem); font-size: clamp(1rem, 1.125vw, 2rem);
} }
p { p,
font-weight: 200; li {
font-size: clamp(1rem, 1.5vw, 2rem); font-weight: 300;
font-size: clamp(1rem, 1.1vw, 1.5rem);
color: var(--text); color: var(--text);
} }
@@ -303,8 +304,8 @@ p {
border-radius: 18px 18px 0 0; border-radius: 18px 18px 0 0;
} }
.skill-card-header h3 { .skill-card-header h4 {
font-size: clamp(1.3rem, 2vw, 3rem); font-weight: 700;
text-align: right; text-align: right;
} }
@@ -324,7 +325,6 @@ p {
.card ul li { .card ul li {
list-style: none; list-style: none;
font-size: clamp(1rem, 1.25vw, 1.5rem);
color: var(--dark-0); color: var(--dark-0);
} }
@@ -377,7 +377,6 @@ p {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
margin-right: 5vw;
} }
/* Tooltip container */ /* Tooltip container */
@@ -449,6 +448,7 @@ p {
} }
.project-text p { .project-text p {
font-weight: 400;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
@@ -472,7 +472,6 @@ p {
} }
.feature-list li { .feature-list li {
font-size: clamp(1rem, 1.5rem, 2rem);
color: var(--text); color: var(--text);
} }
@@ -719,28 +718,38 @@ p {
width: 50%; width: 50%;
} }
.job { .jobs,
width: 100%; .education-section {
border-top: 1px solid var(--accent-0); border-top: 1px solid var(--accent-0);
width: 100%;
}
.job,
.edu {
width: 100%;
padding: 0vw 1vw 1vw 1vw; padding: 0vw 1vw 1vw 1vw;
} }
.job-header-row { .job-header-row,
.edu-header-row {
display: grid; display: grid;
grid-template-columns: 70% 30%; grid-template-columns: 70% 30%;
align-items: center; align-items: center;
} }
.job-time { .job-time,
.edu-time {
justify-self: right; justify-self: right;
} }
.company-and-location { .company-and-location,
.edu-and-degree {
display: flex; display: flex;
align-items: center; align-items: center;
} }
.company-and-location h6 { .company-and-location h6,
.edu-and-degree h6 {
margin-left: .25vw; margin-left: .25vw;
} }
@@ -753,6 +762,21 @@ p {
font-weight: 300; font-weight: 300;
} }
.resume-skills {
border-top: 1px solid var(--accent-0);
width: 100%;
}
.resume-skills-skill {
display: flex;
align-items: center;
}
.resume-skills-skill p {
margin-left: .5vw;
padding: 1vw;
}
/**Animations**/ /**Animations**/
@keyframes background-fade { @keyframes background-fade {
from { from {
+143 -2
View File
@@ -10,11 +10,152 @@ import ErrorPage from "./ErrorPage.jsx";
*/ */
const container = document.getElementById("app"); const container = document.getElementById("app");
const root = createRoot(container); const root = createRoot(container);
// TODO: Read data in from plain text files.
const projectData = [
{
title: "One AI",
description:
"An end-to-end self-hosted Artificial Intelligence solution, using Meta's Ollama platform to run Large Language Models. Go was used for the backend as a wrapper API and the frontend is Flutter. Here are some of the implemented features:",
featureList: [
"AES encryption of messages between client and server",
"SHA-256 hashing for message validation",
"Base64 encoding for file uploads to the server",
"Docker container for isolation and security",
],
image: "/images/one-ai-cropped.png",
imageGallery: null,
url: "https://github.com/quaxlyqueen/one-ai",
},
{
title: "Snake",
description:
"A Snake clone in the command line, written in C#. Utilized a Queue data structure to keep track of the snake's body. Implemented features include:",
featureList: [
"basic pseudo-randomized obstacle generation",
"difficulty selection by adjusting the frequency of obstacle generation",
"keyboard input to move the snake",
"ASCII art for the menu and game over state",
],
image: "/images/snake.gif",
imageGallery: null,
url: "https://github.com/quaxlyqueen/2410-Snake",
},
{
title: "Battery Monitor",
description:
"A battery monitor, written in C with a GUI written in Python. Utilizes the acpi Unix command to gather battery information. Implemented features incldue:",
featureList: [
"embed Unix commands in C to get the date, time, battery percentage, and battery status",
"basic file I/O to store historical battery data",
"daemonize to run as a background process",
"script to install as a SystemD service",
"basic Python GUI in TKinter to provide graph of data",
],
image: "/images/battery-mon.png",
imageGallery: null,
url: "https://github.com/quaxlyqueen/battery-mon",
},
{
title: "D&D Character Builder",
description:
"A Dungeons and Dragons character builder, following the 5th edition rules and creation process. A collaborative project creating a GUI in Java with Swing. Features include:",
featureList: [
"serialization of character data into custom filetype",
"global styling and custom font import",
"button hover effects",
],
image: "/images/dnd.png",
imageGallery: null,
url: "https://github.com/quaxlyqueen/dnd",
},
{
title: "Calculator",
description:
"A simple and themable calculator written in Python. This uses CustomTKinter for the GUI and the eva CLI package for the actual calculator functionality. Supports MacOS and Linux. Implemented features include:",
featureList: [
"custom theming read in from a global .theme file",
"button hover effects",
"keyboard input",
],
image: "/images/calculator.gif",
imageGallery: null,
url: "https://github.com/quaxlyqueen/calculator",
},
];
const skillData = {
languages: [
"C & C#",
"HTML & CSS",
"Go",
"Java",
"JavaScript & Dart",
"Python",
],
tools: [
"Git & GitHub",
"Docker",
"Flutter & React",
"Linux & NeoVim",
"Cloudflare",
"Microsoft Intune",
],
other: [
"Written Communication",
"Conflict Resolution",
"Project Management",
"Event Planning",
"Electronics Repair",
"Soldering",
],
};
const jobData = [
{
company: "SLC Public Library",
title: "Technology & Digital Equity Assistant",
start: "Aug '23",
end: "Present",
location: "Salt Lake City, UT",
responsibilities: [
"Assist library patrons with using technology, on devices such as publicly available PCs, laptops, mobile devices, and more.",
"Teach fundamental computer usage skills.",
"Expose patrons to the importance of digital security, password management, and two-factor authentication.",
"Developing workshop curriculum for Raspberry Pi’s."
],
},
{
company: "Trust Lands Admin.",
title: "IT Intern",
start: "Aug '23",
end: "Aug '24",
location: "Salt Lake City, UT",
responsibilities: [
"Orchestrated Microsoft Intune setup and deployment to multiple platforms.",
"Streamlined IT equipment inventory process",
"Provided training to optimize the usage of hardware and software.",
"Troubleshoot and repair hardware and software on a variety of devices.",
"Developed automation scripts for use in various parts of the business.",
],
},
];
const eduData = [
{
institution: "Salt Lake Comm. College",
degree: "AS Comp Sci",
gpa: "3.48 (CS) || 2.87 (Cumulative)",
start: "Jan '21",
end: "Present",
}
];
root.render( root.render(
<Router> <Router>
<Routes> <Routes>
<Route exact path="/" element={<App />} /> <Route exact path="/" element={<App projectData={projectData} skillData={skillData} />} />
<Route exact path="/resume" element={<Resume />} /> <Route exact path="/resume" element={<Resume jobData={jobData} eduData={eduData} skillData={skillData} />} />
<Route <Route
path="*" path="*"
element={ element={