Skip to content

Instantly share code, notes, and snippets.

@codecademydev
Created March 18, 2021 19:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save codecademydev/aafda80f6fd94d8bcba95ee1854a2d1b to your computer and use it in GitHub Desktop.
Save codecademydev/aafda80f6fd94d8bcba95ee1854a2d1b to your computer and use it in GitHub Desktop.
Codecademy export
import React from 'react';
import { Inventory } from '../features/inventory/Inventory.js';
import { CurrencyFilter } from '../features/currencyFilter/CurrencyFilter.js';
import { Cart } from '../features/cart/Cart.js'
// Render the Cart component below <Inventory />
export const App = (props) => {
const { state, dispatch } = props;
return (
<div>
<CurrencyFilter
currencyFilter={state.currencyFilter}
dispatch={dispatch}
/>
<Inventory
inventory={state.inventory}
currencyFilter={state.currencyFilter}
dispatch={dispatch}
/>
<Cart
cart={state.cart}
currencyFilter={state.currencyFilter}
dispatch={dispatch}
/>
</div>
);
};
import React from 'react';
import {
calculateTotal,
getCurrencySymbol,
} from '../../utilities/utilities.js';
import {changeItemQuantity} from './cartSlice.js'
export const Cart = (props) => {
const { cart, currencyFilter, dispatch } = props;
const onInputChangeHandler = (name, input) => {
// If the user enters a bad value...
if (input === '') {
return;
}
// Otherwise, convert the input into a number and pass it along as the newQuantity.
const newQuantity = Number(input);
// Dispatch an action to change the quantity of the given name and quantity.
dispatch(changeItemQuantity(name, newQuantity));
};
// Use the cart and currencyFilter slices to render their data.
const cartElements = Object.keys(cart).map(createCartItem);;
const total = calculateTotal(cart, currencyFilter);
return (
<div id="cart-container">
<ul id="cart-items">{cartElements}
</ul>
<h3 className="total">
Total{' '}
<span className="total-value">
{getCurrencySymbol(currencyFilter)}{total} {currencyFilter}
</span>
</h3>
</div>
);
function createCartItem(name) {
const item = cart[name];
if (item.quantity === 0) {
return;
}
return (
<li key={name}>
<p>{name}</p>
<select
className="item-quantity"
value={item.quantity}
onChange={(e) => {
onInputChangeHandler(name, e.target.value);
}}
>
{[...Array(100).keys()].map((_, index) => (
<option key={index} value={index}>
{index}
</option>
))}
</select>
</li>
);
}
};
export const addItem = (itemToAdd) => {
return {
type: 'cart/addItem',
payload: itemToAdd,
};
};
// Create your changeItemQuantity action creator here.
export const changeItemQuantity = (name, newQuantity) => {
return {
type: 'cart/changeItemQuantity',
payload: {
name: name,
quantity: newQuantity
}
};
};
const initialCart = {};
export const cartReducer = (cart = initialCart, action) => {
switch (action.type) {
case 'cart/addItem': {
const { name, price } = action.payload;
// if the item already exists, increase the quantity by 1, otherwise set it to 1
const quantity = cart[name] ? cart[name].quantity + 1 : 1;
const newItem = { price, quantity };
// Add the new item to the cart (or replace it if it existed already)
return {
...cart,
[name]: newItem
};
}
case 'cart/changeItemQuantity': {
const { name, newQuantity } = action.payload;
const itemToUpdate = cart[name];
const newItem = {
...itemToUpdate,
quantity: newQuantity
}
return {
...cart,
[name]: newItem
};
}
default: {
return {
...cart,
[name]: newItem
};
}
}
};
import React from 'react';
import { currenciesData } from '../../../data.js';
import { setCurrency } from './currencyFilterSlice.js';
export const CurrencyFilter = ({ currencyFilter, dispatch }) => {
const onClickHandler = (currency) => {
dispatch(setCurrency(currency));
};
return (
<div id="currency-filters-container">
<h3>Choose a currency</h3>
{currenciesData.map(createCurrencyButton)}
</div>
);
function createCurrencyButton(currency) {
return (
<button
className={`currency-button ${
currencyFilter === currency && 'selected'
}`}
key={currency}
onClick={() => onClickHandler(currency)}
>
{currency}
</button>
);
}
};
const initialCurrencyFilter = 'USD';
export const currencyFilterReducer = (
currencyFilter = initialCurrencyFilter,
action
) => {
switch (action.type) {
case 'currencyFilter/setCurrency': {
return action.payload;
}
default: {
return currencyFilter;
}
}
};
export const setCurrency = (currency) => {
return {
type: 'currencyFilter/setCurrency',
payload: currency,
};
};
import React from 'react';
import ReactDOM from 'react-dom';
import { App } from './app/App.js';
import { store } from './app/store.js'
// Pass state and dispatch props to the <App /> component.
const render = () => {
ReactDOM.render(
<App
state={store.getState()}
dispatch={store.dispatch}
/>,
document.getElementById('root')
)
};
render();
store.subscribe(render);
import React, { useEffect } from 'react';
import {
calculatePrice,
getCurrencySymbol,
} from '../../utilities/utilities.js';
import { addItem } from '../cart/cartSlice.js';
import { loadData } from './inventorySlice';
export const Inventory = ({ inventory, currencyFilter, dispatch }) => {
const onMount = () => {
dispatch(loadData());
};
useEffect(onMount, [dispatch]);
const onClickHandler = (inventoryItem) => {
dispatch(addItem(inventoryItem));
};
if (inventory.length === 0) {
return <p> Sorry, no products are currently available... </p>;
}
return <ul id="inventory-container">{inventory.map(createInventoryItem)}</ul>;
function createInventoryItem(inventoryItem) {
const { price, name, img } = inventoryItem;
const displayPrice = calculatePrice(price, currencyFilter);
return (
<li key={name} className="item">
<img src={img} alt={''} />
<h3>{name}</h3>
<h3 className="price">
{getCurrencySymbol(currencyFilter)}
{displayPrice.toFixed(2)} {currencyFilter}
</h3>
<button
onClick={() => onClickHandler(inventoryItem)}
className="add-to-cart-button"
>
Add to Cart
</button>
</li>
);
}
};
// Import createStore and combineReducers here.
import { createStore, combineReducers } from 'redux';
// Import the slice reducers here.
import { cartReducer } from '../features/cart/cartSlice.js'
import { inventoryReducer } from '../features/inventory/inventorySlice.js'
import { currencyFilterReducer } from '../features/currencyFilter/currencyFilterSlice.js'
// Create and export the store here.
const reducers={
cart: cartReducer,
inventory: inventoryReducer,
currencyFilter: currencyFilterReducer
}
const rootReducer = combineReducer(reducers);
export const store = createStore(rootReducer);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment