Skip to content

MXWAR-50: Fix TypeScript build errors and configuration#49

Open
iramsk02 wants to merge 2 commits into
openMF:devfrom
iramsk02:MXWAR-50-fix-build-erros
Open

MXWAR-50: Fix TypeScript build errors and configuration#49
iramsk02 wants to merge 2 commits into
openMF:devfrom
iramsk02:MXWAR-50-fix-build-erros

Conversation

@iramsk02
Copy link
Copy Markdown

@iramsk02 iramsk02 commented Feb 23, 2026

https://mifosforge.jira.com/browse/MXWAR-50

The project was facing significant build failures that prevented deployment and local production testing. This PR stabilizes the build environment and adds data-integrity guards to the accounting module.

Why these changes were made:

Build Stability: The strict erasableSyntaxOnly flag in the TypeScript configuration was causing the Vite build to fail when encountering non-erasable syntax (like Enums/Decorators) commonly used in the codebase.

Developer Velocity: Several unused variables across the project were being treated as fatal build errors. We've adjusted the linting rules to allow these as warnings rather than hard stops, allowing the build process to complete.

Runtime Resilience: The SearchJournalEntry component was vulnerable to crashes because it relied on specific property names (glAccountName, glCode) that the Fineract API does not return consistently across all instances. We've implemented a fallback mechanism to ensure the UI remains functional regardless of the specific API response structure.
Dependencies:

No new dependencies were added.
Related issues and discussion
#MXWAR-50

Screenshots
Screenshot (584)

Screenshot (585)
  • If you have multiple commits please combine them into one commit by squashing them.

  • Read and understood the contribution guidelines at CONTRIBUTING.md.

Summary by CodeRabbit

  • Chores

    • Enhanced ESLint configuration with React-specific linting rules to enforce stricter code standards.
    • Enabled TypeScript compiler checks for detecting unused variables and parameters, improving code reliability.
  • Refactor

    • Cleaned up unused imports and code across multiple components.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to stabilize the frontend build by adjusting TypeScript compiler configuration and pinning OpenAPI generator configuration used during the build pipeline.

Changes:

  • Relaxed TypeScript compiler checks for unused locals/parameters and disabled erasableSyntaxOnly in the app tsconfig.
  • Added openapitools.json to configure/pin OpenAPI generator behavior/version.
  • Updated package-lock.json (notably removing peer: true metadata entries across many packages).

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 3 comments.

File Description
tsconfig.app.json Loosens compiler options related to unused code and erasable-only syntax to unblock tsc -b/Vite builds.
openapitools.json Adds OpenAPI generator CLI configuration (schema reference + pinned generator version).
package-lock.json Lockfile metadata churn (removes peer: true entries), likely from re-generating with a different npm behavior/version.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tsconfig.app.json Outdated
Comment on lines +28 to +30
// "noUnusedLocals": true,
// "noUnusedParameters": true,
// "erasableSyntaxOnly": true,
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

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

The previous settings are left commented-out while the same options are redefined immediately below. This makes the tsconfig harder to read and risks confusion about the intended defaults; it should be simplified by removing the commented lines and keeping only the active values.

Suggested change
// "noUnusedLocals": true,
// "noUnusedParameters": true,
// "erasableSyntaxOnly": true,

Copilot uses AI. Check for mistakes.
Comment thread tsconfig.app.json Outdated
Comment on lines +28 to +32
// "noUnusedLocals": true,
// "noUnusedParameters": true,
// "erasableSyntaxOnly": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

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

Setting "noUnusedLocals"/"noUnusedParameters" to false disables unused-variable reporting entirely (it doesn’t downgrade them to warnings). If the goal is to keep surfacing unused code without failing builds, consider keeping TypeScript’s settings strict and configuring ESLint’s unused-vars rule(s) to 'warn' (or running lint separately) so the signal isn’t lost.

Suggested change
// "noUnusedLocals": true,
// "noUnusedParameters": true,
// "erasableSyntaxOnly": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noUnusedLocals": true,
"noUnusedParameters": true,

Copilot uses AI. Check for mistakes.
Comment thread openapitools.json
Comment on lines +1 to +6
{
"$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
"spaces": 2,
"generator-cli": {
"version": "7.14.0"
}
Copy link

Copilot AI Feb 23, 2026

Choose a reason for hiding this comment

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

The PR description mentions runtime changes (e.g., a fallback mechanism in SearchJournalEntry) and lint rule adjustments, but the diff here only shows TypeScript/OpenAPI config + lockfile updates. If those runtime/lint changes are intended, they may be missing from this PR; otherwise please update the PR description to match what’s actually being changed.

Copilot uses AI. Check for mistakes.
@iramsk02 iramsk02 force-pushed the MXWAR-50-fix-build-erros branch from de997c8 to 00f02d4 Compare February 28, 2026 09:54
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 28, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR enables stricter TypeScript and ESLint checks while cleaning up unused imports across multiple components. Changes include enabling noUnusedLocals and noUnusedParameters in TypeScript configuration, adding React linting rules via the ESLint plugin, and removing unused API/hook imports from several component files.

Changes

Cohort / File(s) Summary
Configuration
eslint.config.js, tsconfig.app.json
Added React ESLint plugin with recommended rules enabled. Enabled strict TypeScript unused variable/parameter checks by setting noUnusedLocals and noUnusedParameters to true.
Component API Import Cleanup
src/pages/organization/holidays/EditHolidays.tsx, src/pages/organization/tellers/CreateTellers.tsx
Removed unused Fineract API imports. Note: CreateTellers.tsx removes TellerCashManagementApi from imports but still instantiates it in code, creating a potential compilation error.
Component Hook Import Cleanup
src/pages/products/floating-rates/ViewFloatingRates.tsx, src/pages/products/recurring-deposit-products/ViewRecurringDepositProducts.tsx
Removed unused useNavigate hook from React Router imports. Note: ViewRecurringDepositProducts.tsx still contains _navigate = useNavigate() assignment despite removing the import, creating a potential compilation error.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 The linter hops through code so fine,
Unused imports? Gone, no sign!
TypeScript now keeps watch so keen,
Though some bugs still hide unseen—
Check those handlers, make them clean! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title references a ticket (MXWAR-50) and states 'Fix TypeScript build errors and configuration', which aligns with the PR's stated objectives to stabilize the TypeScript/Vite build and update configuration files (tsconfig.app.json, eslint.config.js) to address build issues.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

Caution

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

⚠️ Outside diff range comments (7)
src/pages/system/manage-external-events/ManageExternalEvents.tsx (1)

97-126: ⚠️ Potential issue | 🔴 Critical

applyChanges no longer persists updates to backend (false success).

At Line 114–Line 120, the function updates local baseline and shows “External events updated.” but never calls the API. This silently drops user changes after refresh and is a release-blocking correctness issue.

💡 Suggested fix (restore API write before baseline refresh)
   const applyChanges = async () => {
     const externalEventConfigurations: Record<string, boolean> = {}
@@
     if (Object.keys(externalEventConfigurations).length === 0) return

     try {
       setSubmitting(true)
+      // Persist changes first
+      await externalEventsApi.updateExternalEventConfigurations({
+        changes: { externalEventConfigurations },
+      })

       // refresh baseline after success
       const newBase: Record<string, boolean> = {}
       for (const it of externalEvents) {
         if (it?.type) newBase[it.type] = !!it.enabled
       }
       setBaseline(newBase)
       alert('External events updated.')
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/system/manage-external-events/ManageExternalEvents.tsx` around
lines 97 - 126, The applyChanges function currently builds
externalEventConfigurations but never persists them to the backend; restore the
API write by calling the appropriate async save/update API with
externalEventConfigurations before updating local state and showing success.
Inside applyChanges (where externalEventConfigurations is ready and before
creating newBase/setBaseline and alert), await the backend call (e.g.,
updateExternalEventConfigurations or saveExternalEventConfigurations) and handle
errors so setSubmitting is still toggled in finally; only refresh baseline
(setBaseline) and show "External events updated." after the API call succeeds.
src/pages/groups/groups-view/group-actions/TransferClients.tsx (1)

91-93: ⚠️ Potential issue | 🟠 Major

Missing member selection UI renders the feature incomplete.

The label "Select Client Members for Transfer*" is displayed, but there is no corresponding UI element (e.g., checkboxes, multi-select) for users to actually select members from group?.clientMembers. This, combined with the removed setter, means the transfer functionality is entirely broken.

Would you like me to generate a member selection UI component using checkboxes that populates selectedMemberIds?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/groups/groups-view/group-actions/TransferClients.tsx` around lines
91 - 93, The label "Select Client Members for Transfer*" is missing the actual
selection UI: add a member selection component (e.g., a list of checkbox inputs)
that iterates over group?.clientMembers and binds changes to the
selectedMemberIds state setter (restore or create the setter for
selectedMemberIds in TransferClients component); ensure each checkbox uses a
stable key (member.id) and onChange toggles that id in selectedMemberIds, and
update the transfer handler (transferSelectedClients or similar) to read
selectedMemberIds so the transfer action uses the chosen members.
src/pages/tasks/checker-inbox-and-tasks-tabs/checker-inbox/CheckerInbox.tsx (1)

57-72: ⚠️ Potential issue | 🟠 Major

Fetched data is stored but never used.

The change removes the tasks variable to silence the unused variable warning, but the real issue remains: the component fetches data from makerCheckerApi.retrieveCommands(), stores it via setTasks(), and then never uses it. The UI renders dummyData (lines 88-90) instead of the fetched tasks.

This results in:

  1. A wasteful network request on every mount with no effect on the UI.
  2. Users seeing hardcoded dummy data instead of real checker inbox entries.

Either complete the implementation by using tasks in place of dummyData, or remove the fetch logic entirely if this is intentionally placeholder code.

🔧 Option 1: Use the fetched data (recommended)
 const CheckerInboxContent = () => {
-  const [,setTasks] = useState<AuditData[] | null>(null)
+  const [tasks, setTasks] = useState<AuditData[] | null>(null)
   const [filter, setFilter] = useState('')
   const [selectedRows, setSelectedRows] = useState<number[]>([])

Then update filteredData to derive from tasks:

-  const filteredData = dummyData.filter(item =>
-    item.maker.toLowerCase().includes(filter.toLowerCase())
-  )
+  const filteredData = (tasks ?? []).filter(item =>
+    item.maker?.toLowerCase().includes(filter.toLowerCase())
+  )
🗑️ Option 2: Remove dead fetch code if intentionally using dummy data
 const CheckerInboxContent = () => {
-  const [,setTasks] = useState<AuditData[] | null>(null)
   const [filter, setFilter] = useState('')
   const [selectedRows, setSelectedRows] = useState<number[]>([])
-
-  useEffect(() => {
-    const fetchRescheduledLoanDetails = async () => {
-      try {
-        const response = await makerCheckerApi.retrieveCommands()
-        setTasks(response.data)
-      } catch (err) {
-        console.error("Couldn't fetch rescheduled loan details", err)
-      }
-    }
-
-    fetchRescheduledLoanDetails()
-  }, [])
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/tasks/checker-inbox-and-tasks-tabs/checker-inbox/CheckerInbox.tsx`
around lines 57 - 72, The component fetches commands with
makerCheckerApi.retrieveCommands() and calls setTasks but the tasks state
variable was removed and the UI still renders dummyData; either restore the
tasks state (e.g., const [tasks, setTasks] = useState<AuditData[] | null>(null))
and update filteredData and any render logic to use tasks (falling back to
dummyData if tasks is null/empty), or if dummyData is intended, remove the
fetch/useEffect block (and the setTasks call) entirely; reference the
setTasks/useState (tasks), filteredData, dummyData, and
makerCheckerApi.retrieveCommands to find the spots to update.
src/pages/organization/holidays/EditHolidays.tsx (4)

60-60: ⚠️ Potential issue | 🟡 Minor

Update page title to match the feature context.

Line 60 says “Edit Office” on the holidays edit page.

💡 Proposed fix
-        <h2 className="text-2xl font-semibold mb-6">Edit Office</h2>
+        <h2 className="text-2xl font-semibold mb-6">Edit Holiday</h2>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/organization/holidays/EditHolidays.tsx` at line 60, The page
heading currently reads "Edit Office" but this file/component (EditHolidays) is
for editing holidays; open the EditHolidays component and update the h2 text
node ("<h2 className=...>") from "Edit Office" to the correct feature label such
as "Edit Holiday" or "Edit Holidays" so the UI title matches the page context.

43-45: ⚠️ Potential issue | 🔴 Critical

Fix form field keys; inputs currently update the wrong state property.

Lines 68 and 78 pass officeName, but state only has name and description. This makes the controlled fields effectively non-editable.

💡 Proposed fix
-  const handleChange = (field: string, value: string) => {
+  const handleChange = (field: 'name' | 'description', value: string) => {
     setFormData(prev => ({ ...prev, [field]: value }))
   }
...
-              onChange={e => handleChange('officeName', e.target.value)}
+              onChange={e => handleChange('name', e.target.value)}
...
-              onChange={e => handleChange('officeName', e.target.value)}
+              onChange={e => handleChange('description', e.target.value)}

Also applies to: 68-68, 78-78

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/organization/holidays/EditHolidays.tsx` around lines 43 - 45, The
inputs are calling handleChange with the wrong key ("officeName") while formData
expects "name" and "description", so controlled inputs don't update; update the
input onChange handlers (or wherever handleChange is invoked) to pass the
correct keys ("name" for the name input and "description" for the description
input) so that setFormData in handleChange updates the proper properties in
formData; verify handleChange remains defined as const handleChange = (field:
string, value: string) and that inputs bind value to formData.name and
formData.description respectively.

88-88: ⚠️ Potential issue | 🟠 Major

Avoid hard-coded holiday ID in cancel navigation.

Line 88 always routes to holiday 4, which is incorrect for most edits and can confuse users.

💡 Proposed fix
-              onClick={() => navigate('/organization/holidays/4')}
+              onClick={() => navigate('/organization/holidays')}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/organization/holidays/EditHolidays.tsx` at line 88, The onClick
handler currently hardcodes navigate('/organization/holidays/4') in the
EditHolidays component; change it to navigate using the actual holiday id (e.g.,
from route params or the loaded holiday object) or use navigate(-1) to go back.
Locate the onClick that calls navigate and replace the hard-coded '4' with the
dynamic id (for example from useParams().id or holiday.id used in this
component) so cancelling returns to the correct holiday list/detail.

54-54: ⚠️ Potential issue | 🔴 Critical

Remove navigate() call from breadcrumb href—it executes during render and returns undefined.

Line 54 invokes navigate(-1) inside the JSX prop, which runs as a render side effect and breaks the href. Use useParams() to extract the holiday ID from the URL instead.

Proposed fix
-import { useNavigate } from 'react-router-dom'
+import { useNavigate, useParams } from 'react-router-dom'

 const EditHolidays = () => {
+  const { id } = useParams()
   const navigate = useNavigate()
-          { label: 'ID', href: `/organization/holidays/${navigate(-1)}` },
+          { label: 'ID', href: id ? `/organization/holidays/${id}` : '/organization/holidays' },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/organization/holidays/EditHolidays.tsx` at line 54, The breadcrumb
is calling navigate(-1) during render (in EditHolidays.tsx) which executes
immediately and yields undefined; remove that call and instead extract the
holiday id from the route using useParams (import from react-router-dom), e.g.
const { id } = useParams(), then set the breadcrumb href to use that id (e.g.
`/organization/holidays/${id}`), guarding for a missing id (fallback to empty
string) so the href is stable and no navigation is performed during render.
🧹 Nitpick comments (2)
src/pages/users/EditUsers.tsx (1)

34-34: Remove dead useState for setUser.

The user state value is never consumed anywhere in the component. Only setUser is called (line 74) as a sink, while the API response is properly mapped directly to formData (lines 75-84). Removing this unused state eliminates unnecessary re-renders without any impact on functionality.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/users/EditUsers.tsx` at line 34, Remove the unused state tuple
created by useState — specifically delete the declaration "const [,setUser] =
useState<GetUsersResponse | null>(null)" in the EditUsers component and any
calls that only use setUser as a sink; instead let the API response mapping
directly update formData (already done in the effect that populates formData).
Ensure no other code relies on setUser; if there are side-effect-only calls,
remove them or replace with appropriate no-op/comment, leaving formData as the
single source of truth for the fetched user data.
src/pages/products/recurring-deposit-products/ViewRecurringDepositProducts.tsx (1)

23-23: Remove the commented-out useNavigate stub.

Line 23 leaves dead commented code in production source; please delete it to keep the component clean.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/pages/products/recurring-deposit-products/ViewRecurringDepositProducts.tsx`
at line 23, Remove the dead commented stub "// const navigate = useNavigate()"
from the ViewRecurringDepositProducts component to clean up the source; locate
the commented useNavigate line inside the ViewRecurringDepositProducts
function/component and delete it so no unused commented code remains.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.env.sample:
- Around line 27-34: The .env.sample has conflicting defaults for
VITE_FINERACT_API_PROVIDER and VITE_FINERACT_API_VERSION; pick one canonical
contract (e.g. provider prefix = /fineract-provider/api and API version = /v1)
and update the variable values, surrounding comments, and any example usages to
match that contract for both the current block and the later block (lines
~68-84); ensure VITE_FINERACT_API_PROVIDER and VITE_FINERACT_API_VERSION values,
their descriptive comments, and examples consistently reflect the chosen
canonical paths across the file.

In `@src/lib/http-client.ts`:
- Around line 42-47: The getApiBaseUrl function currently concatenates
import.meta.env.VITE_FINERACT_API_URL, VITE_FINERACT_API_PROVIDER, and
VITE_FINERACT_API_VERSION directly which can produce "undefined" fragments,
double slashes, or missing separators; update getApiBaseUrl to provide safe
defaults for each env var (e.g., empty string or "/"), trim any trailing slashes
from VITE_FINERACT_API_URL and leading/trailing slashes from provider/version,
then join them with single "/" separators (or use URL/URLSearchParams-safe
assembly) so the returned string is always a well-formed base URL; ensure the
function still returns a string and update any callers if needed.

In `@src/pages/accounting/create-journal-entry/SearchJournalEntry.tsx`:
- Around line 61-62: SearchJournalEntry currently discards office/GL state
(using const [, setOffices] and const [, setGlAccounts]) yet still includes
those fetches in the Promise.all that drives journal rendering, so any failure
in optional office/GL requests will drop into the catch and clear journal rows.
Fix by keeping the state values (use const [offices, setOffices] and const
[glAccounts, setGlAccounts]) and make the office/GL fetches non-fatal: either
run them after the main journal fetch or replace the Promise.all with
Promise.allSettled and only call setOffices/setGlAccounts when their promise
status is "fulfilled"; ensure failures of these optional calls do not trigger
the branch that clears journal rows (adjust the catch handling around the
journal fetch logic in the SearchJournalEntry component so it only clears rows
on journal fetch failure).

In `@src/pages/collections/IndividualCollectionSheet.tsx`:
- Line 39: The state hook is destructured incorrectly: change the useState usage
so you declare both the value and the setter (e.g., collectionSheet and
setCollectionSheet) instead of only capturing the value; update the declaration
that currently reads useState<any>(null) for setCollectionSheet to a two-item
array [collectionSheet, setCollectionSheet] = useState<any>(null) and ensure any
reads use collectionSheet while calls like setCollectionSheet(response.data)
continue to use the setter.

In `@src/pages/groups/groups-view/group-actions/TransferClients.tsx`:
- Line 32: selectedMemberIds was created with useState but the setter was
removed, so selectedMemberIds can never change and submitDisabled (used to
control the Submit button) stays true; restore the state setter so the value can
be updated (e.g., const [selectedMemberIds, setSelectedMemberIds] =
useState<string[]>([])) and either wire setSelectedMemberIds into the member
selection UI or, if you intentionally don’t use it yet, keep the setter to avoid
breaking behavior but prefix it to silence the linter (const [selectedMemberIds,
_setSelectedMemberIds] = useState<string[]>([])); ensure references to
submitDisabled continue to check selectedMemberIds.length.

In `@src/pages/organization/bulk-loan-reassignmnet/BulkLoanReassignmnet.tsx`:
- Around line 18-29: The component removed StaffApi and the state setters,
leaving officer/template state empty; restore functionality by reintroducing the
StaffApi import (e.g., import { StaffApi } ...), add back state setters for
fromLoanOfficers, toLoanOfficers and officerTemplate (e.g., setFromLoanOfficers,
setToLoanOfficers, setOfficerTemplate) in the BulkLoanReassignment component,
and re-add useEffect hooks that call StaffApi methods to fetch staff/template
data whenever the selected office or from-office changes, then populate those
states so toLoanOfficerId and related selections become selectable and the
submit becomes usable.

In `@src/pages/users/EditUsers.tsx`:
- Around line 105-114: The submit handler (handleSubmit) no longer constructs
the user payload nor calls the update API, so restore the update flow by
reconstructing the payload from formData using the mapped fields shown in the
commented block (username, email, firstname -> firstName, lastname -> lastName,
passwordNeverExpiers, office, staff, roles) and then call the project's user
update API (e.g., updateUser / usersApi.updateUser / PUT to the users endpoint)
with the current user id; ensure you await the request, handle success/error
(update local state or navigate/close the form on success), and surface errors
via existing UI logging/helpers. Reference handleSubmit and the commented
payload in EditUsers to locate where to insert the payload creation and API
invocation.

In `@vite.config.ts`:
- Around line 17-31: The proxyTarget construction in vite.config.ts currently
omits the API version by hardcoding apiProvider as '/fineract-provider/api';
update the variables to use VITE_FINERACT_API_PROVIDER and
VITE_FINERACT_API_VERSION separately (e.g., keep const apiUrl, const
apiProvider, add/read const apiVersion) and build proxyTarget by concatenating
apiUrl + apiProvider + apiVersion so the server.proxy '/api' target matches how
src/lib/http-client.ts composes its base URL; ensure the names apiUrl,
apiProvider, apiVersion, and proxyTarget are used so the change is consistent
and falls back to the documented env defaults.

---

Outside diff comments:
In `@src/pages/groups/groups-view/group-actions/TransferClients.tsx`:
- Around line 91-93: The label "Select Client Members for Transfer*" is missing
the actual selection UI: add a member selection component (e.g., a list of
checkbox inputs) that iterates over group?.clientMembers and binds changes to
the selectedMemberIds state setter (restore or create the setter for
selectedMemberIds in TransferClients component); ensure each checkbox uses a
stable key (member.id) and onChange toggles that id in selectedMemberIds, and
update the transfer handler (transferSelectedClients or similar) to read
selectedMemberIds so the transfer action uses the chosen members.

In `@src/pages/organization/holidays/EditHolidays.tsx`:
- Line 60: The page heading currently reads "Edit Office" but this
file/component (EditHolidays) is for editing holidays; open the EditHolidays
component and update the h2 text node ("<h2 className=...>") from "Edit Office"
to the correct feature label such as "Edit Holiday" or "Edit Holidays" so the UI
title matches the page context.
- Around line 43-45: The inputs are calling handleChange with the wrong key
("officeName") while formData expects "name" and "description", so controlled
inputs don't update; update the input onChange handlers (or wherever
handleChange is invoked) to pass the correct keys ("name" for the name input and
"description" for the description input) so that setFormData in handleChange
updates the proper properties in formData; verify handleChange remains defined
as const handleChange = (field: string, value: string) and that inputs bind
value to formData.name and formData.description respectively.
- Line 88: The onClick handler currently hardcodes
navigate('/organization/holidays/4') in the EditHolidays component; change it to
navigate using the actual holiday id (e.g., from route params or the loaded
holiday object) or use navigate(-1) to go back. Locate the onClick that calls
navigate and replace the hard-coded '4' with the dynamic id (for example from
useParams().id or holiday.id used in this component) so cancelling returns to
the correct holiday list/detail.
- Line 54: The breadcrumb is calling navigate(-1) during render (in
EditHolidays.tsx) which executes immediately and yields undefined; remove that
call and instead extract the holiday id from the route using useParams (import
from react-router-dom), e.g. const { id } = useParams(), then set the breadcrumb
href to use that id (e.g. `/organization/holidays/${id}`), guarding for a
missing id (fallback to empty string) so the href is stable and no navigation is
performed during render.

In `@src/pages/system/manage-external-events/ManageExternalEvents.tsx`:
- Around line 97-126: The applyChanges function currently builds
externalEventConfigurations but never persists them to the backend; restore the
API write by calling the appropriate async save/update API with
externalEventConfigurations before updating local state and showing success.
Inside applyChanges (where externalEventConfigurations is ready and before
creating newBase/setBaseline and alert), await the backend call (e.g.,
updateExternalEventConfigurations or saveExternalEventConfigurations) and handle
errors so setSubmitting is still toggled in finally; only refresh baseline
(setBaseline) and show "External events updated." after the API call succeeds.

In `@src/pages/tasks/checker-inbox-and-tasks-tabs/checker-inbox/CheckerInbox.tsx`:
- Around line 57-72: The component fetches commands with
makerCheckerApi.retrieveCommands() and calls setTasks but the tasks state
variable was removed and the UI still renders dummyData; either restore the
tasks state (e.g., const [tasks, setTasks] = useState<AuditData[] | null>(null))
and update filteredData and any render logic to use tasks (falling back to
dummyData if tasks is null/empty), or if dummyData is intended, remove the
fetch/useEffect block (and the setTasks call) entirely; reference the
setTasks/useState (tasks), filteredData, dummyData, and
makerCheckerApi.retrieveCommands to find the spots to update.

---

Nitpick comments:
In
`@src/pages/products/recurring-deposit-products/ViewRecurringDepositProducts.tsx`:
- Line 23: Remove the dead commented stub "// const navigate = useNavigate()"
from the ViewRecurringDepositProducts component to clean up the source; locate
the commented useNavigate line inside the ViewRecurringDepositProducts
function/component and delete it so no unused commented code remains.

In `@src/pages/users/EditUsers.tsx`:
- Line 34: Remove the unused state tuple created by useState — specifically
delete the declaration "const [,setUser] = useState<GetUsersResponse |
null>(null)" in the EditUsers component and any calls that only use setUser as a
sink; instead let the API response mapping directly update formData (already
done in the effect that populates formData). Ensure no other code relies on
setUser; if there are side-effect-only calls, remove them or replace with
appropriate no-op/comment, leaving formData as the single source of truth for
the fetched user data.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between df36c42 and 00f02d4.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (34)
  • .env.sample
  • .gitignore
  • README.md
  • eslint.config.js
  • openapitools.json
  • src/lib/axios.ts
  • src/lib/fineract-openapi.ts
  • src/lib/http-client.ts
  • src/pages/accounting/create-journal-entry/SearchJournalEntry.tsx
  • src/pages/centers/CloseCenters.tsx
  • src/pages/centers/EditCenters.tsx
  • src/pages/clients/clients-view/family-members-tab/ClientsFamilyMembersAddTab.tsx
  • src/pages/clients/clients-view/family-members-tab/ClientsFamilyMembersTab.tsx
  • src/pages/clients/clients-view/notes-tab/ClientsNotesTab.tsx
  • src/pages/collections/IndividualCollectionSheet.tsx
  • src/pages/groups/groups-view/group-actions/AttachMeeting.tsx
  • src/pages/groups/groups-view/group-actions/TransferClients.tsx
  • src/pages/login/loginApi.ts
  • src/pages/organization/bulk-loan-reassignmnet/BulkLoanReassignmnet.tsx
  • src/pages/organization/employees/EditEmployees.tsx
  • src/pages/organization/holidays/EditHolidays.tsx
  • src/pages/organization/tellers/CreateTellers.tsx
  • src/pages/products/floating-rates/ViewFloatingRates.tsx
  • src/pages/products/loan-products/ViewLoanProducts.tsx
  • src/pages/products/loan-products/create-loan-products/CreateLoanProducts.tsx
  • src/pages/products/loan-products/create-loan-products/create-loan-products-stepper/LoanProductDetailsStep.tsx
  • src/pages/products/recurring-deposit-products/ViewRecurringDepositProducts.tsx
  • src/pages/system/manage-external-events/ManageExternalEvents.tsx
  • src/pages/tasks/checker-inbox-and-tasks-tabs/checker-inbox/CheckerInbox.tsx
  • src/pages/users/EditUsers.tsx
  • src/router/AppRoutes.tsx
  • src/vite-env.d.ts
  • tsconfig.app.json
  • vite.config.ts
💤 Files with no reviewable changes (3)
  • src/pages/products/loan-products/create-loan-products/create-loan-products-stepper/LoanProductDetailsStep.tsx
  • src/pages/clients/clients-view/family-members-tab/ClientsFamilyMembersTab.tsx
  • src/pages/clients/clients-view/family-members-tab/ClientsFamilyMembersAddTab.tsx

Comment thread .env.sample
Comment thread src/lib/http-client.ts Outdated
Comment on lines +42 to +47
export const getApiBaseUrl = (): string => {
return (
import.meta.env.VITE_FINERACT_API_URL +
import.meta.env.VITE_FINERACT_API_PROVIDER +
import.meta.env.VITE_FINERACT_API_VERSION
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

getApiBaseUrl() needs defensive defaults and slash normalization.

At Line 44–46, raw concatenation can generate invalid URLs when env vars are unset or formatted inconsistently (undefined..., double slashes, missing separators).

🔧 Proposed fix
 export const getApiBaseUrl = (): string => {
-  return (
-    import.meta.env.VITE_FINERACT_API_URL +
-    import.meta.env.VITE_FINERACT_API_PROVIDER +
-    import.meta.env.VITE_FINERACT_API_VERSION
-  )
+  const apiUrl = import.meta.env.VITE_FINERACT_API_URL || 'https://localhost:8443'
+  const apiProvider = import.meta.env.VITE_FINERACT_API_PROVIDER || '/fineract-provider'
+  const apiVersion = import.meta.env.VITE_FINERACT_API_VERSION || '/api'
+
+  const base = apiUrl.replace(/\/+$/, '')
+  const provider = apiProvider.startsWith('/') ? apiProvider : `/${apiProvider}`
+  const version = apiVersion.startsWith('/') ? apiVersion : `/${apiVersion}`
+
+  return `${base}${provider}${version}`
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/http-client.ts` around lines 42 - 47, The getApiBaseUrl function
currently concatenates import.meta.env.VITE_FINERACT_API_URL,
VITE_FINERACT_API_PROVIDER, and VITE_FINERACT_API_VERSION directly which can
produce "undefined" fragments, double slashes, or missing separators; update
getApiBaseUrl to provide safe defaults for each env var (e.g., empty string or
"/"), trim any trailing slashes from VITE_FINERACT_API_URL and leading/trailing
slashes from provider/version, then join them with single "/" separators (or use
URL/URLSearchParams-safe assembly) so the returned string is always a
well-formed base URL; ensure the function still returns a string and update any
callers if needed.

Comment on lines +61 to +62
const [, setOffices] = useState<GetOfficesResponse[] | null>(null)
const [, setGlAccounts] = useState<GetGLAccountsResponse[]>([])
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Decouple journal rendering from unused office/GL requests.

Line 61 and Line 62 discard office/GL state values, but Line 72 still includes those calls in Promise.all. If either optional call fails, Line 130 falls into catch and clears journal rows, causing false “No journal entries found.”

💡 Proposed fix
-  const [, setOffices] = useState<GetOfficesResponse[] | null>(null)
-  const [, setGlAccounts] = useState<GetGLAccountsResponse[]>([])
+  // Removed unused office/gl account state

   useEffect(() => {
     ;(async () => {
       try {
-        const [officesRes, glAccountsRes, journalRes] = await Promise.all([
-          officeApi.retrieveOffices(),
-          glApi.retrieveAllAccounts(
-            undefined,
-            undefined,
-            1,
-            true,
-            false
-          ),
-          journalEntryApi.retrieveAll1(),
-        ])
-
-        setOffices(officesRes.data ?? [])
-        setGlAccounts(glAccountsRes.data ?? [])
+        const journalRes = await journalEntryApi.retrieveAll1()

Also applies to: 72-83, 85-87, 130-133

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/accounting/create-journal-entry/SearchJournalEntry.tsx` around
lines 61 - 62, SearchJournalEntry currently discards office/GL state (using
const [, setOffices] and const [, setGlAccounts]) yet still includes those
fetches in the Promise.all that drives journal rendering, so any failure in
optional office/GL requests will drop into the catch and clear journal rows. Fix
by keeping the state values (use const [offices, setOffices] and const
[glAccounts, setGlAccounts]) and make the office/GL fetches non-fatal: either
run them after the main journal fetch or replace the Promise.all with
Promise.allSettled and only call setOffices/setGlAccounts when their promise
status is "fulfilled"; ensure failures of these optional calls do not trigger
the branch that clears journal rows (adjust the catch handling around the
journal fetch logic in the SearchJournalEntry component so it only clears rows
on journal fetch failure).

Comment thread src/pages/collections/IndividualCollectionSheet.tsx Outdated
Comment thread src/pages/groups/groups-view/group-actions/TransferClients.tsx Outdated
Comment thread src/pages/organization/bulk-loan-reassignmnet/BulkLoanReassignmnet.tsx Outdated
Comment thread src/pages/users/EditUsers.tsx Outdated
Comment on lines +105 to +114
// const payload = {
// username: formData.username,
// email: formData.email,
// firstname: formData.firstName,
// lastname: formData.lastName,
// passwordNeverExpiers: formData.passwordNeverExpiers,
// office: formData.office,
// staff: formData.staff,
// roles: formData.roles,
// }
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

User update flow is currently non-functional after submit.

handleSubmit no longer builds/uses a payload and does not invoke any update API call, so “Submit” cannot persist edits. Please restore the update request path before merge.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/users/EditUsers.tsx` around lines 105 - 114, The submit handler
(handleSubmit) no longer constructs the user payload nor calls the update API,
so restore the update flow by reconstructing the payload from formData using the
mapped fields shown in the commented block (username, email, firstname ->
firstName, lastname -> lastName, passwordNeverExpiers, office, staff, roles) and
then call the project's user update API (e.g., updateUser / usersApi.updateUser
/ PUT to the users endpoint) with the current user id; ensure you await the
request, handle success/error (update local state or navigate/close the form on
success), and surface errors via existing UI logging/helpers. Reference
handleSubmit and the commented payload in EditUsers to locate where to insert
the payload creation and API invocation.

Comment thread vite.config.ts Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/pages/groups/groups-view/group-actions/TransferClients.tsx (1)

32-32: ⚠️ Potential issue | 🔴 Critical

Fix swapped useState tuple destructuring for selectedMemberIds.

Line 32 currently captures the setter as selectedMemberIds (const [,selectedMemberIds] = useState...). That makes selectedMemberIds a function, which breaks the selectedMemberIds.length guard on Line 73 and corrupts the submit payload on Line 145.

Proposed fix
-  const [,selectedMemberIds] = useState<string[]>([])
+  const [selectedMemberIds] = useState<string[]>([])
#!/bin/bash
# Verify the tuple destructuring and all local usages of selectedMemberIds.
rg -n -C2 '\[\s*,\s*selectedMemberIds\s*\]\s*=\s*useState<.*>\(' src/pages/groups/groups-view/group-actions/TransferClients.tsx
rg -n -C2 '\bselectedMemberIds\b' src/pages/groups/groups-view/group-actions/TransferClients.tsx
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/groups/groups-view/group-actions/TransferClients.tsx` at line 32,
The useState tuple is destructured backwards in TransferClients.tsx so
selectedMemberIds is currently the setter function; change the declaration from
"const [, selectedMemberIds] = useState<string[]>()" to "const
[selectedMemberIds, setSelectedMemberIds] = useState<string[]>()", then update
any places that call the setter to use setSelectedMemberIds and keep all
existing reads (e.g., checks like selectedMemberIds.length and the submit
payload construction) referencing the array variable selectedMemberIds; search
for selectedMemberIds usages to ensure no remaining references expect the
opposite order.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/pages/groups/groups-view/group-actions/TransferClients.tsx`:
- Line 32: The useState tuple is destructured backwards in TransferClients.tsx
so selectedMemberIds is currently the setter function; change the declaration
from "const [, selectedMemberIds] = useState<string[]>()" to "const
[selectedMemberIds, setSelectedMemberIds] = useState<string[]>()", then update
any places that call the setter to use setSelectedMemberIds and keep all
existing reads (e.g., checks like selectedMemberIds.length and the submit
payload construction) referencing the array variable selectedMemberIds; search
for selectedMemberIds usages to ensure no remaining references expect the
opposite order.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb6ea59 and 7668694.

📒 Files selected for processing (2)
  • src/pages/collections/IndividualCollectionSheet.tsx
  • src/pages/groups/groups-view/group-actions/TransferClients.tsx

- Stabilize TypeScript build (disable erasableSyntaxOnly)
- Adjust unused variable handling
- Fix broken useState destructuring
- Restore state setters in affected components
- Add OpenAPI generator config
- Fix runtime build issues
@iramsk02 iramsk02 force-pushed the MXWAR-50-fix-build-erros branch from 7668694 to f05a27e Compare March 2, 2026 03:35
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (3)
src/pages/organization/employees/EditEmployees.tsx (1)

81-89: ⚠️ Potential issue | 🔴 Critical

Submit handler shows success without saving data.

In Line 87-Line 88, the UI reports “updated successfully” and redirects, but no API update call is made in handleSubmit. This causes silent data loss (user believes changes were saved when they were not). Please call the Staff update endpoint before showing success and navigating.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/organization/employees/EditEmployees.tsx` around lines 81 - 89, The
submit handler handleSubmit currently shows success and redirects without
calling the staff update API; modify handleSubmit to call the Staff update
endpoint (e.g., updateStaff or the appropriate API client function for updating
an employee) with the form data before showing the alert/navigating, await the
response and only call alert('Employee updated successfully!') and
navigate('/organization/employees') on a successful response, and
propagate/handle errors in the existing catch block (show an error message or
set form error state) so failures don't silently redirect.
src/pages/organization/tellers/CreateTellers.tsx (1)

56-80: ⚠️ Potential issue | 🟠 Major

Submit path is currently a no-op.

Line 57 correctly blocks native form submission, but with Lines 58-79 commented out, clicking Submit does nothing and gives no feedback. This leaves the page’s primary action non-functional.

Suggested interim fix (until create API wiring is restored)
-  const handleSubmit = async (e: React.FormEvent) => {
-    e.preventDefault();
-    // const { tellerName, officeId, startDate } = formData;
-    // if (!tellerName || !officeId || !startDate) {
-    //   alert("Please fill all required fields.");
-    //   return;
-    // }
-    // try {
-    //   await tellersApi.createTeller({
-    //     name: formData.tellerName,
-    //     officeId: Number(formData.officeId),
-    //     description: formData.description,
-    //     startDate: formData.startDate,
-    //     endDate: formData.endDate || undefined,
-    //     status: formData.status as "ACTIVE" | "INACTIVE",
-    //     locale: "en",
-    //     dateFormat: "yyyy-MM-dd",
-    //   });
-    //   alert("Teller created successfully!");
-    //   navigate("/organization/tellers");
-    // } catch (err) {
-    //   console.error("Failed to create teller", err);
-    //   alert("Failed to create teller");
-    // }
-  }
+  const handleSubmit = (e: React.FormEvent) => {
+    e.preventDefault()
+    alert('Teller creation is temporarily unavailable.')
+  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/organization/tellers/CreateTellers.tsx` around lines 56 - 80,
handleSubmit is currently a no-op because the implementation is commented out;
restore a meaningful interim submit flow by validating formData (check
tellerName, officeId, startDate), and if invalid show an alert, otherwise either
call tellersApi.createTeller if API wiring is available or show a clear interim
feedback (e.g., alert "Teller creation is temporarily disabled — changes not
saved") and then navigate("/organization/tellers") to preserve UX; update
handleSubmit to use formData, perform validation, provide error/success alerts,
and call navigate as appropriate while keeping the try/catch around
tellersApi.createTeller if you re-enable the API call.
src/pages/system/manage-external-events/ManageExternalEvents.tsx (1)

97-126: ⚠️ Potential issue | 🔴 Critical

Add missing API call to persist external event configuration changes.

The applyChanges function builds the externalEventConfigurations object but never calls an API to persist the changes to the server. It updates the local baseline and displays a success message regardless, leaving server state unchanged.

Insert the API call after line 112:

Fix
   const applyChanges = async () => {
     // build only changed keys
     const externalEventConfigurations: Record<string, boolean> = {}
     for (const it of externalEvents) {
       const t = it.type ?? ''
       if (!t) continue
       const curr = !!it.enabled
       const base = !!baseline[t]
       if (curr !== base) externalEventConfigurations[t] = curr
     }
     if (Object.keys(externalEventConfigurations).length === 0) return

     try {
       setSubmitting(true)
+
+      await externalEventsApi.updateExternalEventConfigurationsDetails({
+        externalEventConfigurations,
+      })

       // refresh baseline after success
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/system/manage-external-events/ManageExternalEvents.tsx` around
lines 97 - 126, The applyChanges function builds externalEventConfigurations but
never persists them; update the function to call the backend API and await its
result before updating local state: invoke an API client (e.g. await
updateExternalEventConfigurations(externalEventConfigurations) or a fetch/POST
to your server endpoint) right after building externalEventConfigurations and
before constructing newBase, wrap the call in the existing try/catch so failures
trigger the catch, and only call setBaseline(newBase), alert('External events
updated.'), and setSubmitting(false) after the API call succeeds; keep existing
error logging in the catch so failed saves do not falsely show success.
🧹 Nitpick comments (2)
src/pages/centers/EditCenters.tsx (1)

26-26: staffId is now read-only and will always be an empty string.

With the setter removed and the AppSelect commented out (lines 65-77), staffId can never change from its initial value. The console.log on line 103 will always output an empty string.

Consider either:

  1. Implementing the staff selection UI with the setter restored, or
  2. Removing staffId entirely if it's not needed yet.
Option 2: Remove unused state
-  const [staffId] = useState<string>('')

And update line 103:

-              onClick={() => console.log('Selected staff:', staffId)}
+              onClick={() => console.log('Confirm clicked')}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/centers/EditCenters.tsx` at line 26, The staffId state is defined
as a read-only empty string (const [staffId] = useState<string>('')) and never
changes because the AppSelect UI is commented out (around the AppSelect block)
so console.log(staffId) will always be empty; either restore the setter and
wiring (change to const [staffId, setStaffId] = useState<string>(''), re-enable
the AppSelect block and pass setStaffId to its onChange/props so user selection
updates staffId) or remove staffId and the console.log usage entirely if staff
selection isn’t needed yet (delete the useState declaration and any references
to staffId).
src/pages/products/loan-products/create-loan-products/CreateLoanProducts.tsx (1)

35-61: loanProducts is fetched but not passed to child stepper components.

The template data is fetched and used only for the loading guard (line 51), but none of the stepper step components receive loanProducts as a prop. If the child components need this template data (e.g., for populating dropdowns), consider passing it down.

If this is intentional scaffolding for future work, this is fine as-is.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/products/loan-products/create-loan-products/CreateLoanProducts.tsx`
around lines 35 - 61, The fetched template stored in loanProducts is only used
for the loading guard and not passed to the step components; update the pages
entries (the component values in the pages array) to pass loanProducts (and its
type) as a prop to each step component that needs it (e.g.,
LoanProductDetailsStep) and adjust those child components' props/interfaces to
accept the template; locate the fetch in useEffect/fetchLoanProductDetails and
the state variables loanProducts/setLoanProducts to wire the prop through.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/pages/tasks/checker-inbox-and-tasks-tabs/checker-inbox/CheckerInbox.tsx`:
- Line 57: The component currently discards the tasks state by using const
[,setTasks] = useState(...) so retrieved data never appears; change the state to
keep both value and setter (const [tasks, setTasks] = useState<AuditData[] |
null>(null)), ensure retrieveCommands calls setTasks(...) with the API response,
and update the JSX in CheckerInbox to render tasks when present (e.g., use tasks
|| dummyData or conditional render) instead of always rendering dummyData;
reference the setTasks, tasks, retrieveCommands and dummyData symbols when
making the edits.

---

Outside diff comments:
In `@src/pages/organization/employees/EditEmployees.tsx`:
- Around line 81-89: The submit handler handleSubmit currently shows success and
redirects without calling the staff update API; modify handleSubmit to call the
Staff update endpoint (e.g., updateStaff or the appropriate API client function
for updating an employee) with the form data before showing the
alert/navigating, await the response and only call alert('Employee updated
successfully!') and navigate('/organization/employees') on a successful
response, and propagate/handle errors in the existing catch block (show an error
message or set form error state) so failures don't silently redirect.

In `@src/pages/organization/tellers/CreateTellers.tsx`:
- Around line 56-80: handleSubmit is currently a no-op because the
implementation is commented out; restore a meaningful interim submit flow by
validating formData (check tellerName, officeId, startDate), and if invalid show
an alert, otherwise either call tellersApi.createTeller if API wiring is
available or show a clear interim feedback (e.g., alert "Teller creation is
temporarily disabled — changes not saved") and then
navigate("/organization/tellers") to preserve UX; update handleSubmit to use
formData, perform validation, provide error/success alerts, and call navigate as
appropriate while keeping the try/catch around tellersApi.createTeller if you
re-enable the API call.

In `@src/pages/system/manage-external-events/ManageExternalEvents.tsx`:
- Around line 97-126: The applyChanges function builds
externalEventConfigurations but never persists them; update the function to call
the backend API and await its result before updating local state: invoke an API
client (e.g. await
updateExternalEventConfigurations(externalEventConfigurations) or a fetch/POST
to your server endpoint) right after building externalEventConfigurations and
before constructing newBase, wrap the call in the existing try/catch so failures
trigger the catch, and only call setBaseline(newBase), alert('External events
updated.'), and setSubmitting(false) after the API call succeeds; keep existing
error logging in the catch so failed saves do not falsely show success.

---

Nitpick comments:
In `@src/pages/centers/EditCenters.tsx`:
- Line 26: The staffId state is defined as a read-only empty string (const
[staffId] = useState<string>('')) and never changes because the AppSelect UI is
commented out (around the AppSelect block) so console.log(staffId) will always
be empty; either restore the setter and wiring (change to const [staffId,
setStaffId] = useState<string>(''), re-enable the AppSelect block and pass
setStaffId to its onChange/props so user selection updates staffId) or remove
staffId and the console.log usage entirely if staff selection isn’t needed yet
(delete the useState declaration and any references to staffId).

In
`@src/pages/products/loan-products/create-loan-products/CreateLoanProducts.tsx`:
- Around line 35-61: The fetched template stored in loanProducts is only used
for the loading guard and not passed to the step components; update the pages
entries (the component values in the pages array) to pass loanProducts (and its
type) as a prop to each step component that needs it (e.g.,
LoanProductDetailsStep) and adjust those child components' props/interfaces to
accept the template; locate the fetch in useEffect/fetchLoanProductDetails and
the state variables loanProducts/setLoanProducts to wire the prop through.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7668694 and f05a27e.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (25)
  • eslint.config.js
  • openapitools.json
  • src/lib/http-client.ts
  • src/pages/accounting/create-journal-entry/SearchJournalEntry.tsx
  • src/pages/centers/CloseCenters.tsx
  • src/pages/centers/EditCenters.tsx
  • src/pages/clients/clients-view/family-members-tab/ClientsFamilyMembersAddTab.tsx
  • src/pages/clients/clients-view/family-members-tab/ClientsFamilyMembersTab.tsx
  • src/pages/clients/clients-view/notes-tab/ClientsNotesTab.tsx
  • src/pages/collections/IndividualCollectionSheet.tsx
  • src/pages/groups/groups-view/group-actions/AttachMeeting.tsx
  • src/pages/groups/groups-view/group-actions/TransferClients.tsx
  • src/pages/organization/bulk-loan-reassignmnet/BulkLoanReassignmnet.tsx
  • src/pages/organization/employees/EditEmployees.tsx
  • src/pages/organization/holidays/EditHolidays.tsx
  • src/pages/organization/tellers/CreateTellers.tsx
  • src/pages/products/floating-rates/ViewFloatingRates.tsx
  • src/pages/products/loan-products/ViewLoanProducts.tsx
  • src/pages/products/loan-products/create-loan-products/CreateLoanProducts.tsx
  • src/pages/products/loan-products/create-loan-products/create-loan-products-stepper/LoanProductDetailsStep.tsx
  • src/pages/products/recurring-deposit-products/ViewRecurringDepositProducts.tsx
  • src/pages/system/manage-external-events/ManageExternalEvents.tsx
  • src/pages/tasks/checker-inbox-and-tasks-tabs/checker-inbox/CheckerInbox.tsx
  • src/pages/users/EditUsers.tsx
  • tsconfig.app.json
💤 Files with no reviewable changes (3)
  • src/pages/clients/clients-view/family-members-tab/ClientsFamilyMembersAddTab.tsx
  • src/pages/clients/clients-view/family-members-tab/ClientsFamilyMembersTab.tsx
  • src/pages/products/loan-products/create-loan-products/create-loan-products-stepper/LoanProductDetailsStep.tsx
🚧 Files skipped from review as they are similar to previous changes (13)
  • openapitools.json
  • src/pages/accounting/create-journal-entry/SearchJournalEntry.tsx
  • tsconfig.app.json
  • src/lib/http-client.ts
  • src/pages/users/EditUsers.tsx
  • src/pages/groups/groups-view/group-actions/AttachMeeting.tsx
  • src/pages/centers/CloseCenters.tsx
  • src/pages/collections/IndividualCollectionSheet.tsx
  • src/pages/products/recurring-deposit-products/ViewRecurringDepositProducts.tsx
  • src/pages/products/floating-rates/ViewFloatingRates.tsx
  • eslint.config.js
  • src/pages/clients/clients-view/notes-tab/ClientsNotesTab.tsx
  • src/pages/organization/holidays/EditHolidays.tsx


const CheckerInboxContent = () => {
const [tasks, setTasks] = useState<AuditData[] | null>(null)
const [,setTasks] = useState<AuditData[] | null>(null)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Line 57 hides a functional regression: fetched data is never rendered.

By discarding the tasks state value, this component always renders dummyData even after retrieveCommands() succeeds. The API call now has no user-visible effect.

Suggested fix
-const [,setTasks] = useState<AuditData[] | null>(null)
+const [tasks, setTasks] = useState<AuditData[] | null>(null)

-const filteredData = dummyData.filter(item =>
+const tableData = tasks ?? dummyData
+const filteredData = tableData.filter(item =>
   item.maker.toLowerCase().includes(filter.toLowerCase())
 )
-checked={selectedRows.length === dummyData.length}
+checked={tableData.length > 0 && selectedRows.length === tableData.length}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/tasks/checker-inbox-and-tasks-tabs/checker-inbox/CheckerInbox.tsx`
at line 57, The component currently discards the tasks state by using const
[,setTasks] = useState(...) so retrieved data never appears; change the state to
keep both value and setter (const [tasks, setTasks] = useState<AuditData[] |
null>(null)), ensure retrieveCommands calls setTasks(...) with the API response,
and update the JSX in CheckerInbox to render tasks when present (e.g., use tasks
|| dummyData or conditional render) instead of always rendering dummyData;
reference the setTasks, tasks, retrieveCommands and dummyData symbols when
making the edits.

@iramsk02
Copy link
Copy Markdown
Author

iramsk02 commented Mar 4, 2026

@IOhacker, could you please take a look and let me know if anything else is needed?
The coderabbit suggestion fix for tasks is out of the scope of this PR so what should I do???

Copy link
Copy Markdown
Collaborator

@gkbishnoi07 gkbishnoi07 left a comment

Choose a reason for hiding this comment

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

please resolve conflicts

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@eslint.config.js`:
- Around line 33-34: The merged config includes react.configs.recommended.rules
which enforces react/react-in-jsx-scope and conflicts with the automatic JSX
transform; update the ESLint config to turn off the react/react-in-jsx-scope
rule (override react/react-in-jsx-scope: "off") and add eslint-plugin-react
settings with react.version set to "detect" (settings.react.version = "detect")
so the plugin stops requiring explicit React imports and correctly detects the
installed React version; target the rules override and settings entries in the
config where react.configs.recommended.rules is merged.

In `@src/pages/organization/tellers/CreateTellers.tsx`:
- Around line 17-21: The file removed the TellerCashManagementApi import but
still constructs a TellerCashManagementApi client at module scope (referenced
where the client is created in CreateTellers.tsx), causing type errors/runtime
failures; either re-add the import for TellerCashManagementApi from
'@/fineract-api' or delete the reserved client construction and any references
to that client (e.g., the module-scope new TellerCashManagementApi(...)
instantiation and related variables) so the module no longer references
TellerCashManagementApi while handleSubmit remains stubbed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: adb486b9-b1ef-4014-ad6f-15cc5f6f1ea2

📥 Commits

Reviewing files that changed from the base of the PR and between f05a27e and b4fb788.

📒 Files selected for processing (6)
  • eslint.config.js
  • src/pages/organization/holidays/EditHolidays.tsx
  • src/pages/organization/tellers/CreateTellers.tsx
  • src/pages/products/floating-rates/ViewFloatingRates.tsx
  • src/pages/products/recurring-deposit-products/ViewRecurringDepositProducts.tsx
  • tsconfig.app.json
💤 Files with no reviewable changes (1)
  • src/pages/organization/holidays/EditHolidays.tsx
✅ Files skipped from review due to trivial changes (2)
  • src/pages/products/floating-rates/ViewFloatingRates.tsx
  • tsconfig.app.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/pages/products/recurring-deposit-products/ViewRecurringDepositProducts.tsx

Comment thread eslint.config.js
Comment on lines +33 to +34

...react.configs.recommended.rules,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify JSX runtime configuration and check if files import React explicitly

echo "=== Checking tsconfig.app.json for jsx setting ==="
rg -n '"jsx"' tsconfig.app.json

echo ""
echo "=== Checking for explicit React imports in TSX files (sample) ==="
rg -l "import React from ['\"]react['\"]" --type tsx --type ts -g '*.tsx' | head -10 || echo "No explicit React imports found (expected with automatic JSX transform)"

echo ""
echo "=== Counting TSX files that would be affected ==="
fd -e tsx | wc -l

Repository: openMF/mifos-x-web-app-react

Length of output: 316


react/react-in-jsx-scope rule conflicts with automatic JSX transform.

The react.configs.recommended.rules includes react/react-in-jsx-scope: 'error', which requires import React from 'react' in every JSX file. The project uses automatic JSX transform ("jsx": "react-jsx" in tsconfig.app.json), making this import unnecessary. This will cause lint errors across all 271 TSX files in the codebase.

Additionally, eslint-plugin-react recommends specifying the React version in settings to avoid detection warnings.

Proposed fix
     plugins: {
       react,
       'react-hooks': reactHooks,
       'react-refresh': reactRefresh,
       prettier: prettier,
     },
+    settings: {
+      react: {
+        version: 'detect',
+      },
+    },
     rules: {
       ...react.configs.recommended.rules,
+      'react/react-in-jsx-scope': 'off',
       ...reactHooks.configs.recommended.rules,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eslint.config.js` around lines 33 - 34, The merged config includes
react.configs.recommended.rules which enforces react/react-in-jsx-scope and
conflicts with the automatic JSX transform; update the ESLint config to turn off
the react/react-in-jsx-scope rule (override react/react-in-jsx-scope: "off") and
add eslint-plugin-react settings with react.version set to "detect"
(settings.react.version = "detect") so the plugin stops requiring explicit React
imports and correctly detects the installed React version; target the rules
override and settings entries in the config where
react.configs.recommended.rules is merged.

Comment on lines 17 to 21
import {
TellerCashManagementApi,

OfficesApi,
type GetOfficesResponse,
} from '@/fineract-api'
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Don't remove this import while Line 24 still constructs the client.

TellerCashManagementApi is still referenced at module scope on Line 24. With this import gone, the file either fails type-checking or throws as soon as this route is evaluated. Since handleSubmit is still stubbed, the cleaner fix is to remove the reserved client entirely; otherwise restore the import here.

Minimal fix
 import {
+  TellerCashManagementApi,
   OfficesApi,
   type GetOfficesResponse,
 } from '@/fineract-api'
📝 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 {
TellerCashManagementApi,
OfficesApi,
type GetOfficesResponse,
} from '@/fineract-api'
import {
TellerCashManagementApi,
OfficesApi,
type GetOfficesResponse,
} from '@/fineract-api'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/pages/organization/tellers/CreateTellers.tsx` around lines 17 - 21, The
file removed the TellerCashManagementApi import but still constructs a
TellerCashManagementApi client at module scope (referenced where the client is
created in CreateTellers.tsx), causing type errors/runtime failures; either
re-add the import for TellerCashManagementApi from '@/fineract-api' or delete
the reserved client construction and any references to that client (e.g., the
module-scope new TellerCashManagementApi(...) instantiation and related
variables) so the module no longer references TellerCashManagementApi while
handleSubmit remains stubbed.

@DavidH-1
Copy link
Copy Markdown
Contributor

CLA check = passed

@gkbishnoi07
Copy link
Copy Markdown
Collaborator

@iramsk02 yet no updates

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.

4 participants