diff --git a/src/api/supabase/queries/cart_queries.ts b/src/api/supabase/queries/cart_queries.ts index 2f1bee77..c8062040 100644 --- a/src/api/supabase/queries/cart_queries.ts +++ b/src/api/supabase/queries/cart_queries.ts @@ -206,7 +206,6 @@ export async function fetchCartItemsWithQuantity(): Promise< }); const fetchedProducts = await Promise.all(productPromises); - console.log(fetchedProducts); return fetchedProducts; } diff --git a/src/api/supabase/queries/delivery_queries.ts b/src/api/supabase/queries/delivery_queries.ts new file mode 100644 index 00000000..baa88631 --- /dev/null +++ b/src/api/supabase/queries/delivery_queries.ts @@ -0,0 +1,15 @@ +import supabase from '../createClient'; + +export type DeliveryTimes = { + delivery_group: number; + delivery_time: number; +}; + +export async function fetchDeliveryTimes(): Promise { + const { data, error } = await supabase.from('delivery_times').select('*'); + + if (error) { + throw new Error(`Error fetching delivery times: ${error.message}`); + } + return data; +} diff --git a/src/api/supabase/queries/order_queries.ts b/src/api/supabase/queries/order_queries.ts index f3e44c69..e011398d 100644 --- a/src/api/supabase/queries/order_queries.ts +++ b/src/api/supabase/queries/order_queries.ts @@ -38,12 +38,10 @@ export async function createOrder() { .insert({ user_id: user.id }) .select('*') .single(); - console.log(order); if (error) { throw new Error(`Error creating order: ${error.message}`); } - console.log(order.id); await supabase .from('profiles') .update({ cart_id: order.id }) diff --git a/src/api/supabase/queries/product_queries.ts b/src/api/supabase/queries/product_queries.ts index 6112c195..85ec9fbb 100644 --- a/src/api/supabase/queries/product_queries.ts +++ b/src/api/supabase/queries/product_queries.ts @@ -88,7 +88,6 @@ export async function filterProduct(productType: string): Promise { export async function convertCategoryToNumber( productType: string, ): Promise { - console.log(productType); const { data: buttonVal, error } = await supabase .from('storefront_buttons') .select('*') @@ -104,7 +103,6 @@ export async function convertCategoryToNumber( export async function fetchUnprescribedCategory( productType: string, ): Promise { - console.log(productType); const productTypeConverted = await convertCategoryToNumber(productType); const { data: products, error } = await supabase diff --git a/src/api/supabase/queries/user_queries.ts b/src/api/supabase/queries/user_queries.ts index 4b70bbcb..6a6c75a8 100644 --- a/src/api/supabase/queries/user_queries.ts +++ b/src/api/supabase/queries/user_queries.ts @@ -1,8 +1,6 @@ -import { Lekton } from 'next/font/google'; import supabase from '../createClient'; import { User, Product } from '../../../schema/schema'; import { fetchProductByID } from './product_queries'; -import { convertButtonNumberToCategory } from './button_queries'; /** * fetchUser is a function that fetches the user data from the database and returns the user object. @@ -55,12 +53,12 @@ export async function fetchUserByUUID(uuid: string) { .single(); if (error) { - console.error('Error fetching user data:', error); + throw new Error(`Error fetching user data: ${error.message}`); } return user; } catch (error) { - console.error('Error:', error); + throw new Error(`Error`); throw error; } } @@ -125,13 +123,12 @@ export async function fetchUserAddress(uuid: string) { .single(); if (error) { - console.error('Error fetching user data:', error); + throw new Error(`Error fetching user data: ${error.message}`); } return user; } catch (error) { - console.error('Error:', error); - throw error; + throw new Error(`Error:`); } } @@ -148,7 +145,6 @@ export async function fetchCurrentUserAddress() { .eq('user_id', user.id) .limit(1) .single(); - console.log(address); if (error) { console.error('Error fetching user data:', error); diff --git a/src/app/[productId]/Buttons.tsx b/src/app/[productId]/Buttons.tsx index 3cfe8355..9cc8d802 100644 --- a/src/app/[productId]/Buttons.tsx +++ b/src/app/[productId]/Buttons.tsx @@ -1,5 +1,7 @@ import React, { useState } from 'react'; import { toast } from 'react-toastify'; +import { Plus, Minus } from 'react-feather'; +import { Body1Bold } from '@/styles/fonts'; import { ButtonsWrapper, AddToCartButton, @@ -37,11 +39,11 @@ export default function Buttons(props: { productNumber: number }) { - – + - {quantity} + {quantity} - + + diff --git a/src/app/[productId]/page.tsx b/src/app/[productId]/page.tsx index 3a45652a..55cd995a 100644 --- a/src/app/[productId]/page.tsx +++ b/src/app/[productId]/page.tsx @@ -2,8 +2,11 @@ import { useEffect, useState } from 'react'; import { convertButtonNumberToCategory } from '@/api/supabase/queries/button_queries'; -import { Body1, Heading1, Body2Light } from '@/styles/fonts'; -import { fetchProductByID } from '../../api/supabase/queries/product_queries'; +import { Body1, Heading1, Body2Light, Body2Bold, Body3 } from '@/styles/fonts'; +import { + fetchProductByID, + fetchUserProducts, +} from '../../api/supabase/queries/product_queries'; import BackButton from '../../components/BackButton/BackButton'; import 'react-toastify/dist/ReactToastify.css'; @@ -13,8 +16,13 @@ import { DescriptionContainer, ToastPopUP, Fullscreen, + LeftColumnDiv, + FavoritePopup, + HeartContainer, + HeartIcon, + TopRightContainer, } from './styles'; - +import { addOrRemoveProductFromFavorite } from '../../api/supabase/queries/user_queries'; import NavBar from '../../components/NavBarFolder/NavBar'; import { Product } from '../../schema/schema'; import Buttons from './Buttons'; @@ -25,6 +33,8 @@ export default function ItemDisplay({ params: { productId: number }; }) { const [Item, setItem] = useState(); + const [IsFavorite, setIsFavorite] = useState(false); + const [FilteredProducts, setFilteredProducts] = useState([]); useEffect(() => { async function fetchProducts() { @@ -33,8 +43,12 @@ export default function ItemDisplay({ response.category = await convertButtonNumberToCategory( response.category, ); + const data = (await fetchUserProducts()) as Product[]; + + setIsFavorite(!!data.find(item => item.id === params.productId)); if (response) { setItem(response); + setFilteredProducts(data); } } catch (error) { // console.error(error); @@ -44,6 +58,14 @@ export default function ItemDisplay({ fetchProducts(); }, [params.productId]); + async function handleFavorite() { + await addOrRemoveProductFromFavorite( + await fetchProductByID(params.productId), + !IsFavorite, + ); + setIsFavorite(!IsFavorite); + } + return ( @@ -53,31 +75,38 @@ export default function ItemDisplay({ limit={1} hideProgressBar /> -
- -
- - {Item?.name} - + + + + {Item?.name} + + - {Item?.name} + + {Item?.name} + handleFavorite()}> + + + {IsFavorite ? 'Remove from favorites' : 'Add to favorites'} + + + + + - {Item?.category} + Category: {Item?.category} - - Product ID: {Item?.id} - + Product Details: - Product Details: + {Item?.description} - {Item?.description}
diff --git a/src/app/[productId]/styles.ts b/src/app/[productId]/styles.ts index e96cbb27..285c5f76 100644 --- a/src/app/[productId]/styles.ts +++ b/src/app/[productId]/styles.ts @@ -1,43 +1,45 @@ import styled from 'styled-components'; import { ToastContainer } from 'react-toastify'; +import { Body3 } from '@/styles/fonts'; +import { Heart } from 'react-feather'; import COLORS from '../../styles/colors'; -export const BackButton = styled.button` +export const LeftColumnDiv = styled.div` display: flex; - padding-top: 230px; - padding-left: 30px; - width: 100px; - height: 40px; - background-color: transparent; - border-color: transparent; - font-size: 15px; + flex-direction: column; + gap: 25px; `; export const DescriptionContainer = styled.div` display: flex; - margin-left: 50px; - margin-right: 50px; + margin-top: 50px; width: 1440px; height: 400px; + justify-content: space-around; + align-self: center; + justify-self: center; +`; + +export const TopRightContainer = styled.div` + display: flex; + justify-content: space-between; + width: 440px; `; export const ImageContainer = styled.div` - margin: 50px; width: 500px; height: 500px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; - margin-left: 200px; background-color: ${COLORS.lightGrey}; `; export const TextContainer = styled.div` - margin-left: 70px; width: 440px; height: 350px; - margin-top: 50px; + margin-top: 41px; `; export const ButtonsWrapper = styled.div` @@ -46,7 +48,7 @@ export const ButtonsWrapper = styled.div` align-items: center; width: 450px; height: 50px; - margin-top: 20px; + margin-top: 40px; `; export const QuantityButton = styled.div` @@ -71,6 +73,7 @@ export const PlusMinusButton = styled.button` font-size: 20px; color: ${COLORS.navy}; `; + export const AddToCartButton = styled.button` width: 265px; height: 50px; @@ -85,6 +88,45 @@ export const AddToCartButton = styled.button` border-color: transparent; `; +export const HeartIcon = styled(Heart)<{ $favorited: boolean }>` + width: 30px; + height: 30px; + color: ${props => (props.$favorited ? COLORS.marineBlue : COLORS.black)}; + fill: ${props => (props.$favorited ? COLORS.marineBlue : 'none')}; + position: relative; +`; + +export const HeartContainer = styled.button` + right: 16px; + top: 16px; + background-color: transparent; + border: none; + cursor: pointer; +`; + +export const FavoritePopup = styled.div` + position: absolute; + visibility: hidden; + width: 150px; + border-radius: 8px; + padding: 8px; + // Find better way to refactor this, it shouldn't need a calc + transform: translate(calc(-50% + 15px), -40px); + z-index: 1; + + color: ${COLORS.black}; + background: ${COLORS.lightPeriwinkle}; + box-shadow: 0px 2px 7px 0px rgba(0, 0, 0, 0.2); + + ${Body3} { + display: inline; + } + + ${HeartContainer}:hover & { + visibility: visible; + } +`; + export const ToastPopUP = styled(ToastContainer)` position: fixed; z-index: 100; @@ -94,4 +136,5 @@ export const ToastPopUP = styled(ToastContainer)` export const Fullscreen = styled.div` width: 100%; height: 100%; + display: grid; `; diff --git a/src/app/favorites/individualItem.tsx b/src/app/favorites/individualItem.tsx new file mode 100644 index 00000000..7b9eea0c --- /dev/null +++ b/src/app/favorites/individualItem.tsx @@ -0,0 +1,78 @@ +import React, { useEffect, useState } from 'react'; + +import { useRouter } from 'next/navigation'; + +import { Body1Bold, Body2, Body3 } from '@/styles/fonts'; + +import { convertButtonNumberToCategory } from '@/api/supabase/queries/button_queries'; +import { + HeartIcon, + Hover, + FavoriteDiv, + ProductNameDiv, + ViewItem, + TransparentButton, +} from './styles'; + +import { addOrRemoveProductFromFavorite } from '../../api/supabase/queries/user_queries'; + +import { Product } from '../../schema/schema'; + +export default function IndividualItem(props: { + favorite: Product; + setFavorites: (category: Product[]) => void; + Favorites: Product[]; +}) { + const { favorite, Favorites, setFavorites } = props; + const router = useRouter(); + const [hovering, setHovering] = useState(false); + + useEffect(() => { + async function changeCategory() { + try { + favorite.category = await convertButtonNumberToCategory( + favorite.category, + ); + } catch (error) { + // console.error(error); + } + } + + changeCategory(); + }, [favorite]); + + async function clickFunctions(props2: { fav: Product }) { + const { fav } = props2; + addOrRemoveProductFromFavorite(fav, false); + setFavorites(Favorites.filter(Prod => Prod.id !== fav.id)); + } + + return ( + + {favorite.name} + + + {favorite.name} + Category: {favorite.category} + router.push(`/${favorite.id}`)}> + View Item + + + + clickFunctions({ fav: favorite })} + onMouseEnter={() => setHovering(true)} + onMouseLeave={() => setHovering(false)} + > + + Remove from favorites + + + + + ); +} diff --git a/src/app/favorites/page.tsx b/src/app/favorites/page.tsx index 8c16242d..6c00e83a 100644 --- a/src/app/favorites/page.tsx +++ b/src/app/favorites/page.tsx @@ -1,34 +1,20 @@ 'use client'; import { useState, useEffect } from 'react'; -import { useRouter } from 'next/navigation'; -import { Body1Bold, Body2, Heading1 } from '@/styles/fonts'; +import { Heading1 } from '@/styles/fonts'; import BackButton from '../../components/BackButton/BackButton'; -import { - arrayOfFavorites, - addOrRemoveProductFromFavorite, -} from '../../api/supabase/queries/user_queries'; +import { arrayOfFavorites } from '../../api/supabase/queries/user_queries'; import NavBar from '../../components/NavBarFolder/NavBar'; -import { - FavoriteDiv, - OutterFavoriteDiv, - OutterBox, - ProductNameDiv, - HeartIcon, - TransparentButton, - ViewItem, - Fullscreen, - ImageLinkWrapper, -} from './styles'; +import { OutterFavoriteDiv, OutterBox, Fullscreen } from './styles'; +import IndividualItem from './individualItem'; import { Product } from '../../schema/schema'; export default function FavoritesPage() { const [Favorites, setFavorites] = useState([]); - const router = useRouter(); async function fetchProducts() { const data = (await arrayOfFavorites()) as Product[]; @@ -38,12 +24,6 @@ export default function FavoritesPage() { fetchProducts(); }, []); - async function clickFunctions(props: { fav: Product }) { - const { fav } = props; - addOrRemoveProductFromFavorite(fav, false); - setFavorites(Favorites.filter(Prod => Prod.id !== fav.id)); - } - return ( @@ -52,29 +32,12 @@ export default function FavoritesPage() { Favorites {Favorites.map(favorite => ( - - - {favorite.name} - - - - {favorite.name} - Category: {favorite.category} - router.push(`/${favorite.id}`)}> - View Item - - - - clickFunctions({ fav: favorite })} - > - - - + ))} diff --git a/src/app/favorites/styles.ts b/src/app/favorites/styles.ts index acd1f56c..479119e8 100644 --- a/src/app/favorites/styles.ts +++ b/src/app/favorites/styles.ts @@ -43,9 +43,11 @@ export const BackDiv = styled.button` export const OutterBox = styled.div` width: 800px; height: 100%; - - margin-top: 50px; - margin-bottom: 50px; + margin-top: 40px; + display: flex; + flex-direction: column; + gap: 20px; + margin-bottom: 20px; `; export const Backtext = styled.p` @@ -58,6 +60,7 @@ export const HeartIcon = styled(Heart)` height: 30px; fill: #333286; margin-right: 25px; + margin-bottom: 40px; `; export const TransparentButton = styled.button` @@ -66,6 +69,22 @@ export const TransparentButton = styled.button` cursor: pointer; `; +export const Hover = styled.div<{ $ishovering?: boolean }>` + visibility: ${props => (props.$ishovering ? 'visible' : 'hidden')}; + transform: translate(-10px, 0px); + margin-bottom: 7px; + color: black; + border: none; + width: 156px; + height: 26px; + border-radius: 8px; + background: var(--Light-Periwinkle, #f4f7ff); + box-shadow: 0px 2px 7px 0px rgba(0, 0, 0, 0.2); + padding-top: 6px; + position: relative; + text-align: center; +`; + export const NavBarMovedUP = styled(NavBar)` position: relative; `; diff --git a/src/app/globals.css b/src/app/globals.css index 4d40d22d..5b0dbd13 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -84,7 +84,11 @@ body { max-width: 100vw; min-height: 100vh; } - +button { + &:hover { + cursor: pointer; + } +} body { background: white; color: black; diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 93fcea70..bae4f37c 100644 --- a/src/app/login/page.tsx +++ b/src/app/login/page.tsx @@ -1,6 +1,7 @@ 'use client'; import { useState } from 'react'; + import Image from 'next/image'; import supabase from '@/api/supabase/createClient'; import { Body1, Heading1 } from '@/styles/fonts'; @@ -40,6 +41,13 @@ export default function App() { } }; + async function applyFilter(e: React.KeyboardEvent) { + const keypressed = e.code; + if (keypressed === 'Enter') { + handleLogin(); + } + } + return ( ([]); @@ -38,12 +48,12 @@ export default function OrderConfirmationDelivery() { const [userAddress, setUserAddress] = useState
(); const searchParams = useSearchParams(); const orderIDFromSearch = searchParams.get('orderID'); + const [delivTimes, setDelivTimes] = useState([]); useEffect(() => { async function fetchProducts() { const cartItems = (await fetchCartItemsWithQuantityByID( orderIDFromSearch, )) as Product[]; - console.log(cartItems); setCart(cartItems); } @@ -53,19 +63,44 @@ export default function OrderConfirmationDelivery() { const address = await fetchCurrentUserAddress(); setUserAddress(address); } + async function fetchDelivTimes() { + const deliv = await fetchDeliveryTimes(); + setDelivTimes(deliv); + } fetchProducts(); setUserDetails(); + fetchDelivTimes(); }, []); + function organizeDelivTime() { + const userGrp = user?.delivery_group == null ? 1 : user?.delivery_group; + const Time = delivTimes[userGrp]?.delivery_time.toLocaleString(); + const date = + Time == null ? ['0', '0', '0'] : Time?.substring(0, 10).split('-'); + const months = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', + ]; + const dateStr = `${months[parseInt(date[1], 10)]} ${date[2]}, ${date[0]}`; + return `${dateStr}`; + } + return (
- - - @@ -85,26 +120,14 @@ export default function OrderConfirmationDelivery() { }} /> -
- - Quantity: - - - {cartItem.quantity} - -
+ {cartItem.name} + Category: {cartItem.category}
+ + + Quantity: {cartItem.quantity} + + ))} @@ -114,7 +137,7 @@ export default function OrderConfirmationDelivery() { Delivery Information Estimated Date - {user?.delivery_group} + {organizeDelivTime()} Location {userAddress?.street}, {userAddress?.city},{' '} diff --git a/src/app/orderConfirmationDelivery/styles.ts b/src/app/orderConfirmationDelivery/styles.ts index e72f1ef1..618a5919 100644 --- a/src/app/orderConfirmationDelivery/styles.ts +++ b/src/app/orderConfirmationDelivery/styles.ts @@ -8,11 +8,17 @@ export const FavoriteDiv = styled.div` display: flex; flex-direction: row; align-items: flex-start; - justify-content: flex-start; + justify-content: space-between; width: 100%; margin-bottom: 50px; margin-top: 30px; - gap: 120px; +`; + +export const Quantity = styled.div` + display: flex; + align-self: center; + justify-content: flex-start; + margin-right: 40px; `; export const OrderDetailsDiv = styled.div` @@ -216,16 +222,18 @@ export const OrderTotalDiv = styled.div` `; export const LeftColumnDiv = styled.div` + margin-top: 30px; display: flex; flex-flow: column; justify-content: space-evenly; align-items: space-evenly; + gap: 20px; `; export const RightColumnDiv = styled.div` display: flex; flex-flow: column; margin-left: 20px; - margin-top: 127px; + margin-top: 123px; `; export const WhiteBackgroundDiv = styled.div` diff --git a/src/app/orderConfirmationPickUp/page.tsx b/src/app/orderConfirmationPickUp/page.tsx index c9b612ce..9a93cb72 100644 --- a/src/app/orderConfirmationPickUp/page.tsx +++ b/src/app/orderConfirmationPickUp/page.tsx @@ -4,10 +4,7 @@ import { useState, useEffect } from 'react'; import { fetchUser } from '@/api/supabase/queries/user_queries'; import { fetchPickupTimesByID } from '@/api/supabase/queries/pickup_queries'; -import { - fetchCurrentOrdersByUser, - getOrderById, -} from '@/api/supabase/queries/order_queries'; +import { getOrderById } from '@/api/supabase/queries/order_queries'; import { Body1, Body1Bold, @@ -73,7 +70,6 @@ export default function OrderConfirmationPickUp() { function organizePickupTime() { const startTime = pickupTime?.start_time.toLocaleString(); - const endTime = pickupTime?.end_time.toLocaleString(); const date = startTime == null ? ['0', '0', '0'] diff --git a/src/app/orderPageDelivery/page.tsx b/src/app/orderPageDelivery/page.tsx new file mode 100644 index 00000000..0b78c29e --- /dev/null +++ b/src/app/orderPageDelivery/page.tsx @@ -0,0 +1,211 @@ +'use client'; + +import { useState, useEffect } from 'react'; +import { + fetchUser, + fetchCurrentUserAddress, +} from '@/api/supabase/queries/user_queries'; + +import { + Body1, + Body2, + Body2Light, + Heading2Bold, + Heading3Bold, + Heading4Bold, +} from '@/styles/fonts'; +import { useSearchParams } from 'next/navigation'; +import { + DeliveryTimes, + fetchDeliveryTimes, +} from '@/api/supabase/queries/delivery_queries'; +import { + fetchOrderProductsbyOrderId, + getOrderById, +} from '@/api/supabase/queries/order_queries'; +import BackButton from '../../components/BackButton/BackButton'; + +import { fetchCartItemsWithQuantityByID } from '../../api/supabase/queries/cart_queries'; + +import NavBar from '../../components/NavBarFolder/NavBar'; + +import { + FavoriteDiv, + OutterFavoriteDiv, + LabelBox, + ScrollDiv, + ShippingDetailsDiv, + BottomColumnDiv, + LeftColumnDiv, + RightColumnDiv, + DetailsHeader, + PageDiv, + CenterDiv, + Quantity, + StatusButton, +} from './styles'; + +import { + Product, + User, + Address, + ProductWithQuantity, + Order, +} from '../../schema/schema'; +import { Body1Bold } from '../orderPage/styles'; +import { BackButtonDiv } from '../orderConfirmationPickUp/styles'; + +export default function OrderPageDelivery() { + const [orders, setOrders] = useState([]); + const searchParams = useSearchParams(); + const orderIDFromSearch = searchParams.get('orderID'); + let currOrderId = 0; + const [delivTimes, setDelivTimes] = useState([]); + + if (orderIDFromSearch !== null) { + currOrderId = parseInt(orderIDFromSearch, 10); + } else { + currOrderId = 32; + } + + const [order, setOrder] = useState(); + const [userAddress, setUserAddress] = useState
(); + const [user, setUser] = useState(); + const months = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', + ]; + + useEffect(() => { + async function fetchProducts() { + const data = (await fetchOrderProductsbyOrderId( + currOrderId, + )) as ProductWithQuantity[]; + const currOrder = await getOrderById(currOrderId); + setOrders(data); + setOrder(currOrder); + } + + async function setUserDetails() { + const fetchedUser = await fetchUser(); + setUser(fetchedUser); + const address = await fetchCurrentUserAddress(); + setUserAddress(address); + } + async function fetchDelivTimes() { + const deliv = await fetchDeliveryTimes(); + setDelivTimes(deliv); + } + + fetchDelivTimes(); + fetchProducts(); + setUserDetails(); + }, []); + + function organizeDelivTime() { + const userGrp = user?.delivery_group == null ? 1 : user?.delivery_group; + const Time = delivTimes[userGrp]?.delivery_time.toLocaleString(); + const date = + Time == null ? ['0', '0', '0'] : Time?.substring(0, 10).split('-'); + const dateStr = `${months[parseInt(date[1], 10) - 1]} ${date[2]}, ${ + date[0] + }`; + return `${dateStr}`; + } + + function organizeOrderDate() { + const Time = order?.created_at.toLocaleString(); + const date = + Time == null ? ['0', '0', '0'] : Time?.substring(0, 10).split('-'); + const dateStr = `${months[parseInt(date[1], 10) - 1]} ${date[2]}, ${ + date[0] + }`; + return `${dateStr}`; + } + + function organizeOrderTime() { + const Time = order?.created_at.toLocaleString(); + console.log(Time); + let ampm = 'AM'; + const date = + Time == null ? ['00', '00'] : Time?.substring(11, 16).split(':'); + + console.log(date); + if (parseInt(date[0], 10) >= 12) { + date[0] = (parseInt(date[0], 10) - 12).toLocaleString(); + ampm = 'PM'; + } + const timeStr = `${date[0]}:${date[1]} ${ampm}`; + return `${timeStr}`; + } + + return ( +
+ + + + + + + Order No. {orderIDFromSearch} + + Order Date: {organizeOrderDate()} + Order Time: {organizeOrderTime()} + + {orders.map(product => ( + + {product.name} + + {product.name} + Category: {product.category} + + + + Quantity: {product.quantity} + + + + ))} + + + + + + {' '} + {order?.order_status}{' '} + + + Delivery Information + Estimated Date + {organizeDelivTime()} + Location + + {userAddress?.street}, {userAddress?.city},{' '} + {userAddress?.zipcode} + + + + + + +
+ ); +} diff --git a/src/app/orderPageDelivery/styles.ts b/src/app/orderPageDelivery/styles.ts new file mode 100644 index 00000000..588dc25c --- /dev/null +++ b/src/app/orderPageDelivery/styles.ts @@ -0,0 +1,265 @@ +import styled from 'styled-components'; + +import { Heart } from 'react-feather'; + +import NavBar from '../../components/NavBarFolder/NavBar'; + +export const FavoriteDiv = styled.div` + display: flex; + flex-direction: row; + align-items: flex-start; + justify-content: space-between; + width: 100%; + margin-bottom: 50px; + margin-top: 30px; +`; + +export const Quantity = styled.div` + display: flex; + align-self: center; + justify-content: flex-start; + margin-right: 40px; +`; + +export const OrderDetailsDiv = styled.div` + width: 750px; + height: auto; + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; +`; + +export const CenterDiv = styled.div` + display: flex; + align-items: center; + justify-content: center; + width: 100%; +`; + +export const OutterFavoriteDiv = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + border-radius: 10px; + background: var(--White, #fff); + box-shadow: 0px 1px 4px 1px rgba(0, 0, 0, 0.2); + width: 650px; + height: auto; + max-height: 793px; + margin-top: 5px; + margin-bottom: 50px; + gap: 24px; + padding: 36px 32px; +`; + +export const ScrollDiv = styled.div` + overflow: scroll; + width: 100%; +`; + +export const BackDiv = styled.button` + display: flex; + flex-direction: row; + align: center; + color: black; + background-color: transparent; + border: transparent; + margin-bottom: 25px; + margin-top: 25px; + margin-left: 25px; + width: 100%; +`; + +export const OutterBox = styled.div` + width: 750px; + height: auto; + display: flex; + flex-direction: column; + justify-content: space-around; + align-items: center; +`; + +export const Backtext = styled.p` + color: var(--Black, #101010); + /* Body 1 - Bold, button */ + font-family: Public Sans; + font-size: 20px; + font-style: normal; + font-weight: 700; + line-height: normal; +`; + +export const HeartIcon = styled(Heart)` + color: #333286; + width: 30px; + height: 30px; + fill: #333286; +`; + +export const TransparentButton = styled.button` + background-color: transparent; + border: transparent; +`; + +export const NavBarMovedUP = styled(NavBar)` + position: static; +`; + +export const Label = styled.p` + margin-top: 9px; +`; + +export const Category = styled.p` + margin-top: 10px; +`; + +export const LabelBox = styled.div` + width: 150px; + height: 100%; + display: flex; + align-self: center; + flex-direction: column; + gap: 9px; +`; + +export const HeaderText = styled.h3` + color: var(--Black, #101010); + margin-top: 30px; + margin-bottom: 20px; + text: center; + color: var(--Black, #101010); + font-family: Public Sans; + font-size: 35px; + font-style: normal; + font-weight: 700; + line-height: normal; +`; + +export const ShippingDetailsDiv = styled.div` + display: flex; + flex-direction: column; + align-items: space-start; + border-radius: 10px; + background: var(--White, #fff); + box-shadow: 0px 1px 4px 1px rgba(0, 0, 0, 0.2); + width: 467px; + height: auto; + max-height: 793px; + margin-top: 10px; + margin-bottom: 50px; + padding: 36px 34px; + gap: 33px; +`; + +export const DetailsHeader = styled.p` + color: var(--Navy, #1b3679); + font-family: Public Sans, sans-serif; + font-size: 20px; + font-style: normal; + font-weight: 700; + line-height: normal; +`; + +export const DetailsText = styled.p` + color: var(--Black, #101010); + font-family: Public Sans; + font-size: 17px; + font-style: normal; + font-weight: 400; + line-height: normal; + margin-top: 20px; +`; + +export const BottomColumnDiv = styled.div` + display: flex; + flex-flow: row; + align-items: space-evenly; + justify-content: space-around; + width: 100%; +`; + +export const PageDiv = styled.div` + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + width: 100%; +`; + +export const TopColumnDiv = styled.div` + display: flex; + flex-flow: column; + align-items: flex-start; + justify-content: space-around; + margin-bottom: 20px; +`; + +export const OrderSummaryDiv = styled.div` + overflow: scroll; + width: 350px; + height: 300px; +`; + +export const ItemSummaryDiv = styled.div` + display: flex; + flex-direction: row; + margin-bottom: 20px; + justify-content: space-between; + padding-left: 10px; + padding-right: 10px; +`; + +export const OrderTotalDiv = styled.div` + height: 50px; + padding-top: 10px; + width: 350px; + padding-left: 0px; + border-top: 1px black solid; + display: flex; + flex-flow: row; + justify-content: space-between; +`; + +export const LeftColumnDiv = styled.div` + margin-top: 30px; + display: flex; + flex-flow: column; + justify-content: space-evenly; + align-items: space-evenly; + gap: 20px; +`; +export const RightColumnDiv = styled.div` + display: flex; + flex-flow: column; + margin-left: 20px; + margin-top: 84px; +`; + +export const WhiteBackgroundDiv = styled.div` + border-radius: 8px; + background: var(--White, #fff); + height: 430px; + width: 350px; + padding-top: 20px; + + box-shadow: 0px 4px 7px 0px rgba(0, 0, 0, 0.1); +`; + +export const StatusButton = styled.button` + margin-left: auto; + margin-right: 0; + color: black; + text-align: center; + width: 210px; + height: 30px; + flex-shrink: 0; + padding-top: 3px; + padding-right: 10px; + padding-left: 10px; + padding-bottom: 3px; + border: none; + border-radius: 16.5px; + background: var(--Baby-Blue, #c7ddff); + margin-bottom: 14px; +`; diff --git a/src/app/pickup/page.tsx b/src/app/pickup/page.tsx index 097b878e..bd8d8ea3 100644 --- a/src/app/pickup/page.tsx +++ b/src/app/pickup/page.tsx @@ -1,6 +1,9 @@ 'use client'; // import { GlobalStyle } from "@/styles/components"; + +import 'react-toastify/dist/ReactToastify.css'; +import { toast } from 'react-toastify'; import { ArrowLeft } from 'react-feather'; import { fetchUser } from '@/api/supabase/queries/user_queries'; import querystring from 'querystring'; @@ -10,8 +13,8 @@ import { totalNumberOfItemsInCart, } from '@/api/supabase/queries/cart_queries'; import { useState, useEffect } from 'react'; -import { useRouter, useSearchParams } from 'next/navigation'; -import { Heading4Bold } from '@/styles/fonts'; +import { useRouter } from 'next/navigation'; +import { Body1, Heading4Bold } from '@/styles/fonts'; import { fetchNRecentPickupTimes } from '@/api/supabase/queries/pickup_queries'; import { updateCartPickupId, @@ -36,6 +39,7 @@ import { PickupContent, PickupContainer, PickupTimeButton, + ToastPopUP, } from './styles'; function DateInfoComponent(date: { date: unknown }) { @@ -100,6 +104,12 @@ export default function PickUp() { return (
+ router.push('/cart')}> @@ -116,10 +126,22 @@ export default function PickUp() { Phone Number {Profile?.phone_numbers} -
+
Time Slot
- +
+ {' '} + Pick Up times: 10:00 AM - 12:00 PM{' '} +
+
+ Location: 3170 23rd Street, San Francisco, CA 94110 +
{Time.map(time => ( ))}
-
Pick Up times: 10:00 AM - 12:00 PM
-
Location: 3170 23rd Street, San Francisco, CA 94110
@@ -157,12 +177,13 @@ export default function PickUp() { await updateOrderStatus(orderID, OrderStatus.Submitted); await createOrder(); const newestOrder = await fetchCartIdFromUser(); - console.log(newestOrder); await updateOrderStatus(newestOrder, OrderStatus.inProgress); const queryString = querystring.stringify({ orderID }); router.push(`/orderConfirmationPickUp?${queryString}`); - } else { - // TODO handle the case where they didn't select a time! + } + if (selectedPickupIndex === 0) { + toast(`You must select a pick-up date!`); + toast.clearWaitingQueue(); } }} > diff --git a/src/app/pickup/styles.ts b/src/app/pickup/styles.ts index 35365312..af517b07 100644 --- a/src/app/pickup/styles.ts +++ b/src/app/pickup/styles.ts @@ -1,5 +1,6 @@ import styled from 'styled-components'; +import { ToastContainer } from 'react-toastify'; import COLORS from '../../styles/colors'; import NavBar from '../../components/NavBarFolder/NavBar'; @@ -263,3 +264,9 @@ export const HeaderShiftLeft = styled.h2` export const PShiftLeft = styled.p` margin-left: 15px; `; + +export const ToastPopUP = styled(ToastContainer)` + position: fixed; + z-index: 100; + transform: translatey(90px); +`; diff --git a/src/app/profileScreen/individualItem.tsx b/src/app/profileScreen/individualItem.tsx new file mode 100644 index 00000000..69288d69 --- /dev/null +++ b/src/app/profileScreen/individualItem.tsx @@ -0,0 +1,64 @@ +import React, { useEffect, useState } from 'react'; + +import { Body1Bold, Body2, Body3 } from '@/styles/fonts'; + +import { convertButtonNumberToCategory } from '@/api/supabase/queries/button_queries'; +import { HeartIcon, Hover, FavoriteDiv, ProductNameDiv } from './styles'; + +import { addOrRemoveProductFromFavorite } from '../../api/supabase/queries/user_queries'; + +import { Product } from '../../schema/schema'; +import { TransparentButton } from '../favorites/styles'; + +export default function IndividualItem(props: { + favorite: Product; + setFavorites: (category: Product[]) => void; + Favorites: Product[]; +}) { + const { favorite, Favorites, setFavorites } = props; + const [hovering, setHovering] = useState(false); + + // useEffect(() => { + // async function changeCategory() { + // try { + // favorite.category = await convertButtonNumberToCategory( + // favorite.category, + // ); + // } catch (error) { + // // console.error(error); + // } + // } + + // changeCategory(); + // }, []); + + async function clickFunctions(props2: { fav: Product }) { + const { fav } = props2; + addOrRemoveProductFromFavorite(fav, false); + setFavorites(Favorites.filter(Prod => Prod.id !== fav.id)); + } + + return ( + + {favorite.name} + + {favorite.name} + Category: {favorite.category} + + clickFunctions({ fav: favorite })} + onMouseEnter={() => setHovering(true)} + onMouseLeave={() => setHovering(false)} + > + + Remove from favorites + + + + + ); +} diff --git a/src/app/profileScreen/page.tsx b/src/app/profileScreen/page.tsx index 0b98511a..a7213cb2 100644 --- a/src/app/profileScreen/page.tsx +++ b/src/app/profileScreen/page.tsx @@ -12,8 +12,8 @@ import { Body2Bold, Body2, } from '@/styles/fonts'; +import { convertButtonNumberToCategory } from '@/api/supabase/queries/button_queries'; import { - addOrRemoveProductFromFavorite, arrayOfFavorites, fetchUser, fetchCurrentUserAddress, @@ -42,9 +42,6 @@ import { TextSpacing, OrderHistory, FavoritesContainer, - ProductNameDiv, - FavoriteDiv, - HeartIcon, BackButtonDiv, BlankSpace, HeaderDiv, @@ -56,18 +53,13 @@ import { } from './styles'; import { signOut } from '../../api/supabase/auth/auth'; import 'react-toastify/dist/ReactToastify.css'; -import { TransparentButton } from '../favorites/styles'; +import IndividualItem from './individualItem'; function FavoriteSection(props: { Favorites: Product[]; setFavorites: (category: Product[]) => void; }) { const { Favorites, setFavorites } = props; - async function clickFunctions(props2: { fav: Product }) { - const { fav } = props2; - addOrRemoveProductFromFavorite(fav, false); - setFavorites(Favorites.filter(Prod => Prod.id !== fav.id)); - } if (Favorites.length > 0) { return (
@@ -77,25 +69,12 @@ function FavoriteSection(props: { {Favorites.slice(0, 2).map(favorite => ( - - {favorite.name} - -

- {favorite.name} -
- Product ID: {favorite.id} -

-
- clickFunctions({ fav: favorite })} - > - - -
+ ))}
@@ -383,11 +362,6 @@ export default function Profile() { const [Orders, setOrder] = useState([]); - async function fetchProducts() { - const data = (await arrayOfFavorites()) as Product[]; - setFavorites(data); - } - async function fetchOrders() { const data = (await fetchOrdersByUserIdSorted()) as Order[]; setOrder(data); @@ -398,10 +372,18 @@ export default function Profile() { setUser(data); } useEffect(() => { + async function fetchProducts() { + const data = (await arrayOfFavorites()) as Product[]; + + console.log(data); + // console.log(data); + setFavorites(data); + } fetchProducts(); fetchOrders(); getUser(); }, []); + if (user === undefined) { return

Loading User

; } diff --git a/src/app/profileScreen/styles.ts b/src/app/profileScreen/styles.ts index 1ee1f70b..1ae59176 100644 --- a/src/app/profileScreen/styles.ts +++ b/src/app/profileScreen/styles.ts @@ -109,6 +109,23 @@ export const HeartIcon = styled(Heart)` width: 25px; height: 25px; fill: #333286; + margin-bottom: 40px; +`; + +export const Hover = styled.div<{ $ishovering?: boolean }>` + visibility: ${props => (props.$ishovering ? 'visible' : 'hidden')}; + transform: translate(0px, -1px); + margin-bottom: 7px; + color: black; + border: none; + width: 156px; + height: 26px; + border-radius: 8px; + background: var(--Light-Periwinkle, #f4f7ff); + box-shadow: 0px 2px 7px 0px rgba(0, 0, 0, 0.2); + padding-top: 6px; + position: relative; + text-align: center; `; export const BackButtonDiv = styled.div` diff --git a/src/app/storefront/productButtons.tsx b/src/app/storefront/productButtons.tsx index 076e25a4..23b99371 100644 --- a/src/app/storefront/productButtons.tsx +++ b/src/app/storefront/productButtons.tsx @@ -68,7 +68,6 @@ export default function ProductButtons(props: { // Applying the filter to the categories of the product if (category !== 'All') { - console.log(category); const products = await filterUserProducts(category); if (products !== null) { setFiltredProducts(products); diff --git a/src/components/InputFieldsFolder/styles.ts b/src/components/InputFieldsFolder/styles.ts index aad7eb73..2fa8ed20 100644 --- a/src/components/InputFieldsFolder/styles.ts +++ b/src/components/InputFieldsFolder/styles.ts @@ -4,7 +4,7 @@ import COLORS from '../../styles/colors'; export const Input1 = styled.input<{ $pickColor?: boolean }>` color: ${props => (props.$pickColor ? '#203354' : COLORS.black)}; - background: ${props => (props.$pickColor ? '#ADD8E6' : COLORS.white)}; + background: ${props => (props.$pickColor ? '#ADD8E6' : COLORS.lightGrey)}; stroke-width: 1px; width: 420px; height: 40px; @@ -31,8 +31,9 @@ export const Input = styled.input<{ stroke-width: 1px; color: ${COLORS.black}; border: 1.5px solid - ${props => (props.$wrongLogin ? COLORS.darkRed : COLORS.black)}; - background: ${props => (props.$pickColor ? COLORS.lightRed : COLORS.white)}; + ${props => (props.$wrongLogin ? COLORS.darkRed : COLORS.neutralGrey)}; + background: ${props => + props.$pickColor ? COLORS.lightRed : COLORS.lightGrey}; width: 420px; height: 40px; padding-left: 10px; diff --git a/src/components/OrderHistory/OrderHistoryText.tsx b/src/components/OrderHistory/OrderHistoryText.tsx index 3c109481..329e4500 100644 --- a/src/components/OrderHistory/OrderHistoryText.tsx +++ b/src/components/OrderHistory/OrderHistoryText.tsx @@ -1,8 +1,9 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import querystring from 'querystring'; import { Heading4Bold, Body1, OrderStatusFont } from '@/styles/fonts'; +import { fetchUser } from '@/api/supabase/queries/user_queries'; import { ViewOrderButton, ArrowIcon, @@ -34,10 +35,24 @@ interface OrderDetailsProps { export default function OrderDetails(props: OrderDetailsProps) { const { date, orderNumber, order } = props; const router = useRouter(); + const [deliveryEnabled, setDeliveryEnabled] = useState(false); + + useEffect(() => { + async function fetchDelivery() { + const data = await fetchUser(); + setDeliveryEnabled(data.delivery_allowed); + } + + fetchDelivery(); + }, []); const viewOrder = (orderID: string) => { const queryString = querystring.stringify({ orderID }); - router.push(`/orderPage?${queryString}`); + if (deliveryEnabled) { + router.push(`/orderPageDelivery?${queryString}`); + } else { + router.push(`/orderPage?${queryString}`); + } }; if (order.order_status === OrderStatus.Rejected) { return ( diff --git a/src/components/OrderSummaryFolder/OrderSummary.tsx b/src/components/OrderSummaryFolder/OrderSummary.tsx index 07f03669..9cf046cc 100644 --- a/src/components/OrderSummaryFolder/OrderSummary.tsx +++ b/src/components/OrderSummaryFolder/OrderSummary.tsx @@ -1,6 +1,6 @@ 'use client'; -import { Body1, Body2, Heading2Bold, Body1Bold } from '@/styles/fonts'; +import { Body1, Heading2Bold, Body1Bold, Body2Light } from '@/styles/fonts'; import { OrderSummaryDiv, HeaderShiftRight, @@ -24,8 +24,8 @@ export default function OrderSummary(props: { Order Summary - Product Name - Qty. + PRODUCT NAME + QTY {cart.map(cartItem => ( diff --git a/src/components/OrderSummaryFolder/styles.ts b/src/components/OrderSummaryFolder/styles.ts index e90a18ef..16fd4a3f 100644 --- a/src/components/OrderSummaryFolder/styles.ts +++ b/src/components/OrderSummaryFolder/styles.ts @@ -1,3 +1,4 @@ +import COLORS from '@/styles/colors'; import styled from 'styled-components'; export const OrderSummaryDiv = styled.div` @@ -37,6 +38,10 @@ export const WhiteBackgroundDiv = styled.div` width: 350px; padding: 20px; box-shadow: 0px 4px 7px 0px rgba(0, 0, 0, 0.1); + display: flex; + justify-content: center; + align-items: flex-start; + flex-direction: column; `; export const HeaderShiftRight = styled.h2` @@ -57,7 +62,8 @@ export const OrderSummaryHeaderDiv = styled.div` justify-content: space-between; align-items: center; flex-direction: row; - margin-bottom: 10px; + margin-bottom: 15px; + color: ${COLORS.marineBlue}; `; export const ItemNameDiv = styled.div`