Skip to content
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
33 changes: 31 additions & 2 deletions src/routes/category/components/product-card/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Link, useNavigate } from "react-router";
import { useState } from "react";

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

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

const variantMap: Record<string, string> = {
"3*3": "3*3",
"5*5": "5*5",
"10*10": "10*10"
};

if (categorySlug === "polos") {
variantTitle = "Elige la talla";
variants = ["Small", "Medium", "Large"];
variantParamName = "size";
} else if (categorySlug === "stickers") {
variantTitle = "Elige la medida";
variants = ["3*3", "5*5", "10*10"];
variants = ["3*3", "5*5", "10*10"];
variantParamName = "measure";
}

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

const hoverVariantClick = (variant: string) => {
if (variantParamName === "measure") {
if (product.stickersVariants && product.stickersVariants.length > 0) {
const variantPrice = product.stickersVariants.find(
(v) => v.measure === variant
)?.price;
setHoveredPrice(variantPrice || null);
} else {
setHoveredPrice(null);
}
}
};

const handleMouseLeave = () => {
setHoveredPrice(null);
};

return (
<Link
to={`/products/${product.id}`}
Expand All @@ -59,6 +84,8 @@ export function ProductCard({ product, categorySlug }: ProductCardProps) {
<Button
key={variant}
onClick={(e) => handleVariantClick(e, variant)}
onMouseEnter={() => hoverVariantClick(variant)}
onMouseLeave={handleMouseLeave}
>
{variant}
</Button>
Expand All @@ -70,7 +97,9 @@ export function ProductCard({ product, categorySlug }: ProductCardProps) {
<div className="flex grow flex-col gap-2 p-4">
<h2 className="text-sm font-medium">{product.title}</h2>
<p className="text-sm text-muted-foreground">{product.description}</p>
<p className="mt-auto text-base font-medium">S/{product.price}</p>
<p className="mt-auto text-base font-medium">
S/{hoveredPrice !== null ? hoveredPrice : product.price}
</p>
</div>
{product.isOnSale && (
<span className="absolute top-0 right-0 rounded-bl-xl bg-primary px-2 py-1 text-sm font-medium text-primary-foreground">
Expand Down
4 changes: 2 additions & 2 deletions src/routes/category/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,6 @@ export default function Category({ loaderData }: Route.ComponentProps) {
</div>
</Container>
</section>
</>
);
    </>
  );
}
40 changes: 27 additions & 13 deletions src/services/product.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,6 @@ import type { Product } from "@/models/product.model";

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

export async function getProductsByCategorySlug(
categorySlug: Category["slug"]
): Promise<Product[]> {
const category = await getCategoryBySlug(categorySlug);
const products = await prisma.product.findMany({
where: { categoryId: category.id },
});

return products.map((product) => ({
...product,
price: product.price.toNumber(),
}));
}

export async function getProductById(id: number): Promise<Product | null> {
const product = await prisma.product.findUnique({
Expand Down Expand Up @@ -48,3 +35,30 @@ export async function getAllProducts(): Promise<Product[]> {
price: p.price.toNumber(),
}));
}

export async function getProductsByCategorySlug(
categorySlug: Category["slug"]
): Promise<Product[]> {
const category = await getCategoryBySlug(categorySlug);
const products = await prisma.product.findMany({
where: { categoryId: category.id },
include: {
stickersVariants: true,
variants: true
},
});

return products.map((product) => ({
...product,
price: product.price.toNumber(),
variants: product.variants?.map(v => ({
id: v.id,
size: v.size as "small" | "medium" | "large",
})),
stickersVariants: product.stickersVariants?.map(s => ({
id: s.id,
measure: s.measure as "3*3" | "5*5" | "10*10",
price: s.price.toNumber(),
})),
}));
}