diff --git a/README.md b/README.md
index 7bf3df67..9204925c 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
Personal Portfolio
- Software and Full-Stack Developer.
Creating beautiful user-centered interactivity and experiences.
+ Full-Stack Software Engineer.
Creating beautiful user-centered interactivity and experiences.
diff --git a/web/common/components/GlassRectangle/styles.ts b/web/common/components/GlassRectangle/styles.ts
index 31ebc6f8..b0946b34 100644
--- a/web/common/components/GlassRectangle/styles.ts
+++ b/web/common/components/GlassRectangle/styles.ts
@@ -48,6 +48,33 @@ export const GlassContainer = styled.div`
}, 0.27)`};
overflow: hidden;
+ &.home-page {
+ width: 51rem;
+ height: 37rem;
+ margin-right: auto;
+ margin-left: auto;
+
+ @media ${({ theme }) => theme.responsive.below1199} {
+ width: 35rem;
+ height: 25rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below599} {
+ width: 32rem;
+ height: 23rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below479} {
+ width: 24rem;
+ height: 17rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below379} {
+ width: 100%;
+ height: 16rem;
+ }
+ }
+
&.about-page {
width: 51rem;
height: 37rem;
@@ -150,6 +177,10 @@ export const GlassImageWrapper = styled.div`
margin-right: auto;
opacity: ${({ opacity }) => opacity ?? '1'};
+ &.home-page {
+ width: 100%;
+ }
+
&.about-page {
width: 100%;
}
@@ -192,6 +223,16 @@ export const GlassImageWrapper = styled.div`
export const GlassImage = styled.img`
width: 100%;
+ &.home-page {
+ &--image-1 {
+ transform: scale(1.1);
+ }
+
+ &--image-2 {
+ transform: scale(1.5);
+ }
+ }
+
&.about-page {
transform: scale(1.1);
}
diff --git a/web/common/components/ItemLink/itemData.ts b/web/common/components/ItemLink/itemData.ts
index d038543e..c99cf7c7 100644
--- a/web/common/components/ItemLink/itemData.ts
+++ b/web/common/components/ItemLink/itemData.ts
@@ -15,11 +15,11 @@ const itemData: TItemData[] = [
title: 'Articles',
path: '/articles',
},
- {
- id: '4c5c324a-92ed-4575-a731-25370c21379a',
- title: 'About',
- path: '/about',
- },
+ // {
+ // id: '4c5c324a-92ed-4575-a731-25370c21379a',
+ // title: 'About',
+ // path: '/about',
+ // },
];
export default itemData;
diff --git a/web/components/home/AboutImage/index.tsx b/web/components/home/AboutImage/index.tsx
new file mode 100644
index 00000000..f1e8a6c6
--- /dev/null
+++ b/web/components/home/AboutImage/index.tsx
@@ -0,0 +1,56 @@
+import { FC, useEffect } from 'react';
+import { useAnimation } from 'framer-motion';
+import { useInView } from 'react-intersection-observer';
+
+import GlassRectangle from 'common/components/GlassRectangle';
+
+import { ImageWrapper } from './styles';
+
+interface IAboutImageProps {
+ customClassName?: string;
+ imgAlt: string;
+ imgSrc: string;
+}
+
+const AboutImage: FC = ({
+ customClassName,
+ imgAlt,
+ imgSrc,
+}) => {
+ const imageAnimateControls = useAnimation();
+
+ const { inView: imageInView, ref: imageRef } = useInView();
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ if (imageInView) {
+ imageAnimateControls.start('visible');
+ }
+ }, 200);
+
+ return () => clearTimeout(timer);
+ }, [imageAnimateControls, imageInView]);
+
+ return (
+
+
+
+ );
+};
+
+export default AboutImage;
diff --git a/web/components/home/AboutImage/styles.ts b/web/components/home/AboutImage/styles.ts
new file mode 100644
index 00000000..780f4d56
--- /dev/null
+++ b/web/components/home/AboutImage/styles.ts
@@ -0,0 +1,19 @@
+import styled from 'styled-components';
+import { motion } from 'framer-motion';
+
+export const ImageWrapper = styled(motion.div).attrs(() => ({
+ initial: 'hidden',
+ variants: {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: { duration: 0.5 },
+ },
+ },
+}))`
+ margin-top: 5rem;
+
+ @media ${({ theme }) => theme.responsive.below899} {
+ margin-top: 0;
+ }
+`;
diff --git a/web/components/home/AboutSection/index.tsx b/web/components/home/AboutSection/index.tsx
new file mode 100644
index 00000000..7fd61381
--- /dev/null
+++ b/web/components/home/AboutSection/index.tsx
@@ -0,0 +1,31 @@
+import { FC } from 'react';
+
+import HeadingPrimary from 'common/typography/HeadingPrimary';
+import Paragraph from 'common/typography/Paragraph';
+
+import { MainAboutWrapper, SecondaryAboutWrapper, Section } from './styles';
+
+const AboutSection: FC = () => (
+
+
+
+ Hello! I love drinking coffee while learning and improving on new and
+ existing technologies
+
+
+
+
+
+ A passionate and curious individual with a BS degree in Physics from
+ UCLA currently working as a Full-Stack Software Engineer at Aerobotics7
+ to remove landmines from around the world. I have experiences with
+ Python, Django, Node.js, React.js, Figma/Lucid Charts and other
+ platforms and tools to facilitate on creating and solving real-world
+ problems for the users to enjoy, and the companies to succeed their
+ vision
+
+
+
+);
+
+export default AboutSection;
diff --git a/web/components/home/AboutSection/styles.ts b/web/components/home/AboutSection/styles.ts
new file mode 100644
index 00000000..55847805
--- /dev/null
+++ b/web/components/home/AboutSection/styles.ts
@@ -0,0 +1,44 @@
+import styled from 'styled-components';
+
+export const Section = styled.section`
+ width: 100%;
+ text-align: right;
+`;
+
+export const MainAboutWrapper = styled.div`
+ width: 80%;
+ margin-bottom: 3rem;
+ margin-left: auto;
+
+ @media ${({ theme }) => theme.responsive.below1199} {
+ width: 97%;
+ }
+
+ @media ${({ theme }) => theme.responsive.below899} {
+ width: 100%;
+ margin-bottom: 5rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below479} {
+ margin-bottom: 3rem;
+ }
+`;
+
+export const SecondaryAboutWrapper = styled.div`
+ width: 95%;
+ margin-bottom: 3rem;
+ margin-left: auto;
+
+ @media ${({ theme }) => theme.responsive.below1199} {
+ width: 97%;
+ }
+
+ @media ${({ theme }) => theme.responsive.below899} {
+ width: 100%;
+ margin-bottom: 5rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below479} {
+ margin-bottom: 3rem;
+ }
+`;
diff --git a/web/components/home/ArticleSection/ArticleContainer.tsx b/web/components/home/ArticleSection/ArticleContainer.tsx
deleted file mode 100644
index 360c7141..00000000
--- a/web/components/home/ArticleSection/ArticleContainer.tsx
+++ /dev/null
@@ -1,167 +0,0 @@
-import { FC, useEffect } from 'react';
-import Link from 'next/link';
-import { useAnimation } from 'framer-motion';
-import { useInView } from 'react-intersection-observer';
-
-import GlassCircle from 'common/components/GlassCircle';
-
-import { useIsHovering } from 'common/hooks';
-
-import HeadingTertiary from 'common/typography/HeadingTertiary';
-
-import { isHoveringOverall } from 'utils';
-
-import {
- ArticleContainerStyle,
- ArticleDescriptionContainer,
- ArticleImageLink,
- ArticleImageWrapper,
- ArticleTitle,
- ArticleTitleLink,
-} from './styles';
-
-export interface IArticleContainer {
- articleClass: string;
- articleImageAlt: string;
- articleImageSrc: string;
- articleLinkPath: string;
- articleTitle: string;
- finishIsFirstMount: boolean;
- isExploreLinkHovering: boolean;
-}
-
-const ArticleContainer: FC = ({
- articleClass,
- articleImageAlt,
- articleImageSrc,
- articleLinkPath,
- articleTitle,
- finishIsFirstMount,
- isExploreLinkHovering,
-}) => {
- const titleAnimateControls = useAnimation();
- const { inView: titleInView, ref: titleRef } = useInView();
-
- const imageAnimateControls = useAnimation();
- const { inView: imageInView, ref: imageRef } = useInView();
-
- const [isTitleLinkHovering, setIsTitleLinkHovering] = useIsHovering();
- const [isImageLinkHovering, setIsImageLinkHovering] = useIsHovering();
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && titleInView) {
- titleAnimateControls.start('visible');
- }
-
- return () => clearTimeout(timer);
- }, 600);
- }, [finishIsFirstMount, titleAnimateControls, titleInView]);
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && imageInView) {
- imageAnimateControls.start('visible');
- }
- }, 900);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, imageAnimateControls, imageInView]);
-
- useEffect(() => {
- if (
- !finishIsFirstMount &&
- isHoveringOverall(isImageLinkHovering, isExploreLinkHovering)
- ) {
- imageAnimateControls.start('hovering');
- } else {
- imageAnimateControls.start('nonHovering');
- }
- }, [
- finishIsFirstMount,
- isImageLinkHovering,
- isExploreLinkHovering,
- imageAnimateControls,
- ]);
-
- return (
-
-
- setIsImageLinkHovering(true)}
- onHoverEnd={() => setIsImageLinkHovering(false)}
- ref={imageRef}
- >
-
-
-
-
-
-
-
-
-
- setIsTitleLinkHovering(true)}
- onMouseLeave={() => setIsTitleLinkHovering(false)}
- >
-
- {articleTitle}
-
-
-
-
-
-
- );
-};
-
-export default ArticleContainer;
diff --git a/web/components/home/ArticleSection/index.tsx b/web/components/home/ArticleSection/index.tsx
deleted file mode 100644
index 2ec628de..00000000
--- a/web/components/home/ArticleSection/index.tsx
+++ /dev/null
@@ -1,151 +0,0 @@
-import React, { FC, useEffect } from 'react';
-import Link from 'next/link';
-import { useAnimation } from 'framer-motion';
-import { useInView } from 'react-intersection-observer';
-
-import LineSeparator from 'common/components/LineSeparator';
-
-import { useIsHovering } from 'common/hooks';
-
-import { IArticle } from 'common/models';
-
-import HeadingSecondary from 'common/typography/HeadingSecondary';
-import Paragraph from 'common/typography/Paragraph';
-
-import environment from 'environment';
-
-import {
- Container,
- ExploreMoreLink,
- ExploreMoreWrapper,
- Introduction,
- Section,
- SectionTitle,
- Wrapper,
-} from './styles';
-import ArticleContainer from './ArticleContainer';
-
-type TArticlesData = Pick<
- IArticle,
- | 'description'
- | 'header_image'
- | 'id'
- | 'title'
- | 'uuid'
- | 'reading_time'
- | 'category'
- | 'tags'
-> & {
- meta: Pick;
-};
-
-interface IArticleSection {
- articlesData: TArticlesData[] | [];
- finishIsFirstMount: boolean;
-}
-
-const ArticleSection: FC = ({
- articlesData,
- finishIsFirstMount,
-}) => {
- const titleAnimateControls = useAnimation();
- const { inView: titleInView, ref: titleRef } = useInView();
-
- const introAnimateControls = useAnimation();
- const { inView: introInView, ref: introRef } = useInView();
-
- const viewMoreAnimateControls = useAnimation();
- const { inView: viewMoreInView, ref: viewMoreRef } = useInView();
-
- const [isHovering, setIsHovering] = useIsHovering();
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && titleInView) {
- titleAnimateControls.start('visible');
- }
- }, 500);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, titleAnimateControls, titleInView]);
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && introInView) {
- introAnimateControls.start('visible');
- }
- }, 600);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, introAnimateControls, introInView]);
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && viewMoreInView) {
- viewMoreAnimateControls.start('visible');
- }
- }, 2000);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, viewMoreAnimateControls, viewMoreInView]);
-
- return (
-
-
-
- Articles
-
-
-
-
-
-
-
-
- I love to write to help others understand programming, mathematics,
- science, and other related technical fields. I also write film and
- book analysis, philosophy, and other things that interest me.
-
-
-
-
- {articlesData.length > 0 &&
- articlesData.map((articleData, articleIndex) => (
-
-
-
- ))}
-
-
-
-
-
- setIsHovering(true)}
- onMouseLeave={() => setIsHovering(false)}
- >
- Explore all articles
-
-
-
-
- );
-};
-
-export default ArticleSection;
diff --git a/web/components/home/ArticleSection/styles.ts b/web/components/home/ArticleSection/styles.ts
deleted file mode 100644
index eff05161..00000000
--- a/web/components/home/ArticleSection/styles.ts
+++ /dev/null
@@ -1,328 +0,0 @@
-import styled from 'styled-components';
-import { motion } from 'framer-motion';
-
-// ARTICLE SECTION
-export const Section = styled.section``;
-
-export const SectionTitle = styled(motion.div).attrs(() => ({
- initial: 'hidden',
- variants: {
- hidden: {
- opacity: 0,
- y: 10,
- },
- visible: {
- opacity: 1,
- y: 0,
- transition: { duration: 0.5 },
- },
- },
-}))``;
-
-export const Container = styled.div`
- display: flex;
- flex-direction: column;
- padding-top: 4rem;
-
- @media ${({ theme }) => theme.responsive.below1199} {
- padding-top: 2.5rem;
- }
-
- @media ${({ theme }) => theme.responsive.below899} {
- padding-top: 2.3rem;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- padding-top: 1rem;
- }
-`;
-
-export const Introduction = styled(motion.div).attrs(() => ({
- initial: 'hidden',
- variants: {
- hidden: {
- opacity: 0,
- y: -10,
- },
- visible: {
- opacity: 1,
- y: 0,
- transition: { duration: 0.5 },
- },
- },
-}))`
- text-align: center;
- padding: 5rem 15rem;
-
- @media ${({ theme }) => theme.responsive.below899} {
- padding: 5rem 8rem;
- }
-
- @media ${({ theme }) => theme.responsive.below599} {
- padding: 5rem 5rem;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- padding: 5rem 1rem;
- }
-
- @media ${({ theme }) => theme.responsive.below379} {
- padding: 4rem 1rem;
- }
-`;
-
-export const Wrapper = styled.div`
- display: grid;
- grid-template-rows: 1fr 1fr;
- grid-template-columns: 1fr 1fr;
- grid-template-areas:
- 'article1 article1'
- 'article2 article3';
- margin-bottom: 10rem;
-
- @media ${({ theme }) => theme.responsive.below899} {
- margin-bottom: 0;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- display: flex;
- flex-direction: column;
- }
-`;
-
-export const ExploreMoreWrapper = styled(motion.div).attrs(() => ({
- variants: {
- visible: {
- rotate: [0, 15, 7.5, 15, 0],
- transition: {
- duration: 1,
- ease: 'easeInOut',
- times: [0, 0.2, 0.5, 0.8, 1],
- },
- },
- },
-}))`
- margin-top: 10rem;
- text-align: center;
-
- @media ${({ theme }) => theme.responsive.below599} {
- margin-top: 6rem;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- margin-top: 5rem;
- }
-
- @media ${({ theme }) => theme.responsive.below379} {
- margin-top: 3rem;
- }
-`;
-
-export const ExploreMoreLink = styled.a`
- font-size: 2rem;
- font-weight: 700;
- color: ${({ theme }) => theme.colors.primary.hex};
- text-decoration: none;
-
- &:hover {
- text-decoration: underline;
- cursor: pointer;
- opacity: 0.9;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- font-size: 1.7rem;
- }
-`;
-
-// ARTICLE CONTAINER
-export const ArticleContainerStyle = styled.div`
- padding-top: 5rem;
- padding-bottom: 5rem;
-
- &.article1 {
- position: relative;
- grid-area: article1;
- }
-
- &.article2 {
- position: relative;
- grid-area: article2;
- padding-left: 15rem;
-
- &:before,
- &:after {
- content: '';
- position: absolute;
- width: 36rem;
- height: 0.2rem;
- background-color: ${({ theme }) =>
- `rgba(${theme.colors.primary.rgb}, 0.5)`};
-
- @media ${({ theme }) => theme.responsive.below899} {
- content: none;
- }
- }
-
- &:before {
- top: -4.7rem;
- left: 24.1rem;
- transform: rotate(40deg);
-
- @media ${({ theme }) => theme.responsive.below1199} {
- left: 5.7rem;
- }
- }
-
- &:after {
- bottom: 5.4rem;
- left: 38rem;
- transform: rotate(90deg);
-
- @media ${({ theme }) => theme.responsive.below1199} {
- left: 19.5rem;
- }
- }
-
- @media ${({ theme }) => theme.responsive.below899} {
- padding-left: 3rem;
- }
-
- @media ${({ theme }) => theme.responsive.below599} {
- padding-top: 2rem;
- padding-bottom: 2rem;
- padding-left: 2rem;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- padding-bottom: 3rem;
- padding-left: 0;
- }
- }
-
- &.article3 {
- position: relative;
- grid-area: article3;
- padding-right: 15rem;
-
- &:before {
- content: '';
- position: absolute;
- top: -4.7rem;
- right: 24.1rem;
- width: 36rem;
- height: 0.2rem;
- background-color: ${({ theme }) =>
- `rgba(${theme.colors.primary.rgb}, 0.5)`};
- transform: rotate(-40deg);
-
- @media ${({ theme }) => theme.responsive.below1199} {
- right: 5.7rem;
- }
-
- @media ${({ theme }) => theme.responsive.below899} {
- content: none;
- }
- }
-
- @media ${({ theme }) => theme.responsive.below899} {
- padding-right: 3rem;
- }
-
- @media ${({ theme }) => theme.responsive.below599} {
- padding-top: 2rem;
- padding-right: 2rem;
- padding-bottom: 2rem;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- padding-right: 0;
- padding-bottom: 3rem;
- }
- }
-
- @media ${({ theme }) => theme.responsive.below599} {
- padding-top: 2rem;
- padding-bottom: 2rem;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- padding-bottom: 3rem;
- }
-`;
-
-export const ArticleDescriptionContainer = styled.div`
- display: flex;
- flex-direction: column;
- align-items: center;
-`;
-
-export const ArticleImageWrapper = styled(motion.div).attrs(
- ({ className }) => ({
- initial: 'hidden',
- variants: {
- hidden: {
- opacity: 0,
- rotate: 0,
- scale: 0,
- },
- hovering: {
- rotate: !className?.includes('article2') ? -720 : 720,
- scale: 1.12,
- transition: {
- type: 'spring',
- bounce: 0.4,
- duration: 0.2,
- },
- },
- nonHovering: {
- rotate: 0,
- scale: 1,
- },
- visible: {
- opacity: 1,
- rotate: !className?.includes('article2') ? 720 : -720,
- scale: 1,
- transition: {
- type: 'spring',
- bounce: 0.4,
- duration: 0.5,
- },
- },
- },
- })
-)`
- margin-bottom: 2rem;
-`;
-
-export const ArticleImageLink = styled.a``;
-
-export const ArticleTitle = styled(motion.div).attrs(() => ({
- initial: 'hidden',
- variants: {
- hidden: {
- opacity: 0,
- },
- visible: {
- opacity: 1,
- transition: { duration: 0.3 },
- },
- },
-}))``;
-
-export const ArticleTitleLink = styled.a`
- text-align: center;
- text-decoration: none;
-
- & h3 {
- max-width: 30.1rem;
- max-height: 3.4rem;
- overflow: hidden;
- text-overflow: ellipsis;
- word-wrap: break-word;
-
- @media ${({ theme }) => theme.responsive.below899} {
- max-height: 2.5rem;
- }
- }
-`;
diff --git a/web/components/home/BeliefsSection/index.tsx b/web/components/home/BeliefsSection/index.tsx
new file mode 100644
index 00000000..f59bed4e
--- /dev/null
+++ b/web/components/home/BeliefsSection/index.tsx
@@ -0,0 +1,82 @@
+import { FC, useEffect } from 'react';
+import { useAnimation } from 'framer-motion';
+import { useInView } from 'react-intersection-observer';
+
+import HeadingSecondary from 'common/typography/HeadingSecondary';
+import Paragraph from 'common/typography/Paragraph';
+
+import { ParagraphWrapper, Section, SectionTitle } from './styles';
+
+const BeliefsSection: FC = () => {
+ const sectionAnimateControls = useAnimation();
+ const { inView: sectionInView, ref: sectionRef } = useInView();
+
+ const titleAnimateControls = useAnimation();
+ const { inView: titleInView, ref: titleRef } = useInView();
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ if (sectionInView) {
+ sectionAnimateControls.start('visible');
+ }
+ }, 200);
+
+ return () => clearTimeout(timer);
+ }, [sectionAnimateControls, sectionInView]);
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ if (titleInView) {
+ titleAnimateControls.start('visible');
+ }
+ }, 200);
+
+ return () => clearTimeout(timer);
+ }, [titleAnimateControls, titleInView]);
+
+ return (
+
+
+
+ Beliefs
+
+
+
+
+
+ As an avid learner, I was a self-taught programmer many years ago, and
+ being self-taught was difficult and created imposter syndrome within
+ myself. I always felt like I was not good enough and needed to know
+ more about the magic of coding. Overtime, I have learned to have
+ self-confidence in my abilities, asking for guidance, and knowing when
+ to just get up and take a walk.
+
+
+
+
+
+ I believe that anyone can become a programmer no matter what
+ background they come from. I believe that if you have tenacity,
+ perseverance, and tolerance within yourself then you can understand
+ the complexities of programming.
+
+
+
+
+
+ I also believe in having good communication, understanding, and
+ patience with others to develop healthy relationships. When these
+ three pillars are achieved, then achieving three more are possible:
+ Better user experience, painless documentation for developers to read,
+ and accomplishing a feat together within the team.
+
+
+
+ );
+};
+
+export default BeliefsSection;
diff --git a/web/components/home/BeliefsSection/styles.ts b/web/components/home/BeliefsSection/styles.ts
new file mode 100644
index 00000000..f882641e
--- /dev/null
+++ b/web/components/home/BeliefsSection/styles.ts
@@ -0,0 +1,88 @@
+import styled from 'styled-components';
+import { motion } from 'framer-motion';
+
+export const Section = styled(motion.section).attrs(() => ({
+ initial: 'hidden',
+ variants: {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: { duration: 0.5 },
+ },
+ },
+}))`
+ margin-top: -28rem;
+ padding-right: 12rem;
+ text-align: left;
+
+ @media ${({ theme }) => theme.responsive.below1199} {
+ padding-right: 3rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below899} {
+ margin-top: 0;
+ padding-left: 3rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below599} {
+ padding-right: 0;
+ padding-left: 0;
+ }
+`;
+
+export const SectionTitle = styled(motion.div).attrs(() => ({
+ initial: 'hidden',
+ variants: {
+ hidden: {
+ opacity: 0,
+ y: 10,
+ },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: { duration: 0.5 },
+ },
+ },
+}))`
+ margin-bottom: 2.5rem;
+
+ @media ${({ theme }) => theme.responsive.below599} {
+ margin-bottom: 1.75rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below479} {
+ margin-bottom: 1.5rem;
+ }
+`;
+
+export const ParagraphWrapper = styled.div`
+ margin-top: 2.5rem;
+ margin-bottom: 2.5rem;
+ line-height: 1.5;
+
+ &:first-child {
+ margin-top: 0;
+ }
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ @media ${({ theme }) => theme.responsive.below899} {
+ line-height: 1.8;
+ }
+
+ @media ${({ theme }) => theme.responsive.below599} {
+ margin-top: 1.75rem;
+ margin-bottom: 1.75rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below479} {
+ margin-top: 1.5rem;
+ margin-bottom: 1.5rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below379} {
+ line-height: 1.5;
+ }
+`;
diff --git a/web/components/home/Col/index.tsx b/web/components/home/Col/index.tsx
new file mode 100644
index 00000000..90aed802
--- /dev/null
+++ b/web/components/home/Col/index.tsx
@@ -0,0 +1,11 @@
+import styled from 'styled-components';
+
+const Col = styled.div`
+ width: 50%;
+
+ @media ${({ theme }) => theme.responsive.below899} {
+ width: 100%;
+ }
+`;
+
+export default Col;
diff --git a/web/components/home/ExperienceSection/index.tsx b/web/components/home/ExperienceSection/index.tsx
new file mode 100644
index 00000000..71708836
--- /dev/null
+++ b/web/components/home/ExperienceSection/index.tsx
@@ -0,0 +1,91 @@
+import { FC, useEffect } from 'react';
+import { useAnimation } from 'framer-motion';
+import { useInView } from 'react-intersection-observer';
+
+import HeadingSecondary from 'common/typography/HeadingSecondary';
+import Paragraph from 'common/typography/Paragraph';
+
+import { ParagraphWrapper, Section, SectionTitle } from './styles';
+
+const ExperienceSection: FC = () => {
+ const sectionAnimateControls = useAnimation();
+ const { inView: sectionInView, ref: sectionRef } = useInView();
+
+ const titleAnimateControls = useAnimation();
+ const { inView: titleInView, ref: titleRef } = useInView();
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ if (sectionInView) {
+ sectionAnimateControls.start('visible');
+ }
+ }, 200);
+
+ return () => clearTimeout(timer);
+ }, [sectionAnimateControls, sectionInView]);
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ if (titleInView) {
+ titleAnimateControls.start('visible');
+ }
+ }, 200);
+
+ return () => clearTimeout(timer);
+ }, [titleAnimateControls, titleInView]);
+
+ return (
+
+
+
+ Experience
+
+
+
+
+
+ At Aerobotics7, I spearheaded the creation of software architectures
+ for controlling drones and efficiently storing landmine detection data
+ at a high-speed receiver rate. Managing the full technology stack,
+ including DevOps, SQL databases, and security protocols, I
+ successfully ensured real-time communication and authentication
+ between the drone and users. Additionally, I presented our hardware
+ and software technology at the Geneva International Centre for
+ Humanitarian Demining (held in Switzerland once a year) to showcase
+ our capabilities to government officials, scientists, and engineers.
+
+
+
+
+
+ Previously at Listing Alert, I helped to develop the mobile app with
+ bare React Native (non-Expo) along with developing our own API with
+ Node.js, Express.js, MongoDB and AWS S3 to be used for the real estate
+ agents to get notifications on property listings from potential
+ buyers. Additionally, the team and I developed a web dashboard with
+ React.js for companies to create agents, offices, and other tasks for
+ their needs. In all of the development process, we used Apollo
+ GraphQL. Over 1600 agents across the country from RE/MAX to Century 21
+ Black Bear Realty use Listing Alert.
+
+
+
+
+
+ In addition, I worked on React for about two and a half years, and
+ before that I worked on vanilla JavaScript for three years. I also
+ worked on Django, Python, Node, Express, MongoDB, MySQL, and
+ PostgreSQL for three to four years. Over the course of these years, I
+ learned how to make better and reusable code that is readable along
+ with clean file structure which follows best practices.
+
+
+
+ );
+};
+
+export default ExperienceSection;
diff --git a/web/components/home/ExperienceSection/styles.ts b/web/components/home/ExperienceSection/styles.ts
new file mode 100644
index 00000000..2bae38f7
--- /dev/null
+++ b/web/components/home/ExperienceSection/styles.ts
@@ -0,0 +1,88 @@
+import styled from 'styled-components';
+import { motion } from 'framer-motion';
+
+export const Section = styled(motion.section).attrs(() => ({
+ initial: 'hidden',
+ variants: {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: { duration: 0.5 },
+ },
+ },
+}))`
+ padding-left: 12rem;
+ text-align: right;
+
+ @media ${({ theme }) => theme.responsive.below1199} {
+ padding-left: 3rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below899} {
+ padding-right: 3rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below599} {
+ padding-right: 0;
+ padding-left: 0;
+ }
+`;
+
+export const SectionTitle = styled(motion.div).attrs(() => ({
+ initial: 'hidden',
+ variants: {
+ hidden: {
+ opacity: 0,
+ y: 10,
+ },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: { duration: 0.5 },
+ },
+ },
+}))`
+ margin-bottom: 2.5rem;
+
+ @media ${({ theme }) => theme.responsive.below599} {
+ margin-bottom: 1.75rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below479} {
+ margin-bottom: 1.5rem;
+ }
+`;
+
+export const ParagraphWrapper = styled.div`
+ margin-top: 2.5rem;
+ margin-bottom: 2.5rem;
+ line-height: 1.5;
+
+ &:first-child {
+ margin-top: 0;
+ }
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ @media ${({ theme }) => theme.responsive.below899} {
+ line-height: 1.8;
+ }
+
+ @media ${({ theme }) => theme.responsive.below599} {
+ margin-top: 1.75rem;
+ margin-bottom: 1.75rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below479} {
+ margin-top: 1.5rem;
+ margin-bottom: 1.5rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below379} {
+ line-height: 1.5;
+ }
+`;
+
+export const Italic = styled.i``;
diff --git a/web/components/home/HeroBanner/index.tsx b/web/components/home/HeroBanner/index.tsx
index 5ad68aea..410340d1 100644
--- a/web/components/home/HeroBanner/index.tsx
+++ b/web/components/home/HeroBanner/index.tsx
@@ -33,15 +33,20 @@ const HeroBanner: FC = () => (
Hello! I'm Elias Gutierrez, and I'm a Full-Stack Software
- Engineer
+ Engineer 🤓. I love drinking coffee ☕️ while learning and improving
+ on new and existing technologies 💾
- I enjoy creating beautiful user-centered interactivities and solving
- abstract software puzzles to create efficiency and scalability for
- teams and companies
+ A passionate and curious individual with a BS degree in Physics from
+ UCLA currently working as a Full-Stack Software Engineer at
+ Aerobotics7 to remove landmines from around the world. I have
+ experiences with Python, Django, Node.js, React.js, Figma/Lucid Charts
+ and other platforms and tools to facilitate on creating and solving
+ real-world problems for the users to enjoy, and the companies to
+ succeed their vision
diff --git a/web/components/home/MoreSection/index.tsx b/web/components/home/MoreSection/index.tsx
new file mode 100644
index 00000000..704c4bc0
--- /dev/null
+++ b/web/components/home/MoreSection/index.tsx
@@ -0,0 +1,204 @@
+import { FC, useEffect } from 'react';
+import { useAnimation } from 'framer-motion';
+import { useInView } from 'react-intersection-observer';
+
+import HeadingSecondary from 'common/typography/HeadingSecondary';
+import Paragraph from 'common/typography/Paragraph';
+
+import {
+ ExternalLink,
+ Italic,
+ ParagraphWrapper,
+ Section,
+ SectionTitle,
+} from './styles';
+
+const MoreSection: FC = () => {
+ const sectionAnimateControls = useAnimation();
+ const { inView: sectionInView, ref: sectionRef } = useInView();
+
+ const titleAnimateControls = useAnimation();
+ const { inView: titleInView, ref: titleRef } = useInView();
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ if (sectionInView) {
+ sectionAnimateControls.start('visible');
+ }
+ }, 200);
+
+ return () => clearTimeout(timer);
+ }, [sectionAnimateControls, sectionInView]);
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ if (titleInView) {
+ titleAnimateControls.start('visible');
+ }
+ }, 200);
+
+ return () => clearTimeout(timer);
+ }, [titleAnimateControls, titleInView]);
+
+ return (
+
+
+
+ More
+
+
+
+
+
+ I enjoy reading as many books as I can. I am currently reading George
+ R.R. Martin's Game of Thrones series
+ (currently at the fourth book 😄), War and Peace by
+ Leo Tolstoy 😮, Michael Mann's
+ Heat 2 (the author is the actual famous film
+ director), and Basic Writings of Nietzsche translated
+ and edited by Walter Kaufmann. My favorite book is{' '}
+ Dune by Frank Herbert.
+
+
+
+
+
+ I also enjoy watching films and television with
+ Children of Men by Alfonso Cuarón being my favorite
+ movie of all time, and my favorite TV show is a tie between
+ Breaking Bad and Attack on Titan.
+
+
+
+
+
+ A few minor things about me is that I like to be active by going to
+ the gym, running, and hiking with rock climbing as my next goal. I
+ love videogames with Half-Life 2 being my all-time
+ favorite. From time-to-time, I continue to learn physics and how to
+ apply them computationally. Lastly, I enjoy helping others whether it
+ is community service or teaching.
+
+
+
+
+
+ If you want to connect with me for coffee, collaboration, or anything
+ else, then
+
+ hit me up on Twitter
+
+ or email (
+
+ gutierrezelias1991@gmail.com
+
+ ).
+
+
+
+
+
+ This site was created with
+
+ Next.js
+
+ ,
+
+ TypeScript
+
+ ,
+
+ Redux Toolkit
+
+ ,
+
+ Styled-Components
+
+ , and
+
+ Framer
+
+ for the Frontend being hosted in
+
+ Netlify
+
+ . It was also created with
+
+ Django
+
+ ,
+
+ Wagtail CMS
+
+ , and
+
+ Django REST Framework
+
+ for the Backend being hosted in
+
+ PythonAnywhere
+
+ . The images for the work and articles are stored in
+
+ AWS S3
+
+ .
+
+
+
+ );
+};
+
+export default MoreSection;
diff --git a/web/components/home/MoreSection/styles.ts b/web/components/home/MoreSection/styles.ts
new file mode 100644
index 00000000..9b7cbc58
--- /dev/null
+++ b/web/components/home/MoreSection/styles.ts
@@ -0,0 +1,107 @@
+import styled from 'styled-components';
+import { motion } from 'framer-motion';
+
+export const Section = styled(motion.section).attrs(() => ({
+ initial: 'hidden',
+ variants: {
+ hidden: { opacity: 0 },
+ visible: {
+ opacity: 1,
+ transition: { duration: 0.5 },
+ },
+ },
+}))`
+ margin-top: 12rem;
+ padding-left: 12rem;
+ text-align: right;
+
+ &.home-page__more-section {
+ margin-top: 0;
+ }
+
+ @media ${({ theme }) => theme.responsive.below1199} {
+ padding-left: 3rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below899} {
+ margin-top: 0;
+ padding-right: 3rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below599} {
+ padding-right: 0;
+ padding-left: 0;
+ }
+`;
+
+export const SectionTitle = styled(motion.div).attrs(() => ({
+ initial: 'hidden',
+ variants: {
+ hidden: {
+ opacity: 0,
+ y: 10,
+ },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: { duration: 0.5 },
+ },
+ },
+}))`
+ margin-bottom: 2.5rem;
+
+ @media ${({ theme }) => theme.responsive.below599} {
+ margin-bottom: 1.75rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below479} {
+ margin-bottom: 1.5rem;
+ }
+`;
+
+export const ParagraphWrapper = styled.div`
+ margin-top: 2.5rem;
+ margin-bottom: 2.5rem;
+ line-height: 1.5;
+
+ &:first-child {
+ margin-top: 0;
+ }
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ @media ${({ theme }) => theme.responsive.below899} {
+ line-height: 1.8;
+ }
+
+ @media ${({ theme }) => theme.responsive.below599} {
+ margin-top: 1.75rem;
+ margin-bottom: 1.75rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below479} {
+ margin-top: 1.5rem;
+ margin-bottom: 1.5rem;
+ }
+
+ @media ${({ theme }) => theme.responsive.below379} {
+ line-height: 1.5;
+ }
+`;
+
+export const Italic = styled.i``;
+
+export const ExternalLink = styled.a`
+ font-weight: 700;
+ color: ${({ theme }) => theme.colors.primary.hex};
+ text-decoration: none;
+ word-break: break-all;
+
+ &:hover {
+ text-decoration: underline;
+ cursor: pointer;
+ opacity: 0.9;
+ }
+`;
diff --git a/web/components/home/Row/index.tsx b/web/components/home/Row/index.tsx
new file mode 100644
index 00000000..683177a3
--- /dev/null
+++ b/web/components/home/Row/index.tsx
@@ -0,0 +1,12 @@
+import styled from 'styled-components';
+
+const Row = styled.div`
+ display: flex;
+ flex-direction: row;
+
+ @media ${({ theme }) => theme.responsive.below899} {
+ flex-direction: column;
+ }
+`;
+
+export default Row;
diff --git a/web/components/home/TalkSection/TalkContainer.tsx b/web/components/home/TalkSection/TalkContainer.tsx
deleted file mode 100644
index 5cc798db..00000000
--- a/web/components/home/TalkSection/TalkContainer.tsx
+++ /dev/null
@@ -1,117 +0,0 @@
-import { FC, useEffect } from 'react';
-import { useAnimation } from 'framer-motion';
-import { useInView } from 'react-intersection-observer';
-
-import GlassTriangle from 'common/components/GlassTriangle';
-
-import { useIsHovering } from 'common/hooks';
-
-import HeadingTertiary from 'common/typography/HeadingTertiary';
-
-import {
- TalkContainerStyle,
- TalkDescriptionContainer,
- TalkImageLink,
- TalkImageWrapper,
- TalkTitle,
- TalkTitleLink,
-} from './styles';
-
-export interface ITalkContainer {
- finishIsFirstMount: boolean;
- reverseClass?: string;
- talkImageAlt: string;
- talkImageSrc: string;
- talkLinkPath: string;
- talkTitle: string;
-}
-
-const TalkContainer: FC = ({
- finishIsFirstMount,
- reverseClass,
- talkImageAlt,
- talkImageSrc,
- talkLinkPath,
- talkTitle,
-}) => {
- const titleAnimateControls = useAnimation();
- const { inView: titleInView, ref: titleRef } = useInView();
-
- const imageAnimateControls = useAnimation();
- const { inView: imageInView, ref: imageRef } = useInView();
-
- const [isTitleLinkHovering, setIsTitleLinkHovering] = useIsHovering();
- const [isImageLinkHovering, setIsImageLinkHovering] = useIsHovering();
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && titleInView) {
- titleAnimateControls.start('visible');
- }
- }, 700);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, titleAnimateControls, titleInView]);
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && imageInView) {
- imageAnimateControls.start('visible');
- }
- }, 1000);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, imageAnimateControls, imageInView]);
-
- return (
-
-
- setIsImageLinkHovering(true)}
- onHoverEnd={() => setIsImageLinkHovering(false)}
- ref={imageRef}
- >
-
-
-
-
-
-
- setIsTitleLinkHovering(true)}
- onMouseLeave={() => setIsTitleLinkHovering(false)}
- >
-
- {talkTitle}
-
-
-
-
-
- );
-};
-
-export default TalkContainer;
diff --git a/web/components/home/TalkSection/index.tsx b/web/components/home/TalkSection/index.tsx
deleted file mode 100644
index 93d612b3..00000000
--- a/web/components/home/TalkSection/index.tsx
+++ /dev/null
@@ -1,79 +0,0 @@
-import React, { FC, useEffect } from 'react';
-import { useAnimation } from 'framer-motion';
-import { useInView } from 'react-intersection-observer';
-
-import LineSeparator from 'common/components/LineSeparator';
-
-import HeadingSecondary from 'common/typography/HeadingSecondary';
-
-import { Container, Section, SectionTitle } from './styles';
-import TalkContainer, { ITalkContainer } from './TalkContainer';
-
-const talkContainerData: Omit[] = [
- {
- talkImageAlt: 'Django Part 1 Presentation',
- talkImageSrc: '/talk-presentation1.png',
- talkLinkPath: 'https://vimeo.com/659389997',
- talkTitle:
- '"Django Magic: MVT" Developer Connect Presentation @ Bitwise Industries',
- },
- {
- reverseClass: 'reverse',
- talkImageAlt: 'Redux Toolkit Presentation',
- talkImageSrc: '/talk-presentation2.png',
- talkLinkPath:
- 'https://us02web.zoom.us/rec/play/coJ_z0w_gxEy5gP6iFtG1FLEuzuWey7dumrFH2xZ3rQQwGCBdy91Exb3Jyu2odOXj39rp-WKgEmPad2J.9De7TgEACj6xPmx3?continueMode=true',
- talkTitle:
- '"Converting Legacy Redux To Redux Toolkit" Developer Connect Presentation @ Bitwise Industries',
- },
-];
-
-interface ITalkSection {
- finishIsFirstMount: boolean;
-}
-
-const TalkSection: FC = ({ finishIsFirstMount }) => {
- const controls = useAnimation();
- const { inView, ref } = useInView();
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && inView) {
- controls.start('visible');
- }
- }, 500);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, controls, inView]);
-
- return (
-
-
-
- Talks
-
-
-
-
-
-
- {talkContainerData.map((talkData) => (
-
-
-
- ))}
-
-
- );
-};
-
-export default TalkSection;
diff --git a/web/components/home/TalkSection/styles.ts b/web/components/home/TalkSection/styles.ts
deleted file mode 100644
index 41ed0677..00000000
--- a/web/components/home/TalkSection/styles.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-import styled from 'styled-components';
-import { motion } from 'framer-motion';
-
-// TALK SECTION
-export const Section = styled.section``;
-
-export const SectionTitle = styled(motion.div).attrs(() => ({
- initial: 'hidden',
- variants: {
- hidden: {
- opacity: 0,
- y: 10,
- },
- visible: {
- opacity: 1,
- y: 0,
- transition: { duration: 0.5 },
- },
- },
-}))`
- text-align: center;
-`;
-
-export const Container = styled.div`
- display: flex;
- padding-top: 4rem;
-
- @media ${({ theme }) => theme.responsive.below899} {
- flex-direction: column;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- padding-top: 1rem;
- }
-`;
-
-// TALK CONTAINER
-export const TalkContainerStyle = styled.div`
- padding-top: 5rem;
- padding-bottom: 5rem;
-
- @media ${({ theme }) => theme.responsive.below899} {
- padding-top: 5rem;
- padding-bottom: 5rem;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- padding-bottom: 1rem;
- }
-
- @media ${({ theme }) => theme.responsive.below379} {
- padding-top: 3rem;
- }
-`;
-
-export const TalkDescriptionContainer = styled.div`
- display: flex;
- flex-direction: column;
- align-items: center;
- text-align: center;
-
- &.reverse {
- flex-direction: column-reverse;
- padding-top: 10rem;
-
- @media ${({ theme }) => theme.responsive.below899} {
- padding-top: 0;
- }
- }
-
- @media ${({ theme }) => theme.responsive.below599} {
- overflow-x: hidden;
- }
-`;
-
-export const TalkImageWrapper = styled(motion.div).attrs(({ className }) => ({
- initial: 'hidden',
- variants: {
- hidden: {
- opacity: 0,
- x: className?.includes('reverse') ? 100 : -100,
- },
- visible: {
- opacity: 1,
- x: 0,
- transition: {
- type: 'spring',
- bounce: 0.4,
- duration: 0.5,
- },
- },
- },
-}))`
- margin-bottom: 2rem;
-
- &.reverse {
- margin-top: 2rem;
- margin-bottom: 0;
- }
-`;
-
-export const TalkImageLink = styled.a``;
-
-export const TalkTitle = styled(motion.div).attrs(() => ({
- initial: 'hidden',
- variants: {
- hidden: {
- opacity: 0,
- },
- visible: {
- opacity: 1,
- transition: { duration: 0.3 },
- },
- },
-}))``;
-
-export const TalkTitleLink = styled.a`
- padding-left: 7rem;
- padding-right: 7rem;
- text-decoration: none;
-
- @media ${({ theme }) => theme.responsive.below1199} {
- padding-left: 4rem;
- padding-right: 4rem;
- }
-
- @media ${({ theme }) => theme.responsive.below899} {
- padding-left: 7rem;
- padding-right: 7rem;
- }
-
- @media ${({ theme }) => theme.responsive.below599} {
- padding-left: 2rem;
- padding-right: 2rem;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- padding-left: 1rem;
- padding-right: 1rem;
- }
-`;
diff --git a/web/components/home/WorkSection/WorkContainer.tsx b/web/components/home/WorkSection/WorkContainer.tsx
deleted file mode 100644
index c4e2250e..00000000
--- a/web/components/home/WorkSection/WorkContainer.tsx
+++ /dev/null
@@ -1,302 +0,0 @@
-import { FC, useEffect } from 'react';
-import Link from 'next/link';
-import { useAnimation } from 'framer-motion';
-import { useInView } from 'react-intersection-observer';
-
-import GlassRectangle from 'common/components/GlassRectangle';
-
-import { useIsHovering } from 'common/hooks';
-
-import HeadingTertiary from 'common/typography/HeadingTertiary';
-import Paragraph from 'common/typography/Paragraph';
-
-import { isHoveringOverall } from 'utils';
-
-import {
- WorkContainerStyle,
- WorkDescription,
- WorkDescriptionContainer,
- WorkExternalLink,
- WorkImageLink,
- WorkImageWrapper,
- WorkLink,
- WorkLinkWrapper,
- WorkTitle,
- WorkTitleLink,
-} from './styles';
-
-export interface IWorkContainer {
- finishIsFirstMount: boolean;
- isExploreLinkHovering: boolean;
- reverseClass?: string;
- workDescription: string;
- workExternalLinkPath: string;
- workImageAlt: string;
- workImageSrc: string;
- workLinkPath: string;
- workTitle: string;
-}
-
-const WorkContainer: FC = ({
- finishIsFirstMount,
- isExploreLinkHovering,
- reverseClass,
- workDescription,
- workExternalLinkPath,
- workImageAlt,
- workImageSrc,
- workLinkPath,
- workTitle,
-}) => {
- const titleAnimateControls = useAnimation();
- const { inView: titleInView, ref: titleRef } = useInView();
-
- const descriptionAnimateControls = useAnimation();
- const { inView: descriptionInView, ref: descriptionRef } = useInView();
-
- const externalLinkAnimateControls = useAnimation();
- const { inView: externalLinkInView, ref: externalLinkRef } = useInView();
-
- const linkAnimateControls = useAnimation();
- const { inView: linkInView, ref: linkRef } = useInView();
-
- const imageAnimateControls = useAnimation();
- const { inView: imageInView, ref: imageRef } = useInView();
-
- const [isTitleLinkHovering, setIsTitleLinkHovering] = useIsHovering();
- const [isImageLinkHovering, setIsImageLinkHovering] = useIsHovering();
- const [isWorkLinkHovering, setIsWorkLinkHovering] = useIsHovering();
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && titleInView) {
- titleAnimateControls.start('visible');
- }
- }, 600);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, titleAnimateControls, titleInView]);
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && descriptionInView) {
- descriptionAnimateControls.start('visible');
- }
- }, 800);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, descriptionAnimateControls, descriptionInView]);
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && externalLinkInView) {
- externalLinkAnimateControls.start('visible');
- }
- }, 1700);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, externalLinkAnimateControls, externalLinkInView]);
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && linkInView) {
- linkAnimateControls.start('visible');
- }
- }, 1700);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, linkAnimateControls, linkInView]);
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && imageInView) {
- imageAnimateControls.start('visible');
- }
- }, 1500);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, imageAnimateControls, imageInView]);
-
- useEffect(() => {
- if (
- !finishIsFirstMount &&
- isHoveringOverall(
- isImageLinkHovering,
- isWorkLinkHovering,
- isExploreLinkHovering
- )
- ) {
- imageAnimateControls.start('hovering');
- } else {
- imageAnimateControls.start('nonHovering');
- }
- }, [
- finishIsFirstMount,
- isImageLinkHovering,
- isWorkLinkHovering,
- isExploreLinkHovering,
- imageAnimateControls,
- ]);
-
- return (
-
-
-
- setIsTitleLinkHovering(true)}
- onMouseLeave={() => setIsTitleLinkHovering(false)}
- >
-
- {workTitle}
-
-
-
-
-
-
-
-
- {workDescription}
-
-
-
- {workExternalLinkPath.length > 0 && (
-
-
- App
-
-
- )}
-
-
-
- setIsWorkLinkHovering(true)}
- onMouseLeave={() => setIsWorkLinkHovering(false)}
- >
- About
-
-
-
-
-
- setIsImageLinkHovering(true)}
- onHoverEnd={() => setIsImageLinkHovering(false)}
- ref={imageRef}
- >
-
-
-
-
-
-
-
- );
-};
-
-export default WorkContainer;
diff --git a/web/components/home/WorkSection/index.tsx b/web/components/home/WorkSection/index.tsx
deleted file mode 100644
index f6190a68..00000000
--- a/web/components/home/WorkSection/index.tsx
+++ /dev/null
@@ -1,126 +0,0 @@
-import React, { FC, useEffect } from 'react';
-import Link from 'next/link';
-import { useAnimation } from 'framer-motion';
-import { useInView } from 'react-intersection-observer';
-
-import LineSeparator from 'common/components/LineSeparator';
-
-import { useIsHovering } from 'common/hooks';
-
-import HeadingSecondary from 'common/typography/HeadingSecondary';
-
-import { IWork } from 'common/models';
-
-import environment from 'environment';
-
-import {
- Container,
- ExploreMoreLink,
- ExploreMoreWrapper,
- Section,
- SectionTitle,
-} from './styles';
-import WorkContainer from './WorkContainer';
-
-type TWorksData = Pick<
- IWork,
- | 'category'
- | 'description'
- | 'first_released_at'
- | 'id'
- | 'logo_image'
- | 'title'
- | 'uuid'
- | 'work_url'
-> & {
- meta: Pick;
-};
-
-interface IWorkSection {
- finishIsFirstMount: boolean;
- worksData: TWorksData[];
-}
-
-const WorkSection: FC = ({ finishIsFirstMount, worksData }) => {
- const titleAnimateControls = useAnimation();
- const { inView: titleInView, ref: titleRef } = useInView();
-
- const viewMoreAnimateControls = useAnimation();
- const { inView: viewMoreInView, ref: viewMoreRef } = useInView();
-
- const [isHovering, setIsHovering] = useIsHovering();
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && titleInView) {
- titleAnimateControls.start('visible');
- }
- }, 500);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, titleAnimateControls, titleInView]);
-
- useEffect(() => {
- const timer = setTimeout(() => {
- if (!finishIsFirstMount && viewMoreInView) {
- viewMoreAnimateControls.start('visible');
- }
- }, 2000);
-
- return () => clearTimeout(timer);
- }, [finishIsFirstMount, viewMoreAnimateControls, viewMoreInView]);
-
- return (
-
-
-
- Work
-
-
-
-
- {worksData.length > 0 &&
- worksData.slice(0, 3).map((workData, workIndex) => (
-
-
-
-
-
- ))}
-
-
-
-
- setIsHovering(true)}
- onMouseLeave={() => setIsHovering(false)}
- >
- Explore all work
-
-
-
-
- );
-};
-
-export default WorkSection;
diff --git a/web/components/home/WorkSection/styles.ts b/web/components/home/WorkSection/styles.ts
deleted file mode 100644
index 09d3cf4e..00000000
--- a/web/components/home/WorkSection/styles.ts
+++ /dev/null
@@ -1,343 +0,0 @@
-import styled from 'styled-components';
-import { motion } from 'framer-motion';
-
-// WORK SECTION
-export const Section = styled.section``;
-
-export const SectionTitle = styled(motion.div).attrs(() => ({
- initial: 'hidden',
- variants: {
- hidden: {
- opacity: 0,
- y: 10,
- },
- visible: {
- opacity: 1,
- y: 0,
- transition: { duration: 0.5 },
- },
- },
-}))`
- text-align: right;
-`;
-
-export const Container = styled.div`
- display: flex;
- flex-direction: column;
- padding-top: 4rem;
-
- @media ${({ theme }) => theme.responsive.below1199} {
- padding-top: 2.5rem;
- }
-
- @media ${({ theme }) => theme.responsive.below899} {
- padding-top: 2.3rem;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- padding-top: 1rem;
- }
-`;
-
-export const ExploreMoreWrapper = styled(motion.div).attrs(() => ({
- variants: {
- visible: {
- rotate: [0, 15, 7.5, 15, 0],
- transition: {
- duration: 1,
- ease: 'easeInOut',
- times: [0, 0.2, 0.5, 0.8, 1],
- },
- },
- },
-}))`
- margin-top: 5rem;
- text-align: center;
-
- @media ${({ theme }) => theme.responsive.below599} {
- margin-top: 2rem;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- margin-top: 1rem;
- }
-`;
-
-export const ExploreMoreLink = styled.a`
- font-size: 2rem;
- font-weight: 700;
- color: ${({ theme }) => theme.colors.primary.hex};
- text-decoration: none;
-
- &:hover {
- text-decoration: underline;
- cursor: pointer;
- opacity: 0.9;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- font-size: 1.7rem;
- }
-`;
-
-// WORK CONTAINER
-export const WorkContainerStyle = styled.div`
- display: flex;
- justify-content: space-between;
- margin-top: 9rem;
- margin-bottom: 9rem;
- padding-top: 1rem;
- padding-bottom: 1rem;
-
- &.reverse {
- flex-direction: row-reverse;
-
- @media ${({ theme }) => theme.responsive.below899} {
- flex-direction: column-reverse;
- }
- }
-
- @media ${({ theme }) => theme.responsive.below899} {
- flex-direction: column;
- margin-top: 5rem;
- margin-bottom: 5rem;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- margin-top: 3rem;
- margin-bottom: 3rem;
- }
-
- @media ${({ theme }) => theme.responsive.below379} {
- margin-top: 2rem;
- margin-bottom: 2rem;
- }
-`;
-
-export const WorkTitle = styled(motion.div).attrs(() => ({
- initial: 'hidden',
- variants: {
- hidden: {
- opacity: 0,
- },
- visible: {
- opacity: 1,
- transition: { duration: 0.3 },
- },
- },
-}))`
- width: 35%;
-
- &.reverse {
- text-align: right;
-
- @media ${({ theme }) => theme.responsive.below899} {
- text-align: center;
- }
-
- @media ${({ theme }) => theme.responsive.below379} {
- text-align: left;
- }
- }
-
- @media ${({ theme }) => theme.responsive.below899} {
- width: 100%;
- padding: 1rem 4.5rem;
- text-align: center;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- padding: 1rem 1rem;
- }
-
- @media ${({ theme }) => theme.responsive.below379} {
- text-align: left;
- }
-`;
-
-export const WorkTitleLink = styled.a`
- text-decoration: none;
-`;
-
-export const WorkDescriptionContainer = styled.div`
- display: flex;
- flex-direction: column;
- width: 100%;
- padding: 2rem 4.5rem;
-
- @media ${({ theme }) => theme.responsive.below899} {
- padding: 1rem 4.5rem;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- padding: 1rem 1rem;
- }
-`;
-
-export const WorkDescription = styled(motion.div).attrs(() => ({
- initial: 'hidden',
- variants: {
- hidden: {
- opacity: 0,
- },
- visible: {
- opacity: 1,
- transition: { duration: 0.3 },
- },
- },
-}))`
- margin-bottom: 2rem;
-
- &.reverse {
- text-align: right;
-
- @media ${({ theme }) => theme.responsive.below899} {
- text-align: center;
- }
-
- @media ${({ theme }) => theme.responsive.below379} {
- margin-bottom: 1rem;
- text-align: left;
- }
- }
-
- @media ${({ theme }) => theme.responsive.below899} {
- text-align: center;
- }
-
- @media ${({ theme }) => theme.responsive.below379} {
- text-align: left;
- }
-`;
-
-export const WorkLinkWrapper = styled(motion.div).attrs(({ className }) => ({
- initial: 'hidden',
- variants: {
- hidden: {
- opacity: 0,
- y: className?.includes('reverse') ? -100 : -150,
- },
- visible: {
- opacity: 1,
- y: 0,
- transition: {
- type: 'spring',
- bounce: 0.4,
- duration: 0.5,
- },
- },
- },
-}))`
- text-align: right;
-
- &.external-link {
- margin-bottom: 2rem;
- }
-
- &.reverse {
- text-align: left;
-
- @media ${({ theme }) => theme.responsive.below899} {
- text-align: center;
- }
-
- @media ${({ theme }) => theme.responsive.below379} {
- order: -1;
- margin-bottom: 2rem;
- text-align: right;
- }
- }
-
- @media ${({ theme }) => theme.responsive.below899} {
- padding: 1rem 4.5rem;
- text-align: center;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- padding: 0rem 1rem;
- }
-
- @media ${({ theme }) => theme.responsive.below379} {
- text-align: right;
- }
-`;
-
-export const WorkLink = styled.a`
- font-size: ${({ theme }) => theme.fonts.paragraph};
- font-weight: 700;
- color: ${({ theme }) => theme.colors.primary.hex};
- text-decoration: none;
-
- &:hover {
- opacity: 0.7;
- }
-`;
-
-export const WorkExternalLink = styled.a`
- font-size: ${({ theme }) => theme.fonts.paragraph};
- font-weight: 700;
- color: ${({ theme }) => theme.colors.primary.hex};
- text-decoration: none;
-
- &:hover {
- opacity: 0.7;
- }
-`;
-
-export const WorkImageWrapper = styled(motion.div).attrs(({ className }) => ({
- initial: 'hidden',
- variants: {
- hidden: {
- opacity: 0,
- y: className?.includes('reverse') ? -100 : -150,
- },
- hovering: {
- rotate: className?.includes('reverse') ? 5 : -5,
- scale: 1.01,
- transition: {
- type: 'spring',
- bounce: 0.4,
- duration: 0.2,
- },
- },
- nonHovering: {
- rotate: 0,
- scale: 1,
- },
- visible: {
- opacity: 1,
- y: 0,
- transition: {
- type: 'spring',
- bounce: 0.4,
- duration: 0.5,
- },
- },
- },
-}))`
- width: 18%;
- margin-left: 3rem;
-
- &.reverse {
- margin-left: 0;
- margin-right: 3rem;
-
- @media ${({ theme }) => theme.responsive.below899} {
- margin-right: auto;
- margin-left: auto;
- }
- }
-
- @media ${({ theme }) => theme.responsive.below899} {
- width: 85%;
- margin-right: auto;
- margin-left: auto;
- padding: 1rem 4.5rem;
- }
-
- @media ${({ theme }) => theme.responsive.below479} {
- padding: 1rem 1rem;
- }
-`;
-
-export const WorkImageLink = styled.a``;
diff --git a/web/components/home/index.ts b/web/components/home/index.ts
index e9bcd71b..66d9da93 100644
--- a/web/components/home/index.ts
+++ b/web/components/home/index.ts
@@ -1,5 +1,9 @@
-export { default as ArticleSection } from './ArticleSection';
+export { default as AboutImage } from './AboutImage';
+export { default as AboutSection } from './AboutSection';
+export { default as BeliefsSection } from './BeliefsSection';
+export { default as Col } from './Col';
+export { default as ExperienceSection } from './ExperienceSection';
export { default as HeroBanner } from './HeroBanner';
export { default as InitialSiteTransition } from './InitialSiteTransition';
-export { default as TalkSection } from './TalkSection';
-export { default as WorkSection } from './WorkSection';
+export { default as MoreSection } from './MoreSection';
+export { default as Row } from './Row';
diff --git a/web/pages/about/index.tsx b/web/pages/about/index.tsx
deleted file mode 100644
index 7abbe4d8..00000000
--- a/web/pages/about/index.tsx
+++ /dev/null
@@ -1,116 +0,0 @@
-import type { NextPage } from 'next';
-import Head from 'next/head';
-
-import LineSeparator from 'common/components/LineSeparator';
-import LoadingIcon from 'common/components/LoadingIcon';
-import PageContainer from 'common/components/PageContainer';
-import WithLoadingOverlay from 'common/components/WithLoadingOverlay';
-
-import {
- AboutImage,
- AboutSection,
- BeliefsSection,
- Col,
- ExperienceSection,
- MoreSection,
- Row,
-} from 'components/about';
-
-import environment from 'environment';
-
-const About: NextPage = () => (
- <>
-
- About | Elias Gutierrez, Software Developer
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
- }
- isLoading={false}
- loaderComponent={}
- loaderDuration={1000}
- />
-
- >
-);
-
-export default About;
diff --git a/web/pages/articles/[slug].tsx b/web/pages/articles/[slug].tsx
index 6334bdfe..92a0a227 100644
--- a/web/pages/articles/[slug].tsx
+++ b/web/pages/articles/[slug].tsx
@@ -78,7 +78,7 @@ const Article: NextPage = () => {
articleData.meta.seo_title.length > 0
? articleData.meta.seo_title
: articleData.title
- } - Articles | Elias Gutierrez, Software Developer`
+ } - Articles | Elias Gutierrez, Software Engineer`
: ''}
@@ -95,7 +95,7 @@ const Article: NextPage = () => {
{
return (
<>
- Articles | Elias Gutierrez, Software Developer
+ Articles | Elias Gutierrez, Software Engineer
diff --git a/web/pages/index.tsx b/web/pages/index.tsx
index 7fdfe11b..e336925f 100644
--- a/web/pages/index.tsx
+++ b/web/pages/index.tsx
@@ -6,30 +6,30 @@ import { nextReduxWrapper } from 'app';
import {
getArticles,
getRunningOperationPromises as getArticlesRunningOperationPromises,
- useGetArticlesQuery,
} from 'app/api/articleExtendedApi';
import {
getWorksByCategory,
getRunningOperationPromises as getWorksRunningOperationPromises,
- useGetWorksByCategoryQuery,
} from 'app/api/workExtendedApi';
+import LineSeparator from 'common/components/LineSeparator';
import LoadingIcon from 'common/components/LoadingIcon';
import PageContainer from 'common/components/PageContainer';
import WithLoadingOverlay from 'common/components/WithLoadingOverlay';
import {
- ArticleSection,
+ AboutImage,
+ BeliefsSection,
+ Col,
+ ExperienceSection,
HeroBanner,
InitialSiteTransition,
- TalkSection,
- WorkSection,
+ MoreSection,
+ Row,
} from 'components/home';
import environment from 'environment';
-import { isLoadingOverall } from 'utils';
-
interface IHome {
isFirstMount: boolean;
}
@@ -64,28 +64,6 @@ export const getStaticProps = nextReduxWrapper.getStaticProps(
const Home: NextPage = ({ isFirstMount }) => {
const [finishIsFirstMount, setFinishIsFirstMount] = useState(isFirstMount);
- const { data: articlesData, isFetching: articlesFetching } =
- useGetArticlesQuery({
- category: 0,
- limit: 3,
- tags: [],
- });
-
- const { selectedData: worksData, isFetching: worksFetching } =
- useGetWorksByCategoryQuery(
- { category: 'Work', limit: 5 },
- {
- selectFromResult: (result) => ({
- ...result,
- selectedData: result.data
- ? result.data.items.filter(
- (resultData) => resultData.title !== 'Node News API'
- )
- : [],
- }),
- }
- );
-
useEffect(() => {
const timer = setTimeout(() => {
if (!isFirstMount) setFinishIsFirstMount(isFirstMount);
@@ -97,28 +75,28 @@ const Home: NextPage = ({ isFirstMount }) => {
return (
<>
- Elias Gutierrez, Software Developer
+ Elias Gutierrez, Software Engineer
@@ -134,12 +112,12 @@ const Home: NextPage = ({ isFirstMount }) => {
= ({ isFirstMount }) => {
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* */}
+
+
+
+
+
>
}
- isLoading={isLoadingOverall(worksFetching, articlesFetching)}
+ isLoading={false}
loaderDuration={1000}
{...(!finishIsFirstMount && {
loaderComponent: ,
diff --git a/web/pages/work/[slug].tsx b/web/pages/work/[slug].tsx
index 7de458e2..96c0dc30 100644
--- a/web/pages/work/[slug].tsx
+++ b/web/pages/work/[slug].tsx
@@ -75,7 +75,7 @@ const Work: NextPage = () => {
workData.meta.seo_title.length > 0
? workData.meta.seo_title
: workData.title
- } - Work | Elias Gutierrez, Software Developer`
+ } - Work | Elias Gutierrez, Software Engineer`
: ''}
@@ -92,7 +92,7 @@ const Work: NextPage = () => {
{
return (
<>
- Work | Elias Gutierrez, Software Developer
+ Work | Elias Gutierrez, Software Engineer
{
diff --git a/web/public/about-pic.jpeg b/web/public/about-pic1.jpeg
similarity index 100%
rename from web/public/about-pic.jpeg
rename to web/public/about-pic1.jpeg
diff --git a/web/public/about-pic3.jpg b/web/public/about-pic3.jpg
new file mode 100644
index 00000000..8c4b1504
Binary files /dev/null and b/web/public/about-pic3.jpg differ
diff --git a/web/public/manifest.json b/web/public/manifest.json
index 5a45d276..deb04673 100644
--- a/web/public/manifest.json
+++ b/web/public/manifest.json
@@ -1,7 +1,7 @@
{
"short_name": "Portfolio",
"name": "Elias Gutierrez's Portfolio",
- "description": "Software and Full-Stack Developer. Creating beautiful user-centered interactivity and experiences.",
+ "description": "Full-Stack Software Engineer. Drinking coffee while learning and improving on new and existing tech.",
"icons": [
{
"src": "/favicon.ico",