Skip to content

Commit ccc1059

Browse files
committed
feat: refactor cart and product models to use attributeValueId, update related functions and components
1 parent cd32444 commit ccc1059

File tree

8 files changed

+65
-33
lines changed

8 files changed

+65
-33
lines changed

src/lib/cart.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { CartItem, CartItemInput } from "@/models/cart.model";
2-
import { type Product } from "@/models/product.model";
2+
// import { type Product } from "@/models/product.model";
3+
import { type VariantAttributeValue } from "@/models/variant-attribute.model";
34
import {
45
alterQuantityCartItem,
56
deleteRemoteCartItem,
@@ -18,14 +19,14 @@ export async function getCart(userId?: number, sessionCartId?: string) {
1819
export async function addToCart(
1920
userId: number | undefined,
2021
sessionCartId: string | undefined,
21-
productId: Product["id"],
22+
attributeValueId: VariantAttributeValue["id"],
2223
quantity: number = 1
2324
) {
2425
try {
2526
const updatedCart = await alterQuantityCartItem(
2627
userId,
2728
sessionCartId,
28-
productId,
29+
attributeValueId,
2930
quantity
3031
);
3132
return updatedCart;
@@ -62,10 +63,10 @@ export function calculateTotal(items: CartItem[] | CartItemInput[]): number {
6263
// Type guard to determine which type we're working with
6364
if ("product" in item) {
6465
// CartItem - has a product property
65-
return total + item.product.price * item.quantity;
66+
return total + Number(item.product.price) * item.quantity;
6667
} else {
6768
// CartItemInput - has price directly
68-
return total + item.price * item.quantity;
69+
return total + Number(item.price) * item.quantity;
6970
}
7071
}, 0);
7172
}

src/models/cart.model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export type CartProductInfo = Pick<
3333
export type CartItemWithProduct = {
3434
product: CartProductInfo;
3535
quantity: number;
36-
attributeId: number;
36+
attributeValueId: number;
3737
};
3838

3939
// Tipo para el carrito con items y productos incluidos

src/models/product.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export type Product = PrismaProduct & {
55
price?: number | null;
66
minPrice?: number | null;
77
maxPrice?: number | null;
8+
variantAttributeValues?: VariantAttributeValue[];
89
};
910

1011
export type ProductVariantValue = PrismaProduct & {

src/routes/cart/add-item/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ import type { Route } from "../+types";
77

88
export async function action({ request }: Route.ActionArgs) {
99
const formData = await request.formData();
10-
const productId = Number(formData.get("productId"));
10+
const attributeValueId = Number(formData.get("attributeValueId"));
1111
const quantity = Number(formData.get("quantity")) || 1;
1212
const redirectTo = formData.get("redirectTo") as string | null;
1313
const session = await getSession(request.headers.get("Cookie"));
1414
const sessionCartId = session.get("sessionCartId");
1515
const userId = session.get("userId");
1616

17-
await addToCart(userId, sessionCartId, productId, quantity);
17+
await addToCart(userId, sessionCartId, attributeValueId, quantity);
1818

1919
return redirect(redirectTo || "/cart");
2020
}

src/routes/cart/index.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export default function Cart({ loaderData }: Route.ComponentProps) {
3030
Carrito de compras
3131
</h1>
3232
<div className="border-solid border rounded-xl flex flex-col">
33-
{cart?.items?.map(({ product, quantity, id }) => (
33+
{cart?.items?.map(({ product, quantity, id, attributeValueId }) => (
3434
<div key={product.id} className="flex gap-7 p-6 border-b">
3535
<div className="w-20 rounded-xl bg-muted">
3636
<img
@@ -55,14 +55,14 @@ export default function Cart({ loaderData }: Route.ComponentProps) {
5555
</div>
5656
<div className="flex flex-col gap-2 md:flex-row md:justify-between md:items-center">
5757
<p className="text-sm font-medium">
58-
${product.price.toFixed(2)}
58+
${product.price!.toFixed(2)}
5959
</p>
6060
<div className="flex gap-4 items-center">
6161
<Form method="post" action="/cart/add-item">
6262
<input type="hidden" name="quantity" value="-1" />
6363
<Button
64-
name="productId"
65-
value={product.id}
64+
name="attributeValueId"
65+
value={attributeValueId}
6666
variant="outline"
6767
size="sm-icon"
6868
disabled={quantity === 1}
@@ -77,8 +77,8 @@ export default function Cart({ loaderData }: Route.ComponentProps) {
7777
<Button
7878
variant="outline"
7979
size="sm-icon"
80-
name="productId"
81-
value={product.id}
80+
name="attributeValueId"
81+
value={attributeValueId}
8282
>
8383
<Plus />
8484
</Button>

src/routes/checkout/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ export default function Checkout({
266266
<div className="flex text-sm font-medium gap-4 items-center self-end">
267267
<p>{quantity}</p>
268268
<X className="w-4 h-4" />
269-
<p>S/{product.price.toFixed(2)}</p>
269+
<p>S/{product.price!.toFixed(2)}</p>
270270
</div>
271271
</div>
272272
</div>

src/routes/product/index.tsx

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import { Form, useNavigation } from "react-router";
21
import { useState } from "react";
2+
import { Form, useNavigation } from "react-router";
3+
34
import { Button, Container, Separator } from "@/components/ui";
45
import { type Product } from "@/models/product.model";
56
import { getProductById } from "@/services/product.service";
7+
68
import NotFound from "../not-found";
9+
710
import type { Route } from "./+types";
811

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

2831
const showSizeSelector = product.categoryId === 1 || product.categoryId === 3;
29-
32+
33+
const getAttributeValueId = () => { // AQUI TRAER EL AttributeValueId con el cambio de SEBAS
34+
if (
35+
!product.variantAttributeValues ||
36+
product.variantAttributeValues.length === 0
37+
) {
38+
return undefined;
39+
}
40+
// Devuelve el attributeId de la posición 0
41+
return product.variantAttributeValues[0].id;
42+
};
43+
3044
const getSizeOptions = () => {
3145
if (product.categoryId === 3) {
3246
return {
3347
label: "Dimensiones",
3448
options: [
3549
{ value: "Small", label: "3x3 cm" },
3650
{ value: "Medium", label: "5x5 cm" },
37-
{ value: "Large", label: "10x10 cm" }
38-
]
51+
{ value: "Large", label: "10x10 cm" },
52+
],
3953
};
4054
} else {
4155
return {
4256
label: "Talla",
4357
options: [
4458
{ value: "Small", label: "Small" },
4559
{ value: "Medium", label: "Medium" },
46-
{ value: "Large", label: "Large" }
47-
]
60+
{ value: "Large", label: "Large" },
61+
],
4862
};
4963
}
5064
};
@@ -67,7 +81,14 @@ export default function Product({ loaderData }: Route.ComponentProps) {
6781
{product.title}
6882
{showSizeSelector && (
6983
<span className="text-muted-foreground">
70-
{" "}({sizeOptions.options.find(option => option.value === selectedSize)?.label})
84+
{" "}
85+
(
86+
{
87+
sizeOptions.options.find(
88+
(option) => option.value === selectedSize
89+
)?.label
90+
}
91+
)
7192
</span>
7293
)}
7394
</h1>
@@ -78,12 +99,16 @@ export default function Product({ loaderData }: Route.ComponentProps) {
7899

79100
{showSizeSelector && (
80101
<div className="mb-9">
81-
<p className="text-sm font-semibold text-accent-foreground mb-2">{sizeOptions.label}</p>
102+
<p className="text-sm font-semibold text-accent-foreground mb-2">
103+
{sizeOptions.label}
104+
</p>
82105
<div className="flex gap-2">
83106
{sizeOptions.options.map((option) => (
84107
<Button
85108
key={option.value}
86-
variant={selectedSize === option.value ? "default" : "secondary"}
109+
variant={
110+
selectedSize === option.value ? "default" : "secondary"
111+
}
87112
size="lg"
88113
onClick={() => setSelectedSize(option.value)}
89114
>
@@ -100,20 +125,25 @@ export default function Product({ loaderData }: Route.ComponentProps) {
100125
name="redirectTo"
101126
value={`/products/${product.id}`}
102127
/>
128+
<input
129+
type="hidden"
130+
name="attributeValueId"
131+
value={getAttributeValueId() ?? ""}
132+
/>
103133
<Button
104134
size="xl"
105135
className="w-full md:w-80"
106136
type="submit"
107-
name="productId"
108-
value={product.id}
137+
// name="productId"
138+
// value={product.id}
109139
disabled={cartLoading}
110140
>
111141
{cartLoading ? "Agregando..." : "Agregar al Carrito"}
112142
</Button>
113143
</Form>
114-
144+
115145
<Separator className="my-6" />
116-
146+
117147
<div>
118148
<h2 className="text-sm font-semibold text-accent-foreground mb-6">
119149
Características
@@ -129,4 +159,4 @@ export default function Product({ loaderData }: Route.ComponentProps) {
129159
</section>
130160
</>
131161
);
132-
}
162+
}

src/services/cart.service.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export async function createRemoteItems(
138138
await prisma.cartItem.createMany({
139139
data: items.map((item) => ({
140140
cartId: cart.id,
141-
attributeValueId: item.attributeId, // modificar
141+
attributeValueId: item.attributeValueId,
142142
quantity: item.quantity,
143143
})),
144144
});
@@ -154,13 +154,13 @@ export async function createRemoteItems(
154154
export async function alterQuantityCartItem(
155155
userId: User["id"] | undefined,
156156
sessionCartId: string | undefined,
157-
attributeId: number,
157+
attributeValueId: number,
158158
quantity: number = 1
159159
): Promise<CartWithItems> {
160160
const cart = await getOrCreateCart(userId, sessionCartId);
161161

162162
const existingItem = cart.items.find(
163-
(item) => item.attributeValueId === attributeId
163+
(item) => item.attributeValueId === attributeValueId
164164
);
165165

166166
if (existingItem) {
@@ -180,7 +180,7 @@ export async function alterQuantityCartItem(
180180
await prisma.cartItem.create({
181181
data: {
182182
cartId: cart.id,
183-
attributeValueId: attributeId,
183+
attributeValueId: attributeValueId,
184184
quantity,
185185
},
186186
});

0 commit comments

Comments
 (0)