diff --git a/index.html b/index.html index 4fe55b3e..a4b611c7 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,10 @@ rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" /> + Josh Ashton diff --git a/package-lock.json b/package-lock.json index 322516c7..73affaf7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,10 @@ "name": "portfolio", "version": "0.0.1", "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-brands-svg-icons": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "@fortawesome/react-fontawesome": "^0.2.2", "react": "^18.2.0", "react-dom": "^18.2.0", "swiper": "^10.0.0" @@ -390,6 +394,64 @@ "node": ">=12" } }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz", + "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz", + "integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==", + "license": "MIT", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-brands-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.7.2.tgz", + "integrity": "sha512-zu0evbcRTgjKfrr77/2XX+bU+kuGfjm0LbajJHVIgBWNIDzrhpRxiCPNT8DW5AdmSsq7Mcf9D1bH0aSeSUSM+Q==", + "license": "(CC-BY-4.0 AND MIT)", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz", + "integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==", + "license": "(CC-BY-4.0 AND MIT)", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", + "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, "node_modules/esbuild": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", @@ -480,6 +542,15 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -516,6 +587,17 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -541,6 +623,12 @@ "react": "^18.3.1" } }, + "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==", + "license": "MIT" + }, "node_modules/rollup": { "version": "3.29.5", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.29.5.tgz", diff --git a/package.json b/package.json index 75dcf369..7fa2e039 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,9 @@ { "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-brands-svg-icons": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "@fortawesome/react-fontawesome": "^0.2.2", "react": "^18.2.0", "react-dom": "^18.2.0", "swiper": "^10.0.0" diff --git a/public/images/one-ai-cropped.png b/public/images/one-ai-cropped.png new file mode 100644 index 00000000..5234b4a4 Binary files /dev/null and b/public/images/one-ai-cropped.png differ diff --git a/src/App.jsx b/src/App.jsx index 8461640d..0c9a082b 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,4 +1,4 @@ -import React, { useRef, useState } from "react"; +import React, { useEffect, useState } from "react"; import VerticalSlider from "./components/VerticalSlider"; import Primary from "./Primary"; import Skills from "./Skills"; @@ -12,9 +12,38 @@ import "./main.css"; * TODO: Read in data from a plain text file for easier editing in the future. */ export default function App() { - const cards = [, , ]; + // FUNCTION DATA + const [isMobile, setIsMobile] = useState(window.innerWidth <= 790); - const skills = { + useEffect(() => { + const handleResize = () => setIsMobile(window.innerWidth <= 790); + window.addEventListener("resize", handleResize); + return () => window.removeEventListener("resize", handleResize); + }, []); + + const initState = isMobile ? [true, false, false] : [true, true, true]; + + // DATA VARIABLES + /* + { + title: "", + description: "", + image: "", + imageGallery: null, + url: "" + }, +*/ + const projectData = [ + { + title: "One AI", + description: "ASDF", + image: "/images/projects/one-ai.png", + imageGallery: null, + url: "https://github.com/quaxlyqueen/one-ai", + }, + ]; + + const skillsData = { languages: ["Java", "JavaScript", "Go", "Dart", "Python", "C#"], tools: [ "Git & GitHub", @@ -40,11 +69,10 @@ export default function App() { secondaryText="Junior full-stack developer." callToAction="Here's my resume." image="/images/profile.jpg" - skills={skills} + skills={skillsData} + initState={initState} />, - , - , - , + , ]; return ; } diff --git a/src/Primary.jsx b/src/Primary.jsx index 8ec042e5..35b7585b 100644 --- a/src/Primary.jsx +++ b/src/Primary.jsx @@ -1,4 +1,4 @@ -// TODO: Replace h4 callToAction with a button callToAction. +// TODO: Replace h4 callToAction with a GREEN button callToAction. import React, { useState } from "react"; import SkillCard from "./components/SkillCard"; @@ -8,6 +8,7 @@ export default function Primary({ callToAction, image, skills, + initState, }) { return ( <> @@ -28,19 +29,19 @@ export default function Primary({ header="Languages" symbol="code" list={skills.languages} - initState={true} + initState={initState[0]} /> diff --git a/src/Projects.jsx b/src/Projects.jsx index 741c0ecf..3fe59b8f 100644 --- a/src/Projects.jsx +++ b/src/Projects.jsx @@ -1,5 +1,33 @@ import React from "react"; +import ProjectCard from "./components/ProjectCard"; -export default function Projects() { - return

TODO: Projects()

; +export default function Projects({ cardData }) { + return ( + <> +
+
+
+

Projects

+ +

+ Here are some projects of mine. Lorem ipsum odor amet, + consectetuer adipiscing elit. Purus molestie vel ornare volutpat + elit et per montes. Lacus fames diam a non taciti sem. +

+
+
+ {cardData.map((c) => ( + + ))} +
+
+
+ + ); } diff --git a/src/components/ProjectCard.jsx b/src/components/ProjectCard.jsx index e2e44d82..ee6de7ac 100644 --- a/src/components/ProjectCard.jsx +++ b/src/components/ProjectCard.jsx @@ -1,5 +1,24 @@ import React from "react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faGithub } from "@fortawesome/free-brands-svg-icons"; -export default function ProjectCard() { - return

TODO: Need to implement ProjectCard

; +export default function ProjectCard({ + title, + description, + image, + imageGallery, + url, +}) { + return ( +
+ +
+
+

{title}

+ +
+

{description}

+
+
+ ); } diff --git a/src/components/SkillCard.jsx b/src/components/SkillCard.jsx index 7c469bff..b22cf055 100644 --- a/src/components/SkillCard.jsx +++ b/src/components/SkillCard.jsx @@ -1,5 +1,7 @@ import React, { useState } from "react"; +// TODO: Add state which only allows one skill card at a time to be expanded. +// TODO: Ensure that the expandability of the skill card is only an option when @media max-width 790px (mobile) export default function SkillCard({ header, symbol, list, initState }) { const [isExpanded, setIsExpanded] = useState(initState); // Initial state diff --git a/src/main.css b/src/main.css index d76577d5..6b7e0bbb 100644 --- a/src/main.css +++ b/src/main.css @@ -51,6 +51,12 @@ body { overflow: hidden; } +.slide-container { + display: flex; + flex-direction: row; + justify-content: center; +} + .swiper-pagination-bullet { width: 18px; height: 18px; @@ -73,6 +79,55 @@ body { column-gap: 1vh; } +#project-container { + height: 100vh; + width: 100%; + display: flex; + flex-direction: row; + justify-content: center; + margin: 5vw; +} + +.project-grid-container { + margin: 2vw; + display: grid; + grid-template-columns: 100%; + grid-template-rows: 1% 90%; + row-gap: 2vh; +} + +.project-card { + background-color: #ebd2ff; + height: 70%; + display: grid; + grid-template-columns: 40% 40%; + grid-template-rows: 100%; + column-gap: 20vw; +} + +.project-text { + display: grid; + grid-template-columns: 100%; + grid-template-rows: 20% 70%; + align-text: left; +} + +.project-text h3 { + font-size: clamp(2rem, 2.5vw, 3rem); +} + +.row { + display: flex; + flex-direction: row; + justify-content: center; +} + +#project-cards-section { + display: flex; + flex-direction: column; + justify-content: center; +} + #header { width: 100%; overflow: hidden;