Users should be able to:
- View the optimal layout for each page depending on their device's screen size
- See hover states for all interactive elements throughout the site
- Receive an error message when the contact form is submitted if:
- The
Name
,Email Address
orMessage
fields are empty should show "This field can't be empty" - The
Email Address
is not formatted correctly should show "Please use a valid email address"
- The
- Solution URL: PayAPI Repo
- Live Site URL: PayAPI site
- Semantic HTML5 markup
- CSS custom properties
- Flexbox
- CSS Grid
- Mobile-first workflow
- React - JS library
- Next.js - React framework
- Tailwind - For styling
- MongoDB Atlas - For storing contact data
- React Hook Form - For creating a quick form complete with validation
- One of the interesting thing I learnt while doing the form validation was, rather than manually adding an error message for each input field, dynamically outputting it using state was a much more efficient way of displaying the error messages. In addition, to make sure that no errors have occurred before submitting the form, a for loop is used to loop over the keys in the formData object to make sure there are no errors, and if there are no errors, then the form can be safely submitted.
const [formData, setFormData] = useState({
id: uuidv4(),
name: "",
email: "",
company: "",
title: "",
message: "",
subscribe: true,
});
const [errors, setErrors] = useState({
name: "",
email: "",
company: "",
title: "",
message: "",
});
function handleChange(event: { target: { name: any; value: any } }) {
//Destructured name and value from event.target
const { name, value } = event.target;
let error = "";
if (name === "email" && !/\S+@\S+\.\S+/.test(value)) {
error = "Please use a valid email address";
} else if (
name !== "email" &&
typeof value === "string" &&
value.trim() === ""
) {
error = "This field can't be empty";
}
setFormData((currData) => {
return { ...currData, [name]: value };
});
setErrors((prevErrors) => {
return { ...prevErrors, [name]: error };
});
}
function handleSubmit(e: { preventDefault: () => void }) {
e.preventDefault();
//Check for errors before submitting
for (const key in formData) {
if (formData.hasOwnProperty(key)) {
handleChange({
target: { name: key, value: formData[key as keyof FormDataProps] },
});
}
}
//If there are no errors, submit the form
if (Object.values(errors).every((error) => !error)) {
addContact(formData);
}
}
- I discovered a way for the page to redirect to a certain page by utilizing the code below:
router.push("/");
NOTE: getStaticProps(); normally in React, initial data is not fetched until the next render cycle (client-side data fetching after a page is fully rendered), therefore, the initial page will load with no data until the next render cycle, which is not good for SEO. However, with getStaticProps(), the data will initially render during the build phase, so that when the initial page is rendered, the data will also be rendered too. Hence, eliminating the need of using useEffect() in the component.
Will create a dashboard to display the registered user data from the contact form page using MongoDB so that the app will be a CRUD app.
- Validate an Email in an Input field in React - This helped me to write a basic way fo validating emails in React
- How to Check if an Input is Empty in React - In addition to email input validation, the same author also outlines how to check for empty input fields
- Type Assertions - Part of the TS handbook, showed the "as" type assertion, used for declaring the type of the keys within my formData data object
- Keyof Type Operator - Part of the TS handbook, referred to this for returning types of the keys within my formData data object
- PayAPI multi-page website - Kevin Tanzyl
- Frontend Mentor - @kebin20
This is a solution to the PayAPI multi-page website challenge on Frontend Mentor.