diff --git a/package-lock.json b/package-lock.json index e4e2d38..f2855d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,10 +11,10 @@ "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^13.0.0", "@testing-library/user-event": "^13.2.1", - "firebase": "^12.12.0", + "firebase": "^12.12.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-icons": "^4.4.0", + "react-icons": "^4.12.0", "react-router-dom": "^7.14.1", "react-scripts": "5.0.1", "web-vitals": "^2.1.0" @@ -64,7 +64,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.9.tgz", "integrity": "sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g==", "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", @@ -965,7 +964,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz", "integrity": "sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A==", "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.18.6" }, @@ -1568,7 +1566,6 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.18.6.tgz", "integrity": "sha512-Mz7xMPxoy9kPS/JScj6fJs03TZ/fZ1dJPlMjRAgTaxaS0fUBk8FV/A2rRgfPsVCZqALNwMexD+0Uaf5zlcKPpw==", "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.18.6", "@babel/helper-module-imports": "^7.18.6", @@ -2343,9 +2340,9 @@ } }, "node_modules/@firebase/ai": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-2.11.0.tgz", - "integrity": "sha512-+oqOne/h5J51LezazR+VyzKe3AK455W29JXnb4jOeVvQhC7FymledN5+XE+w5vEcMhRQ6n1f62fdGs4A44X32A==", + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/@firebase/ai/-/ai-2.11.1.tgz", + "integrity": "sha512-WGTF81W3WBKJY+c7xqTzO15OGAkCAs8cpADqflAI0skhTZjIkhF0qyf55rq4Ctt6jKygkv99rPfMrjAHTgXaVQ==", "license": "Apache-2.0", "dependencies": { "@firebase/app-check-interop-types": "0.3.3", @@ -2405,7 +2402,6 @@ "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.14.11.tgz", "integrity": "sha512-yxADFW35LYkP8oSGobGsYIrI42I+GPCvKTNHx4meT9Yq3C950IVz1eANoBk822I9tbKv1wyv9P4Bv1G5TpucFw==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@firebase/component": "0.7.2", "@firebase/logger": "0.5.0", @@ -2472,7 +2468,6 @@ "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.5.11.tgz", "integrity": "sha512-KaACDjXkK5VLpI01vEs592R7/8s5DjFdIXfKoR385ly1SmK3Tu+jMHCIB4MsiY5jsez6v7VlEX/3rJ90dVkHyA==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@firebase/app": "0.14.11", "@firebase/component": "0.7.2", @@ -2489,7 +2484,6 @@ "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.4.tgz", "integrity": "sha512-crX9TA5SVYZwLPG7/R16IsH8FLlgkPXjJUVhsVpHVDSqJiq3D/NuFTM5ctxGTExXAOeIn//69tQw47CPerM8MQ==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@firebase/logger": "0.5.0" } @@ -2949,7 +2943,6 @@ "integrity": "sha512-AmWf3cHAOMbrCPG4xdPKQaj5iHnyYfyLKZxwz+Xf55bqKbpAmcYifB4jQinT2W9XhDRHISOoPyBOariJpCG6FA==", "hasInstallScript": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "tslib": "^2.1.0" }, @@ -4541,7 +4534,8 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/babel__core": { "version": "7.1.19", @@ -4944,7 +4938,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.7.tgz", "integrity": "sha512-l4L6Do+tfeM2OK0GJsU7TUcM/1oN/N25xHm3Jb4z3OiDU4Lj8dIuxX9LpVMS9riSXQs42D1ieX7b85/r16H9Fw==", "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.30.7", "@typescript-eslint/type-utils": "5.30.7", @@ -4997,7 +4990,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.7.tgz", "integrity": "sha512-Rg5xwznHWWSy7v2o0cdho6n+xLhK2gntImp0rJroVVFkcYFYQ8C8UJTSuTw/3CnExBmPjycjmUJkxVmjXsld6A==", "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.30.7", "@typescript-eslint/types": "5.30.7", @@ -5349,7 +5341,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5469,7 +5460,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -6278,7 +6268,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001366", "electron-to-chromium": "^1.4.188", @@ -6985,7 +6974,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -7944,7 +7932,6 @@ "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "license": "MIT", - "peer": true, "dependencies": { "@eslint/eslintrc": "^1.3.0", "@humanwhocodes/config-array": "^0.9.2", @@ -8445,7 +8432,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -9240,12 +9226,12 @@ } }, "node_modules/firebase": { - "version": "12.12.0", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-12.12.0.tgz", - "integrity": "sha512-5Ap+pN5iEJUvBlQEZEmLuUm7Gvu6I5xv1jZ5SiSNyw4jrwlHo+4tmZv3OPPoKfN9eo1kBwyyBvi+pWHIPXwfYw==", + "version": "12.12.1", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-12.12.1.tgz", + "integrity": "sha512-ee7xA+bTJLfjB9BP/8FQr3EkxmpAAGc1lNc5QkWgTDpUw24HYXFPm7FEWRdLtGnygxIdYpFmepSc5VjkI6NHhw==", "license": "Apache-2.0", "dependencies": { - "@firebase/ai": "2.11.0", + "@firebase/ai": "2.11.1", "@firebase/analytics": "0.10.21", "@firebase/analytics-compat": "0.2.27", "@firebase/app": "0.14.11", @@ -10851,7 +10837,6 @@ "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^27.5.1", "import-local": "^3.0.2", @@ -13698,7 +13683,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -14503,7 +14487,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -15624,7 +15607,6 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -16008,7 +15990,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -16164,7 +16145,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" @@ -16180,9 +16160,9 @@ "license": "MIT" }, "node_modules/react-icons": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.4.0.tgz", - "integrity": "sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz", + "integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==", "license": "MIT", "peerDependencies": { "react": "*" @@ -16199,7 +16179,6 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -16682,7 +16661,6 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.0.tgz", "integrity": "sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g==", "license": "MIT", - "peer": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -18038,7 +18016,6 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "license": "(MIT OR CC0-1.0)", - "peer": true, "engines": { "node": ">=10" }, @@ -18380,7 +18357,6 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz", "integrity": "sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==", "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -18451,7 +18427,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -18505,7 +18480,6 @@ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.3.tgz", "integrity": "sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw==", "license": "MIT", - "peer": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -18561,7 +18535,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -18903,7 +18876,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", diff --git a/package.json b/package.json index 591cbbe..0ca0fb1 100644 --- a/package.json +++ b/package.json @@ -6,10 +6,10 @@ "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^13.0.0", "@testing-library/user-event": "^13.2.1", - "firebase": "^12.12.0", + "firebase": "^12.12.1", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-icons": "^4.4.0", + "react-icons": "^4.12.0", "react-router-dom": "^7.14.1", "react-scripts": "5.0.1", "web-vitals": "^2.1.0" diff --git a/src/App.js b/src/App.js index 2033c26..f598e43 100644 --- a/src/App.js +++ b/src/App.js @@ -1,15 +1,27 @@ import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import { AuthProvider } from './context/AuthContext'; import { AppProvider } from './context/AppContext'; +import ToastContainer from './components/ToastContainer'; import LoginPage from './pages/LoginPage'; import RegisterPage from './pages/RegisterPage'; +import Navbar from './components/Navbar'; + +import Hero from './components/Hero'; +import HeadlineCards from './components/HeadlineCards'; +import Food from './components/Food'; +import Category from './components/Category'; // Main page layout — all the existing components together function MainLayout() { return ( -
-

Welcome to HackUTD's Devday!

+
+ + + + + +
); } diff --git a/src/components/Category.jsx b/src/components/Category.jsx index e3ada3a..d4a57a2 100644 --- a/src/components/Category.jsx +++ b/src/components/Category.jsx @@ -18,7 +18,18 @@ const Category = () => { }, []); return ( -
+
+

+ Eat What Makes You Happy +

+
+ {categories.map((item, index) => ( +
+

{item.name}

+ {item.name} +
+ ))} +
); }; diff --git a/src/components/Food.jsx b/src/components/Food.jsx index d7bc4cc..543fe2a 100644 --- a/src/components/Food.jsx +++ b/src/components/Food.jsx @@ -1,6 +1,7 @@ import React, { useState, useEffect, useContext } from 'react'; import { AppContext } from '../context/AppContext'; import { AiFillHeart, AiOutlineHeart } from 'react-icons/ai'; +// import {data} from '../data/data.js'; // Backend pricing constants const CATEGORY_PRICES = { Chicken: '$$', Beef: '$$$', Pasta: '$$', Seafood: '$$$$' }; @@ -8,13 +9,11 @@ const INITIAL_CATEGORIES = Object.keys(CATEGORY_PRICES); const Food = () => { const [foods, setFoods] = useState([]); - const [ingredientSearchQuery, setIngredientSearchQuery] = useState(''); - const [isSearching, setIsSearching] = useState(false); const { favorites, toggleFavorite } = useContext(AppContext); // Fetch initial menu from TheMealDB + useEffect(() => { const fetchInitialFoods = async () => { - setIsSearching(true); try { const results = await Promise.all( INITIAL_CATEGORIES.map((cat) => @@ -23,7 +22,7 @@ const Food = () => { .then((d) => (d.meals || []).slice(0, 4).map((meal) => ({ id: meal.idMeal, - name: meal.strMeal, + namefet: meal.strMeal, image: meal.strMealThumb, price: CATEGORY_PRICES[cat], })) @@ -31,16 +30,49 @@ const Food = () => { ) ); setFoods(results.flat()); + console.log('Initial foods fetched:', results.flat()); } catch (error) { console.error('Error fetching initial foods:', error); } - setIsSearching(false); }; + fetchInitialFoods(); +}, []); return ( -
- +
+

+ Top Rated Menu Items +

+
+ {foods.map((item, index) => { + const isFav = favorites.some(f => f.id === item.id || f.name === item.namefet); + return ( +
+
+ +
+ < img src = {item.image} alt = {item.name} className='w-full h-[200px] object-cover rounded-t-lg'/> +
+

{item.namefet}

+

+ {item.price} +

+
+
+ );})} +
+ ); }; diff --git a/src/components/HeadlineCards.jsx b/src/components/HeadlineCards.jsx index 8e8717b..f195d6f 100644 --- a/src/components/HeadlineCards.jsx +++ b/src/components/HeadlineCards.jsx @@ -2,7 +2,46 @@ import React from 'react'; const HeadlineCards = () => { return ( -
+
+ {/* First Card */} +
+ {/* Overlay */} +
+

Sun's Out, BOGO's Out

+

Through 8/26

+ +
+ / +
+ {/* Second Card */} +
+
+ {/* Overlay */} +

Spicy Chicken Sandwhich

+

Through 9/25

+ +
+ / +
+ {/* Third Card */} +
+
+ {/* Overlay */} +

Beef Patty

+

Through 4/9

+ +
+ / +
); }; diff --git a/src/components/Hero.jsx b/src/components/Hero.jsx index 4523189..907f287 100644 --- a/src/components/Hero.jsx +++ b/src/components/Hero.jsx @@ -2,7 +2,20 @@ import React from 'react'; const Hero = () => { return ( -
+
+
+
+

The Best +

+

Foods Delivered + +

+
+ / +
); }; diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index d82094f..2b64518 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -3,6 +3,12 @@ import { useNavigate } from 'react-router-dom'; import { useAuth } from '../context/AuthContext'; import { logoutUser } from '../firebase/auth'; +import { AiOutlineMenu, AiOutlineSearch, AiOutlineClose, AiFillTag } from 'react-icons/ai'; +import { BsFillCartFill, BsFillSaveFill } from 'react-icons/bs'; +import {TbTruckDelivery} from 'react-icons/tb'; +import {FaUserFriends, FaWallet} from 'react-icons/fa'; +import {MdFavorite, MdHelp} from 'react-icons/md'; + const Navbar = () => { const [nav, setNav] = useState(false); @@ -16,9 +22,90 @@ const Navbar = () => { } return ( -
+
+
+
setNav(!nav)} className = 'cursor-pointer'> + +
+

+ Best Eats +

+
+

Delivery

+

Pickup

+
+
+ +
+ + +
+ +
+ +
+ + {currentUser ? ( +
+ + {currentUser.email} + + + +
+ ) : ( + + ) + } + + {/* Mobile Menu */} + {/* Overlay */} + {nav ?
+ {/* Side drawer menu */} + +
+ setNav(!nav)} size={30} className='absolute right-4 top-4 cursor-pointer'/> +

+ Best Eats +

+ + +
+
: ''} + +
+ ); }; diff --git a/src/components/ToastContainer.jsx b/src/components/ToastContainer.jsx index 36a15b5..6339a61 100644 --- a/src/components/ToastContainer.jsx +++ b/src/components/ToastContainer.jsx @@ -1,8 +1,15 @@ -import React from 'react'; +import React, {useContext} from 'react'; +import { AppContext } from '../context/AppContext'; const ToastContainer = () => { + const { toasts } = useContext(AppContext); return ( -
+
+ {toasts.map((toast) => ( +
+ {toast.message} +
+ ))}
); }; diff --git a/src/context/AppContext.js b/src/context/AppContext.js index 223c27d..b1350f8 100644 --- a/src/context/AppContext.js +++ b/src/context/AppContext.js @@ -39,14 +39,44 @@ export const AppProvider = ({ children }) => { }, [currentUser]); //toggleFavorite + const toggleFavorite = (food) => { + if (!currentUser){ + addToast('🔒 Log in to save favorites!'); + return; + } + + setFavorites((prev) => { + const exists = prev.some((f) => f.id === food.id || f.name === food.name); + let updated; + if (exists) { + updated = prev.filter((f) => f.id !== food.id && f.name !== food.name); + } else { + updated = [...prev, food]; + } + saveFavoritesToFirestore(updated); + return updated; + }); + }; // Toasts + const [toasts , setToasts] = useState([]); + const addToast = (message) => { + const id = Date.now(); + setToasts((prev) => [...prev, { id, message }]); + setTimeout(() => { + setToasts((prev) => prev.filter((toast) => toast.id !== id)); + }, 3000); + + } return ( {children} ); -}; \ No newline at end of file +}; diff --git a/yarn.lock b/yarn.lock index b7455c2..8d35fe3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1184,10 +1184,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@firebase/ai@2.11.0": - version "2.11.0" - resolved "https://registry.npmjs.org/@firebase/ai/-/ai-2.11.0.tgz" - integrity sha512-+oqOne/h5J51LezazR+VyzKe3AK455W29JXnb4jOeVvQhC7FymledN5+XE+w5vEcMhRQ6n1f62fdGs4A44X32A== +"@firebase/ai@2.11.1": + version "2.11.1" + resolved "https://registry.npmjs.org/@firebase/ai/-/ai-2.11.1.tgz" + integrity sha512-WGTF81W3WBKJY+c7xqTzO15OGAkCAs8cpADqflAI0skhTZjIkhF0qyf55rq4Ctt6jKygkv99rPfMrjAHTgXaVQ== dependencies: "@firebase/app-check-interop-types" "0.3.3" "@firebase/component" "0.7.2" @@ -4940,12 +4940,12 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -firebase@^12.12.0: - version "12.12.0" - resolved "https://registry.npmjs.org/firebase/-/firebase-12.12.0.tgz" - integrity sha512-5Ap+pN5iEJUvBlQEZEmLuUm7Gvu6I5xv1jZ5SiSNyw4jrwlHo+4tmZv3OPPoKfN9eo1kBwyyBvi+pWHIPXwfYw== +firebase@^12.12.1: + version "12.12.1" + resolved "https://registry.npmjs.org/firebase/-/firebase-12.12.1.tgz" + integrity sha512-ee7xA+bTJLfjB9BP/8FQr3EkxmpAAGc1lNc5QkWgTDpUw24HYXFPm7FEWRdLtGnygxIdYpFmepSc5VjkI6NHhw== dependencies: - "@firebase/ai" "2.11.0" + "@firebase/ai" "2.11.1" "@firebase/analytics" "0.10.21" "@firebase/analytics-compat" "0.2.27" "@firebase/app" "0.14.11" @@ -7935,10 +7935,10 @@ react-error-overlay@^6.0.11: resolved "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz" integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== -react-icons@^4.4.0: - version "4.4.0" - resolved "https://registry.npmjs.org/react-icons/-/react-icons-4.4.0.tgz" - integrity sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg== +react-icons@^4.12.0: + version "4.12.0" + resolved "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz" + integrity sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw== react-is@^16.13.1: version "16.13.1"