-
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
c3f6c5e
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,51 @@ | ||
| # Portfolio | ||
| # Portfolio Project | ||
|
|
||
| This is a personal portfolio website built as a school project at [Technigo](https://www.technigo.io/). The project showcases my skills, projects, and journey as a developer, utilizing modern web technologies to create an engaging and responsive user experience. | ||
|
|
||
| ## Tech Stack | ||
|
|
||
| This project is built with the following technologies: | ||
|
|
||
| * **[React](https://react.dev/)**: JavaScript library for building user interfaces. | ||
| * **[Vite](https://vitejs.dev/)**: Next-generation frontend tooling for fast development and building. | ||
| * **[Styled Components](https://styled-components.com/)**: Visual primitives for the component age, allowing for CSS-in-JS. | ||
| * **[AOS (Animate On Scroll)](https://michalsnik.github.io/aos/)**: Library to animate elements as you scroll down the page. | ||
| * **[Swiper](https://swiperjs.com/)**: Modern mobile touch slider for the project showcase. | ||
|
|
||
| ## Features | ||
|
|
||
| The portfolio consists of several key sections: | ||
|
|
||
| * **Hero**: Introduction and welcome message. | ||
| * **Skills**: Overview of my technical skills and competencies. | ||
| * **Projects**: Showcase of my recent work, dynamically loaded from data files. | ||
| * **Tech**: Specific technologies I work with. | ||
| * **Journey**: A timeline or description of my professional and educational background. | ||
| * **Contact**: Information on how to get in touch. | ||
|
|
||
| ## Setup & Installation | ||
|
|
||
| To run this project locally, follow these steps: | ||
|
|
||
| 1. **Clone the repository:** | ||
| ```bash | ||
| git clone <repository-url> | ||
| cd js-project-portfolio | ||
| ``` | ||
|
|
||
| 2. **Install dependencies:** | ||
| ```bash | ||
| npm install | ||
| ``` | ||
|
|
||
| 3. **Run the development server:** | ||
| ```bash | ||
| npm run dev | ||
| ``` | ||
|
|
||
| 4. **Open in your browser:** | ||
| The application will typically be available at `http://localhost:5173`. | ||
|
|
||
| ## View it Live | ||
|
|
||
| [View Deployed Site](https://asako-portfolio.netlify.app/) |
| 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 | ||
| } | ||
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.