Skip to content

Feature/finish live kitchen - #83

Closed
M7mednsr wants to merge 3 commits into
mainfrom
feature/finish-live-kitchen
Closed

Feature/finish live kitchen#83
M7mednsr wants to merge 3 commits into
mainfrom
feature/finish-live-kitchen

Conversation

@M7mednsr

@M7mednsr M7mednsr commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features
    • Added role-based dashboard routing and navigation, including dedicated kitchen access and a Customer App link for super administrators.
    • Added selectable time periods for revenue and order overview charts.
    • Added profile photo upload/removal and account deletion tools.
    • Added chef management controls and improved kitchen ticket synchronization.
  • Bug Fixes
    • Improved order status handling, ticket recovery, cancellations, and identifier matching.
    • Expanded profile, health-form, allergy, and order-detail compatibility.
    • Added safer avatar fallbacks and clearer validation and login errors.
  • Style
    • Refreshed dashboard charts, metric cards, and sidebar layouts.

@netlify

netlify Bot commented Jul 12, 2026

Copy link
Copy Markdown

Deploy Preview for revive-front-end ready!

Name Link
🔨 Latest commit 9a0c7cd
🔍 Latest deploy log https://app.netlify.com/projects/revive-front-end/deploys/6a53fa2688beff000864fcf3
😎 Deploy Preview https://deploy-preview-83--revive-front-end.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@vercel

vercel Bot commented Jul 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
revive-front-end Ready Ready Preview, Comment Jul 12, 2026 8:33pm

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds role-aware dashboard routing, period-based analytics, unified kitchen ticket actions, staff and chef management, profile picture and account deletion flows, normalized authentication and health data, expanded profile validation, and broader order/status mappings.

Changes

Dashboard and kitchen operations

Layer / File(s) Summary
Role-based dashboard access
src/Layout/AppLayout.jsx, src/components/Dashboard/DashboardSidebar.jsx
Routing and sidebar navigation now distinguish super-admin, staff, and kitchen-only users.
Period-specific dashboard data
src/hooks/dashboard/useDashboard.js, src/services/dashboardService.js
Revenue and order overview queries now use selected periods, period-specific cache keys, buckets, and highlights.
Dashboard charts and view composition
src/components/Dashboard/*, src/components/Dashboard/shared/*
Charts receive controlled period filters, revenue visualization is restyled, metrics are reformatted, and recent activity is removed.
Kitchen ticket and order status flow
src/components/Dashboard/LiveKitchen*, src/services/dashboardService.js, src/services/mappers/*, src/services/order.service.js
Kitchen identifiers and statuses are normalized, board tickets are merged with API tickets, and ticket actions use confirmed status updates.
Staff and chef management
src/components/Dashboard/StaffManagementView.jsx
Staff creation applies role rules and the view renders chef management with ticket and chef mutation handlers.

Profile and account management

Layer / File(s) Summary
Profile API and store integration
src/services/clientProfileService.js, src/services/auth.service.js, src/store/profileStore.js
Profile APIs and store actions now support normalized updates, picture operations, forced refreshes, loyalty synchronization, and account deletion.
Profile page and identity display
src/pages/Profile/Profile.jsx, src/pages/Profile/ProfileLayout.jsx, src/pages/Profile/components/Sidebar.jsx
The profile page adds photo and account deletion controls, authenticated identity fallbacks, and avatar error handling.
Health profile contracts and validation
src/constants.js, src/components/auth/StepTwo.jsx, src/components/ui/AllergiesDropdown.jsx, src/pages/Profile/components/HealthForm.jsx
Health options and form values are normalized, with range validation and inline errors.
Profile information and order refresh
src/pages/Profile/components/InfoGrid.jsx, src/pages/Profile/ProfileOrders.jsx
Profile information includes authenticated identity, loyalty points, expanded condition labels, and retained order polling.
Profile store test coverage
src/store/__tests__/profileStore.test.js
Tests now mock the client profile service and verify authenticated-user profile lookup.

Authentication and order contracts

Layer / File(s) Summary
Authentication identity and login routing
src/store/authStore.js, src/pages/auth/Login.jsx
Stored users include normalized email and derived names; login applies role routing and profile existence checks.
Signup payload normalization
src/pages/auth/Signup.jsx
Signup values are trimmed and normalized before registration.
Order submission payloads
src/store/orderStore.js
Order submissions now include optional customizations and numeric redeemed points.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Login
  participant AuthStore
  participant ProfileService
  participant DashboardRoute
  User->>Login: submit credentials
  Login->>AuthStore: authenticate
  AuthStore-->>Login: authenticated user and role
  Login->>ProfileService: validate client profile for regular users
  Login->>DashboardRoute: navigate by role or show profile error
Loading
sequenceDiagram
  participant ProfileUser
  participant ProfilePage
  participant ProfileStore
  participant ClientProfileAPI
  participant AuthUserAPI
  ProfileUser->>ProfilePage: confirm account deletion
  ProfilePage->>ProfileStore: deleteAccount
  ProfileStore->>ClientProfileAPI: delete client profile
  ProfileStore->>AuthUserAPI: delete auth user
  ProfileStore-->>ProfilePage: clear state and log out
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main theme of the changeset, which heavily updates the live kitchen flow and related dashboard behavior.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/finish-live-kitchen

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@M7mednsr M7mednsr closed this Jul 12, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/store/authStore.js (1)

163-174: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Email validation in restoreSession is less strict than in login.

In login (lines 82–84), the guard checks typeof rawUser.email === "string" && rawUser.email.trim().length > 0, but restoreSession (line 174) only checks rawUser.email for truthiness. A whitespace-only string like " " would fail in login but pass in restoreSession, allowing an invalid email into the persisted user.

🛡️ Proposed fix: align restoreSession validation with login
             set({
               token: data.token,
-              user: rawUser.id != null && rawUser.email ? rawUser : get().user,
+              user:
+                rawUser.id != null &&
+                typeof rawUser.email === "string" &&
+                rawUser.email.trim().length > 0
+                  ? rawUser
+                  : get().user,
               isAuthenticated: true,
               expiresAt: data.expiresAt,
               loading: false,
             });
🤖 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/authStore.js` around lines 163 - 174, Update the user assignment
guard in restoreSession to validate rawUser.email exactly as login does: require
it to be a string with nonzero trimmed length, while retaining the existing
rawUser.id check and fallback to get().user.
🧹 Nitpick comments (6)
src/store/authStore.js (1)

77-78: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

fullName and name are always identical — consider consolidating.

Both fields are derived from the same expression `${data.firstName || ""} ${data.lastName || ""}`.trim() in both login and restoreSession. If downstream consumers only need one, keeping both adds maintenance overhead and confusion about which to use.

Also applies to: 168-169

🤖 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/authStore.js` around lines 77 - 78, Consolidate the duplicate
`fullName` and `name` fields in both `login` and `restoreSession` by retaining a
single canonical field derived from the shared first-name/last-name expression.
Update downstream references in `authStore` to use that field, and remove the
redundant property consistently in both locations.
src/pages/auth/Login.jsx (1)

37-43: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Consider adding a timeout or error boundary for the getProfile call.

The getProfile(user.id) call on line 39 has no timeout. If the backend is slow or unresponsive, the user is stuck on the login page with no feedback after authentication has already succeeded. Consider adding a timeout or surfacing a loading state during the profile check.

🤖 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/auth/Login.jsx` around lines 37 - 43, Update the getProfile call
within the Login component’s authentication flow to enforce a bounded wait or
otherwise surface an explicit loading state while the profile check is pending.
Ensure slow or unresponsive requests cannot leave the user indefinitely stuck
after authentication, while preserving the existing missing-profile error
handling.
src/components/Dashboard/DashboardView.jsx (1)

27-31: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

useRevenueData default period doesn't match the app's period vocabulary.

revenuePeriod here is initialized to "This Month" and only ever set to one of "This Day"/"This Week"/"This Month"/"This Year" (via TimeFilter), but useRevenueData's own default parameter is "6m". Currently harmless since this call always passes an explicit period, but it's a latent trap for any future caller relying on the hook's default.

♻️ Suggested alignment (in useDashboard.js)
-export function useRevenueData(period = "6m") {
+export function useRevenueData(period = "This Month") {
🤖 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/DashboardView.jsx` around lines 27 - 31, Update the
default period parameter in useRevenueData to use the app’s established period
vocabulary, specifically the same "This Month" value used by revenuePeriod and
TimeFilter, instead of "6m". Preserve the hook’s existing behavior when callers
provide an explicit period.
src/components/auth/StepTwo.jsx (1)

104-117: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use GOAL_OPTIONS from src/constants.js here. This keeps the goal list in one place and matches the existing pattern used by other form components.

🤖 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/auth/StepTwo.jsx` around lines 104 - 117, Replace the inline
goal options array in the StepTwo goal radio-group mapping with the shared
GOAL_OPTIONS constant imported from src/constants.js. Keep the existing mapping,
checked state, and onChange behavior unchanged.
src/pages/Profile/components/HealthForm.jsx (1)

234-262: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

New "NONE" health-condition option has no mutual-exclusivity handling.

constants.js now includes { value: "NONE", label: "None" } alongside real conditions, but the toggle logic here just adds/removes the clicked value independently — a user can select "NONE" together with "DIABETES", etc., producing a contradictory health profile.

💡 Suggested fix
                       onClick={(e) => {
                         e.preventDefault();
                         const current = form.healthConditions || [];
                         const exists = current.includes(val);
-                        const next = exists
-                          ? current.filter((c) => c !== val)
-                          : [...current, val];
+                        let next;
+                        if (val === "NONE") {
+                          next = exists ? [] : ["NONE"];
+                        } else {
+                          next = exists
+                            ? current.filter((c) => c !== val)
+                            : [...current.filter((c) => c !== "NONE"), val];
+                        }
                         setForm((s) => ({ ...s, healthConditions: next }));
                       }}
🤖 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/HealthForm.jsx` around lines 234 - 262, Update
the health-condition toggle handler in the form component so selecting the
"NONE" value clears all other health conditions, while selecting any real
condition removes "NONE" before adding it. Preserve the existing toggle behavior
for deselecting values and keep the state update within the current setForm
flow.
src/pages/Profile/Profile.test.jsx (1)

18-29: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

New photo upload/removal and account-deletion flows have no test coverage.

The mocked store still only exposes user, fetchProfile, updateHealth; uploadProfilePicture, deleteProfilePicture, and deleteAccount aren't mocked or exercised at all, so this test suite doesn't cover any of the new functionality added to Profile.jsx (upload, remove picture, delete account, error/toast paths).

🤖 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/Profile.test.jsx` around lines 18 - 29, Extend the Profile
test suite’s mocked store to include uploadProfilePicture, deleteProfilePicture,
and deleteAccount, then add tests exercising photo upload, photo removal, and
account deletion through the Profile UI. Cover the associated success and
error/toast paths, using the existing MemoryRouter and test utilities.
🤖 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/DashboardSidebar.jsx`:
- Line 13: Remove the unused isAdminUser named import from the roleUtils import
in DashboardSidebar.jsx, while retaining isKitchenOnlyUser and isSuperAdmin.

In `@src/components/Dashboard/shared/OrderDetailsModal.jsx`:
- Around line 7-19: The orderItems mapping in the dishes-list parsing logic
currently prefixes quantities, causing downstream parsing to treat them as part
of the dish name. Update the order.orderItems branch to emit each item with the
quantity after the name, such as “Chicken Delight x2” or “Chicken Delight (x2)”,
while preserving the existing default quantity and item-name fallbacks.

In `@src/pages/Profile/components/HealthForm.jsx`:
- Around line 28-33: Align the phone field identifier used by the input’s
onChange with the existing phone error key: update the call to update in the
phone input to use “phone” instead of “phoneNumber,” while preserving the
current form-state update behavior and rendered error handling.
- Around line 52-66: Update the height and weight validation in the form submit
logic to account for the selected units, converting values to a common unit or
applying unit-specific bounds before checking ranges. Preserve the existing
error behavior while ensuring valid m, ft, in, and lb values are not rejected by
the cm/kg limits.

In `@src/pages/Profile/Profile.jsx`:
- Around line 33-44: The rawJoinDate fallback should use an explicit empty-state
value such as "Unknown" instead of new Date(), and formattedJoinDate must
preserve that value without attempting to format it as a date. Update the
toLocaleDateString options in the join-date formatting flow to include timeZone:
"UTC", keeping the existing date-field precedence and display format.
- Around line 86-98: Update deleteAccount and the handleDeleteAccount flow so
failures from either deleteClientProfile(id) or deleteAuthUser(id) are
propagated instead of swallowed, and the operation does not return true after a
partial failure. Preserve the existing successful cleanup, success toast, modal
closing, and navigation only when both backend deletions complete successfully.

In `@src/pages/Profile/ProfileLayout.jsx`:
- Around line 44-64: Update the ProfileLayout component’s !user handling to
distinguish fetch errors from a genuinely missing profile: preserve a dedicated
error state UI with a retry action that re-invokes fetchProfile, and show
“Profile Not Found” only when no error occurred. Keep the existing logout
behavior for the missing-profile state.
- Around line 73-80: Update the avatar fallback chain in ProfileLayout so
freshly fetched user picture fields from user take precedence over authUser
fields. Preserve the existing field order within each object and the placeholder
fallback, ensuring uploads or removals reflected by clientProfileService are
displayed even when authUser is stale.

In `@src/services/clientProfileService.js`:
- Around line 35-43: Remove the manually specified Content-Type header from
uploadProfilePicture’s api.patch request. Leave the FormData request headers
unset so Axios/the browser automatically adds the multipart boundary.

In `@src/services/dashboardService.js`:
- Around line 411-423: Clean up the best-effort synchronization block in
updateKitchenStatus by removing the redundant outer try/catch, since
getActiveKitchenTickets and updateTicketStatus already swallow their expected
failures. Preserve the existing ticket lookup and conditional status update
behavior without introducing an unused catch parameter or empty catch block.

In `@src/store/profileStore.js`:
- Around line 147-174: Update deleteAccount so failures from deleteClientProfile
and deleteAuthUser are not swallowed: remove their inline catches or rethrow
after logging, allowing the outer catch to handle them. Make the outer catch set
loading/error appropriately, avoid clearing local user state or logging out as
if deletion succeeded, and return or propagate failure instead of always
returning true; retain the success cleanup and true result only after both
deletions complete.

---

Outside diff comments:
In `@src/store/authStore.js`:
- Around line 163-174: Update the user assignment guard in restoreSession to
validate rawUser.email exactly as login does: require it to be a string with
nonzero trimmed length, while retaining the existing rawUser.id check and
fallback to get().user.

---

Nitpick comments:
In `@src/components/auth/StepTwo.jsx`:
- Around line 104-117: Replace the inline goal options array in the StepTwo goal
radio-group mapping with the shared GOAL_OPTIONS constant imported from
src/constants.js. Keep the existing mapping, checked state, and onChange
behavior unchanged.

In `@src/components/Dashboard/DashboardView.jsx`:
- Around line 27-31: Update the default period parameter in useRevenueData to
use the app’s established period vocabulary, specifically the same "This Month"
value used by revenuePeriod and TimeFilter, instead of "6m". Preserve the hook’s
existing behavior when callers provide an explicit period.

In `@src/pages/auth/Login.jsx`:
- Around line 37-43: Update the getProfile call within the Login component’s
authentication flow to enforce a bounded wait or otherwise surface an explicit
loading state while the profile check is pending. Ensure slow or unresponsive
requests cannot leave the user indefinitely stuck after authentication, while
preserving the existing missing-profile error handling.

In `@src/pages/Profile/components/HealthForm.jsx`:
- Around line 234-262: Update the health-condition toggle handler in the form
component so selecting the "NONE" value clears all other health conditions,
while selecting any real condition removes "NONE" before adding it. Preserve the
existing toggle behavior for deselecting values and keep the state update within
the current setForm flow.

In `@src/pages/Profile/Profile.test.jsx`:
- Around line 18-29: Extend the Profile test suite’s mocked store to include
uploadProfilePicture, deleteProfilePicture, and deleteAccount, then add tests
exercising photo upload, photo removal, and account deletion through the Profile
UI. Cover the associated success and error/toast paths, using the existing
MemoryRouter and test utilities.

In `@src/store/authStore.js`:
- Around line 77-78: Consolidate the duplicate `fullName` and `name` fields in
both `login` and `restoreSession` by retaining a single canonical field derived
from the shared first-name/last-name expression. Update downstream references in
`authStore` to use that field, and remove the redundant property consistently in
both locations.
🪄 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: fd8f25c7-f2a1-4cdb-9345-e53f6c6b2c83

📥 Commits

Reviewing files that changed from the base of the PR and between 3d93e9c and 9a0c7cd.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json, !package-lock.json
📒 Files selected for processing (34)
  • src/Layout/AppLayout.jsx
  • src/components/Dashboard/DashboardSidebar.jsx
  • src/components/Dashboard/DashboardView.jsx
  • src/components/Dashboard/LiveKitchen/KitchenTicketsTable.jsx
  • src/components/Dashboard/LiveKitchenView.jsx
  • src/components/Dashboard/MetricCards.jsx
  • src/components/Dashboard/OrdersView.jsx
  • src/components/Dashboard/RevenueChart.jsx
  • src/components/Dashboard/StaffManagementView.jsx
  • src/components/Dashboard/shared/OrderDetailsModal.jsx
  • src/components/Dashboard/shared/OrdersOverviewChart.jsx
  • src/components/auth/StepTwo.jsx
  • src/components/ui/AllergiesDropdown.jsx
  • src/constants.js
  • src/hooks/dashboard/useDashboard.js
  • src/hooks/dashboard/useKitchenOrders.js
  • src/pages/Profile/Profile.jsx
  • src/pages/Profile/Profile.test.jsx
  • src/pages/Profile/ProfileLayout.jsx
  • src/pages/Profile/ProfileOrders.jsx
  • src/pages/Profile/components/HealthForm.jsx
  • src/pages/Profile/components/InfoGrid.jsx
  • src/pages/Profile/components/Sidebar.jsx
  • src/pages/auth/Login.jsx
  • src/pages/auth/Signup.jsx
  • src/services/auth.service.js
  • src/services/clientProfileService.js
  • src/services/dashboardService.js
  • src/services/mappers/dashboardMappers.js
  • src/services/order.service.js
  • src/store/__tests__/profileStore.test.js
  • src/store/authStore.js
  • src/store/orderStore.js
  • src/store/profileStore.js

import { FiShoppingBag, FiLogOut, FiUsers } from "react-icons/fi";
import useAuthStore from "../../store/authStore";
import { isKitchenOnlyUser, isAdminUser } from "../../utils/roleUtils";
import { isKitchenOnlyUser, isAdminUser, isSuperAdmin } from "../../utils/roleUtils";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove the unused isAdminUser import.

isAdminUser is no longer referenced in this file (replaced by isSuperAdmin), and ESLint flags it as an error, which can fail the lint gate.

🧹 Proposed fix
-import { isKitchenOnlyUser, isAdminUser, isSuperAdmin } from "../../utils/roleUtils";
+import { isKitchenOnlyUser, isSuperAdmin } from "../../utils/roleUtils";
📝 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
import { isKitchenOnlyUser, isAdminUser, isSuperAdmin } from "../../utils/roleUtils";
import { isKitchenOnlyUser, isSuperAdmin } from "../../utils/roleUtils";
🧰 Tools
🪛 ESLint

[error] 13-13: 'isAdminUser' 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/components/Dashboard/DashboardSidebar.jsx` at line 13, Remove the unused
isAdminUser named import from the roleUtils import in DashboardSidebar.jsx,
while retaining isKitchenOnlyUser and isSuperAdmin.

Source: Linters/SAST tools

Comment on lines +7 to 19
// Handle parsing items: it might be an array of objects (orderItems), array of strings (Live Kitchen), or a comma-separated string.
let dishesList = [];
if (Array.isArray(order.items)) {
if (Array.isArray(order.orderItems) && order.orderItems.length > 0) {
dishesList = order.orderItems.map(item => `${item.quantity || 1}x ${item.name || "Item"}`);
} else if (Array.isArray(order.items)) {
dishesList = order.items;
} else if (typeof order.name === 'string') {
} else if (typeof order.name === 'string' && order.name.includes(',')) {
dishesList = order.name.split(',').map(d => d.trim());
} else if (typeof order.items === 'string') {
dishesList = order.items.split(',').map(d => d.trim());
} else {
dishesList = ["Custom Order"];
dishesList = [order.name || "Custom Order"];
}

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
[skip_cloning]
python3 - <<'EOF'
import re
pattern = re.compile(r'(.+?)(?:\s*\(?x(\d+)\)?)?$', re.IGNORECASE)
for s in ["2x Chicken Delight", "Chicken Delight x2", "Chicken Delight (x2)"]:
    m = pattern.match(s)
    print(repr(s), "->", "name=", m.group(1), "qty=", m.group(2))
EOF

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

Length of output: 395


Use trailing quantity format for order.orderItems
orderItems strings need to be emitted as Chicken Delight x2 / Chicken Delight (x2). The current 2x Chicken Delight format is parsed as part of the dish name, so the UI falls back to 1x and duplicates the quantity in the label.

Proposed fix
-    dishesList = order.orderItems.map(item => `${item.quantity || 1}x ${item.name || "Item"}`);
+    dishesList = order.orderItems.map(item => `${item.name || "Item"} x${item.quantity || 1}`);
📝 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
// Handle parsing items: it might be an array of objects (orderItems), array of strings (Live Kitchen), or a comma-separated string.
let dishesList = [];
if (Array.isArray(order.items)) {
if (Array.isArray(order.orderItems) && order.orderItems.length > 0) {
dishesList = order.orderItems.map(item => `${item.quantity || 1}x ${item.name || "Item"}`);
} else if (Array.isArray(order.items)) {
dishesList = order.items;
} else if (typeof order.name === 'string') {
} else if (typeof order.name === 'string' && order.name.includes(',')) {
dishesList = order.name.split(',').map(d => d.trim());
} else if (typeof order.items === 'string') {
dishesList = order.items.split(',').map(d => d.trim());
} else {
dishesList = ["Custom Order"];
dishesList = [order.name || "Custom Order"];
}
// Handle parsing items: it might be an array of objects (orderItems), array of strings (Live Kitchen), or a comma-separated string.
let dishesList = [];
if (Array.isArray(order.orderItems) && order.orderItems.length > 0) {
dishesList = order.orderItems.map(item => `${item.name || "Item"} x${item.quantity || 1}`);
} else if (Array.isArray(order.items)) {
dishesList = order.items;
} else if (typeof order.name === 'string' && order.name.includes(',')) {
dishesList = order.name.split(',').map(d => d.trim());
} else if (typeof order.items === 'string') {
dishesList = order.items.split(',').map(d => d.trim());
} else {
dishesList = [order.name || "Custom Order"];
}
🤖 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/OrderDetailsModal.jsx` around lines 7 - 19,
The orderItems mapping in the dishes-list parsing logic currently prefixes
quantities, causing downstream parsing to treat them as part of the dish name.
Update the order.orderItems branch to emit each item with the quantity after the
name, such as “Chicken Delight x2” or “Chicken Delight (x2)”, while preserving
the existing default quantity and item-name fallbacks.

Comment on lines 28 to 33
const update = (field) => (e) => {
const value =
e.target.type === "checkbox" ? e.target.checked : e.target.value;
setForm((s) => ({ ...s, [field]: value }));
setErrors((prev) => ({ ...prev, [field]: "" }));
};

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 | 🟡 Minor | ⚡ Quick win

Clearing the phone error on change doesn't work — field-name/error-key mismatch.

errors uses the key phone (Line 26), but the phone input's onChange calls update("phoneNumber") (Line 136), and inside update, setErrors((prev) => ({ ...prev, [field]: "" })) sets errors.phoneNumber = "" — a different key than errors.phone, which is what's actually rendered (Line 143). So after a phone validation error appears, editing the phone field does not clear the displayed error; it persists until the next submit().

🐛 Suggested fix
+  const errorKeyMap = { phoneNumber: "phone" };
+
   const update = (field) => (e) => {
     const value =
       e.target.type === "checkbox" ? e.target.checked : e.target.value;
     setForm((s) => ({ ...s, [field]: value }));
-    setErrors((prev) => ({ ...prev, [field]: "" }));
+    setErrors((prev) => ({ ...prev, [errorKeyMap[field] || field]: "" }));
   };

Also applies to: 136-142

🤖 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/HealthForm.jsx` around lines 28 - 33, Align the
phone field identifier used by the input’s onChange with the existing phone
error key: update the call to update in the phone input to use “phone” instead
of “phoneNumber,” while preserving the current form-state update behavior and
rendered error handling.

Comment on lines +52 to +66
if (form.height !== "" && form.height !== null) {
const heightNum = Number(form.height);
if (isNaN(heightNum) || heightNum < 30 || heightNum > 300) {
newErrors.height = "Height must be between 30 and 300";
hasError = true;
}
}

if (form.weight !== "" && form.weight !== null) {
const weightNum = Number(form.weight);
if (isNaN(weightNum) || weightNum < 10 || weightNum > 400) {
newErrors.weight = "Weight must be between 10 and 400";
hasError = true;
}
}

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
rg -n -B1 -A3 'HEIGHT_UNITS|WEIGHT_UNITS' src/constants.js

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

Length of output: 380


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the validation logic and unit handling in the form.
ast-grep outline src/pages/Profile/components/HealthForm.jsx --view expanded

printf '\n--- file excerpt ---\n'
cat -n src/pages/Profile/components/HealthForm.jsx | sed -n '1,220p'

printf '\n--- constants ---\n'
cat -n src/constants.js | sed -n '1,120p'

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

Length of output: 13290


Validate height/weight against the selected unit at src/pages/Profile/components/HealthForm.jsx:52-66. The fixed 30–300 / 10–400 bounds only fit cm/kg, so m/ft/in/lb entries will be rejected incorrectly; convert to a common unit or apply unit-specific ranges before submit.

🤖 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/HealthForm.jsx` around lines 52 - 66, Update the
height and weight validation in the form submit logic to account for the
selected units, converting values to a common unit or applying unit-specific
bounds before checking ranges. Preserve the existing error behavior while
ensuring valid m, ft, in, and lb values are not rejected by the cm/kg limits.

Comment on lines +33 to +44
const rawJoinDate =
user?.createdAt ||
user?.createdDate ||
user?.joinDate ||
user?.registrationDate ||
new Date();

const formattedJoinDate = new Date(rawJoinDate).toLocaleDateString("en-GB", {
day: "2-digit",
month: "short",
year: "numeric",
});

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 | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the relevant implementation and test files with line numbers.
git ls-files 'src/pages/Profile/Profile.jsx' 'src/pages/Profile/Profile.test.jsx' | xargs -r -I{} sh -c 'echo "==== {} ===="; wc -l "{}"; cat -n "{}" | sed -n "1,260p"'

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

Length of output: 12983


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find where the profile user date fields are defined/used and inspect nearby code.
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' '\b(createdAt|createdDate|joinDate|registrationDate)\b' src

# Show the profile store slice if present.
fd -a 'store' src

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

Length of output: 5509


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the profile store and its tests for the user shape and date fields.
wc -l src/store/profileStore.js src/store/__tests__/profileStore.test.js
cat -n src/store/profileStore.js | sed -n '1,260p'
echo "==== tests ===="
cat -n src/store/__tests__/profileStore.test.js | sed -n '1,260p'

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

Length of output: 9495


Join date should not default to today; format the test date in UTC

  • When none of the profile date fields exist, new Date() makes the profile look like it has a join date of today. Use an empty state such as "Unknown" instead.
  • The test expectation for "15 Jan 2024" depends on the browser timezone. Format this date with timeZone: "UTC" or assert against a timezone-safe 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/pages/Profile/Profile.jsx` around lines 33 - 44, The rawJoinDate fallback
should use an explicit empty-state value such as "Unknown" instead of new
Date(), and formattedJoinDate must preserve that value without attempting to
format it as a date. Update the toLocaleDateString options in the join-date
formatting flow to include timeZone: "UTC", keeping the existing date-field
precedence and display format.

Comment on lines 44 to 64
if (!user) {
return (
<div className="min-h-screen flex items-center justify-center p-8 text-gray-500">
No profile data available.
<div className="min-h-screen flex flex-col items-center justify-center p-8 text-center">
<div className="bg-white p-8 rounded-2xl shadow-md max-w-md border border-gray-100">
<h3 className="text-xl font-semibold text-gray-800 mb-2">
Profile Not Found
</h3>
<p className="text-sm text-gray-600 mb-6">
Your profile appears to have been deleted or does not exist.
</p>
<button
onClick={() => useAuthStore.getState().logout()}
className="bg-(--color-orange) hover:bg-orange-500 text-white px-6 py-2 rounded-full text-sm font-semibold transition cursor-pointer"
>
Log Out
</button>
</div>
</div>
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Removing the distinct error UI conflates transient fetch failures with a genuinely missing profile.

Previously error had its own UI; now any !user state (including a transient network/server error during fetchProfile) shows "Profile Not Found" with only a logout action — no retry option. A user hitting a temporary error is forced to log out rather than retry, which is a worse experience than before.

🤖 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/ProfileLayout.jsx` around lines 44 - 64, Update the
ProfileLayout component’s !user handling to distinguish fetch errors from a
genuinely missing profile: preserve a dedicated error state UI with a retry
action that re-invokes fetchProfile, and show “Profile Not Found” only when no
error occurred. Keep the existing logout behavior for the missing-profile state.

Comment on lines 73 to +80
const avatar =
user?.avatar || user?.photo || "/images/avatar-placeholder.jpeg";
authUser?.profilePictureUrl ||
authUser?.avatar ||
authUser?.photo ||
user?.profilePictureUrl ||
user?.avatar ||
user?.photo ||
"/images/avatar-placeholder.jpeg";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Avatar precedence favors authUser over the freshly-fetched profile user, which can show a stale picture.

Profile pictures are managed via clientProfileService (/api/clients/profile/:id/picture), not the auth-user record. Since avatar checks authUser?.profilePictureUrl || authUser?.avatar || authUser?.photo before user?.profilePictureUrl, the Sidebar avatar can keep showing an old/stale value from authUser even after a successful upload or removal via Profile.jsx, if authStore's user object isn't also kept in sync.

💡 Suggested fix
   const avatar =
-    authUser?.profilePictureUrl ||
-    authUser?.avatar ||
-    authUser?.photo ||
     user?.profilePictureUrl ||
     user?.avatar ||
     user?.photo ||
+    authUser?.profilePictureUrl ||
+    authUser?.avatar ||
+    authUser?.photo ||
     "/images/avatar-placeholder.jpeg";
📝 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
const avatar =
user?.avatar || user?.photo || "/images/avatar-placeholder.jpeg";
authUser?.profilePictureUrl ||
authUser?.avatar ||
authUser?.photo ||
user?.profilePictureUrl ||
user?.avatar ||
user?.photo ||
"/images/avatar-placeholder.jpeg";
const avatar =
user?.profilePictureUrl ||
user?.avatar ||
user?.photo ||
authUser?.profilePictureUrl ||
authUser?.avatar ||
authUser?.photo ||
"/images/avatar-placeholder.jpeg";
🤖 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/ProfileLayout.jsx` around lines 73 - 80, Update the avatar
fallback chain in ProfileLayout so freshly fetched user picture fields from user
take precedence over authUser fields. Preserve the existing field order within
each object and the placeholder fallback, ensuring uploads or removals reflected
by clientProfileService are displayed even when authUser is stale.

Comment on lines +35 to +43
export const uploadProfilePicture = (id, file) => {
const formData = new FormData();
formData.append("file", file);
return api.patch(`/api/clients/profile/${id}/picture`, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
};

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## files\n'
git ls-files | rg '^(src/services/clientProfileService\.js|src/|package\.json)$'

printf '\n## clientProfileService.js\n'
cat -n src/services/clientProfileService.js

printf '\n## api wrapper candidates\n'
rg -n "axios|create\\(|interceptors|Content-Type|multipart/form-data|FormData" src package.json

printf '\n## package.json\n'
cat -n package.json

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

Length of output: 8196


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n## src/services/api.js\n'
cat -n src/services/api.js

printf '\n## multipart upload call sites\n'
sed -n '480,570p' src/services/dashboardService.js
printf '\n---\n'
sed -n '1,80p' src/services/user.service.js

printf '\n## focused search for request config mutation\n'
rg -n "transformRequest|headers\\.|Content-Type|FormData" src/services/api.js src/services/*.js

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

Length of output: 9485


🌐 Web query:

axios multipart/form-data boundary automatic FormData browser docs

💡 Result:

When working with FormData in the browser, you should not manually set the Content-Type header [1][2][3]. If you set the Content-Type header manually, you risk overriding the browser's ability to automatically generate and append the necessary multipart boundary string [2][3]. The browser, web worker, or React Native environment must generate this unique boundary itself to correctly structure the multipart/form-data payload [1][2]. Key points for browser usage: 1. Automatic Detection: When you pass a FormData instance as the payload to an Axios request, Axios automatically detects the type and ensures the request is sent with the correct configuration [1][4]. 2. Leave Content-Type Unset: You should leave the Content-Type header unset in your request configuration [1][5]. The browser will automatically set the header to multipart/form-data and include the required boundary parameter [4][2]. 3. Automatic Serialization: Starting from version 0.27.0, if you need to send an object as FormData, you can set the Content-Type header to multipart/form-data in your request config, and Axios will perform the serialization automatically [1][6][7]. This is distinct from passing an already-constructed FormData object, where you should avoid setting the header [1][2]. 4. Shortcut Methods: Axios provides convenience methods such as postForm, putForm, and patchForm, which automatically preset the Content-Type header to multipart/form-data [6][5][7]. If you are using Node.js, the behavior may differ because the environment does not have a native browser-like FormData with automatic boundary management in the same way, often requiring the form-data library or native FormData in newer Node.js versions [1][2][8]. However, for browser-based development, strictly avoiding manual Content-Type header intervention is the standard best practice to ensure the boundary is handled correctly [2][3].

Citations:


Remove the manual multipart header here

FormData uploads should leave Content-Type unset so Axios/the browser can add the boundary parameter. Sending "multipart/form-data" explicitly can break parsing on the server.

🤖 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/clientProfileService.js` around lines 35 - 43, Remove the
manually specified Content-Type header from uploadProfilePicture’s api.patch
request. Leave the FormData request headers unset so Axios/the browser
automatically adds the multipart boundary.

Comment on lines +411 to +423
export const updateKitchenStatus = async (orderId, status) => {
const numericId = String(orderId).replace('#', '');
const result = await updateOrderStatus(numericId, status);
// Synchronize with active kitchen tickets if present
try {
const tickets = await getActiveKitchenTickets().catch(() => []);
const matchingTicket = tickets.find(t => String(t.orderId) === numericId || String(t.id) === numericId);
if (matchingTicket && matchingTicket.id) {
await updateTicketStatus(matchingTicket.id, status).catch(() => {});
}
} catch (_e) {}
return result;
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Clean up the best-effort ticket-sync block.

_e is flagged as unused and the empty catch {} triggers no-empty. Since getActiveKitchenTickets() and updateTicketStatus() already have inner .catch(...), the outer try/catch is largely redundant; either drop it or annotate the intentional swallow.

🧹 Proposed cleanup
   const result = await updateOrderStatus(numericId, status);
   // Synchronize with active kitchen tickets if present
-  try {
-    const tickets = await getActiveKitchenTickets().catch(() => []);
-    const matchingTicket = tickets.find(t => String(t.orderId) === numericId || String(t.id) === numericId);
-    if (matchingTicket && matchingTicket.id) {
-      await updateTicketStatus(matchingTicket.id, status).catch(() => {});
-    }
-  } catch (_e) {}
+  const tickets = await getActiveKitchenTickets().catch(() => []);
+  const matchingTicket = tickets.find(t => String(t.orderId) === numericId || String(t.id) === numericId);
+  if (matchingTicket && matchingTicket.id) {
+    await updateTicketStatus(matchingTicket.id, status).catch(() => {});
+  }
   return result;
📝 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 updateKitchenStatus = async (orderId, status) => {
const numericId = String(orderId).replace('#', '');
const result = await updateOrderStatus(numericId, status);
// Synchronize with active kitchen tickets if present
try {
const tickets = await getActiveKitchenTickets().catch(() => []);
const matchingTicket = tickets.find(t => String(t.orderId) === numericId || String(t.id) === numericId);
if (matchingTicket && matchingTicket.id) {
await updateTicketStatus(matchingTicket.id, status).catch(() => {});
}
} catch (_e) {}
return result;
};
export const updateKitchenStatus = async (orderId, status) => {
const numericId = String(orderId).replace('#', '');
const result = await updateOrderStatus(numericId, status);
// Synchronize with active kitchen tickets if present
const tickets = await getActiveKitchenTickets().catch(() => []);
const matchingTicket = tickets.find(t => String(t.orderId) === numericId || String(t.id) === numericId);
if (matchingTicket && matchingTicket.id) {
await updateTicketStatus(matchingTicket.id, status).catch(() => {});
}
return result;
};
🧰 Tools
🪛 ESLint

[error] 421-421: '_e' is defined but never used.

(no-unused-vars)


[error] 421-421: Empty block statement.

(no-empty)

🤖 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 411 - 423, Clean up the
best-effort synchronization block in updateKitchenStatus by removing the
redundant outer try/catch, since getActiveKitchenTickets and updateTicketStatus
already swallow their expected failures. Preserve the existing ticket lookup and
conditional status update behavior without introducing an unused catch parameter
or empty catch block.

Source: Linters/SAST tools

Comment thread src/store/profileStore.js
Comment on lines +147 to +174
deleteAccount: async () => {
set({ loading: true, error: null });
try {
const id = useAuthStore.getState().user?.id;
if (id) {
await deleteClientProfile(id).catch((err) => {
console.warn("Delete profile API response:", err);
});
await deleteAuthUser(id).catch((err) => {
console.warn("Delete auth user API response:", err);
});
}
set({ user: null, loading: false, error: null });
try {
localStorage.removeItem("revive-profile-store");
} catch (e) {}
await useAuthStore.getState().logout(false);
return true;
} catch (error) {
set({ user: null, loading: false, error: null });
try {
localStorage.removeItem("revive-profile-store");
} catch (e) {}
await useAuthStore.getState().logout(false);
return true;
}
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🔴 Critical | ⚡ Quick win

deleteAccount always returns true, even when both delete calls fail.

Both deleteClientProfile and deleteAuthUser errors are swallowed via .catch((err) => console.warn(...)), and the outer catch block duplicates the exact same "success" side effects (clear user, wipe localStorage, logout, return true). This means a total backend failure (network error, 403, 500) still reports success to the caller — the UI will tell the user their account was deleted and log them out, while the account and its data remain intact server-side. For an account-deletion flow this is a real correctness and compliance concern (e.g. "right to be forgotten" flows should not report success on failure).

This also matches the static-analysis hints: unused e/error and empty catch blocks at Lines 162, 165, and 169 are symptomatic of the swallowed errors.

🛠️ Proposed fix: propagate actual failure instead of always succeeding
       deleteAccount: async () => {
         set({ loading: true, error: null });
-        try {
-          const id = useAuthStore.getState().user?.id;
-          if (id) {
-            await deleteClientProfile(id).catch((err) => {
-              console.warn("Delete profile API response:", err);
-            });
-            await deleteAuthUser(id).catch((err) => {
-              console.warn("Delete auth user API response:", err);
-            });
-          }
-          set({ user: null, loading: false, error: null });
-          try {
-            localStorage.removeItem("revive-profile-store");
-          } catch (e) {}
-          await useAuthStore.getState().logout(false);
-          return true;
-        } catch (error) {
-          set({ user: null, loading: false, error: null });
-          try {
-            localStorage.removeItem("revive-profile-store");
-          } catch (e) {}
-          await useAuthStore.getState().logout(false);
-          return true;
-        }
+        const id = useAuthStore.getState().user?.id;
+        if (!id) {
+          set({ loading: false, error: "User ID not found" });
+          return false;
+        }
+        try {
+          await deleteClientProfile(id);
+          await deleteAuthUser(id);
+        } catch (error) {
+          set({ loading: false, error: error.message || "Failed to delete account" });
+          return false;
+        }
+        set({ user: null, loading: false, error: null });
+        try {
+          localStorage.removeItem("revive-profile-store");
+        } catch {}
+        await useAuthStore.getState().logout(false);
+        return true;
       },
📝 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
deleteAccount: async () => {
set({ loading: true, error: null });
try {
const id = useAuthStore.getState().user?.id;
if (id) {
await deleteClientProfile(id).catch((err) => {
console.warn("Delete profile API response:", err);
});
await deleteAuthUser(id).catch((err) => {
console.warn("Delete auth user API response:", err);
});
}
set({ user: null, loading: false, error: null });
try {
localStorage.removeItem("revive-profile-store");
} catch (e) {}
await useAuthStore.getState().logout(false);
return true;
} catch (error) {
set({ user: null, loading: false, error: null });
try {
localStorage.removeItem("revive-profile-store");
} catch (e) {}
await useAuthStore.getState().logout(false);
return true;
}
},
deleteAccount: async () => {
set({ loading: true, error: null });
const id = useAuthStore.getState().user?.id;
if (!id) {
set({ loading: false, error: "User ID not found" });
return false;
}
try {
await deleteClientProfile(id);
await deleteAuthUser(id);
} catch (error) {
set({ loading: false, error: error.message || "Failed to delete account" });
return false;
}
set({ user: null, loading: false, error: null });
try {
localStorage.removeItem("revive-profile-store");
} catch {}
await useAuthStore.getState().logout(false);
return true;
},
🧰 Tools
🪛 ESLint

[error] 162-162: 'e' is defined but never used.

(no-unused-vars)


[error] 162-162: Empty block statement.

(no-empty)


[error] 165-165: 'error' is defined but never used.

(no-unused-vars)


[error] 169-169: 'e' is defined but never used.

(no-unused-vars)


[error] 169-169: Empty block statement.

(no-empty)

🤖 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/profileStore.js` around lines 147 - 174, Update deleteAccount so
failures from deleteClientProfile and deleteAuthUser are not swallowed: remove
their inline catches or rethrow after logging, allowing the outer catch to
handle them. Make the outer catch set loading/error appropriately, avoid
clearing local user state or logging out as if deletion succeeded, and return or
propagate failure instead of always returning true; retain the success cleanup
and true result only after both deletions complete.

Source: Linters/SAST tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant