contact page

This commit is contained in:
Ruidy Nemausat 2020-01-30 13:23:23 +01:00
parent df6c0e01bb
commit df80472fd7
13 changed files with 146 additions and 14 deletions

View file

@ -52,6 +52,7 @@ Free meal planner for cooks short on ideas! (like me …)
- Cocktail selection
- Create a profile and save your favourite meals
- Notation system: know what are the most loved meals
- Share recipe with your friends and family
- Suggestions based on what your personal taste
- Recipes in Video
- Get a full menu (Starter, Main, Dessert + Cocktail)
@ -84,14 +85,17 @@ Free meal planner for cooks short on ideas! (like me …)
- Progressive Web App
- User Interface Enhancement
- Contact form
## TO DO
- add sidenav on mobile
- accounts v2
- send message after contact form validation (confirm to sender and msg+info to admin)
- code cleanup (props and refactoring)
- put a preloader
- redirect after failed fetch request: (history.push('/path'), or write handleFetchResponse function)
- https://stackoverflow.com/questions/45089386/what-is-the-best-way-to-redirect-a-page-using-react-router
- https://www.henriksommerfeld.se/error-handling-with-fetch/
- Use ErrorBoundaries component ?
- add sidenav on mobile
- accounts v2
- contact form (with validation)
- Back to top button

View file

@ -6,6 +6,7 @@ import { MealPage } from "./pages/Meal";
import { SearchPage } from "./pages/Search";
import { CategoryListPage } from "./pages/CategoryList";
import { CategoryPage } from "./pages/Category";
import { ContactPage } from "./pages/Contact";
import { NotFoundPage } from "./pages/NotFound";
import { Navbar } from "./components/Navbar";
import { SearchBar } from "./components/SearchBar";
@ -137,6 +138,9 @@ export const App = () => {
searchResults={searchResults}
/>
</Route>
<Route path="/contact">
<ContactPage />
</Route>
<Route path="/404">
<NotFoundPage handleClick={getRandomMeal} />
</Route>

View file

@ -26,7 +26,7 @@ const CategoryEntry = props => {
</div>
<div className="card-stacked">
<div className="card-content black-text">
<h4 className="logo">{strCategory}</h4>
<h2 className="logo">{strCategory}</h2>
{/* <p>{strCategoryDescription}</p> */}
</div>
</div>

View file

@ -0,0 +1,98 @@
import React, { useState } from "react";
export const ContactForm = ({ handleSubmit }) => {
const fields = ["firstname", "lastname", "email", "phone", "message"];
// const [firstName, setFirstName] = useState("");
const onSubmit = ev => {
ev.preventDefault();
handleSubmit(true);
};
// const handleChange = ev => {
// const { value } = ev.target;
// setFirstName(value);
// };
return (
<form onSubmit={onSubmit}>
<div className="row">
<div className="col s12">
<div className="col s12 m6">
<ContactFormInput id="First Name" />
</div>
<div className="col s12 m6">
<ContactFormInput id="Last Name" />
</div>
<div className="col s12 m6">
<ContactFormInput
id="Email"
type="email"
placeholder="jd@mail.com"
/>
</div>
<div className="col s12 m6">
<ContactFormInput id="Phone" placeholder="0123456789" />
</div>
<div className="col s12">
<ContactFormTextArea id="Message" />
<ContactFormSubmit text="Send Message" />
</div>
</div>
</div>
</form>
);
};
const ContactFormInput = ({ id, type = "text" }) => {
return (
<div className="input-field">
{/* <i class="material-icons prefix">account_circle</i> */}
<label for={id}>{id}</label>
<input
className="validate"
type={type}
id={id}
name={id}
// value={value}
// onChange={onChange}
/>
</div>
);
};
const ContactFormTextArea = ({ id }) => {
return (
<div className="input-field">
<label for={id}>{id}</label>
<textarea
className="materialize-textarea validate"
rows="12"
// cols="50"
name={id}
// value={value}
// onChange={onChange}
/>
</div>
);
};
const ContactFormSubmit = ({ text }) => {
return (
<button
className="waves-effect waves-light btn"
type="submit"
name="submit"
>
<i class="material-icons right">send</i> {text}
</button>
);
};
// {fields.map(field => (
// <ContactFormInput
// value={field}
// placeholder={field}
// // onChange={handleChange}
// />
// ))}

View file

@ -4,7 +4,7 @@ import { GitHubLink } from "./GitHubLink";
import { FooterLink } from "./FooterLink";
export const Footer = () => {
const links = ["categories", "random"];
const links = ["categories", "random", "contact"];
return (
<footer className="page-footer">

View file

@ -12,7 +12,7 @@ export const MealPresentation = props => {
return (
<div className="row">
<div className="col s12">
<div className="card blue-grey darken-1">
<div className="card teal darken-1">
<div className="card-content white-text">
<span className="card-title">{mealName}</span>
<img className="responsive-img" src={imgAddress} alt={mealName} />

View file

@ -2,9 +2,10 @@ import React from "react";
import { Logo } from "./Logo";
import { RandomButton } from "./RandomButton";
import { Link } from "react-router-dom";
import { FooterLink } from "./FooterLink";
export const Navbar = props => {
const links = ["categories", "contact"];
return (
<div className="row">
<nav>
@ -12,9 +13,10 @@ export const Navbar = props => {
<div className="container">
<Logo />
<ul id="nav-mobile" className="right hide-on-med-and-down">
<li>
<Link to="/categories">Categories</Link>
</li>
{links.map((link, i) => (
<FooterLink i={i} link={link} />
))}
<li>
<RandomButton
handleClick={props.handleClick}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

1
src/images/mail_sent.svg Normal file
View file

@ -0,0 +1 @@
<svg id="fd577a60-d552-4fe8-bffb-d9cccd3352c0" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="788.38181" height="719" viewBox="0 0 788.38181 719"><defs><linearGradient id="aeee3e51-5d06-43ae-b234-e7a12d326f50" x1="365" y1="605" x2="365" y2="286" gradientUnits="userSpaceOnUse"><stop offset="0" stop-opacity="0.12"/><stop offset="0.55135" stop-opacity="0.09"/><stop offset="1" stop-opacity="0.02"/></linearGradient><linearGradient id="acb63a3b-00bb-44a8-8877-bb0607d49a63" x1="1117.61899" y1="-43.05793" x2="1117.61899" y2="-102.40539" gradientTransform="matrix(-0.64881, 0.76095, 0.76095, 0.64881, 817.40491, -656.85567)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="gray" stop-opacity="0.25"/><stop offset="0.53514" stop-color="gray" stop-opacity="0.12"/><stop offset="1" stop-color="gray" stop-opacity="0.1"/></linearGradient></defs><title>Mail sent</title><polygon points="125 410 0 268 374 0 748 268 621 410 125 410" fill="#ee6e73"/><polygon points="125 410 0 268 374 0 748 268 621 410 125 410" fill="#514abf"/><rect y="286" width="730" height="319" fill="#ee6e73"/><rect y="286" width="730" height="319" fill="url(#aeee3e51-5d06-43ae-b234-e7a12d326f50)"/><polygon points="748 719 0 719 0 268 374 494 748 268 748 719" fill="#ee6e73"/><polygon points="652.582 116.818 573.252 55.99 363.113 330.042 246.402 240.55 185.573 319.879 341.938 439.598 341.938 439.598 382.036 469.649 652.582 116.818" fill="#3ad29f"/><polygon points="3.153 166.882 0.179 168.334 0.521 167.726 0.26 167.81 0.626 167.539 40.653 96.307 61.114 113.753 78.667 130.004 73.627 132.465 79.293 142.459 3.153 166.882" fill="url(#acb63a3b-00bb-44a8-8877-bb0607d49a63)"/><polygon points="59.087 115.617 75.131 130.493 2.411 166.646 41.11 117.046 59.087 115.617" fill="#ee6e73"/><polygon points="59.087 115.617 75.131 130.493 2.411 166.646 41.11 117.046 59.087 115.617" opacity="0.2"/><polygon points="40.373 99.66 2.411 166.646 59.087 115.617 40.373 99.66" fill="#ee6e73"/><polygon points="75.599 142.01 2.489 166.16 63.604 120.539 75.599 142.01" fill="#ee6e73"/><polygon points="686.959 38.73 670.942 66.499 788.382 85.622 712.742 32.949 686.959 38.73" fill="#ee6e73"/><polygon points="686.959 38.73 670.942 66.499 788.382 85.622 712.742 32.949 686.959 38.73" opacity="0.2"/><polygon points="706.247 8.293 788.382 85.622 686.959 38.73 706.247 8.293" fill="#ee6e73"/><polygon points="675.274 82.821 788.062 84.976 682.769 47.576 675.274 82.821" fill="#ee6e73"/></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

23
src/pages/Contact.js Normal file
View file

@ -0,0 +1,23 @@
import React, { useState } from "react";
import { ContactForm } from "../components/ContactForm";
export const ContactPage = props => {
const [isSubmitted, setIsSubmitted] = useState(false);
return isSubmitted ? (
<div className="container center-align">
<img
className="responsive-img"
src={require("../images/mail_sent.svg")}
alt="mail_sent"
width="30%"
/>
<h4>Thank you for your message</h4>
</div>
) : (
<div className="container">
<h1 className="logo">Contact Us</h1>
<ContactForm handleSubmit={setIsSubmitted} />
</div>
);
};