diff --git a/index.html b/index.html index 90979b4..31b2550 100644 --- a/index.html +++ b/index.html @@ -10,4 +10,4 @@
- + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 62f63bc..934bc5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "react-router": "^7.9.5", "react-router-dom": "^7.9.5", "recharts": "^3.8.1", + "sonner": "^2.0.7", "tailwindcss": "^4.1.17", "zod": "^4.3.6", "zustand": "^5.0.10" @@ -4648,6 +4649,16 @@ "dev": true, "license": "ISC" }, + "node_modules/sonner": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.7.tgz", + "integrity": "sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==", + "license": "MIT", + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", + "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", diff --git a/package.json b/package.json index ef2de1e..a385afb 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "react-icons": "^5.5.0", "react-router": "^7.9.5", "react-router-dom": "^7.9.5", + "sonner": "^2.0.7", "recharts": "^3.8.1", "tailwindcss": "^4.1.17", "zod": "^4.3.6", diff --git a/public/images/avatar-placeholder.jpeg b/public/images/avatar-placeholder.jpeg new file mode 100644 index 0000000..4f2791d Binary files /dev/null and b/public/images/avatar-placeholder.jpeg differ diff --git a/src/App.jsx b/src/App.jsx index 94b1478..1230f1f 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -12,6 +12,7 @@ import { Thanks, Favorites, StoreDebug, + Profile, Dashboard, Orders, RecipeBuilder, @@ -20,6 +21,7 @@ import { MenuManagement, Ingredients, } from "./pages"; +import { ProfileLayout, ProfileOrders, Rewards } from "./pages/Profile"; import { useAuthInit } from "./hooks/useAuthInit"; import Menu from "./pages/Menu/Menu"; import { useRestaurantInit } from "./hooks/useRestaurantInit"; @@ -47,7 +49,7 @@ export default function App() { {/* ── App Routes ── AppLayout (Navbar + Footer) wraps ALL app pages. Home and Menu are PUBLIC — no auth required. - All other routes are PROTECTED via ProtectedRoute. */} + All other routes are PROTECTED via ProtectedRoute. */} }> {/* Public routes */} @@ -60,8 +62,12 @@ export default function App() { } /> } /> } /> - {/* remove the text when the profile is ready */} -
Profile page coming soon
} /> + + }> + } /> + } /> + } /> + diff --git a/src/Layout/AppLayout.jsx b/src/Layout/AppLayout.jsx index e6f999e..59718d4 100644 --- a/src/Layout/AppLayout.jsx +++ b/src/Layout/AppLayout.jsx @@ -2,12 +2,19 @@ import Footer from "../components/layout/Footer"; import Navbar from "../components/layout/Navbar"; import { Outlet } from "react-router-dom"; import SideCartDrawer from "../components/OrderFlow/SideCartDrawer"; +import { Toaster } from "sonner"; function AppLayout() { return ( -
+
+ {/* navbar will only be displayed on app pages */} {/* This is where child routes will be rendered */}
{/* footer will only be displayed on app pages */} diff --git a/src/components/layout/Navbar.jsx b/src/components/layout/Navbar.jsx index 0393165..3903a38 100644 --- a/src/components/layout/Navbar.jsx +++ b/src/components/layout/Navbar.jsx @@ -1,4 +1,4 @@ -import { Link, NavLink } from "react-router"; +import { Link, NavLink, useLocation } from "react-router"; import Cart from "../UI/Cart"; import SearchBar from "./SearchBar"; import { FaUserCircle } from "react-icons/fa"; @@ -19,7 +19,16 @@ const ALL_NAV_LINKS = [ { to: "/favorites", label: "Favorites" }, ]; - +/* ───────────────────────────────────────────── + More dropdown links + Links that live permanently inside the "More" + dropdown because the main nav is already full. + The button label updates to reflect the active + link inside (e.g. "More" → "Profile"). +───────────────────────────────────────────── */ +const MORE_LINKS = [ + { to: "/profile", label: "Profile" }, +]; /** * Shared className resolver for NavLink — keeps active styling DRY. @@ -41,8 +50,15 @@ function Navbar() { // Read authentication state — used only for Login vs Profile button const isAuthenticated = useAuthStore((state) => state.isAuthenticated); + // Detect if the current route matches any link inside the More dropdown + // so the button label can reflect the active page (e.g. "More" → "Profile") + const location = useLocation(); + const activeMoreLink = MORE_LINKS.find((l) => + location.pathname.startsWith(l.to) + ); + return ( -
@@ -155,4 +184,4 @@ function Navbar() { ); } -export default Navbar; +export default Navbar; \ No newline at end of file diff --git a/src/components/ui/AllergiesDropdown.jsx b/src/components/ui/AllergiesDropdown.jsx index f72631f..e68e0f3 100644 --- a/src/components/ui/AllergiesDropdown.jsx +++ b/src/components/ui/AllergiesDropdown.jsx @@ -1,13 +1,5 @@ +import { HEALTH_CONDITIONS } from "../../constants"; function AllergiesDropdown() { - const options = [ - "None", - "Diabetes", - "High blood pressure", - "High cholesterol", - "Kidney or liver condition", - "Gluten intolerance / Celiac", - "Lactose intolerance", - ]; return (
@@ -17,7 +9,7 @@ function AllergiesDropdown() {
- {options.map((option, index) => ( + {HEALTH_CONDITIONS.map((option, index) => (