keep in memory a data of an API with React.js - javascript

I try to keep in mind by refreshing the page the price of a product. The default value of this price comes from data retrieved from an API and I would like with an input text to change this price and keep it at the refresh of the page. I tried with localStorage so it retrieves the new price in the console application but when I refresh the page the price remains the default one and not the new price put in the input
I leave you my code below and I thank you in advance for your explanations
ProductsDetails :
import React, { Component } from 'react'
import '../css/ProductsDetails.css'
import {AiOutlineArrowLeft} from "react-icons/ai";
import {Link} from 'react-router-dom'
export default class ProductsDetails extends Component {
constructor(props) {
super(props);
this.state = {
id: this.props.match.params.id,
price: 0
};
}
updatePrice = (e) => {
localStorage.setItem('price', e.target.value)
this.setState({
price: e.target.value
});
};
submitHandler = (e) => {
e.preventDefault();
const {
match: {
params: { id }
}
} = this.props;
this.props.updatePrice(id, this.state.price);
};
componentDidMount() {
const price = localStorage.getItem('price')
this.setState({price});
}
render() {
const {
match: {
params: { id }
},
products
} = this.props;
const listProduct = products.find((product) => product.id === Number(id))
if (!listProduct) return null;
return (
<div className="products__details">
<Link to="/">
<AiOutlineArrowLeft className="nav__arrow" />
</Link>
<h1 className="details__title">{listProduct.title}</h1>
<div className="details__align--desk">
<div className="details__img">
<img
className="product__img"
src={listProduct.image}
alt="Affichage du produit"
/>
</div>
<div className="products__align--desk">
<h2 className="product__title">Description</h2>
<p className="product__description">{listProduct.description}</p>
<h2 className="product__title">Price</h2>
<form className="form__price" onSubmit={this.submitHandler}>
<input
name="price"
className="input__price"
type="text"
defaultValue={Number(listProduct.price).toFixed(2)}
onChange={this.updatePrice}
/>
<p>
Price (including VAT):{" "}
{Number(listProduct.price * 1.2).toFixed(2)} €
</p>
<br />
<input
className="btn__update"
type="submit"
value="Update product"
/>
</form>
</div>
<div className="category__align--desk">
<h2 className="product__title">Category</h2>
<p className={`${listProduct.category==="men's clothing" ? "category__orange" : "category__green"} product__category`}>{listProduct.category}</p>
</div>
</div>
</div>
);
}
}
Products :
import React, { Component } from 'react';
import '../css/Products.css';
import './ProductsDetails'
import {Link} from 'react-router-dom'
export default class Products extends Component {
render() {
const listsProducts = this.props.products.map((listProduct) => {
return (
<tbody className="products__body" key={listProduct.id}>
<tr>
<td><Link to={{pathname: "/products-details/" + listProduct.id}}>{listProduct.title}</Link></td>
<td><p className={`${listProduct.category==="men's clothing" ? "category__orange" : "category__green"}`}>{listProduct.category}</p></td>
<td>{Number(listProduct.price).toFixed(2)}</td>
<td>
{Number(listProduct.price * 1.2).toFixed(2)} €
</td>
</tr>
</tbody>
);
});
return (
<main className="products">
<h1 className="products__title">Products management</h1>
<table cellSpacing="0">
<thead className="products__head">
<tr>
<th className="table--title">Product name</th>
<th className="table--title">Category</th>
<th className="table--title">Price</th>
<th className="table--title">Price (including VAT)</th>
</tr>
</thead>
{listsProducts}
</table>
</main>
);
}
}
App :
import React, { useState, useEffect } from 'react';
import './css/App.css';
import './css/Products.css';
import axios from 'axios';
import {Oval} from 'react-loading-icons'
import Navigation from './Components/Navigation';
import Products from './Components/Products';
import {BrowserRouter as Router, Route, Switch,} from 'react-router-dom';
import ProductsDetails from './Components/ProductsDetails';
export default function App() {
const [error, setError] = useState(null);
const [productsData, setProductsData] = useState([]);
const [isLoaded, setIsLoaded] = useState(false);
const updatePrice = (id, price) => {
setProductsData((productsData) =>
productsData.map((product) =>
product.id === Number(id)
? {
...product,
price: Number(price)
}
: product
)
);
};
useEffect(() => {
axios.get("https://fakestoreapi.com/products?limit=7").then((res) => {
setIsLoaded(true);
setProductsData(res.data);
},
(error) => {
setIsLoaded(true);
setError(error);
}
);
}, []);
if (error) {
return <div>Erreur : {error.message}</div>
} else if (!isLoaded) {
return <div>
<Oval stroke="#564AFF"/>
<p>Loading...</p>
</div>
} else {
return (
<div className="App">
<Router>
<Navigation/>
<Switch>
<Route
path="/products-details/:id"
render={(props) => (
<ProductsDetails
products={productsData}
updatePrice={updatePrice}
{...props}
/>
)}
/>
<Route path="/">
<Products products={productsData}
/>
</Route>
</Switch>
</Router>
</div>
)
}
}

Related

how to prefill form data to update in next js with typescript and redux toolkit

i completed crud a project with react and redux toolkit.now i want to implement next js and typescript with the same project.when i wanted to prefill form data using uselocation hook there is showing an error. please someone help me. github link-- https://github.com/arshad007hossain/nex-typescript-crud-app
bookslice.ts
import { PayloadAction } from "#reduxjs/toolkit";
import { toast } from "react-toastify";
const { createSlice } = require("#reduxjs/toolkit");
import { v4 as uuidv4 } from 'uuid'
import { RootState } from "../store";
type Book = {
id: string
title: string
author: string
}
type initialState = {
books: Book[];
}
const initialState: initialState = {
books: [
{ id: uuidv4(), title: "new programmar", author: "john smith" },
{ id: uuidv4(), title: "Connecting the dot", author: "john smith" },
],
};
export const booksSlice = createSlice({
name: "books",
initialState: initialState,
reducers: {
showBooks: (state) => state,
addBook: (state, action: PayloadAction<Book[]>) => {
state.books.push(action.payload);
// state.countBooks = state.countBooks + 1;
toast.success("New Book Added");
},
updateBook: (state, action:PayloadAction<Book>) => {
const { id, title, author } = action.payload;
const isBookExist = state.books.filter((book) => book.id === id);
if (isBookExist) {
isBookExist[0].title = title;
isBookExist[0].author = author;
toast.info("Book Updated");
}
},
deleteBook: (state, action:PayloadAction<Book>) => {
const id = action.payload;
state.books = state.books.filter((book) => book.id !== id);
// state.countBooks = state.countBooks - 1;
toast.warn("Book Deleted");
},
},
});
export const { showBooks, addBook, deleteBook, updateBook } =
booksSlice.actions;
export const getAllBooks = (state: RootState) => state.books
export default booksSlice.reducer;
addBook.tsx
import { useRouter } from "next/router";
import { useForm } from "react-hook-form";
import { useAppDispatch } from "../hooks";
import { v4 as uuidv4 } from "uuid";
import { ToastContainer } from "react-toastify";
import { useNavigate } from "react-router-dom";
import { addBook } from "../slices/bookSlice";
import { useDispatch } from "react-redux";
const AddBook = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm();
const router = useRouter();
const dispatch = useDispatch();
const onSubmit = ({ title, author }) => {
const book = { id: uuidv4(), title, author };
dispatch(addBook(book));
router.push("/showBooks");
};
return (
<div>
<ToastContainer/>
<h2 className="text-center">Add Books</h2>
<div className="d-flex justify-content-center">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="mb-3">
<label htmlFor="text" className="form-label">
Title
</label>
<input
{...register("title", { required: "Title is required" })}
type="text"
className="form-control"
/>
{errors.title?.type === "required" && "Title is required" && (
<p style={{ color: "red" }}>Title is Required.</p>
)}
</div>
<div className="mb-3">
<label htmlFor="text" className="form-label">
Author
</label>
<input
{...register("author", { required: "Author is required" })}
type="text"
className="form-control"
/>
{errors.author?.type === "required" && "Author is required" && (
<p style={{ color: "red" }}>Author is Required.</p>
)}
</div>
<button type="submit" className="btn btn-primary">
Add Book
</button>
</form>
</div>
</div>
);
};
export default AddBook;
editBook.tsx
when i try use uselocation this error occurs:
useLocation() may be used only in the context of a component.
import React, { useState } from "react";
import { useRouter } from "next/router";
import { useDispatch } from "react-redux";
import { useLocation } from "react-router-dom";
import { updateBook } from "../slices/bookSlice";
import { useForm } from "react-hook-form";
import { ToastContainer } from "react-toastify";
const EditBook = ({state}) => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm();
const location = useLocation();
const dispatch = useDispatch();
const router = useRouter();
const [id] = useState(location.state.id);
console.log(location.state.title)
console.log(location.state.author)
const [title, setTitle] = useState(location.state.title);
const [author, setAuthor] = useState(location.state.author);
const onSubmit = (e) => {
dispatch(updateBook({ id, title, author }));
router.push("/showBooks");
};
return (
<div>
<ToastContainer/>
<h1 className="text-center">Edit Book</h1>
<div className="d-flex justify-content-center">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="mb-3">
<label htmlFor="text" className="form-label">
Title
</label>
<input
{...register("title", { required: "Title is required" })}
type="text"
className="form-control"
/>
{errors.title?.type === "required" && "Title is required" && (
<p style={{ color: "red" }}>Title is Required.</p>
)}
</div>
<div className="mb-3">
<label htmlFor="text" className="form-label">
Author
</label>
<input
{...register("author", { required: "Author is required" })}
type="text"
className="form-control"
/>
{errors.author?.type === "required" && "Author is required" && (
<p style={{ color: "red" }}>Author is Required.</p>
)}
</div>
<button type="submit" className="btn btn-primary">
Update Book
</button>
</form>
</div>
</div>
);
};
export default EditBook;
showBooks.tsx
import { useRouter } from "next/router";
import Link from "next/link";
import React from "react";
import { useAppDispatch, useAppSelector } from "../hooks";
import '../node_modules/bootstrap/dist/css/bootstrap.css'
import { deleteBook, getAllBooks } from "../slices/bookSlice";
const BooksView = () => {
const router = useRouter()
const AllBooks = useAppSelector(getAllBooks);
// const count = useAppSelector(selectCount);
// const numberOfBooks = useAppSelector((state) => state
const dispatch = useAppDispatch();
const handleDeleteBook = (id) => {
dispatch(deleteBook(id));
};
return (
<div>
<h2 className="text-center">List of Books</h2>
{/* <h2>There are {numberOfBooks} Books</h2> */}
<table className="table table-striped table-border w-50 align-center m-auto">
<thead className="text-center">
<tr>
{/* <th>ID</th> */}
<th>Title</th>
<th>Author</th>
<th>Action</th>
</tr>
</thead>
<tbody className="text-center">
{AllBooks.books.map((book) => {
const { id, title, author } = book;
return (
<tr key={id}>
{/* <td>{id}</td> */}
<td>{title}</td>
<td>{author}</td>
<td>
<Link href="/editBook">
<button className="btn btn-primary mx-2">Edit</button>
</Link>
<button className="btn btn-info"
onClick={() => {
handleDeleteBook(id);
}}
>
Delete
</button>
</td>
</tr>
);
})}
</tbody>
</table>
</div>
);
};
export default BooksView;

Delete Table Row not working properly with search bar

i'm new to reactjs and i'm trying to make a table that shows the information from a array of objects and have a button of delete and an input to search among the users. The delete button is working correctly when i'm not searching anything, but when i'm searching it doesn't delete the corretly row, and deletes only the first one. I see that it is because the arrays that show the table are different with and without the search being used but I don't know how to make it work.
this is the component of the table:
import { formatDate } from "../../utils/formatDate";
import "./table.css";
import { useState } from "react";
function Table(props) {
const { headerData, bodyData, type, removeItem} = props;
const isUser = type === "user";
const buildTableItems = () => {
return bodyData.map((item, index) => (
<tr className="data-tr">
<td>{item.name}</td>
<td>{item.email}</td>
<td>{item.occupation}</td>
<td>{formatDate(item.birthday)}</td>
<td>
<button className="delete-button" onClick={() => removeItem(index)}>
Delete
</button>
</td>
</tr>
));
};
return (
<div className="user-data">
<table className="user-table">
<thead>
<tr className="data-th">
{headerData.map((headerTable) => (
<th >{headerTable}</th>
))}
</tr>
</thead>
<tbody>{buildTableItems()}</tbody>
</table>
</div>
);
}
export default Table;
Here the component of the search bar:
import "./searchBar.css"
function SearchBar({ searchedData, onSearch }) {
return (
<div className="search-bar">
<label>Search</label>
<input type="text" placeholder="Search User" value={searchedData} onChange={e => onSearch(e.target.value)} />
</div>
);
}
export default SearchBar;
and here is the home:
import "./Home.css";
import React, { useEffect, useState } from "react";
import Header from "../components/Header/Header";
import Table from "../components/Table/Table";
import AddData from "../components/AddData/AddData";
import SearchBar from "../components/SearchBar/SearchBar";
import { userArr } from "../mock/users";
const Home = () => {
const headerUser = ["Name", "Email", "Occupation", "Birthday"];
const [newUserArr, setNewUserArr] = useState(userArr);
const [searchedItem, setSearchedItem] = useState("");
const searchedArray = newUserArr.filter((item) => {
if (item.name.toLowerCase().includes(searchedItem.toLowerCase())) {
return true;
}
});
function onSearch(e) {
setSearchedItem(e);
}
const addDataToArr = (form) => {
setNewUserArr([...newUserArr, form]);
};
const deleteData = (indexUserArr) => {
let restOfDataArray = newUserArr.filter(
(element, ind) => ind !== indexUserArr
);
setNewUserArr(restOfDataArray);
};
return (
<>
<Header />
<SearchBar searchedData={searchedItem} onSearch={onSearch} />
<Table
type="user"
headerData={headerUser}
bodyData={newUserArr}
removeItem={(index) => deleteData(index)}
/>
<AddData saveData={(val) => addDataToArr(val)} />
</>
);
};
export default Home;
thank you
If you have ID in your user data then use that instead of index or create id keywords using concatenate with your values here is examples.
import { formatDate } from "../../utils/formatDate";
import "./table.css";
import { useState } from "react";
function Table(props) {
const { headerData, bodyData, type, removeItem} = props;
const isUser = type === "user";
const buildTableItems = () => {
return bodyData.map((item, index) => (
<tr className="data-tr">
<td>{item.name}</td>
<td>{item.email}</td>
<td>{item.occupation}</td>
<td>{formatDate(item.birthday)}</td>
<td>
<button className="delete-button" onClick={() => removeItem(`${item.name}${item.email}${item.occupation}`)}>
Delete
</button>
</td>
</tr>
));
};
return (
<div className="user-data">
<table className="user-table">
<thead>
<tr className="data-th">
{headerData.map((headerTable) => (
<th >{headerTable}</th>
))}
</tr>
</thead>
<tbody>{buildTableItems()}</tbody>
</table>
</div>
);
}
export default Table;
And here is your delete method ${item.name}${item.email}${index}
const deleteData = (data) => {
let restOfDataArray = newUserArr.filter(
(element, ind) => `${element.name}${element.email}${element.occupation}` !== data
);
setNewUserArr(restOfDataArray);
};
This will fixed your problem. If this doesn't work then you need to use ID to resolve this problem. There is a possibility that ${item.name}${item.email}${item.occupation} can be duplicates.
Never use index ever for deleting or any other operations. Use always ID.

Not able to display the details page for a product in React

On my products list page when i click on view icon underneath the product thumbnail it takes me to a blank product details page.the product detail page has the right id but doesn't display anything
This is my code for the product details page.
import { useState, useEffect } from 'react';
import {useParams} from 'react-router-dom';
const axios = require('axios');
const SingleProduct = () => {
const [data, setData] = useState([]);
const params = useParams();
useEffect(() => {
fetchProduct();
}, []);
const fetchProduct = () => {
axios
.get(
`http://localhost:5000/api/products/${params._id}`
)
.then((res) => {
setData(res.data);
console.log(res.data);
})
.catch((err) => console.log(err))
;
};
return (
<div>
{data.map((item) => {
return (
<div className='product-container' key={item._id}>
<div>
<img className='prod-image' src={item.imageUrl} alt='' />
</div>
<div>
<h1 className='brand'>{item.name}</h1>
<h2>{item.price}</h2>
<p>{item.description}</p>
<p>
<strong>Price:</strong> {item._id}
</p>
<p>
<strong>Color:</strong> {item.color}
</p>
</div>
</div>
);
})}
</div>
);
;
}
export default SingleProduct;
This is the code in App.js:
<Route path='/SingleProduct/:_id' element={SingleProduct} />
This the code in the products list page:
import React from 'react'
import {useEffect} from 'react';
import {Link} from 'react-router-dom'
const ProductsPage = (props) => {
const items = props.items;
const getItems = props.getItems;
useEffect(() => {
getItems();
}, [])
return (
<>
<section className="ProductsPage items-page" onload = {getItems}>
{items.filter (item => item.price < 1000).map(item => (
<ul items-style>
<img src={item.imageUrl} alt="product" />
<h2>{item.name}</h2>
<Link to={`/SingleProduct/${item._id}`}>View</Link>
</ul>
//
))}
</section>
</>
) }
export default ProductsPage

how to hide table rows based on an input in react js

i created an app using react js which get te data from a graphql endpoint .
the data is displayed in a table and i ant to add a search function .
when the attribute name match the input in the search field only the roes that contains that name will stay displayed so basically i ant to hide the other rows
search component :
import React, { useState } from 'react'
const Search = ({ getQuery }) => {
const [text, setText] = useState('')
const onChange = (q) => {
setText(q)
getQuery(q)
}
return (
<section className='search'>
<form>
<input
type='text'
className='form-control'
placeholder='Search characters'
value={text}
onChange={(e) => onChange(e.target.value)}
autoFocus
/>
</form>
</section>
)
}
export default Search
orders list :
import React , { useState, useEffect } from 'react'
import { gql, useQuery } from '#apollo/client';
import Table from 'react-bootstrap/Table'
import Moment from 'react-moment';
import moment from "moment";
import { Link } from 'react-router-dom';
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import { DangerousChangeType } from 'graphql';
import Search from './Search'
import Button from 'react-bootstrap/Button'
const GET_All_Orders = gql`
query Orders($input1: PaginationInput) {
Orders(input: $input1){
pageInfo {
hasNextPage
hasPreviousPage
}
edges{
cursor
node {
id
closed
email
createdAt
updatedAt
cancelledAt
displayFinancialStatus
displayFulfillmentStatus
lineItems{
edges{
node {
customAttributes{
key
value
}
id
quantity
title
variant{
id
image {
altText
id
src
}
title
weight
weightUnit
price
}
}
}
}
shippingAddress {
name
}
phone
subtotalPrice
totalPrice
totalRefunded
totalTax
processedAt
}
}
}
}
`;
export default function AllOrders({ input1 }) {
const { loading, error, data , fetchMore} = useQuery(GET_All_Orders, {
variables: {"input1": {
"num": 20,
}}
,
});
let date = new Date()
const [query, setQuery] = useState('')
if (loading) return <h4>読み込み中...</h4>;
if (error) return `Error! ${error}`;
return( <div>
<Row >
<Col xs={10}> <h5>すべての注文</h5></Col>
<Col><h5> 日付 : <Moment format="YYYY/MM/DD">
{ date}
</Moment> </h5></Col>
</Row>
<br/>
<Table responsive hover size="sm">
<thead>
<tr>
<th className="allOrders">注文日</th>
<th className="allOrders">名前</th>
<th className="allOrders">注文者メールアドレス</th>
<th className="allOrders" >配送状態</th>
<th className="allOrders" >支払状況</th>
<th className="allOrders" >合計金額</th>
<th className="allOrders" >詳細</th>
</tr>
</thead>
<tbody>
{data.Orders.edges.map(({ edges ,node :{id , createdAt , displayFulfillmentStatus , displayFinancialStatus , totalPrice , email , shippingAddress: {
name
} }}) => (
<tr key={id}>
<td> <Moment format="YYYY/MM/DD">
{createdAt}
</Moment></td>
<td>{ name} </td>
<td>{ email} </td>
{displayFulfillmentStatus == "FULFILLED" ? <td className="success">配送済み</td> : <td className="failed">未配送</td>}
{displayFinancialStatus == "PAID" ? <td>支払済み</td> : <td>未払い</td> }
<td>{totalPrice} </td>
<td>
<Link to={`/orders/${id}`} className="btn btn-light">
詳細
</Link></td>
</tr>
))}
</tbody>
</Table>
<div className="text-center">
<Button
variant="light"
onClick={() => {
fetchMore({
variables: {"input1": {
"num": 20,
"cursor": data.Orders.edges[data.Orders.edges.length - 1].cursor }},
updateQuery: (prevResult, { fetchMoreResult }) => {
fetchMoreResult.Orders.edges = [
...prevResult.Orders.edges,
...fetchMoreResult.Orders.edges
];
return fetchMoreResult;
}
});
}}
>
もっと
</Button>
</div>
</div>
)}
when i try it inside the map function like :
{query === name ? <td> {name}</td> : null }
it works fine but i don't know how to deal with the rows and that logic .

Unhandled Rejection (Error) in ReactJS, implementing files causes error

I'm trying to implement some search features for an online book store with reactjs. I found a good repo that uses the google book api and decided to implement it on my project to see how it would work. But I'm getting the following error:
enter image description here
my github is: https://github.com/luismir15/CEN4010.git branch: luis
//code implemented by jason rivera
import React, { Component } from 'react';
import BookList from './BookList';
import SearchBox from './SearchBox';
import request from 'superagent';
class Books extends Component {
constructor(props){
super(props)
this.state = {
books: [],
searchField: '',
sort: ''
}
}
componentDidMount() {
request
.get("https://www.googleapis.com/books/v1/volumes")
.query({ q: this.state.searchField })
.then((data) => {
this.setState({ books: [...data.body.items] })
})
}
handleSubmit = (e) => {
e.preventDefault();
request
.get("https://www.googleapis.com/books/v1/volumes")
.query({ q: this.state.searchField })
.then((data) => {
console.log(data);
this.setState({ books: [...data.body.items] })
})
}
handleChange = (e) => {
this.setState({ searchField: e.target.value })
}
handleSort = (e) => {
this.setState({ sort: e.target.value});
}
render() {
const filteredBooks = this.state.books.sort((a, b) => {
const price1 = a.saleInfo.hasOwnProperty('listPrice') == false ? "$0.00" : a.saleInfo.listPrice.amount;
const price2 = b.saleInfo.hasOwnProperty('listPrice') == false ? "$0.00" : b.saleInfo.listPrice.amount;
if(this.state.sort == 'Newest'){
console.log("in newest")
return parseInt(b.volumeInfo.publishedDate.substring(0, 4)) - parseInt(a.volumeInfo.publishedDate.substring(0, 4));
}
else if(this.state.sort == 'Oldest'){
return parseInt(a.volumeInfo.publishedDate.substring(0, 4)) - parseInt(b.volumeInfo.publishedDate.substring(0, 4));
}
else if(this.state.sort == 'High'){
return parseInt(b.volumeInfo.averageRating) - parseInt(a.volumeInfo.averageRating);
}
else if(this.state.sort == 'Low'){
return parseInt(a.volumeInfo.averageRating) - parseInt(b.volumeInfo.averageRating);
}
else if(this.state.sort === 'Expensive'){
return parseInt(price2) - parseInt(price1);
}
else if(this.state.sort === 'Cheap'){
return parseInt(price1) - parseInt(price2);
}
return;
})
return (
<div className="wrapper">
<SearchBox
data={this.state}
handleSubmit={this.handleSubmit}
handleChange={this.handleChange}
handleSort={this.handleSort}
/>
<BookList books={filteredBooks}/>
</div>
);
}
}
export default Books;
import React, { Component } from 'react';
import BookCard from './BookCard';
const BookList = (props) => {
return (
<div className="list">
{
props.books.map((book) => {
return <BookCard key={book.id} info={book} />
})
}
</div>
);
}
export default BookList;
import React, { Component } from 'react';
const SearchBox = (props) => {
return (
<div className="search-area">
<form onSubmit={props.handleSubmit}>
<input onChange={props.handleChange} placeholder="Search books" type="text"/>
<button type="submit">Search</button>
<select value={props.sort} onChange={props.handleSort}>
<option value="" disabled selected>Sort</option>
<option value="Newest">Newest</option>
<option value="Oldest">Oldest</option>
<option value="High">High to Low</option>
<option value="Low">Low to High</option>
<option value="Expensive">$$$-$</option>
<option value="Cheap">$-$$$</option>
</select>
</form>
</div>
);
}
export default SearchBox;
import React, { Component } from 'react';
const BookCard = (props) => {
const { volumeInfo } = props.info;
const { saleInfo } = props.info;
const {title, authors, averageRating, subtitle, publishedDate} = props.info.volumeInfo;
const price = saleInfo.hasOwnProperty('listPrice') == false ? "$0.00" : saleInfo.listPrice.amount;
const thumbNail = volumeInfo.hasOwnProperty('imageLinks') == false ? "https://vignette.wikia.nocookie.net/pandorahearts/images/a/ad/Not_available.jpg/revision/latest?cb=20141028171337" : volumeInfo.imageLinks.thumbnail;
const publishYear = volumeInfo.hasOwnProperty('publishedDate') == false ? volumeInfo['publishedDate'] = "0000" : volumeInfo.publishedDate;
return (
<div className="card-container">
<img src={thumbNail} alt=""/>
<div className="desc">
<h2>{title}</h2>
<p>Author: {authors}</p>
<p>Price: {price}</p>
<p>Raiting: {averageRating == "0.00" ? "Not available" : averageRating}</p>
<p>Published: {publishYear == "0000" ? "Not available" : publishYear.substring(0,4)}</p>
</div>
</div>
);
}
export default BookCard;
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import '../style/browsing.css';
import Books from '../component/Books';
const Home = () => {
return (
<div>
<ul className="flexbox-container">
<div className="browsing">
<Books/>
</div>
</ul>
</div>
);
}
export default Home;
import React from 'react';
import './index.css';
import './style/browsing.css';
import Home from './pages/Home';
import Register from './pages/Register';
import Login from './pages/Login';
import Orders from './pages/Orders';
import BookDetails from './pages/BookDetails';
import ShopCart from './pages/ShopCart';
import Profile from './pages/Profile';
//import Books from './component/Books';
import { Route, HashRouter, NavLink } from 'react-router-dom';
// NPM RUN CLIENT is the updated src folder, (NPM RUN SERVER/NPM START) runs build in my case which is the old green template
//Use ctrL + C to stop the server
//Always run NPM INSTALL on a newly cloned file
//Do not push updates to master branch, push to your own branch PLZ
//updated file structure on my branch (miguel) 2/17/20
//npm install after downloading/ npm install --save react-bootstrap mighe be needed for BookDetails to work
//npm npm run client to run this package
const App = () => (
<div>
<HashRouter>
<div>
<NavLink to="/" style={{ textDecoration: 'none' }}>
<h1><i class="material-icons">menu_book</i> GeekText</h1>
</NavLink>
<ul className="header">
<li><NavLink exact to="/">Home</NavLink></li>
<li><NavLink to="/Login">Login</NavLink></li>
<li><NavLink to="/Orders">Orders</NavLink></li>
<li><NavLink to="/BookDetails">Book Details</NavLink></li>
<li><NavLink to="/Profile">Profile</NavLink></li>
<li>
<NavLink to="/ShopCart">
<i class="material-icons md-dark md-24">shopping_cart</i>
</NavLink>
</li>
</ul>
<div className="content">
<Route exact path="/" component={Home} />
<Route path="/Register" component={Register} />
<Route path="/Login" component={Login} />
<Route path="/Orders" component={Orders} />
<Route path="/BookDetails" component={BookDetails} />
<Route path="/ShopCart" component={ShopCart} />
<Route path="/Profile" component={Profile} />
</div>
</div>
</HashRouter>
</div>
);
export default App;

Categories

Resources