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
21 changes: 21 additions & 0 deletions ANSWERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[ ] Explain what a token is used for.

A token is used to authenticate a user to ensure they are who they claim to be. This allows the user access to otherwise restricted areas of the site.


- [ ] What steps can you take in your web apps to keep your data secure?

You can set up protected routes so certain pages can't be accessed w/o tokens. Store api keys securely.


- [ ] Describe how web servers work.

A web server holds data for websites and communicates with the client through HTTP. When a user inputs a domain name into the browser, the client sends a request to the server to display a webpage. The server then gets the request and delvers the webpage to the client.


- [ ] Which HTTP methods can be mapped to the CRUD acronym that we use when interfacing with APIs/Servers.

Create: (Post)Request- add new data
Read: (Get)Request- retrieve data
Update: (Put)Request- update data
Delete: (Delete)Request- delete data
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,24 +36,24 @@ Demonstrate your understanding of this Sprint's concepts by answering the follow

Follow these steps to set up and work on your project:

- [ ] Create a forked copy of this project.
- [ ] Add PM as collaborator on Github.
- [ ] Clone your OWN version of Repo (Not Lambda's by mistake!).
- [ ] Create a new Branch on the clone: git checkout -b `<firstName-lastName>`.
- [ ] Implement the project on this Branch, committing changes regularly.
- [ ] Push commits: git push origin `<firstName-lastName>`.
- [ ] **RUN** `npm install` at the root to retrieve all the dependencies for the node server. You will not need to create any react apps here nor will you need to install any other dependencies. You should have all you need in this repo.
- [ ] **LOOK** at all the files you've been given for this project. One important file to note is `server.js`. This file contains an **API** that you are going to be interfacing with. Below is documentation on how to interact with the **API**.
- [ ] **RUN** `npm start` to get your API up and running on `http://localhost:5000`. This is the **URL** you're going to need to use within your React app in order to make AJAX requests for data.
- [ ] **LOOK** at your `client` directory and notice it's just a plain ol' React App that we've built using `create-react-app`.
- [ ] **cd** into `client` and run `npm install` to retrieve the client side dependencies.
- [ ] **RUN** `npm start` to fire up your React application.
- [x] Create a forked copy of this project.
- [x] Add PM as collaborator on Github.
- [x] Clone your OWN version of Repo (Not Lambda's by mistake!).
- [x] Create a new Branch on the clone: git checkout -b `<firstName-lastName>`.
- [x] Implement the project on this Branch, committing changes regularly.
- [x] Push commits: git push origin `<firstName-lastName>`.
- [x] **RUN** `npm install` at the root to retrieve all the dependencies for the node server. You will not need to create any react apps here nor will you need to install any other dependencies. You should have all you need in this repo.
- [x] **LOOK** at all the files you've been given for this project. One important file to note is `server.js`. This file contains an **API** that you are going to be interfacing with. Below is documentation on how to interact with the **API**.
- [x] **RUN** `npm start` to get your API up and running on `http://localhost:5000`. This is the **URL** you're going to need to use within your React app in order to make AJAX requests for data.
- [x] **LOOK** at your `client` directory and notice it's just a plain ol' React App that we've built using `create-react-app`.
- [x] **cd** into `client` and run `npm install` to retrieve the client side dependencies.
- [x] **RUN** `npm start` to fire up your React application.

Follow these steps for completing your project:

- [ ] Submit a Pull-Request to merge <firstName-lastName> Branch into master (student's Repo).
- [ ] Add your Project Manager as a Reviewer on the Pull-request
- [ ] PM then will count the HW as done by merging the branch back into master.
- [x] Submit a Pull-Request to merge <firstName-lastName> Branch into master (student's Repo).
- [x] Add your Project Manager as a Reviewer on the Pull-request
- [x] PM then will count the HW as done by merging the branch back into master.

## Minimum Viable Product

Expand Down
15 changes: 8 additions & 7 deletions client/src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React, { useState } from "react";
import { BrowserRouter as Router, Route } from "react-router-dom";
import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import PrivateRoute from "./components/PrivateRoute";
import BubblePage from "./components/BubblePage";

import Login from "./components/Login";
import "./styles.scss";
Expand All @@ -8,11 +10,10 @@ function App() {
return (
<Router>
<div className="App">
<Route exact path="/" component={Login} />
{/*
Build a PrivateRoute component that will
display BubblePage when you're authenticated
*/}
<Switch>
<Route exact path="/" component={Login} />
<PrivateRoute exact path="/bubbles" component={BubblePage} />
</Switch>
</div>
</Router>
);
Expand Down
20 changes: 19 additions & 1 deletion client/src/components/BubblePage.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
import React, { useState, useEffect } from "react";
import axios from "axios";
import axiosWithAuth from "./axiosWithAuth";

import Bubbles from "./Bubbles";
import ColorList from "./ColorList";


//Stage 2 - Consuming the API

//Step 2a: When `BubblePages` renders, make a GET request to fetch the color data for your bubbles.


const BubblePage = () => {
const [colorList, setColorList] = useState([]);
// fetch your colors data from the server when the component mounts
// set that data to the colorList state property

useEffect(() => {
axiosWithAuth()
.get(`http://localhost:5000/api/colors`)
.then(response => {
// console.log(res)
setColorList(response.data)
})
.catch(err => console.log(err));

}, [])


return (
<>
<ColorList colors={colorList} updateColors={setColorList} />
Expand Down
3 changes: 3 additions & 0 deletions client/src/components/Bubbles.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import React, { useState, useEffect } from "react";
import { Pack } from "@potion/layout";
import { Svg, Circle } from "@potion/element";

//Step 2c: Watch and enjoy as your app responds to updates in the data. Check out `Bubbles.js` to see how this is built.


const Bubbles = ({ colors }) => {
const [bubbleData, setBubbleData] = useState([]);
useEffect(() => {
Expand Down
41 changes: 35 additions & 6 deletions client/src/components/ColorList.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import React, { useState } from "react";
import axios from "axios";
import axiosWithAuth from "./axiosWithAuth";

const initialColor = {
color: "",
code: { hex: "" }
};

//Step 2b: In `ColorList.js`, complete the `saveEdit` and `deleteColor`
//functions to make AJAX requests to the API to edit/delete data


const ColorList = ({ colors, updateColors }) => {
console.log(colors);
const [editing, setEditing] = useState(false);
Expand All @@ -16,17 +20,41 @@ const ColorList = ({ colors, updateColors }) => {
setColorToEdit(color);
};

//PUT request
const saveEdit = e => {
e.preventDefault();
//console.log(colorToEdit)
// Make a put request to save your updated color
// think about where will you get the id from...
// where is is saved right now?
axiosWithAuth()
.put(`http://localhost:5000/api/colors/${colorToEdit.id}`, colorToEdit)
.then(updateColorList())
.catch(error => console.log(error.response));

};

//GET request
const updateColorList = () => {
axiosWithAuth()
.get("http://localhost:5000/api/colors")
.then(response => {
updateColors(response.data);
});
};


//DELETE request
const deleteColor = color => {
// make a delete request to delete this color
// console.log(color)
axiosWithAuth()
.delete(`http://localhost:5000/api/colors/${color.id}`)
.then(updateColorList())
.catch(err => console.log(err.response));
};


return (
<div className="colors-wrap">
<p>colors</p>
Expand All @@ -35,11 +63,11 @@ const ColorList = ({ colors, updateColors }) => {
<li key={color.color} onClick={() => editColor(color)}>
<span>
<span className="delete" onClick={e => {
e.stopPropagation();
deleteColor(color)
}
}>
x
e.stopPropagation();
deleteColor(color)
}
}>
x
</span>{" "}
{color.color}
</span>
Expand Down Expand Up @@ -86,4 +114,5 @@ const ColorList = ({ colors, updateColors }) => {
);
};


export default ColorList;
55 changes: 52 additions & 3 deletions client/src/components/Login.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,63 @@
import React from "react";
import React, { useState } from "react";
import axiosWithAuth from './axiosWithAuth';

const Login = () => {

// Stage 1 - Authentication
// Build a login form to authenticate your users.


const Login = (props) => {
// make a post request to retrieve a token from the api
// when you have handled the token, navigate to the BubblePage route

const [login, setLogin] = useState({ username: "", password: "" });

const handleLogin = event => {
setLogin({ ...login, [event.target.name]: event.target.value });
};

//Step 1a: Construct an AXIOS request to retrieve a token from the server. You'll use this token to interact with the API
//Step 1b: Save the token to localStorage

//POST request
const handleSubmit = event => {
event.preventDefault();
axiosWithAuth()
.post("/api/login", login)
.then(response => {
localStorage.setItem("token", response.data.payload);
props.history.push("/bubbles")
})
.catch(error => console.log(error.response));
};


return (
<>
<h1>Welcome to the Bubble App!</h1>
<p>Build a login page here</p>
<form onSubmit={handleSubmit}>
<input
type="text"
name="username"
placeholder="username"
value={login.username}
onChange={handleLogin}
/>
<input
type="password"
name="password"
placeholder="password"
value={login.password}
onChange={handleLogin}
/>
<button>Log in</button>
</form>
</>
);
};





export default Login;
23 changes: 23 additions & 0 deletions client/src/components/PrivateRoute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from "react";
import { Route, Redirect } from "react-router-dom";


//Step 1d: Build a `PrivateRoute` component and use it to protect a route that renders the `BubblesPage` component


const PrivateRoute = ({ component: Component, ...rest }) => {
return (
<Route
{...rest}
render={props => {
if (localStorage.getItem("token")) {
return <Component {...props} />;
} else {
return <Redirect to="/login" />;
}
}}
/>
);
};

export default PrivateRoute;
15 changes: 15 additions & 0 deletions client/src/components/axiosWithAuth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import axios from 'axios';

//Step 1c: Build a `axiosWithAuth` module to create an instance of axios with the authentication header

export const axiosWithAuth = () => {
const token = localStorage.getItem("token")
return axios.create({
baseURL: "http://localhost:5000",
headers: {
Authorization: token
}
});
};

export default axiosWithAuth;
2 changes: 1 addition & 1 deletion client/src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

Expand Down