Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinjcai committed Oct 19, 2023
1 parent bcf9b36 commit 5a0a3e7
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 23 deletions.
98 changes: 98 additions & 0 deletions src/app/context/ShoppingCartContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { createContext, ReactNode, useContext, useState, useMemo } from "react"
import { useLocalStorage } from "../hooks/useLocalStorage"

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 }]
}
return currItems.map(item => {
if (item.id === id) {
return { ...item, quantity: item.quantity + 1 }
}
return item

})

})
}
function decreaseCartQuantity(id: number) {
setCartItems(currItems => {
if (currItems.find(item => item.id === id)?.quantity === 1) {
return currItems.filter(item => item.id !== id)
}
return currItems.map(item => {
if (item.id === id) {
return { ...item, quantity: item.quantity - 1 }
}
return item

})

})
}
import { useMemo } from "react";

function removeFromCart(id: number) {
setCartItems(currItems => currItems.filter(item => item.id !== id))
}

const contextValue = useMemo(() => ({
getItemQuantity,
increaseCartQuantity,
decreaseCartQuantity,
removeFromCart,
openCart,
closeCart,
cartItems,
cartQuantity,
}), [cartItems, cartQuantity]);

return (
<ShoppingCartContext.Provider value={contextValue}>
{children}
</ShoppingCartContext.Provider>
)
}
20 changes: 20 additions & 0 deletions src/app/hooks/useLocalStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useEffect, useState } from "react"

export function useLocalStorage<T>(key: string, initialValue: T | (() => T)) {
const [value, setValue] = useState<T>(() => {
const jsonValue = localStorage.getItem(key)
if (jsonValue != null) return JSON.parse(jsonValue)

if (typeof initialValue === "function") {
return (initialValue as () => T)()
}
return initialValue

})

useEffect(() => {
localStorage.setItem(key, JSON.stringify(value))
}, [key, value])

return [value, setValue] as [typeof value, typeof setValue]
}
20 changes: 10 additions & 10 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ import {

export default function Checkout() {
testFetchUserData();
testFetchUserByUUID();
testAddUserAddress();
testFetchOrderByUUID();
testFetchOrders();
testGetOrderById();
testToggleOrderProgress();
testFetchProducts();
testFetchProductByName();
testFetchPickupData();
testFetchPickupTimesByUUID();
// testFetchUserByUUID();
// testAddUserAddress();
// testFetchOrderByUUID();
// testFetchOrders();
// testGetOrderById();
// testToggleOrderProgress();
// testFetchProducts();
// testFetchProductByName();
// testFetchPickupData();
// testFetchPickupTimesByUUID();
// testUpdateAllOrdersProgressToTrue();

return (
Expand Down
16 changes: 16 additions & 0 deletions src/components/ShoppingCart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Offcanvas, Stack } from "react-bootstrap"
import { useShoppingCart } from "../context/ShoppingCartContext"
import { formatCurrency } from "../utilities/formatCurrency"
import { CartItem } from "./CartItem"
import storeItems from "../data/items.json"

type ShoppingCartProps = {
isOpen: boolean
}

export function ShoppingCart({ isOpen }: ShoppingCartProps) {
const { closeCart, cartItems } = useShoppingCart()
return (

)
}
Empty file removed src/database/database.txt
Empty file.
6 changes: 6 additions & 0 deletions src/schema/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,9 @@ export type Product = {
photo: string; // text null;
updated_at: string; // timestamp with time zone not null default now();
};

export type Cart = {
id: number; // bigint generated by default as identity
user_id: string; // UUID not null
product_id: Record<string, number>; // JSONB with item as key and quantity as value
};
106 changes: 106 additions & 0 deletions src/supabase/cart_queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* eslint-disable no-console */
//

import {
PostgrestSingleResponse,
PostgrestError,
createClient,
} from '@supabase/supabase-js';

import { Cart } from '../schema/schema';

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseApiKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;

const supabase = createClient(supabaseUrl ?? '', supabaseApiKey ?? '');

export async function fetchAllCarts(): Promise<
PostgrestSingleResponse<Cart[]> | { data: never[]; error: PostgrestError }
> {
try {
const { data: carts, error } = await supabase
.from('Cart')
.select('*');

if (error) {
console.error('Error fetching carts:', error);
return { data: [], error };
}

return { data: carts } as PostgrestSingleResponse<Cart[]>;
} catch (error) {
console.error('Error:', error);
throw error;
}
}

export async function fetchCartByUserId(
userId: string,
): Promise<
PostgrestSingleResponse<Cart[]> | { data: never[]; error: PostgrestError }
> {
try {
const { data: carts, error } = await supabase
.from('Cart')
.select('*')
.eq('user_id', userId).single();

if (error) {
console.error('Error fetching carts for user:', error);
return { data: [], error };
}

return carts;
} catch (error) {
console.error('Error:', error);
throw error;
}
}

export async function fetchCartById(
cartId: number,
): Promise<PostgrestSingleResponse<Cart>> {
try {
const { data: cart, error } = await supabase
.from('Cart')
.select('*')
.eq('id', cartId)
.single();

if (error) {
console.error('Error fetching cart by ID:', error);
}

return cart;
}
catch (error) {
console.error('Error:', error);
throw error;
}
}

export async function updateCartByUserId(
userId: string,
updatedCartData: Partial<Cart>,
): Promise<
PostgrestSingleResponse<Cart> | { data: null; error: PostgrestError }
> {
try {
const { data: updatedCart, error } = await supabase
.from('Cart')
.update(updatedCartData)
.eq('user_id', userId)
.single();

if (error) {
console.error('Error updating cart:', error);
return { data: null, error };
}

return updatedCart;
} catch (error) {
console.error('Error:', error);
throw error;
}
}

5 changes: 2 additions & 3 deletions src/supabase/order_queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,14 @@ export async function fetchOrders(): Promise<
try {
const { data: orders, error } = await supabase
.from('Order') // Update to the "Order" table
.select('*')
.single();
.select('*');

if (error) {
console.error('Error fetching data:', error);
return { data: [], error };
}

return orders;
return { data: orders } as PostgrestSingleResponse<Order[]>;
} catch (error) {
console.error('Error:', error);
throw error;
Expand Down
5 changes: 2 additions & 3 deletions src/supabase/pickup_queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ export async function fetchPickupData(): Promise<
try {
const { data: pickupTimes, error } = await supabase
.from('Pickup_Times')
.select('*')
.single();
.select('*');

if (error) {
console.error('Error fetching data:', error);
return { data: [], error };
}

return pickupTimes;
return { data: pickupTimes } as PostgrestSingleResponse<Schedule[]>;
} catch (error) {
console.error('Error:', error);
throw error;
Expand Down
5 changes: 2 additions & 3 deletions src/supabase/product_queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,14 @@ export async function fetchProducts(): Promise<
try {
const { data: products, error } = await supabase
.from('Product')
.select('*')
.single();
.select('*');

if (error) {
console.error('Error fetching data:', error);
return { data: [], error };
}

return products;
return { data: products } as PostgrestSingleResponse<Product[]>;
} catch (error) {
console.error('Error:', error);
throw error;
Expand Down
9 changes: 5 additions & 4 deletions src/supabase/user_queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,22 @@ export async function fetchUserData(): Promise<
> {
try {
const { data: users, error } = await supabase
.from('Users')
.select('*')
.single();
.from('users')
.select('*');

if (error) {
console.error('Error fetching data:', error);
return { data: [], error };
}
return users;

return { data: users } as PostgrestSingleResponse<User[]>;
} catch (error) {
console.error('Error:', error);
throw error;
}
}


export async function fetchUserByUUID(
uuid: string,
): Promise<PostgrestSingleResponse<unknown>> {
Expand Down

0 comments on commit 5a0a3e7

Please sign in to comment.