From 1d57cf491da09db10ccf9bf18d2ef54a46a9494b Mon Sep 17 00:00:00 2001 From: Monique Cheng Date: Wed, 17 Apr 2024 14:20:29 -0700 Subject: [PATCH 01/18] fixes --- src/app/[productId]/Buttons.tsx | 11 +++++---- src/app/[productId]/page.tsx | 20 ++++++++--------- src/app/[productId]/styles.ts | 26 +++++++++------------- src/app/globals.css | 6 ++++- src/app/login/styles.ts | 8 +++++-- src/app/storefront/productButtons.tsx | 1 - src/components/InputFieldsFolder/styles.ts | 6 ++--- 7 files changed, 42 insertions(+), 36 deletions(-) diff --git a/src/app/[productId]/Buttons.tsx b/src/app/[productId]/Buttons.tsx index 80bea55a..35783e34 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, @@ -9,6 +11,7 @@ import { import { addToCart } from '../../api/supabase/queries/cart_queries'; + export default function Buttons(props: { productNumber: number }) { const [quantity, setQuantity] = useState(1); const { productNumber } = props; @@ -26,18 +29,18 @@ export default function Buttons(props: { productNumber: number }) { // used hyphen instead of dash for display const changeCart = () => { addToCart(productNumber, quantity); - toast(`you have added ${quantity} items to the cart!`); + toast(`You have added ${quantity} items to the cart!`); }; return ( - – + - {quantity} + {quantity} - + + diff --git a/src/app/[productId]/page.tsx b/src/app/[productId]/page.tsx index f93bd3d3..02d35983 100644 --- a/src/app/[productId]/page.tsx +++ b/src/app/[productId]/page.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { convertButtonNumberToCategory } from '@/api/supabase/queries/button_queries'; -import { Body1, Heading1, Body2Light } from '@/styles/fonts'; +import { Body1, Heading1, Body2Light, Body2Bold } from '@/styles/fonts'; import { fetchProductByID } from '../../api/supabase/queries/product_queries'; import BackButton from '../../components/BackButton/BackButton'; import 'react-toastify/dist/ReactToastify.css'; @@ -13,6 +13,7 @@ import { DescriptionContainer, ToastPopUP, Fullscreen, + LeftColumnDiv } from './styles'; import NavBar from '../../components/NavBarFolder/NavBar'; @@ -53,11 +54,10 @@ export default function ItemDisplay({ limit={1} hideProgressBar /> -
- -
+ + + {Item?.name} - {Item?.category} + Category: {Item?.category} - - Product ID: {Item?.id} - - + Product Details: + + + {Item?.description} - {Item?.description} diff --git a/src/app/[productId]/styles.ts b/src/app/[productId]/styles.ts index e96cbb27..3a68f588 100644 --- a/src/app/[productId]/styles.ts +++ b/src/app/[productId]/styles.ts @@ -2,42 +2,37 @@ import styled from 'styled-components'; import { ToastContainer } from 'react-toastify'; 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 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 +41,7 @@ export const ButtonsWrapper = styled.div` align-items: center; width: 450px; height: 50px; - margin-top: 20px; + margin-top: 40px; `; export const QuantityButton = styled.div` @@ -94,4 +89,5 @@ export const ToastPopUP = styled(ToastContainer)` export const Fullscreen = styled.div` width: 100%; height: 100%; + display: grid; `; diff --git a/src/app/globals.css b/src/app/globals.css index 4d40d22d..c241f2ec 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/styles.ts b/src/app/login/styles.ts index 41968785..d94d373f 100644 --- a/src/app/login/styles.ts +++ b/src/app/login/styles.ts @@ -3,11 +3,14 @@ import styled from 'styled-components'; import COLORS from '../../styles/colors'; export const LoginBox = styled.div` + display: flex; width: 500px; height: 420px; - border: 1px solid ${COLORS.neutralGrey}; justify-self: center; align-self: center; + background-color: ${COLORS.white}; + box-shadow: 0px 4px 7px 0px rgba(0, 0, 0, 0.10); + border-radius: 10px; `; export const LoginContent = styled.div` @@ -15,7 +18,6 @@ export const LoginContent = styled.div` flex-direction: column; align-self: center; justify-self: center; - margin-top: 30px; text-color: ${COLORS.black}; `; @@ -78,8 +80,10 @@ export const Fullscreen = styled.div` width: 100%; height: 100vh; display: grid; + background-color: ${COLORS.lightGrey}; `; export const InputField = styled.div` position: relative; + background-color: ${COLORS.lightGrey}; `; 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..73520526 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,8 @@ 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; From 9f61fe8200f845a490afa4a08e9c05ef535724f4 Mon Sep 17 00:00:00 2001 From: Monique Cheng Date: Wed, 17 Apr 2024 21:07:56 -0700 Subject: [PATCH 02/18] product page finished; favorites hover button finished; login partially done --- src/api/supabase/queries/user_queries.ts | 1 + src/app/[productId]/page.tsx | 37 +++++++++-- src/app/[productId]/styles.ts | 49 ++++++++++++++- src/app/favorites/individualItem.tsx | 78 ++++++++++++++++++++++++ src/app/favorites/page.tsx | 47 +++----------- src/app/favorites/styles.ts | 23 +++++++ src/app/profileScreen/individualItem.tsx | 64 +++++++++++++++++++ src/app/profileScreen/page.tsx | 36 +++-------- src/app/profileScreen/styles.ts | 17 ++++++ 9 files changed, 279 insertions(+), 73 deletions(-) create mode 100644 src/app/favorites/individualItem.tsx create mode 100644 src/app/profileScreen/individualItem.tsx diff --git a/src/api/supabase/queries/user_queries.ts b/src/api/supabase/queries/user_queries.ts index 6b374796..cba6d587 100644 --- a/src/api/supabase/queries/user_queries.ts +++ b/src/api/supabase/queries/user_queries.ts @@ -105,6 +105,7 @@ export async function arrayOfFavorites(): Promise { return arrayOfProducts; } + /** * fetchUserAddress: Get's a user's address based on their UUID * @param uuid: String containing the uuid of the user diff --git a/src/app/[productId]/page.tsx b/src/app/[productId]/page.tsx index 02d35983..b657c863 100644 --- a/src/app/[productId]/page.tsx +++ b/src/app/[productId]/page.tsx @@ -2,8 +2,8 @@ import { useEffect, useState } from 'react'; import { convertButtonNumberToCategory } from '@/api/supabase/queries/button_queries'; -import { Body1, Heading1, Body2Light, Body2Bold } 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,9 +13,13 @@ import { DescriptionContainer, ToastPopUP, Fullscreen, - LeftColumnDiv + 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'; @@ -26,6 +30,10 @@ export default function ItemDisplay({ params: { productId: number }; }) { const [Item, setItem] = useState(); + const [IsFavorite, setIsFavorite] = useState( + false + ); + const [FilteredProducts, setFilteredProducts] = useState([]); useEffect(() => { async function fetchProducts() { @@ -34,8 +42,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); @@ -45,6 +57,11 @@ export default function ItemDisplay({ fetchProducts(); }, [params.productId]); + async function handleFavorite() { + await addOrRemoveProductFromFavorite(await fetchProductByID(params.productId), !IsFavorite); + setIsFavorite(!IsFavorite); + } + return ( @@ -67,8 +84,18 @@ export default function ItemDisplay({ + {Item?.name} - + handleFavorite()}> + + + {IsFavorite ? 'Remove from favorites' : 'Add to favorites'} + + + + + + Category: {Item?.category} diff --git a/src/app/[productId]/styles.ts b/src/app/[productId]/styles.ts index 3a68f588..285c5f76 100644 --- a/src/app/[productId]/styles.ts +++ b/src/app/[productId]/styles.ts @@ -1,8 +1,9 @@ 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 LeftColumnDiv = styled.div` display: flex; flex-direction: column; @@ -19,6 +20,12 @@ export const DescriptionContainer = styled.div` justify-self: center; `; +export const TopRightContainer = styled.div` + display: flex; + justify-content: space-between; + width: 440px; +`; + export const ImageContainer = styled.div` width: 500px; height: 500px; @@ -66,6 +73,7 @@ export const PlusMinusButton = styled.button` font-size: 20px; color: ${COLORS.navy}; `; + export const AddToCartButton = styled.button` width: 265px; height: 50px; @@ -80,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; diff --git a/src/app/favorites/individualItem.tsx b/src/app/favorites/individualItem.tsx new file mode 100644 index 00000000..7b68d6ad --- /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(); + }, []); + + 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 + + + + + ); +} \ No newline at end of file diff --git a/src/app/favorites/page.tsx b/src/app/favorites/page.tsx index 8c16242d..96af5abc 100644 --- a/src/app/favorites/page.tsx +++ b/src/app/favorites/page.tsx @@ -1,34 +1,26 @@ '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 NavBar from '../../components/NavBarFolder/NavBar'; import { - FavoriteDiv, OutterFavoriteDiv, OutterBox, - ProductNameDiv, - HeartIcon, - TransparentButton, - ViewItem, Fullscreen, - ImageLinkWrapper, } 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 +30,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 +38,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 b2fb6851..b764502f 100644 --- a/src/app/favorites/styles.ts +++ b/src/app/favorites/styles.ts @@ -43,6 +43,11 @@ export const BackDiv = styled.button` export const OutterBox = styled.div` width: 800px; height: 100%; + margin-top: 40px; + display: flex; + flex-direction: column; + gap: 20px; + margin-bottom: 20px; `; export const Backtext = styled.p` @@ -55,6 +60,7 @@ export const HeartIcon = styled(Heart)` height: 30px; fill: #333286; margin-right: 25px; + margin-bottom: 40px; `; export const TransparentButton = styled.button` @@ -63,6 +69,23 @@ 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/profileScreen/individualItem.tsx b/src/app/profileScreen/individualItem.tsx new file mode 100644 index 00000000..eb2d7627 --- /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 + + + + + ); +} \ No newline at end of file diff --git a/src/app/profileScreen/page.tsx b/src/app/profileScreen/page.tsx index 2e101da1..8dca6cd1 100644 --- a/src/app/profileScreen/page.tsx +++ b/src/app/profileScreen/page.tsx @@ -42,9 +42,6 @@ import { TextSpacing, OrderHistory, FavoritesContainer, - ProductNameDiv, - FavoriteDiv, - HeartIcon, BackButtonDiv, BlankSpace, HeaderDiv, @@ -56,18 +53,14 @@ 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 +70,12 @@ function FavoriteSection(props: { {Favorites.slice(0, 2).map(favorite => ( - - {favorite.name} - -

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

-
- clickFunctions({ fav: favorite })} - > - - -
+ ))}
diff --git a/src/app/profileScreen/styles.ts b/src/app/profileScreen/styles.ts index 884f01b1..5bdb9465 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` From 20ce153cccd8734534c7a8b535f2c41154e22f41 Mon Sep 17 00:00:00 2001 From: Monique Cheng Date: Wed, 17 Apr 2024 21:10:10 -0700 Subject: [PATCH 03/18] eslint and prettier --- src/api/supabase/queries/user_queries.ts | 1 - src/app/[productId]/Buttons.tsx | 5 +- src/app/[productId]/page.tsx | 62 +++++++++++----------- src/app/favorites/individualItem.tsx | 22 ++++---- src/app/favorites/page.tsx | 20 +++---- src/app/favorites/styles.ts | 1 - src/app/globals.css | 2 +- src/app/login/styles.ts | 2 +- src/app/profileScreen/individualItem.tsx | 36 ++++++------- src/app/profileScreen/page.tsx | 12 ++--- src/components/InputFieldsFolder/styles.ts | 3 +- 11 files changed, 79 insertions(+), 87 deletions(-) diff --git a/src/api/supabase/queries/user_queries.ts b/src/api/supabase/queries/user_queries.ts index cba6d587..6b374796 100644 --- a/src/api/supabase/queries/user_queries.ts +++ b/src/api/supabase/queries/user_queries.ts @@ -105,7 +105,6 @@ export async function arrayOfFavorites(): Promise { return arrayOfProducts; } - /** * fetchUserAddress: Get's a user's address based on their UUID * @param uuid: String containing the uuid of the user diff --git a/src/app/[productId]/Buttons.tsx b/src/app/[productId]/Buttons.tsx index 35783e34..a24fb075 100644 --- a/src/app/[productId]/Buttons.tsx +++ b/src/app/[productId]/Buttons.tsx @@ -11,7 +11,6 @@ import { import { addToCart } from '../../api/supabase/queries/cart_queries'; - export default function Buttons(props: { productNumber: number }) { const [quantity, setQuantity] = useState(1); const { productNumber } = props; @@ -36,11 +35,11 @@ export default function Buttons(props: { productNumber: number }) { - + {quantity} - + diff --git a/src/app/[productId]/page.tsx b/src/app/[productId]/page.tsx index b657c863..4f5aa2e0 100644 --- a/src/app/[productId]/page.tsx +++ b/src/app/[productId]/page.tsx @@ -3,7 +3,10 @@ import { useEffect, useState } from 'react'; import { convertButtonNumberToCategory } from '@/api/supabase/queries/button_queries'; import { Body1, Heading1, Body2Light, Body2Bold, Body3 } from '@/styles/fonts'; -import { fetchProductByID, fetchUserProducts } from '../../api/supabase/queries/product_queries'; +import { + fetchProductByID, + fetchUserProducts, +} from '../../api/supabase/queries/product_queries'; import BackButton from '../../components/BackButton/BackButton'; import 'react-toastify/dist/ReactToastify.css'; @@ -17,7 +20,7 @@ import { FavoritePopup, HeartContainer, HeartIcon, - TopRightContainer + TopRightContainer, } from './styles'; import { addOrRemoveProductFromFavorite } from '../../api/supabase/queries/user_queries'; import NavBar from '../../components/NavBarFolder/NavBar'; @@ -30,9 +33,7 @@ export default function ItemDisplay({ params: { productId: number }; }) { const [Item, setItem] = useState(); - const [IsFavorite, setIsFavorite] = useState( - false - ); + const [IsFavorite, setIsFavorite] = useState(false); const [FilteredProducts, setFilteredProducts] = useState([]); useEffect(() => { @@ -44,7 +45,7 @@ export default function ItemDisplay({ ); const data = (await fetchUserProducts()) as Product[]; - setIsFavorite(!!data.find(item => item.id === params.productId)) + setIsFavorite(!!data.find(item => item.id === params.productId)); if (response) { setItem(response); setFilteredProducts(data); @@ -58,7 +59,10 @@ export default function ItemDisplay({ }, [params.productId]); async function handleFavorite() { - await addOrRemoveProductFromFavorite(await fetchProductByID(params.productId), !IsFavorite); + await addOrRemoveProductFromFavorite( + await fetchProductByID(params.productId), + !IsFavorite, + ); setIsFavorite(!IsFavorite); } @@ -74,34 +78,32 @@ export default function ItemDisplay({ - - - {Item?.name} - + + + {Item?.name} + - - {Item?.name} - handleFavorite()}> - - - {IsFavorite ? 'Remove from favorites' : 'Add to favorites'} - - - - - - + + {Item?.name} + handleFavorite()}> + + + {IsFavorite ? 'Remove from favorites' : 'Add to favorites'} + + + + + + Category: {Item?.category} - - Product Details: - + Product Details: {Item?.description} diff --git a/src/app/favorites/individualItem.tsx b/src/app/favorites/individualItem.tsx index 7b68d6ad..7b9eea0c 100644 --- a/src/app/favorites/individualItem.tsx +++ b/src/app/favorites/individualItem.tsx @@ -26,20 +26,20 @@ export default function IndividualItem(props: { 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); - } + try { + favorite.category = await convertButtonNumberToCategory( + favorite.category, + ); + } catch (error) { + // console.error(error); } + } - changeCategory(); - }, []); + changeCategory(); + }, [favorite]); async function clickFunctions(props2: { fav: Product }) { const { fav } = props2; @@ -75,4 +75,4 @@ export default function IndividualItem(props: { ); -} \ No newline at end of file +} diff --git a/src/app/favorites/page.tsx b/src/app/favorites/page.tsx index 96af5abc..6c00e83a 100644 --- a/src/app/favorites/page.tsx +++ b/src/app/favorites/page.tsx @@ -4,17 +4,11 @@ import { useState, useEffect } from 'react'; import { Heading1 } from '@/styles/fonts'; import BackButton from '../../components/BackButton/BackButton'; -import { - arrayOfFavorites, -} from '../../api/supabase/queries/user_queries'; +import { arrayOfFavorites } from '../../api/supabase/queries/user_queries'; import NavBar from '../../components/NavBarFolder/NavBar'; -import { - OutterFavoriteDiv, - OutterBox, - Fullscreen, -} from './styles'; +import { OutterFavoriteDiv, OutterBox, Fullscreen } from './styles'; import IndividualItem from './individualItem'; import { Product } from '../../schema/schema'; @@ -39,11 +33,11 @@ export default function FavoritesPage() { {Favorites.map(favorite => ( + key={favorite.id} + favorite={favorite} + setFavorites={setFavorites} + Favorites={Favorites} + /> ))} diff --git a/src/app/favorites/styles.ts b/src/app/favorites/styles.ts index b764502f..479119e8 100644 --- a/src/app/favorites/styles.ts +++ b/src/app/favorites/styles.ts @@ -69,7 +69,6 @@ export const TransparentButton = styled.button` cursor: pointer; `; - export const Hover = styled.div<{ $ishovering?: boolean }>` visibility: ${props => (props.$ishovering ? 'visible' : 'hidden')}; transform: translate(-10px, 0px); diff --git a/src/app/globals.css b/src/app/globals.css index c241f2ec..5b0dbd13 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -84,7 +84,7 @@ body { max-width: 100vw; min-height: 100vh; } -button{ +button { &:hover { cursor: pointer; } diff --git a/src/app/login/styles.ts b/src/app/login/styles.ts index d94d373f..03fb0708 100644 --- a/src/app/login/styles.ts +++ b/src/app/login/styles.ts @@ -9,7 +9,7 @@ export const LoginBox = styled.div` justify-self: center; align-self: center; background-color: ${COLORS.white}; - box-shadow: 0px 4px 7px 0px rgba(0, 0, 0, 0.10); + box-shadow: 0px 4px 7px 0px rgba(0, 0, 0, 0.1); border-radius: 10px; `; diff --git a/src/app/profileScreen/individualItem.tsx b/src/app/profileScreen/individualItem.tsx index eb2d7627..f7de722e 100644 --- a/src/app/profileScreen/individualItem.tsx +++ b/src/app/profileScreen/individualItem.tsx @@ -17,20 +17,20 @@ export default function IndividualItem(props: { }) { 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); - } + try { + favorite.category = await convertButtonNumberToCategory( + favorite.category, + ); + } catch (error) { + // console.error(error); } + } - changeCategory(); - }, []); + changeCategory(); + }, [favorite]); async function clickFunctions(props2: { fav: Product }) { const { fav } = props2; @@ -40,12 +40,12 @@ export default function IndividualItem(props: { return ( - {favorite.name} - + {favorite.name} + {favorite.name} Category: {favorite.category} @@ -59,6 +59,6 @@ export default function IndividualItem(props: { - + ); -} \ No newline at end of file +} diff --git a/src/app/profileScreen/page.tsx b/src/app/profileScreen/page.tsx index 8dca6cd1..4d63bb8f 100644 --- a/src/app/profileScreen/page.tsx +++ b/src/app/profileScreen/page.tsx @@ -13,7 +13,6 @@ import { Body2, } from '@/styles/fonts'; import { - addOrRemoveProductFromFavorite, arrayOfFavorites, fetchUser, fetchCurrentUserAddress, @@ -55,7 +54,6 @@ import { signOut } from '../../api/supabase/auth/auth'; import 'react-toastify/dist/ReactToastify.css'; import IndividualItem from './individualItem'; - function FavoriteSection(props: { Favorites: Product[]; setFavorites: (category: Product[]) => void; @@ -71,11 +69,11 @@ function FavoriteSection(props: { {Favorites.slice(0, 2).map(favorite => ( + key={favorite.id} + favorite={favorite} + setFavorites={setFavorites} + Favorites={Favorites} + /> ))} diff --git a/src/components/InputFieldsFolder/styles.ts b/src/components/InputFieldsFolder/styles.ts index 73520526..2fa8ed20 100644 --- a/src/components/InputFieldsFolder/styles.ts +++ b/src/components/InputFieldsFolder/styles.ts @@ -32,7 +32,8 @@ export const Input = styled.input<{ color: ${COLORS.black}; border: 1.5px solid ${props => (props.$wrongLogin ? COLORS.darkRed : COLORS.neutralGrey)}; - background: ${props => (props.$pickColor ? COLORS.lightRed : COLORS.lightGrey)}; + background: ${props => + props.$pickColor ? COLORS.lightRed : COLORS.lightGrey}; width: 420px; height: 40px; padding-left: 10px; From f595b6407f7c85b92d0a36fbb5e6302904f70c60 Mon Sep 17 00:00:00 2001 From: Monique Cheng Date: Sun, 21 Apr 2024 11:20:09 -0700 Subject: [PATCH 04/18] order details page done --- src/app/pickup/page.tsx | 26 ++++++++++++++++++-------- src/app/pickup/styles.ts | 9 +++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/app/pickup/page.tsx b/src/app/pickup/page.tsx index 097b878e..4e336ece 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'; @@ -11,7 +14,7 @@ import { } from '@/api/supabase/queries/cart_queries'; import { useState, useEffect } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; -import { Heading4Bold } from '@/styles/fonts'; +import { Body1, Heading4Bold } from '@/styles/fonts'; import { fetchNRecentPickupTimes } from '@/api/supabase/queries/pickup_queries'; import { updateCartPickupId, @@ -36,8 +39,10 @@ import { PickupContent, PickupContainer, PickupTimeButton, + ToastPopUP, } from './styles'; + function DateInfoComponent(date: { date: unknown }) { const date1 = new Date(date.date as string); const daysOfWeek = [ @@ -100,6 +105,12 @@ export default function PickUp() { return (
+ router.push('/cart')}> @@ -116,10 +127,11 @@ 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 +167,12 @@ 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!`); } }} > diff --git a/src/app/pickup/styles.ts b/src/app/pickup/styles.ts index 35365312..257579c3 100644 --- a/src/app/pickup/styles.ts +++ b/src/app/pickup/styles.ts @@ -1,11 +1,13 @@ import styled from 'styled-components'; +import { ToastContainer } from 'react-toastify'; import COLORS from '../../styles/colors'; import NavBar from '../../components/NavBarFolder/NavBar'; import Footer from '../../components/FooterFolder/Footer'; + export const PickupContainer = styled.div` width: 730px; height: 400px; @@ -263,3 +265,10 @@ 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); + background-color: ${COLORS.lightRed}; +`; \ No newline at end of file From a34ef2d70f43e4bf7cb10a766ee0fec7e6c94987 Mon Sep 17 00:00:00 2001 From: Monique Cheng Date: Sun, 21 Apr 2024 11:30:25 -0700 Subject: [PATCH 05/18] changes made --- src/app/pickup/page.tsx | 20 ++++++++++++++----- src/app/pickup/styles.ts | 3 +-- .../OrderSummaryFolder/OrderSummary.tsx | 6 +++--- src/components/OrderSummaryFolder/styles.ts | 8 +++++++- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/app/pickup/page.tsx b/src/app/pickup/page.tsx index 4e336ece..33e43490 100644 --- a/src/app/pickup/page.tsx +++ b/src/app/pickup/page.tsx @@ -42,7 +42,6 @@ import { ToastPopUP, } from './styles'; - function DateInfoComponent(date: { date: unknown }) { const date1 = new Date(date.date as string); const daysOfWeek = [ @@ -127,11 +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
+
+ {' '} + Pick Up times: 10:00 AM - 12:00 PM{' '} +
+
+ Location: 3170 23rd Street, San Francisco, CA 94110 +
{Time.map(time => ( 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` From 745b2a1949b2cac8983436c63f34a99414748bd5 Mon Sep 17 00:00:00 2001 From: Monique Cheng Date: Sun, 21 Apr 2024 12:32:56 -0700 Subject: [PATCH 06/18] order details page done --- src/api/supabase/queries/cart_queries.ts | 1 - src/api/supabase/queries/delivery_queries.ts | 15 ++++++ src/api/supabase/queries/order_queries.ts | 2 - src/api/supabase/queries/product_queries.ts | 2 - src/api/supabase/queries/user_queries.ts | 12 ++--- src/app/orderConfirmationDelivery/page.tsx | 50 ++++++++++++++++++-- src/app/orderConfirmationDelivery/styles.ts | 14 ++++-- src/app/orderConfirmationPickUp/page.tsx | 6 +-- src/app/pickup/page.tsx | 2 +- 9 files changed, 79 insertions(+), 25 deletions(-) create mode 100644 src/api/supabase/queries/delivery_queries.ts 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 6b374796..96cd6def 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. @@ -48,12 +46,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; } } @@ -118,13 +116,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:`); } } @@ -141,7 +138,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/orderConfirmationDelivery/page.tsx b/src/app/orderConfirmationDelivery/page.tsx index 2d2f902d..3a538d50 100644 --- a/src/app/orderConfirmationDelivery/page.tsx +++ b/src/app/orderConfirmationDelivery/page.tsx @@ -6,8 +6,18 @@ import { fetchCurrentUserAddress, } from '@/api/supabase/queries/user_queries'; -import { Body1, Body2Light, Heading3Bold, Heading4Bold } from '@/styles/fonts'; +import { + Body1, + Body2, + Body2Light, + Heading3Bold, + Heading4Bold, +} from '@/styles/fonts'; import { useSearchParams } from 'next/navigation'; +import { + DeliveryTimes, + fetchDeliveryTimes, +} from '@/api/supabase/queries/delivery_queries'; import BackButton from '../../components/BackButton/BackButton'; import { fetchCartItemsWithQuantityByID } from '../../api/supabase/queries/cart_queries'; @@ -26,6 +36,7 @@ import { DetailsHeader, PageDiv, CenterDiv, + Quantity, } from './styles'; import { Product, User, Address } from '../../schema/schema'; @@ -37,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); } @@ -52,11 +63,39 @@ 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 (
@@ -84,6 +123,11 @@ export default function OrderConfirmationDelivery() { {cartItem.name} Category: {cartItem.category} + + + Quantity: {cartItem.quantity} + + ))} @@ -93,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 871a0e1e..671c018a 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/pickup/page.tsx b/src/app/pickup/page.tsx index 33e43490..6ea5a83a 100644 --- a/src/app/pickup/page.tsx +++ b/src/app/pickup/page.tsx @@ -13,7 +13,7 @@ import { totalNumberOfItemsInCart, } from '@/api/supabase/queries/cart_queries'; import { useState, useEffect } from 'react'; -import { useRouter, useSearchParams } from 'next/navigation'; +import { useRouter } from 'next/navigation'; import { Body1, Heading4Bold } from '@/styles/fonts'; import { fetchNRecentPickupTimes } from '@/api/supabase/queries/pickup_queries'; import { From dfd7df1cca03afa739ca33bdc737770819924672 Mon Sep 17 00:00:00 2001 From: Monique Cheng Date: Wed, 17 Apr 2024 14:20:29 -0700 Subject: [PATCH 07/18] fixes --- src/app/[productId]/Buttons.tsx | 8 ++++--- src/app/[productId]/page.tsx | 20 ++++++++--------- src/app/[productId]/styles.ts | 26 +++++++++------------- src/app/globals.css | 6 ++++- src/app/login/styles.ts | 8 +++++-- src/app/storefront/productButtons.tsx | 1 - src/components/InputFieldsFolder/styles.ts | 6 ++--- 7 files changed, 40 insertions(+), 35 deletions(-) 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..d892f214 100644 --- a/src/app/[productId]/page.tsx +++ b/src/app/[productId]/page.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { convertButtonNumberToCategory } from '@/api/supabase/queries/button_queries'; -import { Body1, Heading1, Body2Light } from '@/styles/fonts'; +import { Body1, Heading1, Body2Light, Body2Bold } from '@/styles/fonts'; import { fetchProductByID } from '../../api/supabase/queries/product_queries'; import BackButton from '../../components/BackButton/BackButton'; import 'react-toastify/dist/ReactToastify.css'; @@ -13,6 +13,7 @@ import { DescriptionContainer, ToastPopUP, Fullscreen, + LeftColumnDiv } from './styles'; import NavBar from '../../components/NavBarFolder/NavBar'; @@ -53,11 +54,10 @@ export default function ItemDisplay({ limit={1} hideProgressBar /> -
- -
+ + + {Item?.name} - {Item?.category} + Category: {Item?.category} - - Product ID: {Item?.id} - - + Product Details: + + + {Item?.description} - {Item?.description} diff --git a/src/app/[productId]/styles.ts b/src/app/[productId]/styles.ts index e96cbb27..3a68f588 100644 --- a/src/app/[productId]/styles.ts +++ b/src/app/[productId]/styles.ts @@ -2,42 +2,37 @@ import styled from 'styled-components'; import { ToastContainer } from 'react-toastify'; 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 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 +41,7 @@ export const ButtonsWrapper = styled.div` align-items: center; width: 450px; height: 50px; - margin-top: 20px; + margin-top: 40px; `; export const QuantityButton = styled.div` @@ -94,4 +89,5 @@ export const ToastPopUP = styled(ToastContainer)` export const Fullscreen = styled.div` width: 100%; height: 100%; + display: grid; `; diff --git a/src/app/globals.css b/src/app/globals.css index 4d40d22d..c241f2ec 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/styles.ts b/src/app/login/styles.ts index 41968785..d94d373f 100644 --- a/src/app/login/styles.ts +++ b/src/app/login/styles.ts @@ -3,11 +3,14 @@ import styled from 'styled-components'; import COLORS from '../../styles/colors'; export const LoginBox = styled.div` + display: flex; width: 500px; height: 420px; - border: 1px solid ${COLORS.neutralGrey}; justify-self: center; align-self: center; + background-color: ${COLORS.white}; + box-shadow: 0px 4px 7px 0px rgba(0, 0, 0, 0.10); + border-radius: 10px; `; export const LoginContent = styled.div` @@ -15,7 +18,6 @@ export const LoginContent = styled.div` flex-direction: column; align-self: center; justify-self: center; - margin-top: 30px; text-color: ${COLORS.black}; `; @@ -78,8 +80,10 @@ export const Fullscreen = styled.div` width: 100%; height: 100vh; display: grid; + background-color: ${COLORS.lightGrey}; `; export const InputField = styled.div` position: relative; + background-color: ${COLORS.lightGrey}; `; 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..73520526 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,8 @@ 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; From 37910e22e12143b088fad58210797440a689cc53 Mon Sep 17 00:00:00 2001 From: Monique Cheng Date: Wed, 17 Apr 2024 21:07:56 -0700 Subject: [PATCH 08/18] product page finished; favorites hover button finished; login partially done --- src/api/supabase/queries/user_queries.ts | 1 + src/app/[productId]/page.tsx | 37 +++++++++-- src/app/[productId]/styles.ts | 49 ++++++++++++++- src/app/favorites/individualItem.tsx | 78 ++++++++++++++++++++++++ src/app/favorites/page.tsx | 47 +++----------- src/app/favorites/styles.ts | 25 +++++++- src/app/profileScreen/individualItem.tsx | 64 +++++++++++++++++++ src/app/profileScreen/page.tsx | 36 +++-------- src/app/profileScreen/styles.ts | 17 ++++++ 9 files changed, 278 insertions(+), 76 deletions(-) create mode 100644 src/app/favorites/individualItem.tsx create mode 100644 src/app/profileScreen/individualItem.tsx diff --git a/src/api/supabase/queries/user_queries.ts b/src/api/supabase/queries/user_queries.ts index 4b70bbcb..b186ec0e 100644 --- a/src/api/supabase/queries/user_queries.ts +++ b/src/api/supabase/queries/user_queries.ts @@ -112,6 +112,7 @@ export async function arrayOfFavorites(): Promise { return arrayOfProducts; } + /** * fetchUserAddress: Get's a user's address based on their UUID * @param uuid: String containing the uuid of the user diff --git a/src/app/[productId]/page.tsx b/src/app/[productId]/page.tsx index d892f214..74314a16 100644 --- a/src/app/[productId]/page.tsx +++ b/src/app/[productId]/page.tsx @@ -2,8 +2,8 @@ import { useEffect, useState } from 'react'; import { convertButtonNumberToCategory } from '@/api/supabase/queries/button_queries'; -import { Body1, Heading1, Body2Light, Body2Bold } 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,9 +13,13 @@ import { DescriptionContainer, ToastPopUP, Fullscreen, - LeftColumnDiv + 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'; @@ -26,6 +30,10 @@ export default function ItemDisplay({ params: { productId: number }; }) { const [Item, setItem] = useState(); + const [IsFavorite, setIsFavorite] = useState( + false + ); + const [FilteredProducts, setFilteredProducts] = useState([]); useEffect(() => { async function fetchProducts() { @@ -34,8 +42,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); @@ -45,6 +57,11 @@ export default function ItemDisplay({ fetchProducts(); }, [params.productId]); + async function handleFavorite() { + await addOrRemoveProductFromFavorite(await fetchProductByID(params.productId), !IsFavorite); + setIsFavorite(!IsFavorite); + } + return ( @@ -67,8 +84,18 @@ export default function ItemDisplay({ + {Item?.name} - + handleFavorite()}> + + + {IsFavorite ? 'Remove from favorites' : 'Add to favorites'} + + + + + + Category: {Item?.category} diff --git a/src/app/[productId]/styles.ts b/src/app/[productId]/styles.ts index 3a68f588..285c5f76 100644 --- a/src/app/[productId]/styles.ts +++ b/src/app/[productId]/styles.ts @@ -1,8 +1,9 @@ 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 LeftColumnDiv = styled.div` display: flex; flex-direction: column; @@ -19,6 +20,12 @@ export const DescriptionContainer = styled.div` justify-self: center; `; +export const TopRightContainer = styled.div` + display: flex; + justify-content: space-between; + width: 440px; +`; + export const ImageContainer = styled.div` width: 500px; height: 500px; @@ -66,6 +73,7 @@ export const PlusMinusButton = styled.button` font-size: 20px; color: ${COLORS.navy}; `; + export const AddToCartButton = styled.button` width: 265px; height: 50px; @@ -80,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; diff --git a/src/app/favorites/individualItem.tsx b/src/app/favorites/individualItem.tsx new file mode 100644 index 00000000..7b68d6ad --- /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(); + }, []); + + 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 + + + + + ); +} \ No newline at end of file diff --git a/src/app/favorites/page.tsx b/src/app/favorites/page.tsx index 8c16242d..96af5abc 100644 --- a/src/app/favorites/page.tsx +++ b/src/app/favorites/page.tsx @@ -1,34 +1,26 @@ '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 NavBar from '../../components/NavBarFolder/NavBar'; import { - FavoriteDiv, OutterFavoriteDiv, OutterBox, - ProductNameDiv, - HeartIcon, - TransparentButton, - ViewItem, Fullscreen, - ImageLinkWrapper, } 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 +30,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 +38,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/profileScreen/individualItem.tsx b/src/app/profileScreen/individualItem.tsx new file mode 100644 index 00000000..eb2d7627 --- /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 + + + + + ); +} \ No newline at end of file diff --git a/src/app/profileScreen/page.tsx b/src/app/profileScreen/page.tsx index 0b98511a..105a1fa9 100644 --- a/src/app/profileScreen/page.tsx +++ b/src/app/profileScreen/page.tsx @@ -42,9 +42,6 @@ import { TextSpacing, OrderHistory, FavoritesContainer, - ProductNameDiv, - FavoriteDiv, - HeartIcon, BackButtonDiv, BlankSpace, HeaderDiv, @@ -56,18 +53,14 @@ 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 +70,12 @@ function FavoriteSection(props: { {Favorites.slice(0, 2).map(favorite => ( - - {favorite.name} - -

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

-
- clickFunctions({ fav: favorite })} - > - - -
+ ))}
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` From c7fa3e0ecd314f4a673c7218ed297cf16663137d Mon Sep 17 00:00:00 2001 From: Monique Cheng Date: Wed, 17 Apr 2024 21:10:10 -0700 Subject: [PATCH 09/18] eslint and prettier --- src/api/supabase/queries/user_queries.ts | 1 - src/app/[productId]/page.tsx | 62 +++++++++++----------- src/app/favorites/individualItem.tsx | 22 ++++---- src/app/favorites/page.tsx | 20 +++---- src/app/globals.css | 2 +- src/app/login/styles.ts | 2 +- src/app/profileScreen/individualItem.tsx | 36 ++++++------- src/app/profileScreen/page.tsx | 12 ++--- src/components/InputFieldsFolder/styles.ts | 3 +- 9 files changed, 77 insertions(+), 83 deletions(-) diff --git a/src/api/supabase/queries/user_queries.ts b/src/api/supabase/queries/user_queries.ts index b186ec0e..4b70bbcb 100644 --- a/src/api/supabase/queries/user_queries.ts +++ b/src/api/supabase/queries/user_queries.ts @@ -112,7 +112,6 @@ export async function arrayOfFavorites(): Promise { return arrayOfProducts; } - /** * fetchUserAddress: Get's a user's address based on their UUID * @param uuid: String containing the uuid of the user diff --git a/src/app/[productId]/page.tsx b/src/app/[productId]/page.tsx index 74314a16..55cd995a 100644 --- a/src/app/[productId]/page.tsx +++ b/src/app/[productId]/page.tsx @@ -3,7 +3,10 @@ import { useEffect, useState } from 'react'; import { convertButtonNumberToCategory } from '@/api/supabase/queries/button_queries'; import { Body1, Heading1, Body2Light, Body2Bold, Body3 } from '@/styles/fonts'; -import { fetchProductByID, fetchUserProducts } from '../../api/supabase/queries/product_queries'; +import { + fetchProductByID, + fetchUserProducts, +} from '../../api/supabase/queries/product_queries'; import BackButton from '../../components/BackButton/BackButton'; import 'react-toastify/dist/ReactToastify.css'; @@ -17,7 +20,7 @@ import { FavoritePopup, HeartContainer, HeartIcon, - TopRightContainer + TopRightContainer, } from './styles'; import { addOrRemoveProductFromFavorite } from '../../api/supabase/queries/user_queries'; import NavBar from '../../components/NavBarFolder/NavBar'; @@ -30,9 +33,7 @@ export default function ItemDisplay({ params: { productId: number }; }) { const [Item, setItem] = useState(); - const [IsFavorite, setIsFavorite] = useState( - false - ); + const [IsFavorite, setIsFavorite] = useState(false); const [FilteredProducts, setFilteredProducts] = useState([]); useEffect(() => { @@ -44,7 +45,7 @@ export default function ItemDisplay({ ); const data = (await fetchUserProducts()) as Product[]; - setIsFavorite(!!data.find(item => item.id === params.productId)) + setIsFavorite(!!data.find(item => item.id === params.productId)); if (response) { setItem(response); setFilteredProducts(data); @@ -58,7 +59,10 @@ export default function ItemDisplay({ }, [params.productId]); async function handleFavorite() { - await addOrRemoveProductFromFavorite(await fetchProductByID(params.productId), !IsFavorite); + await addOrRemoveProductFromFavorite( + await fetchProductByID(params.productId), + !IsFavorite, + ); setIsFavorite(!IsFavorite); } @@ -74,34 +78,32 @@ export default function ItemDisplay({ - - - {Item?.name} - + + + {Item?.name} + - - {Item?.name} - handleFavorite()}> - - - {IsFavorite ? 'Remove from favorites' : 'Add to favorites'} - - - - - - + + {Item?.name} + handleFavorite()}> + + + {IsFavorite ? 'Remove from favorites' : 'Add to favorites'} + + + + + + Category: {Item?.category} - - Product Details: - + Product Details: {Item?.description} diff --git a/src/app/favorites/individualItem.tsx b/src/app/favorites/individualItem.tsx index 7b68d6ad..7b9eea0c 100644 --- a/src/app/favorites/individualItem.tsx +++ b/src/app/favorites/individualItem.tsx @@ -26,20 +26,20 @@ export default function IndividualItem(props: { 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); - } + try { + favorite.category = await convertButtonNumberToCategory( + favorite.category, + ); + } catch (error) { + // console.error(error); } + } - changeCategory(); - }, []); + changeCategory(); + }, [favorite]); async function clickFunctions(props2: { fav: Product }) { const { fav } = props2; @@ -75,4 +75,4 @@ export default function IndividualItem(props: { ); -} \ No newline at end of file +} diff --git a/src/app/favorites/page.tsx b/src/app/favorites/page.tsx index 96af5abc..6c00e83a 100644 --- a/src/app/favorites/page.tsx +++ b/src/app/favorites/page.tsx @@ -4,17 +4,11 @@ import { useState, useEffect } from 'react'; import { Heading1 } from '@/styles/fonts'; import BackButton from '../../components/BackButton/BackButton'; -import { - arrayOfFavorites, -} from '../../api/supabase/queries/user_queries'; +import { arrayOfFavorites } from '../../api/supabase/queries/user_queries'; import NavBar from '../../components/NavBarFolder/NavBar'; -import { - OutterFavoriteDiv, - OutterBox, - Fullscreen, -} from './styles'; +import { OutterFavoriteDiv, OutterBox, Fullscreen } from './styles'; import IndividualItem from './individualItem'; import { Product } from '../../schema/schema'; @@ -39,11 +33,11 @@ export default function FavoritesPage() { {Favorites.map(favorite => ( + key={favorite.id} + favorite={favorite} + setFavorites={setFavorites} + Favorites={Favorites} + /> ))} diff --git a/src/app/globals.css b/src/app/globals.css index c241f2ec..5b0dbd13 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -84,7 +84,7 @@ body { max-width: 100vw; min-height: 100vh; } -button{ +button { &:hover { cursor: pointer; } diff --git a/src/app/login/styles.ts b/src/app/login/styles.ts index d94d373f..03fb0708 100644 --- a/src/app/login/styles.ts +++ b/src/app/login/styles.ts @@ -9,7 +9,7 @@ export const LoginBox = styled.div` justify-self: center; align-self: center; background-color: ${COLORS.white}; - box-shadow: 0px 4px 7px 0px rgba(0, 0, 0, 0.10); + box-shadow: 0px 4px 7px 0px rgba(0, 0, 0, 0.1); border-radius: 10px; `; diff --git a/src/app/profileScreen/individualItem.tsx b/src/app/profileScreen/individualItem.tsx index eb2d7627..f7de722e 100644 --- a/src/app/profileScreen/individualItem.tsx +++ b/src/app/profileScreen/individualItem.tsx @@ -17,20 +17,20 @@ export default function IndividualItem(props: { }) { 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); - } + try { + favorite.category = await convertButtonNumberToCategory( + favorite.category, + ); + } catch (error) { + // console.error(error); } + } - changeCategory(); - }, []); + changeCategory(); + }, [favorite]); async function clickFunctions(props2: { fav: Product }) { const { fav } = props2; @@ -40,12 +40,12 @@ export default function IndividualItem(props: { return ( - {favorite.name} - + {favorite.name} + {favorite.name} Category: {favorite.category} @@ -59,6 +59,6 @@ export default function IndividualItem(props: { - + ); -} \ No newline at end of file +} diff --git a/src/app/profileScreen/page.tsx b/src/app/profileScreen/page.tsx index 105a1fa9..49c95de6 100644 --- a/src/app/profileScreen/page.tsx +++ b/src/app/profileScreen/page.tsx @@ -13,7 +13,6 @@ import { Body2, } from '@/styles/fonts'; import { - addOrRemoveProductFromFavorite, arrayOfFavorites, fetchUser, fetchCurrentUserAddress, @@ -55,7 +54,6 @@ import { signOut } from '../../api/supabase/auth/auth'; import 'react-toastify/dist/ReactToastify.css'; import IndividualItem from './individualItem'; - function FavoriteSection(props: { Favorites: Product[]; setFavorites: (category: Product[]) => void; @@ -71,11 +69,11 @@ function FavoriteSection(props: { {Favorites.slice(0, 2).map(favorite => ( + key={favorite.id} + favorite={favorite} + setFavorites={setFavorites} + Favorites={Favorites} + /> ))}
diff --git a/src/components/InputFieldsFolder/styles.ts b/src/components/InputFieldsFolder/styles.ts index 73520526..2fa8ed20 100644 --- a/src/components/InputFieldsFolder/styles.ts +++ b/src/components/InputFieldsFolder/styles.ts @@ -32,7 +32,8 @@ export const Input = styled.input<{ color: ${COLORS.black}; border: 1.5px solid ${props => (props.$wrongLogin ? COLORS.darkRed : COLORS.neutralGrey)}; - background: ${props => (props.$pickColor ? COLORS.lightRed : COLORS.lightGrey)}; + background: ${props => + props.$pickColor ? COLORS.lightRed : COLORS.lightGrey}; width: 420px; height: 40px; padding-left: 10px; From 9b32140dd9c7d5b58851357fa25cf54411d3462d Mon Sep 17 00:00:00 2001 From: Monique Cheng Date: Sun, 21 Apr 2024 11:20:09 -0700 Subject: [PATCH 10/18] order details page done --- src/app/pickup/page.tsx | 26 ++++++++++++++++++-------- src/app/pickup/styles.ts | 9 +++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/app/pickup/page.tsx b/src/app/pickup/page.tsx index 097b878e..4e336ece 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'; @@ -11,7 +14,7 @@ import { } from '@/api/supabase/queries/cart_queries'; import { useState, useEffect } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; -import { Heading4Bold } from '@/styles/fonts'; +import { Body1, Heading4Bold } from '@/styles/fonts'; import { fetchNRecentPickupTimes } from '@/api/supabase/queries/pickup_queries'; import { updateCartPickupId, @@ -36,8 +39,10 @@ import { PickupContent, PickupContainer, PickupTimeButton, + ToastPopUP, } from './styles'; + function DateInfoComponent(date: { date: unknown }) { const date1 = new Date(date.date as string); const daysOfWeek = [ @@ -100,6 +105,12 @@ export default function PickUp() { return (
+ router.push('/cart')}> @@ -116,10 +127,11 @@ 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 +167,12 @@ 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!`); } }} > diff --git a/src/app/pickup/styles.ts b/src/app/pickup/styles.ts index 35365312..257579c3 100644 --- a/src/app/pickup/styles.ts +++ b/src/app/pickup/styles.ts @@ -1,11 +1,13 @@ import styled from 'styled-components'; +import { ToastContainer } from 'react-toastify'; import COLORS from '../../styles/colors'; import NavBar from '../../components/NavBarFolder/NavBar'; import Footer from '../../components/FooterFolder/Footer'; + export const PickupContainer = styled.div` width: 730px; height: 400px; @@ -263,3 +265,10 @@ 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); + background-color: ${COLORS.lightRed}; +`; \ No newline at end of file From 816eb75bde6bbde7991911605601a25f606bd797 Mon Sep 17 00:00:00 2001 From: Monique Cheng Date: Sun, 21 Apr 2024 11:30:25 -0700 Subject: [PATCH 11/18] changes made --- src/app/pickup/page.tsx | 20 ++++++++++++++----- src/app/pickup/styles.ts | 3 +-- .../OrderSummaryFolder/OrderSummary.tsx | 6 +++--- src/components/OrderSummaryFolder/styles.ts | 8 +++++++- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/app/pickup/page.tsx b/src/app/pickup/page.tsx index 4e336ece..33e43490 100644 --- a/src/app/pickup/page.tsx +++ b/src/app/pickup/page.tsx @@ -42,7 +42,6 @@ import { ToastPopUP, } from './styles'; - function DateInfoComponent(date: { date: unknown }) { const date1 = new Date(date.date as string); const daysOfWeek = [ @@ -127,11 +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
+
+ {' '} + Pick Up times: 10:00 AM - 12:00 PM{' '} +
+
+ Location: 3170 23rd Street, San Francisco, CA 94110 +
{Time.map(time => ( 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` From 27560191d56fa2139f1f961e28ae3822b344aea6 Mon Sep 17 00:00:00 2001 From: Monique Cheng Date: Sun, 21 Apr 2024 12:32:56 -0700 Subject: [PATCH 12/18] order details page done --- src/api/supabase/queries/cart_queries.ts | 1 - src/api/supabase/queries/delivery_queries.ts | 15 ++++++ src/api/supabase/queries/order_queries.ts | 2 - src/api/supabase/queries/product_queries.ts | 2 - src/api/supabase/queries/user_queries.ts | 12 ++--- src/app/orderConfirmationDelivery/page.tsx | 50 ++++++++++++++++++-- src/app/orderConfirmationDelivery/styles.ts | 14 ++++-- src/app/orderConfirmationPickUp/page.tsx | 6 +-- src/app/pickup/page.tsx | 2 +- 9 files changed, 79 insertions(+), 25 deletions(-) create mode 100644 src/api/supabase/queries/delivery_queries.ts 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/orderConfirmationDelivery/page.tsx b/src/app/orderConfirmationDelivery/page.tsx index c82042cb..bacfca1d 100644 --- a/src/app/orderConfirmationDelivery/page.tsx +++ b/src/app/orderConfirmationDelivery/page.tsx @@ -6,8 +6,18 @@ import { fetchCurrentUserAddress, } from '@/api/supabase/queries/user_queries'; -import { Body1, Body2Light, Heading3Bold, Heading4Bold } from '@/styles/fonts'; +import { + Body1, + Body2, + Body2Light, + Heading3Bold, + Heading4Bold, +} from '@/styles/fonts'; import { useSearchParams } from 'next/navigation'; +import { + DeliveryTimes, + fetchDeliveryTimes, +} from '@/api/supabase/queries/delivery_queries'; import BackButton from '../../components/BackButton/BackButton'; import { fetchCartItemsWithQuantityByID } from '../../api/supabase/queries/cart_queries'; @@ -26,6 +36,7 @@ import { DetailsHeader, PageDiv, CenterDiv, + Quantity, } from './styles'; import { Product, User, Address } from '../../schema/schema'; @@ -38,12 +49,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,11 +64,39 @@ 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 (
@@ -105,6 +144,11 @@ export default function OrderConfirmationDelivery() {
+ + + Quantity: {cartItem.quantity} + + ))} @@ -114,7 +158,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/pickup/page.tsx b/src/app/pickup/page.tsx index 33e43490..6ea5a83a 100644 --- a/src/app/pickup/page.tsx +++ b/src/app/pickup/page.tsx @@ -13,7 +13,7 @@ import { totalNumberOfItemsInCart, } from '@/api/supabase/queries/cart_queries'; import { useState, useEffect } from 'react'; -import { useRouter, useSearchParams } from 'next/navigation'; +import { useRouter } from 'next/navigation'; import { Body1, Heading4Bold } from '@/styles/fonts'; import { fetchNRecentPickupTimes } from '@/api/supabase/queries/pickup_queries'; import { From cf03702349e1f60b725cd22d3dabdfbf7a9c4a0a Mon Sep 17 00:00:00 2001 From: Buyankhuu Tsolmonkhuu Date: Sun, 21 Apr 2024 14:02:17 -0700 Subject: [PATCH 13/18] preRebase --- src/api/supabase/queries/product_queries.ts | 2 +- src/app/orderConfirmationDelivery/page.tsx | 4 +++- src/app/pickup/page.tsx | 1 + src/app/pickup/styles.ts | 2 +- src/app/profileScreen/individualItem.tsx | 24 ++++++++++----------- src/app/profileScreen/page.tsx | 8 +++++++ 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/api/supabase/queries/product_queries.ts b/src/api/supabase/queries/product_queries.ts index 85ec9fbb..67396986 100644 --- a/src/api/supabase/queries/product_queries.ts +++ b/src/api/supabase/queries/product_queries.ts @@ -64,7 +64,7 @@ export async function fetchProductByID(productId: number): Promise { if (error) { throw new Error(`Error fetching product: ${error.message}`); } - + return product; } diff --git a/src/app/orderConfirmationDelivery/page.tsx b/src/app/orderConfirmationDelivery/page.tsx index bacfca1d..1652742e 100644 --- a/src/app/orderConfirmationDelivery/page.tsx +++ b/src/app/orderConfirmationDelivery/page.tsx @@ -93,7 +93,9 @@ export default function OrderConfirmationDelivery() { 'November', 'December', ]; - const dateStr = `${months[parseInt(date[1], 10)]} ${date[2]}, ${date[0]}`; + const dateStr = `${months[parseInt(date[1], 10) - 1]} ${date[2]}, ${ + date[0] + }`; return `${dateStr}`; } diff --git a/src/app/pickup/page.tsx b/src/app/pickup/page.tsx index 6ea5a83a..bd8d8ea3 100644 --- a/src/app/pickup/page.tsx +++ b/src/app/pickup/page.tsx @@ -183,6 +183,7 @@ export default function PickUp() { } 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 78adbb49..3c984c57 100644 --- a/src/app/pickup/styles.ts +++ b/src/app/pickup/styles.ts @@ -269,5 +269,5 @@ export const ToastPopUP = styled(ToastContainer)` position: fixed; z-index: 100; transform: translatey(90px); - background-color: ${COLORS.lightRed}; + `; diff --git a/src/app/profileScreen/individualItem.tsx b/src/app/profileScreen/individualItem.tsx index f7de722e..457c23d4 100644 --- a/src/app/profileScreen/individualItem.tsx +++ b/src/app/profileScreen/individualItem.tsx @@ -18,19 +18,19 @@ export default function IndividualItem(props: { 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); - } - } + // useEffect(() => { + // // async function changeCategory() { + // // try { + // // favorite.category = await convertButtonNumberToCategory( + // // favorite.category, + // // ); + // // } catch (error) { + // // // console.error(error); + // // } + // // } - changeCategory(); - }, [favorite]); + // // changeCategory(); + // }, []); async function clickFunctions(props2: { fav: Product }) { const { fav } = props2; diff --git a/src/app/profileScreen/page.tsx b/src/app/profileScreen/page.tsx index 49c95de6..42f5a064 100644 --- a/src/app/profileScreen/page.tsx +++ b/src/app/profileScreen/page.tsx @@ -12,6 +12,7 @@ import { Body2Bold, Body2, } from '@/styles/fonts'; +import { convertButtonNumberToCategory } from '@/api/supabase/queries/button_queries'; import { arrayOfFavorites, fetchUser, @@ -363,6 +364,13 @@ export default function Profile() { async function fetchProducts() { const data = (await arrayOfFavorites()) as Product[]; + data.forEach( + async product => + (product.category = await convertButtonNumberToCategory( + product.category, + )), + ); + console.log(data); setFavorites(data); } From 21ff7aa07ed9449aa10d6685119ee27b5b69e166 Mon Sep 17 00:00:00 2001 From: Monique Cheng Date: Sun, 21 Apr 2024 14:10:21 -0700 Subject: [PATCH 14/18] a --- src/app/login/page.tsx | 13 ++++++++++++- src/app/pickup/styles.ts | 1 - src/components/LoginFormFolder/LoginForm.tsx | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx index 93fcea70..aeff396f 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'; @@ -39,6 +40,16 @@ export default function App() { window.location.href = '/storefront'; } }; + + async function applyFilter( + e: React.KeyboardEvent, + ) { + const keypressed = e.code; + if (keypressed === 'Enter') { + handleLogin(); + } + } + return ( @@ -78,7 +89,7 @@ export default function App() { )} {errorMessage && {errorMessage}} - diff --git a/src/app/pickup/styles.ts b/src/app/pickup/styles.ts index 78adbb49..af517b07 100644 --- a/src/app/pickup/styles.ts +++ b/src/app/pickup/styles.ts @@ -269,5 +269,4 @@ export const ToastPopUP = styled(ToastContainer)` position: fixed; z-index: 100; transform: translatey(90px); - background-color: ${COLORS.lightRed}; `; diff --git a/src/components/LoginFormFolder/LoginForm.tsx b/src/components/LoginFormFolder/LoginForm.tsx index 6604f84f..684399e6 100644 --- a/src/components/LoginFormFolder/LoginForm.tsx +++ b/src/components/LoginFormFolder/LoginForm.tsx @@ -8,7 +8,7 @@ export default function LoginForm(props: { isError: boolean; showPassword: boolean; }) { - const { isError, changeUserName, changePassword, showPassword } = props; + const { isError, changeUserName, changePassword, showPassword} = props; return (
Date: Sun, 21 Apr 2024 14:26:39 -0700 Subject: [PATCH 15/18] profile page --- .eslintrc.js | 14 + .github/pull_request_template.md | 28 + .github/workflows/lint.yml | 56 + .gitignore | 36 + .nvmrc | 1 + .prettierignore | 11 + .prettierrc.js | 5 + .vscode/extensions.json | 13 + .vscode/settings.json | 8 + README.md | 54 + holder.zip | Bin 0 -> 48762 bytes next.config.js | 11 + package-lock.json | 6771 +++++++++++++++++ package.json | 49 + public/check.svg | 4 + public/images/Arrow_Left_MD.png | Bin 0 -> 267 bytes public/images/Cart.png | Bin 0 -> 1142 bytes public/images/PAWS.png | Bin 0 -> 84860 bytes public/images/Profile.png | Bin 0 -> 1154 bytes public/images/ShantiLogo.png | Bin 0 -> 4473 bytes public/images/profile (1).svg | 1 + public/images/profile blue version-2.svg | 1 + public/next.svg | 1 + public/ready.svg | 11 + public/right_arrow.svg | 4 + public/vercel.svg | 1 + public/x.svg | 6 + src/api/supabase/auth/auth.tsx | 28 + src/api/supabase/createClient.tsx | 20 + src/api/supabase/queries/button_queries.ts | 32 + src/api/supabase/queries/cart_queries.ts | 263 + src/api/supabase/queries/delivery_queries.ts | 15 + src/api/supabase/queries/order_queries.ts | 272 + src/api/supabase/queries/pickup_queries.ts | 69 + src/api/supabase/queries/product_queries.ts | 144 + src/api/supabase/queries/tests/order_test.ts | 7 + src/api/supabase/queries/tests/pickup_test.ts | 7 + .../supabase/queries/tests/product_test.ts | 25 + src/api/supabase/queries/tests/user_test.ts | 7 + src/api/supabase/queries/user_queries.ts | 157 + src/app/[productId]/Buttons.tsx | 53 + src/app/[productId]/page.tsx | 114 + src/app/[productId]/styles.ts | 140 + src/app/cart/Buttons.tsx | 74 + src/app/cart/cartItem.tsx | 69 + src/app/cart/page.tsx | 91 + src/app/cart/styles.tsx | 383 + src/app/delivery/itemRows.tsx | 62 + src/app/delivery/page.tsx | 100 + src/app/delivery/styles.ts | 157 + src/app/favicon.ico | Bin 0 -> 25931 bytes src/app/favorites/individualItem.tsx | 78 + src/app/favorites/page.tsx | 46 + src/app/favorites/styles.ts | 132 + src/app/globals.css | 106 + src/app/layout.tsx | 23 + src/app/login/page.tsx | 99 + src/app/login/styles.ts | 89 + src/app/orderConfirmationDelivery/page.tsx | 176 + src/app/orderConfirmationDelivery/styles.ts | 247 + src/app/orderConfirmationPickUp/page.tsx | 158 + src/app/orderConfirmationPickUp/styles.ts | 325 + src/app/orderHistory/page.tsx | 51 + src/app/orderHistory/styles.ts | 54 + src/app/orderPage/page.tsx | 115 + src/app/orderPage/styles.ts | 141 + src/app/page.module.css | 229 + src/app/page.tsx | 88 + src/app/pickup/page.tsx | 196 + src/app/pickup/styles.ts | 272 + src/app/profileScreen/individualItem.tsx | 64 + src/app/profileScreen/page.tsx | 430 ++ src/app/profileScreen/styles.ts | 185 + src/app/profileScreen/stylesOld.ts | 128 + src/app/storefront/IndividualItem.tsx | 53 + src/app/storefront/StoreFrontNavBar.tsx | 161 + src/app/storefront/buttonValues.tsx | 24 + src/app/storefront/page.tsx | 51 + src/app/storefront/productButtons.tsx | 96 + src/app/storefront/storefrontItems.tsx | 34 + src/app/storefront/styles.ts | 254 + src/app/types/types.txt | 0 src/app/util/util.txt | 0 src/components/BackButton/BackButton.tsx | 12 + src/components/BackButton/styles.ts | 22 + src/components/FooterFolder/Footer.tsx | 127 + src/components/FooterFolder/Location.tsx | 17 + src/components/FooterFolder/styles.ts | 159 + .../InputFieldsFolder/InputFields.tsx | 56 + src/components/InputFieldsFolder/styles.ts | 56 + src/components/LoginFormFolder/LoginForm.tsx | 34 + src/components/NavBarFolder/NavBar.tsx | 62 + src/components/NavBarFolder/styles.ts | 74 + src/components/OrderHistory/ImageCarousel.tsx | 21 + .../OrderHistory/OrderHistoryBox.tsx | 61 + .../OrderHistory/OrderHistoryText.tsx | 166 + src/components/OrderHistory/styles.ts | 218 + .../OrderSummaryFolder/OrderSummary.tsx | 48 + src/components/OrderSummaryFolder/styles.ts | 77 + src/components/PickUpFolder/PickupButton.tsx | 22 + src/components/PickUpFolder/PickupForm.tsx | 16 + src/components/PickUpFolder/PickupInputs.tsx | 35 + .../ViewAllButton/ViewAllButton.tsx | 16 + src/components/ViewAllButton/styles.ts | 15 + src/components/components.txt | 0 src/schema/schema.ts | 90 + src/styles/colors.ts | 19 + src/styles/components.tsx | 139 + src/styles/fonts.tsx | 160 + tsconfig.json | 41 + 110 files changed, 15243 insertions(+) create mode 100644 .eslintrc.js create mode 100644 .github/pull_request_template.md create mode 100644 .github/workflows/lint.yml create mode 100644 .gitignore create mode 100644 .nvmrc create mode 100644 .prettierignore create mode 100644 .prettierrc.js create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 README.md create mode 100644 holder.zip create mode 100644 next.config.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/check.svg create mode 100644 public/images/Arrow_Left_MD.png create mode 100644 public/images/Cart.png create mode 100644 public/images/PAWS.png create mode 100644 public/images/Profile.png create mode 100644 public/images/ShantiLogo.png create mode 100644 public/images/profile (1).svg create mode 100644 public/images/profile blue version-2.svg create mode 100644 public/next.svg create mode 100644 public/ready.svg create mode 100644 public/right_arrow.svg create mode 100644 public/vercel.svg create mode 100644 public/x.svg create mode 100644 src/api/supabase/auth/auth.tsx create mode 100644 src/api/supabase/createClient.tsx create mode 100644 src/api/supabase/queries/button_queries.ts create mode 100644 src/api/supabase/queries/cart_queries.ts create mode 100644 src/api/supabase/queries/delivery_queries.ts create mode 100644 src/api/supabase/queries/order_queries.ts create mode 100644 src/api/supabase/queries/pickup_queries.ts create mode 100644 src/api/supabase/queries/product_queries.ts create mode 100644 src/api/supabase/queries/tests/order_test.ts create mode 100644 src/api/supabase/queries/tests/pickup_test.ts create mode 100644 src/api/supabase/queries/tests/product_test.ts create mode 100644 src/api/supabase/queries/tests/user_test.ts create mode 100644 src/api/supabase/queries/user_queries.ts create mode 100644 src/app/[productId]/Buttons.tsx create mode 100644 src/app/[productId]/page.tsx create mode 100644 src/app/[productId]/styles.ts create mode 100644 src/app/cart/Buttons.tsx create mode 100644 src/app/cart/cartItem.tsx create mode 100644 src/app/cart/page.tsx create mode 100644 src/app/cart/styles.tsx create mode 100644 src/app/delivery/itemRows.tsx create mode 100644 src/app/delivery/page.tsx create mode 100644 src/app/delivery/styles.ts create mode 100644 src/app/favicon.ico create mode 100644 src/app/favorites/individualItem.tsx create mode 100644 src/app/favorites/page.tsx create mode 100644 src/app/favorites/styles.ts create mode 100644 src/app/globals.css create mode 100644 src/app/layout.tsx create mode 100644 src/app/login/page.tsx create mode 100644 src/app/login/styles.ts create mode 100644 src/app/orderConfirmationDelivery/page.tsx create mode 100644 src/app/orderConfirmationDelivery/styles.ts create mode 100644 src/app/orderConfirmationPickUp/page.tsx create mode 100644 src/app/orderConfirmationPickUp/styles.ts create mode 100644 src/app/orderHistory/page.tsx create mode 100644 src/app/orderHistory/styles.ts create mode 100644 src/app/orderPage/page.tsx create mode 100644 src/app/orderPage/styles.ts create mode 100644 src/app/page.module.css create mode 100644 src/app/page.tsx create mode 100644 src/app/pickup/page.tsx create mode 100644 src/app/pickup/styles.ts create mode 100644 src/app/profileScreen/individualItem.tsx create mode 100644 src/app/profileScreen/page.tsx create mode 100644 src/app/profileScreen/styles.ts create mode 100644 src/app/profileScreen/stylesOld.ts create mode 100644 src/app/storefront/IndividualItem.tsx create mode 100644 src/app/storefront/StoreFrontNavBar.tsx create mode 100644 src/app/storefront/buttonValues.tsx create mode 100644 src/app/storefront/page.tsx create mode 100644 src/app/storefront/productButtons.tsx create mode 100644 src/app/storefront/storefrontItems.tsx create mode 100644 src/app/storefront/styles.ts create mode 100644 src/app/types/types.txt create mode 100644 src/app/util/util.txt create mode 100644 src/components/BackButton/BackButton.tsx create mode 100644 src/components/BackButton/styles.ts create mode 100644 src/components/FooterFolder/Footer.tsx create mode 100644 src/components/FooterFolder/Location.tsx create mode 100644 src/components/FooterFolder/styles.ts create mode 100644 src/components/InputFieldsFolder/InputFields.tsx create mode 100644 src/components/InputFieldsFolder/styles.ts create mode 100644 src/components/LoginFormFolder/LoginForm.tsx create mode 100644 src/components/NavBarFolder/NavBar.tsx create mode 100644 src/components/NavBarFolder/styles.ts create mode 100644 src/components/OrderHistory/ImageCarousel.tsx create mode 100644 src/components/OrderHistory/OrderHistoryBox.tsx create mode 100644 src/components/OrderHistory/OrderHistoryText.tsx create mode 100644 src/components/OrderHistory/styles.ts create mode 100644 src/components/OrderSummaryFolder/OrderSummary.tsx create mode 100644 src/components/OrderSummaryFolder/styles.ts create mode 100644 src/components/PickUpFolder/PickupButton.tsx create mode 100644 src/components/PickUpFolder/PickupForm.tsx create mode 100644 src/components/PickUpFolder/PickupInputs.tsx create mode 100644 src/components/ViewAllButton/ViewAllButton.tsx create mode 100644 src/components/ViewAllButton/styles.ts create mode 100644 src/components/components.txt create mode 100644 src/schema/schema.ts create mode 100644 src/styles/colors.ts create mode 100644 src/styles/components.tsx create mode 100644 src/styles/fonts.tsx create mode 100644 tsconfig.json diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..0d9341d7 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,14 @@ +module.exports = { + extends: ["@calblueprint/eslint-config-react"], + rules: { + // Add any custom rules here + // Disable the rule that requires React to be in scope -- we don't need this with React 18 + 'react/react-in-jsx-scope': 'off', + 'react/jsx-uses-react': 'off', + }, + settings: { + 'import/resolver': { + typescript: {} + } + } +}; \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..1de99dc5 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,28 @@ +[//]: # "These comments are meant for your reference. They are invisible and don't need to be deleted!" + +## What's new in this PR +### Description +[//]: # "Required - Describe what's new in this PR in a few lines. A description and bullet points for specifics will suffice." + +### Screenshots +[//]: # "Required for frontend changes, otherwise optional but strongly recommended. Add screenshots of expected behavior - GIFs if you're feeling fancy!" + +## How to review +[//]: # "Required - Describe the order in which to review files and what to expect when testing locally. Is there anything specifically you want feedback on? Should this be reviewed commit by commit, or all at once? What are some user flows to test? What are some edge cases to look out for?" + +## Next steps +[//]: # "Optional - What's NOT in this PR, doesn't work yet, and/or still needs to be done. Note any temporary fixes in this PR that should be cleaned up later." + +## Relevant Links + +### Online sources +[//]: # "Optional - copy links to any tutorials or documentation that was useful to you when working on this PR" + +### Related PRs +[//]: # "Optional - related PRs you're waiting on/ PRs that will conflict, etc; if this is a refactor, feel free to add PRs that previously modified this code" + + + + +[//]: # "This tags the project leader as a default. Feel free to change, or add on anyone who you should be in on the conversation." +🛍 CC: @EthanAuyeung \ No newline at end of file diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..186e163e --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,56 @@ +--- +name: Lint + +############################# +# Start the job on push # +############################# +on: + push: + branches-ignore: [main] + pull_request: + branches: [main] + +############### +# Set the Job # +############### +jobs: + build: + # Name the Job + name: Run ESLint, Prettier, and TypeScript compiler + # Set the agent to run on + runs-on: ubuntu-latest + + ################## + # Load all steps # + ################## + steps: + ########################## + # Checkout the code base # + ########################## + - name: Checkout Code + uses: actions/checkout@v3 + with: + # Full git history is needed to get a proper + # list of changed files within `super-linter` + fetch-depth: 0 + + ################################ + # Install packages # + ################################ + - name: Install packages + run: npm ci + ################################ + # Lint codebase # + ################################ + - name: Run ESLint + run: npx eslint . + ################################ + # Check Prettier on codebase # + ################################ + - name: Run Prettier + run: npx prettier --check . + ################################ + # Check for TypeScript errors # + ################################ + - name: Run TypeScript compiler (tsc) + run: npx tsc --noEmit \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..45c1abce --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local +.env + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..25bf17fc --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +18 \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..a3757027 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,11 @@ +.github/ +.vscode/ +README.md +package-lock.json +.eslintrc.js +.next/ +.prettierrc.js +next-env.d.ts +next.config.js +package.json +tsconfig.json \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 00000000..324e2c0d --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,5 @@ +const blueprintPrettier = require("@calblueprint/prettier-config"); + +module.exports = { + ...blueprintPrettier, +}; \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..0c7c4d38 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,13 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. + // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp + + // List of extensions which should be recommended for users of this workspace. + "recommendations": [ + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "eamodio.gitlens" + ], + // List of extensions recommended by VS Code that should not be recommended for users of this workspace. + "unwantedRecommendations": [] + } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..2e70ce1e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "typescript.tsdk": "node_modules\\typescript\\lib", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "editor.formatOnSave": true, + "files.autoSave": "onFocusChange" + } \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..f1acdea1 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# Shanti Project + +This project is designed and developed by a team of UC Berkeley students through one of [Cal Blueprint](https://calblueprint.org/)'s project teams during the 2022-23 academic year. + +Learn more about [Shanti Project](https://www.shanti.org/) and [Cal Blueprint](https://calblueprint.org/). + +--- +## Getting Started + +Check your installation of npm and node: + +```sh +node -v +npm -v +``` +We strongly recommend using a Node version manager like [nvm](https://github.com/nvm-sh/nvm) (for Mac) or [nvm-windows](https://github.com/coreybutler/nvm-windows) (for Windows) to install Node.js and npm. See [Downloading and installing Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm). +### Installation + +1. Clone the repo & install dependencies + 1. Clone this repo + * using SSH (recommended) + ```sh + git clone git@github.com:calblueprint/shanti-project.git + ``` + * using HTTPS + ```sh + git clone https://github.com/calblueprint/shanti-project.git + ``` + 2. Enter the cloned directory + ```sh + cd shanti-project + ``` + 3. Install project dependencies. This command installs all packages from [`package.json`](package.json). + ```sh + npm install + ``` +2. Set up secrets: + TBD + +**Helpful resources** + +* [GitHub: Cloning a Repository](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository#cloning-a-repository) +* [GitHub: Generating SSH keys](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent) +### Development Environment + +- **[VSCode](https://code.visualstudio.com/) (recommended)** + 1. Open the `shanti-project` project in VSCode. + 2. Install recommended workspace VSCode extensions. You should see a pop-up on the bottom right to "install the recommended extensions for this repository". +### Running the app +1. In the project directory, run: + ```shell + npm run dev + ``` +2. Open up [http://localhost:3000](http://localhost:3000) in your browser to see the results. diff --git a/holder.zip b/holder.zip new file mode 100644 index 0000000000000000000000000000000000000000..f73e7a51dab44fcbcef02776374442c3af33e72d GIT binary patch literal 48762 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.10.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/cli": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "commander": "^4.0.1", + "convert-source-map": "^2.0.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.2.0", + "make-dir": "^2.1.0", + "slash": "^2.0.0" + }, + "bin": { + "babel": "bin/babel.js", + "babel-external-helpers": "bin/babel-external-helpers.js" + }, + "engines": { + "node": ">=6.9.0" + }, + "optionalDependencies": { + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", + "chokidar": "^3.4.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/cli/node_modules/glob": { + "version": "7.2.3", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@babel/cli/node_modules/slash": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.13", + "license": "MIT", + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.22.20", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helpers": "^7.23.0", + "@babel/parser": "^7.23.0", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.0", + "@babel/types": "^7.23.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-validator-option": "^7.22.15", + "browserslist": "^4.21.9", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "license": "ISC" + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "regexpu-core": "^5.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.4.2", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.22.5", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.22.20", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-wrap-function": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.22.20", + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-member-expression-to-functions": "^7.22.15", + "@babel/helper-optimise-call-expression": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.22.15", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.22.20", + "license": "MIT", + "dependencies": { + "@babel/helper-function-name": "^7.22.5", + "@babel/template": "^7.22.15", + "@babel/types": "^7.22.19" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.1", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.0", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.20", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.0", + "license": "MIT", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-transform-optional-chaining": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-external-helpers": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-class-properties": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-object-rest-spread": { + "version": "7.20.7", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-plugin-utils": "^7.20.2", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-export-namespace-from": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.9", + "@babel/plugin-syntax-async-generators": "^7.8.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-remap-async-to-generator": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.22.11", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.11", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-class-static-block": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-environment-visitor": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-optimise-call-expression": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.9", + "@babel/helper-split-export-declaration": "^7.22.6", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/template": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.22.11", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.22.11", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.22.5", + "@babel/helper-function-name": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.22.11", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-json-strings": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.22.11", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-simple-access": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-module-transforms": "^7.23.0", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.22.11", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.22.11", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.9", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-replace-supers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.22.11", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.22.11", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.11", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.22.10", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.22.5", + "@babel/helper-create-class-features-plugin": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/plugin-syntax-typescript": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.22.10", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.22.5", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.22.5", + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.22.20", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.20", + "@babel/helper-compilation-targets": "^7.22.15", + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.22.15", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.22.15", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-dynamic-import": "^7.8.3", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-import-assertions": "^7.22.5", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.22.5", + "@babel/plugin-transform-async-generator-functions": "^7.22.15", + "@babel/plugin-transform-async-to-generator": "^7.22.5", + "@babel/plugin-transform-block-scoped-functions": "^7.22.5", + "@babel/plugin-transform-block-scoping": "^7.22.15", + "@babel/plugin-transform-class-properties": "^7.22.5", + "@babel/plugin-transform-class-static-block": "^7.22.11", + "@babel/plugin-transform-classes": "^7.22.15", + "@babel/plugin-transform-computed-properties": "^7.22.5", + "@babel/plugin-transform-destructuring": "^7.22.15", + "@babel/plugin-transform-dotall-regex": "^7.22.5", + "@babel/plugin-transform-duplicate-keys": "^7.22.5", + "@babel/plugin-transform-dynamic-import": "^7.22.11", + "@babel/plugin-transform-exponentiation-operator": "^7.22.5", + "@babel/plugin-transform-export-namespace-from": "^7.22.11", + "@babel/plugin-transform-for-of": "^7.22.15", + "@babel/plugin-transform-function-name": "^7.22.5", + "@babel/plugin-transform-json-strings": "^7.22.11", + "@babel/plugin-transform-literals": "^7.22.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.22.11", + "@babel/plugin-transform-member-expression-literals": "^7.22.5", + "@babel/plugin-transform-modules-amd": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.22.15", + "@babel/plugin-transform-modules-systemjs": "^7.22.11", + "@babel/plugin-transform-modules-umd": "^7.22.5", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.22.5", + "@babel/plugin-transform-new-target": "^7.22.5", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.22.11", + "@babel/plugin-transform-numeric-separator": "^7.22.11", + "@babel/plugin-transform-object-rest-spread": "^7.22.15", + "@babel/plugin-transform-object-super": "^7.22.5", + "@babel/plugin-transform-optional-catch-binding": "^7.22.11", + "@babel/plugin-transform-optional-chaining": "^7.22.15", + "@babel/plugin-transform-parameters": "^7.22.15", + "@babel/plugin-transform-private-methods": "^7.22.5", + "@babel/plugin-transform-private-property-in-object": "^7.22.11", + "@babel/plugin-transform-property-literals": "^7.22.5", + "@babel/plugin-transform-regenerator": "^7.22.10", + "@babel/plugin-transform-reserved-words": "^7.22.5", + "@babel/plugin-transform-shorthand-properties": "^7.22.5", + "@babel/plugin-transform-spread": "^7.22.5", + "@babel/plugin-transform-sticky-regex": "^7.22.5", + "@babel/plugin-transform-template-literals": "^7.22.5", + "@babel/plugin-transform-typeof-symbol": "^7.22.5", + "@babel/plugin-transform-unicode-escapes": "^7.22.10", + "@babel/plugin-transform-unicode-property-regex": "^7.22.5", + "@babel/plugin-transform-unicode-regex": "^7.22.5", + "@babel/plugin-transform-unicode-sets-regex": "^7.22.5", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "@babel/types": "^7.22.19", + "babel-plugin-polyfill-corejs2": "^0.4.5", + "babel-plugin-polyfill-corejs3": "^0.8.3", + "babel-plugin-polyfill-regenerator": "^0.5.2", + "core-js-compat": "^3.31.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-transform-react-display-name": "^7.22.5", + "@babel/plugin-transform-react-jsx": "^7.22.15", + "@babel/plugin-transform-react-jsx-development": "^7.22.5", + "@babel/plugin-transform-react-pure-annotations": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5", + "@babel/helper-validator-option": "^7.22.15", + "@babel/plugin-syntax-jsx": "^7.22.5", + "@babel/plugin-transform-modules-commonjs": "^7.23.0", + "@babel/plugin-transform-typescript": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/regjsgen": { + "version": "0.8.0", + "license": "MIT" + }, + "node_modules/@babel/runtime": { + "version": "7.23.1", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.2", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.23.0", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@calblueprint/eslint-config-react": { + "version": "0.0.3", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^5.52.0", + "@typescript-eslint/parser": "^5.52.0", + "eslint": "^8.28.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", + "prettier": "^2.7.1", + "typescript": "^4.3.0" + } + }, + "node_modules/@calblueprint/prettier-config": { + "version": "0.0.1", + "dev": true, + "license": "MIT", + "peerDependencies": { + "prettier": "^2.8.4" + } + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "license": "MIT" + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.9.1", + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.2", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.51.0", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.4.2", + "hasInstallScript": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-free": { + "version": "6.4.2", + "hasInstallScript": true, + "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.4.2", + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.4.2", + "hasInstallScript": true, + "license": "(CC-BY-4.0 AND MIT)", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.0", + "license": "MIT", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.11", + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.1", + "license": "BSD-3-Clause" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.19", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@next/env": { + "version": "13.5.4", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "13.5.2", + "license": "MIT", + "dependencies": { + "glob": "7.1.7" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "13.5.4", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.3", + "license": "MIT", + "optional": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@remix-run/router": { + "version": "1.10.0", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.5.1", + "license": "MIT" + }, + "node_modules/@supabase/functions-js": { + "version": "2.1.5", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/gotrue-js": { + "version": "2.55.0", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/node-fetch": { + "version": "2.6.14", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/@supabase/postgrest-js": { + "version": "1.8.4", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/realtime-js": { + "version": "2.8.0", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14", + "@types/phoenix": "^1.5.4", + "@types/websocket": "^1.0.3", + "websocket": "^1.0.34" + } + }, + "node_modules/@supabase/storage-js": { + "version": "2.5.4", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/supabase-js": { + "version": "2.38.0", + "license": "MIT", + "dependencies": { + "@supabase/functions-js": "^2.1.5", + "@supabase/gotrue-js": "^2.54.2", + "@supabase/node-fetch": "^2.6.14", + "@supabase/postgrest-js": "^1.8.4", + "@supabase/realtime-js": "^2.8.0", + "@supabase/storage-js": "^2.5.4" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.2", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/eslint": { + "version": "8.44.3", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.5", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.13", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.6.3", + "license": "MIT" + }, + "node_modules/@types/phoenix": { + "version": "1.6.2", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.8", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.2.22", + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.7", + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.4", + "license": "MIT" + }, + "node_modules/@types/semver": { + "version": "7.5.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/stylis": { + "version": "4.2.1", + "license": "MIT" + }, + "node_modules/@types/websocket": { + "version": "1.0.7", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "dev": true, + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "dev": true, + "license": "Apache-2.0", + "peer": true + }, + "node_modules/acorn": { + "version": "8.10.0", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "dev": true, + "license": "MIT", + "peer": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "license": "ISC", + "optional": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.0", + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.7", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.2", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.7", + "license": "ISC" + }, + "node_modules/asynciterator.prototype": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.8.2", + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "3.2.1", + "license": "Apache-2.0", + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.5", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.22.6", + "@babel/helper-define-polyfill-provider": "^0.4.2", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.8.4", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.2", + "core-js-compat": "^3.32.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.5.2", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.4.2" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/big.js": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.1", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001541", + "electron-to-chromium": "^1.4.535", + "node-releases": "^2.0.13", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/bufferutil": { + "version": "4.0.7", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/busboy": { + "version": "1.6.0", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001546", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "license": "ISC", + "optional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/clsx": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/commander": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.33.0", + "license": "MIT", + "dependencies": { + "browserslist": "^4.22.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/csstype": { + "version": "3.1.2", + "license": "MIT" + }, + "node_modules/d": { + "version": "1.0.1", + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "license": "BSD-2-Clause" + }, + "node_modules/debug": { + "version": "4.3.4", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dotenv": { + "version": "16.3.1", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.544", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-abstract": { + "version": "1.22.2", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.1", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.0.15", + "license": "MIT", + "dependencies": { + "asynciterator.prototype": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.1", + "es-set-tostringtag": "^2.0.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "iterator.prototype": "^1.1.2", + "safe-array-concat": "^1.0.1" + } + }, + "node_modules/es-module-lexer": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.51.0", + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.51.0", + "@humanwhocodes/config-array": "^0.11.11", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-airbnb": { + "version": "19.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-config-airbnb-base": "^15.0.0", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5" + }, + "engines": { + "node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.28.0", + "eslint-plugin-react-hooks": "^4.3.0" + } + }, + "node_modules/eslint-config-airbnb-base": { + "version": "15.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.2" + } + }, + "node_modules/eslint-config-airbnb-base/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-config-next": { + "version": "13.5.2", + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "13.5.2", + "@rushstack/eslint-patch": "^1.3.3", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "8.10.0", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "license": "ISC", + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.28.1", + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.findlastindex": "^1.2.2", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.8.0", + "has": "^1.0.3", + "is-core-module": "^2.13.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.6", + "object.groupby": "^1.0.0", + "object.values": "^1.1.6", + "semver": "^6.3.1", + "tsconfig-paths": "^3.14.2" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.7.1", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.20.7", + "aria-query": "^5.1.3", + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.6.2", + "axobject-query": "^3.1.1", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "has": "^1.0.3", + "jsx-ast-utils": "^3.3.3", + "language-tags": "=1.0.5", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.33.2", + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.0.12", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.4", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.8" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.4", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.2", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esniff/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" + }, + "node_modules/espree": { + "version": "9.6.1", + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "license": "ISC", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "license": "ISC" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.15.0", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.9", + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.3", + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "license": "BSD-2-Clause" + }, + "node_modules/globals": { + "version": "13.23.0", + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "license": "MIT" + }, + "node_modules/has": { + "version": "1.0.4", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ignore": { + "version": "5.2.4", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "license": "MIT", + "optional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.0", + "license": "MIT", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/is-weakmap": { + "version": "2.0.1", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.2", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "reflect.getprototypeof": "^1.0.4", + "set-function-name": "^2.0.1" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.22", + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.5", + "license": "MIT", + "dependencies": { + "language-subtag-registry": "~0.3.2" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.6", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "license": "MIT" + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/next": { + "version": "13.5.4", + "license": "MIT", + "dependencies": { + "@next/env": "13.5.4", + "@swc/helpers": "0.5.2", + "busboy": "1.6.0", + "caniuse-lite": "^1.0.30001406", + "postcss": "8.4.31", + "styled-jsx": "5.1.1", + "watchpack": "2.4.0" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=16.14.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "13.5.4", + "@next/swc-darwin-x64": "13.5.4", + "@next/swc-linux-arm64-gnu": "13.5.4", + "@next/swc-linux-arm64-musl": "13.5.4", + "@next/swc-linux-x64-gnu": "13.5.4", + "@next/swc-linux-x64-musl": "13.5.4", + "@next/swc-win32-arm64-msvc": "13.5.4", + "@next/swc-win32-ia32-msvc": "13.5.4", + "@next/swc-win32-x64-msvc": "13.5.4" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next-google-fonts": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/next-google-fonts/-/next-google-fonts-2.2.0.tgz", + "integrity": "sha512-TCtNp+uu0vof2X8Xfptfw96Unc3zsUekBY2l4g2mGAX+U8QO/yfAaEioGhFCwU05M8NbMgwP5C8V40Vtwp87iQ==", + "deprecated": "As of Next.js 10.2, Google Fonts are automatically optimized! For more info, see https://github.com/joe-bell/next-google-fonts", + "peerDependencies": { + "next": ">= 10.0.7", + "react": ">= 17.0.1", + "react-dom": ">= 17.0.1" + } + }, + "node_modules/next-tick": { + "version": "1.1.0", + "license": "ISC" + }, + "node_modules/next/node_modules/@next/swc-darwin-x64": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.4.tgz", + "integrity": "sha512-siPuUwO45PnNRMeZnSa8n/Lye5ZX93IJom9wQRB5DEOdFrw0JjOMu1GINB8jAEdwa7Vdyn1oJ2xGNaQpdQQ9Pw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/next/node_modules/@next/swc-linux-arm64-gnu": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.4.tgz", + "integrity": "sha512-l/k/fvRP/zmB2jkFMfefmFkyZbDkYW0mRM/LB+tH5u9pB98WsHXC0WvDHlGCYp3CH/jlkJPL7gN8nkTQVrQ/2w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/next/node_modules/@next/swc-linux-arm64-musl": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.4.tgz", + "integrity": "sha512-YYGb7SlLkI+XqfQa8VPErljb7k9nUnhhRrVaOdfJNCaQnHBcvbT7cx/UjDQLdleJcfyg1Hkn5YSSIeVfjgmkTg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/next/node_modules/@next/swc-linux-x64-gnu": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.4.tgz", + "integrity": "sha512-uE61vyUSClnCH18YHjA8tE1prr/PBFlBFhxBZis4XBRJoR+txAky5d7gGNUIbQ8sZZ7LVkSVgm/5Fc7mwXmRAg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/next/node_modules/@next/swc-linux-x64-musl": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.4.tgz", + "integrity": "sha512-qVEKFYML/GvJSy9CfYqAdUexA6M5AklYcQCW+8JECmkQHGoPxCf04iMh7CPR7wkHyWWK+XLt4Ja7hhsPJtSnhg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/next/node_modules/@next/swc-win32-arm64-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.4.tgz", + "integrity": "sha512-mDSQfqxAlfpeZOLPxLymZkX0hYF3juN57W6vFHTvwKlnHfmh12Pt7hPIRLYIShk8uYRsKPtMTth/EzpwRI+u8w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/next/node_modules/@next/swc-win32-ia32-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.4.tgz", + "integrity": "sha512-aoqAT2XIekIWoriwzOmGFAvTtVY5O7JjV21giozBTP5c6uZhpvTWRbmHXbmsjZqY4HnEZQRXWkSAppsIBweKqw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/next/node_modules/@next/swc-win32-x64-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.4.tgz", + "integrity": "sha512-cyRvlAxwlddlqeB9xtPSfNSCRy8BOa4wtMo0IuI9P7Y0XT2qpDrpFKRyZ7kUngZis59mPVla5k8X1oOJ8RxDYg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/node-gyp-build": { + "version": "4.6.1", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-releases": { + "version": "2.0.13", + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.7", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/object.hasown": { + "version": "1.1.3", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.3", + "license": "MIT", + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/postcss": { + "version": "8.4.31", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "license": "MIT" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.8.8", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react": { + "version": "18.2.0", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-feather": { + "version": "2.0.10", + "license": "MIT", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">=16.8.6" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "license": "MIT" + }, + "node_modules/react-router": { + "version": "6.17.0", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.10.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.17.0", + "license": "MIT", + "dependencies": { + "@remix-run/router": "1.10.0", + "react-router": "6.17.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-toastify": { + "version": "9.1.3", + "license": "MIT", + "dependencies": { + "clsx": "^1.1.1" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "license": "MIT", + "optional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "globalthis": "^1.0.3", + "which-builtin-type": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.1.1", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.0", + "license": "MIT" + }, + "node_modules/regenerator-transform": { + "version": "0.15.2", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "5.3.2", + "license": "MIT", + "dependencies": { + "@babel/regjsgen": "^0.8.0", + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.1.0", + "regjsparser": "^0.9.1", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/resolve": { + "version": "1.22.6", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.23.0", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "7.5.4", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-name": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.10", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.5", + "regexp.prototype.flags": "^1.5.0", + "set-function-name": "^2.0.0", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-components": { + "version": "6.0.8", + "license": "MIT", + "dependencies": { + "@babel/cli": "^7.21.0", + "@babel/core": "^7.21.0", + "@babel/helper-module-imports": "^7.18.6", + "@babel/plugin-external-helpers": "^7.18.6", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-object-rest-spread": "^7.20.7", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@babel/traverse": "^7.21.2", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/unitless": "^0.8.0", + "@types/stylis": "^4.0.2", + "css-to-react-native": "^3.2.0", + "csstype": "^3.1.2", + "postcss": "^8.4.23", + "shallowequal": "^1.1.0", + "stylis": "^4.3.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "babel-plugin-styled-components": ">= 2", + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "babel-plugin-styled-components": { + "optional": true + } + } + }, + "node_modules/styled-jsx": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/stylis": { + "version": "4.3.0", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.21.0", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/text-table": { + "version": "0.2.0", + "license": "MIT" + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "license": "MIT" + }, + "node_modules/tsconfig-paths": { + "version": "3.14.2", + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "license": "0BSD" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/type": { + "version": "1.2.0", + "license": "ISC" + }, + "node_modules/type-check": { + "version": "0.4.0", + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utf-8-validate": { + "version": "5.0.10", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-gyp-build": "^4.3.0" + }, + "engines": { + "node": ">=6.14.2" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "license": "BSD-2-Clause" + }, + "node_modules/webpack": { + "version": "5.88.2", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/websocket": { + "version": "1.0.34", + "license": "Apache-2.0", + "dependencies": { + "bufferutil": "^4.0.1", + "debug": "^2.2.0", + "es5-ext": "^0.10.50", + "typedarray-to-buffer": "^3.1.5", + "utf-8-validate": "^5.0.2", + "yaeti": "^0.0.6" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/websocket/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/websocket/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.1.3", + "license": "MIT", + "dependencies": { + "function.prototype.name": "^1.1.5", + "has-tostringtag": "^1.0.0", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.0.2", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "is-map": "^2.0.1", + "is-set": "^2.0.1", + "is-weakmap": "^2.0.1", + "is-weakset": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.11", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "license": "ISC" + }, + "node_modules/yaeti": { + "version": "0.0.6", + "license": "MIT", + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.4.tgz", + "integrity": "sha512-siPuUwO45PnNRMeZnSa8n/Lye5ZX93IJom9wQRB5DEOdFrw0JjOMu1GINB8jAEdwa7Vdyn1oJ2xGNaQpdQQ9Pw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.4.tgz", + "integrity": "sha512-l/k/fvRP/zmB2jkFMfefmFkyZbDkYW0mRM/LB+tH5u9pB98WsHXC0WvDHlGCYp3CH/jlkJPL7gN8nkTQVrQ/2w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.4.tgz", + "integrity": "sha512-YYGb7SlLkI+XqfQa8VPErljb7k9nUnhhRrVaOdfJNCaQnHBcvbT7cx/UjDQLdleJcfyg1Hkn5YSSIeVfjgmkTg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.4.tgz", + "integrity": "sha512-uE61vyUSClnCH18YHjA8tE1prr/PBFlBFhxBZis4XBRJoR+txAky5d7gGNUIbQ8sZZ7LVkSVgm/5Fc7mwXmRAg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.4.tgz", + "integrity": "sha512-qVEKFYML/GvJSy9CfYqAdUexA6M5AklYcQCW+8JECmkQHGoPxCf04iMh7CPR7wkHyWWK+XLt4Ja7hhsPJtSnhg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.4.tgz", + "integrity": "sha512-mDSQfqxAlfpeZOLPxLymZkX0hYF3juN57W6vFHTvwKlnHfmh12Pt7hPIRLYIShk8uYRsKPtMTth/EzpwRI+u8w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-ia32-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.4.tgz", + "integrity": "sha512-aoqAT2XIekIWoriwzOmGFAvTtVY5O7JjV21giozBTP5c6uZhpvTWRbmHXbmsjZqY4HnEZQRXWkSAppsIBweKqw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "13.5.4", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.4.tgz", + "integrity": "sha512-cyRvlAxwlddlqeB9xtPSfNSCRy8BOa4wtMo0IuI9P7Y0XT2qpDrpFKRyZ7kUngZis59mPVla5k8X1oOJ8RxDYg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..952e86e2 --- /dev/null +++ b/package.json @@ -0,0 +1,49 @@ +{ + "name": "shanti-project", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint:check": "npx eslint .", + "lint:fix": "npx eslint . --fix", + "prettier:check": "npx prettier --check .", + "prettier:fix": "npx prettier --write ." + }, + "dependencies": { + "@fortawesome/fontawesome-free": "^6.4.2", + "@fortawesome/free-solid-svg-icons": "^6.4.2", + "@fortawesome/react-fontawesome": "^0.2.0", + "@supabase/supabase-js": "^2.37.0", + "@types/node": "20.6.3", + "@types/react": "18.2.22", + "@types/react-dom": "18.2.7", + "dotenv": "^16.3.1", + "eslint-config-next": "13.5.2", + "next": "^13.5.4", + "next-google-fonts": "^2.2.0", + "react": "^18.2.0", + "react-dom": "18.2.0", + "react-feather": "^2.0.10", + "react-router-dom": "^6.17.0", + "react-toastify": "^9.1.3", + "styled-components": "^6.0.8" + }, + "devDependencies": { + "@calblueprint/eslint-config-react": "^0.0.3", + "@calblueprint/prettier-config": "^0.0.1", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", + "eslint": "^8.50.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-config-prettier": "^8.10.0", + "eslint-plugin-import": "^2.28.1", + "eslint-plugin-jsx-a11y": "^6.7.1", + "eslint-plugin-react": "^7.33.2", + "eslint-plugin-react-hooks": "^4.6.0", + "file-loader": "^6.2.0", + "prettier": "^2.8.8", + "typescript": "^4.9.5" + } +} diff --git a/public/check.svg b/public/check.svg new file mode 100644 index 00000000..dbeb8fb5 --- /dev/null +++ b/public/check.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/images/Arrow_Left_MD.png b/public/images/Arrow_Left_MD.png new file mode 100644 index 0000000000000000000000000000000000000000..82ecb97ce358c698110a57cc041eb7eb7baece8c GIT binary patch literal 267 zcmeAS@N?(olHy`uVBq!ia0vp^;vmey1|%P7U0DF6I14-?iy0WWg+Z8+Vb&Z8pde#$ zkh>GZx^prwfgF}}M_)$E)e-c@N`~{vajv*C{Z>QLDF)IqVrSshQQ9SL5n5AFd zhUzIYitZjW^*m?lnR_UTMP<0%C~1o=6BWD0uEhN7S+gLc)M{6bjqOqyYps`tEcwf# z`m-~$wrkn_brQvoB$Dl?h`ZDrVtH}ywnXtiZGTP4c2xGgtlX>RnXB*b?pH^Hk)YEYPhCp00i_ I>zopr03&}~kN^Mx literal 0 HcmV?d00001 diff --git a/public/images/Cart.png b/public/images/Cart.png new file mode 100644 index 0000000000000000000000000000000000000000..743667a66018897a35f61195c2e82cb94e7cee69 GIT binary patch literal 1142 zcmV-+1d02JP)z2*;h`%FL@xe;;@2(c=%U2B zE|;sJ8t5|*^swcp_xJaHRuV;!xR3<^3cnLo_(D=g=tS`H^3p@q#Z$owdNMl>9LFi= z^Z63$jZFX8+}ym_+S(eREXf>@G+r*{f1z^f(VYpd>w1s^$LYm&Vk`;#DLk6cjgrg= zY;8%aop{?=64*Omt6yYBK$>5*dM1+sdw9crgc18BGaxdK7jH|`39i6r390PKlu$)< zxxF@Dlu81)BX7?Ot@dH?^8ixe5y&SdVGBJ zS65fB(T`r!c;WA`FTZ4oC6-uXiT?p_92gxI0+R#S`+XTYtpJaYsOV&oS-f}(@q&&A zL{1qu;PGS_8A+1YoD{r1V2-LaU}p4WyRb5^pwZH?%mKC}i4$pT(_Mq%yEssjXn~0b zG~DAAz|$z|?DqEdBsvy~1|`X@g=8!Ee-ZE8YL;Ebt0v}*hWxy$H7(=?dCZ@tuB)hH zkdx=<=PGhr{9hg49W3BjyRi>*pbUhY%zdGsuQ{+5%BBeu<0Ke@rS3UbfB`C)Fq8@v zmH{rl#q$?F`W%`U^yAhtV-v=yQJsjA=vfAO2WEG%Y8Ow9mt7g2B1+>;=$4cQupt`g zb|vA`%as~s!U;OUPHm96VhIwx=sgne zKTvpjt76`Ql4)j{98(17%f*B@yRn^VzA1^MYa5Z)zQjL^-&ec?ST5ECN&o-=07*qo IM6N<$f_%pj?*IS* literal 0 HcmV?d00001 diff --git a/public/images/PAWS.png b/public/images/PAWS.png new file mode 100644 index 0000000000000000000000000000000000000000..7e4e4407d616c98833aa6b4fd98caf9e1a597141 GIT binary patch literal 84860 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 literal 0 HcmV?d00001 diff --git a/public/images/Profile.png b/public/images/Profile.png new file mode 100644 index 0000000000000000000000000000000000000000..3f04c46ff90fb59af2158e90bc72e3d133d386a0 GIT binary patch literal 1154 zcmV-|1bzF7P)&@_Xc09W?i%5wQnNbmk@I23de0*$ItJPpU9(!ntQATJxzPr1N#W9?b zUteF}2hq-Z?<zKOd)cs@LmXyZ=H!&B1lw zdEi3x32(4{FRc^54ZFV!xF8?#2Jf<)*6Hc#DPT#zFN*?t4`U7^xI+J}KE@*r(mc|q z0fc&n*uW-7Q!;K+iJyr>I9Xvy5@tbSfz=%ImAPmxAv{hq0b~(DEyIj1twoEAQg7i* zB@LVj+W$u$=u5-du98}YyW|FJ3wtqN{@Hqj=l=Ee^|?4kVe%x6tw9?k>F3kTB*q}R zF1N*n$kTtr%k)t7`Am<3q7RZ0>Iq5@C1>L&>Vf%L{P6J5_#eT^+*nyz+2q1RkAnUD z`iqoR>j z=3ON|(0xQdc`Jt33QKCeN5+zE!My~k43hV4^ zlIe04sv*v8t89&5P5mXioHaPHH)cLk7<-KT`M`ZU4#f7E)&T!T(HtY>9Z^1lnR94Z zWrg?~u@r%ZcC(|_a1GjNNddeke->FapSquCxW>X{z%=mQ=Fz1+{e~RPY``=K->VFe zIfTY1fi|>!$bOdDOyo)WfLbcsl-qNWH^GMw^08?OQ0JMe&oB@skXVVQAxJi98hF>z z%mDl0nqU)y}gYvzyt%F{1(rl%nvH+_~z!OYn~&>X7=qD>fsc5 zkT@X`g9POHe*;ZBO8{ZRncpyg{%yD65FsL246K32uH=9@u;8q3@C;YmnL?DmC+e>> z-@qtC$pDj+obp8UOqg;GtcZv5ta51my}k(_Gsm!Rfr6*f7y3bRV3HGb7El0ZzYkM8 z(sr6PW^^(z7e|@QyZh>4INcD=BlGun5>HK?Jy`AdaoFxyt1ag}g{Kj%vx UfaF`v5&!@I07*qoM6N<$g58oR>Hq)$ literal 0 HcmV?d00001 diff --git a/public/images/ShantiLogo.png b/public/images/ShantiLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..bcce3127562685ba123833824727fb86f6f2a587 GIT binary patch literal 4473 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 LNkvXXu0mjfS*p3{ literal 0 HcmV?d00001 diff --git a/public/images/profile (1).svg b/public/images/profile (1).svg new file mode 100644 index 00000000..eedf96e6 --- /dev/null +++ b/public/images/profile (1).svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/images/profile blue version-2.svg b/public/images/profile blue version-2.svg new file mode 100644 index 00000000..86a2ed1c --- /dev/null +++ b/public/images/profile blue version-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/next.svg b/public/next.svg new file mode 100644 index 00000000..5174b28c --- /dev/null +++ b/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/ready.svg b/public/ready.svg new file mode 100644 index 00000000..3e356ae2 --- /dev/null +++ b/public/ready.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/public/right_arrow.svg b/public/right_arrow.svg new file mode 100644 index 00000000..36957c93 --- /dev/null +++ b/public/right_arrow.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg new file mode 100644 index 00000000..d2f84222 --- /dev/null +++ b/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/x.svg b/public/x.svg new file mode 100644 index 00000000..495c7fc5 --- /dev/null +++ b/public/x.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/api/supabase/auth/auth.tsx b/src/api/supabase/auth/auth.tsx new file mode 100644 index 00000000..7ea5f70b --- /dev/null +++ b/src/api/supabase/auth/auth.tsx @@ -0,0 +1,28 @@ +/* eslint-disable */ + +import supabase from '../createClient'; + +export const handleSignUp = async (email: string, password: string) => { + const { data, error } = await supabase.auth.signUp({ + email, + password, + }); + console.log(error); +}; + +export const signInWithEmail = async (email: string, password: string) => { + const { data, error } = await supabase.auth.signInWithPassword({ + email, + password, + }); +}; + +export const signOut = async () => { + const { + data: { user }, + } = await supabase.auth.getUser(); + console.log('hi'); + console.log(user); + const { error } = await supabase.auth.signOut(); + console.log(user); +}; diff --git a/src/api/supabase/createClient.tsx b/src/api/supabase/createClient.tsx new file mode 100644 index 00000000..53892337 --- /dev/null +++ b/src/api/supabase/createClient.tsx @@ -0,0 +1,20 @@ +import { createClient } from '@supabase/supabase-js'; +import dotenv from 'dotenv'; + +dotenv.config(); + +if ( + !process.env.NEXT_PUBLIC_SUPABASE_URL || + !process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY +) { + throw new Error( + 'No Supabase environment variables detected, please make sure they are in place!', + ); +} + +const supabase = createClient( + process.env.NEXT_PUBLIC_SUPABASE_URL, + process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, +); + +export default supabase; diff --git a/src/api/supabase/queries/button_queries.ts b/src/api/supabase/queries/button_queries.ts new file mode 100644 index 00000000..191ce031 --- /dev/null +++ b/src/api/supabase/queries/button_queries.ts @@ -0,0 +1,32 @@ +import { StorefrontButtons } from '../../../schema/schema'; +import supabase from '../createClient'; + +export async function fetchButtonCategories(): Promise { + const { data: buttons, error } = await supabase + .from('storefront_buttons') + .select('*'); + if (error) { + throw new Error(`Error fetching buttons: ${error.message}`); + } + + return buttons; +} + +export async function convertButtonNumberToCategory( + id: string, +): Promise { + const { data: buttonsCategory, error } = await supabase + .from('storefront_buttons') + .select('*') + .eq('id', id) + .single(); + if (error) { + throw new Error(`Error fetching buttons: ${error.message}`); + } + + return buttonsCategory.name; +} + +export async function fetchButton() { + return 0; +} diff --git a/src/api/supabase/queries/cart_queries.ts b/src/api/supabase/queries/cart_queries.ts new file mode 100644 index 00000000..c8062040 --- /dev/null +++ b/src/api/supabase/queries/cart_queries.ts @@ -0,0 +1,263 @@ +import supabase from '../createClient'; + +import { fetchUser } from './user_queries'; +import { Product, ProductWithQuantity } from '../../../schema/schema'; +import { fetchProductByID } from './product_queries'; +import { convertButtonNumberToCategory } from './button_queries'; +// define cart item type +export type CartItem = { + id: number; + product_id: number; + quantity: number; +}; + +/** + * get cart item by id + * @param number - cart item id + * @returns Promise - A CartItem object. + */ +export async function fetchCartItem(cartItemID: number): Promise { + const { data, error } = await supabase + .from('order_product') + .select('*') + .eq('id', cartItemID) + .single(); + + if (error) { + throw new Error(`Error fetching cart item: ${error.message}`); + } + return data; +} + +/** + * get cart items in a user's cart + * @returns Promise - An array of CartItem objects. + */ +export async function fetchCart(): Promise { + const user = await fetchUser(); + + // Check if the user has a cart_id + if (!user.cart_id) { + throw new Error('User does not have a cart.'); + } + + const cartID = user.cart_id; + const { data, error } = await supabase + .from('order') + .select('*') + .match({ id: cartID }) + .limit(1); + + if (error) { + throw new Error(`Error fetching cart: ${error.message}`); + } + const products = data[0].order_product_id_array; + if (products !== null && products !== undefined) { + const productPromises = products.map(async (productID: number) => { + const product = await fetchCartItem(productID); + return product; + }); + const fetchedProducts = await Promise.all(productPromises); + return fetchedProducts; + } + + return [] as CartItem[]; +} + +export async function fetchCartItems(): Promise { + const cart = await fetchCart(); + const productPromises = cart.map(async (item: CartItem) => { + const product = await fetchProductByID(item.product_id); + return product; + }); + const fetchedProducts = await Promise.all(productPromises); + + return fetchedProducts; +} + +/** + * update cart + * @param cartID - cart id + * @param cartIDArray - cart id array + */ +async function updateCart(cartID: number, cartIDArray: number[]) { + await supabase + .from('order') + .update({ order_product_id_array: cartIDArray }) + .match({ id: cartID }); +} + +/** + * add product to cart + * @param productID - product id + * @param quantity - quantity of product + */ +export async function addToCart(productID: number, quantity: number) { + const items = await fetchCart(); + + // check if product is already in cart + + const existingItem = items.find( + item => Number(item.product_id) === Number(productID), + ); + + if (existingItem) { + if (existingItem !== undefined && existingItem !== null) { + const newQuantity = existingItem.quantity + quantity; + await supabase + .from('order_product') + .update({ quantity: newQuantity }) + .match({ id: existingItem.id }); + } + } else { + const { data, error } = await supabase + .from('order_product') + .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); + } +} + +/** + * decrease quantity of product in cart + * @param productID - product id + * @param quantity - quantity of product + */ +export async function decreaseFromCart(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('order_product') + .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('order_product') + .update({ quantity: newQuantity }) + .eq('id', existingItem.id); + } + } +} + +/** + * remove product from cart + * @param productID - product id + */ +export async function removeCartItem(productID: number) { + decreaseFromCart(productID, Infinity); +} + +/** + * clear cart + */ +export async function clearCart() { + const user = await fetchUser(); + const cartID = user.cart_id; + updateCart(cartID, []); +} + +/** + * @returns the number of items stored within the cart if there is no items then returns 0 + */ + +export async function totalNumberOfItemsInCart(): Promise { + const cart = await fetchCart(); + if (cart.length === 0 || cart === null || cart === null) { + return 0; + } + return cart.reduce((acc, item) => acc + item.quantity, 0); +} + +export async function fetchCartItemsWithQuantity(): Promise< + ProductWithQuantity[] +> { + const cart = await fetchCart(); + const productPromises = cart.map(async (item: CartItem) => { + const product = await fetchProductByID(item.product_id); + return { + name: product.name, + quantity: item.quantity, + photo: product.photo, + id: product.id, + category: await convertButtonNumberToCategory(product.category), + }; + }); + + const fetchedProducts = await Promise.all(productPromises); + + return fetchedProducts; +} + +export async function fetchCartIdFromUser() { + const user = await fetchUser(); + const cartID = user.cart_id; + return cartID; +} +/** + * get cart items in a user's cart by cart_id + * @returns Promise - An array of CartItem objects. + */ +export async function fetchCartById(cartId: string): Promise { + const { data, error } = await supabase + .from('order') + .select('*') + .match({ id: cartId }) + .limit(1); + + if (error) { + throw new Error(`Error fetching cart: ${error.message}`); + } + const products = data[0].order_product_id_array; + if (products !== null && products !== undefined) { + const productPromises = products.map(async (productID: number) => { + const product = await fetchCartItem(productID); + return product; + }); + const fetchedProducts = await Promise.all(productPromises); + return fetchedProducts; + } + + return [] as CartItem[]; +} + +export async function fetchCartItemsWithQuantityByID( + id: string | null, +): Promise { + if (id == null) throw new Error('no cartID'); + const cart = await fetchCartById(id); + const productPromises = cart.map(async (item: CartItem) => { + const product = await fetchProductByID(item.product_id); + return { + name: product.name, + quantity: item.quantity, + photo: product.photo, + id: product.id, + category: await convertButtonNumberToCategory(product.category), + }; + }); + + const fetchedProducts = await Promise.all(productPromises); + 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 new file mode 100644 index 00000000..e011398d --- /dev/null +++ b/src/api/supabase/queries/order_queries.ts @@ -0,0 +1,272 @@ +/* eslint-disable no-console */ +// + +import { + Order, + OrderProduct, + OrderStatus, + Product, +} from '../../../schema/schema'; +import { fetchUser } from './user_queries'; +import { fetchProductByID } from './product_queries'; +import supabase from '../createClient'; + +/** + * Fetches all orders from the database. + * @returns Promise - An array of Order objects. + */ +export async function getOrderById(orderId: number): Promise { + const { data: order, error } = await supabase + .from('order') // Update to the "Order" table + .select('*') + .eq('id', orderId) + .single(); + if (error) { + throw new Error(`Error fetching order: ${error.message}`); + } + return order; +} + +/** + * creates a new order for the user + */ +export async function createOrder() { + const user = await fetchUser(); + + const { data: order, error } = await supabase + .from('order') + .insert({ user_id: user.id }) + .select('*') + .single(); + if (error) { + throw new Error(`Error creating order: ${error.message}`); + } + + await supabase + .from('profiles') + .update({ cart_id: order.id }) + .match({ id: user.id }); +} + +/** + * gets all orders by user id and sorted it by creation data + * @param Order[] - An array of Order objects. + * @returns Promise - An array of Order objects. + */ +function sortOrdersByCreated(orders: Order[]): Order[] { + return orders.sort( + (a, b) => + new Date(b.created_at).getTime() - new Date(a.created_at).getTime(), + ); +} + +/** + * gets all orders by user id and sorted it by creation data + * @param Order[] - An array of Order objects. + * @returns Promise - An array of Order objects. + */ +export async function fetchOrdersByUser(): Promise { + const user = await fetchUser(); + const userId = user.id; + const { data, error } = await supabase + .from('order') + .select('*') + .eq('user_id', userId) + .neq('order_status', 'In Progress'); + + if (error) { + throw new Error(`Error fetching orders for user: ${error.message}`); + } + + return data; +} + +/** + * gets all orders by user id and sorted it by creation data + * @param Order[] - An array of Order objects. + * @returns Promise - An array of Order objects. + */ +export async function fetchOrdersByUserIdSorted(): Promise { + const orders = await fetchOrdersByUser(); + return sortOrdersByCreated(orders); +} + +/** + * gets all orders by user id and sorted it by creation data and get the first n orders + * @param Order[] - An array of Order objects. + * @returns Promise - An array of Order objects. + */ +export async function fetchNOrdersByUserIdSorted(n: number): Promise { + const orders = await fetchOrdersByUser(); + return sortOrdersByCreated(orders).slice(0, n); +} + +export async function fetchOrderIdsByUserIdSorted(): Promise { + const ordersProm = await fetchOrdersByUser(); + const orders = sortOrdersByCreated(ordersProm); + return orders.map(order => order.id); +} + +export async function fetchOrderProductById( + productId: number, +): Promise { + const { data: orderProduct, error } = await supabase + .from('order_product') + .select('*') + .eq('id', productId) + .single(); + if (error) { + throw new Error(`Error fetching order product: ${error.message}`); + } + return orderProduct; +} + +export async function fetchProductFromOrderProduct( + orderProductId: number, +): Promise { + const orderProduct = await fetchOrderProductById(orderProductId); + const product = await fetchProductByID(orderProduct.product_id); + return product; +} + +export async function fetchProductsFromOrder( + orderId: number, +): Promise { + const order = await getOrderById(orderId); + const products = order.order_product_id_array; + + const productPromises = products.map(async (productID: number) => { + const product = await fetchProductFromOrderProduct(productID); + return product; + }); + const fetchedProducts = await Promise.all(productPromises); + + return fetchedProducts; +} + +export async function fetchProductWithQuantityById( + productId: number, +): Promise { + const { data: orderProduct, error } = await supabase + .from('product') + .select('*') + .eq('id', productId) + .single(); + if (error) { + throw new Error(`Error fetching order product: ${error.message}`); + } + return orderProduct; +} + +export async function fetchOrderProductsbyOrderId( + orderId: number, +): Promise { + const order = await getOrderById(orderId); + const orderProductIds = order.order_product_id_array; + + const newOrderProducts = await Promise.all( + orderProductIds.map(orderProductId => + fetchOrderProductById(orderProductId), + ), + ); + + const orderProducts = await Promise.all( + newOrderProducts.map(async orderProduct => + fetchProductWithQuantityById(orderProduct.product_id), + ), + ); + + return orderProducts; +} + +/** + * gets all orders by user id and sorted it by creation data + * @param Order[] - An array of Order objects. + * @returns Promise - An array of Order objects. + */ +export async function fetchCurrentOrdersByUser(): Promise { + const user = await fetchUser(); + const userCartId = user.cart_id; + const { data, error } = await supabase + .from('order') + .select('*') + .eq('id', userCartId); + + if (error) { + throw new Error(`Error fetching orders for user: ${error.message}`); + } + + return data; +} + +export async function fetchRecentOrderProducts(): Promise { + const order = await fetchNOrdersByUserIdSorted(1); + const orderProductIds = order[0].order_product_id_array; + + const orderProducts = await Promise.all( + orderProductIds.map(async orderProductId => { + try { + const orderProduct = await fetchOrderProductById(orderProductId); + return orderProduct; + } catch (error) { + throw new Error(`Error fetching order product array.`); + } + }), + ); + + return orderProducts; +} + +export async function updateOrderPickupId(orderId: number, pickupId: number) { + await supabase + .from('order') + .update({ pickup_time_id: pickupId }) + .eq('id', orderId); +} + +export async function updateCartPickupId(pickupId: number) { + const user = await fetchUser(); + const cartId = user.cart_id; + await supabase + .from('order') + .update({ pickup_time_id: pickupId }) + .eq('id', cartId); +} + +/* Update the status of an order */ +export async function updateOrderStatus( + orderId: number, + orderStatus: OrderStatus, +) { + await supabase + .from('order') + .update({ order_status: orderStatus }) + .eq('id', orderId); +} +/** + * Gets user's most recent order + * @returns Promise - The most recent Order object, or throws an error if no order is found. + */ +export async function fetchCartIdFromUserfetchMostRecentOrderByUser(): Promise { + const user = await fetchUser(); + const userId = user.id; + const { data, error } = await supabase + .from('order') + .select('*') + .eq('user_id', userId) + .order('created_at', { ascending: false }) // Order by creation date in descending order + .limit(1); // Limit to only one order + + if (error) { + throw new Error( + `Error fetching most recent order for user: ${error.message}`, + ); + } + + if (data.length === 0) { + throw new Error('No orders found for the user.'); + } + + // Return the first order in the data array + return data[0]; +} diff --git a/src/api/supabase/queries/pickup_queries.ts b/src/api/supabase/queries/pickup_queries.ts new file mode 100644 index 00000000..fd56dc46 --- /dev/null +++ b/src/api/supabase/queries/pickup_queries.ts @@ -0,0 +1,69 @@ +import { Pickup } from '../../../schema/schema'; +import supabase from '../createClient'; + +/** + * + * @returns all the pickup times from the database + */ +export async function fetchPickupData(): Promise { + const { data: pickupTimes, error } = await supabase + .from('pickup_times') + .select('*'); + + if (error) { + throw new Error(`Error fetching pickup times: ${error.message}`); + } + return pickupTimes || []; +} + +/** + * + * @param pickupID + * @returns fetches a single pickup time by its ID + */ +export async function fetchPickupTimesByID(pickupID: number): Promise { + const { data: pickupTimes, error } = await supabase + .from('pickup_times') + .select('*') + .eq('id', pickupID) + .single(); + + if (error) { + throw new Error(`Error fetching pickup times: ${error.message}`); + } + + return pickupTimes; +} + +/** + * + * @returns most recevnt pickup + */ +export async function fetchRecentPickupTimes(): Promise { + const { data: getTimes, error } = await supabase + .from('pickup_times') + .select('*') + .limit(2); + + if (error) { + throw new Error(`Error fetching pickup times: ${error.message}`); + } + return getTimes; +} + +/** + * + * @returns 2 most recent pickup times + */ +export async function fetchNRecentPickupTimes(n: number): Promise { + const { data: getTimes, error } = await supabase + .from('pickup_times') + .select('*') + .order('start_time', { ascending: true }) + .limit(n); + + if (error) { + throw new Error(`Error fetching pickup times: ${error.message}`); + } + return getTimes; +} diff --git a/src/api/supabase/queries/product_queries.ts b/src/api/supabase/queries/product_queries.ts new file mode 100644 index 00000000..67396986 --- /dev/null +++ b/src/api/supabase/queries/product_queries.ts @@ -0,0 +1,144 @@ +import { Product, StorefrontButtons } from '../../../schema/schema'; +import supabase from '../createClient'; +import { fetchUser } from './user_queries'; + +/** + * Fetches all products from the database. + * @returns Promise - An array of Product objects. + */ +export async function fetchProducts(): Promise { + const { data: products, error } = await supabase.from('product').select('*'); + if (error) { + throw new Error(`Error fetching products: ${error.message}`); + } + + return products; +} + +export async function fetchUnprescribedProducts(): Promise { + const { data: products, error } = await supabase + .from('product') + .select('*') + .eq('prescribed', false); + if (error) { + throw new Error(`Error fetching products: ${error.message}`); + } + return products; +} + +export async function fetchUserProducts(): Promise { + const products = await fetchUnprescribedProducts(); + const user = await fetchUser(); + + const { data: prescribed, error } = await supabase + .from('product') + .select('*') + .eq('prescribed', true); + if (error) { + throw new Error(`Error fetching products: ${error.message}`); + } + + for (let i = 0; i < prescribed.length; i += 1) { + if (prescribed[i].id) { + if (user.pet_prescription.includes(prescribed[i].id)) { + products.push(prescribed[i]); + } + } + } + + return products; +} + +/** + * Fetches a single product by its ID. + * @param productId - The unique identifier for the product. + * @returns Promise - The Product object. + */ +export async function fetchProductByID(productId: number): Promise { + const { data: product, error } = await supabase + .from('product') + .select('*') + .eq('id', productId) + .single(); + + if (error) { + throw new Error(`Error fetching product: ${error.message}`); + } + + return product; +} + +/** + * @param productType + * @returns the products that match the productType + */ +export async function filterProduct(productType: string): Promise { + const { data: products, error } = await supabase + .from('product') + .select('*') + .eq('category', productType); + + if (error) { + throw new Error(`Error fetching products: ${error.message}`); + } + + return products; +} + +export async function convertCategoryToNumber( + productType: string, +): Promise { + const { data: buttonVal, error } = await supabase + .from('storefront_buttons') + .select('*') + .eq('name', productType) + .single(); + + if (error) { + throw new Error(`Error fetching products: ${error.message}`); + } + return buttonVal.id; +} + +export async function fetchUnprescribedCategory( + productType: string, +): Promise { + const productTypeConverted = await convertCategoryToNumber(productType); + + const { data: products, error } = await supabase + .from('product') + .select('*') + .eq('prescribed', false) + .eq('category', productTypeConverted); + if (error) { + throw new Error(`Error fetching products: ${error.message}`); + } + return products; +} + +export async function filterUserProducts( + productType: string, +): Promise { + const products = await fetchUnprescribedCategory(productType); + const user = await fetchUser(); + + const { data: prescribed, error } = await supabase + .from('product') + .select('*') + .eq('prescribed', true) + .eq('category', productType); + + if (error) { + throw new Error(`Error fetching products: ${error.message}`); + } + + for (let i = 0; i < prescribed.length; i += 1) { + if (prescribed[i].id) { + if (user.pet_prescription.includes(prescribed[i].id)) { + products.push(prescribed[i]); + } + } + } + + return products; +} diff --git a/src/api/supabase/queries/tests/order_test.ts b/src/api/supabase/queries/tests/order_test.ts new file mode 100644 index 00000000..c1f2ace7 --- /dev/null +++ b/src/api/supabase/queries/tests/order_test.ts @@ -0,0 +1,7 @@ +export function tester1() { + return 0; +} + +export function tester2() { + return 0; +} diff --git a/src/api/supabase/queries/tests/pickup_test.ts b/src/api/supabase/queries/tests/pickup_test.ts new file mode 100644 index 00000000..c1f2ace7 --- /dev/null +++ b/src/api/supabase/queries/tests/pickup_test.ts @@ -0,0 +1,7 @@ +export function tester1() { + return 0; +} + +export function tester2() { + return 0; +} diff --git a/src/api/supabase/queries/tests/product_test.ts b/src/api/supabase/queries/tests/product_test.ts new file mode 100644 index 00000000..98bc9637 --- /dev/null +++ b/src/api/supabase/queries/tests/product_test.ts @@ -0,0 +1,25 @@ +/* eslint-disable no-console */ +// + +import { fetchProducts, fetchProductByID } from '../product_queries'; // Replace './your-module' with the actual path to your module + +// Test fetching all products +export async function testFetchProducts() { + try { + const result = await fetchProducts(); + console.log('Fetch Products Result:', result); + } catch (error) { + console.error('Test Fetch Products Error:', error); + } +} + +// Test fetching a product by name +export async function testFetchProductByName() { + const productId = 1; // Replace with a valid product name + try { + const result = await fetchProductByID(productId); + console.log('Fetch Product by Name Result:', result); + } catch (error) { + console.error('Test Fetch Product by Name Error:', error); + } +} diff --git a/src/api/supabase/queries/tests/user_test.ts b/src/api/supabase/queries/tests/user_test.ts new file mode 100644 index 00000000..c1f2ace7 --- /dev/null +++ b/src/api/supabase/queries/tests/user_test.ts @@ -0,0 +1,7 @@ +export function tester1() { + return 0; +} + +export function tester2() { + return 0; +} diff --git a/src/api/supabase/queries/user_queries.ts b/src/api/supabase/queries/user_queries.ts new file mode 100644 index 00000000..6a6c75a8 --- /dev/null +++ b/src/api/supabase/queries/user_queries.ts @@ -0,0 +1,157 @@ +import supabase from '../createClient'; +import { User, Product } from '../../../schema/schema'; +import { fetchProductByID } from './product_queries'; + +/** + * fetchUser is a function that fetches the user data from the database and returns the user object. + * @returns a user object + */ +export async function fetchUser(): Promise { + const { + data: { session }, + error, + } = await supabase.auth.getSession(); + + if (error) { + throw new Error(`Error fetching session: ${error.message}`); + } + + if (!session) { + throw new Error(`Session is null`); + } + + const { user } = session; + + if (user !== null) { + const { data, error: error1 } = await supabase + .from('profiles') + .select() + .eq('id', user.id) + .single(); + + if (error1) { + throw new Error(`Error fetching user: ${error1.message}`); + } + + return data as User; + } + + throw new Error('User is null'); +} + +/** + * fetchUserByUUID is a function that fetches the user data from the database and returns the user object. + * @param uuid: a string that is the user's uuid + * @returns a user object + */ +export async function fetchUserByUUID(uuid: string) { + try { + const { data: user, error } = await supabase + .from('profiles') + .select('*') + .eq('id', uuid) + .single(); + + if (error) { + throw new Error(`Error fetching user data: ${error.message}`); + } + + return user; + } catch (error) { + throw new Error(`Error`); + throw error; + } +} + +/** + * addOrRemoveProductFromFavorite is a function that adds or removes from the user's profiles -> fav_items column based on the state of the heart button. + * @param product: product object to add/remove to user's favorites + * @param isFav: a boolean tracking whether to remove an item from user's favorites + */ + +export async function addOrRemoveProductFromFavorite( + product: Product, + isFav: boolean, +) { + const user = await fetchUser(); + + const favItems = user.fav_items; + + const productID = product.id; + + if (isFav) { + favItems.push(productID); + } else { + const index = favItems.indexOf(productID); + favItems.splice(index, 1); + } + + await supabase + .from('profiles') + .update({ fav_items: favItems }) + .match({ id: user.id }); +} + +/** + * arrayOfFavorites grabs the users favorite items from profiles->fav_items where each fav_item is being tracked by the product_id stored as a string and matches those product_id to the proper product object and stores the product object in an array. + * @returns an array of product objects + */ + +export async function arrayOfFavorites(): Promise { + const user = await fetchUser(); + const favItems = user.fav_items; + if (favItems.length === 0) { + return []; + } + const arrayOfProducts = await Promise.all( + favItems.map(item => fetchProductByID(item)), + ); + + return arrayOfProducts; +} + +/** + * fetchUserAddress: Get's a user's address based on their UUID + * @param uuid: String containing the uuid of the user + */ +export async function fetchUserAddress(uuid: string) { + try { + const { data: user, error } = await supabase + .from('address') + .select('*') + .eq('user_id', uuid) + .single(); + + if (error) { + throw new Error(`Error fetching user data: ${error.message}`); + } + + return user; + } catch (error) { + throw new Error(`Error:`); + } +} + +/** + * fetchUserAddress: Get's a user's address based on their UUID + * @param uuid: String containing the uuid of the user + */ +export async function fetchCurrentUserAddress() { + try { + const user = await fetchUser(); + const { data: address, error } = await supabase + .from('address') + .select('*') + .eq('user_id', user.id) + .limit(1) + .single(); + + if (error) { + console.error('Error fetching user data:', error); + } + return address; + } catch (error) { + console.error('Error:', error); + throw error; + } +} diff --git a/src/app/[productId]/Buttons.tsx b/src/app/[productId]/Buttons.tsx new file mode 100644 index 00000000..9cc8d802 --- /dev/null +++ b/src/app/[productId]/Buttons.tsx @@ -0,0 +1,53 @@ +import React, { useState } from 'react'; +import { toast } from 'react-toastify'; +import { Plus, Minus } from 'react-feather'; +import { Body1Bold } from '@/styles/fonts'; +import { + ButtonsWrapper, + AddToCartButton, + QuantityButton, + PlusMinusButton, +} from './styles'; + +import { addToCart } from '../../api/supabase/queries/cart_queries'; + +export default function Buttons(props: { productNumber: number }) { + const [quantity, setQuantity] = useState(1); + const { productNumber } = props; + + const increaseQuantity = () => { + setQuantity(quantity + 1); + }; + + const decreaseQuantity = () => { + if (quantity > 1) { + setQuantity(quantity - 1); + } + }; + + // used hyphen instead of dash for display + const changeCart = () => { + addToCart(productNumber, quantity); + if (quantity <= 1) { + toast(`you have added ${quantity} item to the cart!`); + } else { + toast(`you have added ${quantity} items to the cart!`); + } + }; + + return ( + + + + + + {quantity} + + + + + + Add to cart + + ); +} diff --git a/src/app/[productId]/page.tsx b/src/app/[productId]/page.tsx new file mode 100644 index 00000000..55cd995a --- /dev/null +++ b/src/app/[productId]/page.tsx @@ -0,0 +1,114 @@ +'use client'; + +import { useEffect, useState } from 'react'; +import { convertButtonNumberToCategory } from '@/api/supabase/queries/button_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'; + +import { + ImageContainer, + TextContainer, + 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'; + +export default function ItemDisplay({ + params, +}: { + params: { productId: number }; +}) { + const [Item, setItem] = useState(); + const [IsFavorite, setIsFavorite] = useState(false); + const [FilteredProducts, setFilteredProducts] = useState([]); + + useEffect(() => { + async function fetchProducts() { + try { + const response = await fetchProductByID(params.productId); + 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); + } + } + + fetchProducts(); + }, [params.productId]); + + async function handleFavorite() { + await addOrRemoveProductFromFavorite( + await fetchProductByID(params.productId), + !IsFavorite, + ); + setIsFavorite(!IsFavorite); + } + + return ( + + + + + + + + + {Item?.name} + + + + + {Item?.name} + handleFavorite()}> + + + {IsFavorite ? 'Remove from favorites' : 'Add to favorites'} + + + + + + + Category: {Item?.category} + + + Product Details: + + {Item?.description} + + + + + ); +} diff --git a/src/app/[productId]/styles.ts b/src/app/[productId]/styles.ts new file mode 100644 index 00000000..285c5f76 --- /dev/null +++ b/src/app/[productId]/styles.ts @@ -0,0 +1,140 @@ +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 LeftColumnDiv = styled.div` + display: flex; + flex-direction: column; + gap: 25px; +`; + +export const DescriptionContainer = styled.div` + display: flex; + 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` + width: 500px; + height: 500px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + background-color: ${COLORS.lightGrey}; +`; + +export const TextContainer = styled.div` + width: 440px; + height: 350px; + margin-top: 41px; +`; + +export const ButtonsWrapper = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + width: 450px; + height: 50px; + margin-top: 40px; +`; + +export const QuantityButton = styled.div` + display: flex; + justify-content: space-evenly; + align-items: center; + width: 165px; + height: 50px; + border-radius: 8px; + background-color: ${COLORS.white}; + border: 2px solid ${COLORS.navy}; + color: ${COLORS.navy}; +`; + +export const PlusMinusButton = styled.button` + width: 25px; + height: 25px; + align-items: center; + justify-content: center; + background-color: transparent; + border-color: transparent; + font-size: 20px; + color: ${COLORS.navy}; +`; + +export const AddToCartButton = styled.button` + width: 265px; + height: 50px; + border-radius: 8px; + background-color: ${COLORS.navy}; + font-family: 'Public Sans', sans-serif; + font-size: 20px; + font-style: normal; + font-weight: 700; + line-height: normal; + color: ${COLORS.white}; + 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; + transform: translatey(90px); +`; + +export const Fullscreen = styled.div` + width: 100%; + height: 100%; + display: grid; +`; diff --git a/src/app/cart/Buttons.tsx b/src/app/cart/Buttons.tsx new file mode 100644 index 00000000..e06950e1 --- /dev/null +++ b/src/app/cart/Buttons.tsx @@ -0,0 +1,74 @@ +import React from 'react'; + +import { QuantityButton, PlusMinusButton } from './styles'; + +import { + decreaseFromCart, + addToCart, +} from '../../api/supabase/queries/cart_queries'; + +import { ProductWithQuantity } from '../../schema/schema'; + +export default function Buttons(props: { + productNumber: number; + quantity: number; + setNumberOfItems: (count: number) => void; + numberOfItems: number; + count: number; + setCount: (count: number) => void; + cart: ProductWithQuantity[]; + setCart: (category: ProductWithQuantity[]) => void; +}) { + const { + productNumber, + + setNumberOfItems, + numberOfItems, + count, + setCount, + cart, + setCart, + } = props; + + const increaseQuantity = () => { + setCount(count + 1); + addToCart(productNumber, 1); + setNumberOfItems(numberOfItems + 1); + const indexOfItem = cart.findIndex(item => item.id === productNumber); + cart[indexOfItem].quantity += 1; + setCart(cart); + }; + + const decreaseQuantity = () => { + if (count > 1) { + setCount(count - 1); + decreaseFromCart(productNumber, 1); + setNumberOfItems(numberOfItems - 1); + const indexOfItem = cart.findIndex(item => item.id === productNumber); + cart[indexOfItem].quantity -= 1; + setCart(cart); + } + }; + + // used hyphen instead of dash for display + + return ( + + + – + + {count} + + + + + + ); +} diff --git a/src/app/cart/cartItem.tsx b/src/app/cart/cartItem.tsx new file mode 100644 index 00000000..8d461e89 --- /dev/null +++ b/src/app/cart/cartItem.tsx @@ -0,0 +1,69 @@ +'use client'; + +import { useState } from 'react'; +import { Body2, Heading4Bold } from '@/styles/fonts'; +import { removeCartItem } from '../../api/supabase/queries/cart_queries'; +import { + FavoriteDiv, + TrashIcon, + TransparentButton, + LabelBox, + ImageBackground, + CategorySpacing, +} from './styles'; + +import Buttons from './Buttons'; + +import { ProductWithQuantity } from '../../schema/schema'; + +export default function CartItem(props: { + cartItemProduct: ProductWithQuantity; + cart: ProductWithQuantity[]; + setCart: (category: ProductWithQuantity[]) => void; + setNumberOfItems: (count: number) => void; + numberOfItems: number; +}) { + const { cartItemProduct, setCart, cart, setNumberOfItems, numberOfItems } = + props; + const [count, setCount] = useState(cartItemProduct.quantity); + async function removeProduct() { + setNumberOfItems(numberOfItems - count); + + const tempCart = cart.filter( + cartItem => cartItem.id !== cartItemProduct.id, + ) as ProductWithQuantity[]; + setCart(tempCart); + removeCartItem(cartItemProduct.id); + } + + return ( + + + {cartItemProduct.name} + + + {cartItemProduct.name} + + Category: {cartItemProduct.category} + + + + removeProduct()}> + + + + ); +} diff --git a/src/app/cart/page.tsx b/src/app/cart/page.tsx new file mode 100644 index 00000000..21be107b --- /dev/null +++ b/src/app/cart/page.tsx @@ -0,0 +1,91 @@ +'use client'; + +import { useRouter } from 'next/navigation'; +import { useState, useEffect } from 'react'; +import { fetchUser } from '@/api/supabase/queries/user_queries'; +import { Heading1 } from '@/styles/fonts'; +import BackButton from '../../components/BackButton/BackButton'; + +import OrderSummary from '../../components/OrderSummaryFolder/OrderSummary'; + +import { + fetchCartItemsWithQuantity, + totalNumberOfItemsInCart, +} from '../../api/supabase/queries/cart_queries'; +import CartItem from './cartItem'; +import NavBar from '../../components/NavBarFolder/NavBar'; +import { + CartItemsDiv, + PageDiv, + CheckoutButton, + LeftColumnDiv, + RightColumnDiv, + ContentDiv, + OrderSumSectionSpacing, +} from './styles'; + +import { ProductWithQuantity } from '../../schema/schema'; + +export default function OrderPage() { + const [numberOfItems, setNumberOfItems] = useState(0); + const [cart, setCart] = useState([]); + const [deliveryEnabled, setDeliveryEnabled] = useState(false); + const router = useRouter(); + useEffect(() => { + async function fetchProducts() { + setNumberOfItems(await totalNumberOfItemsInCart()); + setCart(await fetchCartItemsWithQuantity()); + const data = await fetchUser(); + setDeliveryEnabled(data.delivery_allowed); + } + + fetchProducts(); + }, []); + + const checkDelivery = () => { + if (deliveryEnabled) { + router.push('/delivery'); + } else { + router.push('/pickup'); + } + }; + + return ( + + +
+ +
+ + + + Cart + + {cart.map(cartItem => ( + + ))} + + + + + + checkDelivery()} + disabled={numberOfItems === 0} + > + Check Out + + + + +
+ ); +} diff --git a/src/app/cart/styles.tsx b/src/app/cart/styles.tsx new file mode 100644 index 00000000..ee956f99 --- /dev/null +++ b/src/app/cart/styles.tsx @@ -0,0 +1,383 @@ +import styled from 'styled-components'; + +import { Trash2 } from 'react-feather'; +import COLORS from '../../styles/colors'; + +import NavBar from '../../components/NavBarFolder/NavBar'; + +import Footer from '../../components/FooterFolder/Footer'; + +export const FavoriteDiv = styled.div` + display: flex; + flex-direction: row; + align-items: center; +`; + +export const ImageBackground = styled.div` + width: 200px; + height: 200px; + background-color: ${COLORS.lightGrey}; + display: flex; + justify-content: center; + align-items: center; +`; + +export const CartItemsDiv = styled.div` + display: flex; + flex-direction: column; + align-items: center; + border-radius: 10px; + overflow: auto; + gap: 32px; + margin-top: 20px; +`; + +export const ImageDiv = styled.div` + width: 30px; + height: 30px; + color: ${COLORS.black}; +`; + +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; +`; + +export const OutterBox = styled.div` + width: 900px; + margin-left: 300px; +`; + +export const Backtext = styled.p` + padding-top: 5px; +`; + +export const TrashIcon = styled(Trash2)` + width: 30px; + height: 30px; + color: navy; + margin-right: 30px; + margin-left: 50px; + margin-top: 28px; +`; + +export const FooterMoved = styled(Footer)` + transform: translateY(300px); +`; + +export const TransparentButton = styled.button` + background-color: transparent; + border: transparent; + margin-left: 40px; + margin-bottom: 25px; +`; + +export const NavBarMovedUP = styled(NavBar)` + position: relative; +`; + +export const ButtonsWrapper = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + width: 200px; + height: 50px; + margin-top: 20px; + padding: 30px; +`; + +export const QuantityButton = styled.div` + display: flex; + justify-content: space-evenly; + align-items: center; + width: 165px; + height: 50px; + border-radius: 8px; + font-size: 18px; + font-weight: bold; + background-color: ${COLORS.white}; + border: 2px solid ${COLORS.navy}; + color: ${COLORS.navy}; + cursor: pointer; + margin-left: 200px; +`; + +export const PlusMinusButton = styled.button` + width: 25px; + height: 25px; + align-items: center; + justify-content: center; + background-color: transparent; + border-color: transparent; + font-size: 20px; + color: ${COLORS.navy}; +`; + +export const Label = styled.p` + margin-top: 20px; +`; + +export const LabelBox = styled.div` + width: 150px; + margin-left: 50px; +`; + +export const ContentDiv = styled.div` + display: flex; + flex-direction: row; + justify-content: space-between; + padding-left: 50px; + background-color: ${COLORS.offWhite}; +`; + +export const BackButtonDiv1 = styled.div` + display: flex; + flex-direction: row; + gap: 200px; + margin-bottom: 55px; + text-align: left; + width: 800px; + padding-left: 40px; + padding-right: 40px; +`; + +export const Wrapper = styled.div` + min-height: 100%; /*or 100vh */ + position: relative; + background: var(--Light-Periwinkle, #f4f7ff); + justify-content: space-evenly; + align-items: center; + padding-top: 25px; + padding-bottom: 25px; + padding-left: 20px; + gap: 20px; +`; + +export const OrderSummaryDiv = styled.div` + overflow: auto; + width: 350px; + height: 300px; + padding: 20px; +`; + +export const ItemSummaryDiv = styled.div` + display: flex; + flex-direction: row; + margin-bottom: 20px; + justify-content: space-between; +`; + +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 LeftColumnDiv1 = styled.div` + display: flex; + flex-flow: column; + gap: 16px; +`; + +export const CheckoutButton1 = styled.button` + background: #1b3679; + + height: 40px; + margin-top: 20px; + + border: none; + border-radius: 5px; + + color: var(--White, #fff); + text-align: center; + font-family: 'Public Sans', sans-serif; + font-size: 20px; + font-style: normal; + font-weight: 700; + line-height: normal; +`; + +export const Qty = styled.p` + width: 100%; + padding-left: 290px; +`; + +export const RightColumnDiv1 = styled.div` + display: flex; + flex-flow: column; +`; + +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 HeaderShiftRight = styled.h2` + margin-right: 30px; +`; + +export const PShiftRight = styled.p` + margin-right: 30px; +`; + +export const HeaderShiftLeft = styled.h2` + margin-left: 15px; +`; + +export const PShiftLeft = styled.p` + margin-left: 15px; +`; + +export const PageDiv = styled.div` + height: auto; + width: 100%; + display: flex; + flex-direction: column; + + background-color: ${COLORS.offWhite}; +`; + +export const LeftColumnDiv = styled.div` + flex: 1; + padding-right: 20px; + margin-top: 20px; +`; + +export const InformationText = styled.div` + width: 730px; + height: 50px; + border-radius: 4px; + margin-top: 14px; + margin-bottom: 14px; + border: 1px solid ${COLORS.neutralGrey}; + background: ${COLORS.lightGrey}; + display: flex; /* Use flexbox */ + align-items: center; /* Center vertically */ + font-size: 20px; + font-style: normal; + font-weight: 400; + line-height: normal; + padding-left: 20px; +`; + +export const DeliveryContainer = styled.div` + margin-left: 80px; + margin-right: 80px; + margin-bottom: 80px; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: flex-start; +`; + +export const Container = styled.div` + display: flex; + flex-direction: col; +`; + +export const InformationContainer = styled.div` + width: 100%; + height: 100%; + margin-left: 25px; +`; + +export const OutterDiv = styled.div` + display: flex; + flex-direction: column; +`; + +export const OrderButton = styled.button` + margin-top: 26px; + width: 350px; + height: 50px; + flex-shrink: 0; + align-items: center; + background: ${COLORS.navy}; + border-radius: 8px; + color: ${COLORS.white}; + font-size: 20px; + font-family: 'Public Sans', sans-serif; + font-style: normal; + font-weight: 700; + line-height: normal; +`; + +export const OrderSummary = styled.div` + width: 350px; + height: 360px; + border-radius: 8px; + background: ${COLORS.white}; + box-shadow: 0px 1px 4px 1px rgba(0, 0, 0, 0.15); + align-items: center; +`; + +export const OrderContainer = styled.div` + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + align-items: end; + justify-content: center; +`; + +export const RightColumnDiv = styled.div` + flex: 1; + margin-top: 30px; + padding-left: 20px; +`; + +export const Heading = styled.h1` + font-family: 'Public Sans', sans-serif; + color: black; + margin-bottom: 20px; + font-size: 30px; +`; + +export const BackButtonDiv = styled.div` + display: flex; + flex-direction: row; + text-align: left; + width: 800px; + margin-left: 110px; + margin-bottom: 40px; +`; + +export const CheckoutButton = styled.button` + width: 350px; + background: #1b3679; + color: white; + border: none; + border-radius: 5px; + padding: 10px 20px; + font-size: 18px; + cursor: pointer; + margin-top: 20px; + + &:hover { + background: #0e2351; + } +`; + +export const CategorySpacing = styled.div` + margin-top: 15px; +`; + +export const OrderSumSectionSpacing = styled.div` + margin-left: 135px; +`; diff --git a/src/app/delivery/itemRows.tsx b/src/app/delivery/itemRows.tsx new file mode 100644 index 00000000..9a724bc2 --- /dev/null +++ b/src/app/delivery/itemRows.tsx @@ -0,0 +1,62 @@ +import React, { useEffect, useState } from 'react'; +import { OrderProduct } from '../../schema/schema'; +import { fetchProductByID } from '../../api/supabase/queries/product_queries'; +import { + ItemQuantityContainer, + ItemQuantityRow, + ItemText, + QuantityText, + TotalContainer, +} from './styles'; + +function ItemRows({ products }: { products: OrderProduct[] }) { + const [productDetails, setProductDetails] = useState<{ + [key: number]: string; + }>({}); + + useEffect(() => { + // Fetch product details for each product ID + const fetchProductDetails = async () => { + const details: { [key: number]: string } = {}; + + // Create an array of promises + const productPromises = products.map(async product => { + const productData = await fetchProductByID(product.product_id); + details[product.product_id] = productData.name; + }); + + // Wait for all promises to resolve + await Promise.all(productPromises); + + setProductDetails(details); + }; + + fetchProductDetails(); + }, [products]); + + const totalQuantity = products.reduce( + (total, productVal) => total + productVal.quantity, + 0, + ); + + return ( +
+ + {products.map(productVal => ( + + {productDetails[productVal.product_id]} + {productVal.quantity} + + ))} + + + + Order Total + {totalQuantity} + + +
+ ); +} + +export default ItemRows; diff --git a/src/app/delivery/page.tsx b/src/app/delivery/page.tsx new file mode 100644 index 00000000..1e66b420 --- /dev/null +++ b/src/app/delivery/page.tsx @@ -0,0 +1,100 @@ +'use client'; + +import React, { useState, useEffect } from 'react'; +import { useRouter } from 'next/navigation'; +import { + fetchUser, + fetchUserAddress, +} from '@/api/supabase/queries/user_queries'; +import querystring from 'querystring'; +import { + createOrder, + fetchCurrentOrdersByUser, + updateOrderStatus, +} from '@/api/supabase/queries/order_queries'; +import BackButton from '../../components/BackButton/BackButton'; +import { + fetchCartIdFromUser, + fetchCartItemsWithQuantity, + totalNumberOfItemsInCart, +} from '../../api/supabase/queries/cart_queries'; +import { Heading1, Normal700Text } from '../../styles/fonts'; +import { + ProductWithQuantity, + User, + Address, + OrderStatus, +} from '../../schema/schema'; +import OrderSummary from '../../components/OrderSummaryFolder/OrderSummary'; +import NavBar from '../../components/NavBarFolder/NavBar'; +import { + DeliveryContainer, + OrderContainer, + OrderButton, + InformationContainer, + InformationText, + BackButtonDiv, + OutterDiv, +} from './styles'; + +export default function App() { + const [numberOfItems, setNumberOfItems] = useState(0); + const [cart, setCart] = useState([]); + const [Profile, setProfile] = useState(); + const [UserAddress, setUserAddress] = useState
(); + const router = useRouter(); + useEffect(() => { + async function fetchProducts() { + setNumberOfItems(await totalNumberOfItemsInCart()); + setCart(await fetchCartItemsWithQuantity()); + } + async function fetchUserData() { + const data = await fetchUser(); // change the function to grab the cartItems as products + setProfile(data); + const address = await fetchUserAddress(data.id); + setUserAddress(address); + } + fetchUserData(); + fetchProducts(); + }, []); + + return ( +
+ + + + + + + + Shipping + Name + + {`${Profile?.first_name} ${Profile?.last_name}`} + + Address + + {UserAddress?.street}, {UserAddress?.city}, {UserAddress?.zipcode} + + + + + { + const orderID = await fetchCartIdFromUser(); + await updateOrderStatus(orderID, OrderStatus.Submitted); + await createOrder(); + const newestOrder = await fetchCartIdFromUser(); + await updateOrderStatus(newestOrder, OrderStatus.inProgress); + const queryString = querystring.stringify({ orderID }); + router.push(`/orderConfirmationDelivery?${queryString}`); + }} + > + Place Order + + + + +
+ ); +} diff --git a/src/app/delivery/styles.ts b/src/app/delivery/styles.ts new file mode 100644 index 00000000..eccef97a --- /dev/null +++ b/src/app/delivery/styles.ts @@ -0,0 +1,157 @@ +import styled from 'styled-components'; +import NavBar from '../../components/NavBarFolder/NavBar'; +import COLORS from '../../styles/colors'; + +export const DeliveryContainer = styled.div` + margin-left: 80px; + margin-right: 80px; + margin-bottom: 80px; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; +`; + +export const OutterBox = styled.div` + display: flex; + flex-direction: column; + align-items: center; +`; + +export const OrderSummaryText = styled.div` + margin-top: 27px; + margin-left: 30px; + text-align: left; + width: 285px; + height: 35px; + font-style: normal; + font-weight: 700; + line-height: normal; + font-size: 30px; +`; + +export const QtyText = styled.div` + margin-top: 30px; + margin-right: 20px; + margin-bottom: 5px; + font-style: normal; + font-weight: 400; + line-height: normal; + text-align: right; +`; + +export const ItemText = styled.div` + font-style: normal; + font-weight: 400; + line-height: normal; +`; + +export const QuantityText = styled.div` + font-style: normal; + font-weight: 400; + line-height: normal; + text-align: right; +`; + +export const InformationContainer = styled.div` + width: 730px; + height: 400px; + margin: 40px; +`; + +export const InformationText = styled.div` + width: 730px; + height: 50px; + border-radius: 4px; + margin-top: 14px; + margin-bottom: 14px; + border: 1px solid ${COLORS.neutralGrey}; + background: ${COLORS.lightGrey}; + display: flex; /* Use flexbox */ + align-items: center; /* Center vertically */ + font-size: 20px; + font-style: normal; + font-weight: 400; + line-height: normal; + padding-left: 20px; +`; + +export const OrderContainer = styled.div` + margin-top: 50px; + width: 350px; + height: 500px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +`; + +export const OrderSummary = styled.div` + width: 350px; + height: 360px; + border-radius: 8px; + background: ${COLORS.white}; + box-shadow: 0px 1px 4px 1px rgba(0, 0, 0, 0.15); + align-items: center; +`; + +export const ItemQuantityContainer = styled.div` + padding-top: 200px + width: 300px; + height: 170px; + display: flex; + flex-direction: column; + overflow-y: auto; + align-items: center; + justify-content: center; +`; + +export const ItemQuantityRow = styled.div` + width: 285px; + height: 25px; + display: flex; + justify-content: space-between; + margin-bottom: 30px; +`; + +export const TotalContainer = styled.div` + width: 350px; + height: 75px; + border-top: 1px solid black; + display: flex; + align-items: center; + justify-content: center; +`; + +export const OrderButton = styled.button` + margin-top: 26px; + width: 350px; + height: 50px; + flex-shrink: 0; + align-items: center; + background: ${COLORS.navy}; + border-radius: 8px; + color: ${COLORS.white}; + font-size: 20px; + font-family: 'Public Sans', sans-serif; + font-style: normal; + font-weight: 700; + line-height: normal; +`; + +export const NavBarMovedUP = styled(NavBar)` + position: static; +`; + +export const BackButtonDiv = styled.div` + display: flex; + flex-direction: row; + text-align: left; + width: 800px; + margin-left: 40px; +`; + +export const OutterDiv = styled.div` + display: flex; + flex-direction: column; +`; diff --git a/src/app/favicon.ico b/src/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..718d6fea4835ec2d246af9800eddb7ffb276240c GIT binary patch literal 25931 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 LrJugUA?W`A8`#=m literal 0 HcmV?d00001 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 new file mode 100644 index 00000000..6c00e83a --- /dev/null +++ b/src/app/favorites/page.tsx @@ -0,0 +1,46 @@ +'use client'; + +import { useState, useEffect } from 'react'; +import { Heading1 } from '@/styles/fonts'; +import BackButton from '../../components/BackButton/BackButton'; + +import { arrayOfFavorites } from '../../api/supabase/queries/user_queries'; + +import NavBar from '../../components/NavBarFolder/NavBar'; + +import { OutterFavoriteDiv, OutterBox, Fullscreen } from './styles'; +import IndividualItem from './individualItem'; + +import { Product } from '../../schema/schema'; + +export default function FavoritesPage() { + const [Favorites, setFavorites] = useState([]); + + async function fetchProducts() { + const data = (await arrayOfFavorites()) as Product[]; + setFavorites(data); + } + useEffect(() => { + fetchProducts(); + }, []); + + return ( + + + + + Favorites + + {Favorites.map(favorite => ( + + ))} + + + + ); +} diff --git a/src/app/favorites/styles.ts b/src/app/favorites/styles.ts new file mode 100644 index 00000000..479119e8 --- /dev/null +++ b/src/app/favorites/styles.ts @@ -0,0 +1,132 @@ +import styled from 'styled-components'; + +import { Heart } from 'react-feather'; +import Link from 'next/link'; +import COLORS from '@/styles/colors'; + +import NavBar from '../../components/NavBarFolder/NavBar'; + +export const FavoriteDiv = styled.div` + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-around; + width: 100%; + margin-bottom: 50px; + margin-top: 30px; +`; + +export const OutterFavoriteDiv = styled.div` + display: flex; + flex-direction: column; + align-items: center; + border-radius: 10px; + background: var(--White, #fff); + box-shadow: 0px 1px 4px 1px rgba(0, 0, 0, 0.2); + width: 800px; + height: 650px; + overflow: scroll; + margin-top: 10px; +`; + +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; +`; + +export const OutterBox = styled.div` + width: 800px; + height: 100%; + margin-top: 40px; + display: flex; + flex-direction: column; + gap: 20px; + margin-bottom: 20px; +`; + +export const Backtext = styled.p` + padding-top: 5px; +`; + +export const HeartIcon = styled(Heart)` + color: #333286; + width: 30px; + height: 30px; + fill: #333286; + margin-right: 25px; + margin-bottom: 40px; +`; + +export const TransparentButton = styled.button` + background-color: transparent; + border: transparent; + 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; +`; + +export const ProductNameDiv = styled.div` + width: 350px; +`; + +export const ViewItem = styled.button` + background: #1b3679; + color: #fbfbfb; + text-align: center; + width: 132px; + height: 28px; + flex-shrink: 0; + margin-top: 26px; + padding-top: 3px; + padding-right: 10px; + padding-left: 10px; + padding-bottom: 3px; + border: none; + border-radius: 5px; + line-height: normal; + border-radius: 14px; +`; + +export const Fullscreen = styled.div` + width: 100vw; + height: 100%; + display: flex; + flex-direction: column; + align-items: center; +`; + +export const ImageLinkWrapper = styled(Link)` + width: 100px; + height: 100px; + background-color: ${COLORS.lightGrey}; + padding: 32px; + margin-bottom: 8px; + display: flex; + justify-content: center; + align-items: center; + box-shadow: 1px 1px 4px 1px rgba(0, 0, 0, 0.1); +`; diff --git a/src/app/globals.css b/src/app/globals.css new file mode 100644 index 00000000..5b0dbd13 --- /dev/null +++ b/src/app/globals.css @@ -0,0 +1,106 @@ +:root { + --max-width: 1100px; + --border-radius: 12px; + --font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', + 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', + 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace; + + --foreground-rgb: 0, 0, 0; + --background-start-rgb: 214, 219, 220; + --background-end-rgb: 255, 255, 255; + + --primary-glow: conic-gradient( + from 180deg at 50% 50%, + #16abff33 0deg, + #0885ff33 55deg, + #54d6ff33 120deg, + #0071ff33 160deg, + transparent 360deg + ); + --secondary-glow: radial-gradient( + rgba(255, 255, 255, 1), + rgba(255, 255, 255, 0) + ); + + --tile-start-rgb: 239, 245, 249; + --tile-end-rgb: 228, 232, 233; + --tile-border: conic-gradient( + #00000080, + #00000040, + #00000030, + #00000020, + #00000010, + #00000010, + #00000080 + ); + + --callout-rgb: 238, 240, 241; + --callout-border-rgb: 172, 175, 176; + --card-rgb: 180, 185, 188; + --card-border-rgb: 131, 134, 135; +} + +@media (prefers-color-scheme: dark) { + :root { + --foreground-rgb: 255, 255, 255; + --background-start-rgb: 0, 0, 0; + --background-end-rgb: 0, 0, 0; + + --primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0)); + --secondary-glow: linear-gradient( + to bottom right, + rgba(1, 65, 255, 0), + rgba(1, 65, 255, 0), + rgba(1, 65, 255, 0.3) + ); + + --tile-start-rgb: 2, 13, 46; + --tile-end-rgb: 2, 5, 19; + --tile-border: conic-gradient( + #ffffff80, + #ffffff40, + #ffffff30, + #ffffff20, + #ffffff10, + #ffffff10, + #ffffff80 + ); + + --callout-rgb: 20, 20, 20; + --callout-border-rgb: 108, 108, 108; + --card-rgb: 100, 100, 100; + --card-border-rgb: 200, 200, 200; + } +} + +* { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +html, +body { + max-width: 100vw; + min-height: 100vh; +} +button { + &:hover { + cursor: pointer; + } +} +body { + background: white; + color: black; +} + +a { + color: inherit; + text-decoration: none; +} + +@media (prefers-color-scheme: dark) { + html { + color-scheme: dark; + } +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx new file mode 100644 index 00000000..42fb4ff2 --- /dev/null +++ b/src/app/layout.tsx @@ -0,0 +1,23 @@ +import './globals.css'; +import type { Metadata } from 'next'; +// eslint-disable-next-line camelcase +import { Public_Sans } from 'next/font/google'; + +const publicSans = Public_Sans({ subsets: ['latin'] }); + +export const metadata: Metadata = { + title: 'Shanti Project', + description: 'Application Created by Blueprint', +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + {children} + + ); +} diff --git a/src/app/login/page.tsx b/src/app/login/page.tsx new file mode 100644 index 00000000..aeff396f --- /dev/null +++ b/src/app/login/page.tsx @@ -0,0 +1,99 @@ +'use client'; + +import { useState } from 'react'; + +import Image from 'next/image'; +import supabase from '@/api/supabase/createClient'; +import { Body1, Heading1 } from '@/styles/fonts'; +import LoginForm from '../../components/LoginFormFolder/LoginForm'; + +import { + Fullscreen, + LoginBox, + LoginContent, + WelcomeSign, + Button, + ErrorMessage, + EyeOffIcon, + EyeIcon, +} from './styles'; + +export default function App() { + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + const [errorMessage, setErrorMessage] = useState(''); + const [isError, setIsError] = useState(false); + const [showPassword, setShowPassword] = useState(false); + + const handleLogin = async () => { + const { error } = await supabase.auth.signInWithPassword({ + email, + password, + }); + + setErrorMessage(''); + + if (error) { + setErrorMessage('Incorrect email or password'); + setIsError(true); + } else { + window.location.href = '/storefront'; + } + }; + + async function applyFilter( + e: React.KeyboardEvent, + ) { + const keypressed = e.code; + if (keypressed === 'Enter') { + handleLogin(); + } + } + + + return ( + + logo pic + + + + Welcome + + + + {showPassword ? ( + setShowPassword(false)} + style={{ cursor: 'pointer' }} + /> + ) : ( + setShowPassword(true)} + style={{ cursor: 'pointer' }} + /> + )} + + {errorMessage && {errorMessage}} + + + + + ); +} diff --git a/src/app/login/styles.ts b/src/app/login/styles.ts new file mode 100644 index 00000000..03fb0708 --- /dev/null +++ b/src/app/login/styles.ts @@ -0,0 +1,89 @@ +import { EyeOff, Eye } from 'react-feather'; +import styled from 'styled-components'; +import COLORS from '../../styles/colors'; + +export const LoginBox = styled.div` + display: flex; + width: 500px; + height: 420px; + justify-self: center; + align-self: center; + background-color: ${COLORS.white}; + box-shadow: 0px 4px 7px 0px rgba(0, 0, 0, 0.1); + border-radius: 10px; +`; + +export const LoginContent = styled.div` + margin-left: 40px; + flex-direction: column; + align-self: center; + justify-self: center; + text-color: ${COLORS.black}; +`; + +export const Button = styled.button` + color: ${COLORS.white}; + width: 420px; + height: 40px; + border-radius: 8px; + background: ${COLORS.navy}; + border: transparent; +`; + +export const WelcomeSign = styled.div` + color: ${COLORS.navy}; +`; + +export const FormHeaders = styled.p` + color: ${COLORS.black}; + font-size: 18px; + font-style: normal; + font-weight: 400; + line-height: normal; + margin-top: 20px; + margin-bottom: 10px; +`; + +export const ErrorMessage = styled.div` + transform: translateY(-250%); + margin-bottom: 20px; + width: 420px; + color: ${COLORS.darkRed}; + text-align: left; + font-size: 13px; + font-style: normal; + font-weight: 300; + line-height: normal; + z-index: 0; + position: absolute; +`; + +export const EyeOffIcon = styled(EyeOff)` + stroke-width: 1.5; + width: 20px; + height: 20px; + color: ${COLORS.black}; + margin: 20px; + transform: translateY(-250%) translateX(1800%); +`; + +export const EyeIcon = styled(Eye)` + stroke-width: 1.5; + width: 20px; + height: 20px; + color: ${COLORS.black}; + margin: 20px; + transform: translateY(-250%) translateX(1800%); +`; + +export const Fullscreen = styled.div` + width: 100%; + height: 100vh; + display: grid; + background-color: ${COLORS.lightGrey}; +`; + +export const InputField = styled.div` + position: relative; + background-color: ${COLORS.lightGrey}; +`; diff --git a/src/app/orderConfirmationDelivery/page.tsx b/src/app/orderConfirmationDelivery/page.tsx new file mode 100644 index 00000000..1652742e --- /dev/null +++ b/src/app/orderConfirmationDelivery/page.tsx @@ -0,0 +1,176 @@ +'use client'; + +import { useState, useEffect } from 'react'; +import { + fetchUser, + fetchCurrentUserAddress, +} from '@/api/supabase/queries/user_queries'; + +import { + Body1, + Body2, + Body2Light, + Heading3Bold, + Heading4Bold, +} from '@/styles/fonts'; +import { useSearchParams } from 'next/navigation'; +import { + DeliveryTimes, + fetchDeliveryTimes, +} from '@/api/supabase/queries/delivery_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, +} from './styles'; + +import { Product, User, Address } from '../../schema/schema'; +import { Body1Bold } from '../orderPage/styles'; +import { BackButtonDiv } from '../orderConfirmationPickUp/styles'; + +export default function OrderConfirmationDelivery() { + const [Cart, setCart] = useState([]); + const [user, setUser] = useState(); + 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[]; + setCart(cartItems); + } + + async function setUserDetails() { + const fetchedUser = await fetchUser(); + setUser(fetchedUser); + 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) - 1]} ${date[2]}, ${ + date[0] + }`; + return `${dateStr}`; + } + + return ( +
+ + + + + + + + + + Your order has been submitted + + Order No. {orderIDFromSearch} + + {Cart.map(cartItem => ( + + {cartItem.name} + +
+ + Quantity: + + + {cartItem.quantity} + +
+
+ + + Quantity: {cartItem.quantity} + + +
+ ))} +
+
+
+ + + Delivery Information + Estimated Date + {organizeDelivTime()} + Location + + {userAddress?.street}, {userAddress?.city},{' '} + {userAddress?.zipcode} + + + +
+
+
+
+ ); +} diff --git a/src/app/orderConfirmationDelivery/styles.ts b/src/app/orderConfirmationDelivery/styles.ts new file mode 100644 index 00000000..618a5919 --- /dev/null +++ b/src/app/orderConfirmationDelivery/styles.ts @@ -0,0 +1,247 @@ +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: 123px; +`; + +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); +`; diff --git a/src/app/orderConfirmationPickUp/page.tsx b/src/app/orderConfirmationPickUp/page.tsx new file mode 100644 index 00000000..9a93cb72 --- /dev/null +++ b/src/app/orderConfirmationPickUp/page.tsx @@ -0,0 +1,158 @@ +'use client'; + +import { useState, useEffect } from 'react'; + +import { fetchUser } from '@/api/supabase/queries/user_queries'; +import { fetchPickupTimesByID } from '@/api/supabase/queries/pickup_queries'; +import { getOrderById } from '@/api/supabase/queries/order_queries'; +import { + Body1, + Body1Bold, + Body2Light, + Heading3Bold, + Heading4Bold, +} from '@/styles/fonts'; +import { useSearchParams } from 'next/navigation'; +import { fetchCartItemsWithQuantityByID } from '../../api/supabase/queries/cart_queries'; + +import BackButton from '../../components/BackButton/BackButton'; + +import NavBar from '../../components/NavBarFolder/NavBar'; + +import { + TextDiv, + TextDiv1, + BackButtonDiv, + FavoriteDiv, + OutterFavoriteDiv, + LabelBox, + LabelBox1, + ScrollDiv, + ShippingDetailsDiv, + ImageDiv, + BottomColumnDiv, + Wrapper, + LeftColumnDiv, + RightColumnDiv, + DetailsHeader, + PageDiv, + CenterDiv, +} from './styles'; + +import { Product, User, Pickup } from '../../schema/schema'; + +export default function OrderConfirmationPickUp() { + const [Cart, setCart] = useState([]); + const [user, setUser] = useState(); + const [pickupTime, setPickupTime] = useState(); + const searchParams = useSearchParams(); + const orderIDFromSearch = searchParams.get('orderID'); + + useEffect(() => { + async function fetchProducts() { + const cartItems = (await fetchCartItemsWithQuantityByID( + orderIDFromSearch, + )) as Product[]; + setCart(cartItems); + } + + async function setUserDetails() { + const fetchedUser = await fetchUser(); + setUser(fetchedUser); + const currOrder = await getOrderById(Number(orderIDFromSearch)); + const pickup = await fetchPickupTimesByID(currOrder.pickup_time_id); + setPickupTime(pickup); + } + + fetchProducts(); + setUserDetails(); + }, []); + + function organizePickupTime() { + const startTime = pickupTime?.start_time.toLocaleString(); + const date = + startTime == null + ? ['0', '0', '0'] + : startTime?.substring(0, 10).split('-'); + const dateStr = `${date[1]}/${date[2]}/${date[0]}`; + return `${dateStr}`; + } + + return ( +
+ + + + + + + + + + Your order has been submitted + + + + Order No. {orderIDFromSearch} + + + {Cart.map(cartItem => ( + + + {cartItem.name} + + + {cartItem.name} +
+ + Category: {cartItem.category} + +
+ +
+ + Quantity: + + + {cartItem.quantity} + +
+
+
+ ))} +
+
+
+ + + Pickup Information + Time Slot + {organizePickupTime()} (10:00 am - 12:30 pm) + Location + 3170 23rd Street, San Francisco, CA 94110 + + +
+
+
+
+ ); +} diff --git a/src/app/orderConfirmationPickUp/styles.ts b/src/app/orderConfirmationPickUp/styles.ts new file mode 100644 index 00000000..4f2e25a8 --- /dev/null +++ b/src/app/orderConfirmationPickUp/styles.ts @@ -0,0 +1,325 @@ +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: center; + justify-content: space-between; + width: 100%; + margin-bottom: 50px; + margin-top: 30px; + margin-right: 20px; +`; + +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: 800px; + max-height: 100%; + margin-top: 20px; + margin-right: 60px; + margin-left: 60px; + padding-right: 20px; + padding-left: 10px; + padding-top: 10px; +`; + +export const ScrollDiv = styled.div` + overflow: scroll; + width: 100%; +`; + +export const ImageDiv = styled.div` + box-shadow: 1px 1px 4px 1px rgba(0, 0, 0, 0.08); + width: 150px; + height: 150px; + margin-left: 30px; + display: flex; + justify-content: center; + align-items: center; +`; + +export const Wrapper = styled.div` + padding: 15px; + display: flex; + justify-content: center; + align-items: center; +`; + +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; +`; + +export const OutterBox = styled.div` + width: 900px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +`; + +export const CenterBox = styled.div` + display: flex; + justify-content: 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: 20px; +`; + +export const LabelBox1 = styled.div` + width: 250px; + height: 100%; + padding: 20px; +`; + +export const LabelBox = styled.div` + width: 150px; + height: 100%; + padding: 20px; + gap: 50px; + margin-right: 30px; +`; + +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 AddressText = styled.p` + color: var(--Black, #101010); + font-family: Public Sans; + font-size: 17px; + font-style: normal; + font-weight: 400; + line-height: normal; + margin-bottom: 20px; + margin-left: 45px; +`; + +export const DateText = styled.p` + color: var(--Black, #101010); + margin-top: 20px; + margin-left: 45px; + + font-family: Public Sans; + font-size: 25px; + font-style: normal; + font-weight: 700; + line-height: normal; + text-decoration-line: underline; +`; + +export const PickUpText = styled.p` + color: var(--Marine-Blue, #333286); + text-align: right; + /* Body 2 - Bold */ + font-family: Public Sans; + font-size: 15px; + font-style: normal; + font-weight: 700; + line-height: normal; + margin-top: 15px; +`; + +export const ColDiv = styled.div` + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + width: 750px; +`; + +export const AddressDiv = styled.div` + position: relative; + display: flex; + align-items: flex-end; +`; + +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` + display: flex; + flex-flow: column; + justify-content: space-evenly; + align-items: space-evenly; + width: 100%; +`; +export const RightColumnDiv = styled.div` + display: flex; + flex-flow: column; + align-items: start; + margin-left: 10px; + width: 100%; +`; + +export const BackButtonDiv = styled.div` + display: flex; + flex-direction: row; + text-align: left; + width: 800px; + margin-left: 80px; + margin-top: 40px; +`; + +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 BottomColumnDiv = styled.div` + display: flex; + flex-direction: row; + align-items: space-evenly; + justify-content: space-around; + width: 100%; + margin-left: 20px; + margin-bottom: 30px; + gap: 30px; +`; + +export const TextDiv = styled.div` + display: flex; + flex-direction: row; + margin-left: 60px; + margin-top: 20px; + margin-bottom: 20px; +`; + +export const TextDiv1 = styled.div` + display: flex; + flex-direction: row; + padding: 10px; + margin-left: 20px; + margin-top: 15px; +`; + +export const PageDiv = styled.div` + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: flex-start; + width: 100%; +`; + +export const ShippingDetailsDiv = 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: 467px; + height: auto; + max-height: 100%; + padding: 36px 34px; + gap: 33px; + max-height: 100%; + margin-top: 205px; + margin-bottom: 30px; + margin-right: 40px; +`; + +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 CenterDiv = styled.div` + display: flex; + align-items: center; + justify-content: center; + width: 100%; + padding: 20px; +`; diff --git a/src/app/orderHistory/page.tsx b/src/app/orderHistory/page.tsx new file mode 100644 index 00000000..e02c8e1e --- /dev/null +++ b/src/app/orderHistory/page.tsx @@ -0,0 +1,51 @@ +'use client'; + +import React, { useEffect, useState } from 'react'; +import { Heading1, Body1 } from '@/styles/fonts'; +import OrderDetailsWithProducts from '../../components/OrderHistory/OrderHistoryBox'; +import { fetchOrderIdsByUserIdSorted } from '../../api/supabase/queries/order_queries'; +import Footer from '../../components/FooterFolder/Footer'; +import { + OrderHistoryContainer, + OutterBox, + NavBarMovedUP, + Fullscreen, +} from './styles'; +import BackButton from '../../components/BackButton/BackButton'; + +function OrderHistory() { + const [orderIds, setOrderIds] = useState([]); + + useEffect(() => { + const fetchIds = async () => { + const ids = await fetchOrderIdsByUserIdSorted(); + setOrderIds(ids); + }; + + fetchIds(); + }, []); + + return ( + + + + +
+ Order History +
+ + {orderIds.length > 0 ? ( + orderIds.map((orderId: number) => ( + + )) + ) : ( + No Order + )} + +
+