Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

117 refactor lo mas vendido #128

Merged
merged 10 commits into from
Sep 11, 2023
Merged
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
39 changes: 23 additions & 16 deletions src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
@layer base {
::-webkit-scrollbar {
background: #ededed;
width: 8px;
}
::-webkit-scrollbar-thumb {
background: #41444384;
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: #3a3b3b;
}
}
@layer utilities {
.title {
font-size: 4rem;
font-weight: bold;
text-align: center;
margin-top: 2rem;
margin-bottom: 2rem;
}
}

@tailwind base;
@tailwind components;
@tailwind utilities;



@layer base {
/*Cambio de estilos para etiquetas como h1, h2,, h3, p, span, div,
es decir estilos por default*/
}
@layer utilities {
.title {
font-size: 4rem;
font-weight: bold;
text-align: center;
margin-top: 2rem;
margin-bottom: 2rem;
}
}
5 changes: 2 additions & 3 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import MainCarousel from '~/components/carousels/mainCarousel';
import { productos } from '~/mockData/mockProducts';
import { brands } from '~/mockData/mockBrands';
import { ContainerCard } from '~/components/containerCards/containerCards';
import { TopSellers } from '~/components/containerCards/containerCards';
import { createIconsTypes } from '~/utils/createIcons';
import { ContainerPage } from './container_page';
import CategoryCategory from '~/components/containerCards/containerCardsCategoty';
Expand All @@ -14,8 +13,8 @@ export default function Home() {
return (
<ContainerPage header={<MainCarousel />}>
<CategoryCategory category={category} />
<TopSellers />
<PaymentMethodsList />
<ContainerCard products={productos} />
<BrandCategory brand={brands} />
</ContainerPage>
);
Expand Down
6 changes: 5 additions & 1 deletion src/app/products/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { ContainerPage } from '../container_page';

export default function Landing() {
return <h1>Hola soy products</h1>;
return <ContainerPage>
Products page
</ContainerPage>;
}
3 changes: 1 addition & 2 deletions src/assets/icons/CarShoping.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ export default function Cash() {
width="100%"
height="100%"
viewBox="0 0 30 30"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 1C0 0.734784 0.105357 0.48043 0.292893 0.292893C0.48043 0.105357 0.734784 0 1 0H4C4.22306 6.1623e-05 4.4397 0.0747014 4.61546 0.212049C4.79122 0.349398 4.91602 0.541568 4.97 0.758L5.78 4H29C29.1479 4.00009 29.2939 4.03298 29.4276 4.0963C29.5612 4.15963 29.6792 4.25181 29.7729 4.3662C29.8666 4.48059 29.9338 4.61435 29.9696 4.75784C30.0054 4.90133 30.009 5.05098 29.98 5.196L27.98 15.196C27.9362 15.4141 27.821 15.6113 27.6526 15.7566C27.4842 15.9018 27.2721 15.9868 27.05 15.998L8.256 16.942L8.83 20H26C26.2652 20 26.5196 20.1054 26.7071 20.2929C26.8946 20.4804 27 20.7348 27 21C27 21.2652 26.8946 21.5196 26.7071 21.7071C26.5196 21.8946 26.2652 22 26 22H8C7.76686 21.9998 7.54113 21.9181 7.36182 21.7691C7.18251 21.6201 7.0609 21.4132 7.018 21.184L4.02 5.214L3.22 2H1C0.734784 2 0.48043 1.89464 0.292893 1.70711C0.105357 1.51957 0 1.26522 0 1ZM6.204 6L7.884 14.958L26.172 14.04L27.78 6H6.204ZM10 22C8.93913 22 7.92172 22.4214 7.17157 23.1716C6.42143 23.9217 6 24.9391 6 26C6 27.0609 6.42143 28.0783 7.17157 28.8284C7.92172 29.5786 8.93913 30 10 30C11.0609 30 12.0783 29.5786 12.8284 28.8284C13.5786 28.0783 14 27.0609 14 26C14 24.9391 13.5786 23.9217 12.8284 23.1716C12.0783 22.4214 11.0609 22 10 22ZM24 22C22.9391 22 21.9217 22.4214 21.1716 23.1716C20.4214 23.9217 20 24.9391 20 26C20 27.0609 20.4214 28.0783 21.1716 28.8284C21.9217 29.5786 22.9391 30 24 30C25.0609 30 26.0783 29.5786 26.8284 28.8284C27.5786 28.0783 28 27.0609 28 26C28 24.9391 27.5786 23.9217 26.8284 23.1716C26.0783 22.4214 25.0609 22 24 22ZM10 24C10.5304 24 11.0391 24.2107 11.4142 24.5858C11.7893 24.9609 12 25.4696 12 26C12 26.5304 11.7893 27.0391 11.4142 27.4142C11.0391 27.7893 10.5304 28 10 28C9.46957 28 8.96086 27.7893 8.58579 27.4142C8.21071 27.0391 8 26.5304 8 26C8 25.4696 8.21071 24.9609 8.58579 24.5858C8.96086 24.2107 9.46957 24 10 24ZM24 24C24.5304 24 25.0391 24.2107 25.4142 24.5858C25.7893 24.9609 26 25.4696 26 26C26 26.5304 25.7893 27.0391 25.4142 27.4142C25.0391 27.7893 24.5304 28 24 28C23.4696 28 22.9609 27.7893 22.5858 27.4142C22.2107 27.0391 22 26.5304 22 26C22 25.4696 22.2107 24.9609 22.5858 24.5858C22.9609 24.2107 23.4696 24 24 24Z"
fill="black"
fill="currentColor"
/>
</svg>
);
Expand Down
26 changes: 26 additions & 0 deletions src/assets/icons/Heart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export default function Heart({ className }: { className: string }) {
return (
<svg
className={className}
xmlns="http://www.w3.org/2000/svg"
width="100%"
height="100%"
viewBox="0 0 24 24"
>
<g transform="translate(24 0) scale(-1 1)">
<g>
<path
d="M19.071 13.142L13.414 18.8a2 2 0 0 1-2.828 0l-5.657-5.657A5 5 0 1 1 12 6.072a5 5 0 0 1 7.071 7.07Z"
opacity="1"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19.071 13.142L13.414 18.8a2 2 0 0 1-2.828 0l-5.657-5.657a5 5 0 0 1 7.07-7.071a5 5 0 0 1 7.072 7.071Z"
/>
</g>
</g>
</svg>
);
}
66 changes: 66 additions & 0 deletions src/components/cards/ProductCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import Image from 'next/image';
import { MainButton } from '../button/button';
import Icon from '~/assets/icons/icon';
import { ProductCardProps } from '~/types/products';
import { useState } from 'react';
import Heart from '~/assets/icons/Heart';

export function ProductCard({
title,
price,
offer,
imageSrc,
}: ProductCardProps) {
const [favorite, setFavorite] = useState(false);
const handleFavorite = () => setFavorite((cur) => !cur);
return (
<div className="p-6 shadow-md hover:shadow-xl rounded-md overflow-hidden bg-white w-[250px] min-h-[330px] relative space-y-3">
<Image
src={imageSrc}
alt="Cubre Volante"
width={245}
height={154}
className="w-full h-[9.625rem] "
/>
<div>
<h3 className="font-semibold mb-2">{title}</h3>
<p className="line-through text-secondary-dm text-sm">{`${toCurrency(
price
)}`}</p>
<p className="font-semibold text-primary-lm ">{`${toCurrency(
price - price * offer
)}`}</p>
</div>
<div className="grid place-content-center">
<MainButton color="red" className="flex gap-x-2 py-2 pl-5">
Añadir al Carrito
<div className="w-6 aspect-square">
<Icon icon="CarShoping" />
</div>
</MainButton>
</div>
<button
onClick={handleFavorite}
className="group absolute right-2 top-0 w-8 aspect-square rounded-full bg-white p-0.5 grid place-content-center"
>
<Heart
className={
favorite
? 'fill-primary-lm stroke-primary-lm group-hover:stroke-text-lm group-hover:fill-text-lm'
: 'fill-none stroke-text-lm group-hover:stroke-primary-lm'
}
/>
</button>
</div>
);
}

function toCurrency(number: number, currency: string = 'COP') {
const formatter = new Intl.NumberFormat(currency, {
currency: currency,
style: 'currency',
minimumFractionDigits: 0,
});

return formatter.format(number);
}
100 changes: 100 additions & 0 deletions src/components/carousels/carousel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
'use client';
import { useRef } from 'react';
import { BsChevronCompactLeft, BsChevronCompactRight } from 'react-icons/bs';

type CarouselProps = {
children: React.ReactNode[];
};

export function Carousel({ children }: CarouselProps) {
const carouselRef = useRef<HTMLDivElement>(null);

function next() {
if (!carouselRef.current) return;

if (carouselRef?.current?.children?.length > 0) {
const firstElement = carouselRef?.current?.children[0];
carouselRef.current.style.transition = '300ms ease-out all';

const size = carouselRef.current.children[0].clientWidth;

carouselRef.current.style.transform = `translatex(-${size}px)`;

const transicion = () => {
if (!carouselRef.current) return;

carouselRef.current.style.transition = 'none';
carouselRef.current.style.transform = 'translatex(0px)';

carouselRef.current.appendChild(firstElement);
carouselRef.current.removeEventListener('transitionend', transicion);
};

carouselRef.current.addEventListener('transitionend', transicion);
}
}
function previus() {
if (!carouselRef.current) return;

if (carouselRef?.current?.children.length > 0) {
const endElement =
carouselRef.current.children[carouselRef.current.children.length - 1];
carouselRef.current.insertBefore(
endElement,
carouselRef?.current?.firstChild
);

carouselRef.current.style.transition = 'none';

const size = carouselRef.current.children[0].clientWidth;
carouselRef.current.style.transform = `translate(-${size}px)`;

setTimeout(() => {
if (!carouselRef.current) return;

carouselRef.current.style.transition = '300ms ease-out all';
carouselRef.current.style.transform = 'translatex(0)';
}, 30);
}
}

if (!children.length) return;

return (
<>
<div className="flex gap-1 relative items-center px-2">
<button
onClick={() => previus()}
className={`w-10 aspect-square rounded-full p-2 bg-white hover:scale-105 hover:text-primary-lm shadow hover:shadow-lg ${''}`}
>
<BsChevronCompactLeft size="100%" />
</button>
<div className="overflow-hidden w-full">
<div
ref={carouselRef}
className="flex flex-nowrap justify-start min-h-[50px]"
>
{children.map((child, i) => {
return (
<div
key={i}
className={`${
i < 4 ? '' : ''
} min-w-full sm:min-w-[calc(100%/2)] md:min-w-[calc(100%/3)] lg:min-w-[calc(100%/4)] px-1 grid place-content-center overflow-hidden`}
>
{child}
</div>
);
})}
</div>
</div>
<button
onClick={() => next()}
className={`w-10 aspect-square rounded-full p-2 bg-white shadow hover:scale-105 hover:text-primary-lm hover:shadow-lg ${''}`}
>
<BsChevronCompactRight size="100%" />
</button>
</div>
</>
);
}
86 changes: 16 additions & 70 deletions src/components/containerCards/containerCards.tsx
Original file line number Diff line number Diff line change
@@ -1,85 +1,31 @@
'use client';
import { useState } from 'react';
import Card from '../cards/landingCard';
import Pagination from '../pagination';
import { ProductCard } from '../cards/ProductCard';
import { productos } from '~/mockData/mockProducts';
import { Carousel } from '../carousels/carousel';
import { ProductsProps } from '~/types/products';

type Brand = {
id: string;
name: string;
};

type Category = {
id: string;
name: string;
};

type Products = {
id: string;
title: string;
state: string;
stock: number;
price: number;
availability: number;
image: string[];
model: string;
year: string;
brand: Brand;
category: Category;
};

type ContainerCardProps = {
products: Products[];
};

export function ContainerCard({ products }: ContainerCardProps) {
const [pagination, setPagination] = useState({
page: 1,
itemsPage: 5,
});

const maximo = Math.ceil(products.length / pagination.itemsPage);
const startIndex = (pagination.page - 1) * pagination.itemsPage;
const endIndex = startIndex + pagination.itemsPage;

const anteriorSiguiente = (action: 'Anterior' | 'Siguiente') => {
if (action === 'Anterior')
setPagination({
...pagination,
page: pagination.page - 1,
});
else if (action === 'Siguiente')
setPagination({
...pagination,
page: pagination.page + 1,
});
};
export function TopSellers() {
const products = productos.slice(0, 10);

return (
<div>
<h1 className='title'>
Productos
</h1>
<div className="grid justify-items-center grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-8">
{products.slice(startIndex, endIndex).map((producto: Products) => {
<div className="my-8">
<div className="grid place-content-center bg-[#13131D] text-white border-b-4 border-b-[#ff0000] py-5 mb-6">
<h2 className="text-2xl">Lo más vendidos</h2>
</div>
<Carousel>
{products.map((producto: ProductsProps) => {
const { title, id, price, image } = producto;
return (
<Card
<ProductCard
key={id}
title={title}
price={price.toString()}
nota={title}
price={price}
offer={0.1}
imageSrc={image[0]}
/>
);
})}
</div>
<div className="flex justify-center items-center text-center m-10">
<Pagination
page={pagination.page}
anteriorSiguiente={anteriorSiguiente}
maximo={maximo}
/>
</div>
</Carousel>
</div>
);
}
Loading