end to end flow testing for all modules paralley enhancing profile schema to gather all info
This commit is contained in:
parent
6542f0fb30
commit
dad534c169
@ -354,6 +354,8 @@ export const ApplicationDetails = () => {
|
|||||||
stageApprovals: data.stageApprovals || [],
|
stageApprovals: data.stageApprovals || [],
|
||||||
fddAssignments: data.fddAssignments || [],
|
fddAssignments: data.fddAssignments || [],
|
||||||
constitutionType: data.constitutionType,
|
constitutionType: data.constitutionType,
|
||||||
|
architectureStatus: data.architectureStatus,
|
||||||
|
statutoryStatus: data.statutoryStatus,
|
||||||
};
|
};
|
||||||
setApplication(mappedApp);
|
setApplication(mappedApp);
|
||||||
if (data.uploadedDocuments) {
|
if (data.uploadedDocuments) {
|
||||||
@ -1202,7 +1204,7 @@ export const ApplicationDetails = () => {
|
|||||||
id: 12,
|
id: 12,
|
||||||
name: 'LOA',
|
name: 'LOA',
|
||||||
status: getStageStatus('LOA', () => ['EOR In Progress', 'EOR Complete', 'Inauguration', 'Approved', 'Onboarded'].includes(application.status) ? 'completed' : application.status === 'LOA Pending' ? 'active' : 'pending'),
|
status: getStageStatus('LOA', () => ['EOR In Progress', 'EOR Complete', 'Inauguration', 'Approved', 'Onboarded'].includes(application.status) ? 'completed' : application.status === 'LOA Pending' ? 'active' : 'pending'),
|
||||||
isLocked: application.status === 'LOA Pending' && getDeposit('FINAL')?.status !== 'Verified',
|
isLocked: application.status === 'LOA Pending' && getDeposit('FIRST_FILL')?.status !== 'Verified',
|
||||||
lockMessage: 'First Fill (₹15L) must be verified by Finance before LOA Approval.',
|
lockMessage: 'First Fill (₹15L) must be verified by Finance before LOA Approval.',
|
||||||
evaluators: Array.from(new Set((application.participants || [])
|
evaluators: Array.from(new Set((application.participants || [])
|
||||||
.filter((p: any) => p.metadata?.stageCode === 'LOA_APPROVAL' || p.metadata?.allAssignments?.includes('LOA_APPROVAL'))
|
.filter((p: any) => p.metadata?.stageCode === 'LOA_APPROVAL' || p.metadata?.allAssignments?.includes('LOA_APPROVAL'))
|
||||||
@ -1682,7 +1684,7 @@ export const ApplicationDetails = () => {
|
|||||||
'LOA Pending', 'EOR In Progress', 'EOR Complete', 'Inauguration'
|
'LOA Pending', 'EOR In Progress', 'EOR Complete', 'Inauguration'
|
||||||
].includes(application.status);
|
].includes(application.status);
|
||||||
|
|
||||||
const finalDepositVerified = getDeposit('FINAL')?.status === 'Verified';
|
const finalDepositVerified = getDeposit('FIRST_FILL')?.status === 'Verified';
|
||||||
const isLoaLocked = application.status === 'LOA Pending' && !finalDepositVerified;
|
const isLoaLocked = application.status === 'LOA Pending' && !finalDepositVerified;
|
||||||
|
|
||||||
// Sequential Enforcement for LOI APPROVAL (SRS 6.16.3.5)
|
// Sequential Enforcement for LOI APPROVAL (SRS 6.16.3.5)
|
||||||
@ -2024,21 +2026,7 @@ export const ApplicationDetails = () => {
|
|||||||
<div key={report.id} className="p-6 space-y-6 bg-white">
|
<div key={report.id} className="p-6 space-y-6 bg-white">
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||||
<div className="space-y-5">
|
<div className="space-y-5">
|
||||||
<div>
|
{/* Auditor Recommendation Hidden as per request */}
|
||||||
<Label className="text-[10px] text-slate-400 uppercase tracking-widest font-black mb-2 block">Auditor Recommendation</Label>
|
|
||||||
<div className={cn(
|
|
||||||
"inline-flex items-center gap-2 px-3 py-1.5 rounded-full border text-xs font-black shadow-sm",
|
|
||||||
report.recommendation === 'Recommended' || report.recommendation === 'Green' ? "bg-green-50 border-green-200 text-green-700" :
|
|
||||||
report.recommendation === 'Qualified with Observations' || report.recommendation === 'Amber' ? "bg-amber-50 border-amber-200 text-amber-700" :
|
|
||||||
"bg-red-50 border-red-200 text-red-700"
|
|
||||||
)}>
|
|
||||||
<div className={cn("w-2 h-2 rounded-full",
|
|
||||||
report.recommendation === 'Recommended' || report.recommendation === 'Green' ? "bg-green-500" :
|
|
||||||
report.recommendation === 'Qualified with Observations' || report.recommendation === 'Amber' ? "bg-amber-500" : "bg-red-500"
|
|
||||||
)} />
|
|
||||||
{report.recommendation?.toUpperCase()}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-[10px] text-slate-400 uppercase tracking-widest font-black mb-2 block">Findings Summary</Label>
|
<Label className="text-[10px] text-slate-400 uppercase tracking-widest font-black mb-2 block">Findings Summary</Label>
|
||||||
@ -2093,16 +2081,23 @@ export const ApplicationDetails = () => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="pt-4 flex items-center gap-3">
|
<div className="pt-4 flex flex-col gap-2">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<div className="flex items-center gap-1.5 bg-slate-50 border border-slate-100 px-3 py-1 rounded-full">
|
||||||
|
<User className="w-3.5 h-3.5 text-slate-500" />
|
||||||
|
<span className="text-[10px] font-bold text-slate-600 uppercase">Submitted by: {report.submitter?.fullName || 'Auditor'}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{report.verifiedAt ? (
|
{report.verifiedAt ? (
|
||||||
<div className="flex items-center gap-2 bg-green-50 border border-green-100 px-3 py-1.5 rounded-full">
|
<div className="flex items-center gap-2 bg-green-50 border border-green-100 px-3 py-1.5 rounded-full w-fit">
|
||||||
<CheckCircle className="w-4 h-4 text-green-600" />
|
<CheckCircle className="w-4 h-4 text-green-600" />
|
||||||
<span className="text-[10px] font-black text-green-700 uppercase">Audit Verified by Finance</span>
|
<span className="text-[10px] font-black text-green-700 uppercase"> Verified by {report.verifier?.fullName || 'Admin'}</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex items-center gap-2 bg-amber-50 border border-amber-100 px-3 py-1.5 rounded-full">
|
<div className="flex items-center gap-2 bg-amber-50 border border-amber-100 px-3 py-1.5 rounded-full w-fit">
|
||||||
<Clock className="w-4 h-4 text-amber-600" />
|
<Clock className="w-4 h-4 text-amber-600" />
|
||||||
<span className="text-[10px] font-black text-amber-700 uppercase">Pending Finance Review</span>
|
<span className="text-[10px] font-black text-amber-700 uppercase">Pending Review</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -3169,7 +3164,7 @@ export const ApplicationDetails = () => {
|
|||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
{/* Initial Security Deposit */}
|
{/* Initial Security Deposit */}
|
||||||
{(() => {
|
{(() => {
|
||||||
const deposit = getDeposit('INITIAL');
|
const deposit = getDeposit('SECURITY_DEPOSIT');
|
||||||
const config = paymentConfigs.SECURITY_DEPOSIT;
|
const config = paymentConfigs.SECURITY_DEPOSIT;
|
||||||
const expectedAmount = config?.amount || 500000;
|
const expectedAmount = config?.amount || 500000;
|
||||||
|
|
||||||
@ -3252,7 +3247,7 @@ export const ApplicationDetails = () => {
|
|||||||
|
|
||||||
{/* Final Security Deposit */}
|
{/* Final Security Deposit */}
|
||||||
{(() => {
|
{(() => {
|
||||||
const deposit = getDeposit('FINAL');
|
const deposit = getDeposit('FIRST_FILL');
|
||||||
const config = paymentConfigs.FIRST_FILL;
|
const config = paymentConfigs.FIRST_FILL;
|
||||||
const expectedAmount = config?.amount || 1500000;
|
const expectedAmount = config?.amount || 1500000;
|
||||||
|
|
||||||
@ -4856,6 +4851,7 @@ export const ApplicationDetails = () => {
|
|||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
|
{(currentUser?.role !== 'FDD' && currentUser?.roleCode !== 'FDD') && (
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label className="text-[10px] font-black uppercase tracking-widest text-slate-400">Auditor Recommendation</Label>
|
<Label className="text-[10px] font-black uppercase tracking-widest text-slate-400">Auditor Recommendation</Label>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
@ -4876,6 +4872,7 @@ export const ApplicationDetails = () => {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label className="text-[10px] font-black uppercase tracking-widest text-slate-400">Findings Summary</Label>
|
<Label className="text-[10px] font-black uppercase tracking-widest text-slate-400">Findings Summary</Label>
|
||||||
@ -4914,7 +4911,9 @@ export const ApplicationDetails = () => {
|
|||||||
applicationId: application!.id,
|
applicationId: application!.id,
|
||||||
stageCode: 'FDD_VERIFICATION',
|
stageCode: 'FDD_VERIFICATION',
|
||||||
decision: 'Approved',
|
decision: 'Approved',
|
||||||
remarks: `[RECOMMENDATION: ${fddAuditRecommendation}] \nFindings: ${fddAuditFindings}`,
|
remarks: (currentUser?.role === 'FDD' || currentUser?.roleCode === 'FDD')
|
||||||
|
? `Findings: ${fddAuditFindings}`
|
||||||
|
: `[RECOMMENDATION: ${fddAuditRecommendation}] \nFindings: ${fddAuditFindings}`,
|
||||||
nextStatus: 'LOI In Progress',
|
nextStatus: 'LOI In Progress',
|
||||||
nextProgress: 65
|
nextProgress: 65
|
||||||
});
|
});
|
||||||
|
|||||||
@ -252,6 +252,45 @@ export function ConstitutionalChangeDetails({ requestId, onBack }: Constitutiona
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
{/* Establishment Details */}
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Establishment & Dealer Codes</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="grid grid-cols-2 md:grid-cols-4 gap-6">
|
||||||
|
<div>
|
||||||
|
<p className="text-slate-600 text-sm mb-1">Sales Code</p>
|
||||||
|
<p className="text-slate-900">{request.dealer?.dealerProfile?.dealerCode?.salesCode || 'N/A'}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-slate-600 text-sm mb-1">Service Code</p>
|
||||||
|
<p className="text-slate-900">{request.dealer?.dealerProfile?.dealerCode?.serviceCode || 'N/A'}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-slate-600 text-sm mb-1">GMA Code</p>
|
||||||
|
<p className="text-slate-900">{request.dealer?.dealerProfile?.dealerCode?.gmaCode || 'N/A'}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-slate-600 text-sm mb-1">Gear Code</p>
|
||||||
|
<p className="text-slate-900">{request.dealer?.dealerProfile?.dealerCode?.gearCode || 'N/A'}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-slate-600 text-sm mb-1">Inauguration Date</p>
|
||||||
|
<p className="text-slate-900">{request.dealer?.dealerProfile?.onboardedAt ? formatDateTime(request.dealer.dealerProfile.onboardedAt, 'date') : 'N/A'}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-slate-600 text-sm mb-1">LOI Date</p>
|
||||||
|
<p className="text-slate-900">{request.dealer?.dealerProfile?.loiDate ? formatDateTime(request.dealer.dealerProfile.loiDate, 'date') : 'N/A'}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-slate-600 text-sm mb-1">LOA Date</p>
|
||||||
|
<p className="text-slate-900">{request.dealer?.dealerProfile?.loaDate ? formatDateTime(request.dealer.dealerProfile.loaDate, 'date') : 'N/A'}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||||
{/* Main Content */}
|
{/* Main Content */}
|
||||||
<div className="lg:col-span-2 space-y-6">
|
<div className="lg:col-span-2 space-y-6">
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import {
|
|||||||
import { WorkNotesPage } from './WorkNotesPage';
|
import { WorkNotesPage } from './WorkNotesPage';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { DocumentPreviewModal } from '../ui/DocumentPreviewModal';
|
import { DocumentPreviewModal } from '../ui/DocumentPreviewModal';
|
||||||
import { formatDateTime, cn } from '@/components/ui/utils';
|
import { formatDateTime } from '@/components/ui/utils';
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
@ -45,10 +45,9 @@ export function FDDApplicationDetails() {
|
|||||||
const [selectedPreviewDoc, setSelectedPreviewDoc] = useState<any>(null);
|
const [selectedPreviewDoc, setSelectedPreviewDoc] = useState<any>(null);
|
||||||
const [showFinalizeModal, setShowFinalizeModal] = useState(false);
|
const [showFinalizeModal, setShowFinalizeModal] = useState(false);
|
||||||
const [showFlagModal, setShowFlagModal] = useState(false);
|
const [showFlagModal, setShowFlagModal] = useState(false);
|
||||||
const [fddAuditRecommendation, setFddAuditRecommendation] = useState<string>('Recommended');
|
|
||||||
const [fddAuditFindings, setFddAuditFindings] = useState<string>('');
|
const [fddAuditFindings, setFddAuditFindings] = useState<string>('');
|
||||||
const user = useSelector((state: RootState) => state.auth.user);
|
const user = useSelector((state: RootState) => state.auth.user);
|
||||||
const isFddRole = user?.role === 'FDD' || user?.role === 'FDD Auditor';
|
const isFddRole = user?.role === 'FDD';
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (id) fetchApplication();
|
if (id) fetchApplication();
|
||||||
@ -202,6 +201,14 @@ export function FDDApplicationDetails() {
|
|||||||
<Upload className="w-4 h-4" />
|
<Upload className="w-4 h-4" />
|
||||||
{uploading ? 'Uploading...' : 'Upload Report'}
|
{uploading ? 'Uploading...' : 'Upload Report'}
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
disabled={uploading}
|
||||||
|
onClick={() => setShowFinalizeModal(true)}
|
||||||
|
className="flex items-center gap-2 px-4 py-2 bg-slate-900 text-white font-bold text-xs uppercase tracking-wider rounded-lg hover:bg-slate-800 transition-all shadow-lg shadow-slate-200"
|
||||||
|
>
|
||||||
|
<CheckCircle2 className="w-4 h-4" />
|
||||||
|
{uploading ? 'Processing...' : 'Submit Final Findings'}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
disabled={uploading}
|
disabled={uploading}
|
||||||
onClick={() => setShowFlagModal(true)}
|
onClick={() => setShowFlagModal(true)}
|
||||||
@ -545,26 +552,6 @@ export function FDDApplicationDetails() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-4 pt-2">
|
<div className="space-y-4 pt-2">
|
||||||
<div className="space-y-2">
|
|
||||||
<Label className="text-[10px] font-black uppercase tracking-widest text-slate-400">Auditor Recommendation</Label>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
{['Recommended', 'Qualified with Observations', 'Not Recommended'].map((rec) => (
|
|
||||||
<Button
|
|
||||||
key={rec}
|
|
||||||
variant={fddAuditRecommendation === rec ? 'default' : 'outline'}
|
|
||||||
className={cn(
|
|
||||||
"flex-1 h-10 font-bold text-[9px] uppercase tracking-wider rounded-xl transition-all",
|
|
||||||
fddAuditRecommendation === rec && rec === 'Recommended' && "bg-emerald-600 hover:bg-emerald-700",
|
|
||||||
fddAuditRecommendation === rec && rec === 'Qualified with Observations' && "bg-amber-500 hover:bg-amber-600",
|
|
||||||
fddAuditRecommendation === rec && rec === 'Not Recommended' && "bg-red-600 hover:bg-red-700"
|
|
||||||
)}
|
|
||||||
onClick={() => setFddAuditRecommendation(rec)}
|
|
||||||
>
|
|
||||||
{rec}
|
|
||||||
</Button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label className="text-[10px] font-black uppercase tracking-widest text-slate-400">Detailed Audit Findings & Remarks</Label>
|
<Label className="text-[10px] font-black uppercase tracking-widest text-slate-400">Detailed Audit Findings & Remarks</Label>
|
||||||
@ -594,16 +581,12 @@ export function FDDApplicationDetails() {
|
|||||||
toast.error('Please provide findings.');
|
toast.error('Please provide findings.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!assignment?.id) {
|
|
||||||
toast.error('Assignment not found.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setUploading(true);
|
setUploading(true);
|
||||||
const res: any = await API.submitFddReport({
|
const res: any = await API.submitFddReport({
|
||||||
assignmentId: assignment.id,
|
assignmentId: assignment?.id,
|
||||||
|
applicationId: id,
|
||||||
findings: fddAuditFindings,
|
findings: fddAuditFindings,
|
||||||
recommendation: fddAuditRecommendation
|
recommendation: null
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.data?.success) {
|
if (res.data?.success) {
|
||||||
|
|||||||
@ -49,7 +49,7 @@ export function FinanceOnboardingPage({ onViewPaymentDetails }: FinanceOnboardin
|
|||||||
const getRelevantPaymentStatus = (app: any) => {
|
const getRelevantPaymentStatus = (app: any) => {
|
||||||
if (!app.securityDeposits || app.securityDeposits.length === 0) return 'Awaiting Payment';
|
if (!app.securityDeposits || app.securityDeposits.length === 0) return 'Awaiting Payment';
|
||||||
const s = app.overallStatus || app.status;
|
const s = app.overallStatus || app.status;
|
||||||
const relevantType = (s.includes('LOI') || s === 'PAYMENT_VERIFICATION' || s === 'Security Details') ? 'INITIAL' : 'FINAL';
|
const relevantType = (s.includes('LOI') || s === 'PAYMENT_VERIFICATION' || s === 'Security Details') ? 'SECURITY_DEPOSIT' : 'FIRST_FILL';
|
||||||
const deposit = app.securityDeposits.find((d: any) => d.depositType === relevantType);
|
const deposit = app.securityDeposits.find((d: any) => d.depositType === relevantType);
|
||||||
return deposit ? deposit.status : 'Awaiting Payment';
|
return deposit ? deposit.status : 'Awaiting Payment';
|
||||||
};
|
};
|
||||||
|
|||||||
@ -33,7 +33,7 @@ interface FinancePaymentDetailsPageProps {
|
|||||||
export function FinancePaymentDetailsPage({ applicationId, onBack }: FinancePaymentDetailsPageProps) {
|
export function FinancePaymentDetailsPage({ applicationId, onBack }: FinancePaymentDetailsPageProps) {
|
||||||
const [application, setApplication] = useState<any>(null);
|
const [application, setApplication] = useState<any>(null);
|
||||||
const [deposits, setDeposits] = useState<any[]>([]);
|
const [deposits, setDeposits] = useState<any[]>([]);
|
||||||
const [activeType, setActiveType] = useState<'INITIAL' | 'FINAL'>('INITIAL');
|
const [activeType, setActiveType] = useState<'SECURITY_DEPOSIT' | 'FIRST_FILL'>('SECURITY_DEPOSIT');
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
const [configs, setConfigs] = useState<any>({});
|
const [configs, setConfigs] = useState<any>({});
|
||||||
@ -68,7 +68,7 @@ export function FinancePaymentDetailsPage({ applicationId, onBack }: FinancePaym
|
|||||||
|
|
||||||
setPaymentDetails({
|
setPaymentDetails({
|
||||||
verificationTransactionId: '',
|
verificationTransactionId: '',
|
||||||
receivedAmount: activeType === 'INITIAL' ? initialDefault.toString() : finalDefault.toString(),
|
receivedAmount: activeType === 'SECURITY_DEPOSIT' ? initialDefault.toString() : finalDefault.toString(),
|
||||||
receivedDate: new Date().toISOString().split('T')[0],
|
receivedDate: new Date().toISOString().split('T')[0],
|
||||||
verificationRemarks: ''
|
verificationRemarks: ''
|
||||||
});
|
});
|
||||||
@ -110,7 +110,7 @@ export function FinancePaymentDetailsPage({ applicationId, onBack }: FinancePaym
|
|||||||
status: 'Verified'
|
status: 'Verified'
|
||||||
});
|
});
|
||||||
|
|
||||||
toast.success(`${activeType === 'INITIAL' ? 'Security Deposit' : 'First Fill'} verified and approved`);
|
toast.success(`${activeType === 'SECURITY_DEPOSIT' ? 'Security Deposit' : 'First Fill'} verified and approved`);
|
||||||
await fetchData();
|
await fetchData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error('Failed to verify payment');
|
toast.error('Failed to verify payment');
|
||||||
@ -134,7 +134,7 @@ export function FinancePaymentDetailsPage({ applicationId, onBack }: FinancePaym
|
|||||||
remarks: paymentDetails.verificationRemarks
|
remarks: paymentDetails.verificationRemarks
|
||||||
});
|
});
|
||||||
|
|
||||||
toast.error(`${activeType === 'INITIAL' ? 'Security Deposit' : 'First Fill'} rejected`);
|
toast.error(`${activeType === 'SECURITY_DEPOSIT' ? 'Security Deposit' : 'First Fill'} rejected`);
|
||||||
await fetchData();
|
await fetchData();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error('Failed to reject payment');
|
toast.error('Failed to reject payment');
|
||||||
@ -167,17 +167,17 @@ export function FinancePaymentDetailsPage({ applicationId, onBack }: FinancePaym
|
|||||||
<div className="flex gap-2 mt-2">
|
<div className="flex gap-2 mt-2">
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant={activeType === 'INITIAL' ? 'default' : 'outline'}
|
variant={activeType === 'SECURITY_DEPOSIT' ? 'default' : 'outline'}
|
||||||
className={activeType === 'INITIAL' ? 'bg-amber-600 hover:bg-amber-700' : ''}
|
className={activeType === 'SECURITY_DEPOSIT' ? 'bg-amber-600 hover:bg-amber-700' : ''}
|
||||||
onClick={() => setActiveType('INITIAL')}
|
onClick={() => setActiveType('SECURITY_DEPOSIT')}
|
||||||
>
|
>
|
||||||
Security Deposit
|
Security Deposit
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
variant={activeType === 'FINAL' ? 'default' : 'outline'}
|
variant={activeType === 'FIRST_FILL' ? 'default' : 'outline'}
|
||||||
className={activeType === 'FINAL' ? 'bg-amber-600 hover:bg-amber-700' : ''}
|
className={activeType === 'FIRST_FILL' ? 'bg-amber-600 hover:bg-amber-700' : ''}
|
||||||
onClick={() => setActiveType('FINAL')}
|
onClick={() => setActiveType('FIRST_FILL')}
|
||||||
>
|
>
|
||||||
First Fill
|
First Fill
|
||||||
</Button>
|
</Button>
|
||||||
@ -210,7 +210,7 @@ export function FinancePaymentDetailsPage({ applicationId, onBack }: FinancePaym
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-slate-900 font-bold">
|
<p className="text-slate-900 font-bold">
|
||||||
{activeType === 'INITIAL' ? 'Security Deposit' : 'First Fill'}
|
{activeType === 'SECURITY_DEPOSIT' ? 'Security Deposit' : 'First Fill'}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-slate-600">
|
<p className="text-sm text-slate-600">
|
||||||
{activeDeposit?.status === 'Verified'
|
{activeDeposit?.status === 'Verified'
|
||||||
@ -274,7 +274,7 @@ export function FinancePaymentDetailsPage({ applicationId, onBack }: FinancePaym
|
|||||||
<div className="p-4 bg-slate-50 rounded-lg border border-slate-200">
|
<div className="p-4 bg-slate-50 rounded-lg border border-slate-200">
|
||||||
<Label className="text-slate-500 block mb-1">Expected Amount</Label>
|
<Label className="text-slate-500 block mb-1">Expected Amount</Label>
|
||||||
<p className="text-2xl font-bold text-amber-900">
|
<p className="text-2xl font-bold text-amber-900">
|
||||||
₹{(activeType === 'INITIAL'
|
₹{(activeType === 'SECURITY_DEPOSIT'
|
||||||
? (configs.SECURITY_DEPOSIT?.amount || 500000)
|
? (configs.SECURITY_DEPOSIT?.amount || 500000)
|
||||||
: (configs.FIRST_FILL?.amount || 1500000)
|
: (configs.FIRST_FILL?.amount || 1500000)
|
||||||
).toLocaleString()}
|
).toLocaleString()}
|
||||||
@ -319,13 +319,13 @@ export function FinancePaymentDetailsPage({ applicationId, onBack }: FinancePaym
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
{application.uploadedDocuments?.filter((d: any) =>
|
{application.uploadedDocuments?.filter((d: any) =>
|
||||||
activeType === 'INITIAL'
|
activeType === 'SECURITY_DEPOSIT'
|
||||||
? d.documentType?.toLowerCase().includes('security') && d.documentType?.toLowerCase().includes('deposit')
|
? d.documentType?.toLowerCase().includes('security') && d.documentType?.toLowerCase().includes('deposit')
|
||||||
: d.documentType?.toLowerCase().includes('first') && d.documentType?.toLowerCase().includes('fill')
|
: d.documentType?.toLowerCase().includes('first') && d.documentType?.toLowerCase().includes('fill')
|
||||||
).length > 0 ? (
|
).length > 0 ? (
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
{application.uploadedDocuments.filter((d: any) =>
|
{application.uploadedDocuments.filter((d: any) =>
|
||||||
activeType === 'INITIAL'
|
activeType === 'SECURITY_DEPOSIT'
|
||||||
? d.documentType?.toLowerCase().includes('security') && d.documentType?.toLowerCase().includes('deposit')
|
? d.documentType?.toLowerCase().includes('security') && d.documentType?.toLowerCase().includes('deposit')
|
||||||
: d.documentType?.toLowerCase().includes('first') && d.documentType?.toLowerCase().includes('fill')
|
: d.documentType?.toLowerCase().includes('first') && d.documentType?.toLowerCase().includes('fill')
|
||||||
).map((doc: any, index: number) => (
|
).map((doc: any, index: number) => (
|
||||||
@ -393,7 +393,7 @@ export function FinancePaymentDetailsPage({ applicationId, onBack }: FinancePaym
|
|||||||
<Input
|
<Input
|
||||||
id="receivedAmount"
|
id="receivedAmount"
|
||||||
type="number"
|
type="number"
|
||||||
placeholder={(activeType === 'INITIAL' ? 500000 : 1500000).toString()}
|
placeholder={(activeType === 'SECURITY_DEPOSIT' ? 500000 : 1500000).toString()}
|
||||||
disabled={activeDeposit?.status === 'Verified'}
|
disabled={activeDeposit?.status === 'Verified'}
|
||||||
className="mt-1"
|
className="mt-1"
|
||||||
value={paymentDetails.receivedAmount}
|
value={paymentDetails.receivedAmount}
|
||||||
@ -468,10 +468,10 @@ export function FinancePaymentDetailsPage({ applicationId, onBack }: FinancePaym
|
|||||||
<CardContent className="text-xs text-slate-300 space-y-3">
|
<CardContent className="text-xs text-slate-300 space-y-3">
|
||||||
<p>Once verified, the following will occur:</p>
|
<p>Once verified, the following will occur:</p>
|
||||||
<ul className="list-disc pl-4 space-y-2">
|
<ul className="list-disc pl-4 space-y-2">
|
||||||
<li>Applicant status will advance to {activeType === 'INITIAL' ? 'LOI Issuance' : 'LOA Approval'}</li>
|
<li>Applicant status will advance to {activeType === 'SECURITY_DEPOSIT' ? 'LOI Issuance' : 'LOA Approval'}</li>
|
||||||
<li>Email notification will be sent to Applicant</li>
|
<li>Email notification will be sent to Applicant</li>
|
||||||
<li>Digital {activeType === 'INITIAL' ? 'LOI' : 'LOA'} generation will be unlocked</li>
|
<li>Digital {activeType === 'SECURITY_DEPOSIT' ? 'LOI' : 'LOA'} generation will be unlocked</li>
|
||||||
<li>This payment confirms the {activeType === 'INITIAL' ? 'Security Deposit' : 'First Fill'}</li>
|
<li>This payment confirms the {activeType === 'SECURITY_DEPOSIT' ? 'Security Deposit' : 'First Fill'}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@ -313,33 +313,33 @@ export function ResignationDetails({ resignationId, onBack, currentUser }: Resig
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-6">
|
<div className="grid grid-cols-2 md:grid-cols-3 gap-6">
|
||||||
<div>
|
|
||||||
<Label className="text-slate-600">Dealer Code</Label>
|
|
||||||
<p>{resignationData?.outlet?.code}</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-slate-600">Dealer Name</Label>
|
<Label className="text-slate-600">Dealer Name</Label>
|
||||||
<p>{resignationData?.outlet?.name}</p>
|
<p>{resignationData?.dealer?.fullName || resignationData?.outlet?.name}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-slate-600">GST</Label>
|
<Label className="text-slate-600">GST</Label>
|
||||||
<p>{resignationData?.outlet?.gstNumber || 'N/A'}</p>
|
<p>{resignationData?.dealer?.dealerProfile?.gstNumber || resignationData?.outlet?.gstNumber || 'N/A'}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label className="text-slate-600">Sales Code</Label>
|
||||||
|
<p>{resignationData?.dealer?.dealerProfile?.dealerCode?.salesCode || 'N/A'}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label className="text-slate-600">Service Code</Label>
|
||||||
|
<p>{resignationData?.dealer?.dealerProfile?.dealerCode?.serviceCode || 'N/A'}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label className="text-slate-600">GMA Code</Label>
|
||||||
|
<p>{resignationData?.dealer?.dealerProfile?.dealerCode?.gmaCode || 'N/A'}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label className="text-slate-600">Gear Code</Label>
|
||||||
|
<p>{resignationData?.dealer?.dealerProfile?.dealerCode?.gearCode || 'N/A'}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-2">
|
<div className="col-span-2">
|
||||||
<Label className="text-slate-600">Address</Label>
|
<Label className="text-slate-600">Address</Label>
|
||||||
<p>{resignationData?.outlet?.address}</p>
|
<p>{resignationData?.dealer?.dealerProfile?.registeredAddress || resignationData?.outlet?.address}</p>
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label className="text-slate-600">City</Label>
|
|
||||||
<p>{resignationData?.outlet?.city}</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label className="text-slate-600">State</Label>
|
|
||||||
<p>{resignationData?.outlet?.state}</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label className="text-slate-600">Region</Label>
|
|
||||||
<p>{resignationData?.outlet?.region}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
@ -353,11 +353,19 @@ export function ResignationDetails({ resignationId, onBack, currentUser }: Resig
|
|||||||
<div className="grid grid-cols-2 md:grid-cols-3 gap-6">
|
<div className="grid grid-cols-2 md:grid-cols-3 gap-6">
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-slate-600">Inauguration</Label>
|
<Label className="text-slate-600">Inauguration</Label>
|
||||||
<p>{resignationData?.outlet?.inaugurationDate ? new Date(resignationData.outlet.inaugurationDate).toLocaleDateString() : 'N/A'}</p>
|
<p>{resignationData?.dealer?.dealerProfile?.onboardedAt ? formatDateTime(resignationData.dealer.dealerProfile.onboardedAt, 'date') : (resignationData?.outlet?.inaugurationDate ? new Date(resignationData.outlet.inaugurationDate).toLocaleDateString() : 'N/A')}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label className="text-slate-600">LOA Date</Label>
|
||||||
|
<p>{resignationData?.dealer?.dealerProfile?.loaDate ? formatDateTime(resignationData.dealer.dealerProfile.loaDate, 'date') : 'N/A'}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label className="text-slate-600">LOI Date</Label>
|
||||||
|
<p>{resignationData?.dealer?.dealerProfile?.loiDate ? formatDateTime(resignationData.dealer.dealerProfile.loiDate, 'date') : 'N/A'}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-slate-600">Dealership Type</Label>
|
<Label className="text-slate-600">Dealership Type</Label>
|
||||||
<p>{resignationData?.outlet?.type || 'N/A'}</p>
|
<p>{resignationData?.dealer?.dealerProfile?.application?.businessType || resignationData?.outlet?.type || 'N/A'}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-slate-600">City Category</Label>
|
<Label className="text-slate-600">City Category</Label>
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '.
|
|||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table';
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../ui/table';
|
||||||
import { Alert, AlertDescription, AlertTitle } from '../ui/alert';
|
import { Alert, AlertDescription, AlertTitle } from '../ui/alert';
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import { User, mockWorkNotes } from '../../lib/mock-data';
|
import { User } from '../../lib/mock-data';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import { terminationService } from '../../services/termination.service';
|
import { terminationService } from '../../services/termination.service';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
@ -305,7 +305,7 @@ export function TerminationDetails({ terminationId, onBack, currentUser }: Termi
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const workNotesCount = mockWorkNotes.length;
|
const workNotesCount = (request.worknotes || []).length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
@ -326,7 +326,7 @@ export function TerminationDetails({ terminationId, onBack, currentUser }: Termi
|
|||||||
</Button>
|
</Button>
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-2xl">{request.requestId || terminationId}</h1>
|
<h1 className="text-2xl">{request.requestId || terminationId}</h1>
|
||||||
<p className="text-slate-600">{request.dealer?.businessName || request.dealerName}</p>
|
<p className="text-slate-600">{request.dealer?.businessName || request.dealer?.legalName || 'Termination'}</p>
|
||||||
</div>
|
</div>
|
||||||
<Badge className={getSeverityColor(request.severity)}>
|
<Badge className={getSeverityColor(request.severity)}>
|
||||||
{request.severity}
|
{request.severity}
|
||||||
@ -438,9 +438,9 @@ export function TerminationDetails({ terminationId, onBack, currentUser }: Termi
|
|||||||
className="relative hover:bg-red-50 hover:border-red-300 hover:text-red-700 transition-all shadow-sm"
|
className="relative hover:bg-red-50 hover:border-red-300 hover:text-red-700 transition-all shadow-sm"
|
||||||
onClick={() => navigate(`/worknotes/termination/${terminationId}`, {
|
onClick={() => navigate(`/worknotes/termination/${terminationId}`, {
|
||||||
state: {
|
state: {
|
||||||
applicationName: terminationData?.dealerName || 'Termination',
|
applicationName: request?.dealer?.businessName || 'Termination',
|
||||||
registrationNumber: terminationId || '',
|
registrationNumber: terminationId || '',
|
||||||
participants: terminationData?.participants || []
|
participants: request?.participants || []
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
@ -516,7 +516,11 @@ export function TerminationDetails({ terminationId, onBack, currentUser }: Termi
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-slate-600">GMA Code</Label>
|
<Label className="text-slate-600">GMA Code</Label>
|
||||||
<p>{request.dealer?.dealerCode?.gmaCode || request.gmaCode || 'N/A'}</p>
|
<p>{request.dealer?.dealerCode?.gmaCode || 'N/A'}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Label className="text-slate-600">Gear Code</Label>
|
||||||
|
<p>{request.dealer?.dealerCode?.gearCode || 'N/A'}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
@ -533,12 +537,12 @@ export function TerminationDetails({ terminationId, onBack, currentUser }: Termi
|
|||||||
<p>{request.dealer?.onboardedAt ? formatDateTime(request.dealer.onboardedAt, 'date') : (request.inauguration || 'N/A')}</p>
|
<p>{request.dealer?.onboardedAt ? formatDateTime(request.dealer.onboardedAt, 'date') : (request.inauguration || 'N/A')}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-slate-600">LOA</Label>
|
<Label className="text-slate-600">LOA Date</Label>
|
||||||
<p>{request.loa || 'N/A'}</p>
|
<p>{request.dealer?.loaDate ? formatDateTime(request.dealer.loaDate, 'date') : 'N/A'}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-slate-600">LOI</Label>
|
<Label className="text-slate-600">LOI Date</Label>
|
||||||
<p>{request.loi || 'N/A'}</p>
|
<p>{request.dealer?.loiDate ? formatDateTime(request.dealer.loiDate, 'date') : 'N/A'}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-slate-600">Last 6 Months Sales</Label>
|
<Label className="text-slate-600">Last 6 Months Sales</Label>
|
||||||
|
|||||||
@ -253,32 +253,55 @@ export function WorkNotesPage(props: Partial<WorkNotesPageProps>) {
|
|||||||
}
|
}
|
||||||
}, [requestId, requestType, socket]);
|
}, [requestId, requestType, socket]);
|
||||||
|
|
||||||
// Fetch application details if metadata or participants are missing (e.g. on refresh)
|
// Fetch details if metadata or participants are missing (e.g. on refresh)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (requestId && requestType === 'application') {
|
if (!requestId || !requestType) return;
|
||||||
const fetchApplicationDetails = async () => {
|
|
||||||
|
const fetchDetails = async () => {
|
||||||
try {
|
try {
|
||||||
const appData = await onboardingService.getApplicationById(requestId);
|
let data: any = null;
|
||||||
if (appData) {
|
if (requestType === 'application') {
|
||||||
// Update participants if not provided
|
data = await onboardingService.getApplicationById(requestId);
|
||||||
if (externalParticipants.length === 0 && appData.participants) {
|
if (data) {
|
||||||
setExternalParticipants(appData.participants);
|
if (externalParticipants.length === 0 && data.participants) setExternalParticipants(data.participants);
|
||||||
|
if (!appName || appName === 'Application') setAppName(data.companyName || 'Application');
|
||||||
|
if (!regNumber) setRegNumber(data.registrationNumber || '');
|
||||||
}
|
}
|
||||||
// Update metadata if not provided via props/state
|
} else if (requestType === 'termination') {
|
||||||
if (!props.applicationName && !location.state?.applicationName && appData.companyName) {
|
const { API } = await import('../../api/API');
|
||||||
setAppName(appData.companyName);
|
const res: any = await API.getTerminationById(requestId);
|
||||||
|
if (res.data?.success) {
|
||||||
|
data = res.data.termination;
|
||||||
|
if (externalParticipants.length === 0 && data.participants) setExternalParticipants(data.participants);
|
||||||
|
if (!appName || appName === 'Application' || appName === 'Termination') setAppName(data.dealer?.businessName || 'Termination');
|
||||||
|
if (!regNumber) setRegNumber(data.requestId || '');
|
||||||
}
|
}
|
||||||
if (!props.registrationNumber && !location.state?.registrationNumber && appData.registrationNumber) {
|
} else if (requestType === 'constitutional' || requestType === 'constitutional-change') {
|
||||||
setRegNumber(appData.registrationNumber);
|
const { API } = await import('../../api/API');
|
||||||
|
const res: any = await API.getConstitutionalChangeById(requestId);
|
||||||
|
if (res.data?.success) {
|
||||||
|
data = res.data.request;
|
||||||
|
if (externalParticipants.length === 0 && data.participants) setExternalParticipants(data.participants);
|
||||||
|
if (!appName || appName === 'Application' || appName === 'Constitutional Change') setAppName(data.outlet?.name || 'Constitutional Change');
|
||||||
|
if (!regNumber) setRegNumber(data.requestId || '');
|
||||||
|
}
|
||||||
|
} else if (requestType === 'resignation') {
|
||||||
|
const { API } = await import('../../api/API');
|
||||||
|
const res: any = await API.getResignationById(requestId);
|
||||||
|
if (res.data?.success) {
|
||||||
|
data = res.data.resignation;
|
||||||
|
if (externalParticipants.length === 0 && data.participants) setExternalParticipants(data.participants);
|
||||||
|
if (!appName || appName === 'Application' || appName === 'Resignation') setAppName(data.dealer?.businessName || 'Resignation');
|
||||||
|
if (!regNumber) setRegNumber(data.resignationId || '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to fetch application details:', error);
|
console.error(`Failed to fetch ${requestType} details:`, error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fetchApplicationDetails();
|
|
||||||
}
|
fetchDetails();
|
||||||
}, [requestId, requestType, externalParticipants.length, props.applicationName, props.registrationNumber, location.state]);
|
}, [requestId, requestType, externalParticipants.length, appName, regNumber]);
|
||||||
|
|
||||||
// Auto-scroll logic
|
// Auto-scroll logic
|
||||||
const messagesEndRef = useRef<HTMLDivElement>(null);
|
const messagesEndRef = useRef<HTMLDivElement>(null);
|
||||||
|
|||||||
@ -311,7 +311,11 @@ export function FinanceDashboard({ onNavigate, onViewPaymentDetails, onViewAudit
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-slate-600">Type</p>
|
<p className="text-slate-600">Type</p>
|
||||||
<p>{app.paymentType}</p>
|
<p>
|
||||||
|
{app.paymentType === 'SECURITY_DEPOSIT' ? 'Security Deposit' :
|
||||||
|
app.paymentType === 'FIRST_FILL' ? 'First Fill' :
|
||||||
|
app.paymentType}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-slate-600">Amount</p>
|
<p className="text-slate-600">Amount</p>
|
||||||
@ -384,7 +388,11 @@ export function FinanceDashboard({ onNavigate, onViewPaymentDetails, onViewAudit
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-slate-600">Type</p>
|
<p className="text-slate-600">Type</p>
|
||||||
<p>{app.paymentType}</p>
|
<p>
|
||||||
|
{app.paymentType === 'SECURITY_DEPOSIT' ? 'Security Deposit' :
|
||||||
|
app.paymentType === 'FIRST_FILL' ? 'First Fill' :
|
||||||
|
app.paymentType}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p className="text-slate-600">Amount</p>
|
<p className="text-slate-600">Amount</p>
|
||||||
|
|||||||
@ -137,6 +137,7 @@ export interface Application {
|
|||||||
areaId?: string;
|
areaId?: string;
|
||||||
districtId?: string;
|
districtId?: string;
|
||||||
fddAssignments?: any[];
|
fddAssignments?: any[];
|
||||||
|
statutoryStatus?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Participant {
|
export interface Participant {
|
||||||
@ -157,6 +158,7 @@ export interface User {
|
|||||||
email: string;
|
email: string;
|
||||||
password: string;
|
password: string;
|
||||||
role: UserRole;
|
role: UserRole;
|
||||||
|
roleCode?: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,8 @@ export const initializeAuth = createAsyncThunk(
|
|||||||
name: user.fullName || user.email.split('@')[0],
|
name: user.fullName || user.email.split('@')[0],
|
||||||
email: user.email,
|
email: user.email,
|
||||||
password: '',
|
password: '',
|
||||||
role: typeof user.role === 'string' ? user.role : (user.roleCode || 'User')
|
role: typeof user.role === 'string' ? user.role : (user.roleCode || 'User'),
|
||||||
|
roleCode: user.roleCode || (typeof user.role === 'string' ? user.role : 'User')
|
||||||
} as User,
|
} as User,
|
||||||
token
|
token
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user