The data variable contains all the data needed for this operation the problem is that the frontend shows card one below the other whereas I want it to show 3 or 4 in one row. I can assure that the error is not with the react or the graphql, the error is in the bootstrap or the way I am rendering the data.
I just want a responsive design so at first i have created a html css bootstrap ui which was perfectly working and was responsive but when i combined it with the data it lost its responsiveness and now it shows cards one below the other.
here is the image of how it is currentlyIt shows that there is a card but no other card along the row
Here is my code:
import React, { useState } from "react";
import { gql, useQuery } from "#apollo/client";
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";
const getBooksQuery = gql`
{
books {
name
id
genre
author {
name
}
description
rating
image
}
}
`;
function BooksDisplay() {
const { loading, error, data } = useQuery(getBooksQuery);
var [selected, setSelected] = useState("");
if (loading) return <p>Loading....</p>;
if (error) return <p>Ops! Something went wrong</p>;
return (
<div>
<div id="book-list">
{data.books.map((book) => (
<div className="container-fluid my-5 books_section">
<div className="row">
<div className="col-xl-3 col-lg-4 col-sm-6 col-12 mt-4">
<div className="card h-100">
<img src={book.image} className="card-img-top" alt="..." />
<div className="card-body">
<h5 className="card-title font-weight-bold text-secondary">
{book.name}
</h5>
<span className="card-text">
{book.description}
<div className="collapse m-0" id="collapseExample">
<div className="card card-body border-0 p-0">
{book.description}
</div>
</div>
</span>
<a
className="card-link d-block"
data-toggle="collapse"
href="#collapseExample"
role="button"
aria-expanded="false"
aria-controls="collapseExample">
See More
</a>
</div>
<ul className="list-group list-group-flush">
<li className="list-group-item">
Authors:
<span>
{book.author.map((author) => author.name).join(" ")}
</span>
</li>
<li className="list-group-item">
Genre: <span>{book.genre.join(" ")}</span>
</li>
<li className="list-group-item">
Ratings: <span>{book.rating}</span>
</li>
</ul>
</div>
</div>
</div>
</div>
))}
</div>
{/* <BookDetail bookid={selected} /> */}
</div>
);
}
function BookList() {
return (
<div>{BooksDisplay()}</div>
);
}
export default BookList;
You need to iterate the columns instead of the container...
import React, { useState } from "react";
import { gql, useQuery } from "#apollo/client";
import "../../node_modules/bootstrap/dist/css/bootstrap.min.css";
const getBooksQuery = gql`
{
books {
name
id
genre
author {
name
}
description
rating
image
}
}
`;
function BooksDisplay() {
const { loading, error, data } = useQuery(getBooksQuery);
var [selected, setSelected] = useState("");
if (loading) return <p>Loading....</p>;
if (error) return <p>Ops! Something went wrong</p>;
return (
<div>
<div id="book-list">
<div className="container-fluid my-5 books_section">
<div className="row">
{data.books.map((book) => (
<div className="col-xl-3 col-lg-4 col-sm-6 col-12 mt-4">
<div className="card h-100">
<img src={book.image} className="card-img-top" alt="..." />
<div className="card-body">
<h5 className="card-title font-weight-bold text-secondary">
{book.name}
</h5>
<span className="card-text">
{book.description}
<div className="collapse m-0" id="collapseExample">
<div className="card card-body border-0 p-0">
{book.description}
</div>
</div>
</span>
<a
className="card-link d-block"
data-toggle="collapse"
href="#collapseExample"
role="button"
aria-expanded="false"
aria-controls="collapseExample">
See More
</a>
</div>
<ul className="list-group list-group-flush">
<li className="list-group-item">
Authors:
<span>
{book.author.map((author) => author.name).join(" ")}
</span>
</li>
<li className="list-group-item">
Genre: <span>{book.genre.join(" ")}</span>
</li>
<li className="list-group-item">
Ratings: <span>{book.rating}</span>
</li>
</ul>
</div>
</div>
))}
</div>
</div>
</div>
{/* <BookDetail bookid={selected} /> */}
</div>
);
}
function BookList() {
return (
<div>{BooksDisplay()}</div>
);
}
export default BookList;
Just put these 2 tags out of the loop
< div className="container-fluid my-5 books_section">
< div className="row">
And it will work.
Related
import React, { useEffect } from "react";
import Loader from "../layout/Loader";
import { useAlert } from "react-alert";
import { useDispatch, useSelector } from "react-redux";
import { getProductDetails, clearErrors } from "../../actions/productActions";
const ProductDetails = ({ match }) => {
const dispatch = useDispatch();
const alert = useAlert();
const { loading, error, product } = useSelector((state) =>
state.productDetails()
);
useEffect(() => {
dispatch(getProductDetails());
if (error) {
alert.error(error);
dispatch(clearErrors());
}
}, [dispatch, alert, error]);
return (
<>
{!loading ? (
<Loader />
) : (
<>
<div className='row f-flex justify-content-around'>
<div className='col-12 col-lg-5 img-fluid' id='product_image'>
<img
src='https://i5.walmartimages.com/asr/1223a935-2a61-480a-95a1-21904ff8986c_1.17fa3d7870e3d9b1248da7b1144787f5.jpeg?odnWidth=undefined&odnHeight=undefined&odnBg=ffffff'
alt='sdf'
height='500'
width='500'/>
</div>
<div className='col-12 col-lg-5 mt-5'>
<h3>{product.name}</h3>
<p id='product_id'>Product # sklfjdk35fsdf5090</p>
<hr />
<div className='rating-outer'>
<div className='rating-inner'></div>
</div>
<span id='no_of_reviews'>(5 Reviews)</span>
<hr />
<p id='product_price'>$108.00</p>
<div className='stockCounter d-inline'>
<span className='btn btn-danger minus'>-</span>
<input
type='number'
className='form-control count d-inline'
value='1'
readOnly
/>
<span className='btn btn-primary plus'>+</span>
</div>
<button
type='button'
id='cart_btn'
className='btn btn-primary d-inline ml-4'
>
Add to Cart
</button>
<hr />
<p>
Status: <span id='stock_status'>In Stock</span>
</p>
<hr />
<h4 className='mt-2'>Description:</h4>
<p>
Binge on movies and TV episodes, news, sports, music and more!
We insisted on 720p High Definition for this 32" LED TV,
bringing out more lifelike color, texture and detail. We also
partnered with Roku to bring you the best possible content with
thousands of channels to choose from, conveniently presented
through your own custom home screen.
</p>
<hr />
<p id='product_seller mb-3'>
Sold by: <strong>Amazon</strong>
</p>
<button
id='review_btn'
type='button'
className='btn btn-primary mt-4'
data-toggle='modal'
data-target='#ratingModal'
>
Submit Your Review
</button>
<div className='row mt-2 mb-5'>
<div className='rating w-50'>
<div
className='modal fade'
id='ratingModal'
tabIndex='-1'
role='dialog'
aria-labelledby='ratingModalLabel'
aria-hidden='true'
>
<div className='modal-dialog' role='document'>
<div className='modal-content'>
<div className='modal-header'>
<h5 className='modal-title' id='ratingModalLabel'>
Submit Review
</h5>
<button
type='button'
className='close'
data-dismiss='modal'
aria-label='Close'
>
<span aria-hidden='true'>×</span>
</button>
</div>
<div className='modal-body'>
<ul className='stars'>
<li className='star'>
<i className='fa fa-star'></i>
</li>
<li className='star'>
<i className='fa fa-star'></i>
</li>
<li className='star'>
<i className='fa fa-star'></i>
</li>
<li className='star'>
<i className='fa fa-star'></i>
</li>
<li className='star'>
<i className='fa fa-star'></i>
</li>
</ul>
<textarea
name='review'
id='review'
className='form-control mt-3'
></textarea>
<button
className='btn my-3 float-right review-btn px-4 text-white'
data-dismiss='modal'
aria-label='Close'
>
Submit
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</>
)}
</>
);
};
export default ProductDetails;
As the error suggests
state.productDetails is not a function
This is because productDetails is a reducer object and Not a function created by redux. Hence, your code should be
const { loading, error, product } = useSelector((state) =>state.productDetails); //Note: productDetails without '()'
Hope it helps.
Side Note: While posting any question or answer please format the code properly next time so it's readable. :)
Im mapping through some context.api data, and displaying that data on a page. this works fine. However, when i want to send a piece of that array.map back to the context for state management, it only chooses the last item. I want it to choose the item you click on.
Code:
import { React, useState, useEffect, useContext } from "react";
import { DataContext } from "../contexts/dataContext";
import { Link } from "react-router-dom";
const Example = () => {
const [open, setOpen] = useState(false);
const [input, setInput] = useState(null);
const[designation, setDesignation] = useState(null);
const { data } = useContext(DataContext);
const { onChange } = useContext(DataContext);
const { onClick} = useContext(DataContext);
return(
<div className="container">
<div className="row">
<div className="col-xs-12 col-sm-6 col-md-6 col-lg-6 col-xl-6 col-xxl-6 offset-sm-3 offset-md-3 offset-lg-3 offset-xl-3 offset-xxl-3 min-vh-100 text-center p-5 border">
{
data.map((item) => {
return(
<div className='row' key={item.id}>
<div className='col-xs-12 placeholder placeholder_image rounded'></div>
<div className='col-xs-12 text-start p-0 pt-2 m-0'>
<h2>{item.title}</h2>
<p>
<div className='col-sm-11'>
<a className="no_underline link-dark" data-bs-toggle="collapse" href={item.dataTarget} role="button" aria-expanded="false" aria-controls="collapseExample">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam venenatis sapien...<i className="bi bi-caret-down-fill"></i></a>
</div>
</p>
<div className="collapse" id={item.dataId}>
<div>
<p>{item.text}</p>
</div>
<form>
<div className='row mt-2 mb-2'>
<div className='d-grid gap-2 col-8 mx-auto'>
<div className="form-floating text-start">
<input type="text" className="form-control" id="enterAmount" placeholder='Enter Amount' aria-describedby="enterAmount" onChange={e => {setInput(e.target.value);onChange(e.target.value);}} />
<label htmlFor="enterAmount">Enter Amount</label>
</div>
</div>
</div>
<div className='row mt-2 mb-2'>
<div className='d-grid gap-2 col-6 mx-auto'>
<Link to="/checkout" className="btn btn-lg button-color" onClick={ onClick(item.title) }>Give <i className="bi bi-arrow-right"></i></Link>
</div>
</div>
</form>
</div>
</div>
</div>
)
})
}
</div>
</div>
</div>
)
}
export default Example
This is the part that i am using to get the data:
<Link to="/checkout" className="btn btn-lg button-color" onClick={ onClick(item.title) }>Give <i className="bi bi-arrow-right"></i></Link>
the onClick function in my context api looks like this:
const[designation, setDesignation] = useState(null);
its just a setState function really.
So why is it that every time its set, its returning the third title in a 3 item array?
Change onClick event on Link to this.
<Link to="/checkout" className="btn btn-lg button-color" onClick={() =>onClick(item.title) }>Give <i className="bi bi-arrow-right"></i></Link> –
onClick takes a function, but you’re passing it the value of calling a function.
The function gets called on each iteration, which updates the state each time and ultimately state settles in the last item’s onClick call.
Try this:
onClick={() => onClick(item.name)}
So, I am a react js and bootstrap noob. Please help me by telling how can I achieve this desired change - Basically I want the Image ( which is seen on the right in the image below) to be put on the total right on my website, currently the text and image are a too close to each other. How can I do this? below the image is also my code for that webpage.
https://i.stack.imgur.com/6OoTa.png
import React from "react";
import web from "../src/images/myimage.svg";
import {NavLink} from "react-router-dom";
const Common =(props) => {
return (
<>
<section id = "header" className = "d-flex align-items-between ">
<div className = "container-fluid">
<div className = 'row'>
<div className = "col-10" mx-auto>
<div className ="row">
<div className = "col-md-6 pt-5 pt-lg-0 order-2 order-lg-1 d-flex justify-content-center flex-column">
<h1>{props.name} <strong className = "brand-name"> Pinnacle Tutorials</strong>
</h1>
<h2 className = "my-3">
We are a team of talented Teachers here for your ward
</h2>
<div ClassName = "mt-3">
<NavLink to={props.visit} className = "btn btn-success">Get Started check - {props.btname}</NavLink>
</div>
</div>
<div className = "col-lg-6 order-6 order-lg-5 header-img d-flex justify-content-end">
<img src ={props.imgsrc} className = "img animated" alt = "home img "/>
</div>
</div>
</div>
</div>
</div>
</section>
</>
);
};
export default Common;
NAVBAR CODE :
import React from "react";
import { NavLink } from "react-router-dom";
const Navbar = () => {
return (
<>
<div className = "container-fullwidth nav_bg">
<div className = 'row'>
<div className = "col-12 mx-auto">
<nav className="navbar navbar-expand-lg navbar-light bg-light py-3 container-fluid">
<NavLink className="navbar-brand" to="/">Pinnacle Tutorials</NavLink>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav ms-auto">
<li className="nav-item active">
<NavLink activeClassName ="menu_active" exact className="nav-link" to="/">Home <span className="sr-only">(current)</span></NavLink>
</li>
<li className="nav-item">
<NavLink activeClassName ="menu_active" className="nav-link" to="/about">About</NavLink>
</li>
<li className="nav-item">
<NavLink activeClassName ="menu_active" className="nav-link" to="/service">Services</NavLink>
</li>
<li className="nav-item">
<NavLink activeClassName ="menu_active" className="nav-link" to="/contact">Contact</NavLink>
</li>
</ul>
</div>
</nav>
</div>
</div>
</div>
</>
);
};
export default Navbar
So what's going on here is that you're creating two columns, each of equal width. If you want the column containing the image to place the image at the extreme end, I'd suggest doing it the flex way, i.e, giving the col containing the <img> a display of flex which can be given with the class d-flex, and then applying a justify-content: flex-end; to it, which can be done by adding the class name justify-content-end
At the end, your div should look something like this:
<div className = "col-lg-6 order-6 order-lg-5 pad-10 header-img d-flex justify-content-end">
<img src ={props.imgsrc} className = "img-fluid animated" alt = "home img "/>
</div>
p {
padding-right: 150px;
}
<div class="bg-light d-flex justify-content-between">
<div>Total Cost</div>
<div>$50</div>
</div>
There is a button which I have in one of my components named header. I want to hide the navbar component based on that button. I tried creating a prop in the main component shown below which displays all the other components including header and navbar. Below is my main component.
import App from "./graph";
import Navbar from "./navbar";
import Header_Top from "./header";
import Flame from "./section_1";
import Section_3 from "./section_3_graph1";
// import Flame from "./section_test";
import Section_2 from "./section_2";
import Section_5 from "./section_5";
import Section_test from "./section_test";
class main extends Component {
constructor(props) {
super(props);
// this.fullscreenState = this.fullscreenState.bind(this);
}
state = {};
style2 = {
boxShadow:
" 0px 0px 40px rgba(255,255,255,0.08),inset 0px 0px 20px rgba(0,0,0,0.3)",
margin: 5,
padding: 0,
textAlign: "center",
// borderRadius: 20,
};
render() {
var fullscreenState = {
fullscreen: true,
};
return (
<div
className="row justify-content-center"
style={{
// backgroundColor: "#32373D",
backgroundImage: "linear-gradient(360deg, #191919, #272A2F)",
}}
>
<Header_Top fullscreenState={fullscreenState} />
{this.props.fullscreenState.fullscreen === true ? <Navbar /> : null}
<div className="row col-xl-9 col-lg-9 col-md-12 col-sm-12">
<div style={this.style1} className="col-xl-12">
<div className="col-md-12" style={this.style2}>
<Flame />
</div>
</div>
<div style={this.style1} className="col-xl-4 col-lg-8">
<div className="col-md-12" style={this.style2}>
<Section_2 />
</div>
</div>
<div style={this.style1} className="col-xl-8 col-lg-8" ref="inner">
<div className="col-md-12" style={this.style2}>
<Section_3 />
</div>
</div>
<div style={this.style1} className="col-xl-12 col-lg-12">
<div className="col-md-12" style={this.style2}>
<App />
</div>
</div>
</div>
<div className="column col-xl-3 col-lg-3 col-md-12 col-sm-12 ">
<div style={this.style1} className="col-xl-12 col-lg-12 my-auto">
<div className="col-md-12" style={this.style2}>
<Section_5 />
</div>
</div>
<div style={this.style1} className="col-xl-12 col-lg-12">
<div className="col-md-12" style={this.style2}>
<Section_test />
</div>
</div>
</div>
</div>
);
}
}
export default main;
This is my header component:
class Header_Top extends Component {
state = {
fullscreen: true,
};
toggleFullScreen = () => {
let fullscreen = this.props.fullscreenState.fullscreen;
this.setState({
fullscreen: !fullscreen,
});
};
changeLabel() {
let Label = "";
Label +=
this.props.fullscreenState.fullscreen === true
? "Exit full Screen"
: "Go to full Screen";
return Label;
}
render() {
return (
<div className="d-none d-md-block " style={{ width: "100%" }}>
<nav class="navbar navbar-expand-md navbar-light bg-light">
<a class="navbar-brand" href="#">
<img
src={require("./images/logo.png")}
width="50"
// height="50"
class="img-responsive"
alt=""
style={{}}
/>
</a>
<a class="navbar-brand" href="#">
<h1>SolarSenz</h1>
</a>
<button
class="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarNavDropdown"
aria-controls="navbarNavDropdown"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav ml-auto">
<li className="nav-item">
<button
className="btn btn-outline-dark"
onClick={this.toggleFullScreen}
>
{this.changeLabel()}
</button>
</li>
<li class="nav-item dropdown">
<a
class="nav-link dropdown-toggle active"
href="#"
id="navbarDropdownMenuLink"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
Admin Console<span class="sr-only">(current)</span>
</a>
<div
class="dropdown-menu"
aria-labelledby="navbarDropdownMenuLink"
>
<a class="dropdown-item" href="#">
Action
</a>
<a class="dropdown-item" href="#">
Another action
</a>
<a class="dropdown-item" href="#">
Something else here
</a>
</div>
</li>
</ul>
</div>
<a class="navbar-brand" href="#">
<img
src={require("./images/logo.png")}
width="50"
// height="50"
class="img-responsive"
alt=""
style={{}}
/>
</a>
</nav>
</div>
);
}
}
export default Header_Top;
I keep getting the error
TypeError: Cannot read property 'fullscreen' of undefined
What does this mean and how can I fix it?
The error you are getting is due to the following line (in 'render' function of class 'main'):
{this.props.fullscreenState.fullscreen === true ? <Navbar /> : null}
As the error indicates "this.props.fullscreenState" is udefined.
Props are arguments passed into React components. If no prop called "fullscreenState" was passed to class "main", it will be undefined.
What your are probably should do is to create state for the 'main' class which should include 'fullscreenState'. Then add this class a function that will toggle the state and pass it, together with the 'fullscreenState' to the 'header' component:
import App from "./graph";
import Navbar from "./navbar";
import Header_Top from "./header";
import Flame from "./section_1";
import Section_3 from "./section_3_graph1";
// import Flame from "./section_test";
import Section_2 from "./section_2";
import Section_5 from "./section_5";
import Section_test from "./section_test";
class main extends Component {
constructor(props) {
super(props);
this.state = {
fullscreen: false
}
// this.fullscreenState = this.fullscreenState.bind(this);
}
style2 = {
boxShadow: " 0px 0px 40px rgba(255,255,255,0.08),inset 0px 0px 20px rgba(0,0,0,0.3)",
margin: 5,
padding: 0,
textAlign: "center",
// borderRadius: 20,
};
toggleFullScreen = this.setState({fullscreen: !this.state.fullscreen});
render() {
return (
<div
className="row justify-content-center"
style={{
// backgroundColor: "#32373D",
backgroundImage: "linear-gradient(360deg, #191919, #272A2F)",
}}
>
<Header_Top fullscreenState={this.state.fullscreenState} toggleFullScreen={toggleFullScreen} />
{this.props.fullscreenState.fullscreen === true ? <Navbar /> : null}
<div className="row col-xl-9 col-lg-9 col-md-12 col-sm-12">
<div style={this.style1} className="col-xl-12">
<div className="col-md-12" style={this.style2}>
<Flame />
</div>
</div>
<div style={this.style1} className="col-xl-4 col-lg-8">
<div className="col-md-12" style={this.style2}>
<Section_2 />
</div>
</div>
<div style={this.style1} className="col-xl-8 col-lg-8" ref="inner">
<div className="col-md-12" style={this.style2}>
<Section_3 />
</div>
</div>
<div style={this.style1} className="col-xl-12 col-lg-12">
<div className="col-md-12" style={this.style2}>
<App />
</div>
</div>
</div>
<div className="column col-xl-3 col-lg-3 col-md-12 col-sm-12 ">
<div style={this.style1} className="col-xl-12 col-lg-12 my-auto">
<div className="col-md-12" style={this.style2}>
<Section_5 />
</div>
</div>
<div style={this.style1} className="col-xl-12 col-lg-12">
<div className="col-md-12" style={this.style2}>
<Section_test />
</div>
</div>
</div>
</div>
);
}
}
export default main;
Now in the header you don't need the state as you can use the 'fullscreenstate' prop and in the toggle function in the header change so it wil caontain the call of the toggle function of the 'main' component. something like this:
class Header_Top extends Component {
toggleFullScreen = () => {
this.props.toggleFullScreen
};
Don't copy-paste what I've done as there might be syntax error as I've been using functional components in the last few months.
we are building an e-commerce website using React and Redux as a front-end. And we need to display categories data on the category page. We successfully get JSON data in console, but we have a problem to display in the category component page.
Please help to solve this problem
reducer/categories.js:
import { RECEIVE_CATEGORIES } from "../constants/ActionTypes";
const initialState = {
categories: []
};
const categoryReducer = (state = initialState, action) => {
switch (action.type) {
case RECEIVE_CATEGORIES:
return {
...state,
categories: action.categories
};
default:
return state;
}
};
export default categoryReducer;
action/index.js:
import shop from '../api/shop'
import * as types from '../constants/ActionTypes'
import store from "../store";
import { toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.min.css';
export const fetchProductsBegin = () => ({
type: types.FETCH_PRODUCTS_BEGIN
});
export const fetchCategoryBegin = () => ({
type: types.FETCH_CATEGORIES_BEGIN
});
export const receiveProducts = products => ({
type: types.RECEIVE_PRODUCTS,
products
})
export const receiveCategories = categories => ({
type: types.RECEIVE_CATEGORIES,
categories
})
export const getAllProducts = () => dispatch => {
dispatch(fetchProductsBegin());
return shop.getProducts(
products => {
products.then((data)=> { dispatch(receiveProducts(data));})})
}
export const getAllCategories = () => dispatch => {
dispatch(fetchCategoryBegin());
return shop.getCategories(
products => {
products.then((data)=> {
console.log("executed");
dispatch(receiveCategories(data));})})
}
export const fetchSingleProduct = productId => ({
type: types.FETCH_SINGLE_PRODUCT,
productId
})
//it seems that I should probably use this as the basis for "Cart"
export const addToCart = (product,qty) => (dispatch) => {
toast.success("Item Added to Cart");
dispatch(addToCartUnsafe(product, qty))
}
export const addToCartAndRemoveWishlist = (product,qty) => (dispatch) => {
toast.success("Item Added to Cart");
dispatch(addToCartUnsafe(product, qty));
dispatch(removeFromWishlist(product));
}
export const addToCartUnsafe = (product, qty) => ({
type: types.ADD_TO_CART,
product,
qty
});
export const removeFromCart = product_id => (dispatch) => {
toast.error("Item Removed from Cart");
dispatch({
type: types.REMOVE_FROM_CART,
product_id
})
};
export const incrementQty = (product,qty) => (dispatch) => {
toast.success("Item Added to Cart");
dispatch(addToCartUnsafe(product, qty))
}
export const decrementQty = productId => (dispatch) => {
toast.warn("Item Decrement Qty to Cart");
dispatch({
type: types.DECREMENT_QTY,
productId})
};
//it seems that I should probably use this as the basis for "Wishlist"
export const addToWishlist = (product) => (dispatch) => {
toast.success("Item Added to Wishlist");
dispatch(addToWishlistUnsafe(product))
}
export const addToWishlistUnsafe = (product) => ({
type: types.ADD_TO_WISHLIST,
product
});
export const removeFromWishlist = product_id => (dispatch) => {
toast.error("Item Removed from Wishlist");
dispatch({
type: types.REMOVE_FROM_WISHLIST,
product_id
})
};
//Compare Products
export const addToCompare = (product) => (dispatch) => {
toast.success("Item Added to Compare");
dispatch(addToCompareUnsafe(product))
}
export const addToCompareUnsafe= (product) => ({
type: types.ADD_TO_COMPARE,
product
});
export const removeFromCompare = product_id => ({
type: types.REMOVE_FROM_COMPARE,
product_id
});
// Filters
export const filterBrand = (brand) => ({
type: types.FILTER_BRAND,
brand
});
export const filterColor = (color) => ({
type: types.FILTER_COLOR,
color
});
export const filterPrice = (value) => ({
type: types.FILTER_PRICE,
value
});
export const filterSort = (sort_by) => ({
type: types.SORT_BY,
sort_by
});
// Currency
export const changeCurrency = (symbol) => ({
type: types.CHANGE_CURRENCY,
symbol
});
Api/shop.js:
/**
* Mocking client-server processing
*/
import axios from "axios";
// import _products from './data.json'
import React, { useState, useEffect } from "react";
import store from "../store";
import { receiveProducts } from "../actions/index";
const TIMEOUT = 100;
const _products = axios
.get(`http://localhost:4000/product`)
.then((response) => {
return response.data;
});
const _category = axios
.get(`http://localhost:4000/categories`)
.then((response) => {
return response.data;
});
export default {
getProducts: (cb, timeout) =>
setTimeout(() => cb(_products), timeout || TIMEOUT),
getCategories: (cb, timeout) =>
setTimeout(() => cb(_category), timeout || TIMEOUT),
buyProducts: (payload, cb, timeout) =>
setTimeout(() => cb(), timeout || TIMEOUT),
};
element-category.jsx:
import React, { Component } from "react";
import Slider from "react-slick";
import Breadcrumb from "../../common/breadcrumb";
import { Slider6, Slider4 } from "../../../services/script";
import "react-tabs/style/react-tabs.scss";
import { connect } from "react-redux";
import { getAllCategories } from "../../../actions";
class ElementCategory extends Component {
constructor(props) {
super(props);
this.state = {
categories: this.props.categories
};
}
componentDidMount() {
this.props.getAllCategories();
}
render() {
console.log(this.state.categories);
return (
<div>
<Breadcrumb parent={"Elements"} title={"Category"} />
{/*Category One*/}
<div className="container">
<section className="section-b-space">
<div className="row">
<div className="col">
<Slider {...Slider6} className="slide-6 no-arrow">
<div className="category-block">
<a href="#">
<div className="category-image">
<img
src={`${process.env.PUBLIC_URL}/assets/images/icon/cat1.png`}
alt=""
/>
</div>
</a>
<div className="category-details">
<a href="#">
<h5>shoes</h5>
</a>
</div>
</div>
<div className="category-block">
<a href="#">
<div className="category-image">
<img
src={`${process.env.PUBLIC_URL}/assets/images/icon/cat2.png`}
alt=""
/>
</div>
</a>
<div className="category-details">
<a href="#">
<h5>casual shoes</h5>
</a>
</div>
</div>
<div className="category-block">
<a href="#">
<div className="category-image">
<img
src={`${process.env.PUBLIC_URL}/assets/images/icon/cat3.png`}
alt=""
/>
</div>
</a>
<div className="category-details">
<a href="#">
<h5>formal shoes</h5>
</a>
</div>
</div>
<div className="category-block">
<a href="#">
<div className="category-image">
<img
src={`${process.env.PUBLIC_URL}/assets/images/icon/cat4.png`}
alt=""
/>
</div>
</a>
<div className="category-details">
<a href="#">
<h5>flat</h5>
</a>
</div>
</div>
<div className="category-block">
<a href="#">
<div className="category-image">
<img
src={`${process.env.PUBLIC_URL}/assets/images/icon/cat5.png`}
alt=""
/>
</div>
</a>
<div className="category-details">
<a href="#">
<h5>heels</h5>
</a>
</div>
</div>
<div className="category-block">
<a href="#">
<div className="category-image">
<img
src={`${process.env.PUBLIC_URL}/assets/images/icon/cat6.png`}
alt=""
/>
</div>
</a>
<div className="category-details">
<a href="#">
<h5>boots</h5>
</a>
</div>
</div>
<div className="category-block">
<a href="#">
<div className="category-image">
<img
src={`${process.env.PUBLIC_URL}/assets/images/icon/cat2.png`}
alt=""
/>
</div>
</a>
<div className="category-details">
<a href="#">
<h5>casual shoes</h5>
</a>
</div>
</div>
<div className="category-block">
<a href="#">
<div className="category-image">
<img
src={`${process.env.PUBLIC_URL}/assets/images/icon/cat3.png`}
alt=""
/>
</div>
</a>
<div className="category-details">
<a href="#">
<h5>casual shoes</h5>
</a>
</div>
</div>
</Slider>
</div>
</div>
</section>
</div>
{/*Category Two*/}
<section className="p-0 ratio2_1">
<div className="container-fluid">
<div className="row category-border">
<div className="col-sm-4 border-padding">
<div className="category-banner">
<div>
<img
src={`${process.env.PUBLIC_URL}/assets/images/cat1.png`}
className="img-fluid blur-up lazyload bg-img"
alt=""
/>
</div>
<div className="category-box">
<a href="#">
<h2>men</h2>
</a>
</div>
</div>
</div>
<div className="col-sm-4 border-padding">
<div className="category-banner">
<div>
<img
src={`${process.env.PUBLIC_URL}/assets/images/cat2.png`}
className="img-fluid blur-up lazyload bg-img"
alt=""
/>
</div>
<div className="category-box">
<a href="#">
<h2>women</h2>
</a>
</div>
</div>
</div>
<div className="col-sm-4 border-padding">
<div className="category-banner">
<div>
<img
src={`${process.env.PUBLIC_URL}/assets/images/cat3.png`}
className="img-fluid blur-up lazyload bg-img"
alt=""
/>
</div>
<div className="category-box">
<a href="#">
<h2>kids</h2>
</a>
</div>
</div>
</div>
</div>
</div>
</section>
{/*Category Three*/}
<div className="container category-button">
<section className="section-b-space">
<div className="row partition1">
<div className="col">
<a href="#" className="btn btn-outline btn-block">
airbag
</a>
</div>
<div className="col">
<a href="#" className="btn btn-outline btn-block">
burn bag
</a>
</div>
<div className="col">
<a href="#" className="btn btn-outline btn-block">
briefcase
</a>
</div>
<div className="col">
<a href="#" className="btn btn-outline btn-block">
carpet bag
</a>
</div>
<div className="col">
<a href="#" className="btn btn-outline btn-block">
money bag
</a>
</div>
<div className="col">
<a href="#" className="btn btn-outline btn-block">
tucker bag
</a>
</div>
</div>
</section>
</div>
{/*Category Four*/}
<div className="category-bg ratio_square">
<div className="container-fluid p-0">
<div className="row order-section">
<div className="col-sm-4 p-0">
<a href="#" className="image-block">
<img
alt=""
src={`${process.env.PUBLIC_URL}/assets/images/cat1.jpg`}
className="img-fluid blur-up lazyload bg-img"
/>
</a>
</div>
<div className="col-sm-4 p-0">
<div className="contain-block even">
<div>
<h6>new products</h6>
<a href="#">
<h2>zipper storage bag</h2>
</a>
<a href="#" className="btn btn-solid category-btn">
-80% off
</a>
<a href="#">
<h6>
<span>shop now</span>
</h6>
</a>
</div>
</div>
</div>
<div className="col-sm-4 p-0">
<a href="#" className="image-block">
<img
alt=""
src={`${process.env.PUBLIC_URL}/assets/images/cat2.jpg`}
className="img-fluid blur-up lazyload bg-img"
/>
</a>
</div>
<div className="col-sm-4 p-0">
<div className="contain-block">
<div>
<h6>on sale</h6>
<a href="#">
<h2>tucker bag</h2>
</a>{" "}
<a href="#" className="btn btn-solid category-btn">
save 30% off
</a>
<a href="#">
<h6>
<span>shop now</span>
</h6>
</a>
</div>
</div>
</div>
<div className="col-sm-4 p-0">
<a href="#" className="image-block even">
<img
alt=""
src={`${process.env.PUBLIC_URL}/assets/images/cat3.jpg`}
className="img-fluid blur-up lazyload bg-img"
/>
</a>
</div>
<div className="col-sm-4 p-0">
<div className="contain-block">
<div>
<h6>summer sale</h6>
<a href="#">
<h2>gate check bag</h2>
</a>{" "}
<a href="#" className="btn btn-solid category-btn">
minimum 50% off
</a>
<a href="#">
<h6>
<span>shop now</span>
</h6>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
{/*Category Five*/}
<section className="ratio_portrait">
<div className="container">
<div className="row">
<div className="col">
<Slider {...Slider4} className="slide-4 category-m no-arrow">
<div>
<div className="category-wrapper">
<div>
<div>
<img
src={`${process.env.PUBLIC_URL}/assets/images/watch/cat1.png`}
className="img-fluid blur-up lazyload bg-img"
alt=""
/>
</div>
<h4>watch models</h4>
<ul className="category-link">
<li>
d1 milano
</li>
<li>
damaskeening
</li>
<li>
diving watch
</li>
<li>
dollar watch
</li>
</ul>
<a href="#" className="btn btn-outline">
view more
</a>
</div>
</div>
</div>
<div>
<div className="category-wrapper">
<div>
<div>
<img
src={`${process.env.PUBLIC_URL}/assets/images/watch/cat2.png`}
className="img-fluid blur-up lazyload bg-img"
alt=""
/>
</div>
<h4>calculator watch</h4>
<ul className="category-link">
<li>
Shock-resistant watch
</li>
<li>
Skeleton watch
</li>
<li>
Slow watch
</li>
<li>
Solar-powered watch
</li>
</ul>
<a href="#" className="btn btn-outline">
view more
</a>
</div>
</div>
</div>
<div className="category-wrapper">
<div>
<div>
<img
src={`${process.env.PUBLIC_URL}/assets/images/watch/cat3.png`}
className="img-fluid blur-up lazyload bg-img"
alt=""
/>
</div>
<h4>Antimagnetic watch</h4>
<ul className="category-link">
<li>
Watchmaking conglomerates
</li>
<li>
Breitling SA
</li>
<li>
Casio watches
</li>
<li>
Citizen Watch
</li>
</ul>
<a href="#" className="btn btn-outline">
view more
</a>
</div>
</div>
<div className="category-wrapper">
<div>
<div>
<img
src={`${process.env.PUBLIC_URL}/assets/images/watch/cat2.png`}
className="img-fluid blur-up lazyload bg-img"
alt=""
/>
</div>
<h4>History of watches</h4>
<ul className="category-link">
<li>
Manufacture d'horlogerie
</li>
<li>
Mechanical watch
</li>
<li>
Microbrand watches
</li>
<li>
MIL-W-46374
</li>
</ul>
<a href="#" className="btn btn-outline">
view more
</a>
</div>
</div>
<div className="category-wrapper">
<div>
<div>
<img
src={`${process.env.PUBLIC_URL}/assets/images/watch/cat1.png`}
className="img-fluid blur-up lazyload bg-img"
alt=""
/>
</div>
<h4>watch models</h4>
<ul className="category-link">
<li>
d1 milano
</li>
<li>
damaskeening
</li>
<li>
diving watch
</li>
<li>
dollar watch
</li>
</ul>
<a href="#" className="btn btn-outline">
view more
</a>
</div>
</div>
</Slider>
</div>
</div>
</div>
</section>
{/*Category Six*/}
<section className="section-b-space">
<div className="container">
<div className="row background">
<div className="col">
<a href="#">
<div className="contain-bg">
<h4 data-hover="size 06">size 06</h4>
</div>
</a>
</div>
<div className="col">
<a href="#">
<div className="contain-bg">
<h4>size 07</h4>
</div>
</a>
</div>
<div className="col">
<a href="#">
<div className="contain-bg">
<h4>size 08</h4>
</div>
</a>
</div>
<div className="col">
<a href="#">
<div className="contain-bg">
<h4>size 09</h4>
</div>
</a>
</div>
<div className="col">
<a href="#">
<div className="contain-bg">
<h4>size 10</h4>
</div>
</a>
</div>
</div>
</div>
</section>
</div>
);
}
}
const mapStateToProps = store => {
return {
categories: store.category.categories
};
};
// export default connect(mapStateToProps, { getAllCategories })(ElementCategory);
export default connect(mapStateToProps, { getAllCategories })(ElementCategory);