Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Danny Solis #2

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions README.md
@@ -1,3 +1,4 @@
# Contact List

A starter repo for the ACA full stack contact list project.
This is for Danny Solis
43 changes: 19 additions & 24 deletions db.json
@@ -1,34 +1,29 @@
{
"contacts": [
{
"_id": 1,
"name": "Dale Cooper",
"occupation": "FBI Agent",
"avatar": "https://upload.wikimedia.org/wikipedia/en/5/50/Agentdalecooper.jpg"
"name": "Soap McTavish",
"avatar": "http://vignette4.wikia.nocookie.net/callofduty/images/b/b7/Soap_MW3_model.png/revision/latest?cb=20120122010801",
"occupation": "British SAS",
"_id": 6
},
{
"_id": 2,
"name": "Spike Spiegel",
"occupation": "Bounty Hunter",
"avatar": "http://vignette4.wikia.nocookie.net/deadliestfiction/images/d/de/Spike_Spiegel_by_aleztron.jpg/revision/latest?cb=20130920231337"
"name": "Lilith",
"avatar": "http://vignette3.wikia.nocookie.net/talesfromtheborderlands/images/7/7e/Lilith.png/revision/latest?cb=20150722060031",
"occupation": "Siren",
"_id": 8
},
{
"_id": 3,
"name": "Wirt",
"occupation": "adventurer",
"avatar": "http://66.media.tumblr.com/5ea59634756e3d7c162da2ef80655a39/tumblr_nvasf1WvQ61ufbniio1_400.jpg"
"name": "Master Chief",
"avatar": "http://img.mota.ru/upload/wallpapers/2011/05/30/10/04/25864/mota_ru_1053028-preview.jpg",
"occupation": "Spartan",
"_id": 10
},
{
"_id": 4,
"name": "Michael Myers",
"occupation": "Loving little brother",
"avatar": "http://vignette2.wikia.nocookie.net/villains/images/e/e3/MMH.jpg/revision/latest?cb=20150810215746"
},
{
"_id": 5,
"name": "Dana Scully",
"occupation": "FBI Agent",
"avatar": "https://pbs.twimg.com/profile_images/718881904834056192/WnMTb__R.jpg"
"name": "Cortana",
"avatar": "https://content.halocdn.com/media/Default/encyclopedia/characters/cortana/cortana-square-542x542-0234af18940e48b1827c1423b5a8ed40-620b1e678f634dd099bba9f3533c560d.jpg",
"occupation": "AI",
"_id": 9
}
]
}
],
"favorites": []
}
34 changes: 34 additions & 0 deletions db.json.ORIGINAL
@@ -0,0 +1,34 @@
{
"contacts": [
{
"_id": 1,
"name": "Dale Cooper",
"occupation": "FBI Agent",
"avatar": "https://upload.wikimedia.org/wikipedia/en/5/50/Agentdalecooper.jpg"
},
{
"_id": 2,
"name": "Spike Spiegel",
"occupation": "Bounty Hunter",
"avatar": "http://vignette4.wikia.nocookie.net/deadliestfiction/images/d/de/Spike_Spiegel_by_aleztron.jpg/revision/latest?cb=20130920231337"
},
{
"_id": 3,
"name": "Wirt",
"occupation": "adventurer",
"avatar": "http://66.media.tumblr.com/5ea59634756e3d7c162da2ef80655a39/tumblr_nvasf1WvQ61ufbniio1_400.jpg"
},
{
"_id": 4,
"name": "Michael Myers",
"occupation": "Loving little brother",
"avatar": "http://vignette2.wikia.nocookie.net/villains/images/e/e3/MMH.jpg/revision/latest?cb=20150810215746"
},
{
"_id": 5,
"name": "Dana Scully",
"occupation": "FBI Agent",
"avatar": "https://pbs.twimg.com/profile_images/718881904834056192/WnMTb__R.jpg"
}
]
}
7 changes: 5 additions & 2 deletions package.json
Expand Up @@ -9,10 +9,12 @@
"react-scripts": "0.7.0"
},
"dependencies": {
"axios": "^0.15.3",
"foreman": "^2.0.0",
"json-server": "^0.9.4",
"react": "^15.3.2",
"react-dom": "^15.3.2"
"react-dom": "^15.3.2",
"react-router": "^4.0.0-beta.6"
},
"scripts": {
"start": "nf start",
Expand All @@ -22,5 +24,6 @@
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
},
"proxy": "http://localhost:4000"
}
1 change: 1 addition & 0 deletions public/index.html
Expand Up @@ -27,5 +27,6 @@
To begin the development, run `npm start`.
To create a production bundle, use `npm run build`.
-->
<script src="https://use.fontawesome.com/9822dc9e23.js"></script>
</body>
</html>
16 changes: 16 additions & 0 deletions src/Activity.js
@@ -0,0 +1,16 @@
import React from 'react';

const Activity = props => {
return (
<div className="activity-log">
<h4>Recent Activity</h4>
<ul className="activity-items">
{props.activity.length > 0 ? props.activity.map(action => {
return <li>{action}</li>
}) : <li>No activity</li>}
</ul>
</div>
)
}

export default Activity;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would like to see the use of propTypes here

19 changes: 13 additions & 6 deletions src/App.js
@@ -1,13 +1,20 @@
import React, { Component } from 'react';
import React, {Component} from "react";
import Profile from "./Profile";
import Contacts from "./Contacts";
import {BrowserRouter, Route, Switch} from "react-router-dom";

class App extends Component {
render() {
return (
<div className="App">
<h1>
Contact List!
</h1>
</div>
<BrowserRouter>
<div className="router">
<Switch>
<Route exact path="/" component={Contacts} />
<Route exact path="/profile/:id" component={Profile} />
<Route render={() => <h2>Not Found!</h2>} />
</Switch>
</div>
</BrowserRouter>
);
}
}
Expand Down
47 changes: 47 additions & 0 deletions src/Contact.js
@@ -0,0 +1,47 @@
import React from 'react';
import { Link } from 'react-router-dom';

class Contact extends React.Component {
constructor() {
super();

this.state = {
confirmDelete: false
};
}

render() {
return (
<Link to={`/profile/${this.props.id}`} className="contact-link">
<li className="contact">
<div className="image-cropper">
<img src={this.props.avatar} alt="avatar"/>
</div>
{this.state.confirmDelete ? <div className="contact-alert">
<h3>Delete this contact? <span onClick={() => this.props.handleDelete(this.props.id, this.props.listName.toString().toLowerCase())}>Yes</span> / <span onClick={() => this.setState({confirmDelete: false})}>No</span></h3>
</div> : <div className="contact-info">
<h2>{this.props.name}</h2>
{this.props.occupation}
</div>
}

<div className="add-start" onClick={() => this.props.handleFav(this.props.id)}>
<span className={this.props.buttonText}></span>
</div>
<div className="add-start" onClick={() => this.setState({confirmDelete: true})}>
<span className="fa fa-minus-square"></span>
</div>
</li>
</Link>
);
}
}

Contact.propTypes = {
id: React.PropTypes.number.isRequired,
avatar: React.PropTypes.string.isRequired,
name: React.PropTypes.string.isRequired,
occupation: React.PropTypes.string.isRequired,
}

export default Contact;
90 changes: 90 additions & 0 deletions src/ContactForm.js
@@ -0,0 +1,90 @@
import React from 'react';

class ContactForm extends React.Component {
constructor() {
super();

this.state = {
name: '',
avatar: '',
occupation: ''
}
}

handleNameChange(event) {
this.setState({
name: event.target.value
});
}

handleOccupationChange(event) {
this.setState({
occupation: event.target.value
});
}

handleAvatarChange(event) {
this.setState({
avatar: event.target.value
});
}

handleSubmit(event) {
event.preventDefault();

const { name, avatar, occupation } = this.state;
this.props.onSubmit({ name, avatar, occupation }, 'contacts');

this.setState({
name: '',
avatar: '',
occupation: ''
});
}

render() {
return (
<div id="form-container">
<span className="fa fa-remove" onClick={() => this.props.hideForm()}></span>
<form className="new-contact-form" onSubmit={this.handleSubmit.bind(this)}>

<input
type="text"
name="name"
placeholder="Name"
value={this.state.name}
onChange={this.handleNameChange.bind(this)}
/>

<input
type="text"
name="occupation"
placeholder="Occupation"
value={this.state.occupation}
onChange={this.handleOccupationChange.bind(this)}
/>

<input
type="text"
name="avatar"
placeholder="Avatar (link)"
value={this.state.avatar}
onChange={this.handleAvatarChange.bind(this)}
/>

<input
type="submit"
value="+ Add New"
disabled={!this.state.name.trim() || !this.state.occupation.trim() || !this.state.avatar.trim()}
/>
</form>
</div>
);
}
}

ContactForm.propTypes = {
onSubmit: React.PropTypes.func.isRequired
};

export default ContactForm;
30 changes: 30 additions & 0 deletions src/ContactList.js
@@ -0,0 +1,30 @@
import React from 'react';
import Contact from './Contact';

const ContactList = props => {
return (
<div className="contact-container">
<ul className="contact-list">
<h1>{props.listName}</h1>
{props.contacts.length > 0 ?
props.contacts.map(contact => {
return (
<Contact
key={contact._id}
id={contact._id}
name={contact.name}
avatar={contact.avatar}
occupation={contact.occupation}
buttonText={props.buttonText}
handleFav={props.handleFav}
handleDelete={props.handleDelete}
listName={props.listName}
/>
)
}) : <h3>No {props.listName.toString().toLowerCase()}</h3>}
</ul>
</div>
);
}

export default ContactList;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would like to see propTypes here also.