-
-
Save codecademydev/19f4b67647a2eede2695d3025bb0e69b to your computer and use it in GitHub Desktop.
Codecademy export
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?' /> | |
<button type='submit'>Add Contact</button> | |
</form> | |
); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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