multi iteration done in approval flow for progress stsus

This commit is contained in:
laxman h 2026-04-01 18:03:19 +05:30
parent e68f96a929
commit 7fa34dd3d6
10 changed files with 730 additions and 495 deletions

View File

@ -69,6 +69,7 @@ export const API = {
getInterviews: (applicationId: string) => client.get(`/assessment/interviews/${applicationId}`), getInterviews: (applicationId: string) => client.get(`/assessment/interviews/${applicationId}`),
updateRecommendation: (data: any) => client.post('/assessment/recommendation', data), updateRecommendation: (data: any) => client.post('/assessment/recommendation', data),
updateInterviewDecision: (data: any) => client.post('/assessment/decision', data), updateInterviewDecision: (data: any) => client.post('/assessment/decision', data),
submitStageDecision: (data: any) => client.post('/assessment/stage-decision', data),
getInterviewApprovalStatus: (interviewId: string) => client.get(`/assessment/interviews/${interviewId}/approval-status`), getInterviewApprovalStatus: (interviewId: string) => client.get(`/assessment/interviews/${interviewId}/approval-status`),
getApprovalPolicies: () => client.get('/assessment/approval-policies'), getApprovalPolicies: () => client.get('/assessment/approval-policies'),
upsertApprovalPolicy: (stageCode: string, data: any) => client.put(`/assessment/approval-policies/${stageCode}`, data), upsertApprovalPolicy: (stageCode: string, data: any) => client.put(`/assessment/approval-policies/${stageCode}`, data),

View File

@ -8,7 +8,7 @@ const client = create({
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Accept': 'application/json', 'Accept': 'application/json',
}, },
timeout: 10000, timeout: 30000,
}); });
// Interceptor for Auth Token // Interceptor for Auth Token
@ -23,7 +23,13 @@ client.addRequestTransform((request) => {
client.addResponseTransform((response) => { client.addResponseTransform((response) => {
if (!response.ok) { if (!response.ok) {
if (response.status === 401) { if (response.status === 401) {
console.error('Unauthorized access - potential token expiration'); const token = localStorage.getItem('token');
console.error('Unauthorized access - potential token expiration. Token exists in localStorage:', !!token);
console.error('Full 401 Response Details:', {
url: response.config?.url,
method: response.config?.method,
data: response.data
});
// Dispatch global event for App to handle logout // Dispatch global event for App to handle logout
window.dispatchEvent(new Event('auth:logout')); window.dispatchEvent(new Event('auth:logout'));
} }

View File

@ -46,7 +46,6 @@ export function UserManagementPage() {
const [regions, setRegions] = useState<any[]>([]); const [regions, setRegions] = useState<any[]>([]);
const [states, setStates] = useState<any[]>([]); const [states, setStates] = useState<any[]>([]);
const [districts, setDistricts] = useState<any[]>([]); const [districts, setDistricts] = useState<any[]>([]);
const [areas, setAreas] = useState<any[]>([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [searchQuery, setSearchQuery] = useState(''); const [searchQuery, setSearchQuery] = useState('');
@ -69,8 +68,7 @@ export function UserManagementPage() {
zoneId: '', zoneId: '',
regionId: '', regionId: '',
stateId: '', stateId: '',
districtId: '', districtId: ''
areaId: ''
}); });
useEffect(() => { useEffect(() => {
@ -120,15 +118,9 @@ export function UserManagementPage() {
} }
}, [formData.stateId]); }, [formData.stateId]);
// Load areas when district changes // Load areas when district changes (Disabled)
useEffect(() => { useEffect(() => {
if (formData.districtId) { // Area selection removed as per user request
masterService.getAreas(formData.districtId).then((res: any) => {
if (res && res.success) setAreas(normalizeList(res, 'areas'));
});
} else {
setAreas([]);
}
}, [formData.districtId]); }, [formData.districtId]);
const handleEditUser = (user: any) => { const handleEditUser = (user: any) => {
@ -139,8 +131,7 @@ export function UserManagementPage() {
const regionId = user.regionId || (userLocationType === 'region' ? userLocation?.id : getParentIdByType(userLocation, 'region')); const regionId = user.regionId || (userLocationType === 'region' ? userLocation?.id : getParentIdByType(userLocation, 'region'));
const stateId = user.stateId || (userLocationType === 'state' ? userLocation?.id : getParentIdByType(userLocation, 'state')); const stateId = user.stateId || (userLocationType === 'state' ? userLocation?.id : getParentIdByType(userLocation, 'state'));
const districtId = user.districtId || (userLocationType === 'district' ? userLocation?.id : getParentIdByType(userLocation, 'district')); const districtId = user.districtId || (userLocationType === 'district' ? userLocation?.id : getParentIdByType(userLocation, 'district'));
const areaId = user.areaId || (userLocationType === 'area' ? userLocation?.id : '');
setEditingUser(user); setEditingUser(user);
setFormData({ setFormData({
fullName: user.fullName || '', fullName: user.fullName || '',
@ -155,8 +146,7 @@ export function UserManagementPage() {
zoneId: zoneId || '', zoneId: zoneId || '',
regionId: regionId || '', regionId: regionId || '',
stateId: stateId || '', stateId: stateId || '',
districtId: districtId || '', districtId: districtId || ''
areaId: areaId || ''
}); });
setShowUserModal(true); setShowUserModal(true);
}; };
@ -168,7 +158,7 @@ export function UserManagementPage() {
} }
try { try {
const userLocationId = formData.areaId || formData.districtId || formData.stateId || formData.regionId || formData.zoneId || null; const userLocationId = formData.districtId || formData.stateId || formData.regionId || formData.zoneId || null;
const submitData = { const submitData = {
...formData, ...formData,
locationId: userLocationId locationId: userLocationId
@ -187,7 +177,7 @@ export function UserManagementPage() {
setFormData({ setFormData({
fullName: '', email: '', roleCode: '', status: 'active', isActive: true, fullName: '', email: '', roleCode: '', status: 'active', isActive: true,
mobileNumber: '', department: '', designation: '', employeeId: '', mobileNumber: '', department: '', designation: '', employeeId: '',
zoneId: '', regionId: '', stateId: '', districtId: '', areaId: '' zoneId: '', regionId: '', stateId: '', districtId: ''
}); });
setShowUserModal(false); setShowUserModal(false);
fetchData(); fetchData();
@ -236,7 +226,7 @@ export function UserManagementPage() {
setEditingUser(null); setFormData({ setEditingUser(null); setFormData({
fullName: '', email: '', roleCode: '', status: 'active', isActive: true, fullName: '', email: '', roleCode: '', status: 'active', isActive: true,
mobileNumber: '', department: '', designation: '', employeeId: '', mobileNumber: '', department: '', designation: '', employeeId: '',
zoneId: '', regionId: '', stateId: '', districtId: '', areaId: '' zoneId: '', regionId: '', stateId: '', districtId: ''
}); setShowUserModal(true); }); setShowUserModal(true);
}} }}
className="bg-amber-600 hover:bg-amber-700 text-white shrink-0" className="bg-amber-600 hover:bg-amber-700 text-white shrink-0"
@ -506,7 +496,7 @@ export function UserManagementPage() {
<Label htmlFor="zoneId">Zone (Top Level)</Label> <Label htmlFor="zoneId">Zone (Top Level)</Label>
<Select <Select
value={formData.zoneId} value={formData.zoneId}
onValueChange={(val) => setFormData({ ...formData, zoneId: val, regionId: '', stateId: '', districtId: '', areaId: '' })} onValueChange={(val) => setFormData({ ...formData, zoneId: val, regionId: '', stateId: '', districtId: '' })}
> >
<SelectTrigger id="zoneId"> <SelectTrigger id="zoneId">
<SelectValue placeholder="Select Zone" /> <SelectValue placeholder="Select Zone" />
@ -539,7 +529,7 @@ export function UserManagementPage() {
<Label htmlFor="stateId">State</Label> <Label htmlFor="stateId">State</Label>
<Select <Select
value={formData.stateId} value={formData.stateId}
onValueChange={(val) => setFormData({ ...formData, stateId: val, districtId: '', areaId: '' })} onValueChange={(val) => setFormData({ ...formData, stateId: val, districtId: '' })}
disabled={!formData.zoneId} disabled={!formData.zoneId}
> >
<SelectTrigger id="stateId"> <SelectTrigger id="stateId">
@ -556,7 +546,7 @@ export function UserManagementPage() {
<Label htmlFor="districtId">District</Label> <Label htmlFor="districtId">District</Label>
<Select <Select
value={formData.districtId} value={formData.districtId}
onValueChange={(val) => setFormData({ ...formData, districtId: val, areaId: '' })} onValueChange={(val) => setFormData({ ...formData, districtId: val })}
disabled={!formData.stateId} disabled={!formData.stateId}
> >
<SelectTrigger id="districtId"> <SelectTrigger id="districtId">
@ -569,23 +559,6 @@ export function UserManagementPage() {
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
<div className="grid gap-2">
<Label htmlFor="areaId">Area</Label>
<Select
value={formData.areaId}
onValueChange={(val) => setFormData({ ...formData, areaId: val })}
disabled={!formData.districtId}
>
<SelectTrigger id="areaId">
<SelectValue placeholder="Select Area" />
</SelectTrigger>
<SelectContent>
{areas.filter(a => (a.parents && a.parents.some((p:any) => p.id === formData.districtId)) || a.districtId === formData.districtId).map(area => (
<SelectItem key={area.id} value={area.id}>{area.name || area.areaName}</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div> </div>
</div> </div>
</div> </div>

File diff suppressed because it is too large Load Diff

View File

@ -152,17 +152,24 @@ export function WorkNotesPage(props: Partial<WorkNotesPageProps>) {
// Map backend participants to the UI sub-format // Map backend participants to the UI sub-format
// Handles both nested structure { user: { id, fullName } } and flat { id, userId, name/fullName } // Handles both nested structure { user: { id, fullName } } and flat { id, userId, name/fullName }
// NOTE: p.id is the RequestParticipant record ID. p.userId or p.user?.id is the actual User ID. // NOTE: p.id is the RequestParticipant record ID. p.userId or p.user?.id is the actual User ID.
const participantsList: ParticipantUI[] = externalParticipants.map((p: any) => { // Map backend participants to the UI sub-format and ensure uniqueness by User ID to avoid duplicates in mentions
const participantsList: ParticipantUI[] = [];
const seenIds = new Set<string>();
externalParticipants.forEach((p: any) => {
const id = p.user?.id || p.userId || p.id || ''; const id = p.user?.id || p.userId || p.id || '';
const name = p.user?.fullName || p.user?.name || p.fullName || p.name || 'Unknown User'; if (id && !seenIds.has(id)) {
const email = p.user?.email || p.email || ''; seenIds.add(id);
return { const name = p.user?.fullName || p.user?.name || p.fullName || p.name || 'Unknown User';
id, const email = p.user?.email || p.email || '';
name, participantsList.push({
email, id,
initials: getInitials(name), name,
color: getAvatarColor(name) email,
}; initials: getInitials(name),
color: getAvatarColor(name)
});
}
}); });
console.log('Participants list for mentions:', participantsList.map(p => ({ id: p.id, name: p.name }))); console.log('Participants list for mentions:', participantsList.map(p => ({ id: p.id, name: p.name })));

View File

@ -3,7 +3,7 @@ import { Button } from '../ui/button';
import { Input } from '../ui/input'; import { Input } from '../ui/input';
import { Label } from '../ui/label'; import { Label } from '../ui/label';
import { Checkbox } from '../ui/checkbox'; import { Checkbox } from '../ui/checkbox';
import { AlertCircle, Copy, Check } from 'lucide-react'; import { AlertCircle, Copy, Check, Eye, EyeOff } from 'lucide-react';
import { mockUsers } from '../../lib/mock-data'; import { mockUsers } from '../../lib/mock-data';
import { toast } from 'sonner'; import { toast } from 'sonner';
@ -18,6 +18,7 @@ export function LoginPage({ onLogin }: LoginPageProps) {
const [error, setError] = useState(''); const [error, setError] = useState('');
const [showForgotPassword, setShowForgotPassword] = useState(false); const [showForgotPassword, setShowForgotPassword] = useState(false);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [showPassword, setShowPassword] = useState(false);
const [copiedIndex, setCopiedIndex] = useState<number | null>(null); const [copiedIndex, setCopiedIndex] = useState<number | null>(null);
const copyToClipboard = async (text: string, index: number) => { const copyToClipboard = async (text: string, index: number) => {
@ -144,15 +145,29 @@ export function LoginPage({ onLogin }: LoginPageProps) {
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="password">Password</Label> <Label htmlFor="password">Password</Label>
<Input <div className="relative">
id="password" <Input
type="password" id="password"
placeholder="Enter your password" type={showPassword ? "text" : "password"}
value={password} placeholder="Enter your password"
onChange={(e) => setPassword(e.target.value)} value={password}
className="w-full" onChange={(e) => setPassword(e.target.value)}
disabled={isLoading} className="w-full pr-10"
/> disabled={isLoading}
/>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 hover:text-slate-600 focus:outline-none"
disabled={isLoading}
>
{showPassword ? (
<EyeOff className="w-5 h-5" />
) : (
<Eye className="w-5 h-5" />
)}
</button>
</div>
</div> </div>
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">

View File

@ -6,7 +6,7 @@ import { Textarea } from '../ui/textarea';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select';
import { RadioGroup, RadioGroupItem } from '../ui/radio-group'; import { RadioGroup, RadioGroupItem } from '../ui/radio-group';
import { Checkbox } from '../ui/checkbox'; import { Checkbox } from '../ui/checkbox';
import { CheckCircle, Users, Star, Shield, LogIn, Award, TrendingUp, Handshake } from 'lucide-react'; import { CheckCircle, Users, Star, LogIn, Award, TrendingUp, Handshake } from 'lucide-react';
import { toast } from 'sonner'; import { toast } from 'sonner';
// import backgroundImage from 'figma:asset/ee01d864b6e23a8197b42f3168c98eedec9d2440.png'; // import backgroundImage from 'figma:asset/ee01d864b6e23a8197b42f3168c98eedec9d2440.png';
import { onboardingService } from '../../services/onboarding.service'; import { onboardingService } from '../../services/onboarding.service';
@ -52,7 +52,9 @@ export function ApplicationFormPage({ onAdminLogin }: ApplicationFormPageProps)
try { try {
// ZoneID is optional, public API should return all states if no zone override // ZoneID is optional, public API should return all states if no zone override
const response: any = await masterService.getStates(); const response: any = await masterService.getStates();
if (response && response.states) { if (response && response.data) {
setStates(response.data);
} else if (response && response.states) {
setStates(response.states); setStates(response.states);
} }
} catch (error) { } catch (error) {
@ -72,7 +74,9 @@ export function ApplicationFormPage({ onAdminLogin }: ApplicationFormPageProps)
try { try {
const response: any = await masterService.getDistricts(selectedState.id); const response: any = await masterService.getDistricts(selectedState.id);
if (response && response.districts) { if (response && response.data) {
setDistricts(response.data);
} else if (response && response.districts) {
setDistricts(response.districts); setDistricts(response.districts);
} }
} catch (error) { } catch (error) {
@ -112,8 +116,8 @@ export function ApplicationFormPage({ onAdminLogin }: ApplicationFormPageProps)
try { try {
const selectedState = states.find((s: any) => s.id === formData.stateId); const selectedState = states.find((s: any) => s.id === formData.stateId);
const selectedDistrict = districts.find((d: any) => d.id === formData.districtId); const selectedDistrict = districts.find((d: any) => d.id === formData.districtId);
const stateName = selectedState?.stateName || ''; const stateName = selectedState?.name || selectedState?.stateName || '';
const districtName = selectedDistrict?.districtName || ''; const districtName = selectedDistrict?.name || selectedDistrict?.districtName || '';
// Map form data to backend expected format // Map form data to backend expected format
const payload = { const payload = {
@ -409,7 +413,7 @@ export function ApplicationFormPage({ onAdminLogin }: ApplicationFormPageProps)
<SelectContent className="bg-slate-800 border-slate-700 text-white h-64"> <SelectContent className="bg-slate-800 border-slate-700 text-white h-64">
{states.map((state: any) => ( {states.map((state: any) => (
<SelectItem key={state.id} value={state.id}> <SelectItem key={state.id} value={state.id}>
{state.stateName} {state.name || state.stateName}
</SelectItem> </SelectItem>
))} ))}
</SelectContent> </SelectContent>
@ -431,7 +435,7 @@ export function ApplicationFormPage({ onAdminLogin }: ApplicationFormPageProps)
<SelectContent className="bg-slate-800 border-slate-700 text-white h-64"> <SelectContent className="bg-slate-800 border-slate-700 text-white h-64">
{districts.map((district: any) => ( {districts.map((district: any) => (
<SelectItem key={district.id} value={district.id}> <SelectItem key={district.id} value={district.id}>
{district.districtName} {district.name || district.districtName}
</SelectItem> </SelectItem>
))} ))}
</SelectContent> </SelectContent>

View File

@ -57,7 +57,8 @@ export type ApplicationStatus =
| 'Inauguration' | 'Inauguration'
| 'Approved' | 'Approved'
| 'Rejected' | 'Rejected'
| 'Disqualified'; | 'Disqualified'
| 'Onboarded';
export interface Application { export interface Application {
id: string; id: string;
@ -107,7 +108,12 @@ export interface Application {
architectureDocumentDate?: string; architectureDocumentDate?: string;
architectureCompletionDate?: string; architectureCompletionDate?: string;
inaugurationDate?: string; inaugurationDate?: string;
onboardedDate?: string;
questionnaireDate?: string;
shortlistDate?: string;
progressTracking?: any[];
questionnaireResponses?: any[]; // added for response view questionnaireResponses?: any[]; // added for response view
stageApprovals?: any[];
participants?: Participant[]; participants?: Participant[];
architectureAssignedTo?: string; architectureAssignedTo?: string;
architectureStatus?: string; architectureStatus?: string;

View File

@ -141,7 +141,6 @@ const PublicQuestionnairePage: React.FC = () => {
const activeQuestions = questions.filter(q => q.sectionName === activeSection); const activeQuestions = questions.filter(q => q.sectionName === activeSection);
const currentSectionIndex = sections.indexOf(activeSection); const currentSectionIndex = sections.indexOf(activeSection);
const totalMarks = questions.reduce((sum, q) => sum + (Number(q.weight) || 0), 0);
return ( return (
<div className="flex-1 flex flex-col overflow-hidden h-screen bg-slate-50"> <div className="flex-1 flex flex-col overflow-hidden h-screen bg-slate-50">
@ -219,11 +218,6 @@ const PublicQuestionnairePage: React.FC = () => {
<div className="text-amber-400 text-2xl font-bold">{sections.length}</div> <div className="text-amber-400 text-2xl font-bold">{sections.length}</div>
<div className="text-slate-400 text-xs uppercase tracking-wider">Sections</div> <div className="text-slate-400 text-xs uppercase tracking-wider">Sections</div>
</div> </div>
<div className="h-10 w-px bg-slate-700"></div>
<div className="text-center px-4">
<div className="text-amber-400 text-2xl font-bold">{totalMarks}</div>
<div className="text-slate-400 text-xs uppercase tracking-wider">Total Marks</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -282,11 +276,6 @@ const PublicQuestionnairePage: React.FC = () => {
{q.questionText} {q.questionText}
{q.isMandatory && <span className="text-red-500 ml-1">*</span>} {q.isMandatory && <span className="text-red-500 ml-1">*</span>}
</label> </label>
{q.weight > 0 && (
<span className="shrink-0 px-2 py-1 bg-slate-100 text-slate-600 text-xs font-semibold rounded border border-slate-200">
{q.weight} Marks
</span>
)}
</div> </div>
<div className="max-w-xl"> <div className="max-w-xl">

View File

@ -2,200 +2,117 @@ import { API } from '../api/API';
export const onboardingService = { export const onboardingService = {
submitApplication: async (data: any) => { submitApplication: async (data: any) => {
try { const response: any = await API.submitApplication(data);
const response: any = await API.submitApplication(data); if (!response.ok) throw new Error(response.data?.message || 'Failed to submit application');
return response.data; return response.data;
} catch (error) {
console.error('Submit application error:', error);
throw error;
}
}, },
getApplications: async () => { getApplications: async () => {
try { const response: any = await API.getApplications();
const response: any = await API.getApplications(); if (!response.ok) throw new Error(response.data?.message || 'Failed to fetch applications');
return response.data?.data || response.data; return response.data?.data || response.data;
} catch (error) {
console.error('Get applications error:', error);
throw error;
}
}, },
shortlistApplications: async (applicationIds: string[], assignedTo: string[], remarks?: string) => { shortlistApplications: async (applicationIds: string[], assignedTo: string[], remarks?: string) => {
try { const response: any = await API.shortlistApplications({ applicationIds, assignedTo, remarks });
const response: any = await API.shortlistApplications({ applicationIds, assignedTo, remarks }); if (!response.ok) throw new Error(response.data?.message || 'Failed to shortlist applications');
return response.data; return response.data;
} catch (error) {
console.error('Shortlist applications error:', error);
throw error;
}
}, },
getApplicationById: async (id: string) => { getApplicationById: async (id: string) => {
try { const response: any = await API.getApplicationById(id);
const response: any = await API.getApplicationById(id); if (!response.ok) {
return response.data?.data || response.data; console.error('API Error Response:', response.status, response.data);
} catch (error) { throw new Error(response.data?.message || 'Failed to fetch application details');
console.error('Get application by id error:', error);
throw error;
} }
return response.data?.data || response.data;
}, },
getUsers: async (params?: any) => { getUsers: async (params?: any) => {
try { const response: any = await API.getUsers(params);
const response: any = await API.getUsers(params); if (!response.ok) throw new Error(response.data?.message || 'Failed to fetch users');
return response.data?.data || response.data; return response.data?.data || response.data;
} catch (error) {
console.error('Get users error:', error);
throw error;
}
}, },
addParticipant: async (data: any) => { addParticipant: async (data: any) => {
try { const response: any = await API.addParticipant(data);
const response: any = await API.addParticipant(data); if (!response.ok) throw new Error(response.data?.message || 'Failed to add participant');
return response.data; return response.data;
} catch (error) {
console.error('Add participant error:', error);
throw error;
}
}, },
scheduleInterview: async (data: any) => { scheduleInterview: async (data: any) => {
try { const response: any = await API.scheduleInterview(data);
const response: any = await API.scheduleInterview(data); if (!response.ok) throw new Error(response.data?.message || 'Failed to schedule interview');
return response.data; return response.data;
} catch (error) { },
console.error('Schedule interview error:', error); updateInterview: async (id: string, data: any) => {
throw error; const response: any = await API.updateInterview(id, data);
} if (!response.ok) throw new Error(response.data?.message || 'Failed to update interview');
return response.data;
}, },
getInterviews: async (applicationId: string) => { getInterviews: async (applicationId: string) => {
try { const response: any = await API.getInterviews(applicationId);
const response: any = await API.getInterviews(applicationId); if (!response.ok) throw new Error(response.data?.message || 'Failed to fetch interviews');
const data = response.data?.data || response.data; const data = response.data?.data || response.data;
return Array.isArray(data) ? data : []; return Array.isArray(data) ? data : [];
} catch (error) {
console.error('Get interviews error:', error);
throw error;
}
}, },
getDocuments: async (id: string) => { getDocuments: async (id: string) => {
try { const response: any = await API.getDocuments(id);
const response: any = await API.getDocuments(id); if (!response.ok) throw new Error(response.data?.message || 'Failed to fetch documents');
return response.data?.data || response.data; return response.data?.data || response.data;
} catch (error) {
console.error('Get documents error:', error);
throw error;
}
}, },
uploadDocument: async (id: string, data: any) => { uploadDocument: async (id: string, data: any) => {
try { const response: any = await API.uploadDocument(id, data);
const response: any = await API.uploadDocument(id, data); if (!response.ok) throw new Error(response.data?.message || 'Failed to upload document');
return response.data; return response.data;
} catch (error) {
console.error('Upload document error:', error);
throw error;
}
}, },
submitKTMatrix: async (data: any) => { submitKTMatrix: async (data: any) => {
try { const response: any = await API.submitKTMatrix(data);
const response: any = await API.submitKTMatrix(data); if (!response.ok) throw new Error(response.data?.message || 'Failed to submit KT Matrix');
if (response.ok) { return response.data;
return response.data;
} else {
throw new Error(response.problem || 'Failed to submit KT Matrix');
}
} catch (error) {
console.error('Submit KT Matrix error:', error);
throw error;
}
}, },
submitLevel2Feedback: async (data: any) => { submitLevel2Feedback: async (data: any) => {
try { const response: any = await API.submitLevel2Feedback(data);
const response: any = await API.submitLevel2Feedback(data); if (!response.ok) throw new Error(response.data?.message || 'Failed to submit feedback');
if (response.ok) { return response.data;
return response.data;
} else {
throw new Error(response.problem || 'Failed to submit Level 2 Feedback');
}
} catch (error) {
console.error('Submit Level 2 Feedback error:', error);
throw error;
}
}, },
updateRecommendation: async (data: any) => { updateRecommendation: async (data: any) => {
try { const response: any = await API.updateRecommendation(data);
const response: any = await API.updateRecommendation(data); if (!response.ok) throw new Error(response.data?.message || 'Failed to update recommendation');
if (response.ok) { return response.data;
return response.data; },
} else { submitStageDecision: async (data: any) => {
throw new Error(response.problem || 'Failed to update recommendation'); const response: any = await API.submitStageDecision(data);
} if (!response.ok) throw new Error(response.data?.message || 'Failed to process stage decision');
} catch (error) { return response.data;
console.error('Update recommendation error:', error);
throw error;
}
}, },
updateInterviewDecision: async (data: any) => { updateInterviewDecision: async (data: any) => {
try { const response: any = await API.updateInterviewDecision(data);
const response: any = await API.updateInterviewDecision(data); if (!response.ok) throw new Error(response.data?.message || 'Failed to update interview decision');
if (response.ok) { return response.data;
return response.data;
} else {
throw new Error(response.problem || 'Failed to update interview decision');
}
} catch (error) {
console.error('Update interview decision error:', error);
throw error;
}
}, },
assignArchitectureTeam: async (applicationId: string, assignedTo: string) => { assignArchitectureTeam: async (applicationId: string, assignedTo: string) => {
try { const response: any = await API.assignArchitectureTeam(applicationId, assignedTo);
const response: any = await API.assignArchitectureTeam(applicationId, assignedTo); if (!response.ok) throw new Error(response.data?.message || 'Failed to assign architecture team');
return response.data; return response.data;
} catch (error) {
console.error('Assign architecture team error:', error);
throw error;
}
}, },
updateArchitectureStatus: async (applicationId: string, status: string, remarks?: string) => { updateArchitectureStatus: async (applicationId: string, status: string, remarks?: string) => {
try { const response: any = await API.updateArchitectureStatus(applicationId, status, remarks);
const response: any = await API.updateArchitectureStatus(applicationId, status, remarks); if (!response.ok) throw new Error(response.data?.message || 'Failed to update architecture status');
return response.data; return response.data;
} catch (error) {
console.error('Update architecture status error:', error);
throw error;
}
}, },
generateDealerCodes: async (applicationId: string) => { generateDealerCodes: async (applicationId: string) => {
try { const response: any = await API.generateDealerCodes(applicationId);
const response: any = await API.generateDealerCodes(applicationId); if (!response.ok) throw new Error(response.data?.message || 'Failed to generate dealer codes');
return response.data; return response.data;
} catch (error) {
console.error('Generate dealer codes error:', error);
throw error;
}
}, },
updateApplicationStatus: async (id: string, data: any) => { updateApplicationStatus: async (id: string, data: any) => {
try { const response: any = await API.updateApplicationStatus(id, data);
const response: any = await API.updateApplicationStatus(id, data); if (!response.ok) throw new Error(response.data?.message || 'Failed to update application status');
return response.data; return response.data;
} catch (error) {
console.error('Update application status error:', error);
throw error;
}
}, },
createDealer: async (data: any) => { createDealer: async (data: any) => {
try { const response: any = await API.createDealer(data);
const response: any = await API.createDealer(data); if (!response.ok) throw new Error(response.data?.message || 'Failed to create dealer profile');
return response.data; return response.data;
} catch (error) {
console.error('Create dealer error:', error);
throw error;
}
}, },
retriggerEvaluators: async (id: string) => { retriggerEvaluators: async (id: string) => {
try { const response: any = await API.retriggerEvaluators(id);
const response: any = await API.retriggerEvaluators(id); if (!response.ok) throw new Error(response.data?.message || 'Failed to retrigger evaluators');
return response.data; return response.data;
} catch (error) {
console.error('Retrigger evaluators error:', error);
throw error;
}
} }
}; };