Skip to content

Commit b09d189

Browse files
author
Kellyarias02
committed
Refactor: to add interactivity hover category stickers and to improve the user experiencie.
1 parent 885eba2 commit b09d189

File tree

3 files changed

+60
-17
lines changed

3 files changed

+60
-17
lines changed

src/routes/category/components/product-card/index.tsx

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Link, useNavigate } from "react-router";
2+
import { useState } from "react";
23

34
import type { Product } from "@/models/product.model";
45
import { Button } from "@/components/ui";
@@ -10,17 +11,24 @@ interface ProductCardProps {
1011

1112
export function ProductCard({ product, categorySlug }: ProductCardProps) {
1213
const navigate = useNavigate();
14+
const [hoveredPrice, setHoveredPrice] = useState<number | null>(null);
1315
let variantTitle: string | null = null;
1416
let variants: string[] = [];
1517
let variantParamName: "size" | "measure" | null = null;
1618

19+
const variantMap: Record<string, string> = {
20+
"3*3": "3*3",
21+
"5*5": "5*5",
22+
"10*10": "10*10"
23+
};
24+
1725
if (categorySlug === "polos") {
1826
variantTitle = "Elige la talla";
1927
variants = ["Small", "Medium", "Large"];
2028
variantParamName = "size";
2129
} else if (categorySlug === "stickers") {
2230
variantTitle = "Elige la medida";
23-
variants = ["3*3", "5*5", "10*10"];
31+
variants = ["3*3", "5*5", "10*10"];
2432
variantParamName = "measure";
2533
}
2634

@@ -37,6 +45,23 @@ export function ProductCard({ product, categorySlug }: ProductCardProps) {
3745
}
3846
};
3947

48+
const hoverVariantClick = (variant: string) => {
49+
if (variantParamName === "measure") {
50+
if (product.stickersVariants && product.stickersVariants.length > 0) {
51+
const variantPrice = product.stickersVariants.find(
52+
(v) => v.measure === variant
53+
)?.price;
54+
setHoveredPrice(variantPrice || null);
55+
} else {
56+
setHoveredPrice(null);
57+
}
58+
}
59+
};
60+
61+
const handleMouseLeave = () => {
62+
setHoveredPrice(null);
63+
};
64+
4065
return (
4166
<Link
4267
to={`/products/${product.id}`}
@@ -59,6 +84,8 @@ export function ProductCard({ product, categorySlug }: ProductCardProps) {
5984
<Button
6085
key={variant}
6186
onClick={(e) => handleVariantClick(e, variant)}
87+
onMouseEnter={() => hoverVariantClick(variant)}
88+
onMouseLeave={handleMouseLeave}
6289
>
6390
{variant}
6491
</Button>
@@ -70,7 +97,9 @@ export function ProductCard({ product, categorySlug }: ProductCardProps) {
7097
<div className="flex grow flex-col gap-2 p-4">
7198
<h2 className="text-sm font-medium">{product.title}</h2>
7299
<p className="text-sm text-muted-foreground">{product.description}</p>
73-
<p className="mt-auto text-base font-medium">S/{product.price}</p>
100+
<p className="mt-auto text-base font-medium">
101+
S/{hoveredPrice !== null ? hoveredPrice : product.price}
102+
</p>
74103
</div>
75104
{product.isOnSale && (
76105
<span className="absolute top-0 right-0 rounded-bl-xl bg-primary px-2 py-1 text-sm font-medium text-primary-foreground">

src/routes/category/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,6 @@ export default function Category({ loaderData }: Route.ComponentProps) {
9292
</div>
9393
</Container>
9494
</section>
95-
</>
96-
);
95+
    </>
96+
  );
9797
}

src/services/product.service.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,6 @@ import type { Product } from "@/models/product.model";
44

55
import { getCategoryBySlug } from "./category.service";
66

7-
export async function getProductsByCategorySlug(
8-
categorySlug: Category["slug"]
9-
): Promise<Product[]> {
10-
const category = await getCategoryBySlug(categorySlug);
11-
const products = await prisma.product.findMany({
12-
where: { categoryId: category.id },
13-
});
14-
15-
return products.map((product) => ({
16-
...product,
17-
price: product.price.toNumber(),
18-
}));
19-
}
207

218
export async function getProductById(id: number): Promise<Product | null> {
229
const product = await prisma.product.findUnique({
@@ -48,3 +35,30 @@ export async function getAllProducts(): Promise<Product[]> {
4835
price: p.price.toNumber(),
4936
}));
5037
}
38+
39+
export async function getProductsByCategorySlug(
40+
categorySlug: Category["slug"]
41+
): Promise<Product[]> {
42+
const category = await getCategoryBySlug(categorySlug);
43+
const products = await prisma.product.findMany({
44+
where: { categoryId: category.id },
45+
include: {
46+
stickersVariants: true,
47+
variants: true
48+
},
49+
});
50+
51+
return products.map((product) => ({
52+
...product,
53+
price: product.price.toNumber(),
54+
variants: product.variants?.map(v => ({
55+
id: v.id,
56+
size: v.size as "small" | "medium" | "large",
57+
})),
58+
stickersVariants: product.stickersVariants?.map(s => ({
59+
id: s.id,
60+
measure: s.measure as "3*3" | "5*5" | "10*10",
61+
price: s.price.toNumber(),
62+
})),
63+
}));
64+
}

0 commit comments

Comments
 (0)