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
104 changes: 52 additions & 52 deletions prisma/initial_data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ export const categories = [
];

export const variantAttributes = [
{ name: "no aplica" },
{ name: "talla" },
{ name: "dimensiones" },
{ name: "no aplica" },
]

export const products = [
Expand Down Expand Up @@ -357,74 +357,74 @@ export const products = [

export const variantAttributeValues = [
// --- POLOS (talla: S, M, L) ---
{ attributeId: 1, productId: 1, value: "S", price: 20.0 },
{ attributeId: 1, productId: 1, value: "M", price: 20.0 },
{ attributeId: 1, productId: 1, value: "L", price: 20.0 },
{ attributeId: 1, productId: 1, value: "Small", price: 20.0 },
{ attributeId: 1, productId: 1, value: "Medium", price: 20.0 },
{ attributeId: 1, productId: 1, value: "Large", price: 20.0 },

{ attributeId: 1, productId: 2, value: "S", price: 20.0 },
{ attributeId: 1, productId: 2, value: "M", price: 20.0 },
{ attributeId: 1, productId: 2, value: "L", price: 20.0 },
{ attributeId: 1, productId: 2, value: "Small", price: 20.0 },
{ attributeId: 1, productId: 2, value: "Medium", price: 20.0 },
{ attributeId: 1, productId: 2, value: "Large", price: 20.0 },

{ attributeId: 1, productId: 3, value: "S", price: 20.0 },
{ attributeId: 1, productId: 3, value: "M", price: 20.0 },
{ attributeId: 1, productId: 3, value: "L", price: 20.0 },
{ attributeId: 1, productId: 3, value: "Small", price: 20.0 },
{ attributeId: 1, productId: 3, value: "Medium", price: 20.0 },
{ attributeId: 1, productId: 3, value: "Large", price: 20.0 },

{ attributeId: 1, productId: 4, value: "S", price: 20.0 },
{ attributeId: 1, productId: 4, value: "M", price: 20.0 },
{ attributeId: 1, productId: 4, value: "L", price: 20.0 },
{ attributeId: 1, productId: 4, value: "Small", price: 20.0 },
{ attributeId: 1, productId: 4, value: "Medium", price: 20.0 },
{ attributeId: 1, productId: 4, value: "Large", price: 20.0 },

{ attributeId: 1, productId: 5, value: "S", price: 25.0 },
{ attributeId: 1, productId: 5, value: "M", price: 25.0 },
{ attributeId: 1, productId: 5, value: "L", price: 25.0 },
{ attributeId: 1, productId: 5, value: "Small", price: 25.0 },
{ attributeId: 1, productId: 5, value: "Medium", price: 25.0 },
{ attributeId: 1, productId: 5, value: "Large", price: 25.0 },

{ attributeId: 1, productId: 6, value: "S", price: 25.0 },
{ attributeId: 1, productId: 6, value: "M", price: 25.0 },
{ attributeId: 1, productId: 6, value: "L", price: 25.0 },
{ attributeId: 1, productId: 6, value: "Small", price: 25.0 },
{ attributeId: 1, productId: 6, value: "Medium", price: 25.0 },
{ attributeId: 1, productId: 6, value: "Large", price: 25.0 },

{ attributeId: 1, productId: 7, value: "S", price: 25.0 },
{ attributeId: 1, productId: 7, value: "M", price: 25.0 },
{ attributeId: 1, productId: 7, value: "L", price: 25.0 },
{ attributeId: 1, productId: 7, value: "Small", price: 25.0 },
{ attributeId: 1, productId: 7, value: "Medium", price: 25.0 },
{ attributeId: 1, productId: 7, value: "Large", price: 25.0 },

{ attributeId: 1, productId: 8, value: "S", price: 15.0 },
{ attributeId: 1, productId: 8, value: "M", price: 15.0 },
{ attributeId: 1, productId: 8, value: "L", price: 15.0 },
{ attributeId: 1, productId: 8, value: "Small", price: 15.0 },
{ attributeId: 1, productId: 8, value: "Medium", price: 15.0 },
{ attributeId: 1, productId: 8, value: "Large", price: 15.0 },

{ attributeId: 1, productId: 9, value: "S", price: 15.0 },
{ attributeId: 1, productId: 9, value: "M", price: 15.0 },
{ attributeId: 1, productId: 9, value: "L", price: 15.0 },
{ attributeId: 1, productId: 9, value: "Small", price: 15.0 },
{ attributeId: 1, productId: 9, value: "Medium", price: 15.0 },
{ attributeId: 1, productId: 9, value: "Large", price: 15.0 },

// --- STICKERS (dimensiones: 3x3, 6x6, 9x9) ---
{ attributeId: 2, productId: 10, value: "3x3", price: 2.99 },
{ attributeId: 2, productId: 10, value: "5x5", price: 3.99 },
{ attributeId: 2, productId: 10, value: "10x10", price: 4.99 },
{ attributeId: 2, productId: 10, value: "3x3 cm", price: 2.99 },
{ attributeId: 2, productId: 10, value: "5x5 cm", price: 3.99 },
{ attributeId: 2, productId: 10, value: "10x10 cm", price: 4.99 },

{ attributeId: 2, productId: 11, value: "3x3", price: 2.49 },
{ attributeId: 2, productId: 11, value: "5x5", price: 3.49 },
{ attributeId: 2, productId: 11, value: "10x10", price: 4.49 },
{ attributeId: 2, productId: 11, value: "3x3 cm", price: 2.49 },
{ attributeId: 2, productId: 11, value: "5x5 cm", price: 3.49 },
{ attributeId: 2, productId: 11, value: "10x10 cm", price: 4.49 },

{ attributeId: 2, productId: 12, value: "3x3", price: 3.99 },
{ attributeId: 2, productId: 12, value: "5x5", price: 4.99 },
{ attributeId: 2, productId: 12, value: "10x10", price: 5.99 },
{ attributeId: 2, productId: 12, value: "3x3 cm", price: 3.99 },
{ attributeId: 2, productId: 12, value: "5x5 cm", price: 4.99 },
{ attributeId: 2, productId: 12, value: "10x10 cm", price: 5.99 },

{ attributeId: 2, productId: 13, value: "3x3", price: 2.99 },
{ attributeId: 2, productId: 13, value: "5x5", price: 3.99 },
{ attributeId: 2, productId: 13, value: "10x10", price: 4.99 },
{ attributeId: 2, productId: 13, value: "3x3 cm", price: 2.99 },
{ attributeId: 2, productId: 13, value: "5x5 cm", price: 3.99 },
{ attributeId: 2, productId: 13, value: "10x10 cm", price: 4.99 },

{ attributeId: 2, productId: 14, value: "3x3", price: 2.49 },
{ attributeId: 2, productId: 14, value: "5x5", price: 3.49 },
{ attributeId: 2, productId: 14, value: "10x10", price: 4.49 },
{ attributeId: 2, productId: 14, value: "3x3 cm", price: 2.49 },
{ attributeId: 2, productId: 14, value: "5x5 cm", price: 3.49 },
{ attributeId: 2, productId: 14, value: "10x10 cm", price: 4.49 },

{ attributeId: 2, productId: 15, value: "3x3", price: 2.49 },
{ attributeId: 2, productId: 15, value: "5x5", price: 3.49 },
{ attributeId: 2, productId: 15, value: "10x10", price: 4.49 },
{ attributeId: 2, productId: 15, value: "3x3 cm", price: 2.49 },
{ attributeId: 2, productId: 15, value: "5x5 cm", price: 3.49 },
{ attributeId: 2, productId: 15, value: "10x10 cm", price: 4.49 },

{ attributeId: 2, productId: 16, value: "3x3", price: 2.99 },
{ attributeId: 2, productId: 16, value: "5x5", price: 3.99 },
{ attributeId: 2, productId: 16, value: "10x10", price: 4.99 },
{ attributeId: 2, productId: 16, value: "3x3 cm", price: 2.99 },
{ attributeId: 2, productId: 16, value: "5x5 cm", price: 3.99 },
{ attributeId: 2, productId: 16, value: "10x10 cm", price: 4.99 },

{ attributeId: 2, productId: 17, value: "3x3", price: 2.99 },
{ attributeId: 2, productId: 17, value: "5x5", price: 3.99 },
{ attributeId: 2, productId: 17, value: "10x10", price: .99 },
{ attributeId: 2, productId: 17, value: "3x3 cm", price: 2.99 },
{ attributeId: 2, productId: 17, value: "5x5 cm", price: 3.99 },
{ attributeId: 2, productId: 17, value: "10x10 cm", price: 4.99 },

// --- TAZAS (no aplica: Único) ---
{ attributeId: 3, productId: 18, value: "Único", price: 14.99 },
Expand Down
29 changes: 18 additions & 11 deletions src/routes/category/components/product-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,25 @@ export function ProductCard({ product }: 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>
{isSticker ? (
<div className="text-xs text-muted-foreground">
<p className="text-base font-semibold text-accent-foreground">
Desde
</p>
<p className="font-medium text-foreground text-base">
S/{product.minPrice} - S/{product.maxPrice}
</p>
</div>
{product.categoryId === 3 ? (
<div className="text-xs text-muted-foreground">
<p className="text-base font-semibold text-accent-foreground">
Desde
</p>
<p className="font-medium text-foreground text-base">
S/{product.minPrice} - S/{product.maxPrice}
</p>
</div>
) : (
<p className="mt-auto text-base font-medium">S/{product.price}</p>
)}
<div className="text-xs text-muted-foreground">
<p className="text-base font-semibold text-accent-foreground">
Precio
</p>
<p className="font-medium text-foreground text-base">
S/{product.price}
</p>
</div>
)}
</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
70 changes: 45 additions & 25 deletions src/routes/product/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from "react";
import { useState, useEffect } from "react";
import { Form, useNavigation } from "react-router";

import { Button, Container, Separator } from "@/components/ui";
Expand All @@ -22,14 +22,57 @@ export default function Product({ loaderData }: Route.ComponentProps) {
const { product } = loaderData;
const navigation = useNavigation();
const cartLoading = navigation.state === "submitting";
const [selectedSize, setSelectedSize] = useState<string>("Medium");

// Estados para manejar variantes
const [selectedVariant, setSelectedVariant] = useState<number | null>(null);
const [currentPrice, setCurrentPrice] = useState<number>(0);

if (!product) {
return <NotFound />;
}

const showSizeSelector = product.categoryId === 1 || product.categoryId === 3;

// Verificar si el producto tiene variantes
const hasVariants = product.variantAttributeValues && product.variantAttributeValues.length > 0;

// Verificar si debe mostrar selectores (solo polos y stickers)
const shouldShowVariants = hasVariants && (product.categoryId === 1 || product.categoryId === 3);

// Agrupar variantes por atributo (en caso de que un producto tenga múltiples tipos de atributos)
const variantGroups = shouldShowVariants
? product.variantAttributeValues.reduce((groups, variant) => {
const attributeName = variant.variantAttribute.name;
if (!groups[attributeName]) {
groups[attributeName] = [];
}
groups[attributeName].push(variant);
return groups;
}, {} as Record<string, typeof product.variantAttributeValues>)
: {};

// Inicializar precio y variante seleccionada
useEffect(() => {
if (hasVariants) {
// Seleccionar la primera variante por defecto
const firstVariant = product.variantAttributeValues[0];
setSelectedVariant(firstVariant.id);
setCurrentPrice(firstVariant.price);
} else {
// Si no hay variantes, usar el precio base del producto (asumiendo que existe)
setCurrentPrice(product.price || 0);
}
}, [product]);

// Manejar cambio de variante
const handleVariantChange = (variantId: number) => {
setSelectedVariant(variantId);
const variant = product.variantAttributeValues.find(v => v.id === variantId);
if (variant) {
setCurrentPrice(variant.price);
}
};

const getAttributeValueId = () => { // AQUI TRAER EL AttributeValueId con el cambio de SEBAS
if (
!product.variantAttributeValues ||
Expand All @@ -41,29 +84,6 @@ export default function Product({ loaderData }: Route.ComponentProps) {
return product.variantAttributeValues[0].id;
};

const getSizeOptions = () => {
if (product.categoryId === 3) {
return {
label: "Dimensiones",
options: [
{ value: "Small", label: "3x3 cm" },
{ value: "Medium", label: "5x5 cm" },
{ value: "Large", label: "10x10 cm" },
],
};
} else {
return {
label: "Talla",
options: [
{ value: "Small", label: "Small" },
{ value: "Medium", label: "Medium" },
{ value: "Large", label: "Large" },
],
};
}
};

const sizeOptions = getSizeOptions();

return (
<>
Expand Down
Loading