multi iteration done in approval flow for progress stsus
This commit is contained in:
parent
e68f96a929
commit
7fa34dd3d6
@ -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),
|
||||||
|
|||||||
@ -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'));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
@ -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 })));
|
||||||
|
|||||||
@ -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">
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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">
|
||||||
|
|||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user