Skip to content
This repository has been archived by the owner on Jun 28, 2022. It is now read-only.

New start #19

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ Most of the commits in this repository correspond to videos in the program.
Because this is a code-along project and the commits correspond to specific videos in the program, we will not be accepting pull requests.

If you feel like there's a major problem, please open an issue to discuss the problem and potential resolution.

## Contributing

MIT
33,396 changes: 33,396 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

26 changes: 20 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,28 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-scripts": "1.1.1"
"escape-string-regexp": "^5.0.0",
"form-serialize": "^0.7.2",
"prop-types": "^15.8.1",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-router-dom": "^4.3.1",
"react-scripts": "2.1.1",
"sort-by": "^1.2.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
}
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
50 changes: 48 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,56 @@
import React, { Component } from 'react';

import ListContacts from './ListContacts';
import * as ContactsApi from './utils/ContactsAPI'
import { Route } from 'react-router-dom'
import CreateContact from "./createContact";
class App extends Component {

state = {
contacts: []
}
componentDidMount() {
ContactsApi.getAll().then((contacts) => {
this.setState({
contacts
})
})
}

deleteContact = (contact) => {
this.setState((currentState) => ({
contacts: currentState.contacts.filter((c) => {
return c.id !== contact.id
})
}))

ContactsApi.remove(contact)
}

createContact = (contact) => {
ContactsApi.create(contact).then((contact) => {
this.setState((currentState) => ({
contacts: currentState.contacts.concat([contact])
}
))
})
}

render() {
return (
<div>
Hello World
<Route exact path="/" render={() => (
<ListContacts contacts={this.state.contacts} onDeleteContact={this.deleteContact} />
)} >

</Route>
<Route
path="/create" render={({ history }) => (
<CreateContact onCreateContact={(contact) => {
this.createContact(contact)
history.push('/')
}} />)
}
></Route>
</div>
);
}
Expand Down
89 changes: 89 additions & 0 deletions src/ListContacts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Link } from 'react-router-dom'

class ListContacts extends Component {

state = {
query: ''
}
updateQuery = (query) => {
this.setState(() => ({
query: (query !== '' && query.length > 0) ? query.trim() : query
}))
}

static propTypes = {
contacts: PropTypes.array.isRequired,
onDeleteContact: PropTypes.func.isRequired
}

clearQuery() {
this.updateQuery('')
}


render() {
const { contacts, onDeleteContact } = this.props
const { query } = this.state

const showedContacts = query === ''
? contacts
: contacts.filter((c) => (c.name.toLowerCase().includes(query.toLowerCase()))
)

return (
<div className='list-contacts'>
<div className='list-contacts-top'>
<input type="text" className='search-contacts' placeholder='Search contacts' value={query} onChange={(event) => this.updateQuery(event.target.value)}></input>
<Link
to='/create'
className="add-contact"
>
Add Contact
</Link>
</div>
{
showedContacts.length !== contacts.length && (
<div className='showing-contacts'>
<span> Now showing {showedContacts.length} of {contacts.length}
</span>
<button onClick={() => this.clearQuery()}>
Show all
</button>
</div>
)
}
<ol className='contact-list'>
{showedContacts.map((item) =>
(
<li className='contact-list-item' key={item.id}>
<div className='contact-avatar'
style={{
backgroundImage: `url(${item.avatarURL})`
}}
>
</div>
<div className='contact-details'>
<p>
{item.name}
</p>
<p>
@{item.handle}
</p>
</div>
<button className='contact-remove' onClick={() => onDeleteContact(item)} >
</button>
</li>
)
)}
</ol>
</div>

)
}
}



export default ListContacts
39 changes: 39 additions & 0 deletions src/createContact.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import ImageInput from './ImageInput'
import serializeForm from 'form-serialize'
class CreateContact extends Component {
handleOnSubmit = (e) => {
debugger
e.preventDefault();
let values = serializeForm (e.target ,{hash:true})
this.props.onCreateContact(values )
}
render() {

return (
<div>
<Link
className='close-create-contact'
to='/'
>
Close
</Link>
<form onSubmit={this.handleOnSubmit} className='create-contact-form'>
<ImageInput
className='create-contact-avatar-input'
name='avatarURL'
maxHeight={64}
/>
<div className='create-contact-details'>
<input type='text' name='name' placeholder='Name' />
<input type='text' name='handle' placeholder='Handle' />
<button>Add Contact</button>
</div>
</form>
</div>
)
}
}

export default CreateContact
5 changes: 4 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(<App />, document.getElementById('root'));
ReactDOM.render(
<BrowserRouter>
<App /></BrowserRouter>, document.getElementById('root'));
registerServiceWorker();
31 changes: 31 additions & 0 deletions src/utils/ContactsAPI.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const api = process.env.REACT_APP_CONTACTS_API_URL || 'http://localhost:5001'

let token = localStorage.token

if (!token)
token = localStorage.token = Math.random().toString(36).substr(-8)

const headers = {
'Accept': 'application/json',
'Authorization': token
}

export const getAll = () =>
fetch(`${api}/contacts`, { headers })
.then(res => res.json())
.then(data => data.contacts)

export const remove = (contact) =>
fetch(`${api}/contacts/${contact.id}`, { method: 'DELETE', headers })
.then(res => res.json())
.then(data => data.contact)

export const create = (body) =>
fetch(`${api}/contacts`, {
method: 'POST',
headers: {
...headers,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
}).then(res => res.json())
Loading