From 51e166825406209683d35d7c3775c28f4683e054 Mon Sep 17 00:00:00 2001 From: Kevin Cai Date: Tue, 21 Nov 2023 23:31:31 -0800 Subject: [PATCH] Alpha done --- src/api/supabase/queries/cart_queries.ts | 114 +++++++++++++++++ src/api/supabase/queries/user_queries.ts | 155 +---------------------- src/app/cart/page.tsx | 1 + src/app/storefront/IndividualItem.tsx | 1 + src/schema/schema.ts | 2 +- 5 files changed, 124 insertions(+), 149 deletions(-) create mode 100644 src/api/supabase/queries/cart_queries.ts diff --git a/src/api/supabase/queries/cart_queries.ts b/src/api/supabase/queries/cart_queries.ts new file mode 100644 index 00000000..ac4468e8 --- /dev/null +++ b/src/api/supabase/queries/cart_queries.ts @@ -0,0 +1,114 @@ +import supabase from '../createClient'; + +import { fetchUser } from './user_queries'; + +// define cart item type +export type CartItem = { + id: number; + product_id: number; + quantity: number; +}; + +export async function fetchCartItem(cartItemID: number): Promise { + const { data, error } = await supabase + .from('cart_items') + .select('*') + .match({ id: cartItemID }) + .single(); + if (error) { + throw new Error(`Error fetching cart item: ${error.message}`); + } + return data; +} + +export async function fetchCart(): Promise { + const user = await fetchUser(); + const cartID = user.cart_id; + const { data, error } = await supabase + .from('order') + .select('*') + .match({ id: cartID }) + .single(); + if (error) { + throw new Error(`Error fetching cart: ${error.message}`); + } + const products = data.product_id_array; + const productPromises = products.map(async (productID: number) => { + const product = await fetchCartItem(productID); + return product; + }); + const fetchedProducts = await Promise.all(productPromises); + + return fetchedProducts; +} + +export async function updateCart(cartID: number, productIDArray: number[]) { + await supabase + .from('order') + .update({ product_id_array: productIDArray }) + .match({ id: cartID }); +} + +export async function addToCart(productID: number, quantity: number) { + const items = await fetchCart(); + + // check if product is already in cart + const existingItem = items.find(item => item.product_id === productID); + if (existingItem) { + const newQuantity = existingItem.quantity + quantity; + await supabase + .from('cart_items') + .update({ quantity: newQuantity }) + .match({ id: existingItem.id }); + } else { + const { data, error } = await supabase + .from('cart_items') + .insert([{ product_id: productID, quantity }]) + .select('*') + .single(); + if (error) { + throw new Error(`Error adding to cart: ${error.message}`); + } + // append to existing cart + const user = await fetchUser(); + const cartID = user.cart_id; + const productIdArray = items.map(item => item.id); + productIdArray.push(data.id); + updateCart(cartID, productIdArray); + } +} + +export async function removeFromCart(productID: number, quantity: number) { + const items = await fetchCart(); + const existingItem = items.find(item => item.product_id === productID); + if (existingItem) { + const newQuantity = existingItem.quantity - quantity; + if (newQuantity <= 0) { + await supabase + .from('cart_items') + .delete() + .match({ id: existingItem.id }) + .select('*') + .single(); + + // remove from existing cart + const user = await fetchUser(); + const cartID = user.cart_id; + const productIdArray = items.map(item => item.id); + const index = productIdArray.indexOf(existingItem.id); + productIdArray.splice(index, 1); + updateCart(cartID, productIdArray); + } else { + await supabase + .from('cart_items') + .update({ quantity: newQuantity }) + .match({ id: existingItem.id }); + } + } +} + +export async function clearCart() { + const user = await fetchUser(); + const cartID = user.cart_id; + updateCart(cartID, []); +} diff --git a/src/api/supabase/queries/user_queries.ts b/src/api/supabase/queries/user_queries.ts index 0ed1f8cb..c9353fa2 100644 --- a/src/api/supabase/queries/user_queries.ts +++ b/src/api/supabase/queries/user_queries.ts @@ -1,13 +1,5 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -/* eslint-disable no-console */ -// - -import { - PostgrestSingleResponse, - PostgrestError, - createClient, -} from '@supabase/supabase-js'; -import { User, Product } from '../../../schema/schema'; +import { createClient } from '@supabase/supabase-js'; +import { User } from '../../../schema/schema'; // Replace these with your Supabase project URL and API key const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; @@ -16,144 +8,11 @@ const supabaseApiKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY; // Initialize the Supabase client const supabase = createClient(supabaseUrl ?? '', supabaseApiKey ?? ''); -export async function fetchUserData(): Promise< - PostgrestSingleResponse | { data: never[]; error: PostgrestError } -> { - try { - const { data: users, error } = await supabase.from('profiles').select('*'); - - if (error) { - console.error('Error fetching data:', error); - return { data: [], error }; - } - - return { data: users } as PostgrestSingleResponse; - } catch (error) { - console.error('Error:', error); - throw error; - } -} - -export async function fetchUserByUUID(uuid: string) { - try { - const { data: user, error } = await supabase - .from('profiles') - .select('*') - .eq('user_id', uuid) - .single(); - - if (error) { - console.error('Error fetching user data:', error); - } - - return user; - } catch (error) { - console.error('Error:', error); - throw error; +export default async function fetchUser(): Promise { + const { data, error } = await supabase.auth.getUser(); + if (error) { + throw new Error(`Error fetching user: ${error.message}`); } -} - -export async function getUserInfo(product: Product, isFav: boolean) { - const { - data: { user }, - } = await supabase.auth.getUser(); - - if (user !== null) { - const { data } = await supabase - .from('profiles') - .select() - .eq('user_id', user.id); - - if (data !== null) { - const CurrUserFavoriteItems = data[0].fav_items; - - if (isFav) { - CurrUserFavoriteItems[product.product_id] = 1; - } else { - delete CurrUserFavoriteItems[product.product_id]; - } - - const { error } = await supabase - .from('profiles') - .update({ fav_items: CurrUserFavoriteItems }) - .eq('user_id', user.id); - } - } -} - -export async function arrayOfFavorites() { - const { - data: { user }, - } = await supabase.auth.getUser(); - - if (user !== null) { - const { data: userProfileData, error: userProfileError } = await supabase - .from('profiles') - .select() - .eq('user_id', user.id) - .single(); - - const CurrUserFavoriteItems = userProfileData.fav_items; - const Favkey = Object.keys(CurrUserFavoriteItems); - - const { data: productData, error: productError } = await supabase - .from('product') - .select('*'); - - if (productData !== null && productData !== undefined) { - const FavArray = productData.filter(product => - Favkey.includes(String(product.product_id)), - ); - - return FavArray; - } - } - return []; -} - -export async function getProduct() { - const { data } = await supabase.from('product').select('*'); - return data; -} - -export async function filterProduct(productType: string) { - const { data } = await supabase - .from('product') - .select('*') - .eq('category', productType); - return data; -} - -export async function totalNumberOfItemsInCart() { - const { - data: { user }, - } = await supabase.auth.getUser(); - - if (user !== null) { - const { data, error } = await supabase - .from('profiles') - .select() - .eq('user_id', user.id) - .single(); - - if (data !== null) { - const CurrUserCart = data.cart; - - if (CurrUserCart === null || CurrUserCart === undefined) { - return 0; - } - - const itemNumb = Object.values(CurrUserCart) as number[]; - - let sum = 0; - - for (let i = 0; i < itemNumb.length; i += 1) { - sum += itemNumb[i]; - } - - return sum; - } - } - return 0; + return data.user.user_metadata as User; } diff --git a/src/app/cart/page.tsx b/src/app/cart/page.tsx index 0381094a..9207b8cf 100644 --- a/src/app/cart/page.tsx +++ b/src/app/cart/page.tsx @@ -58,6 +58,7 @@ export default function OrderPage() { fetchProducts(); }, []); + // eslint-disable-next-line @typescript-eslint/no-unused-vars async function clickFunctions(props: { fav: Product }) { const { fav } = props; getUserInfo(fav, false); diff --git a/src/app/storefront/IndividualItem.tsx b/src/app/storefront/IndividualItem.tsx index 665b9fd4..7eae19c4 100644 --- a/src/app/storefront/IndividualItem.tsx +++ b/src/app/storefront/IndividualItem.tsx @@ -28,6 +28,7 @@ export default function IndividualItem(props: { } } fetchProducts(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [products]); async function clickFunction() { diff --git a/src/schema/schema.ts b/src/schema/schema.ts index ce5a9bdb..4f0829bd 100644 --- a/src/schema/schema.ts +++ b/src/schema/schema.ts @@ -7,7 +7,7 @@ export type User = { pet_information: string; delivery_allowed: boolean; created_at: Date; // timestamp of when record was created - cart_id: string; // UUID + cart_id: number; // UUID address_id: string; // UUID };