From e35491b73353b8db9e84fb04a6a1254377d6c166 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Mon, 23 Dec 2024 17:55:07 -0700 Subject: [PATCH] Implemented primary section consisting of key information, including collapsible skill cards. --- index.html | 5 + public/images/profile.jpg | Bin 0 -> 17403 bytes src/About.jsx | 5 + src/App.jsx | 62 ++-- src/Contact.jsx | 5 + src/Primary.jsx | 53 ++++ src/Projects.jsx | 5 + src/Skills.jsx | 8 + src/components/AccordionContext.jsx | 19 ++ src/components/Footer.jsx | 0 src/components/ProjectCard.jsx | 5 + src/components/SkillCard.jsx | 25 ++ src/components/VerticalSlider.jsx | 24 +- src/main.css | 429 ++++++++++++++++++++++++++++ src/styles.css | 2 +- 15 files changed, 610 insertions(+), 37 deletions(-) create mode 100644 public/images/profile.jpg create mode 100644 src/About.jsx create mode 100644 src/Contact.jsx create mode 100644 src/Primary.jsx create mode 100644 src/Projects.jsx create mode 100644 src/Skills.jsx create mode 100644 src/components/AccordionContext.jsx create mode 100644 src/components/Footer.jsx create mode 100644 src/components/ProjectCard.jsx create mode 100644 src/components/SkillCard.jsx create mode 100644 src/main.css diff --git a/index.html b/index.html index aeb1553f..4fe55b3e 100644 --- a/index.html +++ b/index.html @@ -3,6 +3,11 @@ + + Josh Ashton diff --git a/public/images/profile.jpg b/public/images/profile.jpg new file mode 100644 index 0000000000000000000000000000000000000000..91c37a8e7beb3632372bd8ed0e724a495bf032f9 GIT binary patch literal 17403 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%0Dg4A@O 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: About()

; +} diff --git a/src/App.jsx b/src/App.jsx index be0441d7..8461640d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,22 +1,50 @@ import React, { useRef, useState } from "react"; import VerticalSlider from "./components/VerticalSlider"; -import "./styles.css"; +import Primary from "./Primary"; +import Skills from "./Skills"; +import Projects from "./Projects"; +import Contact from "./Contact"; +import About from "./About"; +import ProjectCard from "./components/ProjectCard"; +import "./main.css"; + +/** + * TODO: Read in data from a plain text file for easier editing in the future. + */ export default function App() { - const data = [ - { - title: "Test Header", - description: "A description of some length. Lorem ipsum this shit.", - color: "purple", - image: "/images/landscape.jpg", - alt: "A pretty background.", - }, - { - title: "Another one", - description: "A description of some length. Lorem ipsum this shit.", - color: "purple", - image: "/images/landscape.jpg", - alt: "A pretty background.", - }, + const cards = [, , ]; + + const skills = { + languages: ["Java", "JavaScript", "Go", "Dart", "Python", "C#"], + tools: [ + "Git & GitHub", + "Docker & Kubernetes", + "Flutter", + "React", + "Linux", + "Microsoft Intune", + ], + other: [ + "Written Communication", + "Conflict Resolution", + "Project Management", + "Event Planning", + "Electronics Repair", + "Soldering", + ], + }; + + const slides = [ + , + , + , + , ]; - return ; + return ; } diff --git a/src/Contact.jsx b/src/Contact.jsx new file mode 100644 index 00000000..e8cca20b --- /dev/null +++ b/src/Contact.jsx @@ -0,0 +1,5 @@ +import React from "react"; + +export default function Contact() { + return

TODO: Contact()

; +} diff --git a/src/Primary.jsx b/src/Primary.jsx new file mode 100644 index 00000000..8ec042e5 --- /dev/null +++ b/src/Primary.jsx @@ -0,0 +1,53 @@ +// TODO: Replace h4 callToAction with a button callToAction. +import React, { useState } from "react"; +import SkillCard from "./components/SkillCard"; + +export default function Primary({ + primaryText, + secondaryText, + callToAction, + image, + skills, +}) { + return ( + <> +
+ +
+
+ + + +
+
+ + keyboard_double_arrow_down + +
+ + ); +} diff --git a/src/Projects.jsx b/src/Projects.jsx new file mode 100644 index 00000000..741c0ecf --- /dev/null +++ b/src/Projects.jsx @@ -0,0 +1,5 @@ +import React from "react"; + +export default function Projects() { + return

TODO: Projects()

; +} diff --git a/src/Skills.jsx b/src/Skills.jsx new file mode 100644 index 00000000..98936875 --- /dev/null +++ b/src/Skills.jsx @@ -0,0 +1,8 @@ +import React from "react"; + +export default function Skills({ skills }) { + const languages = skills.languages; + const tools = skills.tools; + const other = skills.other; + return <>; +} diff --git a/src/components/AccordionContext.jsx b/src/components/AccordionContext.jsx new file mode 100644 index 00000000..32d6fdc6 --- /dev/null +++ b/src/components/AccordionContext.jsx @@ -0,0 +1,19 @@ +import React, { createContext, useState } from "react"; + +const AccordionContext = createContext(); + +export const AccordionProvider = ({ children }) => { + const [expandedCardId, setExpandedCardId] = useState(null); + + const handleAccordionClick = (cardId) => { + setExpandedCardId(cardId === expandedCardId ? null : cardId); + }; + + return ( + + {children} + + ); +}; + +export default AccordionContext; diff --git a/src/components/Footer.jsx b/src/components/Footer.jsx new file mode 100644 index 00000000..e69de29b diff --git a/src/components/ProjectCard.jsx b/src/components/ProjectCard.jsx new file mode 100644 index 00000000..e2e44d82 --- /dev/null +++ b/src/components/ProjectCard.jsx @@ -0,0 +1,5 @@ +import React from "react"; + +export default function ProjectCard() { + return

TODO: Need to implement ProjectCard

; +} diff --git a/src/components/SkillCard.jsx b/src/components/SkillCard.jsx new file mode 100644 index 00000000..7c469bff --- /dev/null +++ b/src/components/SkillCard.jsx @@ -0,0 +1,25 @@ +import React, { useState } from "react"; + +export default function SkillCard({ header, symbol, list, initState }) { + const [isExpanded, setIsExpanded] = useState(initState); // Initial state + + const toggleExpansion = () => { + setIsExpanded(!isExpanded); + }; + + return ( +
+
+ {symbol} +

{header}

+
+ {isExpanded && ( +
    + {list.map((item) => ( +
  • {item}
  • + ))} +
+ )} +
+ ); +} diff --git a/src/components/VerticalSlider.jsx b/src/components/VerticalSlider.jsx index fd6b95e5..72edb32f 100644 --- a/src/components/VerticalSlider.jsx +++ b/src/components/VerticalSlider.jsx @@ -4,16 +4,16 @@ import { Mousewheel, Pagination } from "swiper/modules"; import "swiper/css"; import "swiper/css/pagination"; -import "../styles.css"; +import "../main.css"; -export default function VerticalSlider({ slideData }) { +export default function VerticalSlider({ slides }) { return ( <> - {slideData.map((slide, index) => ( + {slides.map((slide, index) => ( - {({ isActive }) => ( -
-
-

{slide.title}

-

{slide.description}

-
-
-
- {slide.alt} -
-
- )} + {({ isActive }) =>
{slide}
}
))}
diff --git a/src/main.css b/src/main.css new file mode 100644 index 00000000..d76577d5 --- /dev/null +++ b/src/main.css @@ -0,0 +1,429 @@ +@import url("https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap"); + +/* +#EBD2FF +#c69bca +#9e75a8 +#4a245e +*/ + +:root { + --width: 480px; +} + +*, +*::before, +*::after { + padding: 0; + margin: 0; + box-sizing: border-box; + font-family: "Lato", sans-serif; +} + +html, +body { + position: relative; + height: 100%; + background: #222; +} + +body { + margin: 0; + height: 100vh; + background: linear-gradient( + 135deg, + #84509f 0%, + #5e3276 39%, + hsl(279deg 62% 19%) 61%, + hsl(279deg 94% 7%) 100% + ); + background-size: + 300% 100%, + cover; + animation: background-fade 4s linear infinite; + animation-direction: alternate; + background-attachment: fixed; +} + +.swiper { + width: 100%; + height: 100vh; + overflow: hidden; +} + +.swiper-pagination-bullet { + width: 18px; + height: 18px; + background-color: #f9f2ff; + border-radius: 50%; + transition: all 0.6s ease-in-out; +} + +.swiper-pagination-bullet-active { + height: 36px; + background-color: #ebd2ff; + border-radius: 14px; +} + +#primary { + display: grid; + height: 100vh; + grid-template-columns: 100%; + grid-template-rows: 40% 50% 10%; + column-gap: 1vh; +} + +#header { + width: 100%; + overflow: hidden; + + display: grid; + grid-template-columns: 60% 35%; + grid-template-rows: 100%; + column-gap: 2vw; +} + +#header-text { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding-left: 120px; + text-align: center; + opacity: 0; +} + +#header-text h1 { + font-size: clamp(4.25rem, 5.5vw, 10rem); + font-weight: 600; + letter-spacing: 2px; + width: max-content; + margin-bottom: 32px; + opacity: 0; + color: #ebd2ff; +} + +#header-text h3, +#header-text h4 { + color: #ebd2ff; + font-weight: 300; + line-height: 1.5; + opacity: 0; +} + +#header-text h3 { + font-size: clamp(1.5rem, 3vw, 3rem); +} +#header-text h4 { + font-size: clamp(1rem, 1.5vw, 1.25rem); +} + +.swiper-slide-active #header-text { + opacity: 1; +} + +.swiper-slide-active #header-text h1, +.swiper-slide-active #header-text h3, +.swiper-slide-active #header-text h4 { + animation: moveDown 0.8s ease-in forwards; +} + +.swiper-slide-active #header-text h1 { + animation-delay: 0.2s; +} + +.swiper-slide-active #header-text h3 { + animation-delay: 0.8s; +} + +.swiper-slide-active #header-text h4 { + animation-delay: 0.8s; +} + +#header-image { + height: 40vh; + display: flex; + align-items: center; + justify-content: center; + width: var(--width); + aspect-ratio: 1/1; + margin: 0 auto; + border-radius: 50%; + overflow: hidden; +} + +#header-image img { + display: block; + width: calc(var(--width) / 2); + filter: drop-shadow(5px 6px 5px rgba(36, 36, 42, 0.5)); + user-select: none; + opacity: 0; + z-index: 1; + border-radius: 50%; +} + +#header-image img { + animation: imgMoveDown 0.8s ease-in forwards 0.2s; +} + +.material-icons { + font-variation-settings: + "FILL" 0, + "wght" 200, + "GRAD" 0, + "opsz" 24; + font-size: 5vw; + color: #ebd2ff; + + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +#skills-section { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; +} + +#skills-section h2 { + font-size: clamp(3.25rem, 4.5vw, 8rem); + color: #ebd2ff; + opacity: 0; + padding-bottom: 36px; +} + +.cards { + display: grid; + grid-template-columns: 30% 30% 30%; + grid-template-rows: 100%; + column-gap: 2.25vw; + justify-content: center; +} + +.card { + align-items: center; + justify-content: center; + text-align: center; + background-color: #ebd2ff; + border-radius: 20px; + width: 20vw; + box-shadow: + 0 13px 27px -5px hsla(240, 30.1%, 28%, 0.25), + 0 8px 16px -8px hsla(0, 0%, 0%, 0.3), + 0 -6px 16px -6px hsla(0, 0%, 0%, 0.03); +} + +.card .skill-section-header { + display: grid; + grid-template-columns: 20% 60%; + grid-template-rows: 100%; + column-gap: 1vw; + align-items: center; + justify-content: center; + text-align: center; + + padding: 2vw; + margin: 0; + background-color: #4a245e; + border-radius: 18px 18px 0 0; + + width: 100%; +} + +.card .skill-section-header .skill-symbol { + font-variation-settings: + "FILL" 0, + "wght" 200, + "GRAD" 0, + "opsz" 24; + font-size: 5vw; + height: 5vh; + text-align: left; +} + +.card .skill-section-header h3 { + font-size: clamp(1rem, 2vw, 3rem); + color: #ebd2ff; +} + +.card ul { + padding: 1vw; +} + +.card ul li { + list-style: none; + font-size: clamp(1rem, 1.25vw, 1.5rem); + color: #4a245e; +} + +.swiper-slide-active #skills-section .cards .card { + opacity: 0; +} + +.swiper-slide-active #skills-section h2, +.swiper-slide-active #skills-section .card { + animation: moveCardsDown 0.8s ease-in forwards; +} + +.swiper-slide-active #skills-section .card { + animation-delay: 1.2s; +} + +.down-indicator { + opacity: 0; + animation: moveDown 0.8s ease-in forwards; + animation-delay: 0.2s; +} + +/**Animations**/ +@keyframes background-fade { + from { + background-position: right, center; + } +} + +@keyframes moveDown { + 0% { + transform: translateY(-20px); + opacity: 0; + } + 100% { + transform: translateY(0); + opacity: 1; + } +} + +@keyframes moveCardsDown { + 0% { + transform: translateY(-40px); + opacity: 0; + } + 100% { + transform: translateY(0); + opacity: 1; + } +} + +@keyframes imgMoveDown { + 0% { + transform: translateY(calc(var(--width) / -5)); + opacity: 0; + } + 100% { + transform: translateY(0); + opacity: 1; + } +} + +/**Responsiveness**/ +@media (max-width: 1250px) { + #header-text { + padding-left: 90px; + } +} + +@media (max-width: 1075px) { + :root { + --width: 400px; + } + + .swiper-slide .slide-container { + column-gap: 20px; + } + + #header-text { + padding-left: 60px; + } +} + +@media (max-width: 990px) { + :root { + --width: 360px; + } + + #header-text { + padding-left: 0px; + } +} + +@media (max-width: 790px) { + #primary { + display: grid; + grid-template-rows: 50% 40% 10%; + grid-template-columns: 100%; + } + + #header { + grid-template-columns: 60% 40%; + } + + #header-text { + margin: 0; + } + + #header-text h1 { + font-size: clamp(2.5rem, 2.75vw, 3rem); + } + + #header-image { + display: flex; + flex-direction: row; + align-items: center; + justify-content: left; + } + + #skills-section .card .skill-section-header { + border-radius: 18px 18px 18px 18px; + } + + #skills-section h2 { + padding-bottom: 0; + } + + .cards { + grid-template-columns: 100%; + grid-template-rows: 30% 30% 30%; + column-gap: 0; + padding: 30px; + } + + .card { + width: 50vw; + margin: 1vw; + } + + .card .skill-section-header h3 { + font-size: clamp(1.5rem, 2vw, 2.5rem); + } + + #header-text h1 { + margin-bottom: 16px; + width: unset; + line-height: 1.1; + } + + .swiper-pagination-bullet { + width: 14px; + height: 14px; + } + + .swiper-pagination-bullet-active { + height: 28px; + } + + .material-symbols-outlined { + font-size: 10vw; + } +} + +@media (max-width: 485px) { + :root { + --width: 280px; + } +} diff --git a/src/styles.css b/src/styles.css index f45bfd4b..a444ea9b 100644 --- a/src/styles.css +++ b/src/styles.css @@ -175,7 +175,7 @@ body { } } -.swiper-paginatino-bullet { +.swiper-pagination-bullet { width: 18px; height: 18px; background-color: #7e7e7e;