Skip to content

Commit

Permalink
WIP Cart
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinjcai committed Oct 31, 2023
1 parent e93cbc7 commit e8846a4
Show file tree
Hide file tree
Showing 15 changed files with 299 additions and 107 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"react": "^18.2.0",
"react-bootstrap": "^2.9.0",
"react-dom": "18.2.0",
"react-router-dom": "^6.17.0",
"styled-components": "^6.0.8",
"vitedge": "^0.19.1"
},
Expand Down
1 change: 1 addition & 0 deletions src/api/supabase/queries/product_queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export async function fetchProductByID(
productId: number,
): Promise<PostgrestSingleResponse<Product>> {
try {
// console.log('productId:', productId);
const { data: product, error } = await supabase
.from('product')
.select('*')
Expand Down
70 changes: 11 additions & 59 deletions src/api/supabase/queries/user_queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export async function fetchUserData(): Promise<
PostgrestSingleResponse<User[]> | { data: never[]; error: PostgrestError }
> {
try {
const { data: users, error } = await supabase.from('users').select('*');
const { data: users, error } = await supabase.from('profiles').select('*');

if (error) {
console.error('Error fetching data:', error);
Expand All @@ -36,10 +36,10 @@ export async function fetchUserData(): Promise<

export async function fetchUserByUUID(
uuid: string,
): Promise<PostgrestSingleResponse<unknown>> {
) {
try {
const { data: user, error } = await supabase
.from('Users')
.from('profiles')
.select('*')
.eq('user_id', uuid)
.single();
Expand All @@ -55,64 +55,16 @@ export async function fetchUserByUUID(
}
}

export async function addUserAddress(
uuid: string,
newStreet: string,
newCity: string,
newZipcode: string,
): Promise<PostgrestSingleResponse<unknown>> {
try {
const { data: existingUser, error: selectError } = await supabase
.from('Users')
.select('street, city, zipcode')
.eq('user_id', uuid)
.single();

if (selectError) {
console.error('Error selecting user data:', selectError);
throw selectError;
}

// Append new values to the arrays
const updatedStreet = [...(existingUser?.street || []), newStreet];
const updatedCity = [...(existingUser?.city || []), newCity];
const updatedZipcode = [...(existingUser?.zipcode || []), newZipcode];

const { data, error } = await supabase
.from('Users')
.update({
street: updatedStreet,
city: updatedCity,
zipcode: updatedZipcode,
})
.eq('user_id', uuid)
.single();

if (error) {
console.error('Error updating user data:', error);
throw error;
}

return { data, error: null, status: 200, statusText: 'OK', count: 1 };
} catch (error) {
console.error('Error:', error);
throw error;
}
}

export async function updateCartForUser(
userId: string,
newCartData: Record<string, number>,
): Promise<PostgrestSingleResponse<User[]>> {
) {
try {
const { data: users, error } = await supabase
.from('users') // Specify the User type for type safety
.upsert([
{
userId,
cart_items: newCartData, // Update the 'cart_items' field with new cart data
},
]);
.from('profiles') // Specify the User type for type safety
.update({ cart: newCartData })
.eq('user_id', userId);

if (error) {
console.error('Error updating cart for user:', error);
Expand All @@ -128,11 +80,11 @@ export async function updateCartForUser(

export async function getCartForUser(
userId: string,
): Promise<PostgrestSingleResponse<Record<string, number>>> {
) {
try {
const { data: user, error } = await supabase
.from('users')
.select('cart_items') // Select only the 'cart_items' field
.from('profiles')
.select('cart') // Select only the 'cart_items' field
.eq('user_id', userId)
.single();

Expand All @@ -142,7 +94,7 @@ export async function getCartForUser(
}

if (user) {
return { data: user.cart_items } as PostgrestSingleResponse<
return { data: user.cart } as PostgrestSingleResponse<
Record<string, number>
>;
}
Expand Down
104 changes: 104 additions & 0 deletions src/app/context/ShoppingCartContext copy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"use client";


import { createContext, ReactNode, useContext, useState } from 'react';
import ShoppingCart from '../../components/cart/ShoppingCart';
import useLocalStorage from '../hooks/useLocalStorage';
import { updateCartForUser } from '../../api/supabase/queries/user_queries';

type ShoppingCartProviderProps = {
children: ReactNode
}

type CartItem = {
id: number
quantity: number
}

type ShoppingCartContext = {
openCart: () => void
closeCart: () => void
getItemQuantity: (id: number) => number
increaseCartQuantity: (id: number) => void
decreaseCartQuantity: (id: number) => void
removeFromCart: (id: number) => void
cartQuantity: number
cartItems: CartItem[]
}

const ShoppingCartContext = createContext({} as ShoppingCartContext)

export function useShoppingCart() {
return useContext(ShoppingCartContext)
}
export function ShoppingCartProvider({ children }: ShoppingCartProviderProps) {
const [isOpen, setIsOpen] = useState(false)
const [cartItems, setCartItems] = useLocalStorage<CartItem[]>(
"shopping-cart",
[]
)

const cartQuantity = cartItems.reduce(
(quantity, item) => item.quantity + quantity,
0
)

const openCart = () => setIsOpen(true)
const closeCart = () => setIsOpen(false)
function getItemQuantity(id: number) {
return cartItems.find(item => item.id === id)?.quantity || 0
}
function increaseCartQuantity(id: number) {
setCartItems(currItems => {
if (currItems.find(item => item.id === id) == null) {
return [...currItems, { id, quantity: 1 }]
} else {
return currItems.map(item => {
if (item.id === id) {
return { ...item, quantity: item.quantity + 1 }
} else {
return item
}
})
}
})
}
function decreaseCartQuantity(id: number) {
setCartItems(currItems => {
if (currItems.find(item => item.id === id)?.quantity === 1) {
return currItems.filter(item => item.id !== id)
} else {
return currItems.map(item => {
if (item.id === id) {
return { ...item, quantity: item.quantity - 1 }
} else {
return item
}
})
}
})
}
function removeFromCart(id: number) {
setCartItems(currItems => {
return currItems.filter(item => item.id !== id)
})
}

return (
<ShoppingCartContext.Provider
value={{
getItemQuantity,
increaseCartQuantity,
decreaseCartQuantity,
removeFromCart,
openCart,
closeCart,
cartItems,
cartQuantity,
}}
>
{children}
<ShoppingCart isOpen={isOpen} />
</ShoppingCartContext.Provider>
)
}
7 changes: 6 additions & 1 deletion src/app/context/ShoppingCartContext.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
"use client";


import { createContext, ReactNode, useContext, useState } from 'react';
import ShoppingCart from '../../components/cart/ShoppingCart';
import useLocalStorage from '../hooks/useLocalStorage';
Expand All @@ -8,7 +11,7 @@ type ShoppingCartProviderProps = {
};

// TODO: get this from the user
const userID = '1';
const userID = '726543df-8e1a-4c6d-a2c6-326e94eb0a0a';

type CartItem = {
id: number;
Expand All @@ -26,6 +29,8 @@ type ShoppingCartContext = {
cartItems: CartItem[];
};



const ShoppingCartContext = createContext({} as ShoppingCartContext);

export function useShoppingCart() {
Expand Down
28 changes: 28 additions & 0 deletions src/app/context/new_ShoppingCartContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// import { createContext, ReactNode, useContext, useState, useMemo, useReducer} from 'react';
// import ShoppingCart from '../../components/cart/ShoppingCart';
// import useLocalStorage from '../hooks/useLocalStorage';
// import { updateCartForUser } from '../../api/supabase/queries/user_queries';

// type ShoppingCartProviderProps = {
// children: ReactNode;
// };

// type CartItem = {
// id: number;
// quantity: number;
// };

// export interface cartState {
// items: CartItem[];
// }

// export type AuthContextAction =
// | { type: 'ADD_ITEM'; userObject: RegularUser | null }
// | { type: 'REMOVE_ITEM'; userObject: RegularUser | null }
// | { type: 'REMOVE_ITEM' }
// | { type: 'CHANGE_BOOKMARK'; bookmarkedArray: string[] | undefined }
// | { type: 'UPDATE_LANGUAGE'; language: string | undefined };

// // TODO: get this from the user
// const userID = '1';

72 changes: 32 additions & 40 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,37 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { useRouter } from 'next/router'
import { Container } from "react-bootstrap"
import { Home } from "./pages/Home"
import Store from "./pages/Store"
import { About } from "./pages/About"
import Navbar from "../components/cart/Navbar"
import { ShoppingCartProvider } from "./context/ShoppingCartContext copy"

import Link from 'next/link';
import {
testFetchUserData,
testFetchUserByUUID,
testAddUserAddress,
} from '../api/supabase/queries/tests/user_test';
import {
testFetchOrderByUUID,
testFetchOrders,
testGetOrderById,
testToggleOrderProgress,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
testUpdateAllOrdersProgressToTrue,
} from '../api/supabase/queries/tests/order_test';
import {
testFetchProducts,
testFetchProductByName,
} from '../api/supabase/queries/tests/product_test';
import {
testFetchPickupData,
testFetchPickupTimesByUUID,
} from '../api/supabase/queries/tests/pickup_test';
function App() {
const router = useRouter();

export default function Checkout() {
// testFetchUserData();
// testFetchUserByUUID();
// testAddUserAddress();
// testFetchOrderByUUID();
// testFetchOrders();
// testGetOrderById();
// testToggleOrderProgress();
testFetchProducts();
// testFetchProductByName();
// testFetchPickupData();
// testFetchPickupTimesByUUID();
// testUpdateAllOrdersProgressToTrue();
let Component;
switch (router.pathname) {
case '/':
Component = Home;
break;
case '/store':
Component = Store;
break;
case '/about':
Component = About;
break;
default:
Component = Home;
}

return (
<main>
<Link href="/store">Store</Link>
</main>
);
<ShoppingCartProvider>
<Navbar />
<Container className="mb-4">
<Component />
</Container>
</ShoppingCartProvider>
)
}

export default App;
3 changes: 3 additions & 0 deletions src/app/pages/About.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function About() {
return <h1>About</h1>
}
3 changes: 3 additions & 0 deletions src/app/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function Home() {
return <h1>Home</h1>
}
Loading

0 comments on commit e8846a4

Please sign in to comment.