Skip to content

Commit

Permalink
Merge pull request #6 from ITurres/feature/assess-for-jsr
Browse files Browse the repository at this point in the history
Issues #3 and #5 🎟️: Waving Alien when form submitted (Contact Page) and JSR Assess changes
  • Loading branch information
ITurres authored Feb 9, 2024
2 parents d836b95 + dea6340 commit bbe79a5
Show file tree
Hide file tree
Showing 16 changed files with 284 additions and 96 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Deploy Workflow

on:
push:
branches:
- gh-pages

jobs:
deploy:
name: portfolioDeploy
runs-on: ubuntu-latest
environment: github-pages
env:
REACT_APP_FORM_ACTION_URL: ${{ secrets.REACT_APP_FORM_ACTION_URL }}
REACT_APP_INVOLVEMENT_API_BASE_URL: ${{ secrets.REACT_APP_INVOLVEMENT_API_BASE_URL }}
REACT_APP_INVOLVEMENT_API_APP_ID: ${{ secrets.REACT_APP_INVOLVEMENT_API_APP_ID }}
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@ To run the linters included in this project, execute the following command:
- [ ] Scrollable count for **LineCount** component.
- [ ] **FloatingAstronaut** on **ExpertisePage**.
- [ ] Add **Suspense** and **ErrorBoundaries**.
- [ ] Swap configs to Environmental Variables.
- [ ] Small Waving Alien in _Thank You btn message_ at the contact form.
- [ ] Horizontal ide Navbar.
- [x] Swap configs to Environmental Variables.
- [x] Small Waving Alien in _Thank You btn message_ at the contact form.
- [x] Horizontal ide Navbar.

<p align="right">(<a href="#readme-top">back to top</a>)</p>

Expand Down
Binary file added public/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 11 additions & 5 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="2023 reactive iturres portfolio" />
<meta
name="description"
content="
Arthur Iturres is a Full-Stack Developer from Argentina, with a passion for creating
beautiful and functional web applications. He has experience in
a wide range of technologies, he is also and advocate for teamwork
and collaboration. He is always looking for new challenges and
opportunities to grow as a professional.
"
/>
<meta name="author" content="Arturo Emanuel Guerra Iturres" />
<link rel="icon" href="%PUBLIC_URL%/reactive-portfolio-favicon.png" />
<link
rel="apple-touch-icon"
href="%PUBLIC_URL%/arthur-logo-favicon.png"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/apple-touch-icon.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>ITurres Portfolio</title>
</head>
Expand Down
6 changes: 3 additions & 3 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"short_name": "reactive-portfolio",
"name": "reactive-portfolio",
"short_name": "Arthur ITurres Portfolio",
"name": "Arthur ITurres Portfolio",
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"theme_color": "#090909",
"background_color": "#ffffff"
}
56 changes: 37 additions & 19 deletions src/components/UI/ContactForm.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import React, {
useRef, useEffect, useMemo, useState,
useRef,
useEffect,
useMemo,
useState,
useCallback,
} from 'react';

import '../../styles/UI/ContactForm.scss';

const successButtonIcon = 'https://camo.githubusercontent.com/b55970b1d4c6e5d8d09a07556bce08ff3cfec080b680ad6b5be3ed46546e6f77/68747470733a2f2f6d656469612e67697068792e636f6d2f6d656469612f6b52654b6366727331596f546d74324151742f67697068792e676966';

const ContactForm: React.FC = () => {
const [formContent, setFormContent] = useState(
JSON.parse(sessionStorage.getItem('formContent')!) || null,
Expand Down Expand Up @@ -36,9 +42,8 @@ const ContactForm: React.FC = () => {
() => ({
name: /[a-z]{2,}/,
company: /[a-z]{3,}/,
email:
/^[\w.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
message: /[\w.!,.@#%&'"*+/=-]{20,}/,
email: /^[\w.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
message: /[\w\s.!,.@#%&'"*+/=-]{20,}/,
}),
[],
);
Expand Down Expand Up @@ -69,7 +74,7 @@ const ContactForm: React.FC = () => {
}
};

const validateInput = (input: any, regex: RegExp) => {
const validateInput = useCallback((input: any, regex: RegExp) => {
const inputKey = input.obj.current?.name as keyof typeof inputs;
const isValid = regex.test(input.obj.current?.value || '');

Expand All @@ -80,15 +85,15 @@ const ContactForm: React.FC = () => {
setSubmitButtonStyle(
Object.values(inputs).every((inputObj) => inputObj.validated),
);
};
}, [inputs]);

useEffect(() => {
if (formContent) {
sessionStorage.setItem('formContent', JSON.stringify(formContent));
}
}, [formContent]);

const updateFormContent = (input: any) => () => {
const updateFormContent = useCallback((input: any) => () => {
const inputKey = input.obj.current?.name as keyof typeof inputs;

setFormContent((previousFormContent: any) => {
Expand All @@ -97,7 +102,7 @@ const ContactForm: React.FC = () => {

return currentFormContent;
});
};
}, []);

useEffect(() => {
Object.values(inputs).forEach((input) => {
Expand All @@ -107,7 +112,7 @@ const ContactForm: React.FC = () => {
input.obj.current?.removeEventListener('blur', updateFormContent);
};
});
}, [inputs]);
}, [inputs, updateFormContent]);

// * this useEffect is to update the form inputs values and styles
// * when the user comes back to the page.
Expand All @@ -134,7 +139,7 @@ const ContactForm: React.FC = () => {
}
});
}
}, [formContent, inputs, validInputsPattern]);
}, [formContent, inputs, validInputsPattern, validateInput]);

const submitButtonErrorContent = (error: Error | string) => {
if ($submitButton.current) {
Expand All @@ -145,7 +150,7 @@ const ContactForm: React.FC = () => {
}
};

const hideInputs = () => {
const hideInputs = useCallback(() => {
if (formSubmittedStatus) {
Object.values(inputs).forEach((input) => {
const inputElement = input;
Expand All @@ -155,11 +160,11 @@ const ContactForm: React.FC = () => {
}
});
}
};
}, [formSubmittedStatus, inputs]);

useEffect(() => {
if (formSubmittedStatus) hideInputs();
}, [formSubmittedStatus]);
}, [formSubmittedStatus, hideInputs]);

const submitForm = async () => {
try {
Expand Down Expand Up @@ -223,7 +228,7 @@ const ContactForm: React.FC = () => {
input.obj.current?.removeEventListener('keyup', () => validateInput);
};
});
}, [inputs]);
}, [inputs, validInputsPattern, validateInput]);

return (
<form
Expand All @@ -235,7 +240,7 @@ const ContactForm: React.FC = () => {
type="text"
ref={$nameInputRef}
name="name"
placeholder="tell me your name"
placeholder="your name, at least 2 characters long"
minLength={2}
required
/>
Expand All @@ -244,7 +249,7 @@ const ContactForm: React.FC = () => {
type="text"
ref={$companyInputRef}
name="company"
placeholder="your company name here!"
placeholder="your company name, at least 3 characters long"
minLength={3}
required
/>
Expand All @@ -253,21 +258,34 @@ const ContactForm: React.FC = () => {
type="email"
ref={$emailInputRef}
name="email"
placeholder="an email so I can contact you back!"
placeholder="an email, e.g [email protected]"
required
/>

<textarea
ref={$messageInputRef}
name="message"
placeholder="your message here!"
placeholder="your message, at least 20 characters long"
rows={5}
cols={20}
required
/>

<button type="submit" ref={$submitButton} className="my-btn">
<button
type="submit"
disabled={formSubmittedStatus}
ref={$submitButton}
className="my-btn"
>
{formSubmittedStatus ? 'Thank you!' : 'Send'}
{formSubmittedStatus && (
<img
src={successButtonIcon}
alt="alien waving hand"
aria-hidden="true"
className="send-email-icon"
/>
)}
</button>
</form>
);
Expand Down
19 changes: 12 additions & 7 deletions src/components/UI/LikeButton.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import React, { useState, useRef, useEffect } from 'react';
import React, {
useState,
useRef,
useEffect,
useCallback,
} from 'react';

import { SlLike } from 'react-icons/sl';

Expand All @@ -18,17 +23,17 @@ const LikeButton: React.FC<LikeButtonProps> = ({ itemId }) => {

const likeBtn = useRef<HTMLButtonElement>(null);

const styleButton = () => {
const styleButton = useCallback(() => {
if (wasLiked) {
likeBtn.current?.classList.toggle('liked');
}
};
}, [wasLiked]);

useEffect(() => {
if (wasLiked) {
styleButton();
}
}, [wasLiked]);
}, [wasLiked, styleButton]);

interface Like {
// * disable camelcase since 'item_id' is the name of the property in the API response.
Expand All @@ -37,19 +42,19 @@ const LikeButton: React.FC<LikeButtonProps> = ({ itemId }) => {
likes: number;
}

const updateLikeCount = async () => {
const updateLikeCount = useCallback(async () => {
const likes: Like[] = (await involvement.getLikes()) as Like[];

const likedProject = likes.find((like) => like.item_id === itemId);

if (likedProject) {
setLikeCount(likedProject.likes);
}
};
}, [itemId]);

useEffect(() => {
updateLikeCount();
}, [itemId]);
}, [itemId, updateLikeCount]);

const handleLikeSubmit = async () => {
setWasLiked((liked) => !liked);
Expand Down
29 changes: 23 additions & 6 deletions src/components/pages/AboutPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import React, { useEffect, useRef } from 'react';

import { Link } from 'react-router-dom';

import { AiOutlineMail } from 'react-icons/ai';

import profileImage from '../../assets/images/profile/profile.png';
import homepageDotsImage from '../../assets/images/bg/homepage-dots-img.png';
import '../../styles/pages/AboutPage.scss';
Expand Down Expand Up @@ -28,14 +32,27 @@ const AboutPage: React.FC = () => {
<span className="emoji">&#128075;</span>
</h1>
<p className="aboutPage__about-p">
I excel in remote collaboration, driven by a robust skill set
developed through daily coding with global teams. I&apos;m adept at
meeting tight deadlines and experienced in diverse tech stacks like
React, Redux, TypeScript, JavaScript, SASS, CSS, HTML and more. My
adaptability, honed by international living experiences, enables me to
collaborate with diverse teams across the world seamlessly.
I excel in collaborative environments, leveraging a robust skill set
honed through daily interactions with global teams. My experience
spans diverse tech stacks, including Rails, React, Redux, TypeScript,
JavaScript, SASS, CSS, HTML, and more. Committed to meeting tight
deadlines, I am an advocate for teamwork, recognizing its pivotal role
in driving organizational success. My adaptability, cultivated through
international living experiences, enables me to seamlessly collaborate
with diverse teams worldwide.
</p>

<AnimatedButton />

<Link
to="/iturres-reactive-portfolio/homepage/contact"
className="aboutPage__cta"
title="This link will take you to the contact page."
>
<AiOutlineMail size={20} className="mail-icon text-hue-rotate" />
&nbsp;Let&apos;s collaborate and drive success together. Reach out to
discuss how we can achieve your goals. ( link )
</Link>
</div>
<div className="aboutPage__images">
<img
Expand Down
7 changes: 7 additions & 0 deletions src/components/pages/ContactPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React, { useState, useEffect } from 'react';

import { IoMdArrowRoundDown } from 'react-icons/io';

import '../../styles/pages/ContactPage.scss';

import Drone from '../animations/Drone.tsx';
Expand Down Expand Up @@ -31,6 +33,11 @@ const ContactPage: React.FC = () => {
{windowWidth >= laptopWidth ? <Drone /> : null}
<main className="contact-page container">
<ContactForm />

<div className="contact-page__details text-hue-rotate">
<IoMdArrowRoundDown className="details-icon" />
<span>[email protected]</span>
</div>
</main>
</div>
</div>
Expand Down
Loading

0 comments on commit bbe79a5

Please sign in to comment.