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
11 changes: 6 additions & 5 deletions src/lib/cart.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { CartItem, CartItemInput } from "@/models/cart.model";
import { type Product } from "@/models/product.model";
// import { type Product } from "@/models/product.model";
import { type VariantAttributeValue } from "@/models/variant-attribute.model";
import {
alterQuantityCartItem,
deleteRemoteCartItem,
Expand All @@ -18,14 +19,14 @@ export async function getCart(userId?: number, sessionCartId?: string) {
export async function addToCart(
userId: number | undefined,
sessionCartId: string | undefined,
productId: Product["id"],
attributeValueId: VariantAttributeValue["id"],
quantity: number = 1
) {
try {
const updatedCart = await alterQuantityCartItem(
userId,
sessionCartId,
productId,
attributeValueId,
quantity
);
return updatedCart;
Expand Down Expand Up @@ -62,10 +63,10 @@ export function calculateTotal(items: CartItem[] | CartItemInput[]): number {
// Type guard to determine which type we're working with
if ("product" in item) {
// CartItem - has a product property
return total + item.product.price * item.quantity;
return total + Number(item.product.price) * item.quantity;
} else {
// CartItemInput - has price directly
return total + item.price * item.quantity;
return total + Number(item.price) * item.quantity;
}
}, 0);
}
2 changes: 1 addition & 1 deletion src/models/cart.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export type CartProductInfo = Pick<
export type CartItemWithProduct = {
product: CartProductInfo;
quantity: number;
attributeId: number;
attributeValueId: number;
};

// Tipo para el carrito con items y productos incluidos
Expand Down
1 change: 1 addition & 0 deletions src/models/product.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type Product = PrismaProduct & {
price?: number | null;
minPrice?: number | null;
maxPrice?: number | null;
variantAttributeValues?: VariantAttributeValue[];
};

export type ProductVariantValue = PrismaProduct & {
Expand Down
4 changes: 2 additions & 2 deletions src/routes/cart/add-item/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import type { Route } from "../+types";

export async function action({ request }: Route.ActionArgs) {
const formData = await request.formData();
const productId = Number(formData.get("productId"));
const attributeValueId = Number(formData.get("attributeValueId"));
const quantity = Number(formData.get("quantity")) || 1;
const redirectTo = formData.get("redirectTo") as string | null;
const session = await getSession(request.headers.get("Cookie"));
const sessionCartId = session.get("sessionCartId");
const userId = session.get("userId");

await addToCart(userId, sessionCartId, productId, quantity);
await addToCart(userId, sessionCartId, attributeValueId, quantity);

return redirect(redirectTo || "/cart");
}
12 changes: 6 additions & 6 deletions src/routes/cart/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default function Cart({ loaderData }: Route.ComponentProps) {
Carrito de compras
</h1>
<div className="border-solid border rounded-xl flex flex-col">
{cart?.items?.map(({ product, quantity, id }) => (
{cart?.items?.map(({ product, quantity, id, attributeValueId }) => (
<div key={product.id} className="flex gap-7 p-6 border-b">
<div className="w-20 rounded-xl bg-muted">
<img
Expand All @@ -55,14 +55,14 @@ export default function Cart({ loaderData }: Route.ComponentProps) {
</div>
<div className="flex flex-col gap-2 md:flex-row md:justify-between md:items-center">
<p className="text-sm font-medium">
${product.price.toFixed(2)}
${product.price!.toFixed(2)}
</p>
<div className="flex gap-4 items-center">
<Form method="post" action="/cart/add-item">
<input type="hidden" name="quantity" value="-1" />
<Button
name="productId"
value={product.id}
name="attributeValueId"
value={attributeValueId}
variant="outline"
size="sm-icon"
disabled={quantity === 1}
Expand All @@ -77,8 +77,8 @@ export default function Cart({ loaderData }: Route.ComponentProps) {
<Button
variant="outline"
size="sm-icon"
name="productId"
value={product.id}
name="attributeValueId"
value={attributeValueId}
>
<Plus />
</Button>
Expand Down
2 changes: 1 addition & 1 deletion src/routes/checkout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ export default function Checkout({
<div className="flex text-sm font-medium gap-4 items-center self-end">
<p>{quantity}</p>
<X className="w-4 h-4" />
<p>S/{product.price.toFixed(2)}</p>
<p>S/{product.price!.toFixed(2)}</p>
</div>
</div>
</div>
Expand Down
58 changes: 44 additions & 14 deletions src/routes/product/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { Form, useNavigation } from "react-router";
import { useState } from "react";
import { Form, useNavigation } from "react-router";

import { Button, Container, Separator } from "@/components/ui";
import { type Product } from "@/models/product.model";
import { getProductById } from "@/services/product.service";

import NotFound from "../not-found";

import type { Route } from "./+types";

export async function loader({ params }: Route.LoaderArgs) {
Expand All @@ -26,25 +29,36 @@ export default function Product({ loaderData }: Route.ComponentProps) {
}

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


const getAttributeValueId = () => { // AQUI TRAER EL AttributeValueId con el cambio de SEBAS
if (
!product.variantAttributeValues ||
product.variantAttributeValues.length === 0
) {
return undefined;
}
// Devuelve el attributeId de la posición 0
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" }
]
{ value: "Large", label: "10x10 cm" },
],
};
} else {
return {
label: "Talla",
options: [
{ value: "Small", label: "Small" },
{ value: "Medium", label: "Medium" },
{ value: "Large", label: "Large" }
]
{ value: "Large", label: "Large" },
],
};
}
};
Expand All @@ -67,7 +81,14 @@ export default function Product({ loaderData }: Route.ComponentProps) {
{product.title}
{showSizeSelector && (
<span className="text-muted-foreground">
{" "}({sizeOptions.options.find(option => option.value === selectedSize)?.label})
{" "}
(
{
sizeOptions.options.find(
(option) => option.value === selectedSize
)?.label
}
)
</span>
)}
</h1>
Expand All @@ -78,12 +99,16 @@ export default function Product({ loaderData }: Route.ComponentProps) {

{showSizeSelector && (
<div className="mb-9">
<p className="text-sm font-semibold text-accent-foreground mb-2">{sizeOptions.label}</p>
<p className="text-sm font-semibold text-accent-foreground mb-2">
{sizeOptions.label}
</p>
<div className="flex gap-2">
{sizeOptions.options.map((option) => (
<Button
key={option.value}
variant={selectedSize === option.value ? "default" : "secondary"}
variant={
selectedSize === option.value ? "default" : "secondary"
}
size="lg"
onClick={() => setSelectedSize(option.value)}
>
Expand All @@ -100,20 +125,25 @@ export default function Product({ loaderData }: Route.ComponentProps) {
name="redirectTo"
value={`/products/${product.id}`}
/>
<input
type="hidden"
name="attributeValueId"
value={getAttributeValueId() ?? ""}
/>
<Button
size="xl"
className="w-full md:w-80"
type="submit"
name="productId"
value={product.id}
// name="productId"
// value={product.id}
disabled={cartLoading}
>
{cartLoading ? "Agregando..." : "Agregar al Carrito"}
</Button>
</Form>

<Separator className="my-6" />

<div>
<h2 className="text-sm font-semibold text-accent-foreground mb-6">
Características
Expand All @@ -129,4 +159,4 @@ export default function Product({ loaderData }: Route.ComponentProps) {
</section>
</>
);
}
}
8 changes: 4 additions & 4 deletions src/services/cart.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export async function createRemoteItems(
await prisma.cartItem.createMany({
data: items.map((item) => ({
cartId: cart.id,
attributeValueId: item.attributeId, // modificar
attributeValueId: item.attributeValueId,
quantity: item.quantity,
})),
});
Expand All @@ -154,13 +154,13 @@ export async function createRemoteItems(
export async function alterQuantityCartItem(
userId: User["id"] | undefined,
sessionCartId: string | undefined,
attributeId: number,
attributeValueId: number,
quantity: number = 1
): Promise<CartWithItems> {
const cart = await getOrCreateCart(userId, sessionCartId);

const existingItem = cart.items.find(
(item) => item.attributeValueId === attributeId
(item) => item.attributeValueId === attributeValueId
);

if (existingItem) {
Expand All @@ -180,7 +180,7 @@ export async function alterQuantityCartItem(
await prisma.cartItem.create({
data: {
cartId: cart.id,
attributeValueId: attributeId,
attributeValueId: attributeValueId,
quantity,
},
});
Expand Down