Skip to content

updated officer side#19

Open
Dbarsha-hub wants to merge 4 commits intoCodeByDeepankar:mainfrom
Dbarsha-hub:ui-verification-fixes
Open

updated officer side#19
Dbarsha-hub wants to merge 4 commits intoCodeByDeepankar:mainfrom
Dbarsha-hub:ui-verification-fixes

Conversation

@Dbarsha-hub
Copy link
Contributor

updated officer side

Copilot AI review requested due to automatic review settings December 9, 2025 10:14
Copy link

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 enhances the officer-side functionality by adding loan tracking capabilities, improving the dashboard UI with expandable alert cards, and refactoring the beneficiary list to display evidence uploads inline. The changes support better loan monitoring and verification workflows for district officers.

Key Changes:

  • Added loan tracking fields (loanId, loanAmount, lastSynced) to beneficiary metadata
  • Implemented expandable alert sections in the dashboard showing high-risk, pending, and deadline-crossed loans
  • Enhanced beneficiary list cards to preview evidence uploads with real-time loading

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 18 comments.

Show a summary per file
File Description
types/beneficiary.ts Added loan tracking fields to BeneficiaryMetadata and BeneficiaryRecord interfaces
services/api/submissionRepository.ts Cleaned up merge conflict markers from git history
services/api/beneficiaryRepository.ts Updated data mapping to handle new metadata fields and ensure createdAt consistency
screens/officer/verification-tasks-screen.tsx Added comprehensive stylesheet definitions for card UI components
screens/officer/support-screen.tsx Removed redundant header section, relying on WaveHeader instead
screens/officer/reports-screen.tsx Added "Reject" action button with alert functionality for quick actions panel
screens/officer/dashboard-screen.tsx Implemented collapsible alert cards with loan details, added FAB notification button
screens/officer/beneficiary-list-screen.tsx Refactored to show evidence uploads in cards, added high-priority filtering logic
screens/officer/beneficiary-form-screen.tsx Updated metadata initialization to include loan tracking fields
components/organisms/beneficiary-risk-lists.tsx New component providing reusable loan risk categorization lists with mock data
Comments suppressed due to low confidence (1)

screens/officer/beneficiary-list-screen.tsx:70

  • The HIGH_PRIORITY_LOAN_IDS Set contains hardcoded loan IDs. This creates a maintenance issue where loan priorities need to be updated in the code rather than being data-driven.

Consider:

  1. Moving this to a configuration file or fetching from an API
  2. Adding a priority field to the loan data structure
  3. Documenting why these specific IDs are high priority

This will make the system more flexible and easier to maintain.

const IMAGE_QUALITY_LABELS: Record<ImageQuality, string> = {

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

Comment on lines +405 to +421
const handleAction = (action: string) => {
switch (action) {
case 'Approve':
Alert.alert('Approve file', 'Confirm when AI risk is low and KYC + site proofs align.');
break;
case 'Ask Re-Upload':
Alert.alert('Ask for re-upload', 'Request clearer or corrected documents and add a note for the applicant.');
break;
case 'Raise Field Inspection':
Alert.alert('Raise field inspection', 'Escalate to field verification when anomalies persist or address validation is needed.');
break;
case 'Reject':
Alert.alert('Reject file', 'Reject only when fraud is confirmed; record the rejection reason and notify the applicant.');
break;
default:
break;
}
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

The Alert messages in the handleAction function repeat the helper text from the quickActions array. This creates duplicated content that needs to be maintained in two places.

Consider displaying the helper text directly from the action object instead of duplicating it in the Alert calls, or create a single source of truth for these messages.

Copilot uses AI. Check for mistakes.
Comment on lines +258 to +277
}
const existingIds = new Set(loans.map((item) => item.loanId));
const demoAdditions = FALLBACK_BENEFICIARIES.filter((item) => !existingIds.has(item.loanId));
return [...loans, ...demoAdditions];
}, [loans]);

const getDisplayStatus = (loan: BeneficiaryLoan) => {
if (HIGH_PRIORITY_LOAN_IDS.has(loan.loanId)) {
return 'High Priority';
}
switch (loan.status as string) {
case 'sanctioned':
return 'Synced';
case 'disbursed':
case 'approved':
return 'Approved';
case 'pending':
case 'pending-review':
return 'Pending';
case 'rejected':
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

The getDisplayStatus function has inconsistent status mapping. For example:

  • 'sanctioned' maps to 'Synced'
  • 'approved' and 'disbursed' both map to 'Approved'
  • 'rejected' and 'closed' both map to 'Rejected'

This status transformation logic should be clearly documented or moved to a shared utility, as the mappings may not be intuitive (e.g., why does 'sanctioned' become 'Synced'?). This could lead to confusion when debugging status-related issues.

Copilot uses AI. Check for mistakes.
accent,
accentSoft,
borderSoft,
onViewDetails,
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

The BeneficiaryCard component performs a data fetch via the useBeneficiaryUploads hook for every card rendered in the list. If there are many beneficiaries, this could result in N+1 query pattern issues, causing numerous simultaneous API calls.

Consider:

  1. Batch loading uploads for all visible beneficiaries at the list level
  2. Implementing pagination or virtual scrolling to limit rendered cards
  3. Lazy loading uploads only when cards are expanded or come into view

This will significantly improve performance when displaying large lists of beneficiaries.

Copilot uses AI. Check for mistakes.
beneficiaryUid: `BEN-${Date.now().toString().slice(-6)}`,
createdAt: new Date().toISOString(),
status: 'Active',
lastSynced: null,
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

The metadataSeed object initializes lastSynced with null, but the TypeScript interface defines it as any type. This inconsistency could lead to type safety issues.

Since lastSynced should represent a timestamp, consider typing it as string | null in the interface and consistently using null for unset values.

Copilot uses AI. Check for mistakes.
category: string;
loanId: string;
bank: string;
status: 'High Risk' | 'Pending' | 'Deadline Crossed' | string;
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

The status field in the LoanItem type uses a union type with a catch-all string. This defeats the purpose of type safety:

status: 'High Risk' | 'Pending' | 'Deadline Crossed' | string;

The | string makes any string value acceptable, negating the type checking for the specific status values. Consider either:

  1. Removing | string and using only the specific status values
  2. Using a separate field for custom statuses
  3. Creating an enum or const assertion for all possible status values

This will provide better type safety and prevent typos in status values.

Suggested change
status: 'High Risk' | 'Pending' | 'Deadline Crossed' | string;
status: 'High Risk' | 'Pending' | 'Deadline Crossed' | 'High Priority';

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +129
export const highRiskLoans: LoanItem[] = [
{
id: 'HR001',
name: 'Ramesh Kumar',
address: 'MG Road',
category: 'High Risk',
loanId: 'LN-98234',
bank: 'SBI',
status: 'High Risk',
assignedTo: 'Officer A',
documents: 2,
lastUpdated: '2 hours ago',
},
{
id: 'HR002',
name: 'Neha Verma',
address: 'Brigade Road',
category: 'High Risk',
loanId: 'LN-98299',
bank: 'HDFC',
status: 'High Risk',
assignedTo: 'Officer D',
documents: 3,
lastUpdated: '30 mins ago',
},
{
id: 'HR003',
name: 'Manaswini Patro',
address: 'Jayadev Vihar',
category: 'High Priority',
loanId: '9981345206',
bank: 'Canara Bank',
status: 'High Priority',
assignedTo: 'Officer G',
documents: 1,
lastUpdated: '45 mins ago',
},
];

export const pendingReviewLoans: LoanItem[] = [
{
id: 'PR005',
name: 'Swastik Kumar Purohit',
address: 'Danish Nagar',
category: 'Normal',
loanId: '9861510432',
bank: 'Punjab Bank',
status: 'Synced',
assignedTo: 'Officer B',
documents: 0,
lastUpdated: 'Just now',
},
{
id: 'PR006',
name: 'Kavita Joshi',
address: 'Civil Lines',
category: 'Normal',
loanId: 'LN-11229',
bank: 'Axis Bank',
status: 'Pending',
assignedTo: 'Officer E',
documents: 1,
lastUpdated: '15 mins ago',
},
{
id: 'PR007',
name: 'Aarav Mishra',
address: 'Shivaji Nagar',
category: 'Normal',
loanId: '7345129081',
bank: 'Bank of Baroda',
status: 'Pending',
assignedTo: 'Officer H',
documents: 2,
lastUpdated: '10 mins ago',
},
{
id: 'PR008',
name: 'Sonal Tiwari',
address: 'Saket Nagar',
category: 'Normal',
loanId: '9034572211',
bank: 'SBI',
status: 'Approved',
assignedTo: 'Officer I',
documents: 3,
lastUpdated: '1 hour ago',
},
{
id: 'PR009',
name: 'Rahul Patra',
address: 'Old Town',
category: 'Normal',
loanId: '8023114455',
bank: 'ICICI',
status: 'Rejected',
assignedTo: 'Officer J',
documents: 1,
lastUpdated: '2 hours ago',
},
];
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

The loan data contains inconsistent status values across the three arrays. In highRiskLoans, item HR003 (line 61) has status: 'High Priority' while items HR001 and HR002 have status: 'High Risk'. Similarly, in pendingReviewLoans, there are 'Synced', 'Pending', 'Approved', and 'Rejected' statuses mixed together.

These status inconsistencies don't align with the array groupings:

  • highRiskLoans should contain only high-risk items
  • pendingReviewLoans should contain only pending items
  • Items with 'Approved' or 'Rejected' status shouldn't be in pendingReviewLoans

This will cause confusion and potential bugs in filtering and display logic. Ensure status values correctly reflect the categorization.

Copilot uses AI. Check for mistakes.
Comment on lines +226 to +229
<AppText variant="headlineMedium" weight="600" translate={false}>
{title}
</AppText>
<AppText variant="bodySmall" color="muted" translate={false}>
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

The translate={false} prop is used extensively throughout this component (lines 173, 176, 190, 193, 198, 226, 229), but there's no indication this prop is supported by the AppText component.

If AppText doesn't support a translate prop, this will either:

  1. Have no effect (if TypeScript allows extra props)
  2. Cause TypeScript errors (if strict prop checking is enabled)
  3. Be passed down to the underlying Text component where it may not be valid

Verify that AppText supports the translate prop, or remove these if they're not functional.

Suggested change
<AppText variant="headlineMedium" weight="600" translate={false}>
{title}
</AppText>
<AppText variant="bodySmall" color="muted" translate={false}>
<AppText variant="headlineMedium" weight="600">
{title}
</AppText>
<AppText variant="bodySmall" color="muted">

Copilot uses AI. Check for mistakes.
const metadata = {
beneficiaryUid: normalizedMobile,
createdAt: new Date().toISOString(),
lastSynced: null,
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

[nitpick] Setting lastSynced to null and loanId to undefined creates type inconsistency. Since loanId is typed as string | undefined in the interface, using undefined is correct. However, lastSynced should consistently be null if that's the intended default, or undefined if following the same pattern as loanId.

Recommend standardizing on either null or undefined for optional/unset values across the metadata object for consistency.

Suggested change
lastSynced: null,
lastSynced: undefined,

Copilot uses AI. Check for mistakes.
...metadataSeed,
updatedAt: new Date().toISOString(),
loanId: values.loanId,
loanAmount: Number(values.sanctionAmount || 0),
Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

Converting values.sanctionAmount to a number using Number() without validation could result in NaN if the input is invalid. This should include validation or a fallback:

loanAmount: Number(values.sanctionAmount) || 0,

Or better yet, validate that sanctionAmount is a valid number before conversion.

Suggested change
loanAmount: Number(values.sanctionAmount || 0),
loanAmount: (() => {
const n = Number(values.sanctionAmount);
return isNaN(n) ? 0 : n;
})(),

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +45
const handleViewDetails = (loan: LoanItem) => {
navigation.navigate('VerificationTasks', {
filter: loan.status,
loanId: loan.loanId,
});
};

Copy link

Copilot AI Dec 9, 2025

Choose a reason for hiding this comment

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

Unused variable handleViewDetails.

Suggested change
const handleViewDetails = (loan: LoanItem) => {
navigation.navigate('VerificationTasks', {
filter: loan.status,
loanId: loan.loanId,
});
};

Copilot uses AI. Check for mistakes.
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.

3 participants