Skip to content

Commit

Permalink
Merge pull request #9 from aseerkt/master
Browse files Browse the repository at this point in the history
Single Product Page
  • Loading branch information
Devang47 authored Aug 7, 2021
2 parents b144971 + 9f77d10 commit 7da4e8d
Show file tree
Hide file tree
Showing 10 changed files with 432 additions and 46 deletions.
23 changes: 8 additions & 15 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,26 @@ import Homepage from './Components/Homepage/Homepage';
import MyCart from './Components/CartPage/MyCart';
import SignIn from './Components/SignIn/SignIn';
import ProductList from './Components/ProductList/ProductList';
import SingleProduct from './Components/SingleProduct/SingleProduct';

function App() {
const setQuery = useStore(state => state.setQuery);

useEffect(() => {
setQuery('');
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<Router>
<ShowNavFooter>
<Switch>
<Route exact path="/">
<Homepage />
</Route>
<Route exact path="/register">
<Homepage />
</Route>
<Route exact path="/signin">
<SignIn />
</Route>
<Route exact path="/cart">
<MyCart />
</Route>
<Route exact path="/products">
<ProductList />
</Route>
<Route exact path="/" component={Homepage} />
<Route exact path="/register" component={Homepage} />
<Route exact path="/signin" component={SignIn} />
<Route exact path="/cart" component={MyCart} />
<Route exact path="/products" component={ProductList} />
<Route exact path="/products/:productId" component={SingleProduct} />
</Switch>
</ShowNavFooter>
</Router>
Expand Down
13 changes: 2 additions & 11 deletions src/Components/ProductList/ProductItem.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
import { Link } from 'react-router-dom';
import { numberWithCommas } from '../../utils';
import { formatDate, numberWithCommas } from '../../utils';
import Rating from './Rating';

function formatDate(dt) {
return dt.toLocaleString('en-CA', {
month: 'long',
day: 'numeric',
year: 'numeric',
});
}

function ProductItem({ product }) {
const priceWithoutDiscount = parseInt(
(product.price * 100) / (100 - product.discount),
Expand Down Expand Up @@ -66,8 +58,7 @@ function ProductItem({ product }) {
</div>
<div className="delivery_time">
{/* need to get prime image here */}

{product.fullfilled && <i className='prime'></i>} Get it by
{product.fullfilled && <i className="prime"></i>} Get it by
<strong> {formatDate(deliveryDate)} </strong>
</div>
<div className="free_delivery">
Expand Down
33 changes: 33 additions & 0 deletions src/Components/SingleProduct/ProductCart.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import useStore from '../../store';

function ProductCart({ product }) {
const user_location = useStore(state => state.user_location);
return (
<div className="product-cart">
<p>
<label htmlFor="qty">Quantity: </label>
<select name="qty" id="qty" value="1">
{new Array(9).fill(1).map((_, i) => (
<option key={`${product.id}_${i}`} value={i}>
{i} {i === 0 && '(Delete)'}
</option>
))}
</select>
</p>
<div>
<button className="sign_in_btn">Add to Cart</button>
<button className="sign_in_btn buy_now_btn">Buy Now</button>
</div>
<div className="secure-transaction">
<span class="iconify" data-icon="bx:bxs-lock-alt"></span>
<p>Secure transaction</p>
</div>
<div className="delivery-details">
<span class="iconify" data-icon="akar-icons:location"></span>
<p className="no-underline amz-link">Deliver to {user_location}</p>
</div>
</div>
);
}

export default ProductCart;
166 changes: 166 additions & 0 deletions src/Components/SingleProduct/SingleProduct.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import { Link, useParams } from 'react-router-dom';
import { getProductById } from '../../Data/products/index';
import { capitalizeFirst, formatDate, numberWithCommas } from '../../utils';
import Rating from '../ProductList/Rating';
import ProductCart from './ProductCart';

function DeliveryFeature() {
const items = [
{
id: '8zeyta-kx8gfg-fjk4h3-8sto0p',
dataId: 'RETURNS_POLICY',
name: '7 Days Replacement',
image:
'https://images-na.ssl-images-amazon.com/images/G/31/A2I-Convert/mobile/IconFarm/icon-returns._CB484059092_.png',
},
{
id: 'ibgdh0-jdltm8-4exan-3k9cpe',
dataId: 'AMAZON_DELIVERED',
name: 'Amazon Delivered',
image:
'https://images-na.ssl-images-amazon.com/images/G/31/A2I-Convert/mobile/IconFarm/icon-amazon-delivered._CB485933725_.png',
},
{
id: '6h83sn-2ix3xj-piu7hy-gldgb6',
dataId: 'WARRANTY',
name: '1 Year Warranty',
image:
'https://images-na.ssl-images-amazon.com/images/G/31/A2I-Convert/mobile/IconFarm/icon-warranty._CB485935626_.png',
},
{
id: 'ka0dd9-f9ibnx-cv0w2n-b0lldt',
dataId: 'NO_CONTACT_DELIVERY',
name: 'No-Contact Delivery',
image:
'https://images-na.ssl-images-amazon.com/images/G/31/A2I-Convert/mobile/IconFarm/No_contact_delivery_final._CB432269791_.png',
},
];

return (
<div className="icon-farm-wrapper">
{items.map(i => (
<div
data-name={i.dataId}
id={i.dataId}
class="icon-container"
data-csa-c-id={i.id}
>
<div class="a-section a-spacing-none">
<img
src={i.image}
class="icon-box"
id=""
style={{ height: '35px', width: '35px' }}
alt={i.name}
data-a-image-source={i.image}
/>
</div>
<div class="icon-content">
<Link class="amz-link" href="#">
{i.name}{' '}
</Link>
</div>
</div>
))}
</div>
);
}

function SingleProduct() {
const { productId } = useParams();
const product = getProductById(productId);
const priceWithoutDiscount = parseInt(
(product.price * 100) / (100 - product.discount),
);
let deliveryDate = new Date();
deliveryDate.setDate(deliveryDate.getDate() + product.deliveryDays);

return (
<div className="singleProduct">
<div className="product-image">
<img src={product.image} alt={product.name} />
</div>
<div className="product-details">
<h1>{product.name}</h1>
<p>
Category:{' '}
<Link className="amz-link" to="#">
{capitalizeFirst(product.category)}
</Link>
</p>
<div className="ratings">
<Rating stars={product.stars} />
<span
className="iconify"
data-icon="akar-icons:chevron-down"
data-inline="true"
></span>
<span className="reviews">
{numberWithCommas(product.numReviews)} ratings
</span>
</div>
{product.fullfilled && (
<p>
<img
className="fullfilled-image"
src="https://m.media-amazon.com/images/G/31/marketing/fba/fba-badge_18px._CB485936079_.png"
alt="fullfilled"
/>
</p>
)}
<div className="price-details">
<table>
<tr>
<th>M.R.P.:</th>
<td className="strike">
{numberWithCommas(priceWithoutDiscount)}
</td>
</tr>
<tr>
<th>Deal Price:</th>
<td className="price">{numberWithCommas(product.price)}</td>
</tr>
<tr>
<th>You Save:</th>
<td className="save">
{numberWithCommas(priceWithoutDiscount - product.price)} (
{product.discount}%)
</td>
</tr>
<tr>
<th></th>
<td>Inclusive of all taxes</td>
</tr>
</table>
</div>
<p className="delivery-info">
<span className="free-delivery amz-link">
{product.price > 500 ? 'FREE Delivery' : 'Delivery at'}:
</span>
<strong>{formatDate(deliveryDate)}</strong>
<span className="amz-link">Details</span>
</p>
<DeliveryFeature />
<span className="stock">In Stock.</span>
<p>
Sold by <span className="amz-link">Random Seller</span>
{product.fullfilled && (
<span>
{' '}
and <span className="amz-link">Fulfilled by Amazon</span>
</span>
)}
</p>
<p style={{ marginTop: '1rem' }}>
{product.description} Lorem ipsum dolor, sit amet consectetur
adipisicing elit. Nobis corporis dolore eos veritatis deserunt non?
Consequuntur possimus placeat iste earum at quos facere facilis
dolores voluptate, libero officiis itaque nesciunt.{' '}
</p>
</div>
<ProductCart product={product} />
</div>
);
}

export default SingleProduct;
4 changes: 4 additions & 0 deletions src/Data/products/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,8 @@ function shuffle(array) {

const products = shuffle([...mobiles, ...laptops]);

export function getProductById(id) {
return products.find(p => p.id === id);
}

export default products;
File renamed without changes.
51 changes: 33 additions & 18 deletions src/Styles/_resuable.scss
Original file line number Diff line number Diff line change
@@ -1,25 +1,40 @@
.sign_in_btn {
background-color: #ffd814;
padding: 8px 5px;
display: block;
border: none;
border-radius: 8px;
width: 100%;
text-align: center;
font-size: 13px;
margin: 10px 0;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.061);
cursor: pointer;
&:hover {
background-color: #f6d115;
}
&:active {
background-color: #ceac06;
}
background-color: #ffd814;
padding: 8px 5px;
display: block;
border: none;
border-radius: 8px;
width: 100%;
text-align: center;
font-size: 13px;
margin: 10px 0;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.061);
cursor: pointer;
&:hover {
background-color: #f6d115;
}
&:active {
background-color: #ceac06;
}
}

.bold {
font-weight: 600;
font-weight: 600;
}

.amz-link {
text-decoration: none;
color: #007185;

&:hover {
text-decoration: underline;
cursor: pointer;
color: #c7511f;
}

&.no-underline:hover {
text-decoration: none;
}
}

// Max-width: 1450px or 1500px
Loading

0 comments on commit 7da4e8d

Please sign in to comment.