├── .gitignore
├── README.md
├── assets
└── website.PNG
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
└── src
├── App.js
├── components
├── About
│ ├── About.js
│ └── About.module.css
├── Contact
│ ├── Contact.js
│ └── Contact.module.css
├── Landing
│ ├── Landing.js
│ └── Landing.module.css
├── Logo
│ ├── Logo.js
│ └── Logo.module.css
├── NavBar
│ ├── Burger.js
│ ├── NavBar.js
│ └── RightNav.js
├── Preloader
│ └── Preloader.js
├── Project
│ ├── Project.js
│ └── Project.module.css
├── ProjectList
│ ├── ProjectList.js
│ └── ProjectList.module.css
├── Social
│ ├── Social.js
│ └── Social.module.css
└── UI
│ ├── Cancel.js
│ ├── Card.js
│ ├── Card.module.css
│ ├── Mouse.css
│ ├── Mouse.js
│ ├── ProjectModal.js
│ ├── ProjectModal.module.css
│ ├── ThankYou.js
│ └── ThankYou.module.css
├── data.js
├── img
├── Fooder.png
├── Jingle.png
├── homepage.png
├── marker.png
├── notepad.png
├── oldportfolio.png
└── simplify1.png
├── index.css
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | config.js
8 |
9 | # testing
10 | /coverage
11 |
12 | # production
13 | /build
14 |
15 | # misc
16 | .DS_Store
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 18_React_NN
2 | React: Personal Portfolio
3 |
4 | ## Introduction
5 | Mobile responsive personal portfolio. This portfolio include modern features such as:
6 | * Landing page with engineered stroke-dash animation
7 | * A sticky side footer for socials
8 | * Animation on-hover navigation bar with link to Resume
9 | * Preloader animation using gsap library
10 | * Animated SVG scroll down button
11 | * Cursor animation
12 | * AOS on-scroll animation for smooth scrolling
13 | * Framer-motion to render component animations
14 | * Email JS to validate and send email from contact form
15 | * Google Map API to show current location
16 | * Spinning Skill Cube made with pure css
17 |
18 | 
19 |
20 | ## User Story
21 |
22 | ```
23 | AS AN employer looking for candidates with experience building single-page applications
24 | I WANT to view a potential employee's deployed React portfolio of work samples
25 | SO THAT I can assess whether they're a good candidate for an open position
26 | ```
27 |
28 | ## Acceptance Criteria
29 |
30 | ```
31 | GIVEN a single-page application portfolio for a web developer
32 | WHEN I load the portfolio
33 | THEN I am presented with a page containing a header, a section for content, and a footer
34 | WHEN I view the header
35 | THEN I am presented with the developer's name and navigation with titles corresponding to different sections of the portfolio
36 | WHEN I view the navigation titles
37 | THEN I am presented with the titles About Me, Portfolio, Contact, and Resume, and the title corresponding to the current section is highlighted
38 | WHEN I click on a navigation title
39 | THEN I am presented with the corresponding section below the navigation without the page reloading and that title is highlighted
40 | WHEN I load the portfolio the first time
41 | THEN the About Me title and section are selected by default
42 | WHEN I am presented with the About Me section
43 | THEN I see a recent photo or avatar of the developer and a short bio about them
44 | WHEN I am presented with the Portfolio section
45 | THEN I see titled images of six of the developer’s applications with links to both the deployed applications and the corresponding GitHub repositories
46 | WHEN I am presented with the Contact section
47 | THEN I see a contact form with fields for a name, an email address, and a message
48 | WHEN I move my cursor out of one of the form fields without entering text
49 | THEN I receive a notification that this field is required
50 | WHEN I enter text into the email address field
51 | THEN I receive a notification if I have entered an invalid email address
52 | WHEN I am presented with the Resume section
53 | THEN I see a link to a downloadable resume and a list of the developer’s proficiencies
54 | WHEN I view the footer
55 | THEN I am presented with text or icon links to the developer’s GitHub and LinkedIn profiles, and their profile on a third platform (Stack Overflow, Twitter)
56 |
57 | ```
58 |
59 | ## Submission
60 | This portfolio was uploaded to GitHub at the following repository link:
61 | [https://github.com/nhanng19/portfolio_react](https://github.com/nhanng19/portfolio_react)
62 |
63 | Deployed Link:
64 | [https://www.nhanngyn.tech/](https://www.nhanngyn.tech/)
65 |
--------------------------------------------------------------------------------
/assets/website.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhanng19/portfolio_react/d1041400f2f475664d355e329ba7deccc456e06e/assets/website.PNG
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "portfolio",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@fortawesome/fontawesome-svg-core": "^6.2.0",
7 | "@fortawesome/free-brands-svg-icons": "^6.2.0",
8 | "@fortawesome/react-fontawesome": "^0.2.0",
9 | "@react-google-maps/api": "^2.17.0",
10 | "@testing-library/jest-dom": "^5.16.5",
11 | "@testing-library/react": "^13.4.0",
12 | "@testing-library/user-event": "^13.5.0",
13 | "aos": "^2.3.4",
14 | "emailjs": "^4.0.1",
15 | "emailjs-com": "^3.2.0",
16 | "framer-motion": "^7.6.12",
17 | "gsap": "^3.11.3",
18 | "html-react-parser": "^3.0.4",
19 | "react": "^18.2.0",
20 | "react-dom": "^18.2.0",
21 | "react-dotenv": "^0.1.3",
22 | "react-scripts": "5.0.1",
23 | "react-scroll": "^1.8.8",
24 | "react-transition-group": "^4.4.5",
25 | "styled-components": "^5.3.6",
26 | "web-vitals": "^2.1.4"
27 | },
28 | "scripts": {
29 | "start": "react-scripts start",
30 | "build": "react-scripts build",
31 | "test": "react-scripts test",
32 | "eject": "react-scripts eject"
33 | },
34 | "eslintConfig": {
35 | "extends": [
36 | "react-app",
37 | "react-app/jest"
38 | ]
39 | },
40 | "browserslist": {
41 | "production": [
42 | ">0.2%",
43 | "not dead",
44 | "not op_mini all"
45 | ],
46 | "development": [
47 | "last 1 chrome version",
48 | "last 1 firefox version",
49 | "last 1 safari version"
50 | ]
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhanng19/portfolio_react/d1041400f2f475664d355e329ba7deccc456e06e/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
45 | "Design is not just what it looks like and feels like. Design is how
46 | it works" - Steve Jobs
47 |
48 |
49 | I have always had an affinity for technology and the arts, a chemistry
50 | I gratefully utilize today as a developer. I have a serious passion
51 | for creating dynamic digital experiences and intuitive user interfaces
52 | while allowing seamless front-end integration to back-end systems.
53 | Minimalism and "less is more" have always been my philosophy on
54 | removing unnecessary distractions that would keep me from exuding my
55 | creativity and products from executing its idea effectively. I am
56 | interested in anything coding or design related, from software
57 | engineering to UI/UX, and look forward to working on incredible projects
58 | with positive people.
59 |
63 | Thank you for reaching out! I'll get back to you as soon as possible.
64 |
65 |
66 |
69 |
70 | );
71 | };
72 | const ThankYou = (props) => {
73 | return (
74 | <>
75 | {ReactDOM.createPortal(
76 | ,
77 | document.getElementById("backdrop-root")
78 | )}
79 | {ReactDOM.createPortal(
80 | ,
85 | document.getElementById("overlay-root")
86 | )}
87 | >
88 | );
89 | };
90 |
91 | export default ThankYou;
92 |
--------------------------------------------------------------------------------
/src/components/UI/ThankYou.module.css:
--------------------------------------------------------------------------------
1 | .backdrop {
2 | position: fixed;
3 | top: 0;
4 | left: 0;
5 | width: 100%;
6 | height: 100vh;
7 | z-index: 100000;
8 | background: rgba(0, 0, 0, 0.75);
9 | }
10 |
11 | .modal {
12 | position: fixed;
13 | top: 30vh;
14 | left: 10%;
15 | width: 80%;
16 | z-index: 100000;
17 | background: rgb(0, 0, 0);
18 | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
19 | border: 1px solid white;
20 | overflow: hidden;
21 | }
22 |
23 |
24 | .content {
25 | padding: 1rem;
26 | }
27 |
28 | .actions {
29 | padding: 1rem;
30 | display: flex;
31 | justify-content: flex-end;
32 | }
33 |
34 | @media (min-width: 768px) {
35 | .modal {
36 | left: calc(50% - 20rem);
37 | width: 40rem;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/data.js:
--------------------------------------------------------------------------------
1 | import Simplify from "./img/simplify1.png";
2 | import DrawMe from "./img/homepage.png";
3 | import Fooder from "./img/Fooder.png";
4 | import Jingle from "./img/Jingle.png";
5 | import Notepad from "./img/notepad.png";
6 | import Portfolio from "./img/oldportfolio.png";
7 | export const projects = [
8 | {
9 | id: 1,
10 | title: "Simplify",
11 | techno: "React | MySQL | Express",
12 | description: "Text Summarizer",
13 | summary: `Simplify is a website productivity application that can take long and tedious text and summarize it for students to easily digest information. By utilizing the innovations of natural language processing and web scraping technologies, we're able to create a more practical method for students to streamline their studying process. As a result, Simplify was developed with the goal of making it easier for students to comprehend extensive information and automatically generate flashcards to assist them in retaining key concepts. I had the pleasure to collaborate with a UX designer and a brilliant developer to win 1st place at the 2022 API World Hackathon with this project!`,
14 | img: Simplify,
15 | link: "https://simplify-apiworlds.netlify.app/summarize",
16 | source: "https://github.com/lam-brian/API-World",
17 | delay: "0",
18 | },
19 | {
20 | id: 2,
21 | title: "Draw.me",
22 | techno: "Handlebars | MySQL | Node | Express",
23 | description: "Drawing Platform",
24 | summary:
25 | "Draw.me is a community-based drawing platform where users can create an account to draw, post, share, and comment on other user's art. Our server uses mySQL database to store users' confidential credentials, drawings, and comments. Our drawing application is engineered with the Canvas API. Canvas provides a means for drawing graphics via JavaScript and the HTML canvas element. Our Javascript function can render objects such as shapes, lines, and strokes on the Canvas element at any given space coordinates, which in our application's case, the x and y coordinates of our cursor. By using Sequelize ORM, we were able to consistently store data such as drawings and comments by updating queries, so our Express server can respond back to user's requests. Our social network service is entirely built on this stack to retrieve, store, and render data back to our client.",
26 | img: DrawMe,
27 | link: "https://drawme.herokuapp.com/",
28 | source: "https://github.com/nhanng19/Draw.me",
29 | delay: "100",
30 | },
31 | {
32 | id: 3,
33 | title: "Fooder",
34 | techno: "HTML | CSS | JavaScript | Web API",
35 | description: "Food Application",
36 | summary: `Fooder is a food search web application that would allow users to quickly find multiple restaurant locations of savory and delicious food. We will ask you for your location services and with that we can directly pinpoint your position wherever you are and give you food in your location. Spoonacular gave us the ability to use a information (data) of different types of food and manipulate the data where we could let the user find any type of food of their choice. The YelpAPI calls would allow us to find different restaurants and store data and by taking SpoonacularsAPI calls and manipulating the data moving forward into Yelp's API, we would be able to accomplish our goal to allow the user to get any type of food in his/her area. I was lucky enough to have won 2nd place at the 2022 API World Hackathon with this project!`,
37 | img: Fooder,
38 | link: "https://nhanng19.github.io/Fooder",
39 | source: "https://github.com/nhanng19/Fooder",
40 | delay: "200",
41 | },
42 | {
43 | id: 4,
44 | title: "Jingle",
45 | techno: "HTML | CSS | JavaScript | Web API",
46 | description: "Music Guessing Game",
47 | summary:
48 | "We wanted to find a interactive way to use data from an API that worked with music specifically, was inspired by the recent game wordle. Small music themed game that uses the last.fm API to pull a top track list, and Wikipedia's MediaWiki Api to pull a artist photo, so that users can play by guessing the artist who performed a song name that is randomly generated. ",
49 | img: Jingle,
50 | link: "https://nhanng19.github.io/music_wordle",
51 | source: "https://github.com/nhanng19/music_wordle",
52 | delay: "0",
53 | },
54 | {
55 | id: 5,
56 | title: "CSS Portfolio",
57 | techno: "HTML | CSS",
58 | description: "First Porfolio",
59 | summary:
60 | "This is my first portfolio site made with pure HTML and CSS. This is my favorite project out of the six because it reminds me how far I've come!",
61 | img: Portfolio,
62 | link: "https://nhanng19.github.io/css_portfolio/develop/index",
63 | source: "https://github.com/nhanng19/css_portfolio",
64 | delay: "100",
65 | },
66 | {
67 | id: 6,
68 | title: "Note Express",
69 | techno: "HTML | CSS | JavaScript",
70 | description: "Note taking application",
71 | summary:
72 | "A note application utilizing Express.js backend to write, store, retrieve, and delete notes. It uses an Express.js back end that save and retrieve note data from a JSON file.",
73 | img: Notepad,
74 | link: "https://expressnotepad.herokuapp.com/",
75 | source: "https://github.com/nhanng19/notepad",
76 | delay: "200",
77 | },
78 | ];
79 |
--------------------------------------------------------------------------------
/src/img/Fooder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhanng19/portfolio_react/d1041400f2f475664d355e329ba7deccc456e06e/src/img/Fooder.png
--------------------------------------------------------------------------------
/src/img/Jingle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhanng19/portfolio_react/d1041400f2f475664d355e329ba7deccc456e06e/src/img/Jingle.png
--------------------------------------------------------------------------------
/src/img/homepage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhanng19/portfolio_react/d1041400f2f475664d355e329ba7deccc456e06e/src/img/homepage.png
--------------------------------------------------------------------------------
/src/img/marker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhanng19/portfolio_react/d1041400f2f475664d355e329ba7deccc456e06e/src/img/marker.png
--------------------------------------------------------------------------------
/src/img/notepad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhanng19/portfolio_react/d1041400f2f475664d355e329ba7deccc456e06e/src/img/notepad.png
--------------------------------------------------------------------------------
/src/img/oldportfolio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhanng19/portfolio_react/d1041400f2f475664d355e329ba7deccc456e06e/src/img/oldportfolio.png
--------------------------------------------------------------------------------
/src/img/simplify1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhanng19/portfolio_react/d1041400f2f475664d355e329ba7deccc456e06e/src/img/simplify1.png
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | font-family: "Poppins";
4 | color: white;
5 | }
6 |
7 | *::-webkit-scrollbar {
8 | display: none;
9 | }
10 | body {
11 | background: black;
12 | }
13 | .cursor {
14 | position: fixed;
15 | width: 50px;
16 | height: 50px;
17 | border: 1px solid #c6c6c6;
18 | background-color: #c6c6c6;
19 | opacity: 0.5;
20 | border-radius: 50%;
21 | left: 50%;
22 | top: 50%;
23 | pointer-events: none;
24 | transform: translate(-50%, -50%);
25 | transition: 0.1s;
26 | z-index: 1000000;
27 | }
28 |
29 | .cursor2 {
30 | position: fixed;
31 | width: 8px;
32 | height: 8px;
33 | background-color: #c6c6c6;
34 | border-radius: 50%;
35 | left: 50%;
36 | top: 50%;
37 | pointer-events: none;
38 | transform: translate(-50%, -50%);
39 | transition: 0.15s;
40 | z-index: 1000000;
41 | }
42 |
43 | @media screen and (max-width: 390px) {
44 | .cursor,
45 | .cursor2 {
46 | display: none;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import App from './App';
4 | import "./index.css"
5 | const root = ReactDOM.createRoot(document.getElementById('root'));
6 | root.render(
7 |
8 |
9 |
10 | );
11 |
12 |
--------------------------------------------------------------------------------