change the currency to EGP intead of $ and update the dashboard , liv… - #69
Conversation
…ekitchen , orders pages with backend api
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/store/orderStore.js (1)
432-432: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winUpdate error message currency from
$toEGP.The max-order-total error still says
10,000$while the rest of the PR migrates to EGP. This is a user-facing string that should be consistent.💚 Proposed fix
- throw new Error("Order total exceeds limit of 10,000$."); + throw new Error("Order total exceeds limit of 10,000 EGP.");🤖 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/store/orderStore.js` at line 432, The user-facing max-order-total error message still uses “$” instead of “EGP”, so update the string thrown in the order total limit check to match the new currency. Locate the error in the order total validation logic in orderStore and change the message in the relevant throw so it consistently says 10,000 EGP across the PR.
🧹 Nitpick comments (6)
src/components/Dashboard/DashboardHeader.jsx (2)
51-53: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
initialsis now dead code.The avatar rendering at lines 193-202 always uses an
<img>, soinitialsis no longer referenced anywhere in the component. Remove it to avoid confusion.♻️ Remove unused `initials`
- const initials = safeName - ? safeName.split(" ").map(n => n[0]).join("").substring(0, 2).toUpperCase() - : "U"; - const displaySubtitle = subtitle🤖 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/components/Dashboard/DashboardHeader.jsx` around lines 51 - 53, The `initials` value in `DashboardHeader` is now unused because the avatar render path always uses the `<img>` branch, so remove the dead `initials` computation from the component. Clean up the related logic near `safeName` and ensure no other references depend on `initials` in `DashboardHeader` or its avatar rendering flow.
33-42: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
rawNamederivation duplicates the same field-resolution pattern forprofileUserandauthUser.The 10-line expression repeats identical
name → fullName → firstName/lastNamelogic twice. Extracting a small helper would improve readability and make it easier to add new user sources.♻️ Proposed helper extraction
+ const resolveName = (u) => + u?.name || + u?.fullName || + (u?.firstName || u?.lastName + ? `${u?.firstName || ""} ${u?.lastName || ""}`.trim() + : "") || + ""; + const rawName = - profileUser?.name || - profileUser?.fullName || - (profileUser?.firstName || profileUser?.lastName ? `${profileUser?.firstName || ""} ${profileUser?.lastName || ""}`.trim() : "") || - authUser?.name || - authUser?.fullName || - (authUser?.firstName || authUser?.lastName ? `${authUser?.firstName || ""} ${authUser?.lastName || ""}`.trim() : "") || - authUser?.username || - authUser?.email?.split("@")[0] || - "Chef Admin"; + resolveName(profileUser) || + resolveName(authUser) || + authUser?.username || + authUser?.email?.split("@")[0] || + "Chef Admin";🤖 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/components/Dashboard/DashboardHeader.jsx` around lines 33 - 42, The rawName derivation in DashboardHeader.jsx repeats the same user-name fallback chain for profileUser and authUser, making it hard to read and maintain. Extract the shared name-resolution logic into a small helper (for example, a function that takes a user object and returns name/fullName/firstName-lastName/username/email prefix) and then use that helper for both profileUser and authUser in the rawName expression.src/components/ui/RegularFoodCard.jsx (1)
125-133: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider using
formatCurrencyfor price display.Both the strike-through and main price use inline
formatPrice(...) EGPinstead of the sharedformatCurrencyutility. WhileformatPricedoes calltoFixed(2), it strips trailing zeros (parseFloat(num.toFixed(2)).toString()), so12.00becomes"12"— inconsistent withformatCurrencywhich always shows 2 decimals.</review_comment_end -->
🤖 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/components/ui/RegularFoodCard.jsx` around lines 125 - 133, The price rendering in RegularFoodCard is using formatPrice directly for both the strike-through price and the main price, which causes inconsistent decimal display. Update the price display logic in RegularFoodCard to use the shared formatCurrency utility instead of formatPrice for these spans, and ensure both the discounted and original prices render with consistent 2-decimal formatting. Locate the affected JSX by the displayPrice/hasDiscount price block in RegularFoodCard and replace the inline formatting there.src/components/Dashboard/TrendingMenus.jsx (1)
62-64: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReplace
MdAttachMoneywith a currency-neutral icon.The
MdAttachMoneyicon (a dollar sign) is still used next to the EGP-formatted revenue display, which is inconsistent with the currency migration from$toEGP.Proposed fix
-<MdAttachMoney size={15} className="text-[`#F97316`]" /> +<MdTrendingUp size={15} className="text-[`#F97316`]" />Alternatively, import a more neutral icon like
FiDollarSign→FiTrendingUporMdPaymentsdepending on what's already available in the project's icon set.🤖 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/components/Dashboard/TrendingMenus.jsx` around lines 62 - 64, Replace the currency-specific MdAttachMoney icon in TrendingMenus with a neutral revenue icon to match the EGP display. Update the icon used in the revenue row inside the TrendingMenus component, keeping the existing label and formatting intact, and swap in a neutral alternative already available in the project (for example a payments or trend icon) so the UI no longer implies USD.src/services/dashboardService.js (2)
165-181: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winReuse the activityLog utility instead of re-implementing storage access.
This duplicates the
"revive_activity_log"key and the raw-read/try-catch already provided bygetActivityRaw()insrc/utils/activityLog.js. Importing the helper avoids the magic string drifting from the writer (pushActivity).♻️ Proposed refactor
-import { formatTimeAgo } from "../utils/activityLog"; +import { formatTimeAgo, getActivityRaw } from "../utils/activityLog"; @@ export const getRecentActivity = () => { try { - const stored = JSON.parse(localStorage.getItem("revive_activity_log") || "[]"); + const stored = getActivityRaw(); return Promise.resolve(🤖 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/services/dashboardService.js` around lines 165 - 181, getRecentActivity duplicates the revive_activity_log storage read and error handling instead of reusing the shared activityLog helper. Update dashboardService’s getRecentActivity to import and use getActivityRaw() from src/utils/activityLog.js, then keep only the mapping/formatting logic there so the storage key and try-catch stay centralized with pushActivity.
244-245: 🚀 Performance & Scalability | 🔵 Trivial | ⚖️ Poor tradeoffAll dashboard metrics are derived from a hard cap of 500 orders.
Every derived value (revenue, overview, trending, adaptive daily goals, historical averages) is computed from
getOrders(), which fixessize: 500. Once order volume exceeds 500, historical averages and revenue-by-month will silently undercount. Consider paginating/aggregating server-side for these computations, or documenting the cap as an intentional approximation.🤖 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/services/dashboardService.js` around lines 244 - 245, The dashboard metrics are all based on getOrders(), which hardcodes a size cap of 500 and causes revenue, overview, trending, goals, and historical averages to undercount once order volume grows beyond that limit. Update the data retrieval path used by getOrders() and the dependent dashboard calculations to support full pagination or server-side aggregation instead of relying on the fixed 500-order fetch, or explicitly document the cap if it is intended as an approximation.
🤖 Prompt for all review comments with 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.
Inline comments:
In `@src/components/Dashboard/MetricCards.jsx`:
- Line 16: The `formatValue` logic in `MetricCards` is formatting `totalRevenue`
inline with `toLocaleString()`, which bypasses the shared currency formatter and
can produce inconsistent precision. Update the `formatValue` branch for
`totalRevenue` to use the existing `formatCurrency` utility instead of
constructing the EGP string manually, so the display matches the rest of the
app’s price formatting.
In `@src/components/Dashboard/OrdersView.jsx`:
- Line 278: The order total formatting is inconsistent between the table row in
OrdersView and the OrderDetailsModal, which can show different values for the
same order. Update the total display in the table so it uses the same decimal
precision as the modal’s order total formatting, and make sure both places rely
on the same formatting approach for the order.total value.
In `@src/components/Dashboard/shared/DishDetailsModal.jsx`:
- Line 42: The price display in DishDetailsModal is using dish.price directly,
so it can render inconsistent values for floats or string inputs. Update the
price rendering in the DishDetailsModal component to format dish.price
numerically before display, matching the app’s other price formatting patterns
(for example using Number(...).toFixed(...) as appropriate), and keep the
existing label and styling intact.
In `@src/components/Dashboard/shared/InactiveMenuModal.jsx`:
- Line 114: The price display in InactiveMenuModal is rendering item.price
directly, which can lead to inconsistent formatting for float or string values.
Update the price rendering in InactiveMenuModal to format item.price the same
way as DishDetailsModal by converting it to a number and applying toFixed before
display, so the price output is consistent across menus.
In `@src/pages/Profile/components/OrderCard.jsx`:
- Line 67: The OrderCard price display is rendering order.totalPrice as a raw
value, so it may show inconsistent decimals. Update the total price render in
OrderCard.jsx to use the same number formatting approach used elsewhere in the
app, ensuring values like 12.5 display as 12.50 while keeping the EGP label.
In `@src/services/dashboardService.js`:
- Line 18: The dashboardService module has an unused axios import that is never
referenced because requests go through api instead. Remove the axios import from
the top of the file and keep the existing api-based calls unchanged in
dashboardService so ESLint no-unused-vars is satisfied.
- Around line 20-23: Update isOrderDone in dashboardService so it checks the
same status values produced by mapOrders/getOrders rather than raw backend
states. The current logic compares against uppercase values like CONFIRMED, but
mapOrders converts that status to the UI label Preparing, so confirmed orders
are missed in revenue/completion totals. Adjust the condition to match the
mapped label set used by getOrders/mapOrders, keeping the helper aligned with
the values it actually receives.
- Around line 41-65: The revenue aggregation in getRevenueData currently buckets
by month name only, which merges identical months across different years and can
distort the chart. Update the grouping key to include the year alongside the
month in getRevenueData, then sort the aggregated series chronologically before
calling Mappers.mapRevenueData so the revenue chart reflects true time order.
In `@src/services/mappers/dashboardMappers.js`:
- Line 129: The address fallback in the mapper currently builds a truthy ", "
when customerDetails.address and customerDetails.city are empty, which prevents
deliveryAddress from being used. Update the address composition in the dashboard
order mapper and the corresponding logic in mapKitchenOrders to only use a
customerDetails string when it contains actual non-empty parts, otherwise fall
through to item.deliveryAddress and then the empty string.
---
Outside diff comments:
In `@src/store/orderStore.js`:
- Line 432: The user-facing max-order-total error message still uses “$” instead
of “EGP”, so update the string thrown in the order total limit check to match
the new currency. Locate the error in the order total validation logic in
orderStore and change the message in the relevant throw so it consistently says
10,000 EGP across the PR.
---
Nitpick comments:
In `@src/components/Dashboard/DashboardHeader.jsx`:
- Around line 51-53: The `initials` value in `DashboardHeader` is now unused
because the avatar render path always uses the `<img>` branch, so remove the
dead `initials` computation from the component. Clean up the related logic near
`safeName` and ensure no other references depend on `initials` in
`DashboardHeader` or its avatar rendering flow.
- Around line 33-42: The rawName derivation in DashboardHeader.jsx repeats the
same user-name fallback chain for profileUser and authUser, making it hard to
read and maintain. Extract the shared name-resolution logic into a small helper
(for example, a function that takes a user object and returns
name/fullName/firstName-lastName/username/email prefix) and then use that helper
for both profileUser and authUser in the rawName expression.
In `@src/components/Dashboard/TrendingMenus.jsx`:
- Around line 62-64: Replace the currency-specific MdAttachMoney icon in
TrendingMenus with a neutral revenue icon to match the EGP display. Update the
icon used in the revenue row inside the TrendingMenus component, keeping the
existing label and formatting intact, and swap in a neutral alternative already
available in the project (for example a payments or trend icon) so the UI no
longer implies USD.
In `@src/components/ui/RegularFoodCard.jsx`:
- Around line 125-133: The price rendering in RegularFoodCard is using
formatPrice directly for both the strike-through price and the main price, which
causes inconsistent decimal display. Update the price display logic in
RegularFoodCard to use the shared formatCurrency utility instead of formatPrice
for these spans, and ensure both the discounted and original prices render with
consistent 2-decimal formatting. Locate the affected JSX by the
displayPrice/hasDiscount price block in RegularFoodCard and replace the inline
formatting there.
In `@src/services/dashboardService.js`:
- Around line 165-181: getRecentActivity duplicates the revive_activity_log
storage read and error handling instead of reusing the shared activityLog
helper. Update dashboardService’s getRecentActivity to import and use
getActivityRaw() from src/utils/activityLog.js, then keep only the
mapping/formatting logic there so the storage key and try-catch stay centralized
with pushActivity.
- Around line 244-245: The dashboard metrics are all based on getOrders(), which
hardcodes a size cap of 500 and causes revenue, overview, trending, goals, and
historical averages to undercount once order volume grows beyond that limit.
Update the data retrieval path used by getOrders() and the dependent dashboard
calculations to support full pagination or server-side aggregation instead of
relying on the fixed 500-order fetch, or explicitly document the cap if it is
intended as an approximation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: af06874d-91b1-4c2d-9415-dccd996a9c90
📒 Files selected for processing (22)
src/components/Dashboard/DashboardHeader.jsxsrc/components/Dashboard/DashboardView.jsxsrc/components/Dashboard/LiveKitchenView.jsxsrc/components/Dashboard/MetricCards.jsxsrc/components/Dashboard/OrdersView.jsxsrc/components/Dashboard/RevenueChart.jsxsrc/components/Dashboard/TrendingMenus.jsxsrc/components/Dashboard/shared/DishDetailsModal.jsxsrc/components/Dashboard/shared/InactiveMenuModal.jsxsrc/components/Dashboard/shared/OrderDetailsModal.jsxsrc/components/ui/PopularMenuCard.jsxsrc/components/ui/RegularFoodCard.jsxsrc/constants.jssrc/hooks/dashboard/useOrders.jssrc/pages/Profile/components/OrderCard.jsxsrc/pages/Profile/components/OrderDetailsModal.jsxsrc/services/dashboardService.jssrc/services/mappers/dashboardMappers.jssrc/services/order.service.jssrc/store/orderStore.jssrc/utils/activityLog.jssrc/utils/formatters.js
|
|
||
| function formatValue(key, value) { | ||
| if (key === "totalRevenue") return `$${value.toLocaleString()}`; | ||
| if (key === "totalRevenue") return `${value.toLocaleString()} EGP`; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
Use formatCurrency instead of inline EGP formatting.
formatValue bypasses the shared formatCurrency utility and uses toLocaleString() which doesn't guarantee 2 decimal places (e.g., "1,234 EGP" vs "1,234.00 EGP"). This creates inconsistency across the app's price displays.
♻️ Proposed fix
- if (key === "totalRevenue") return `${value.toLocaleString()} EGP`;
+ if (key === "totalRevenue") return formatCurrency(value);📝 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.
| if (key === "totalRevenue") return `${value.toLocaleString()} EGP`; | |
| if (key === "totalRevenue") return formatCurrency(value); |
🤖 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/components/Dashboard/MetricCards.jsx` at line 16, The `formatValue` logic
in `MetricCards` is formatting `totalRevenue` inline with `toLocaleString()`,
which bypasses the shared currency formatter and can produce inconsistent
precision. Update the `formatValue` branch for `totalRevenue` to use the
existing `formatCurrency` utility instead of constructing the EGP string
manually, so the display matches the rest of the app’s price formatting.
| <td className="px-5 py-4 text-[13px] font-medium text-[#1a1a1a] max-w-[180px] truncate">{order.name}</td> | ||
| <td className="px-5 py-4 text-[13px] text-[#1a1a1a] font-medium">{order.items}</td> | ||
| <td className="px-5 py-4 text-[13px] font-bold text-orange-500">${order.total.toFixed(0)}</td> | ||
| <td className="px-5 py-4 text-[13px] font-bold text-orange-500">{order.total.toFixed(0)} EGP</td> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Inconsistent decimal precision for order totals.
The table renders order.total.toFixed(0) while OrderDetailsModal (line 25 of the same file's companion) renders the same order.total with toFixed(2). A value like 150.99 shows as "151 EGP" in the table but "150.99 EGP" in the modal, which could confuse users.
Proposed fix: align decimal precision
-<td className="px-5 py-4 text-[13px] font-bold text-orange-500">{order.total.toFixed(0)} EGP</td>
+<td className="px-5 py-4 text-[13px] font-bold text-orange-500">{Number(order.total).toFixed(2)} EGP</td>📝 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.
| <td className="px-5 py-4 text-[13px] font-bold text-orange-500">{order.total.toFixed(0)} EGP</td> | |
| <td className="px-5 py-4 text-[13px] font-bold text-orange-500">{Number(order.total).toFixed(2)} EGP</td> |
🧰 Tools
🪛 ast-grep (0.44.1)
[warning] 278-278: A list component should have a key to prevent re-rendering
Context: {order.customer}
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.
(list-component-needs-key)
🤖 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/components/Dashboard/OrdersView.jsx` at line 278, The order total
formatting is inconsistent between the table row in OrdersView and the
OrderDetailsModal, which can show different values for the same order. Update
the total display in the table so it uses the same decimal precision as the
modal’s order total formatting, and make sure both places rely on the same
formatting approach for the order.total value.
| </div> | ||
| <div className="text-right shrink-0"> | ||
| <span className="block text-[22px] font-black text-[#38761d]">${dish.price}</span> | ||
| <span className="block text-[22px] font-black text-[#38761d]">{dish.price} EGP</span> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Apply numeric formatting to dish.price.
dish.price is rendered raw without Number().toFixed(). If the value is a float like 150.5 or a string, the display may be inconsistent with other price displays in the app that use toFixed(2) or toFixed(0).
Proposed fix
-<span className="block text-[22px] font-black text-[`#38761d`]">{dish.price} EGP</span>
+<span className="block text-[22px] font-black text-[`#38761d`]">{Number(dish.price).toFixed(2)} EGP</span>📝 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.
| <span className="block text-[22px] font-black text-[#38761d]">{dish.price} EGP</span> | |
| <span className="block text-[22px] font-black text-[`#38761d`]">{Number(dish.price).toFixed(2)} EGP</span> |
🤖 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/components/Dashboard/shared/DishDetailsModal.jsx` at line 42, The price
display in DishDetailsModal is using dish.price directly, so it can render
inconsistent values for floats or string inputs. Update the price rendering in
the DishDetailsModal component to format dish.price numerically before display,
matching the app’s other price formatting patterns (for example using
Number(...).toFixed(...) as appropriate), and keep the existing label and
styling intact.
| <span>{item.category}</span> | ||
| <span className="w-1 h-1 bg-gray-300 rounded-full"></span> | ||
| <span className="text-orange-500 font-bold">${item.price}</span> | ||
| <span className="text-orange-500 font-bold">{item.price} EGP</span> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Apply numeric formatting to item.price.
Same as DishDetailsModal — item.price is rendered without Number().toFixed(), risking inconsistent display for float or string values.
Proposed fix
-<span className="text-orange-500 font-bold">{item.price} EGP</span>
+<span className="text-orange-500 font-bold">{Number(item.price).toFixed(2)} EGP</span>📝 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.
| <span className="text-orange-500 font-bold">{item.price} EGP</span> | |
| <span className="text-orange-500 font-bold">{Number(item.price).toFixed(2)} EGP</span> |
🧰 Tools
🪛 ast-grep (0.44.1)
[warning] 110-114: A list component should have a key to prevent re-rendering
Context:
{item.category}
{item.price} EGP
Note: [CWE-710] Improper Adherence to Coding Standards. Security best practice.
(list-component-needs-key)
🤖 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/components/Dashboard/shared/InactiveMenuModal.jsx` at line 114, The price
display in InactiveMenuModal is rendering item.price directly, which can lead to
inconsistent formatting for float or string values. Update the price rendering
in InactiveMenuModal to format item.price the same way as DishDetailsModal by
converting it to a number and applying toFixed before display, so the price
output is consistent across menus.
| style={{ color: "#2e7d32" }} | ||
| > | ||
| {order.totalPrice}$ | ||
| {order.totalPrice} EGP |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Apply number formatting to order.totalPrice.
{order.totalPrice} EGP renders the raw value without decimal formatting. If totalPrice is 12.5, the user sees "12.5 EGP" instead of "12.50 EGP", inconsistent with other price displays across the app.
💚 Proposed fix
- {order.totalPrice} EGP
+ {Number(order.totalPrice || 0).toFixed(2)} EGP📝 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.
| {order.totalPrice} EGP | |
| {Number(order.totalPrice || 0).toFixed(2)} EGP |
🤖 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/pages/Profile/components/OrderCard.jsx` at line 67, The OrderCard price
display is rendering order.totalPrice as a raw value, so it may show
inconsistent decimals. Update the total price render in OrderCard.jsx to use the
same number formatting approach used elsewhere in the app, ensuring values like
12.5 display as 12.50 while keeping the EGP label.
| import { useAuthStore } from "../store"; | ||
| import { evaluateStock } from "../utils/stockUtils"; | ||
| import { formatTimeAgo } from "../utils/activityLog"; | ||
| import axios from "axios"; |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Remove the unused axios import.
axios is imported but never referenced (calls go through api). Flagged by ESLint no-unused-vars.
♻️ Proposed fix
-import { formatTimeAgo } from "../utils/activityLog";
-import axios from "axios";
+import { formatTimeAgo } from "../utils/activityLog";📝 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.
| import axios from "axios"; |
🧰 Tools
🪛 ESLint
[error] 18-18: 'axios' is defined but never used. Allowed unused vars must match /^[A-Z_]/u.
(no-unused-vars)
🤖 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/services/dashboardService.js` at line 18, The dashboardService module has
an unused axios import that is never referenced because requests go through api
instead. Remove the axios import from the top of the file and keep the existing
api-based calls unchanged in dashboardService so ESLint no-unused-vars is
satisfied.
Source: Linters/SAST tools
| const isOrderDone = (o) => { | ||
| const st = (o?.status || "").toUpperCase(); | ||
| return st === "DONE" || st === "COMPLETED" || st === "DELIVERED" || st === "CONFIRMED"; | ||
| }; |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Confirm getOrders feeds mapped statuses into isOrderDone consumers
rg -nP "isOrderDone|mapOrders\b|STATUS_MAP" src/services/dashboardService.js src/services/mappers/dashboardMappers.js -C2Repository: Revive-Graduation-Project/Revive-Front-End
Length of output: 5282
🏁 Script executed:
#!/bin/bash
set -euo pipefail
sed -n '88,106p' src/services/mappers/dashboardMappers.js
sed -n '20,24p' src/services/dashboardService.jsRepository: Revive-Graduation-Project/Revive-Front-End
Length of output: 969
isOrderDone should match the mapped UI labels. getOrders() feeds it mapOrders() output, so only "Done" can match here; "CONFIRMED" becomes "Preparing", which excludes confirmed orders from revenue/completion totals.
🤖 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/services/dashboardService.js` around lines 20 - 23, Update isOrderDone in
dashboardService so it checks the same status values produced by
mapOrders/getOrders rather than raw backend states. The current logic compares
against uppercase values like CONFIRMED, but mapOrders converts that status to
the UI label Preparing, so confirmed orders are missed in revenue/completion
totals. Adjust the condition to match the mapped label set used by
getOrders/mapOrders, keeping the helper aligned with the values it actually
receives.
| export const getRevenueData = async () => { | ||
| const orders = await getOrders().catch(() => []); | ||
| const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; | ||
| const MONTHS = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]; | ||
| const revenueByMonth = {}; | ||
|
|
||
| orders.forEach(o => { | ||
| if (o.status !== 'Cancelled' && o.time) { | ||
| const date = new Date(o.time); | ||
| // Use preserved ISO createdAt from mapOrders | ||
| if (isOrderDone(o) && o.createdAt) { | ||
| const date = new Date(o.createdAt); | ||
| if (!isNaN(date.getTime())) { | ||
| const monthStr = months[date.getMonth()]; | ||
| revenueByMonth[monthStr] = (revenueByMonth[monthStr] || 0) + (o.total || 0); | ||
| const key = MONTHS[date.getMonth()]; | ||
| revenueByMonth[key] = (revenueByMonth[key] || 0) + (o.total || 0); | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| const result = Object.entries(revenueByMonth).map(([month, rev]) => ({ | ||
| month, | ||
| revenue: Math.round(rev / 1000), | ||
| income: Math.round((rev * 0.7) / 1000), | ||
| expense: Math.round((rev * 0.3) / 1000) | ||
| revenue: Math.round(rev), // exact EGP amount | ||
| })); | ||
| return Mappers.mapRevenueData(result.length ? result : [ | ||
| { month: "Jan", income: 10, revenue: 15, expense: 5 }, | ||
| { month: "Feb", income: 12, revenue: 18, expense: 6 } | ||
| ]); | ||
|
|
||
| // Minimal fallback only when truly no orders exist | ||
| return Mappers.mapRevenueData( | ||
| result.length ? result : [{ month: "—", income: 0, revenue: 0, expense: 0 }] | ||
| ); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
git ls-files src/services/dashboardService.js src | sed -n '1,120p'Repository: Revive-Graduation-Project/Revive-Front-End
Length of output: 5002
🏁 Script executed:
ast-grep outline src/services/dashboardService.js --view expandedRepository: Revive-Graduation-Project/Revive-Front-End
Length of output: 3286
🏁 Script executed:
sed -n '1,120p' src/services/dashboardService.js && printf '\n---\n' && sed -n '1,220p' src/components/Dashboard/RevenueChart.jsx && printf '\n---\n' && rg -n "mapRevenueData|RevenueChart|revenue" src/services src/components -g '!**/*.map'Repository: Revive-Graduation-Project/Revive-Front-End
Length of output: 9029
🏁 Script executed:
sed -n '1,120p' src/services/mappers/dashboardMappers.js && printf '\n---\n' && sed -n '1,220p' src/hooks/dashboard/useDashboard.js && printf '\n---\n' && sed -n '1,220p' src/hooks/dashboard/useDashboardRealtime.jsRepository: Revive-Graduation-Project/Revive-Front-End
Length of output: 10193
🏁 Script executed:
sed -n '230,280p' src/services/dashboardService.js && printf '\n---\n' && rg -n "getRevenueData\\(" srcRepository: Revive-Graduation-Project/Revive-Front-End
Length of output: 2568
Use a year-aware key and sort the revenue series
MONTHS[date.getMonth()]merges the same month across different years, anduseRevenueData(period)still fetches the full order history, so the chart can blend unrelated revenue into one bucket.- Emit the series in explicit chronological order before passing it to the chart.
🤖 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/services/dashboardService.js` around lines 41 - 65, The revenue
aggregation in getRevenueData currently buckets by month name only, which merges
identical months across different years and can distort the chart. Update the
grouping key to include the year alongside the month in getRevenueData, then
sort the aggregated series chronologically before calling Mappers.mapRevenueData
so the revenue chart reflects true time order.
| total: item.totalPrice ?? item.total ?? 0, | ||
| customer: item.clientId ? `Client #${item.clientId}` : (item.customer || (item.customerDetails ? `${item.customerDetails.firstName || ""} ${item.customerDetails.lastName || ""}`.trim() : "")), | ||
| phone: item.phone || item.phoneNumber || item.customerDetails?.phone || item.customerPhone || item.user?.phone || item.customerDetails?.phoneNumber || "", | ||
| address: item.address || (item.customerDetails ? `${item.customerDetails.address || ""}, ${item.customerDetails.city || ""}` : "") || item.deliveryAddress || "", |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Address fallback yields a stray ", " and skips deliveryAddress.
When customerDetails exists but its address/city are empty, the template produces ", ", which is truthy, so item.deliveryAddress is never reached and the UI shows a lone comma. The same pattern exists at Line 159 in mapKitchenOrders.
♻️ Proposed fix
- address: item.address || (item.customerDetails ? `${item.customerDetails.address || ""}, ${item.customerDetails.city || ""}` : "") || item.deliveryAddress || "",
+ address: item.address
+ || [item.customerDetails?.address, item.customerDetails?.city].filter(Boolean).join(", ")
+ || item.deliveryAddress
+ || "",📝 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.
| address: item.address || (item.customerDetails ? `${item.customerDetails.address || ""}, ${item.customerDetails.city || ""}` : "") || item.deliveryAddress || "", | |
| address: item.address | |
| || [item.customerDetails?.address, item.customerDetails?.city].filter(Boolean).join(", ") | |
| || item.deliveryAddress | |
| || "", |
🤖 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/services/mappers/dashboardMappers.js` at line 129, The address fallback
in the mapper currently builds a truthy ", " when customerDetails.address and
customerDetails.city are empty, which prevents deliveryAddress from being used.
Update the address composition in the dashboard order mapper and the
corresponding logic in mapKitchenOrders to only use a customerDetails string
when it contains actual non-empty parts, otherwise fall through to
item.deliveryAddress and then the empty string.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…ekitchen , orders pages with backend api
Summary by CodeRabbit
New Features
Bug Fixes