Skip to content

Commit

Permalink
Merge pull request #4 from garygcchiu/feature/v2
Browse files Browse the repository at this point in the history
Release: Website 2.0 - merge feature/v2 to master
  • Loading branch information
garygcchiu authored Sep 20, 2020
2 parents ed38700 + 09144e2 commit 69aaab6
Show file tree
Hide file tree
Showing 35 changed files with 845 additions and 227 deletions.
94 changes: 94 additions & 0 deletions components/About.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React, { forwardRef } from 'react';
import FadeInDiv from './FadeInDiv';

const About = forwardRef((props, ref) => {
return <div className={'about'} ref={ref}>
<FadeInDiv threshold={0.8} className={'pb-5 mb-5'}>
<h2 className={'about__title'}>
Nice to meet you 😄
</h2>
<div className={'about__text'}>
I’m currently a Software Developer at Konrad Group, building innovative solutions for industry-leading clients.<br/>
I am passionate about using technology to improve quality of life — and making it look & feel as good as possible.
</div>
</FadeInDiv>
<FadeInDiv threshold={0.15} className={'py-5 my-5'} animationOrder={0}>
<h2 className={'about__title'}>
Skills
</h2>
<div className={'about__text about__skills'}>
<FadeInDiv threshold={0.5} animationOrder={1} fast className={'mb-5'}>
<div className={'about__skills__title'}>Languages</div>
<div>JavaScript</div>
<div>HTML</div>
<div>CSS/Sass</div>
<div>SQL (PostgreSQL, MySQL)</div>
<div>Java</div>
<div>Python</div>
<div>TypeScript</div>
<div>C#</div>
<div>Elasticsearch</div>
</FadeInDiv>
<FadeInDiv threshold={0.4} animationOrder={2} fast className={'mb-5'}>
<div className={'about__skills__title'}>Frameworks</div>
<div>React</div>
<div>Node.js</div>
<div>Express</div>
<div>.NET Core</div>
<div>Next.js</div>
<div>Redux</div>
<div>Android</div>
<div>Spring Boot</div>
<div>Angular</div>
<div>Unity3D</div>
</FadeInDiv>
<FadeInDiv threshold={0.3} animationOrder={3} fast>
<div className={'about__skills__title'}>DevOps</div>
<div>Amazon Web Services</div>
<div>Docker</div>
<div>Google Cloud Platform</div>
<div>Pivotal Cloud Foundry</div>
<div>Concourse CI/CD</div>
<div>Mocha, Chai</div>
</FadeInDiv>
</div>
</FadeInDiv>
<FadeInDiv threshold={0.15} className={'py-5 my-5'} animationOrder={2}>
<h2 className={'about__title'}>
Experience
</h2>
<div className={'about__text'}>
<div className={'about__company'}>
<div>
<a href={'https://konrad.com'} target={'_blank'}><b>Konrad Group</b></a>
<div>Software Developer</div>
</div>
<div className={'about__company__dates'}>May 2019 – Present</div>
</div>
<div className={'about__company'}>
<div>
<a href={'https://manulife.ca'} target={'_blank'}><b>Manulife</b></a>
<div>Software Developer/Project Coordinator Co-op</div>
</div>
<div className={'about__company__dates'}>May 2018 – August 2018 </div>
</div>
<div className={'about__company'}>
<div>
<a href={'https://mapsted.com'} target={'_blank'}><b>Mapsted</b></a>
<div>Software Developer Intern</div>
</div>
<div className={'about__company__dates'}>January 2018 – April 2018</div>
</div>
<div className={'about__company'}>
<div>
<a href={'https://bigbluebubble.com'} target={'_blank'}><b>Big Blue Bubble</b></a>
<div>Games Programmer - Intern</div>
</div>
<div className={'about__company__dates'}>May 2017 – December 2017</div>
</div>
</div>
</FadeInDiv>
</div>
});

export default About;
20 changes: 20 additions & 0 deletions components/Contact.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Footer from './Footer';
import FadeInDiv from './FadeInDiv';

const Contact = () => {
return <div className={'contact'}>
<FadeInDiv className={'contact__main'} threshold={0.5}>
<span className={'mr-2 contact__text'}>
Interested?
</span>
<a href="#mailgo" data-address="gary.gc.chiu" data-domain="gmail.com">
Contact me!
</a>
</FadeInDiv>
<div className={'contact__footer'}>
<Footer />
</div>
</div>;
};

export default Contact;
26 changes: 26 additions & 0 deletions components/FadeInDiv.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { useEffect, useState } from 'react';
import { useInView } from 'react-intersection-observer';

const FadeInDiv = ({ children, className = '', threshold, animationOrder = 0, fast = false }) => {
const [ref, inView] = useInView({
threshold: threshold || 0.80,
triggerOnce: true
});
const [loaded, setLoaded] = useState(false);

useEffect(() => {
if (inView){
setTimeout(() => setLoaded(true), 1000);
}
}, [inView]);

return <div
ref={ref}
className={`${className} fade-in-div ${inView ? 'fade-in-div--visible' : '' } ${fast ? 'fade-in-div--fast' : ''}`}
style={{ '--animation-order': animationOrder && !loaded ? animationOrder : 0 }}
>
{ children }
</div>;
};

export default FadeInDiv;
22 changes: 0 additions & 22 deletions components/FadeInSection.js

This file was deleted.

15 changes: 15 additions & 0 deletions components/Footer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import Socials from './Socials';

const Footer = () => {
return <div className={'footer'}>
<div className={'footer__copyright'}>
© { new Date().getFullYear() } Gary Chiu. <span className={'footer__copyright__arr'}>All Rights Reserved.</span>
</div>
<div>
<Socials />
</div>
</div>;
}

export default Footer;
28 changes: 26 additions & 2 deletions components/Header.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,31 @@
import React from 'react';
import Switch from "react-switch";
import { useDarkMode } from 'next-dark-mode'
import * as ReactGA from '../utils/react-ga';

const Header = () => {
return <div className={'header'}>
<div className={'container'}>
const { darkModeActive, switchToLightMode, switchToDarkMode } = useDarkMode();

return <div className={'header'}>
<div className={`header__theme`}>
<div className={'header__theme__icon sun'}/>
<Switch
onChange={() => {
ReactGA.sendEvent('Interaction', `Toggled Theme to ${darkModeActive ? 'Light' : 'Dark'}`);
if (darkModeActive) {
switchToLightMode();
} else {
switchToDarkMode();
}
}}
checked={darkModeActive}
checkedIcon={false}
uncheckedIcon={false}
height={24}
width={50}
handleDiameter={18}
/>
<div className={'header__theme__icon moon'}/>
</div>
</div>
};
Expand Down
10 changes: 4 additions & 6 deletions components/IconLink.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,12 @@ const IconLink = ({ href, imgAlt, icon, onClick, className, download = false, ta
onClick={onClick}
className={className ? className : 'socials__icon'}
>
{icon ?
<img src={icon}
className={className ? className : 'socials__icon'}
alt={imgAlt}
{
icon && <img src={icon}
className={className ? className : 'socials__icon'}
alt={imgAlt}
/>
: null
}

</a>
};

Expand Down
4 changes: 2 additions & 2 deletions components/ImageSection.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const ImageSection = () => {
return <section className={'image-section'}>
return <div className={'image-section'}>
<div className={'image-section__overlay image-section__overlay--top'}/>
<div className={'image-section__overlay image-section__overlay--bottom'}/>
</section>
</div>
};

export default ImageSection;
48 changes: 48 additions & 0 deletions components/Landing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { useRef, useEffect } from 'react';
import Typed from "typed.js";
import Header from './Header';
import Socials from './Socials';
import FadeInDiv from './FadeInDiv';

const Landing = () => {
const descRef = useRef(null);

useEffect(() => {
const typed = new Typed(descRef.current, {
strings: ['Software Engineer', 'Full Stack Web Developer', 'Consultant'],
typeSpeed: 50,
backSpeed: 30,
loop: true,
backDelay: 2500
});

// destroy Typed instance on unmounting the component
return () => {
typed.destroy();
};
}, []);

return <>
<FadeInDiv className={'header'}>
<Header className={'hehe'} />
</FadeInDiv>
<FadeInDiv className={'landing'} animationOrder={1}>
<div className={'d-flex flex-column'}>
<div className={'landing__title'}>
Hello!
</div>
<div className={'landing__title'}>
I'm <b>Gary Chiu</b>, a <span ref={descRef} />
</div>
<div className={'landing__title'}>
I build web applications & custom software solutions, currently based in Toronto, Canada. 👨‍💻
</div>
<div className={'landing__cta'}>
<Socials />
</div>
</div>
</FadeInDiv>
</>;
};

export default Landing;
27 changes: 27 additions & 0 deletions components/Loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React, { useState, useEffect } from 'react';

const Loader = ({ onLoadComplete }) => {
const [loaded, setLoaded] = useState(false);

useEffect(() => {
setTimeout(() => {
setLoaded(true);
setTimeout(() => {
onLoadComplete();
}, 700);
}, 1500);
}, []);

return <section className={'loader'}>
<div className={`sk-chase ${loaded ? 'sk-chase--loaded': ''}`}>
<div className="sk-chase-dot" />
<div className="sk-chase-dot" />
<div className="sk-chase-dot" />
<div className="sk-chase-dot" />
<div className="sk-chase-dot" />
<div className="sk-chase-dot" />
</div>
</section>
};

export default Loader;
51 changes: 51 additions & 0 deletions components/Socials.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import * as ReactGA from '../utils/react-ga';
import IconLink from './IconLink';
import resume from '../public/Gary_Chiu_Resume_2020.pdf';

const handleResumeDownloaded = () => {
ReactGA.sendEvent('Link', 'Downloaded Resume');
};

const handleSocialLinkClicked = website => {
ReactGA.sendEvent('Link', `Clicked ${website} Profile`);
};

const scrollToSection = ref => {
const el = ref.current ? ref.current : ref;
el.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
ReactGA.sendEvent('Interaction', `Clicked Scroll Down`);
};

const Socials = () => {

return <div className={'landing__socials'}>
<IconLink
href={resume}
imgAlt={'Resume Download'}
className={'socials__icon resume'}
download={false}
onClick={handleResumeDownloaded}
/>
<span className={"socials__separator"}>|</span>
<IconLink
href={'https://www.github.com/garygcchiu'}
imgAlt={'GitHub Profile'}
className={'socials__icon github'}
onClick={() => handleSocialLinkClicked('Github')}
/>
<span className={"socials__separator"}>|</span>
<IconLink
href={'https://www.linkedin.com/in/garygcchiu/'}
imgAlt={'LinkedIn Profile'}
className={'socials__icon linkedin'}
onClick={() => handleSocialLinkClicked('LinkedIn')}
/>
<span className={"socials__separator"}>|</span>
<a href="#mailgo" data-address="gary.gc.chiu" data-domain="gmail.com" className={'socials__icon mail'} />
</div>
};

export default Socials;
Loading

1 comment on commit 69aaab6

@vercel
Copy link

@vercel vercel bot commented on 69aaab6 Sep 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.