Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0d9e047

Browse files
committedJan 9, 2022
New design for Cart (Responsive) and Footer(Responsive) added
1 parent b107a9b commit 0d9e047

File tree

9 files changed

+158
-69
lines changed

9 files changed

+158
-69
lines changed
 

‎public/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
</head>
3434
<body>
3535
<noscript>You need to enable JavaScript to run this app.</noscript>
36-
<div id="root"></div>
36+
<div id="root" class="bg-gray-200"></div>
3737
<!--
3838
This HTML file is a template.
3939
If you open it directly in the browser, you will see an empty page.

‎src/index.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
@import url('https://fonts.googleapis.com/css2?family=Bungee&display=swap');
66
@import url('https://fonts.googleapis.com/css2?family=Roboto&display=swap');
7+
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300&display=swap');
78

89
.wrapper{
910
position: relative;

‎src/pages/cart/components/Item.jsx

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import React from 'react';
2+
import { useDispatch } from 'react-redux';
3+
import { addToCart, removeFromCart } from '../../../redux/actions/cart';
4+
export const Item = ({ item }) => {
5+
//const { name, price, product, image, qty, countInStock } = props;
6+
const dispatch = useDispatch();
7+
8+
const removeHandle = ( productId ) => {
9+
dispatch(removeFromCart(productId));
10+
}
11+
return (
12+
<tr>
13+
<td className='flex flex-row mt-8 gap-x-6'>
14+
<img
15+
src={`${process.env.PUBLIC_URL}/img/${item.image}`}
16+
alt="Img_product"
17+
className='w-40 h-32'
18+
/>
19+
<div className='flex flex-col gap-y-3'>
20+
<p
21+
className='w-56 break-words font-bold'>{item.name}</p>
22+
<p
23+
className='text-gray-400'
24+
>
25+
Medida:
26+
</p>
27+
<p
28+
className='text-gray-400'>Marca: {item.brand}</p>
29+
</div>
30+
</td>
31+
<td className='pl-28 lg:pl-0'>
32+
<div className='mx-5'>
33+
<select
34+
value={item.qty}
35+
onChange={(e) => dispatch(addToCart(item.product, Number(e.target.value)))}
36+
className='block h-12 w-36 bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500'
37+
>
38+
{
39+
[...Array(item.countInStock).keys()].map(x =>
40+
<option key={x + 1} value={x + 1}>{x + 1}</option>
41+
)
42+
}
43+
</select>
44+
</div>
45+
</td>
46+
<td>
47+
<div className='mx-5'>
48+
<p className='font-extrabold'>{'$' + item.price.$numberDecimal}</p>
49+
</div>
50+
</td>
51+
<td>
52+
<div className='mx-5 flex flex-row gap-x-4'>
53+
<button type='button'
54+
className='transition ease-out bg-red-500 hover:bg-red-700 duration-300 text-white font-bold py-2 px-4 rounded'
55+
>
56+
<i className="far fa-heart"></i>
57+
</button>
58+
<button type='button'
59+
className='w-full transition ease-out bg-green-500 hover:bg-green-700 duration-300 text-white font-bold py-2 px-4 rounded'
60+
onClick={() => removeHandle(item.product)}
61+
>
62+
Borrar
63+
</button>
64+
</div>
65+
</td>
66+
</tr>
67+
)
68+
}

‎src/pages/cart/pages/CartScreen.jsx

Lines changed: 66 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Link, useLocation, useParams } from 'react-router-dom';
33
import { useSelector } from 'react-redux';
44
import { useDispatch } from 'react-redux';
55
import { addToCart } from '../../../redux/actions/cart';
6+
import { Item } from '../components/Item';
67
export default function CartScreen() {
78
const params = useParams();
89
const dispatch = useDispatch();
@@ -14,11 +15,17 @@ export default function CartScreen() {
1415

1516
const cart = useSelector((state) => state.cart);
1617
const { cartItems, error } = cart;
18+
19+
const precioTotal = cartItems.reduce((a, c) => a + (c.price.$numberDecimal * c.qty), 0).toFixed(2);
20+
const descuento = 0.00;
21+
const total = (precioTotal - (precioTotal * descuento)).toFixed(2);
1722
useEffect(() => {
1823
if (productId) {
1924
dispatch(addToCart(productId, qty));
2025
}
2126
}, [dispatch, productId, qty]);
27+
28+
2229
return (
2330
<div className='container mx-auto px-4'>
2431
{
@@ -30,65 +37,69 @@ export default function CartScreen() {
3037
Cart is empty. <Link to="/">Go shopping</Link>
3138
</div>
3239
) : (
33-
<div className='flex flex-row gap-x-5 mt-10'>
34-
<div className='w-9/12 flex flex-col'>
35-
<div className='flex justify-between'>
36-
<p className='font-semibold text-2xl'>Shipping Cart</p>
37-
<p className='text-lg text-gray-600 font-semibold'>Precio</p>
40+
<div className='container mx-auto font-open my-10'>
41+
<div className='
42+
flex flex-col gap-y-5
43+
lg:flex-row lg:gap-x-8 lg:gap-y-0
44+
'>
45+
<div
46+
style={{ height: '26rem' }}
47+
className='
48+
w-full bg-white rounded-lg shadow-xl overflow-auto
49+
lg:w-9/12
50+
'>
51+
<table className='table-auto'>
52+
<thead>
53+
<tr>
54+
<th className='text-gray-400 text-left pl-5 pt-5'>Producto</th>
55+
<th className='text-gray-400 text-left pl-32 lg:pl-5 pt-5'>Cantidad</th>
56+
<th className='text-gray-400 text-left pl-5 pt-5'>Precio</th>
57+
<th className='text-gray-400 text-left pl-5 pt-5'>Acciones</th>
58+
</tr>
59+
</thead>
60+
<tbody>
61+
{
62+
cartItems.map((item, index) => (
63+
<Item item={ item } key={index} />
64+
))
65+
}
66+
</tbody>
67+
</table>
3868
</div>
39-
<div className='w-full h-1 my-4 bg-gray-300'></div>
40-
{
41-
cartItems.map((item, index) => (
42-
<div key={index} className='flex flex-row mt-10 gap-x-10'>
43-
44-
<div>
45-
<img
46-
src={`${process.env.PUBLIC_URL}/img/${item.image}`}
47-
alt="img_product"
48-
className='w-40'
49-
/>
50-
</div>
51-
<div>
52-
<p className='text-xl font-semibold text-blue-600'>{item.name.toUpperCase()}</p>
53-
{item.qty > 0 && <p className='text-xs my-2 text-green-600'>Disponible</p>}
54-
<select
55-
value={item.qty}
56-
onChange={(e) => dispatch(addToCart(item.product, Number(e.target.value)))}
57-
className='mt-5 block h-12 w-36 bg-gray-200 border border-gray-200 text-gray-700 py-3 px-4 pr-8 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500'
58-
>
59-
{
60-
[...Array(item.countInStock).keys()].map(x =>
61-
<option key={x + 1} value={x + 1}>{x + 1}</option>
62-
)
63-
}
64-
</select>
65-
<button
66-
type='button'
67-
className='mt-2 bg-red-400 w-36 hover:bg-red-900 text-white font-bold py-2 px-4 rounded'
68-
>
69-
Eliminar
70-
</button>
69+
70+
<div className='w-full lg:w-3/12'>
71+
<div className='flex flex-col gap-y-5'>
72+
<div className='w-full rounded-lg bg-white shadow-xl'>
73+
<div className='mx-5 my-5'>
74+
<div className='mb-5'>
75+
<p className=''>Tiene cupon?</p>
76+
</div>
77+
<div>
78+
<input type="text"
79+
className='shadow appearance-none border rounded-l-lg w-8/12 py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline'
80+
placeholder='Cupon...'
81+
/>
82+
<button type='button'
83+
className='bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded-r-lg'
84+
>Aplicar</button>
85+
</div>
7186
</div>
72-
<div className='ml-auto mr-0'>
73-
<p className='font-semibold text-2xl text-right'>US$ { item.price.$numberDecimal }</p>
87+
</div>
88+
89+
<div className='w-full rounded-lg bg-white shadow-xl'>
90+
<div className='flex flex-col gap-y-5 mx-5 my-5'>
91+
<p className='font-semibold'>Precio Total: <span className='font-extrabold ml-3'>{'$' + cartItems.reduce((a, c) => a + (c.price.$numberDecimal * c.qty), 0).toFixed(2)}</span></p>
92+
<p className='font-semibold'>Descuento: <span className='font-extrabold text-red-600 ml-3'>{'$' + descuento}</span></p>
93+
<p className='font-semibold'>Total: <span className='font-extrabold ml-3'>{'$' + total}</span></p>
94+
<button type='button'
95+
className='transition ease-in-out bg-green-500 hover:bg-green-700 hover:scale-110 text-white font-bold py-2 px-4 rounded duration-300'
96+
>Proceder</button>
97+
<Link to='/'
98+
className='text-center transition ease-in-out bg-yellow-500 hover:bg-yellow-700 hover:scale-110 text-white font-bold py-2 px-4 rounded duration-300'
99+
>Seguir comprando</Link>
74100
</div>
75101
</div>
76-
))
77-
}
78-
</div>
79-
<div className='w-3/12 bg-gray-200 h-full text-center py-5 px-10'>
80-
<span className='text-gray-900 font-semibold'>
81-
Cart Subtotal ({cartItems.reduce((a, c) => a + c.qty, 0)} items) :
82-
</span>
83-
<strong className='text-lg'> $ {cartItems.reduce((a, c) => a + (c.price.$numberDecimal * c.qty), 0).toFixed(2)}</strong>
84-
<button
85-
type='button'
86-
className='mt-5 bg-green-500 w-full hover:bg-green-700 text-white font-bold py-2 px-4 rounded'
87-
>
88-
Proceder al pago
89-
</button>
90-
<div className='mt-5'>
91-
<p>Productos recomendados</p>
102+
</div>
92103
</div>
93104
</div>
94105
</div>

‎src/pages/product/components/Product.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from "react";
22
import { Link } from 'react-router-dom';
33
export const Product = ({ product }) => {
44
return (
5-
<div className="transition ease-out max-w-sm rounded overflow-hidden shadow-2xl hover:shadow-green-500 duration-300">
5+
<div className="transition ease-out max-w-sm bg-white rounded overflow-hidden shadow-2xl hover:shadow-green-500 duration-300">
66
<img className="w-3/4 mx-12" src={`${process.env.PUBLIC_URL}/img/${product.image}`} alt="Sunset in the mountains" />
77
<div className='flex flex-col mx-10 my-5'>
88

‎src/pages/product/pages/ProductScreen.jsx

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,31 @@ export default function ProductScreen() {
2323
loading ? (<p>Cargando...</p>) : error ? (<p>Error...</p>) :
2424
(
2525
<div className='container mx-auto mt-10' key={product._id}>
26-
<div className="flex flex-row justify-center gap-x-10">
27-
<div className='w-96'>
26+
<div className="
27+
flex flex-col mx-7 justify-center gap-y-10
28+
lg:flex lg:flex-row lg:justify-center lg:gap-x-10 lg:gap-y-0
29+
">
30+
<div className='w-full lg:w-96'>
2831
<img
2932
src={`${process.env.PUBLIC_URL}/img/${product.image}`}
30-
className='shadow-xl p-8'
33+
className='shadow-xl p-8 w-3/4 mx-12 bg-white'
3134
alt="IMG_PRODUCT"
3235
/>
3336
<div className='flex flex-row justify-center gap-x-4 mt-5'>
34-
<div className='w-3/12 h-24 shadow-2xl'>imagen de prueba</div>
35-
<div className='w-3/12 shadow-2xl'>imagen de prueba</div>
36-
<div className='w-3/12 shadow-2xl'>imagen de prueba</div>
37+
<div className='w-3/12 h-24 shadow-2xl bg-white'>imagen de prueba</div>
38+
<div className='w-3/12 shadow-2xl bg-white'>imagen de prueba</div>
39+
<div className='w-3/12 shadow-2xl bg-white'>imagen de prueba</div>
3740
</div>
3841
</div>
39-
<div className='w-96'>
40-
<p className='font-semibold'>{product.name}</p>
42+
<div className='w-full lg:w-96'>
43+
<p className='font-semibold break-normal'>{product.name}</p>
4144
<p className='text-cyan-700 my-3' >Marca: {product.brand}</p>
4245
{
4346
product.description
4447
}
45-
</div>
46-
<div className='w-80'>
47-
<div className='w-full border-2 rounded-lg p-7'>
48+
</div>
49+
<div className='w-full lg:w-80'>
50+
<div className='w-full border-2 rounded-lg p-7 bg-white'>
4851
<p className='my-3 text-xl'><strong>Precio: </strong>{'$' + product.price.$numberDecimal}</p>
4952
<p className={`my-3 text-xl ${product.stock > 0 ? 'text-black' : 'text-red-600'}`}><strong className='text-black'>Estado: </strong>{product.stock > 0 ? 'En stock' : 'Sin stock'}</p>
5053
<strong className='text-xl'>Cantidad: </strong>

‎src/redux/actions/cart.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ export const addToCart = ( id, qty ) => async( dispatch, getState ) => {
99
type: CART_ADD_ITEM,
1010
payload: {
1111
name: data.name,
12+
description: data.description,
13+
brand: data.brand,
14+
category: data.category,
15+
createdAt: data.createdAt,
16+
updatedAt: data.updatedAt,
1217
image: data.image,
1318
price: data.price,
1419
countInStock: data.stock,

‎src/shared/footer/Footer.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
export const Footer = () => {
33
return (
44
<div className=''>
5-
<div className='flex flex-col justify-center py-10'>
5+
<div className='flex flex-col justify-center py-10 mx-5 lg:mx-0'>
66
<div className='text-center text-white py-5'>
77
<b className='font-semibold text-2xl'>ShoppingStar</b> es una tienda digital construida en NodeJS
88
integrada con ReactJS, Express, etc.

‎tailwind.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module.exports = {
66
extend: {},
77
fontFamily: {
88
'body': ['"Bungee"'],
9+
'open': ['"Open Sans"', 'sans-serif']
910
}
1011
},
1112
plugins: [],

0 commit comments

Comments
 (0)
Please sign in to comment.