-
Notifications
You must be signed in to change notification settings - Fork 55
Portfolio - Asako #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
11e626d
9178279
03706a4
494aa10
b2fd7be
2c6b727
ff3451f
f42f70a
824ed3d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,5 @@ | ||
| # Portfolio | ||
|
|
||
| Netlify link - https://asako-portfolio.netlify.app/ | ||
|
|
||
| Figma link - https://www.figma.com/design/8rhyek3LxsIZM2rjSBVfee/Portfolio-design?node-id=0-1&t=3RJwp8MXaEhHBVpV-1 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,44 @@ | ||
| import { useEffect } from "react" | ||
| import AOS from "aos" | ||
| import "aos/dist/aos.css" | ||
|
|
||
| import { GlobalStyle } from "./styles/globalStyles"; | ||
| import { Projects } from "./components/Sections/projects"; | ||
| import { Contact } from "./components/Sections/contact"; | ||
| import { Hero } from "./components/Sections/hero"; | ||
| import { Journey } from "./components/Sections/journey"; | ||
| import { Skills } from "./components/Sections/skills"; | ||
| import { Tech } from "./components/Sections/tech"; | ||
|
|
||
| export const App = () => { | ||
|
|
||
| useEffect(() => { | ||
| AOS.init({ | ||
| duration: 2000 , | ||
| once: false, | ||
| easing: "ease-out-cubic", | ||
| offset: 200 | ||
| }) | ||
| }, []) | ||
|
|
||
|
|
||
| return ( | ||
| <> | ||
| <h1>Portfolio</h1> | ||
| <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatem, laborum! Maxime animi nostrum facilis distinctio neque labore consectetur beatae eum ipsum excepturi voluptatum, dicta repellendus incidunt fugiat, consequatur rem aperiam.</p> | ||
|
|
||
| <GlobalStyle /> | ||
|
|
||
| <Hero /> | ||
|
|
||
| <Skills /> | ||
|
|
||
| <Projects /> | ||
|
|
||
| <Tech /> | ||
|
|
||
| <Journey /> | ||
|
|
||
| <Contact /> | ||
|
|
||
| </> | ||
| ) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| import styled, { keyframes } from "styled-components" | ||
| import profileImage from "../../images/hello4.png" | ||
| import { Icon, IconRow } from "../common/icons" | ||
| import { iconLinks } from "../../data/iconLinks.json" | ||
| import { Heading2, Paragraph } from "../common/typography" | ||
|
|
||
|
|
||
| export const Contact = () => { | ||
| return ( | ||
| <ContactContainer> | ||
| <ImageContainer> | ||
| <img | ||
| src={profileImage} | ||
| alt="Asako Kanno profile picture" | ||
| className="contact-image" | ||
| /> | ||
| </ImageContainer> | ||
| <ContactInfo> | ||
| <AnimatedHeading>Let's talk</AnimatedHeading> | ||
| <Paragraph>Asako Kanno</Paragraph> | ||
| <Paragraph>asako.k1317@outlook.com</Paragraph> | ||
| <IconRow> | ||
| {iconLinks.map((icon) => ( | ||
| <Icon | ||
| key={icon.name} | ||
| name={icon.name} | ||
| href={icon.href} | ||
| /> | ||
| ))} | ||
| </IconRow> | ||
| </ContactInfo> | ||
| </ContactContainer> | ||
| ) | ||
| } | ||
|
|
||
| // Styled component below | ||
|
|
||
| const ContactContainer = styled.div` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again a personal preference but maybe it's to wide a gap between the text and the picture? |
||
| display: flex; | ||
| flex-direction: row; | ||
| justify-content: space-around; | ||
| margin: 64px 0; | ||
| img { | ||
| width: 500px; | ||
| height: auto; | ||
| } | ||
| @media (max-width: 1440px) { | ||
| flex-direction: column; | ||
| } | ||
| ` | ||
|
|
||
| const ImageContainer = styled.div` | ||
| @media (max-width: 1440px) { | ||
| display: flex; | ||
| justify-content: center; | ||
| } | ||
| ` | ||
|
|
||
| const ContactInfo = styled.div` | ||
| padding-top: 20px; | ||
| @media (max-width: 1440px) { | ||
| text-align: center; | ||
| } | ||
| ` | ||
|
|
||
| const wobble = keyframes` | ||
| 0% { transform: scale(1) rotate(0deg); } | ||
| 25% { transform: scale(1.03) rotate(2deg); } | ||
| 50% { transform: scale(1.03) rotate(-2deg); } | ||
| 75% { transform: scale(1.03) rotate(1deg); } | ||
| 100% { transform: scale(1) rotate(0deg); } | ||
| ` | ||
|
|
||
| const AnimatedHeading = styled(Heading2)` | ||
| animation: ${wobble} 2s ease-in-out infinite; | ||
| display: inline-block; | ||
| transform-origin: center; | ||
| ` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The hero looks great and really nice animation! Just a little to much space between the rows of text for my liking but that's individual :) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| import styled, { keyframes } from "styled-components" | ||
| import ProfileImg from "../../images/profile4.png" | ||
| import { Icon } from "../common/icons" | ||
| import { iconLinks } from "../../data/iconLinks.json" | ||
| import { Heading1, Heading3, Paragraph } from "../common/typography" | ||
| import { IconRow } from "../common/icons" | ||
|
|
||
| export const Hero = () => { | ||
| return ( | ||
| <HeroSection> | ||
| <VisuallyHiddenH1>Asako Kanno - Frontend Developer</VisuallyHiddenH1> | ||
|
|
||
| <div> | ||
| <Heading3 as="h2">Hi, I'm Asako!</Heading3> | ||
| <AnimatedHeading1 | ||
| as="h3" | ||
| className="hero-title" | ||
| > | ||
| Frontend <br />Developer | ||
| </AnimatedHeading1> | ||
| <Paragraph>Creating friendly experiences for everyday life.<br /><br /> | ||
| I like building web experiences that feel clear, warm, and supportive.<br /><br /> | ||
| I care about usability and thoughtful design, and I believe technology should simply help people feel at ease in their daily lives. | ||
| </Paragraph> | ||
| <IconRow> | ||
| {iconLinks.map((icon) => ( | ||
| <Icon | ||
| key={icon.name} | ||
| name={icon.name} | ||
| href={icon.href} | ||
| /> | ||
| ))} | ||
| </IconRow> | ||
| </div> | ||
| <ImageContainer> | ||
| <img | ||
| src={ProfileImg} | ||
| alt="Asako Kanno profile image" | ||
| className="hero-image" | ||
| /> | ||
| </ImageContainer> | ||
| </HeroSection> | ||
| ) | ||
| } | ||
|
|
||
| // Styled component below | ||
|
|
||
| const VisuallyHiddenH1 = styled.h1` | ||
| position: absolute; | ||
| left: -9999px; | ||
| top: auto; | ||
| width: 1px; | ||
| height: 1px; | ||
| overflow: hidden; | ||
| ` | ||
|
|
||
| const HeroSection = styled.div` | ||
| display: flex; | ||
| justify-content: space-around; | ||
| padding: 128px 128px 0 128px; | ||
|
|
||
| // fade-in animation | ||
| opacity: 0; | ||
| transform: translateY(24px); | ||
| animation: fadeInHero 1.8s ease-out forwards; | ||
|
|
||
| @keyframes fadeInHero { | ||
| from { | ||
| opacity: 0; | ||
| transform: translateY(24px) | ||
| } | ||
| to { | ||
| opacity: 1; | ||
| transform: translateY(0) | ||
| } | ||
| } | ||
|
|
||
| img { | ||
| width: 500px; | ||
| height: auto; | ||
| } | ||
|
|
||
| @media (max-width: 1440px) { | ||
| flex-direction: column; | ||
| padding: 64px 24px 0; | ||
|
|
||
| img { | ||
| justify-content: center; | ||
| } | ||
| } | ||
| ` | ||
|
|
||
| const ImageContainer = styled.div` | ||
| @media (max-width: 1440px) { | ||
| display: flex; | ||
| justify-content: center; | ||
| } | ||
| ` | ||
|
|
||
| const breathe = keyframes` | ||
| 0% { transform: scale(1); } | ||
| 50% { transform: scale(1.03); } | ||
| 100% { transform: scale(1); } | ||
| ` | ||
| const AnimatedHeading1 = styled(Heading1)` | ||
| animation: ${breathe} 3s ease-in-out infinite; | ||
| ` |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| import styled from "styled-components"; | ||
| import journey from "../../data/journey.json" | ||
| import img1 from "../../images/img1.png" | ||
| import img2 from "../../images/img2.png" | ||
| import img3 from "../../images/img3.png" | ||
| import { JourneyCard } from "../common/cards"; | ||
| import { Heading2 } from "../common/typography"; | ||
| import { Carousel } from "../../styles/carousel" | ||
|
|
||
|
|
||
| export const Journey = () => { | ||
| return ( | ||
| <> | ||
| <JourneySection> | ||
| <Heading2>My Journey</Heading2> | ||
|
|
||
| <Carousel | ||
| data={journey.journey} | ||
| renderItem={(item, index) => ( | ||
| <JourneyCard | ||
| {...item} | ||
| image={imageMap[item.image]} | ||
| index={index} | ||
| /> | ||
| )} | ||
| /> | ||
| </JourneySection> | ||
| </> | ||
| ) | ||
| } | ||
|
|
||
| // Styled component below | ||
|
|
||
| const JourneySection = styled.div` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe put the articles more centered since they are fewer then the projects? So it looks more intentional :) |
||
| margin: 64px 0; | ||
| ` | ||
|
|
||
| const imageMap = { | ||
| img1, | ||
| img2, | ||
| img3 | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| import styled from "styled-components" | ||
|
|
||
| import projects from "../../data/projects.json" | ||
| import { ProjectCard } from "../common/cards" | ||
| import { Heading2 } from "../common/typography" | ||
| import { Carousel } from "../../styles/carousel" | ||
| import business from "../../images/business.png" | ||
| import recipe from "../../images/recipe.png" | ||
| import weather from "../../images/weather.png" | ||
| import accessibility from "../../images/accessibility.png" | ||
|
|
||
| export const Projects = () => { | ||
| return ( | ||
| <> | ||
| <ProjectContainer> | ||
| <Heading2>Featured Projects</Heading2> | ||
|
|
||
| <Carousel | ||
| data={projects.projects} | ||
| renderItem={(project, index) => ( | ||
| <ProjectCard | ||
| {...project} | ||
| image={imgMap[project.image]} | ||
| index={index} | ||
| /> | ||
| )} | ||
| /> | ||
| </ProjectContainer> | ||
| </> | ||
| ) | ||
| } | ||
|
|
||
| const imgMap = { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice that you use a map of all the images in order to get it via the name in the project object. |
||
| business, | ||
| recipe, | ||
| weather, | ||
| accessibility | ||
| } | ||
|
|
||
| const ProjectContainer = styled.div` | ||
| width: 100%; | ||
| @media (max-width: 1440px) { | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
| ` | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that this,
aos, is a really old library (7 years since last publish). Avoid old packages, this is due to security concerns.