Skip to content

Commit

Permalink
stepped
Browse files Browse the repository at this point in the history
  • Loading branch information
wesbos committed Feb 27, 2018
1 parent 65b99e0 commit 69294da
Show file tree
Hide file tree
Showing 16 changed files with 1,043 additions and 324 deletions.
601 changes: 401 additions & 200 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 9 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,19 @@
"react-dom": "^16.3.0-alpha.1",
"react-router-dom": "^4.2.2",
"react-transition-group": "^2.2.1",
"serve": "^6.5.0",
"stylus": "0.54.5"
},
"scripts": {
"start": "react-scripts start",
"watch": "concurrently --names \"webpack, stylus\" --prefix name \"npm run start\" \"npm run styles:watch\"",
"dev": "react-scripts start",
"start": "serve --single ./build",
"watch":
"concurrently --names \"webpack, stylus\" --prefix name \"npm run start\" \"npm run styles:watch\"",
"build": "react-scripts build",
"eject": "react-scripts eject",
"styles": "stylus -u autoprefixer-stylus ./src/css/style.styl -o ./src/css/style.css",
"styles:watch": "stylus -u autoprefixer-stylus -w ./src/css/style.styl -o ./src/css/style.css"
"styles":
"stylus -u autoprefixer-stylus ./src/css/style.styl -o ./src/css/style.css",
"styles:watch":
"stylus -u autoprefixer-stylus -w ./src/css/style.styl -o ./src/css/style.css"
}
}
20 changes: 10 additions & 10 deletions security-rules.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// These are your firebase security rules - put them in the "Security & Rules" tab of your database
{
"rules": {
// won't let people delete an existing room
".write": "!data.exists()",
".read": true,
"$room" : {
// only the store owner can edit the data
".write" : "auth != null && (!data.exists() || data.child('owner').val() === auth.uid)",
".read" : true
}
"rules": {
// won't let people delete an existing room
".write": "!data.exists()",
".read": true,
"$room": {
// only the store owner can edit the data
".write":
"auth != null && (!data.exists() || data.child('owner').val() === auth.uid)",
".read": true
}
}
}

16 changes: 16 additions & 0 deletions src/base.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import Rebase from "re-base";
import firebase from "firebase";

const firebaseApp = firebase.initializeApp({
apiKey: "AIzaSyDXUCNSpi5u07F76httlCTXAA4mPVQlEHs",
authDomain: "catch-of-the-day-wes-bos-2.firebaseapp.com",
databaseURL: "https://catch-of-the-day-wes-bos-2.firebaseio.com"
});

const base = Rebase.createClass(firebaseApp.database());

// This is a named export
export { firebaseApp };

// this is a default export
export default base;
57 changes: 57 additions & 0 deletions src/components/AddFishForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from "react";
import PropTypes from "prop-types";

class AddFishForm extends React.Component {
nameRef = React.createRef();
priceRef = React.createRef();
statusRef = React.createRef();
descRef = React.createRef();
imageRef = React.createRef();

static propTypes = {
addFish: PropTypes.func
};

createFish = event => {
// 1. stop the form from submitting
event.preventDefault();
const fish = {
name: this.nameRef.value.value,
price: parseFloat(this.priceRef.value.value),
status: this.statusRef.value.value,
desc: this.descRef.value.value,
image: this.imageRef.value.value
};
this.props.addFish(fish);
// refresh the form
event.currentTarget.reset();
};
render() {
return (
<form className="fish-edit" onSubmit={this.createFish}>
<input name="name" ref={this.nameRef} type="text" placeholder="Name" />
<input
name="price"
ref={this.priceRef}
type="text"
placeholder="Price"
/>
<select name="status" ref={this.statusRef}>
<option value="available">Fresh!</option>
<option value="unavailable">Sold Out!</option>
</select>

<textarea name="desc" ref={this.descRef} placeholder="Desc" />
<input
name="image"
ref={this.imageRef}
type="text"
placeholder="Image"
/>
<button type="submit">+ Add Fish</button>
</form>
);
}
}

export default AddFishForm;
114 changes: 111 additions & 3 deletions src/components/App.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,125 @@
import React from "react";
import PropTypes from "prop-types";
import Header from "./Header";
import Order from "./Order";
import Inventory from "./Inventory";
import sampleFishes from "../sample-fishes";
import Fish from "./Fish";
import base from "../base";

class App extends React.Component {
state = {
fishes: {},
order: {}
};

static propTypes = {
match: PropTypes.object
};

componentDidMount() {
const { params } = this.props.match;
// first reinstate our localStorage
const localStorageRef = localStorage.getItem(params.storeId);
if (localStorageRef) {
this.setState({ order: JSON.parse(localStorageRef) });
}

this.ref = base.syncState(`${params.storeId}/fishes`, {
context: this,
state: "fishes"
});
}

componentDidUpdate() {
localStorage.setItem(
this.props.match.params.storeId,
JSON.stringify(this.state.order)
);
}

componentWillUnmount() {
base.removeBinding(this.ref);
}

addFish = fish => {
// 1. Take a copy of the existing state
const fishes = { ...this.state.fishes };
// 2. Add our new fish to that fishes variable
fishes[`fish${Date.now()}`] = fish;
// 3. Set the new fishes object to state
this.setState({ fishes });
};

updateFish = (key, updatedFish) => {
// 1. Take a copy of the current state
const fishes = { ...this.state.fishes };
// 2. Update that state
fishes[key] = updatedFish;
// 3. Set that to state
this.setState({ fishes });
};

deleteFish = key => {
// 1. take a copy of state
const fishes = { ...this.state.fishes };
// 2. update the state
fishes[key] = null;
// 3. update state
this.setState({ fishes });
};

loadSampleFishes = () => {
this.setState({ fishes: sampleFishes });
};

addToOrder = key => {
// 1. take a copy of state
const order = { ...this.state.order };
// 2. Either add to the order, or update the number in our order
order[key] = order[key] + 1 || 1;
// 3. Call setState to update our state object
this.setState({ order });
};

removeFromOrder = key => {
// 1. take a copy of state
const order = { ...this.state.order };
// 2. remove that itemf from order
delete order[key];
// 3. Call setState to update our state object
this.setState({ order });
};

render() {
return (
<div className="catch-of-the-day">
<div className="menu">
<Header tagline="Fresh Seafood Market" age={100} />
<Header tagline="Fresh Seafood Market" />
<ul className="fishes">
{Object.keys(this.state.fishes).map(key => (
<Fish
key={key}
index={key}
details={this.state.fishes[key]}
addToOrder={this.addToOrder}
/>
))}
</ul>
</div>
<Order />
<Inventory />
<Order
fishes={this.state.fishes}
order={this.state.order}
removeFromOrder={this.removeFromOrder}
/>
<Inventory
addFish={this.addFish}
updateFish={this.updateFish}
deleteFish={this.deleteFish}
loadSampleFishes={this.loadSampleFishes}
fishes={this.state.fishes}
storeId={this.props.match.params.storeId}
/>
</div>
);
}
Expand Down
69 changes: 69 additions & 0 deletions src/components/EditFishForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from "react";
import PropTypes from "prop-types";

class EditFishForm extends React.Component {
static propTypes = {
fish: PropTypes.shape({
image: PropTypes.string,
name: PropTypes.string,
desc: PropTypes.string,
status: PropTypes.string,
price: PropTypes.number
}),
index: PropTypes.string,
updateFish: PropTypes.func
};
handleChange = event => {
console.log(event.currentTarget.value);
// update that fish
// 1. Take a copy of the curernt fish
const updatedFish = {
...this.props.fish,
[event.currentTarget.name]: event.currentTarget.value
};
this.props.updateFish(this.props.index, updatedFish);
};
render() {
return (
<div className="fish-edit">
<input
type="text"
name="name"
onChange={this.handleChange}
value={this.props.fish.name}
/>
<input
type="text"
name="price"
onChange={this.handleChange}
value={this.props.fish.price}
/>
<select
type="text"
name="status"
onChange={this.handleChange}
value={this.props.fish.status}
>
<option value="available">Fresh!</option>
<option value="unavailable">Sold Out!</option>
</select>
<textarea
name="desc"
onChange={this.handleChange}
value={this.props.fish.desc}
/>
<input
type="text"
name="image"
onChange={this.handleChange}
value={this.props.fish.image}
/>
<button onClick={() => this.props.deleteFish(this.props.index)}>
Remove Fish
</button>
</div>
);
}
}

export default EditFishForm;
38 changes: 38 additions & 0 deletions src/components/Fish.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from "react";
import PropTypes from "prop-types";
import { formatPrice } from "../helpers";

class Fish extends React.Component {
static propTypes = {
details: PropTypes.shape({
image: PropTypes.string,
name: PropTypes.string,
desc: PropTypes.string,
status: PropTypes.string,
price: PropTypes.number
}),
addToOrder: PropTypes.func
};
render() {
const { image, name, price, desc, status } = this.props.details;
const isAvailable = status === "available";
return (
<li className="menu-fish">
<img src={image} alt={name} />
<h3 className="fish-name">
{name}
<span className="price">{formatPrice(price)}</span>
</h3>
<p>{desc}</p>
<button
disabled={!isAvailable}
onClick={() => this.props.addToOrder(this.props.index)}
>
{isAvailable ? "Add To Order" : "Sold Out!"}
</button>
</li>
);
}
}

export default Fish;
5 changes: 5 additions & 0 deletions src/components/Header.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import PropTypes from "prop-types";

const Header = props => (
<header className="top">
Expand All @@ -16,4 +17,8 @@ const Header = props => (
</header>
);

Header.propTypes = {
tagline: PropTypes.string.isRequired
};

export default Header;
Loading

0 comments on commit 69294da

Please sign in to comment.