Skip to content
This repository was archived by the owner on Jun 28, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18,254 changes: 18,207 additions & 47 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"escape-string-regexp": "^1.0.5",
"form-serialize": "^0.7.2",
"prop-types": "^15.6.2",
"react": "^16.6.3",
"prop-types": "^15.8.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^4.3.1",
"react-dom": "^16.6.3",
"react-scripts": "2.1.1"
"react-scripts": "^2.1.1",
"sort-by": "^1.2.0"
},
"scripts": {
"start": "react-scripts start",
Expand Down
66 changes: 57 additions & 9 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,61 @@
import React, { Component } from 'react';

class App extends Component {
render() {
return (
<div>
Hello World
</div>
);
import React, {useState, useEffect} from 'react';
import ListContacts from './ListContacts';
import * as ContactsAPI from './utils/ContactsAPI';
import CreateContact from './CreateContact';
import {BrowserRouter as Router, Route, Switch, Redirect} from 'react-router-dom'

function App(props) {

const [contacts, setContacts] = useState([]);

const [contactCreated, setContactCreated] = useState(false)


//or useLayoutEffect

useEffect(()=>{
ContactsAPI.getAll()
.then((contacts) =>{
setContacts(contacts)
})

}, [])

const removeContact = (contact) =>{
const updateContacts = [...contacts]

const removedContacts = updateContacts.filter(c =>{
return (c.id !== contact.id)
})

setContacts(removedContacts) ;

ContactsAPI.remove(contact)
}

const createContact = (contact) =>{
ContactsAPI.create(contact)
.then((contact) => {
const newContacts = [...contacts]
newContacts.push(contact)
setContacts(newContacts)
setContactCreated(true)
})
}

return (

<div>
<Switch>
<Route exact path = "/">
<ListContacts contacts={contacts} removeContact = {removeContact} />
</Route>
<Route path="/create">
{contactCreated ? <Redirect to = "/" /> : <CreateContact onCreateContact = {createContact}/>}
</Route>
</Switch>
</div>
);
}

export default App;
40 changes: 40 additions & 0 deletions src/CreateContact.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from "react";
import { Link } from "react-router-dom";
import ImageInput from "./ImageInput";
import serializeform from "form-serialize"

function CreateContact ({onCreateContact} ){

const handleSubmit=(e)=>{
e.preventDefault();
const values = serializeform(e.target, {
hash: true
})

// if(onCreateContact){
// onCreateContact(values)
// }

onCreateContact(values)
}

return (
<div>
<Link className="close-create-contact" to="/">
CLose
</Link>
<form className="create-contact-form" onSubmit={handleSubmit}>
<ImageInput className="create-contact-avatar-input" name="avatarURL" maxHeigt={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;
33 changes: 33 additions & 0 deletions src/ListContacts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import { Link } from 'react-router-dom'

function ListContacts({contacts, removeContact}) {

return (

<div className="list-contacts">
<div className="list-contacts-top">
<Link to="/create" className='add-contact'>Add Contact</Link>
</div>
<ol className="contact-list">
{contacts.map(contact => (
<li key={contact.id} className="contact-list-item">
<div className="contact-avatar" style={{backgroundImage: `url(${contact.avatarURL})`}}>
</div>
<div className="contact-details">
<p>{contact.name}</p>
<p>{contact.handle}</p>
</div>
<button className="contact-remove" onClick={() => removeContact(contact)} name = {contact}>
Remove
</button>
</li>
))}
</ol>

</div>

)
}

export default ListContacts ;
17 changes: 12 additions & 5 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
html {
box-sizing: border-box;
}
*, *:before, *:after {
*,
*:before,
*:after {
box-sizing: inherit;
}
html, body, .root {
html,
body,
.root {
height: 100%;
}
body {
Expand All @@ -13,7 +17,8 @@ body {
font-family: sans-serif;
line-height: 1.5;
}
body, .app {
body,
.app {
background: #f5f5f5;
}

Expand Down Expand Up @@ -63,7 +68,6 @@ body, .app {
outline: 0;
}


.create-contact-details button {
margin-top: 20px;
background: #ccc;
Expand All @@ -82,9 +86,12 @@ body, .app {
.list-contacts-top {
position: fixed;
width: 100%;
height: 30px;
top: 0;
border-bottom: 1px solid #d5d8df;
display: flex;

/* border: 2px solid red; */
}

.search-contacts {
Expand Down Expand Up @@ -185,4 +192,4 @@ body, .app {
vertical-align: middle;
cursor: pointer;
outline: none;
}
}
7 changes: 6 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter, Router} from 'react-router-dom'
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

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