Skip to content
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
45,100 changes: 20,231 additions & 24,869 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 12 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@
"@testing-library/jest-dom": "^5.11.10",
"@testing-library/react": "^11.2.6",
"@testing-library/user-event": "^12.8.3",
"bootstrap": "^5.3.2",
"eslint-config-wesbos": "^3.2.3",
"prop-types": "^15.8.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"react-router-dom": "^6.16.0",
"react-scripts": "^5.0.1",
"web-vitals": "^1.1.1"
},
"scripts": {
Expand All @@ -19,8 +23,7 @@
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
"wesbos"
]
},
"browserslist": {
Expand All @@ -34,5 +37,10 @@
"last 1 firefox version",
"last 1 safari version"
]
}
},
"description": "This project has been created by a student at Parsity, an online software engineering course. The work in this repository is wholly of the student based on a sample starter project that can be accessed by looking at the repository that this project forks.",
"main": "index.js",
"keywords": [],
"author": "",
"license": "ISC"
}
151 changes: 151 additions & 0 deletions src/AddContactForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import PropTypes from 'prop-types';

const AddContactForm = ({ addContact }) => {
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [phone, setPhone] = useState('');
const [image, setImage] = useState('');
const navigate = useNavigate();

function handleNameChange(e) {
setName(e.target.value);
}
function handleEmailChange(e) {
setEmail(e.target.value);
}
function handlePhoneChange(e) {
setPhone(e.target.value);
}
function handleImageChange(e) {
setImage(e.target.value);
}
function handleAddContact() {
const generateId = () => Math.round(Math.random() * 100000000);
const newContact = {
id: generateId(),
name,
email,
phone,
image,
};

// setName('');
// setEmail('');
// setPhone('');
// setImage('');
addContact(newContact);
navigate('/Index');
}

return (
<div className="container">
<nav className="navbar navbar-expand-lg navbar-dark bg-dark">
<div className="container-fluid">
<a className="navbar-brand" href="/">
Home
</a>
<button
className="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon" />
</button>
<div className="collapse navbar-collapse" id="navbarNav">
<ul className="navbar-nav">
<li className="nav-item">
<a
className="nav-link active"
aria-current="page"
href="/AddContact"
>
Add Contact
</a>
</li>
<li className="nav-item">
<a className="nav-link" href="/Index">
Index
</a>
</li>
</ul>
</div>
</div>
</nav>
<div className="row">
<div className="col-md-6 offset-3">
<div className="page-header">
<h1>Add Contact</h1>
<hr />
</div>
<label htmlFor="Full Name" className="form-label">
Full Name
</label>
<input
type="text"
className="form-control"
placeholder="First and Last Name"
value={name}
onChange={handleNameChange}
/>
<br />
</div>
<div className="col-md-6 offset-3">
<label htmlFor="Email Address" className="form-label">
Email Address
</label>
<input
type="text"
className="form-control"
placeholder="Email Address"
value={email}
onChange={handleEmailChange}
/>
<br />
</div>
<div className="col-md-6 offset-3">
<label htmlFor="Phone Number" className="form-label">
Phone Number
</label>
<input
type="text"
className="form-control"
placeholder="Phone Number"
value={phone}
onChange={handlePhoneChange}
/>
<br />
</div>
<div className="col-md-6 offset-3">
<label htmlFor="Image Url" className="form-label">
Image URL
</label>
<input
type="text"
className="form-control"
placeholder="Image URL"
value={image}
onChange={handleImageChange}
/>
<br />
</div>
</div>
<button
type="button"
className="btn btn-dark addcontact2-btn"
onClick={handleAddContact}
>
Add Contact
</button>
</div>
);
};
AddContactForm.propTypes = {
addContact: PropTypes.func.isRequired,
};
export default AddContactForm;
93 changes: 93 additions & 0 deletions src/AllContacts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import PropTypes from 'prop-types';
import { useNavigate } from 'react-router-dom';

function Index({ contacts }) {
const navigate = useNavigate();

const handleRowClick = (contactId) => {
navigate(`${contactId}`);
};

return (
<main>
<div className="container">
<nav className="navbar navbar-expand-lg navbar-dark bg-dark">
<div className="container-fluid">
<a className="navbar-brand" href="/">
Home
</a>

<button
className="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon" />
</button>
<div className="collapse navbar-collapse" id="navbarNav">
<ul className="navbar-nav">
<li className="nav-item">
<a className="nav-link" href="/AddContact">
Add Contact
</a>
</li>
<li className="nav-item">
<a className="nav-link" href="/Index">
Index
</a>
</li>
</ul>
</div>
</div>
</nav>
<h1>Index Page</h1>
<hr />
<div className="container">
<div className="row">
<div className="col-md-10 offset-1">
<table className="table table-bordered table-hover">
<thead className="table-dark">
<tr className="table-active">
<th scope="col">Profile Picture</th>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Phone Number</th>
</tr>
</thead>
<tbody>
{contacts.map((contact) => (
<tr
key={contact.id}
onClick={() => handleRowClick(contact.id)}
>
<td>
<img
src={contact.image}
alt="Profile"
width="200"
height="200"
/>
</td>
<td>{contact.name}</td>
<td>{contact.email}</td>
<td>{contact.phone}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
</div>
</main>
);
}
Index.propTypes = {
contacts: PropTypes.array.isRequired,
};

export default Index;
69 changes: 69 additions & 0 deletions src/ContactPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from 'react';
import PropTypes from 'prop-types';
import { useNavigate, useParams } from 'react-router-dom';

const ContactPage = ({ contacts }) => {
const { id } = useParams();
const contact = contacts.find((c) => c.id === parseInt(id));

const navigate = useNavigate();

const handleButtonclick = () => {
navigate('/Index');
};

if (!contact) {
return (
<div>
<h1>Contact Not Found</h1>
</div>
);
}
return (
<div className="container">
<div className="row">
<div className="col-md-10 offset-1">
<div>
<table className="table table-bordered table-hover">
<thead className="table-dark">
<tr className="table-active">
<th scope="col">Profile Picture</th>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Phone Number</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<img
src={contact.image}
alt="Profile"
width="200"
height="200"
/>
</td>
<td>{contact.name}</td>
<td>{contact.email}</td>
<td>{contact.phone}</td>
</tr>
</tbody>
</table>
</div>
<button
type="button"
className="btn btn-dark "
onClick={() => handleButtonclick()}
>
Back To Contact Index
</button>
</div>
</div>
</div>
);
};
ContactPage.propTypes = {
contacts: PropTypes.array.isRequired,
};

export default ContactPage;
45 changes: 45 additions & 0 deletions src/HomePage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const Home = () => (
<div className="container">
<nav className="navbar navbar-expand-lg navbar-dark bg-dark">
<div className="container-fluid">
<a className="navbar-brand" href="/">
Home
</a>
<button
className="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon" />
</button>
<div className="collapse navbar-collapse" id="navbarNav">
<ul className="navbar-nav">
<li className="nav-item">
<a
className="nav-link active"
aria-current="page"
href="/AddContact"
>
Add Contact
</a>
</li>
<li className="nav-item">
<a className="nav-link" href="/Index">
Index
</a>
</li>
</ul>
</div>
</div>
</nav>
<h1>Contact List Eval</h1>
<hr />
<div />
</div>
);

export default Home;
Loading