From ebba704cf1399f95c463ec991f92ef6bab4f535d Mon Sep 17 00:00:00 2001
From: evgongora
Date: Tue, 12 Nov 2024 00:59:50 -0600
Subject: [PATCH 1/7] feat: add shopping cart page and functionality
---
.../_components/features/ProductCatalog.tsx | 9 --
.../_components/features/ProductDetails.tsx | 30 +++++-
.../app/_components/features/ShoppingCart.tsx | 17 +++-
apps/web/src/app/marketplace/page.tsx | 10 +-
apps/web/src/app/product/[id]/page.tsx | 4 +-
.../src/server/api/routers/shoppingCart.ts | 96 +++----------------
6 files changed, 60 insertions(+), 106 deletions(-)
diff --git a/apps/web/src/app/_components/features/ProductCatalog.tsx b/apps/web/src/app/_components/features/ProductCatalog.tsx
index cc587e5..948f794 100755
--- a/apps/web/src/app/_components/features/ProductCatalog.tsx
+++ b/apps/web/src/app/_components/features/ProductCatalog.tsx
@@ -22,14 +22,6 @@ export default function ProductCatalog() {
const [query, setQuery] = useAtom(searchQueryAtom);
const router = useRouter();
- const utils = api.useUtils();
-
- const { mutate: addItem } = api.shoppingCart.addItem.useMutation({
- onSuccess: async () => {
- await utils.shoppingCart.getItems.invalidate();
- },
- });
-
// Using an infinite query to fetch products with pagination
const { data, fetchNextPage, hasNextPage, isFetchingNextPage } =
api.product.getProducts.useInfiniteQuery(
@@ -99,7 +91,6 @@ export default function ProductCatalog() {
variety={product.name}
price={product.price}
badgeText={product.strength}
- isAddingToShoppingCart={false} // Disable shopping cart action for now
onClick={() => accessProductDetails(product.id)} // Trigger add-to-cart action
/>
);
diff --git a/apps/web/src/app/_components/features/ProductDetails.tsx b/apps/web/src/app/_components/features/ProductDetails.tsx
index e841cd0..b155b8c 100644
--- a/apps/web/src/app/_components/features/ProductDetails.tsx
+++ b/apps/web/src/app/_components/features/ProductDetails.tsx
@@ -4,14 +4,17 @@ import Button from "@repo/ui/button";
import { ChatWithSeller } from "@repo/ui/chatWithSeller";
import { DataCard } from "@repo/ui/dataCard";
import PageHeader from "@repo/ui/pageHeader";
+import { useAtom, useAtomValue } from "jotai";
import Image from "next/image";
import { useRouter } from "next/navigation";
import { useState } from "react";
+import { addItemAtom, cartItemsAtom } from "~/store/cartAtom";
import { ProducerInfo } from "./ProducerInfo";
import { SelectionTypeCard } from "./SelectionTypeCard";
interface ProductDetailsProps {
product: {
+ id: number;
image: string;
name: string;
region: string;
@@ -29,22 +32,39 @@ export default function ProductDetails({ product }: ProductDetailsProps) {
const {
image,
name,
- region,
farmName,
roastLevel,
bagsAvailable,
price,
type,
- description,
process,
} = product;
const [quantity, setQuantity] = useState(1);
const [isLiked, setIsLiked] = useState(false);
const router = useRouter();
+ const [isAddingToCart, setIsAddingToCart] = useState(false);
+ const [, addItem] = useAtom(addItemAtom);
+ const items = useAtomValue(cartItemsAtom);
+ const cartItemsCount = items.reduce(
+ (total, item) => total + item.quantity,
+ 0,
+ );
const isSoldOut = type === "SoldOut";
const isFarmer = type === "Farmer";
+ const handleAddToCart = () => {
+ setIsAddingToCart(true);
+ addItem({
+ id: String(product.id),
+ name: product.name,
+ quantity: quantity,
+ price: product.price,
+ imageUrl: product.image,
+ });
+ setIsAddingToCart(false);
+ };
+
return (
@@ -52,7 +72,8 @@ export default function ProductDetails({ product }: ProductDetailsProps) {
title={
{name}
}
showBackButton
onBackClick={() => router.back()}
- hideCart={false}
+ showCart={true}
+ cartItemsCount={cartItemsCount}
rightActions={
)}
diff --git a/apps/web/src/app/_components/features/ShoppingCart.tsx b/apps/web/src/app/_components/features/ShoppingCart.tsx
index 86feb98..93ef06e 100644
--- a/apps/web/src/app/_components/features/ShoppingCart.tsx
+++ b/apps/web/src/app/_components/features/ShoppingCart.tsx
@@ -1,6 +1,7 @@
"use client";
import { XMarkIcon } from "@heroicons/react/24/solid";
+import { useRouter } from "next/navigation";
import { api } from "~/trpc/react";
interface ShoppingCartProps {
@@ -17,8 +18,8 @@ interface CartItem {
}
export default function ShoppingCart({ closeCart }: ShoppingCartProps) {
- const cartId = "1"; // Assume you have the logic to get the cartId
-
+ const router = useRouter();
+ const cartId = "1";
const utils = api.useUtils();
const { mutate: removeItem } = api.shoppingCart.removeItem.useMutation({
@@ -31,6 +32,11 @@ export default function ShoppingCart({ closeCart }: ShoppingCartProps) {
removeItem({ itemId });
};
+ const handleCheckout = () => {
+ closeCart();
+ router.push("/shopping-cart");
+ };
+
const { data: cartItems, isLoading } = api.shoppingCart.getItems.useQuery({
cartId,
});
@@ -48,7 +54,7 @@ export default function ShoppingCart({ closeCart }: ShoppingCartProps) {
) : (
<>
- {cartItems?.map((item: CartItem) => (
+ {cartItems?.items.map((item: CartItem) => (
{item.product.name}
${item.product.price}
@@ -62,7 +68,7 @@ export default function ShoppingCart({ closeCart }: ShoppingCartProps) {
Total
$
- {cartItems?.reduce(
+ {cartItems?.items.reduce(
(total: number, item: CartItem) =>
total + item.product.price * item.quantity,
0,
@@ -70,8 +76,9 @@ export default function ShoppingCart({ closeCart }: ShoppingCartProps) {
diff --git a/apps/web/src/app/marketplace/page.tsx b/apps/web/src/app/marketplace/page.tsx
index ef4c915..ad37f5b 100755
--- a/apps/web/src/app/marketplace/page.tsx
+++ b/apps/web/src/app/marketplace/page.tsx
@@ -2,12 +2,13 @@
import Carousel from "@repo/ui/carousel";
import { useAccount, useDisconnect } from "@starknet-react/core";
-import { useAtom } from "jotai";
+import { useAtom, useAtomValue } from "jotai";
import { useTranslation } from "react-i18next";
import ProductCatalog from "~/app/_components/features/ProductCatalog";
import Header from "~/app/_components/layout/Header";
import Main from "~/app/_components/layout/Main";
import { searchQueryAtom } from "~/atoms/productAtom";
+import { cartItemsAtom } from "~/store/cartAtom";
import SearchBar from "../_components/features/SearchBar";
export default function Home() {
@@ -15,6 +16,11 @@ export default function Home() {
const { address } = useAccount();
const { disconnect } = useDisconnect();
const [query] = useAtom(searchQueryAtom);
+ const items = useAtomValue(cartItemsAtom);
+ const cartItemsCount = items.reduce(
+ (total, item) => total + item.quantity,
+ 0,
+ );
const carouselData = [
{
@@ -39,7 +45,7 @@ export default function Home() {
return (
-
+
{query.length <= 0 && (
diff --git a/apps/web/src/app/product/[id]/page.tsx b/apps/web/src/app/product/[id]/page.tsx
index 12ca56c..41db457 100644
--- a/apps/web/src/app/product/[id]/page.tsx
+++ b/apps/web/src/app/product/[id]/page.tsx
@@ -6,6 +6,7 @@ import { useEffect, useState } from "react";
import ProductDetails from "~/app/_components/features/ProductDetails";
interface Product {
+ id: number;
image: string;
name: string;
region: string;
@@ -58,6 +59,7 @@ function ProductPage() {
const parsedMetadata = JSON.parse(data.nftMetadata) as NftMetadata;
const product: Product = {
+ id: Number(id),
image: parsedMetadata.imageUrl,
name: data.name,
region: data.region,
@@ -66,7 +68,7 @@ function ProductPage() {
bagsAvailable: data.bagsAvailable ?? 10,
price: data.price,
description: parsedMetadata.description,
- type: "SoldOut",
+ type: "Buyer",
process: data.process ?? "Natural",
};
diff --git a/apps/web/src/server/api/routers/shoppingCart.ts b/apps/web/src/server/api/routers/shoppingCart.ts
index 9ce3512..829f78c 100644
--- a/apps/web/src/server/api/routers/shoppingCart.ts
+++ b/apps/web/src/server/api/routers/shoppingCart.ts
@@ -7,98 +7,24 @@ export const shoppingCartRouter = createTRPCRouter({
z.object({
cartId: z.string(),
productId: z.number(),
- quantity: z.number().min(1),
+ quantity: z.number(),
}),
)
- .mutation(async ({ ctx, input }) => {
- const { cartId, productId, quantity } = input;
-
- console.log("input", input);
-
- const product = await ctx.db.product.findUnique({
- where: { id: productId },
- });
- if (!product) {
- throw new Error("Product not found");
- }
- return ctx.db.shoppingCartItem.create({
- data: {
- shoppingCartId: cartId,
- productId,
- quantity,
- },
- });
- }),
-
- getItems: publicProcedure
- .input(z.object({ cartId: z.string() }))
- .query(({ ctx, input }) => {
- return ctx.db.shoppingCartItem.findMany({
- where: { shoppingCartId: input.cartId },
- include: { product: true },
- });
+ .mutation(async ({ input }) => {
+ // TODO: Implement actual cart logic
+ return { success: true };
}),
removeItem: publicProcedure
.input(z.object({ itemId: z.string() }))
- .mutation(async ({ ctx, input }) => {
- return ctx.db.shoppingCartItem.delete({
- where: { id: input.itemId },
- });
- }),
-
- createOrder: publicProcedure
- .input(
- z.object({
- userId: z.string(),
- }),
- )
- .mutation(async ({ ctx, input }) => {
- const { userId } = input;
- const cartItems = await ctx.db.shoppingCartItem.findMany({
- where: { shoppingCart: { userId } },
- include: { product: true },
- });
- if (cartItems.length === 0) {
- throw new Error("No items in cart to create an order.");
- }
- const total = cartItems.reduce(
- (acc, item) => acc + item.product.price * item.quantity,
- 0,
- );
- const order = await ctx.db.order.create({
- data: {
- userId,
- total,
- status: "PENDING",
- items: {
- create: cartItems.map((item) => ({
- productId: item.productId,
- quantity: item.quantity,
- price: item.product.price,
- })),
- },
- },
- });
- await ctx.db.shoppingCartItem.deleteMany({
- where: {
- shoppingCartId: { in: cartItems.map((item) => item.shoppingCartId) },
- },
- });
- return order;
+ .mutation(async ({ input }) => {
+ // TODO: Implement actual remove logic
+ return { success: true };
}),
- getOrders: publicProcedure
- .input(
- z.object({
- userId: z.string(),
- }),
- )
- .query(async ({ ctx, input }) => {
- const { userId } = input;
- return ctx.db.order.findMany({
- where: { userId },
- include: { items: true },
- });
+ getItems: publicProcedure
+ .input(z.object({ cartId: z.string() }))
+ .query(async ({ input }) => {
+ return { items: [] };
}),
});
From 0dc546e44a6ac4f19918853f8263997128f04d9e Mon Sep 17 00:00:00 2001
From: evgongora
Date: Tue, 12 Nov 2024 01:02:01 -0600
Subject: [PATCH 2/7] feat: add the add to cart functionality
---
.../app/_components/features/ProductList.tsx | 23 ++++++++++---------
.../features/SelectionTypeCard.tsx | 6 +++--
2 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/apps/web/src/app/_components/features/ProductList.tsx b/apps/web/src/app/_components/features/ProductList.tsx
index 6b8397b..eb5ca11 100644
--- a/apps/web/src/app/_components/features/ProductList.tsx
+++ b/apps/web/src/app/_components/features/ProductList.tsx
@@ -1,6 +1,7 @@
"use client";
-import { api } from "~/trpc/react";
+import { useAtom } from "jotai";
+import { addItemAtom } from "~/store/cartAtom";
interface Product {
id: number;
@@ -14,16 +15,16 @@ interface ProductListProps {
}
export default function ProductList({ products }: ProductListProps) {
- const utils = api.useUtils();
+ const [, addItem] = useAtom(addItemAtom);
- const { mutate: addToCart } = api.shoppingCart.addItem.useMutation({
- onSuccess: async () => {
- await utils.shoppingCart.getItems.invalidate();
- },
- });
-
- const handleAddToCart = (productId: number) => {
- addToCart({ cartId: "1", productId, quantity: 1 });
+ const handleAddToCart = (product: Product) => {
+ addItem({
+ id: String(product.id),
+ name: product.name,
+ quantity: 1,
+ price: product.price,
+ imageUrl: "/default-image.webp",
+ });
};
return (
@@ -38,7 +39,7 @@ export default function ProductList({ products }: ProductListProps) {
${product.price.toFixed(2)}
-
{rightActions}
- {!hideCart && (
-
+ {showCart && (
+ router.push("/shopping-cart")}
+ className="p-2 relative"
+ aria-label="Shopping cart"
+ >
-
+
+ {cartItemsCount}
+
+
)}
From 8e694adb71b28783f331f410ec19042cd2294764 Mon Sep 17 00:00:00 2001
From: evgongora
Date: Tue, 12 Nov 2024 01:06:09 -0600
Subject: [PATCH 4/7] fix: change functionality of product card
---
packages/ui/src/productCard.tsx | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/packages/ui/src/productCard.tsx b/packages/ui/src/productCard.tsx
index 94eeeaa..9949eac 100644
--- a/packages/ui/src/productCard.tsx
+++ b/packages/ui/src/productCard.tsx
@@ -12,7 +12,8 @@ interface ProductCardProps {
price: number;
badgeText: string;
onClick: () => void;
- isAddingToShoppingCart: boolean;
+ onAddToCart?: () => void;
+ isAddingToShoppingCart?: boolean;
}
export function ProductCard({
@@ -23,7 +24,7 @@ export function ProductCard({
price,
badgeText,
onClick,
- isAddingToShoppingCart,
+ onAddToCart,
}: ProductCardProps) {
return (
@@ -51,7 +52,6 @@ export function ProductCard({
variant="secondary"
onClick={onClick}
icon={
}
- disabled={isAddingToShoppingCart}
/>
From d12a25086d055e9fe28eebaf5585f680f0484dd2 Mon Sep 17 00:00:00 2001
From: evgongora
Date: Tue, 12 Nov 2024 12:11:30 -0600
Subject: [PATCH 5/7] fix: build issues and cart counter changes
---
apps/web/src/app/user/my-sales/page.tsx | 32 ++++++++++++-------------
packages/ui/package.json | 5 +++-
packages/ui/src/pageHeader.tsx | 8 ++++---
3 files changed, 25 insertions(+), 20 deletions(-)
diff --git a/apps/web/src/app/user/my-sales/page.tsx b/apps/web/src/app/user/my-sales/page.tsx
index 4ab3fe4..b6bece5 100644
--- a/apps/web/src/app/user/my-sales/page.tsx
+++ b/apps/web/src/app/user/my-sales/page.tsx
@@ -134,28 +134,28 @@ export default function MySales() {
activeFilters.statusDelivered,
];
- const matchesStatus =
- !activeStatusFilters.some(Boolean) ??
- (activeFilters.statusPaid &&
- item.status === SalesStatusEnum.Paid) ??
- (activeFilters.statusPrepared &&
- item.status === SalesStatusEnum.Prepared) ??
- (activeFilters.statusShipped &&
- item.status === SalesStatusEnum.Shipped) ??
- (activeFilters.statusDelivered &&
- item.status === SalesStatusEnum.Delivered);
+ const matchesStatus = !activeStatusFilters.some(Boolean)
+ ? true
+ : (activeFilters.statusPaid &&
+ item.status === SalesStatusEnum.Paid) ??
+ (activeFilters.statusPrepared &&
+ item.status === SalesStatusEnum.Prepared) ??
+ (activeFilters.statusShipped &&
+ item.status === SalesStatusEnum.Shipped) ??
+ (activeFilters.statusDelivered &&
+ item.status === SalesStatusEnum.Delivered);
const activeDeliveryFilters = [
activeFilters.deliveryAddress,
activeFilters.deliveryMeetup,
];
- const matchesDelivery =
- !activeDeliveryFilters.some(Boolean) ??
- (activeFilters.deliveryAddress &&
- item.delivery === DeliveryMethodEnum.Address) ??
- (activeFilters.deliveryMeetup &&
- item.delivery === DeliveryMethodEnum.Meetup);
+ const matchesDelivery = !activeDeliveryFilters.some(Boolean)
+ ? true
+ : (activeFilters.deliveryAddress &&
+ item.delivery === DeliveryMethodEnum.Address) ??
+ (activeFilters.deliveryMeetup &&
+ item.delivery === DeliveryMethodEnum.Meetup);
return matchesSearch && matchesStatus && matchesDelivery;
}),
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 7dc868f..0f151e0 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -22,7 +22,10 @@
"./tooltip": "./src/tooltip.tsx",
"./skeleton": "./src/skeleton.tsx",
"./particle": "./src/particle.tsx",
- "./nftCard": "./src/nftCard.tsx"
+ "./nftCard": "./src/nftCard.tsx",
+ "./chatWithSeller": "./src/chatWithSeller.tsx",
+ "./dataCard": "./src/dataCard.tsx",
+ "./infoCard": "./src/infoCard.tsx"
},
"scripts": {
"lint": "eslint . --max-warnings 0",
diff --git a/packages/ui/src/pageHeader.tsx b/packages/ui/src/pageHeader.tsx
index 6761938..a105d5f 100644
--- a/packages/ui/src/pageHeader.tsx
+++ b/packages/ui/src/pageHeader.tsx
@@ -128,9 +128,11 @@ function PageHeader({
aria-label="Shopping cart"
>
-
- {cartItemsCount}
-
+ {cartItemsCount && cartItemsCount > 0 ? (
+
+ {cartItemsCount}
+
+ ) : null}
)}
From 1689d3c6e39f9aa3c7dc5716a7b28c378c9e5c53 Mon Sep 17 00:00:00 2001
From: t0fudev
Date: Wed, 13 Nov 2024 11:30:44 -0600
Subject: [PATCH 6/7] fix: tailwind colors
---
apps/web/src/app/_components/features/ShoppingCart.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apps/web/src/app/_components/features/ShoppingCart.tsx b/apps/web/src/app/_components/features/ShoppingCart.tsx
index 93ef06e..9756bda 100644
--- a/apps/web/src/app/_components/features/ShoppingCart.tsx
+++ b/apps/web/src/app/_components/features/ShoppingCart.tsx
@@ -76,7 +76,7 @@ export default function ShoppingCart({ closeCart }: ShoppingCartProps) {
From 9ad4518796bd6e34180f6b772838f96159f0f22f Mon Sep 17 00:00:00 2001
From: evgongora
Date: Tue, 19 Nov 2024 12:59:52 -0600
Subject: [PATCH 7/7] fix: use only jotai, delete imports and files
---
.../app/_components/features/ShoppingCart.tsx | 86 +++++++------------
apps/web/src/app/marketplace/page.tsx | 8 +-
apps/web/src/app/user/favorites/page.tsx | 23 +++--
apps/web/src/server/api/root.ts | 2 -
.../src/server/api/routers/shoppingCart.ts | 30 -------
5 files changed, 42 insertions(+), 107 deletions(-)
delete mode 100644 apps/web/src/server/api/routers/shoppingCart.ts
diff --git a/apps/web/src/app/_components/features/ShoppingCart.tsx b/apps/web/src/app/_components/features/ShoppingCart.tsx
index 9756bda..8607f94 100644
--- a/apps/web/src/app/_components/features/ShoppingCart.tsx
+++ b/apps/web/src/app/_components/features/ShoppingCart.tsx
@@ -1,35 +1,21 @@
"use client";
import { XMarkIcon } from "@heroicons/react/24/solid";
+import { useAtom, useAtomValue } from "jotai";
import { useRouter } from "next/navigation";
-import { api } from "~/trpc/react";
+import { cartItemsAtom, removeItemAtom } from "~/store/cartAtom";
interface ShoppingCartProps {
closeCart: () => void;
}
-interface CartItem {
- id: string;
- product: {
- name: string;
- price: number;
- };
- quantity: number;
-}
-
export default function ShoppingCart({ closeCart }: ShoppingCartProps) {
const router = useRouter();
- const cartId = "1";
- const utils = api.useUtils();
-
- const { mutate: removeItem } = api.shoppingCart.removeItem.useMutation({
- onSuccess: async () => {
- await utils.shoppingCart.getItems.invalidate();
- },
- });
+ const items = useAtomValue(cartItemsAtom);
+ const [, removeItem] = useAtom(removeItemAtom);
const handleRemoveItem = (itemId: string) => {
- removeItem({ itemId });
+ removeItem(itemId);
};
const handleCheckout = () => {
@@ -37,9 +23,10 @@ export default function ShoppingCart({ closeCart }: ShoppingCartProps) {
router.push("/shopping-cart");
};
- const { data: cartItems, isLoading } = api.shoppingCart.getItems.useQuery({
- cartId,
- });
+ const totalPrice = items.reduce(
+ (total, item) => total + item.price * item.quantity,
+ 0,
+ );
return (
@@ -49,41 +36,28 @@ export default function ShoppingCart({ closeCart }: ShoppingCartProps) {
- {isLoading ? (
- Loading...
- ) : (
- <>
-
- {cartItems?.items.map((item: CartItem) => (
-
-
{item.product.name}
-
${item.product.price}
-
handleRemoveItem(item.id)} type="button">
- Remove
-
-
- ))}
-
-
-
Total
-
- $
- {cartItems?.items.reduce(
- (total: number, item: CartItem) =>
- total + item.product.price * item.quantity,
- 0,
- )}
-
+
+ {items.map((item) => (
+
+
{item.name}
+
${item.price}
+
handleRemoveItem(item.id)} type="button">
+ Remove
+
-
- Checkout
-
- >
- )}
+ ))}
+
+
+
Total
+
${totalPrice}
+
+
+ Checkout
+
);
}
diff --git a/apps/web/src/app/marketplace/page.tsx b/apps/web/src/app/marketplace/page.tsx
index ad37f5b..5953fae 100755
--- a/apps/web/src/app/marketplace/page.tsx
+++ b/apps/web/src/app/marketplace/page.tsx
@@ -2,13 +2,12 @@
import Carousel from "@repo/ui/carousel";
import { useAccount, useDisconnect } from "@starknet-react/core";
-import { useAtom, useAtomValue } from "jotai";
+import { useAtom } from "jotai";
import { useTranslation } from "react-i18next";
import ProductCatalog from "~/app/_components/features/ProductCatalog";
import Header from "~/app/_components/layout/Header";
import Main from "~/app/_components/layout/Main";
import { searchQueryAtom } from "~/atoms/productAtom";
-import { cartItemsAtom } from "~/store/cartAtom";
import SearchBar from "../_components/features/SearchBar";
export default function Home() {
@@ -16,11 +15,6 @@ export default function Home() {
const { address } = useAccount();
const { disconnect } = useDisconnect();
const [query] = useAtom(searchQueryAtom);
- const items = useAtomValue(cartItemsAtom);
- const cartItemsCount = items.reduce(
- (total, item) => total + item.quantity,
- 0,
- );
const carouselData = [
{
diff --git a/apps/web/src/app/user/favorites/page.tsx b/apps/web/src/app/user/favorites/page.tsx
index fc13042..d8937dc 100644
--- a/apps/web/src/app/user/favorites/page.tsx
+++ b/apps/web/src/app/user/favorites/page.tsx
@@ -1,9 +1,10 @@
"use client";
import { ProductCard } from "@repo/ui/productCard";
+import { useAtom, useAtomValue } from "jotai";
import React from "react";
import { ProfileOptionLayout } from "~/app/_components/features/ProfileOptionLayout";
-import { api } from "~/trpc/react";
+import { addItemAtom, cartItemsAtom } from "~/store/cartAtom";
const userFavoriteProducts = [
{
@@ -28,19 +29,17 @@ export default function Favorites() {
// and avoid code duplication
const [addedProduct, setAddedProduct] = React.useState(null);
- const utils = api.useUtils();
-
- const { mutate: addItem } = api.shoppingCart.addItem.useMutation({
- onSuccess: async () => {
- await utils.shoppingCart.getItems.invalidate();
- setAddedProduct(null);
- },
- });
+ const items = useAtomValue(cartItemsAtom);
+ const [, addItem] = useAtom(addItemAtom);
const handleAddToCart = (productId: number) => {
- const cartId = 1;
-
- addItem({ cartId: cartId.toString(), productId, quantity: 1 });
+ addItem({
+ id: productId.toString(),
+ name: "Product Name",
+ quantity: 1,
+ price: 10.0,
+ imageUrl: "/default-image.webp",
+ });
setAddedProduct(productId);
};
diff --git a/apps/web/src/server/api/root.ts b/apps/web/src/server/api/root.ts
index 507551c..d0144f7 100644
--- a/apps/web/src/server/api/root.ts
+++ b/apps/web/src/server/api/root.ts
@@ -1,5 +1,4 @@
import { productRouter } from "~/server/api/routers/product";
-import { shoppingCartRouter } from "~/server/api/routers/shoppingCart";
import { userRouter } from "~/server/api/routers/user";
import { createCallerFactory, createTRPCRouter } from "~/server/api/trpc";
@@ -9,7 +8,6 @@ import { createCallerFactory, createTRPCRouter } from "~/server/api/trpc";
* All routers added in /api/routers should be manually added here.
*/
export const appRouter = createTRPCRouter({
- shoppingCart: shoppingCartRouter,
product: productRouter,
user: userRouter,
});
diff --git a/apps/web/src/server/api/routers/shoppingCart.ts b/apps/web/src/server/api/routers/shoppingCart.ts
deleted file mode 100644
index 829f78c..0000000
--- a/apps/web/src/server/api/routers/shoppingCart.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { z } from "zod";
-import { createTRPCRouter, publicProcedure } from "~/server/api/trpc";
-
-export const shoppingCartRouter = createTRPCRouter({
- addItem: publicProcedure
- .input(
- z.object({
- cartId: z.string(),
- productId: z.number(),
- quantity: z.number(),
- }),
- )
- .mutation(async ({ input }) => {
- // TODO: Implement actual cart logic
- return { success: true };
- }),
-
- removeItem: publicProcedure
- .input(z.object({ itemId: z.string() }))
- .mutation(async ({ input }) => {
- // TODO: Implement actual remove logic
- return { success: true };
- }),
-
- getItems: publicProcedure
- .input(z.object({ cartId: z.string() }))
- .query(async ({ input }) => {
- return { items: [] };
- }),
-});