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
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
"axios": "^0.19.2",
"bootstrap": "^4.4.1",
"classnames": "^2.2.6",
"node-sass": "^4.14.1",
"prop-types": "^15.7.2",
"react": "^16.13.1",
"react-bootstrap": "^1.0.0-beta.17",
Expand All @@ -33,10 +32,11 @@
"react-router-dom": "^5.1.2",
"react-scripts": "3.4.0",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0"
"redux-thunk": "^2.3.0",
"sass": "^1.86.3"
},
"scripts": {
"start": "react-scripts start",
"start": "set NODE_OPTIONS=--openssl-legacy-provider && react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
Expand Down
16 changes: 16 additions & 0 deletions src/components/Products/FavouriteIcon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React, { useState } from 'react';
import styles from './SingleProduct.module.css'

const FavouriteIcon = ({isActive=false}) => {
const[hovered,setHovered]=useState(false)
const iconClass=hovered ||isActive ?'fas fa-heart' :'far fa-heart'
return (
<div className={`${styles.favorite}`}
onMouseEnter={()=>setHovered(true)}
onMouseLeave={()=>setHovered(false)}>
<i className={iconClass}></i>
</div>
)
}

export default FavouriteIcon
213 changes: 111 additions & 102 deletions src/components/Products/NewArrivals.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,105 +4,114 @@
** Github URL: https://github.com/quintuslabs/fashion-cube
*/

import React, { Component } from "react";
import SingleProduct from "./SingleProduct";
import Heading from "../Heading";
import PropTypes from "prop-types";
class NewArrivals extends Component {
constructor(props) {
super(props);
this.state = {
products: this.props.products,
productsBAK: this.props.products,
departments: this.props.departments
};
}

optionClicked(option) {
let FilterList = this.state.productsBAK.filter(
item => item.department === option
);
if (FilterList.length > 0) {
this.setState({ products: FilterList });
} else {
this.setState({ products: this.state.productsBAK });
}
this.setState({ selectedOption: option });
}

render() {
const { products, departments } = this.state;

return (
<div className="new_arrivals" data-aos="fade-up">
<div className="container">
<div className="row">
<Heading title="New Arrivals" data-aos="fade-up" />
</div>
<div className="row align-items-center" data-aos="fade-up">
<div className="col text-center">
<div className="new_arrivals_sorting">
<ul className="arrivals_grid_sorting clearfix button-group filters-button-group">
<li
onClick={() => this.optionClicked("All")}
className={`grid_sorting_button button d-flex flex-column justify-content-center align-items-center ${
this.state.selectedOption === "All"
? "active is-checked"
: null
}`}
>
all
</li>
<li
className={`grid_sorting_button button d-flex flex-column justify-content-center align-items-center ${
this.state.selectedOption === "Women"
? "active is-checked"
: null
}`}
onClick={() => this.optionClicked("Women")}
>
women's
</li>

<li
className={`grid_sorting_button button d-flex flex-column justify-content-center align-items-center ${
this.state.selectedOption === "Men"
? "active is-checked"
: null
}`}
onClick={() => this.optionClicked("Men")}
>
men's
</li>
</ul>
</div>
</div>
</div>
<div className="row">
{products &&
products.slice(0, 8).map((item, index) => {
return (
<div
className="col-lg-3 col-sm-6"
key={index}
data-aos="zoom-in"
>
<SingleProduct
productItem={item}
addToBag={this.props.addToBag}
/>
</div>
);
})}
</div>
</div>
</div>
);
}
}

NewArrivals.propTypes = {
addToCart: PropTypes.func
};

export default NewArrivals;
import React, { Component } from "react";
import SingleProduct from "./SingleProduct";
import Heading from "../Heading";
import PropTypes from "prop-types";
import jumpTo from "../../modules/Navigation";
class NewArrivals extends Component {
constructor(props) {
super(props);
this.state = {
products: this.props.products,
productsBAK: this.props.products,
departments: this.props.departments
};
}

optionClicked(option) {
let FilterList = this.state.productsBAK.filter(
item => item.department === option
);
if (FilterList.length > 0) {
this.setState({ products: FilterList });
} else {
this.setState({ products: this.state.productsBAK });
}
this.setState({ selectedOption: option });
}
handleNavigate = (productId) => {
jumpTo(`/fashion-cube/single-product/${productId}`);
};
handleAddToCart = (productId) => {
this.props.addToBag(productId)
};
render() {
const { products, departments } = this.state;

return (
<div className="new_arrivals" data-aos="fade-up">
<div className="container">
<div className="row">
<Heading title="New Arrivals" data-aos="fade-up" />

</div>
<div className="row align-items-center " data-aos="fade-up">
<div className="col text-center">
<div className="new_arrivals_sorting">
<ul className="arrivals_grid_sorting clearfix button-group filters-button-group">
<li
onClick={() => this.optionClicked("All")}
className={`grid_sorting_button button d-flex flex-column justify-content-center align-items-center ${
this.state.selectedOption === "All"
? "active is-checked"
: null
}`}
>
all
</li>
<li
className={`grid_sorting_button button d-flex flex-column justify-content-center align-items-center ${
this.state.selectedOption === "Women"
? "active is-checked"
: null
}`}
onClick={() => this.optionClicked("Women")}
>
women's
</li>

<li
className={`grid_sorting_button button d-flex flex-column justify-content-center align-items-center ${
this.state.selectedOption === "Men"
? "active is-checked"
: null
}`}
onClick={() => this.optionClicked("Men")}
>
men's
</li>
</ul>
</div>
</div>
</div>
<div className="row">
{products &&
products.slice(0, 8).map((item, index) => {
return (
<div
className="col-lg-3 col-sm-6"
key={index}
data-aos="zoom-in"
>
<SingleProduct
productItem={item}
onNavigate={this.handleNavigate}
onAddToCart={this.handleAddToCart}
/>
</div>
);
})}
</div>
</div>
</div>
);
}
}

NewArrivals.propTypes = {
addToCart: PropTypes.func
};

export default NewArrivals;

22 changes: 22 additions & 0 deletions src/components/Products/ProductPrice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react'
import styles from './SingleProduct.module.css';
import SkeletonProduct from './SkeltonProduct';
const ProductPrice = ({productItem}) => {
const newprice=productItem?.price

if(!newprice){
return(
<SkeletonProduct type={'text'}/>
)
}
const oldPrice=(parseFloat(newprice) + 30).toFixed(2)
return (
<h2 className={styles.price}>
<span className={styles.oldprice}> ₹ {oldPrice}</span>
<span className={styles.newprice}>₹ {newprice}</span>

</h2>
)
}

export default ProductPrice
107 changes: 64 additions & 43 deletions src/components/Products/SingleProduct.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,67 @@
** Github URL: https://github.com/quintuslabs/fashion-cube
*/

import React from "react";
import jumpTo from "../../modules/Navigation";

function SingleProduct(props) {
const { productItem } = props;
return (
<div className="product-item men">
<div
className="product discount product_filter"
onClick={() =>
jumpTo(`/fashion-cube/single-product/${productItem._id}`)
}
>
<div className="product_image">
<img src={productItem.imagePath} alt="" className="img-fluid" />
</div>
<div className="favorite favorite_left">
<i className="far fa-heart"></i>
</div>
{/* <div className="product_bubble product_bubble_right product_bubble_red d-flex flex-column align-items-center">
<span>-$20</span>
</div> */}
<div className="product_info">
<h6 className="product_name">
<div>{productItem.title}</div>
</h6>
<div className="product_price">
₹ {productItem.price}
<span> ₹ {(parseFloat(productItem.price) + 30).toFixed(2)}</span>
</div>
</div>
</div>
<div
className="red_button add_to_cart_button"
onClick={() => props.addToBag(productItem._id)}
>
<div style={{ color: "#ffffff" }}>add to cart</div>
</div>
</div>
);
}

export default SingleProduct;
import React, { useState } from "react";
import SkeletonProduct from "./SkeltonProduct";
import FavouriteIcon from "./FavouriteIcon";
import ProductPrice from "./ProductPrice";
import styles from "./SingleProduct.module.css";
const SingleProduct = ({ productItem, onNavigate, onAddToCart }) => {
const[imageError,setImageError]=useState(false)
if (!productItem) {
return <SkeletonProduct type={'product'} />;
}
const HandleNavigate = () => {
onNavigate(productItem._id);
};
const HandleAddToCart = (e) => {
e.stopPropagation();
onAddToCart(productItem._id);
};
return (
<div className={styles.card}>
<div
className={`${styles.product} ${styles.discount}`}
onClick={HandleNavigate}
>
<div className={styles.image}>
{!imageError ?<img
src={productItem.imagePath}
alt={productItem.title}
className={styles.imageTag}
loading="lazy"
onError={()=>setImageError(true)}
/>:<SkeletonProduct type={'image'}/>}

</div>
<div>
<FavouriteIcon />
</div>
{productItem.discount && (
<div className={`${styles.productBubble}`}>
<span>-${productItem.discount}</span>
</div>
)}

<div className={styles.info}>
<h6 className={styles.name}>
<div>{productItem.title}</div>
</h6>
<div>
<ProductPrice productItem={productItem} />
</div>
</div>
<button
className={`${styles.addToCart}`}
onClick={HandleAddToCart}
aria-label={`Add${productItem.title} to cart`}
>
Add to Cart
</button>
</div>
</div>
);
};

export default React.memo(SingleProduct);

Loading