Skip to content

Instantly share code, notes, and snippets.

@codecademydev
Created January 23, 2022 22:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codecademydev/19f4b67647a2eede2695d3025bb0e69b to your computer and use it in GitHub Desktop.
Save codecademydev/19f4b67647a2eede2695d3025bb0e69b to your computer and use it in GitHub Desktop.
Codecademy export
import React, { useState } from "react";
import { Switch, Route, Redirect, NavLink } from "react-router-dom";
import { AppointmentsPage } from "./containers/appointmentsPage/AppointmentsPage";
import { ContactsPage } from "./containers/contactsPage/ContactsPage";
function App() {
/*
Define state variables for
contacts and appointments
*/
const [ contacts, setContacts ] = useState([]);
const [ appointments, setAppointments ] = useState([]);
const ROUTES = {
CONTACTS: "/contacts",
APPOINTMENTS: "/appointments",
};
/*
Implement functions to add data to
contacts and appointments
*/
const addContact = (name, phone, email) => {
const newContact = {
name: name,
phone: phone,
email: email
}
setContacts([...contacts, newContact]);
}
const addAppointment = (title, contact, date, time) => {
const newAppointment = {
title: title,
contact: contact,
date: date,
time: time
}
setAppointments([...appointments, newAppointment]);
}
return (
<>
<nav>
<NavLink to={ROUTES.CONTACTS} activeClassName="active">
Contacts
</NavLink>
<NavLink to={ROUTES.APPOINTMENTS} activeClassName="active">
Appointments
</NavLink>
</nav>
<main>
<Switch>
<Route path={ROUTES.CONTACTS}>
{/* Add props to ContactsPage */}
<ContactsPage contacts={contacts} addContact={addContact} />
</Route>
<Route path={ROUTES.APPOINTMENTS}>
{/* Add props to AppointmentsPage */}
<AppointmentsPage
contacts={contacts}
appointments={appointments}
addAppointment={addAppointment}/>
</Route>
</Switch>
</main>
</>
);
}
export default App;
import React from "react";
import { ContactPicker } from '../contactPicker/ContactPicker';
export const AppointmentForm = ({
contacts,
title,
setTitle,
contact,
setContact,
date,
setDate,
time,
setTime,
handleSubmit
}) => {
const getTodayString = () => {
const [month, day, year] = new Date()
.toLocaleDateString("en-US")
.split("/");
return `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`;
};
const contactNames = () => {
return contacts.map(contact => contact.name);
};
return (
<form onSubmit={handleSubmit}>
<input
type='text'
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder='Appointment Title'
required />
<ContactPicker
contactNames={contactNames()}
value={contact}
onChange={(e) => setContact(e.target.value)} />
<input
type='date'
value={date}
onChange={(e) => setDate(e.target.value)}
placeholder='Date'
required
min={getTodayString()} />
<input
type='time'
value={time}
onChange={(e) => setTime(e.target.value)}
placeholder='Time'
required />
<button type='submit'>Add Appointment</button>
</form>
);
};
import React, { useState } from "react";
import { TileList } from '../../components/tileList/TileList';
import { AppointmentForm } from '../../components/appointmentForm/AppointmentForm';
export const AppointmentsPage = ({contacts, appointments, addAppointment}) => {
/*
Define state variables for
appointment info
*/
const [ title, setTitle ] = useState('');
const [ contact, setContact ] = useState('');
const [ date, setDate ] = useState('');
const [ time, setTime ] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
/*
Add contact info and clear data
*/
addAppointment(title, contact, date, time);
setTitle('');
setContact('');
setDate('');
setTime('');
};
return (
<div>
<section>
<h2>Add Appointment</h2>
<AppointmentForm
title={title} setTitle={setTitle}
contact={contact} setContact={setContact}
date={date} setDate={setDate}
time={time} setTime={setTime}
contacts={contacts}
handleSubmit={handleSubmit} />
</section>
<hr />
<section>
<h2>Appointments</h2>
<TileList tiles={appointments} />
</section>
</div>
);
};
import React from "react";
export const ContactForm = ({
name,
setName,
phone,
setPhone,
email,
setEmail,
handleSubmit
}) => {
return (
<form onSubmit={handleSubmit}>
<input
type='text'
value={name}
onChange={(e) => setName(e.target.value)}
placeholder='Contact Name'
required />
<input
type='tel'
value={phone}
onChange={(e) => setPhone(e.target.value)}
placeholder='Phone Number'
required
pattern='^(\(?\+?[0-9]*\)?)?[0-9_\- \(\)]*$' />
<input
type='email'
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder='Email Address'
required
pattern='(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?' />
<button type='submit'>Add Contact</button>
</form>
);
};
import React from "react";
export const ContactPicker = ({contactNames, onChange}) => {
return (
<select onChange={onChange}>
<option selected='selected' value='' key={-1}>
Select a Contact</option>
{contactNames.map((contact) => {
return (
<option value={contact} key={contact}>
{contact}
</option>
);
})}
</select>
);
};
import React, { useState, useEffect } from "react";
import { ContactForm } from '../../components/contactForm/ContactForm';
import { TileList } from '../../components/tileList/TileList';
export const ContactsPage = ({contacts, addContact}) => {
/*
Define state variables for
contact info and duplicate check
*/
const [ name, setName ] = useState('');
const [ phone, setPhone ] = useState('');
const [ email, setEmail ] = useState('');
const [ duplicate, setDuplicate ] = useState(false);
const handleSubmit = (e) => {
e.preventDefault();
/*
Add contact info and clear data
if the contact name is not a duplicate
*/
if(!duplicate) {
addContact(name, phone, email);
setName('');
setPhone('');
setEmail('');
setDuplicate(false);
}
};
/*
Using hooks, check for contact name in the
contacts array variable in props
*/
useEffect(() => {
const match = contacts.filter(contact => contact.name === name);
if(match.length > 0) {
setDuplicate(true);
} else {
setDuplicate(false);
}
},[name, contacts, duplicate]);
return (
<div>
<section>
<h2>Add Contact</h2>
{duplicate ? <p style={{color:'red', fontSize: 14}}>{`${name} is already in the contact list`}</p> : null}
<ContactForm
name={name} setName={setName}
phone={phone} setPhone={setPhone}
email={email} setEmail={setEmail}
handleSubmit={handleSubmit} />
</section>
<hr />
<section>
<h2>Contacts</h2>
<TileList tiles={contacts}/>
</section>
</div>
);
};
import React from "react";
import { Tile } from '../tile/Tile';
export const TileList = ({tiles}) => {
return (
<div>
{tiles.map((tile, index) => (
<Tile tile={tile} key={index}/>
))}
</div>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment