Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
</html>
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Binary file added public/images/avatar-placeholder.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 9 additions & 3 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
Thanks,
Favorites,
StoreDebug,
Profile,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Confirm the full destructured import from "./pages" in App.jsx includes `Orders`,
# and confirm both `Orders` bindings collide in the same module scope.
rg -n -B2 -A2 '^\s*Orders\b|from "\./pages"|from "\./pages/Profile"' src/App.jsx

Repository: Revive-Graduation-Project/Revive-Front-End

Length of output: 485


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '1,120p' src/App.jsx | nl -ba | sed -n '1,120p'

Repository: Revive-Graduation-Project/Revive-Front-End

Length of output: 220


🏁 Script executed:

#!/bin/bash
set -euo pipefail
awk '{printf "%4d  %s\n", NR, $0}' src/App.jsx | sed -n '1,140p'

Repository: Revive-Graduation-Project/Revive-Front-End

Length of output: 4321


Alias the profile Orders import src/App.jsx:24,68,98 imports Orders twice in the same module (./pages and ./pages/Profile), which creates a duplicate binding and breaks compilation. Rename one import, e.g. Orders as ProfileOrders, and use that in the /profile/orders route.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/App.jsx` at line 15, There is a duplicate Orders binding in App that
breaks compilation because src/App.jsx imports Orders from both ./pages and
./pages/Profile. Update the import from ./pages/Profile to use a distinct alias
such as ProfileOrders, then use that aliased symbol in the /profile/orders route
so the module has unique bindings throughout App.

Dashboard,
Orders,
RecipeBuilder,
Expand All @@ -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";
Expand Down Expand Up @@ -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. */}
<Route path="/" element={<AppLayout />}>

{/* Public routes */}
Expand All @@ -60,8 +62,12 @@ export default function App() {
<Route path="checkout" element={<Checkout />} />
<Route path="payment" element={<Payment />} />
<Route path="thanks" element={<Thanks />} />
{/* remove the text when the profile is ready */}
<Route path="profile" element={<ProtectedRoute><div className="min-h-screen flex items-center justify-center text-xl text-gray-500">Profile page coming soon</div></ProtectedRoute>} />

<Route path="profile" element={<ProtectedRoute><ProfileLayout /></ProtectedRoute>}>
<Route index element={<Profile />} />
<Route path="orders" element={<ProfileOrders />} />
<Route path="rewards" element={<Rewards />} />
</Route>

</Route>

Expand Down
9 changes: 8 additions & 1 deletion src/Layout/AppLayout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<div className="min-h-screen bg-center bg-cover">
<div className="min-h-screen bg-center bg-cover">
<Navbar />
<SideCartDrawer />
<Toaster
position="top-right"
richColors
expand={false}
duration={3000}
/>
{/* navbar will only be displayed on app pages */}
<Outlet /> {/* This is where child routes will be rendered */}
<Footer /> {/* footer will only be displayed on app pages */}
Expand Down
59 changes: 44 additions & 15 deletions src/components/layout/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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.
Expand All @@ -41,19 +50,26 @@ 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 (
<nav className="bg-gray-50 fixed inset-x-0 z-10 flex flex-wrap p-3 gap-y-3">
<nav className="bg-gray-50 fixed inset-x-0 z-30 flex flex-wrap p-3 gap-y-3">

{/* ── Top bar: Logo · Search · Actions ── */}
<div className="w-full flex flex-wrap p-3 gap-y-2 justify-around items-center">

{/* Branding */}
<h1 className="grow text-center">
<Link to="/">
<span className="branding-title text-3xl md:text-4xl text-(--color-orange)">
<span className="branding-title text-3xl md:text-4xl text-orange">
Re
</span>
<span className="branding-title text-3xl md:text-4xl text-(--color-green)">
<span className="branding-title text-3xl md:text-4xl text-green">
vive
</span>
</Link>
Expand All @@ -69,7 +85,7 @@ function Navbar() {
/* ── Authenticated: Profile icon ── */
<Link
to="/profile"
className="text-(--color-green) flex items-center gap-x-2 group transition-colors"
className="text-green flex items-center gap-x-2 group transition-colors"
title="View your profile"
>
<FaUserCircle className="text-3xl transform group-hover:rotate-360 duration-500" />
Expand All @@ -79,7 +95,7 @@ function Navbar() {
/* ── Guest: Login link ── */
<Link
to="/auth/login"
className="text-(--color-green) flex items-center gap-x-2 group transition-colors"
className="text-green flex items-center gap-x-2 group transition-colors"
>
<FaUserCircle className="text-3xl transform group-hover:rotate-360 duration-500" />
<span className="text-xl tracking-tight font-medium">Login</span>
Expand Down Expand Up @@ -111,12 +127,13 @@ function Navbar() {
<button
onClick={() => setIsMoreOpen((prev) => !prev)}
className={`${
isMoreOpen ? "active-navlink" : ""
activeMoreLink || isMoreOpen ? "active-navlink" : ""
} hover:text-green p-2 flex items-center gap-1 cursor-pointer`}
aria-haspopup="true"
aria-expanded={isMoreOpen}
>
More
{/* Show active link name when inside a More route, otherwise "More" */}
{activeMoreLink ? activeMoreLink.label : "More"}
<MdOutlineKeyboardArrowDown
className={`text-xl text-green transition-transform duration-300 ${
isMoreOpen ? "rotate-180" : ""
Expand All @@ -130,12 +147,24 @@ function Navbar() {
isMoreOpen ? "max-h-60 opacity-100" : "max-h-0 opacity-0"
} overflow-hidden transition-all duration-300 ease-in-out
md:absolute md:left-0 md:top-full md:mt-1
md:bg-white md:rounded-xl md:shadow-lg md:border md:border-gray-100 md:min-w-[200px]`}
md:bg-white md:rounded-xl md:shadow-lg md:border md:border-gray-100 md:min-w-50`}
>
{/* change it later */}
<span className="block px-4 py-3 text-gray-400 italic text-base">
this contains secondary sections
</span>
{/* Map over MORE_LINKS — add future links to the array above */}
{MORE_LINKS.map(({ to, label }) => (
<NavLink
key={to}
to={to}
className={({ isActive }) =>
`flex items-center gap-2 px-4 py-3 text-base hover:bg-gray-50 transition-colors ${
isActive ? "text-green font-semibold" : "text-gray-700"
}`
}
onClick={() => setIsMoreOpen(false)}
>
<FaUserCircle className="text-lg text-green" />
{label}
</NavLink>
))}
</div>
</div>

Expand All @@ -155,4 +184,4 @@ function Navbar() {
);
}

export default Navbar;
export default Navbar;
12 changes: 2 additions & 10 deletions src/components/ui/AllergiesDropdown.jsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="flex flex-col space-y-2">
Expand All @@ -17,7 +9,7 @@ function AllergiesDropdown() {

<div className="border border-orange rounded-2xl p-4 ">
<div className="grid grid-cols-1 gap-2 text-sm">
{options.map((option, index) => (
{HEALTH_CONDITIONS.map((option, index) => (
<label
key={index}
className="flex items-center gap-2 cursor-pointer"
Expand Down
30 changes: 30 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,33 @@ export const CURRENCY_SYMBOL = "$";
* @type {'PRE' | 'POST'}
*/
export const CURRENCY_FORMAT = "POST";

// Allergy and health condition options for user profiles
export const HEALTH_CONDITIONS = [
"Diabetes",
"High blood pressure",
"High cholesterol",
"Kidney or liver condition",
"Gluten intolerance / Celiac",
"Lactose intolerance",
];

// --- Health Profile Options ---
export const GENDER_OPTIONS = ["MALE", "FEMALE", "OTHER"];
export const GOAL_OPTIONS = ["LOSE_WEIGHT", "MAINTAIN", "GAIN_MUSCLE"];
export const HEIGHT_UNITS = ["m", "ft", "cm", "in"];
export const WEIGHT_UNITS = ["kg", "lb"];

// --- Order history (profile) ---
export const NON_CANCELLABLE_ORDER_STATUSES = [
"PREPARING",
"READY",
"CANCELED",
];
Comment on lines +58 to +62

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

NON_CANCELLABLE_ORDER_STATUSES omits CANCELED, allowing already-canceled orders to appear cancellable.

This array is the source powering isOrderCancellable in src/utils/orderHelpers.js (Line 50: return !NON_CANCELLABLE_ORDER_STATUSES.includes(normalizeStatus(order.status));). Since CANCELED isn't in this list, an order already in CANCELED status would incorrectly evaluate as cancellable, exposing a "Cancel" action for orders that can no longer be canceled.

🐛 Proposed fix
 export const NON_CANCELLABLE_ORDER_STATUSES = [
   "PREPARING",
   "READY",
+  "CANCELED",
 ];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const NON_CANCELLABLE_ORDER_STATUSES = [
"PREPARING",
"READY",
];
export const NON_CANCELLABLE_ORDER_STATUSES = [
"PREPARING",
"READY",
"CANCELED",
];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/constants.js` around lines 58 - 61, Update NON_CANCELLABLE_ORDER_STATUSES
in constants.js to include CANCELED so isOrderCancellable in
src/utils/orderHelpers.js correctly treats already-canceled orders as not
cancellable. Keep the normalization flow unchanged and ensure the status list
used by includes(normalizeStatus(order.status)) covers every terminal
non-cancellable state.


export const ACTIVE_TRACKING_ORDER_STATUSES = [
"PENDING",
"CONFIRMED",
"PREPARING",
"READY",
];
28 changes: 25 additions & 3 deletions src/index.css
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
@import "tailwindcss";


@layer base {
button {
cursor: pointer;
}
}

:root {
@theme {
--color-green: #2e7d32;
--color-orange: #ff9800;
}
Expand All @@ -15,9 +15,9 @@ html {
font-family: "open-sans", sans-serif;
line-height: 2;
}

.branding-title {
font-weight: 700;
font-style: bold;
font-variation-settings: "wdth" 100;
letter-spacing: -2px;
}
Expand Down Expand Up @@ -99,6 +99,28 @@ html {
animation: float-fast 8s infinite ease-in-out;
}

@keyframes slideInRight {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}

@keyframes slideOutRight {
from {
transform: translateX(0);
opacity: 1;
}
to {
transform: translateX(100%);
opacity: 0;
}
}

.animate-shimmer {
animation: shimmer 2s infinite linear;
}
Expand Down
3 changes: 2 additions & 1 deletion src/mocks/enums.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export const ActivityLevel = {

export const OrderStatus = {
PENDING: "PENDING",
CONFIRMED: "CONFIRMED",
PREPARING: "PREPARING",
READY: "READY",
DELIVERED: "DELIVERED",
CANCELED: "CANCELED",
};
Loading