-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
637 additions
and
47 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,76 @@ | ||
export const App = () => { | ||
return ( | ||
<div | ||
style={{ | ||
height: '100vh', | ||
display: 'flex', | ||
justifyContent: 'center', | ||
alignItems: 'center', | ||
fontSize: 40, | ||
color: '#010101' | ||
}} | ||
> | ||
React homework template | ||
</div> | ||
); | ||
}; | ||
import React, { Component } from 'react'; | ||
import { nanoid } from 'nanoid'; | ||
|
||
import { Section } from './Section/Section'; | ||
import { ContactForm } from './ContactForm/ContactForm'; | ||
import { ContactList } from './ContactList/ContactList'; | ||
import { Filter } from './Filter/Filter'; | ||
|
||
export class App extends Component { | ||
|
||
state = { | ||
contacts: [ | ||
{ id: 'id-1', name: 'Rosie Simpson', number: '459-12-56' }, | ||
{ id: 'id-2', name: 'Hermione Kline', number: '443-89-12' }, | ||
{ id: 'id-3', name: 'Eden Clements', number: '645-17-79' }, | ||
{ id: 'id-4', name: 'Annie Copeland', number: '227-91-26' }, | ||
], | ||
filter: '', | ||
}; | ||
|
||
formSubmit = ({ name, number }) => { | ||
const contact = { id: nanoid(), name, number }; | ||
|
||
if (this.state.contacts.some(e => e.name === name)) { | ||
|
||
return alert(`${name} is already in contacts!`); | ||
} | ||
|
||
this.setState(({ contacts }) => ({ contacts: [contact, ...contacts] })); | ||
}; | ||
|
||
getFilteredContacts = () => { | ||
const { contacts, filter } = this.state; | ||
const filterContactsList = contacts.filter(contact => { | ||
|
||
return contact.name.toLowerCase().includes(filter.toLowerCase()); | ||
}); | ||
|
||
return filterContactsList; | ||
}; | ||
|
||
filterList = evt => { | ||
const { name, value } = evt.target; | ||
|
||
this.setState({ [name]: value }); | ||
}; | ||
|
||
deleteContact = contactId => { | ||
|
||
this.setState(prevState => ({ | ||
contacts: prevState.contacts.filter(contact => contact.id !== contactId), | ||
})); | ||
}; | ||
|
||
render() { | ||
const {filter} = this.state; | ||
|
||
return ( | ||
<div> | ||
<h1> | ||
Phonebook | ||
</h1> | ||
<Section title="Phonebook"> | ||
<ContactForm onSubmit={this.formSubmit} /> | ||
</Section> | ||
<Section title="Contacts"> | ||
<Filter value={filter} onChange={this.filterList} /> | ||
<ContactList | ||
contacts={this.getFilteredContacts()} | ||
deleteContact={this.deleteContact} | ||
/> | ||
</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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import React, { Component } from 'react'; | ||
import { nanoid } from 'nanoid'; | ||
import PropTypes from 'prop-types'; | ||
|
||
import { Form, Label, Input, ButtonForm } from './ContactForm.styled'; | ||
|
||
export class ContactForm extends Component { | ||
state = { | ||
name: '', | ||
number: '', | ||
}; | ||
|
||
NameInputId = nanoid(); | ||
NumberInputId = nanoid(); | ||
|
||
handleInputChange = evt => { | ||
const { name, value } = evt.currentTarget; | ||
this.setState({ [name]: value }); | ||
}; | ||
|
||
handleSubmit = evt => { | ||
evt.preventDefault(); | ||
this.props.onSubmit(this.state); | ||
this.reset(); | ||
}; | ||
|
||
reset = () => { | ||
this.setState({ name: '', number: '' }); | ||
}; | ||
|
||
render() { | ||
return ( | ||
<Form onSubmit={this.handleSubmit}> | ||
<Label htmlFor={this.NameInputId}> | ||
Name | ||
<Input | ||
onChange={this.handleInputChange} | ||
value={this.state.name} | ||
type="text" | ||
name="name" | ||
placeholder="Name" | ||
id={this.NameInputId} | ||
pattern="^[a-zA-Zа-яА-Я]+(([' -][a-zA-Zа-яА-Я ])?[a-zA-Zа-яА-Я]*)*$" | ||
title="Name may contain only letters, apostrophe, dash and spaces. For example Adrian, Jacob Mercer, Charles de Batz de Castelmore d'Artagnan" | ||
required | ||
/> | ||
</Label> | ||
<Label htmlFor={this.NumberInputId}> | ||
Number | ||
<Input | ||
value={this.state.number} | ||
onChange={this.handleInputChange} | ||
type="tel" | ||
name="number" | ||
placeholder="Number" | ||
id={this.NumberInputId} | ||
pattern="\+?\d{1,4}?[-.\s]?\(?\d{1,3}?\)?[-.\s]?\d{1,4}[-.\s]?\d{1,4}[-.\s]?\d{1,9}" | ||
title="Phone number must be digits and can contain spaces, dashes, parentheses and can start with +" | ||
required | ||
/> | ||
</Label> | ||
<ButtonForm type="submit">Add contact</ButtonForm> | ||
</Form> | ||
); | ||
} | ||
} | ||
ContactForm.propTypes = { | ||
name: PropTypes.string, | ||
value: PropTypes.string, | ||
handleSubmit: PropTypes.func, | ||
handleInputChange: PropTypes.func, | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import styled from 'styled-components'; | ||
|
||
export const Form = styled.form` | ||
margin: 0 auto; | ||
border: 1px solid black; | ||
width: 320px; | ||
padding: 30px; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: flex-start; | ||
gap: 30px; | ||
`; | ||
export const Label = styled.label` | ||
display: flex; | ||
flex-direction: column; | ||
align-items: flex-start; | ||
gap: 12px; | ||
font-size: 20px; | ||
font-weight: 600; | ||
`; | ||
export const Input = styled.input` | ||
width: 300px; | ||
height: 24px; | ||
outline: transparent; | ||
padding: 0 8px; | ||
border: 1px solid #000; | ||
&:hover, | ||
&:focus { | ||
border: 2px solid #92a8d1; | ||
} | ||
`; | ||
export const ButtonForm = styled.button` | ||
padding: 6px; | ||
font-size: 18px; | ||
cursor: pointer; | ||
border: transparent; | ||
border: 1px solid black; | ||
&:hover, | ||
&:focus { | ||
background: #92a8d1; | ||
} | ||
`; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import React from 'react'; | ||
import propTypes from 'prop-types'; | ||
import { | ||
ContactListUl, | ||
ContactListLi, | ||
ButtonDelete, | ||
} from './ContactList.styled'; | ||
import { FcPhoneAndroid } from 'react-icons/fc'; | ||
|
||
export const ContactList = ({ contacts, deleteContact }) => ( | ||
<ContactListUl> | ||
{contacts.map((contact, id) => ( | ||
<ContactListLi key={id}> | ||
<FcPhoneAndroid /> | ||
{contact.name}: {contact.number} | ||
<ButtonDelete type="button" onClick={() => deleteContact(contact.id)}> | ||
Delete | ||
</ButtonDelete> | ||
</ContactListLi> | ||
))} | ||
</ContactListUl> | ||
); | ||
ContactList.propTypes = { | ||
deleteContact: propTypes.func.isRequired, | ||
contacts: propTypes.arrayOf( | ||
propTypes.exact({ | ||
id: propTypes.string.isRequired, | ||
name: propTypes.string.isRequired, | ||
number: propTypes.string.isRequired, | ||
}) | ||
), | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import styled from 'styled-components'; | ||
|
||
export const ContactListUl = styled.ul` | ||
font-size: 24px; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
padding: 0; | ||
`; | ||
export const ContactListLi = styled.li` | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
border: 1px solid black; | ||
list-style-position: inside; | ||
width: 450px; | ||
padding: 20px; | ||
&:not(:last-child) { | ||
margin-bottom: 5px; | ||
} | ||
`; | ||
export const ButtonDelete = styled.button` | ||
margin-left: 18px; | ||
font-size: 18px; | ||
cursor: pointer; | ||
`; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import propTypes from 'prop-types'; | ||
import { FilterLabel, FilterInput } from './Filter.styled'; | ||
|
||
export const Filter = ({ value, onChange }) => ( | ||
<FilterLabel> | ||
Find contacts by Name | ||
<FilterInput | ||
type="text" | ||
name="filter" | ||
placeholder="Search contact" | ||
value={value} | ||
onChange={onChange} | ||
/> | ||
</FilterLabel> | ||
); | ||
|
||
Filter.propTypes = { | ||
value: propTypes.string.isRequired, | ||
onChange: propTypes.func.isRequired, | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import styled from 'styled-components'; | ||
|
||
export const FilterLabel = styled.label` | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
margin-bottom: 30px; | ||
gap: 12px; | ||
font-size: 20px; | ||
font-weight: 600; | ||
`; | ||
|
||
export const FilterInput = styled.input` | ||
width: 300px; | ||
height: 24px; | ||
outline: transparent; | ||
padding: 0 8px; | ||
border: 1px solid #000; | ||
&:hover, | ||
&:focus { | ||
border: 2px solid #92a8d1; | ||
} | ||
`; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
import { SectionContainer, Title } from './Section.styled'; | ||
|
||
export const Section = ({ title, children }) => ( | ||
<SectionContainer> | ||
<Title>{title}</Title> | ||
{children} | ||
</SectionContainer> | ||
); | ||
|
||
Section.propTypes = { | ||
title: PropTypes.string.isRequired, | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import styled from 'styled-components'; | ||
|
||
export const SectionContainer = styled.section` | ||
width: 80vw; | ||
padding: 20px; | ||
text-align: center; | ||
`; | ||
export const Title = styled.h2` | ||
font-size: 34px; | ||
margin-bottom: 30px; | ||
color: #034f84; | ||
`; |
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