ui and extra inputs fwhile creeating region zone, assigning zm are removed
This commit is contained in:
parent
8ea748fde6
commit
bc2b7faf08
@ -9,6 +9,7 @@ export const API = {
|
|||||||
|
|
||||||
// Master module routes
|
// Master module routes
|
||||||
getRoles: () => client.get('/admin/roles'),
|
getRoles: () => client.get('/admin/roles'),
|
||||||
|
createRole: (data: any) => client.post('/admin/roles', data),
|
||||||
getPermissions: () => client.get('/admin/permissions'),
|
getPermissions: () => client.get('/admin/permissions'),
|
||||||
updateRole: (id: string, data: any) => client.put(`/admin/roles/${id}`, data),
|
updateRole: (id: string, data: any) => client.put(`/admin/roles/${id}`, data),
|
||||||
|
|
||||||
|
|||||||
@ -490,7 +490,8 @@ export function UserManagementPage() {
|
|||||||
|
|
||||||
{/* Geographical Assignments */}
|
{/* Geographical Assignments */}
|
||||||
<div className="col-span-2 border-t pt-4 mt-2">
|
<div className="col-span-2 border-t pt-4 mt-2">
|
||||||
<h3 className="text-sm font-semibold text-slate-900 mb-4">Geographical Assignments</h3>
|
<h3 className="text-sm font-semibold text-slate-900 mb-1">Geographical Assignments</h3>
|
||||||
|
<p className="text-xs text-slate-500 mb-4">Optional: you can create users without territory mapping and assign later.</p>
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label htmlFor="zoneId">Zone (Top Level)</Label>
|
<Label htmlFor="zoneId">Zone (Top Level)</Label>
|
||||||
|
|||||||
@ -174,7 +174,7 @@ export function AllApplicationsPage({ onViewDetails, initialFilter = 'all' }: Al
|
|||||||
];
|
];
|
||||||
|
|
||||||
const getStatusColor = (status: ApplicationStatus) => {
|
const getStatusColor = (status: ApplicationStatus) => {
|
||||||
const colors: Record<ApplicationStatus, string> = {
|
const colors: Partial<Record<ApplicationStatus, string>> = {
|
||||||
'Submitted': 'bg-blue-100 text-blue-800',
|
'Submitted': 'bg-blue-100 text-blue-800',
|
||||||
'Questionnaire Pending': 'bg-yellow-100 text-yellow-800',
|
'Questionnaire Pending': 'bg-yellow-100 text-yellow-800',
|
||||||
'Questionnaire Completed': 'bg-cyan-100 text-cyan-800',
|
'Questionnaire Completed': 'bg-cyan-100 text-cyan-800',
|
||||||
@ -219,12 +219,8 @@ export function AllApplicationsPage({ onViewDetails, initialFilter = 'all' }: Al
|
|||||||
'Security Details Approved': 'bg-green-100 text-green-800',
|
'Security Details Approved': 'bg-green-100 text-green-800',
|
||||||
'Security Details': 'bg-amber-100 text-amber-800',
|
'Security Details': 'bg-amber-100 text-amber-800',
|
||||||
'LOA Issued': 'bg-pink-100 text-pink-800',
|
'LOA Issued': 'bg-pink-100 text-pink-800',
|
||||||
'EOR Complete': 'bg-violet-100 text-violet-800',
|
|
||||||
'Level 1 Approved': 'bg-green-100 text-green-800',
|
|
||||||
'Level 2 Approved': 'bg-green-100 text-green-800',
|
|
||||||
'Level 3 Approved': 'bg-green-100 text-green-800',
|
|
||||||
};
|
};
|
||||||
return (statusColors as any)[status] || 'bg-gray-100 text-gray-800';
|
return colors[status] || 'bg-gray-100 text-gray-800';
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1875,6 +1875,8 @@ export const ApplicationDetails = () => {
|
|||||||
].includes(application.status);
|
].includes(application.status);
|
||||||
|
|
||||||
const isLoaLocked = application.status === 'LOA Pending' && getDeposit('FIRST_FILL')?.status !== 'Verified';
|
const isLoaLocked = application.status === 'LOA Pending' && getDeposit('FIRST_FILL')?.status !== 'Verified';
|
||||||
|
const isSecurityDetailsLocked = ['Security Details', 'Payment Pending'].includes(application.status) &&
|
||||||
|
getDeposit('SECURITY_DEPOSIT')?.status !== 'Verified';
|
||||||
const isFinalState = application.status === 'Onboarded' || application.status === 'Rejected';
|
const isFinalState = application.status === 'Onboarded' || application.status === 'Rejected';
|
||||||
|
|
||||||
// 2. Interview Specific Logic
|
// 2. Interview Specific Logic
|
||||||
@ -1903,15 +1905,18 @@ export const ApplicationDetails = () => {
|
|||||||
|
|
||||||
// 5. Final Permission Bits
|
// 5. Final Permission Bits
|
||||||
const isDecisionMade = (activeInterviewForUser ? hasMadeInterviewDecision : false) || hasMadeStageDecision;
|
const isDecisionMade = (activeInterviewForUser ? hasMadeInterviewDecision : false) || hasMadeStageDecision;
|
||||||
const canApproveReject = !isLoaLocked && !isFinalState && !isDecisionMade && (
|
const canApproveReject = !isFinalState && !isDecisionMade && (
|
||||||
(!!activeInterviewForUser && !!hasSubmittedFeedback) ||
|
(!!activeInterviewForUser && !!hasSubmittedFeedback) ||
|
||||||
(isAdminRole && isAdministrativeStage && sequenceMet && (!['EOR In Progress', 'Inauguration', 'Approved'].includes(application.status) || eorProgress === 100))
|
(isAdminRole && isAdministrativeStage && sequenceMet && (!['EOR In Progress', 'Inauguration', 'Approved'].includes(application.status) || eorProgress === 100))
|
||||||
);
|
);
|
||||||
|
const canApprove = canApproveReject && !isLoaLocked && !isSecurityDetailsLocked;
|
||||||
|
const canReject = canApproveReject && !isLoaLocked;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
canApprove: canApproveReject,
|
canApprove,
|
||||||
canReject: canApproveReject,
|
canReject,
|
||||||
isLoaLocked,
|
isLoaLocked,
|
||||||
|
isSecurityDetailsLocked,
|
||||||
showDecisionMessage: isDecisionMade && (!isAdministrativeStage || hasMadeStageDecision),
|
showDecisionMessage: isDecisionMade && (!isAdministrativeStage || hasMadeStageDecision),
|
||||||
canSchedule: ['DD Admin', 'Super Admin', 'DD AM', 'ASM'].includes(currentUser.role) &&
|
canSchedule: ['DD Admin', 'Super Admin', 'DD AM', 'ASM'].includes(currentUser.role) &&
|
||||||
!isFinalState &&
|
!isFinalState &&
|
||||||
@ -3643,6 +3648,17 @@ export const ApplicationDetails = () => {
|
|||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{permissions.isSecurityDetailsLocked && (
|
||||||
|
<Alert variant="destructive" className="mb-4 bg-amber-50 border-amber-200 text-amber-800">
|
||||||
|
<Lock className="w-4 h-4 text-amber-600" />
|
||||||
|
<AlertTitle className="text-amber-900 font-semibold">Security Details approval locked</AlertTitle>
|
||||||
|
<AlertDescription className="text-amber-800">
|
||||||
|
Finance must verify the <span className="font-medium">Security Deposit</span> before this stage can be approved.
|
||||||
|
You can still use <span className="font-medium">Reject</span> if needed.
|
||||||
|
</AlertDescription>
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
|
|
||||||
{['Security Details', 'Payment Pending'].includes(application.status) && (
|
{['Security Details', 'Payment Pending'].includes(application.status) && (
|
||||||
<Alert className="mb-4 border-sky-200 bg-sky-50/90 text-sky-900">
|
<Alert className="mb-4 border-sky-200 bg-sky-50/90 text-sky-900">
|
||||||
<Info className="h-4 w-4 text-sky-700" />
|
<Info className="h-4 w-4 text-sky-700" />
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import { UserManagementTable } from './MasterPage/UserManagementTable';
|
|||||||
import { SLAConfiguration } from './MasterPage/SLAConfiguration';
|
import { SLAConfiguration } from './MasterPage/SLAConfiguration';
|
||||||
import { RolePermissions } from './MasterPage/RolePermissions';
|
import { RolePermissions } from './MasterPage/RolePermissions';
|
||||||
import { RoleDialog } from './MasterPage/RoleDialog';
|
import { RoleDialog } from './MasterPage/RoleDialog';
|
||||||
|
import { AddRoleDialog } from './MasterPage/AddRoleDialog';
|
||||||
import { EmailTemplates } from './MasterPage/EmailTemplates';
|
import { EmailTemplates } from './MasterPage/EmailTemplates';
|
||||||
import { LocationManagement } from './MasterPage/LocationManagement';
|
import { LocationManagement } from './MasterPage/LocationManagement';
|
||||||
import { ASMDialog } from './MasterPage/ASMDialog';
|
import { ASMDialog } from './MasterPage/ASMDialog';
|
||||||
@ -40,6 +41,7 @@ export const MasterPage: React.FC = () => {
|
|||||||
const { fetchInitialData, fetchAreas } = useMasterData();
|
const { fetchInitialData, fetchAreas } = useMasterData();
|
||||||
const {
|
const {
|
||||||
asms, zonalManagerMappings, ddLeads,
|
asms, zonalManagerMappings, ddLeads,
|
||||||
|
allStates,
|
||||||
allDistricts,
|
allDistricts,
|
||||||
users,
|
users,
|
||||||
roles,
|
roles,
|
||||||
@ -60,9 +62,6 @@ export const MasterPage: React.FC = () => {
|
|||||||
// Form State (ASM)
|
// Form State (ASM)
|
||||||
const [editingASMId, setEditingASMId] = useState<string | null>(null);
|
const [editingASMId, setEditingASMId] = useState<string | null>(null);
|
||||||
const [asmManagerId, setAsmManagerId] = useState('');
|
const [asmManagerId, setAsmManagerId] = useState('');
|
||||||
const [asmName, setAsmName] = useState('');
|
|
||||||
const [asmCode, setAsmCode] = useState('');
|
|
||||||
const [asmEmployeeId, setAsmEmployeeId] = useState('');
|
|
||||||
const [asmStatus, setAsmStatus] = useState<'active' | 'inactive'>('active');
|
const [asmStatus, setAsmStatus] = useState<'active' | 'inactive'>('active');
|
||||||
const [selectedASMZone, setSelectedASMZone] = useState('');
|
const [selectedASMZone, setSelectedASMZone] = useState('');
|
||||||
const [selectedASMRegion, setSelectedASMRegion] = useState('');
|
const [selectedASMRegion, setSelectedASMRegion] = useState('');
|
||||||
@ -74,9 +73,6 @@ export const MasterPage: React.FC = () => {
|
|||||||
const [showZMDialog, setShowZMDialog] = useState(false);
|
const [showZMDialog, setShowZMDialog] = useState(false);
|
||||||
const [editingZMId, setEditingZMId] = useState<string | null>(null);
|
const [editingZMId, setEditingZMId] = useState<string | null>(null);
|
||||||
const [zmManagerId, setZmManagerId] = useState('');
|
const [zmManagerId, setZmManagerId] = useState('');
|
||||||
const [zmName, setZmName] = useState('');
|
|
||||||
const [zmCode, setZmCode] = useState('');
|
|
||||||
const [zmEmployeeId, setZmEmployeeId] = useState('');
|
|
||||||
const [zmStatus, setZmStatus] = useState<'active' | 'inactive'>('active');
|
const [zmStatus, setZmStatus] = useState<'active' | 'inactive'>('active');
|
||||||
const [selectedZMZone, setSelectedZMZone] = useState('');
|
const [selectedZMZone, setSelectedZMZone] = useState('');
|
||||||
const [selectedZMRegions, setSelectedZMRegions] = useState<string[]>([]);
|
const [selectedZMRegions, setSelectedZMRegions] = useState<string[]>([]);
|
||||||
@ -85,15 +81,13 @@ export const MasterPage: React.FC = () => {
|
|||||||
const [showDDLeadDialog, setShowDDLeadDialog] = useState(false);
|
const [showDDLeadDialog, setShowDDLeadDialog] = useState(false);
|
||||||
const [editingDDLeadId, setEditingDDLeadId] = useState<string | null>(null);
|
const [editingDDLeadId, setEditingDDLeadId] = useState<string | null>(null);
|
||||||
const [ddLeadManagerId, setDdLeadManagerId] = useState('');
|
const [ddLeadManagerId, setDdLeadManagerId] = useState('');
|
||||||
const [ddLeadName, setDdLeadName] = useState('');
|
|
||||||
const [ddLeadCode, setDdLeadCode] = useState('');
|
|
||||||
const [ddLeadEmployeeId, setDdLeadEmployeeId] = useState('');
|
|
||||||
const [ddLeadStatus, setDdLeadStatus] = useState<'active' | 'inactive'>('active');
|
const [ddLeadStatus, setDdLeadStatus] = useState<'active' | 'inactive'>('active');
|
||||||
const [selectedDDLeadZones, setSelectedDDLeadZones] = useState<string[]>([]);
|
const [selectedDDLeadZones, setSelectedDDLeadZones] = useState<string[]>([]);
|
||||||
|
|
||||||
// Role Management State
|
// Role Management State
|
||||||
const [showRoleDialog, setShowRoleDialog] = useState(false);
|
const [showRoleDialog, setShowRoleDialog] = useState(false);
|
||||||
const [editingRole, setEditingRole] = useState<any>(null);
|
const [editingRole, setEditingRole] = useState<any>(null);
|
||||||
|
const [showAddRoleDialog, setShowAddRoleDialog] = useState(false);
|
||||||
|
|
||||||
// Form State (Zone)
|
// Form State (Zone)
|
||||||
const [editingZoneId, setEditingZoneId] = useState<string | null>(null);
|
const [editingZoneId, setEditingZoneId] = useState<string | null>(null);
|
||||||
@ -105,7 +99,6 @@ export const MasterPage: React.FC = () => {
|
|||||||
// Form State (Region)
|
// Form State (Region)
|
||||||
const [editingRegionId, setEditingRegionId] = useState<string | null>(null);
|
const [editingRegionId, setEditingRegionId] = useState<string | null>(null);
|
||||||
const [regionName, setRegionName] = useState('');
|
const [regionName, setRegionName] = useState('');
|
||||||
const [regionCode, setRegionCode] = useState('');
|
|
||||||
const [regionDescription, setRegionDescription] = useState('');
|
const [regionDescription, setRegionDescription] = useState('');
|
||||||
const [selectedRegionZone, setSelectedRegionZone] = useState('');
|
const [selectedRegionZone, setSelectedRegionZone] = useState('');
|
||||||
const [regionalManagerId, setRegionalManagerId] = useState('');
|
const [regionalManagerId, setRegionalManagerId] = useState('');
|
||||||
@ -176,7 +169,6 @@ export const MasterPage: React.FC = () => {
|
|||||||
const payload = {
|
const payload = {
|
||||||
userId: asmManagerId,
|
userId: asmManagerId,
|
||||||
roleCode: asmRoleCode,
|
roleCode: asmRoleCode,
|
||||||
asmCode,
|
|
||||||
districts: selectedASMDistricts,
|
districts: selectedASMDistricts,
|
||||||
status: asmStatus
|
status: asmStatus
|
||||||
};
|
};
|
||||||
@ -197,9 +189,6 @@ export const MasterPage: React.FC = () => {
|
|||||||
const handleEditASM = (asm: any) => {
|
const handleEditASM = (asm: any) => {
|
||||||
setEditingASMId(asm.id);
|
setEditingASMId(asm.id);
|
||||||
setAsmManagerId(asm.id);
|
setAsmManagerId(asm.id);
|
||||||
setAsmName(asm.name);
|
|
||||||
setAsmCode(asm.asmCode);
|
|
||||||
setAsmEmployeeId(asm.employeeId);
|
|
||||||
setAsmStatus(asm.status.toLowerCase() as 'active' | 'inactive');
|
setAsmStatus(asm.status.toLowerCase() as 'active' | 'inactive');
|
||||||
setSelectedASMZone(asm.zoneId);
|
setSelectedASMZone(asm.zoneId);
|
||||||
setSelectedASMRegion(asm.regionId);
|
setSelectedASMRegion(asm.regionId);
|
||||||
@ -212,9 +201,6 @@ export const MasterPage: React.FC = () => {
|
|||||||
const handleEditZM = (zm: any) => {
|
const handleEditZM = (zm: any) => {
|
||||||
setEditingZMId(zm.id);
|
setEditingZMId(zm.id);
|
||||||
setZmManagerId(zm.id);
|
setZmManagerId(zm.id);
|
||||||
setZmName(zm.name);
|
|
||||||
setZmCode(zm.zmCode || zm.code || '');
|
|
||||||
setZmEmployeeId(zm.employeeId || '');
|
|
||||||
setZmStatus(zm.status?.toLowerCase() === 'active' ? 'active' : 'inactive');
|
setZmStatus(zm.status?.toLowerCase() === 'active' ? 'active' : 'inactive');
|
||||||
setSelectedZMZone(zm.zoneId || '');
|
setSelectedZMZone(zm.zoneId || '');
|
||||||
setSelectedZMRegions(zm.assignedRegionIds || []);
|
setSelectedZMRegions(zm.assignedRegionIds || []);
|
||||||
@ -224,9 +210,6 @@ export const MasterPage: React.FC = () => {
|
|||||||
const handleEditDDLead = (lead: any) => {
|
const handleEditDDLead = (lead: any) => {
|
||||||
setEditingDDLeadId(lead.id);
|
setEditingDDLeadId(lead.id);
|
||||||
setDdLeadManagerId(lead.id);
|
setDdLeadManagerId(lead.id);
|
||||||
setDdLeadName(lead.name);
|
|
||||||
setDdLeadCode(lead.leadCode || '');
|
|
||||||
setDdLeadEmployeeId(lead.employeeId || '');
|
|
||||||
setDdLeadStatus(lead.status?.toLowerCase() === 'active' ? 'active' : 'inactive');
|
setDdLeadStatus(lead.status?.toLowerCase() === 'active' ? 'active' : 'inactive');
|
||||||
setSelectedDDLeadZones(lead.assignedZoneIds || []);
|
setSelectedDDLeadZones(lead.assignedZoneIds || []);
|
||||||
setShowDDLeadDialog(true);
|
setShowDDLeadDialog(true);
|
||||||
@ -240,7 +223,6 @@ export const MasterPage: React.FC = () => {
|
|||||||
try {
|
try {
|
||||||
const payload = {
|
const payload = {
|
||||||
userId: zmManagerId,
|
userId: zmManagerId,
|
||||||
zmCode,
|
|
||||||
zoneId: selectedZMZone,
|
zoneId: selectedZMZone,
|
||||||
regionIds: selectedZMRegions,
|
regionIds: selectedZMRegions,
|
||||||
status: zmStatus
|
status: zmStatus
|
||||||
@ -268,7 +250,6 @@ export const MasterPage: React.FC = () => {
|
|||||||
try {
|
try {
|
||||||
const payload = {
|
const payload = {
|
||||||
userId: ddLeadManagerId,
|
userId: ddLeadManagerId,
|
||||||
leadCode: ddLeadCode,
|
|
||||||
zoneIds: selectedDDLeadZones,
|
zoneIds: selectedDDLeadZones,
|
||||||
status: ddLeadStatus
|
status: ddLeadStatus
|
||||||
};
|
};
|
||||||
@ -316,7 +297,6 @@ export const MasterPage: React.FC = () => {
|
|||||||
const payload = {
|
const payload = {
|
||||||
...(editingRegionId ? { id: editingRegionId } : {}),
|
...(editingRegionId ? { id: editingRegionId } : {}),
|
||||||
name: regionName,
|
name: regionName,
|
||||||
code: regionCode,
|
|
||||||
description: regionDescription,
|
description: regionDescription,
|
||||||
parentId: selectedRegionZone,
|
parentId: selectedRegionZone,
|
||||||
managerId: regionalManagerId,
|
managerId: regionalManagerId,
|
||||||
@ -384,11 +364,32 @@ export const MasterPage: React.FC = () => {
|
|||||||
setShowRoleDialog(true);
|
setShowRoleDialog(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCreateRole = async (data: { roleCode: string; roleName: string; description?: string }) => {
|
||||||
|
try {
|
||||||
|
const payload = {
|
||||||
|
...data,
|
||||||
|
permissionIds: []
|
||||||
|
};
|
||||||
|
const res = await (masterService as any).createRole(payload);
|
||||||
|
if (res?.success) {
|
||||||
|
toast.success('Role created successfully');
|
||||||
|
fetchInitialData();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new Error(res?.message || 'Failed to create role');
|
||||||
|
} catch (error: any) {
|
||||||
|
const msg = error?.response?.data?.message || error?.message || 'Failed to create role';
|
||||||
|
toast.error(msg);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleEditLocation = (loc: any) => {
|
const handleEditLocation = (loc: any) => {
|
||||||
|
const matchedDistrict = allDistricts.find((d: any) => d.id === loc.districtId);
|
||||||
setEditingLocationId(loc.id);
|
setEditingLocationId(loc.id);
|
||||||
setLocationState(loc.stateName || '');
|
setLocationState(matchedDistrict?.stateId || loc.stateId || '');
|
||||||
setLocationCity(loc.city || '');
|
setLocationCity(loc.city || '');
|
||||||
setLocationDistrict(loc.name || '');
|
setLocationDistrict(loc.districtId || '');
|
||||||
setLocationActiveFrom(loc.openFrom ? new Date(loc.openFrom).toISOString().split('T')[0] : '');
|
setLocationActiveFrom(loc.openFrom ? new Date(loc.openFrom).toISOString().split('T')[0] : '');
|
||||||
setLocationActiveTo(loc.openTo ? new Date(loc.openTo).toISOString().split('T')[0] : '');
|
setLocationActiveTo(loc.openTo ? new Date(loc.openTo).toISOString().split('T')[0] : '');
|
||||||
setLocationStatus(loc.isActive ? 'active' : 'inactive');
|
setLocationStatus(loc.isActive ? 'active' : 'inactive');
|
||||||
@ -397,10 +398,23 @@ export const MasterPage: React.FC = () => {
|
|||||||
|
|
||||||
const handleSaveLocation = async () => {
|
const handleSaveLocation = async () => {
|
||||||
try {
|
try {
|
||||||
|
if (!locationState) {
|
||||||
|
toast.error('Please select a state');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!locationDistrict) {
|
||||||
|
toast.error('Please select a district');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectedState = allStates.find((s: any) => s.id === locationState);
|
||||||
|
const selectedDistrict = allDistricts.find((d: any) => d.id === locationDistrict);
|
||||||
const payload = {
|
const payload = {
|
||||||
id: editingLocationId,
|
id: editingLocationId,
|
||||||
stateName: locationState,
|
stateId: locationState,
|
||||||
name: locationDistrict,
|
stateName: selectedState?.name || selectedState?.stateName || '',
|
||||||
|
districtId: locationDistrict,
|
||||||
|
name: locationCity || selectedDistrict?.name || 'New Location',
|
||||||
city: locationCity,
|
city: locationCity,
|
||||||
status: locationStatus,
|
status: locationStatus,
|
||||||
openFrom: locationActiveFrom,
|
openFrom: locationActiveFrom,
|
||||||
@ -474,11 +488,10 @@ export const MasterPage: React.FC = () => {
|
|||||||
<ZoneDetails selectedZone={selectedZone} onAddZone={() => { setEditingZoneId(null); setZoneName(''); setZoneCode(''); setZoneDescription(''); setZonalBusinessHeadId('none'); setShowZoneDialog(true); }}
|
<ZoneDetails selectedZone={selectedZone} onAddZone={() => { setEditingZoneId(null); setZoneName(''); setZoneCode(''); setZoneDescription(''); setZonalBusinessHeadId('none'); setShowZoneDialog(true); }}
|
||||||
onEditZone={(z) => { setEditingZoneId(z.id); setZoneName(z.name); setZoneCode(z.code); setZoneDescription(z.description); setZonalBusinessHeadId(z.zonalBusinessHead?.id || 'none'); setShowZoneDialog(true); }} />
|
onEditZone={(z) => { setEditingZoneId(z.id); setZoneName(z.name); setZoneCode(z.code); setZoneDescription(z.description); setZonalBusinessHeadId(z.zonalBusinessHead?.id || 'none'); setShowZoneDialog(true); }} />
|
||||||
|
|
||||||
<RegionalManagement selectedZone={selectedZone} onAddRegion={() => { setEditingRegionId(null); setRegionName(''); setRegionCode(''); setSelectedRegionZone(selectedZone === 'all' ? '' : selectedZone); setRegionalManagerId(''); setSelectedRegionDistricts([]); setShowRegionDialog(true); }}
|
<RegionalManagement selectedZone={selectedZone} onAddRegion={() => { setEditingRegionId(null); setRegionName(''); setSelectedRegionZone(selectedZone === 'all' ? '' : selectedZone); setRegionalManagerId(''); setSelectedRegionDistricts([]); setShowRegionDialog(true); }}
|
||||||
onEditRegion={(r) => {
|
onEditRegion={(r) => {
|
||||||
setEditingRegionId(r.id);
|
setEditingRegionId(r.id);
|
||||||
setRegionName(r.name);
|
setRegionName(r.name);
|
||||||
setRegionCode(r.code);
|
|
||||||
setSelectedRegionZone(r.zoneId);
|
setSelectedRegionZone(r.zoneId);
|
||||||
setRegionalManagerId(r.regionalManager?.id || '');
|
setRegionalManagerId(r.regionalManager?.id || '');
|
||||||
setSelectedRegionDistricts(r.districts?.map((d: any) => d.id) || []);
|
setSelectedRegionDistricts(r.districts?.map((d: any) => d.id) || []);
|
||||||
@ -488,7 +501,7 @@ export const MasterPage: React.FC = () => {
|
|||||||
|
|
||||||
<ZMManagement selectedZone={selectedZone}
|
<ZMManagement selectedZone={selectedZone}
|
||||||
onAddZM={() => {
|
onAddZM={() => {
|
||||||
setEditingZMId(null); setZmManagerId(''); setZmName(''); setZmCode(''); setZmEmployeeId('');
|
setEditingZMId(null); setZmManagerId('');
|
||||||
setZmStatus('active'); setSelectedZMZone(selectedZone === 'all' ? '' : selectedZone);
|
setZmStatus('active'); setSelectedZMZone(selectedZone === 'all' ? '' : selectedZone);
|
||||||
setSelectedZMRegions([]);
|
setSelectedZMRegions([]);
|
||||||
setShowZMDialog(true);
|
setShowZMDialog(true);
|
||||||
@ -496,12 +509,12 @@ export const MasterPage: React.FC = () => {
|
|||||||
onEditZM={handleEditZM}
|
onEditZM={handleEditZM}
|
||||||
onDeleteZM={() => toast.error('ZM deletion restricted')} />
|
onDeleteZM={() => toast.error('ZM deletion restricted')} />
|
||||||
|
|
||||||
<ASMManagement selectedZone={selectedZone} onAddASM={() => { setEditingASMId(null); setAsmManagerId(''); setAsmName(''); setAsmCode(''); setAsmEmployeeId(''); setSelectedASMZone(selectedZone === 'all' ? '' : selectedZone); setSelectedASMRegion(''); setSelectedASMStates([]); setSelectedASMDistricts([]); setShowASMDialog(true); }}
|
<ASMManagement selectedZone={selectedZone} onAddASM={() => { setEditingASMId(null); setAsmManagerId(''); setSelectedASMZone(selectedZone === 'all' ? '' : selectedZone); setSelectedASMRegion(''); setSelectedASMStates([]); setSelectedASMDistricts([]); setShowASMDialog(true); }}
|
||||||
onEditASM={handleEditASM} onDeleteASM={() => toast.error('ASM deletion restricted')} />
|
onEditASM={handleEditASM} onDeleteASM={() => toast.error('ASM deletion restricted')} />
|
||||||
|
|
||||||
<DDLeadManagement selectedZone={selectedZone}
|
<DDLeadManagement selectedZone={selectedZone}
|
||||||
onAddLead={() => {
|
onAddLead={() => {
|
||||||
setEditingDDLeadId(null); setDdLeadManagerId(''); setDdLeadName(''); setDdLeadCode(''); setDdLeadEmployeeId('');
|
setEditingDDLeadId(null); setDdLeadManagerId('');
|
||||||
setDdLeadStatus('active'); setSelectedDDLeadZones([]);
|
setDdLeadStatus('active'); setSelectedDDLeadZones([]);
|
||||||
setShowDDLeadDialog(true);
|
setShowDDLeadDialog(true);
|
||||||
}}
|
}}
|
||||||
@ -512,7 +525,7 @@ export const MasterPage: React.FC = () => {
|
|||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
<TabsContent value="roles" className="animate-in fade-in duration-300">
|
<TabsContent value="roles" className="animate-in fade-in duration-300">
|
||||||
<RolePermissions onAddRole={() => toast.info('Unified Role Management interface being updated')}
|
<RolePermissions onAddRole={() => setShowAddRoleDialog(true)}
|
||||||
onEditRole={handleEditRole} />
|
onEditRole={handleEditRole} />
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
|
|
||||||
@ -592,20 +605,14 @@ export const MasterPage: React.FC = () => {
|
|||||||
|
|
||||||
{/* Main Dialogs */}
|
{/* Main Dialogs */}
|
||||||
<ZoneDialog isOpen={showZoneDialog} onOpenChange={setShowZoneDialog} editingZoneId={editingZoneId} zoneName={zoneName} setZoneName={setZoneName} zoneCode={zoneCode} setZoneCode={setZoneCode} zoneDescription={zoneDescription} setZoneDescription={setZoneDescription} zonalBusinessHeadId={zonalBusinessHeadId} setZonalBusinessHeadId={setZonalBusinessHeadId} onSave={handleSaveZone} userAssignedData={users.length > 0 ? users.map(u => ({...u, name: u.fullName || u.name, role: u.role?.roleName, roleCode: u.role?.roleCode, allRoles: u.allRoles})) : asms} />
|
<ZoneDialog isOpen={showZoneDialog} onOpenChange={setShowZoneDialog} editingZoneId={editingZoneId} zoneName={zoneName} setZoneName={setZoneName} zoneCode={zoneCode} setZoneCode={setZoneCode} zoneDescription={zoneDescription} setZoneDescription={setZoneDescription} zonalBusinessHeadId={zonalBusinessHeadId} setZonalBusinessHeadId={setZonalBusinessHeadId} onSave={handleSaveZone} userAssignedData={users.length > 0 ? users.map(u => ({...u, name: u.fullName || u.name, role: u.role?.roleName, roleCode: u.role?.roleCode, allRoles: u.allRoles})) : asms} />
|
||||||
<RegionDialog isOpen={showRegionDialog} onOpenChange={setShowRegionDialog} editingRegionId={editingRegionId} regionName={regionName} setRegionName={setRegionName} regionCode={regionCode} setRegionCode={setRegionCode} regionDescription={regionDescription} setRegionDescription={setRegionDescription} selectedRegionZone={selectedRegionZone} setSelectedRegionZone={setSelectedRegionZone} regionalManagerId={regionalManagerId} setRegionalManagerId={setRegionalManagerId} selectedRegionStates={selectedRegionDistricts} setSelectedRegionStates={setSelectedRegionDistricts} onSave={handleSaveRegion} userAssignedData={users.length > 0 ? users.map(u => ({...u, name: u.fullName || u.name, role: u.role?.roleName, roleCode: u.role?.roleCode, allRoles: u.allRoles})) : asms} />
|
<RegionDialog isOpen={showRegionDialog} onOpenChange={setShowRegionDialog} editingRegionId={editingRegionId} regionName={regionName} setRegionName={setRegionName} regionDescription={regionDescription} setRegionDescription={setRegionDescription} selectedRegionZone={selectedRegionZone} setSelectedRegionZone={setSelectedRegionZone} regionalManagerId={regionalManagerId} setRegionalManagerId={setRegionalManagerId} selectedRegionStates={selectedRegionDistricts} setSelectedRegionStates={setSelectedRegionDistricts} onSave={handleSaveRegion} userAssignedData={users.length > 0 ? users.map(u => ({...u, name: u.fullName || u.name, role: u.role?.roleName, roleCode: u.role?.roleCode, allRoles: u.allRoles})) : asms} />
|
||||||
<ASMDialog isOpen={showASMDialog} onOpenChange={setShowASMDialog} editingASMId={editingASMId} asmManagerId={asmManagerId} setAsmManagerId={setAsmManagerId} asmName={asmName} setAsmName={setAsmName} asmCode={asmCode} setAsmCode={setAsmCode} asmEmployeeId={asmEmployeeId} setAsmEmployeeId={setAsmEmployeeId} asmStatus={asmStatus} setAsmStatus={setAsmStatus} selectedASMZone={selectedASMZone} setSelectedASMZone={setSelectedASMZone} selectedASMRegion={selectedASMRegion} setSelectedASMRegion={setSelectedASMRegion} selectedASMStates={selectedASMStates} setSelectedASMStates={setSelectedASMStates} selectedASMDistricts={selectedASMDistricts} setSelectedASMDistricts={setSelectedASMDistricts} onSave={handleSaveASM} asmRoleCode={asmRoleCode} setAsmRoleCode={setAsmRoleCode} userAssignedData={users.length > 0 ? users.map(u => ({...u, name: u.fullName || u.name, role: u.role?.roleName, roleCode: u.role?.roleCode, allRoles: u.allRoles})) : asms} districtsAssignedToOthers={districtsAssignedToOthers} getDistrictsForSelectedState={(state) => getDistrictsForSelectedState(state, selectedASMRegion || undefined)} />
|
<ASMDialog isOpen={showASMDialog} onOpenChange={setShowASMDialog} editingASMId={editingASMId} asmManagerId={asmManagerId} setAsmManagerId={setAsmManagerId} asmStatus={asmStatus} setAsmStatus={setAsmStatus} selectedASMZone={selectedASMZone} setSelectedASMZone={setSelectedASMZone} selectedASMRegion={selectedASMRegion} setSelectedASMRegion={setSelectedASMRegion} selectedASMStates={selectedASMStates} setSelectedASMStates={setSelectedASMStates} selectedASMDistricts={selectedASMDistricts} setSelectedASMDistricts={setSelectedASMDistricts} onSave={handleSaveASM} asmRoleCode={asmRoleCode} setAsmRoleCode={setAsmRoleCode} userAssignedData={users.length > 0 ? users.map(u => ({...u, name: u.fullName || u.name, role: u.role?.roleName, roleCode: u.role?.roleCode, allRoles: u.allRoles})) : asms} districtsAssignedToOthers={districtsAssignedToOthers} getDistrictsForSelectedState={(state) => getDistrictsForSelectedState(state, selectedASMRegion || undefined)} />
|
||||||
<ZMDialog
|
<ZMDialog
|
||||||
isOpen={showZMDialog}
|
isOpen={showZMDialog}
|
||||||
onOpenChange={setShowZMDialog}
|
onOpenChange={setShowZMDialog}
|
||||||
editingZMId={editingZMId}
|
editingZMId={editingZMId}
|
||||||
zmManagerId={zmManagerId}
|
zmManagerId={zmManagerId}
|
||||||
setZmManagerId={setZmManagerId}
|
setZmManagerId={setZmManagerId}
|
||||||
zmName={zmName}
|
|
||||||
setZmName={setZmName}
|
|
||||||
zmCode={zmCode}
|
|
||||||
setZmCode={setZmCode}
|
|
||||||
zmEmployeeId={zmEmployeeId}
|
|
||||||
setZmEmployeeId={setZmEmployeeId}
|
|
||||||
zmStatus={zmStatus}
|
zmStatus={zmStatus}
|
||||||
setZmStatus={setZmStatus}
|
setZmStatus={setZmStatus}
|
||||||
selectedZone={selectedZMZone}
|
selectedZone={selectedZMZone}
|
||||||
@ -621,12 +628,6 @@ export const MasterPage: React.FC = () => {
|
|||||||
editingLeadId={editingDDLeadId}
|
editingLeadId={editingDDLeadId}
|
||||||
leadManagerId={ddLeadManagerId}
|
leadManagerId={ddLeadManagerId}
|
||||||
setLeadManagerId={setDdLeadManagerId}
|
setLeadManagerId={setDdLeadManagerId}
|
||||||
leadName={ddLeadName}
|
|
||||||
setLeadName={setDdLeadName}
|
|
||||||
leadCode={ddLeadCode}
|
|
||||||
setLeadCode={setDdLeadCode}
|
|
||||||
leadEmployeeId={ddLeadEmployeeId}
|
|
||||||
setLeadEmployeeId={setDdLeadEmployeeId}
|
|
||||||
leadStatus={ddLeadStatus}
|
leadStatus={ddLeadStatus}
|
||||||
setLeadStatus={setDdLeadStatus}
|
setLeadStatus={setDdLeadStatus}
|
||||||
selectedZones={selectedDDLeadZones}
|
selectedZones={selectedDDLeadZones}
|
||||||
@ -635,8 +636,9 @@ export const MasterPage: React.FC = () => {
|
|||||||
userAssignedData={users.length > 0 ? users.map(u => ({...u, name: u.fullName || u.name, role: u.role?.roleName, roleCode: u.role?.roleCode, allRoles: u.allRoles, assignedZoneIds: (ddLeads.find(l => l.id === u.id)?.assignedZoneIds || [])})) : asms}
|
userAssignedData={users.length > 0 ? users.map(u => ({...u, name: u.fullName || u.name, role: u.role?.roleName, roleCode: u.role?.roleCode, allRoles: u.allRoles, assignedZoneIds: (ddLeads.find(l => l.id === u.id)?.assignedZoneIds || [])})) : asms}
|
||||||
/>
|
/>
|
||||||
<TemplateDialog isOpen={showTemplateDialog} onOpenChange={setShowTemplateDialog} editingTemplate={editingTemplate} setEditingTemplate={setEditingTemplate} testDataInput={testDataInput} setTestDataInput={setTestDataInput} previewLoading={previewLoading} handlePreviewTemplate={handlePreviewTemplate} previewContent={previewContent} handleSaveTemplate={handleSaveTemplate} />
|
<TemplateDialog isOpen={showTemplateDialog} onOpenChange={setShowTemplateDialog} editingTemplate={editingTemplate} setEditingTemplate={setEditingTemplate} testDataInput={testDataInput} setTestDataInput={setTestDataInput} previewLoading={previewLoading} handlePreviewTemplate={handlePreviewTemplate} previewContent={previewContent} handleSaveTemplate={handleSaveTemplate} />
|
||||||
<LocationDialog isOpen={showLocationDialog} onOpenChange={setShowLocationDialog} editingLocationId={editingLocationId} locationState={locationState} setLocationState={setLocationState} locationDistrict={locationDistrict} setLocationDistrict={setLocationDistrict} locationCity={locationCity} setLocationCity={setLocationCity} locationActiveFrom={locationActiveFrom} setLocationActiveFrom={setLocationActiveFrom} locationActiveTo={locationActiveTo} setLocationActiveTo={setLocationActiveTo} locationStatus={locationStatus} setLocationStatus={setLocationStatus} onSave={handleSaveLocation} />
|
<LocationDialog isOpen={showLocationDialog} onOpenChange={setShowLocationDialog} editingLocationId={editingLocationId} locationState={locationState} setLocationState={setLocationState} locationDistrict={locationDistrict} setLocationDistrict={setLocationDistrict} locationCity={locationCity} setLocationCity={setLocationCity} locationActiveFrom={locationActiveFrom} setLocationActiveFrom={setLocationActiveFrom} locationActiveTo={locationActiveTo} setLocationActiveTo={setLocationActiveTo} locationStatus={locationStatus} setLocationStatus={setLocationStatus} allStates={allStates} allDistricts={allDistricts} onSave={handleSaveLocation} />
|
||||||
<RoleDialog isOpen={showRoleDialog} onOpenChange={setShowRoleDialog} role={editingRole} onSave={handleSaveRole} />
|
<RoleDialog isOpen={showRoleDialog} onOpenChange={setShowRoleDialog} role={editingRole} onSave={handleSaveRole} />
|
||||||
|
<AddRoleDialog isOpen={showAddRoleDialog} onOpenChange={setShowAddRoleDialog} onSave={handleCreateRole} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { useSelector } from 'react-redux';
|
|||||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/dialog';
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/dialog';
|
||||||
import { Button } from '../../ui/button';
|
import { Button } from '../../ui/button';
|
||||||
import { Label } from '../../ui/label';
|
import { Label } from '../../ui/label';
|
||||||
import { Input } from '../../ui/input';
|
|
||||||
import { Checkbox } from '../../ui/checkbox';
|
import { Checkbox } from '../../ui/checkbox';
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip';
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip';
|
||||||
@ -15,12 +14,6 @@ interface ASMDialogProps {
|
|||||||
editingASMId: string | null;
|
editingASMId: string | null;
|
||||||
asmManagerId: string;
|
asmManagerId: string;
|
||||||
setAsmManagerId: (id: string) => void;
|
setAsmManagerId: (id: string) => void;
|
||||||
asmName: string;
|
|
||||||
setAsmName: (name: string) => void;
|
|
||||||
asmCode: string;
|
|
||||||
setAsmCode: (code: string) => void;
|
|
||||||
asmEmployeeId: string;
|
|
||||||
setAsmEmployeeId: (id: string) => void;
|
|
||||||
asmStatus: 'active' | 'inactive';
|
asmStatus: 'active' | 'inactive';
|
||||||
setAsmStatus: (status: 'active' | 'inactive') => void;
|
setAsmStatus: (status: 'active' | 'inactive') => void;
|
||||||
selectedASMZone: string;
|
selectedASMZone: string;
|
||||||
@ -41,7 +34,6 @@ interface ASMDialogProps {
|
|||||||
|
|
||||||
export const ASMDialog: React.FC<ASMDialogProps> = ({
|
export const ASMDialog: React.FC<ASMDialogProps> = ({
|
||||||
isOpen, onOpenChange, editingASMId, asmManagerId, setAsmManagerId,
|
isOpen, onOpenChange, editingASMId, asmManagerId, setAsmManagerId,
|
||||||
asmName, setAsmName, asmCode, setAsmCode, asmEmployeeId, setAsmEmployeeId,
|
|
||||||
asmStatus, setAsmStatus, selectedASMZone, setSelectedASMZone,
|
asmStatus, setAsmStatus, selectedASMZone, setSelectedASMZone,
|
||||||
selectedASMRegion, setSelectedASMRegion, selectedASMStates, setSelectedASMStates,
|
selectedASMRegion, setSelectedASMRegion, selectedASMStates, setSelectedASMStates,
|
||||||
selectedASMDistricts, setSelectedASMDistricts, onSave,
|
selectedASMDistricts, setSelectedASMDistricts, onSave,
|
||||||
@ -257,13 +249,7 @@ export const ASMDialog: React.FC<ASMDialogProps> = ({
|
|||||||
setAsmManagerId(value);
|
setAsmManagerId(value);
|
||||||
const selectedUser = userAssignedData.find(u => u.id === value);
|
const selectedUser = userAssignedData.find(u => u.id === value);
|
||||||
if (selectedUser) {
|
if (selectedUser) {
|
||||||
setAsmName(selectedUser.name);
|
|
||||||
setAsmEmployeeId(selectedUser.employeeId || '');
|
|
||||||
|
|
||||||
// Extraction logic: Look for managerCode in the territoryProfile matching the current role
|
|
||||||
const roleProfile = (selectedUser.territoryProfile || []).find((t: any) => t.roleCode === asmRoleCode);
|
const roleProfile = (selectedUser.territoryProfile || []).find((t: any) => t.roleCode === asmRoleCode);
|
||||||
const existingCode = roleProfile?.managerCode || selectedUser.asmCode || selectedUser.employeeId || '';
|
|
||||||
setAsmCode(existingCode);
|
|
||||||
|
|
||||||
// Extract zone/region from assignments if present
|
// Extract zone/region from assignments if present
|
||||||
if (roleProfile?.zoneId) setSelectedASMZone(roleProfile.zoneId);
|
if (roleProfile?.zoneId) setSelectedASMZone(roleProfile.zoneId);
|
||||||
@ -295,22 +281,6 @@ export const ASMDialog: React.FC<ASMDialogProps> = ({
|
|||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
|
||||||
<div>
|
|
||||||
<Label>Employee ID</Label>
|
|
||||||
<Input readOnly placeholder="Auto-populated" className="mt-2 bg-slate-100" value={asmEmployeeId} />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>ASM Code</Label>
|
|
||||||
<Input placeholder="Enter ASM Code" className="mt-2 text-slate-900" value={asmCode} onChange={(e) => setAsmCode(e.target.value)} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<Label>Full Name</Label>
|
|
||||||
<Input placeholder="Enter full name" className="mt-2 text-slate-900" value={asmName} onChange={(e) => setAsmName(e.target.value)} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Label>Status</Label>
|
<Label>Status</Label>
|
||||||
<Select value={asmStatus} onValueChange={(val: 'active' | 'inactive') => setAsmStatus(val)}>
|
<Select value={asmStatus} onValueChange={(val: 'active' | 'inactive') => setAsmStatus(val)}>
|
||||||
|
|||||||
99
src/components/applications/MasterPage/AddRoleDialog.tsx
Normal file
99
src/components/applications/MasterPage/AddRoleDialog.tsx
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/dialog';
|
||||||
|
import { Button } from '../../ui/button';
|
||||||
|
import { Input } from '../../ui/input';
|
||||||
|
import { Label } from '../../ui/label';
|
||||||
|
import { Textarea } from '../../ui/textarea';
|
||||||
|
|
||||||
|
interface AddRoleDialogProps {
|
||||||
|
isOpen: boolean;
|
||||||
|
onOpenChange: (open: boolean) => void;
|
||||||
|
onSave: (data: { roleCode: string; roleName: string; description?: string }) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AddRoleDialog: React.FC<AddRoleDialogProps> = ({
|
||||||
|
isOpen,
|
||||||
|
onOpenChange,
|
||||||
|
onSave
|
||||||
|
}) => {
|
||||||
|
const [roleName, setRoleName] = useState('');
|
||||||
|
const [roleCode, setRoleCode] = useState('');
|
||||||
|
const [description, setDescription] = useState('');
|
||||||
|
const [saving, setSaving] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isOpen) return;
|
||||||
|
setRoleName('');
|
||||||
|
setRoleCode('');
|
||||||
|
setDescription('');
|
||||||
|
setSaving(false);
|
||||||
|
}, [isOpen]);
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
if (!roleName.trim() || !roleCode.trim()) return;
|
||||||
|
setSaving(true);
|
||||||
|
try {
|
||||||
|
await onSave({
|
||||||
|
roleName: roleName.trim(),
|
||||||
|
roleCode: roleCode.trim(),
|
||||||
|
description: description.trim() || undefined
|
||||||
|
});
|
||||||
|
onOpenChange(false);
|
||||||
|
} finally {
|
||||||
|
setSaving(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={isOpen} onOpenChange={onOpenChange}>
|
||||||
|
<DialogContent className="sm:max-w-md">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Add Role</DialogTitle>
|
||||||
|
<DialogDescription>Create a new role for Master Configuration.</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="role-name">Role Name</Label>
|
||||||
|
<Input
|
||||||
|
id="role-name"
|
||||||
|
value={roleName}
|
||||||
|
onChange={(e) => setRoleName(e.target.value)}
|
||||||
|
placeholder="e.g. Finance Admin"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="role-code">Role Code</Label>
|
||||||
|
<Input
|
||||||
|
id="role-code"
|
||||||
|
value={roleCode}
|
||||||
|
onChange={(e) => setRoleCode(e.target.value)}
|
||||||
|
placeholder="e.g. FINANCE_ADMIN"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label htmlFor="role-description">Description</Label>
|
||||||
|
<Textarea
|
||||||
|
id="role-description"
|
||||||
|
value={description}
|
||||||
|
onChange={(e) => setDescription(e.target.value)}
|
||||||
|
placeholder="Optional"
|
||||||
|
rows={3}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex justify-end gap-2">
|
||||||
|
<Button variant="outline" onClick={() => onOpenChange(false)} disabled={saving}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button onClick={handleSubmit} disabled={saving || !roleName.trim() || !roleCode.trim()}>
|
||||||
|
{saving ? 'Saving...' : 'Create Role'}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -3,7 +3,6 @@ import { useSelector } from 'react-redux';
|
|||||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/dialog';
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/dialog';
|
||||||
import { Button } from '../../ui/button';
|
import { Button } from '../../ui/button';
|
||||||
import { Label } from '../../ui/label';
|
import { Label } from '../../ui/label';
|
||||||
import { Input } from '../../ui/input';
|
|
||||||
import { Checkbox } from '../../ui/checkbox';
|
import { Checkbox } from '../../ui/checkbox';
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
|
||||||
import { RootState } from '../../../store';
|
import { RootState } from '../../../store';
|
||||||
@ -14,12 +13,6 @@ interface DDLeadDialogProps {
|
|||||||
editingLeadId: string | null;
|
editingLeadId: string | null;
|
||||||
leadManagerId: string;
|
leadManagerId: string;
|
||||||
setLeadManagerId: (id: string) => void;
|
setLeadManagerId: (id: string) => void;
|
||||||
leadName: string;
|
|
||||||
setLeadName: (name: string) => void;
|
|
||||||
leadCode: string;
|
|
||||||
setLeadCode: (code: string) => void;
|
|
||||||
leadEmployeeId: string;
|
|
||||||
setLeadEmployeeId: (id: string) => void;
|
|
||||||
leadStatus: 'active' | 'inactive';
|
leadStatus: 'active' | 'inactive';
|
||||||
setLeadStatus: (status: 'active' | 'inactive') => void;
|
setLeadStatus: (status: 'active' | 'inactive') => void;
|
||||||
selectedZones: string[];
|
selectedZones: string[];
|
||||||
@ -30,7 +23,6 @@ interface DDLeadDialogProps {
|
|||||||
|
|
||||||
export const DDLeadDialog: React.FC<DDLeadDialogProps> = ({
|
export const DDLeadDialog: React.FC<DDLeadDialogProps> = ({
|
||||||
isOpen, onOpenChange, editingLeadId, leadManagerId, setLeadManagerId,
|
isOpen, onOpenChange, editingLeadId, leadManagerId, setLeadManagerId,
|
||||||
leadName, setLeadName, leadCode, setLeadCode, leadEmployeeId, setLeadEmployeeId,
|
|
||||||
leadStatus, setLeadStatus, selectedZones, setSelectedZones, onSave,
|
leadStatus, setLeadStatus, selectedZones, setSelectedZones, onSave,
|
||||||
userAssignedData
|
userAssignedData
|
||||||
}) => {
|
}) => {
|
||||||
@ -70,10 +62,6 @@ export const DDLeadDialog: React.FC<DDLeadDialogProps> = ({
|
|||||||
setLeadManagerId(value);
|
setLeadManagerId(value);
|
||||||
const selectedUser = userAssignedData.find(u => u.id === value);
|
const selectedUser = userAssignedData.find(u => u.id === value);
|
||||||
if (selectedUser) {
|
if (selectedUser) {
|
||||||
setLeadName(selectedUser.name);
|
|
||||||
setLeadEmployeeId(selectedUser.employeeId || '');
|
|
||||||
setLeadCode(selectedUser.leadCode || selectedUser.employeeId || '');
|
|
||||||
|
|
||||||
// If they have existing assigned zones
|
// If they have existing assigned zones
|
||||||
if (selectedUser.assignedZoneIds) {
|
if (selectedUser.assignedZoneIds) {
|
||||||
setSelectedZones(selectedUser.assignedZoneIds);
|
setSelectedZones(selectedUser.assignedZoneIds);
|
||||||
@ -124,22 +112,6 @@ export const DDLeadDialog: React.FC<DDLeadDialogProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
|
||||||
<div>
|
|
||||||
<Label>Employee ID</Label>
|
|
||||||
<Input readOnly placeholder="Auto-populated" className="mt-2 bg-slate-50 border-slate-200" value={leadEmployeeId} />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>Lead Code</Label>
|
|
||||||
<Input placeholder="Enter Lead Code" className="mt-2 text-slate-900 border-slate-200" value={leadCode} onChange={(e) => setLeadCode(e.target.value)} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<Label>Full Name</Label>
|
|
||||||
<Input placeholder="Enter full name" className="mt-2 text-slate-900 border-slate-200" value={leadName} onChange={(e) => setLeadName(e.target.value)} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Label>Status</Label>
|
<Label>Status</Label>
|
||||||
<Select value={leadStatus} onValueChange={(val: 'active' | 'inactive') => setLeadStatus(val)}>
|
<Select value={leadStatus} onValueChange={(val: 'active' | 'inactive') => setLeadStatus(val)}>
|
||||||
|
|||||||
@ -9,9 +9,9 @@ interface LocationDialogProps {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onOpenChange: (open: boolean) => void;
|
onOpenChange: (open: boolean) => void;
|
||||||
editingLocationId: string | null;
|
editingLocationId: string | null;
|
||||||
locationState: string;
|
locationState: string; // stateId
|
||||||
setLocationState: (id: string) => void;
|
setLocationState: (id: string) => void;
|
||||||
locationDistrict: string;
|
locationDistrict: string; // districtId
|
||||||
setLocationDistrict: (id: string) => void;
|
setLocationDistrict: (id: string) => void;
|
||||||
locationCity: string;
|
locationCity: string;
|
||||||
setLocationCity: (city: string) => void;
|
setLocationCity: (city: string) => void;
|
||||||
@ -21,6 +21,8 @@ interface LocationDialogProps {
|
|||||||
setLocationActiveTo: (date: string) => void;
|
setLocationActiveTo: (date: string) => void;
|
||||||
locationStatus: string;
|
locationStatus: string;
|
||||||
setLocationStatus: (status: string) => void;
|
setLocationStatus: (status: string) => void;
|
||||||
|
allStates: any[];
|
||||||
|
allDistricts: any[];
|
||||||
onSave: () => void;
|
onSave: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,8 +30,14 @@ export const LocationDialog: React.FC<LocationDialogProps> = ({
|
|||||||
isOpen, onOpenChange, editingLocationId, locationState, setLocationState,
|
isOpen, onOpenChange, editingLocationId, locationState, setLocationState,
|
||||||
locationDistrict, setLocationDistrict, locationCity, setLocationCity,
|
locationDistrict, setLocationDistrict, locationCity, setLocationCity,
|
||||||
locationActiveFrom, setLocationActiveFrom,
|
locationActiveFrom, setLocationActiveFrom,
|
||||||
locationActiveTo, setLocationActiveTo, locationStatus, setLocationStatus, onSave
|
locationActiveTo, setLocationActiveTo, locationStatus, setLocationStatus,
|
||||||
|
allStates, allDistricts, onSave
|
||||||
}) => {
|
}) => {
|
||||||
|
const filteredDistricts = React.useMemo(() => {
|
||||||
|
if (!locationState) return [];
|
||||||
|
return (allDistricts || []).filter((d: any) => d.stateId === locationState);
|
||||||
|
}, [allDistricts, locationState]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={isOpen} onOpenChange={onOpenChange}>
|
<Dialog open={isOpen} onOpenChange={onOpenChange}>
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
@ -40,12 +48,24 @@ export const LocationDialog: React.FC<LocationDialogProps> = ({
|
|||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<Label className="flex items-center gap-2 text-sm leading-none font-medium text-slate-700">State</Label>
|
<Label className="flex items-center gap-2 text-sm leading-none font-medium text-slate-700">State</Label>
|
||||||
<Input
|
<Select
|
||||||
placeholder="Enter state name"
|
|
||||||
className="mt-2 text-slate-900 border-slate-200 focus-visible:ring-amber-500/30 focus-visible:border-amber-500"
|
|
||||||
value={locationState}
|
value={locationState}
|
||||||
onChange={(e) => setLocationState(e.target.value)}
|
onValueChange={(value) => {
|
||||||
/>
|
setLocationState(value);
|
||||||
|
setLocationDistrict('');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SelectTrigger className="mt-2 text-slate-900 border-slate-200 focus:ring-amber-500/30 focus:border-amber-500">
|
||||||
|
<SelectValue placeholder="Select state" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{(allStates || []).map((state: any) => (
|
||||||
|
<SelectItem key={state.id} value={state.id}>
|
||||||
|
{state.name || state.stateName}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="flex items-center gap-2 text-sm leading-none font-medium text-slate-700">City</Label>
|
<Label className="flex items-center gap-2 text-sm leading-none font-medium text-slate-700">City</Label>
|
||||||
@ -58,12 +78,18 @@ export const LocationDialog: React.FC<LocationDialogProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="flex items-center gap-2 text-sm leading-none font-medium text-slate-700">District</Label>
|
<Label className="flex items-center gap-2 text-sm leading-none font-medium text-slate-700">District</Label>
|
||||||
<Input
|
<Select value={locationDistrict} onValueChange={setLocationDistrict} disabled={!locationState}>
|
||||||
placeholder="Enter district name"
|
<SelectTrigger className="mt-2 text-slate-900 border-slate-200 focus:ring-amber-500/30 focus:border-amber-500">
|
||||||
className="mt-2 text-slate-900 border-slate-200 focus-visible:ring-amber-500/30 focus-visible:border-amber-500"
|
<SelectValue placeholder={locationState ? 'Select district' : 'Select state first'} />
|
||||||
value={locationDistrict}
|
</SelectTrigger>
|
||||||
onChange={(e) => setLocationDistrict(e.target.value)}
|
<SelectContent>
|
||||||
/>
|
{filteredDistricts.map((district: any) => (
|
||||||
|
<SelectItem key={district.id} value={district.id}>
|
||||||
|
{district.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="border rounded-lg p-4 bg-gradient-to-br from-blue-50 to-cyan-50 border-blue-200">
|
<div className="border rounded-lg p-4 bg-gradient-to-br from-blue-50 to-cyan-50 border-blue-200">
|
||||||
|
|||||||
@ -16,8 +16,6 @@ interface RegionDialogProps {
|
|||||||
editingRegionId: string | null;
|
editingRegionId: string | null;
|
||||||
regionName: string;
|
regionName: string;
|
||||||
setRegionName: (name: string) => void;
|
setRegionName: (name: string) => void;
|
||||||
regionCode: string;
|
|
||||||
setRegionCode: (code: string) => void;
|
|
||||||
regionDescription: string;
|
regionDescription: string;
|
||||||
setRegionDescription: (desc: string) => void;
|
setRegionDescription: (desc: string) => void;
|
||||||
selectedRegionZone: string;
|
selectedRegionZone: string;
|
||||||
@ -32,7 +30,7 @@ interface RegionDialogProps {
|
|||||||
|
|
||||||
export const RegionDialog: React.FC<RegionDialogProps> = ({
|
export const RegionDialog: React.FC<RegionDialogProps> = ({
|
||||||
isOpen, onOpenChange, editingRegionId, regionName, setRegionName,
|
isOpen, onOpenChange, editingRegionId, regionName, setRegionName,
|
||||||
regionCode, setRegionCode, regionDescription, setRegionDescription,
|
regionDescription, setRegionDescription,
|
||||||
selectedRegionZone, setSelectedRegionZone, regionalManagerId, setRegionalManagerId,
|
selectedRegionZone, setSelectedRegionZone, regionalManagerId, setRegionalManagerId,
|
||||||
selectedRegionStates, setSelectedRegionStates, onSave, userAssignedData
|
selectedRegionStates, setSelectedRegionStates, onSave, userAssignedData
|
||||||
}) => {
|
}) => {
|
||||||
@ -142,16 +140,10 @@ export const RegionDialog: React.FC<RegionDialogProps> = ({
|
|||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
|
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{/* Region Code & Name */}
|
{/* Region Name */}
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div>
|
||||||
<div>
|
<Label>Region Name</Label>
|
||||||
<Label>Region Code</Label>
|
<Input placeholder="e.g., Delhi NCR Region" className="mt-2 text-slate-900" value={regionName} onChange={(e) => setRegionName(e.target.value)} />
|
||||||
<Input placeholder="e.g., NZ-R1" className="mt-2 text-slate-900" value={regionCode} onChange={(e) => setRegionCode(e.target.value)} />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>Region Name</Label>
|
|
||||||
<Input placeholder="e.g., Delhi NCR Region" className="mt-2 text-slate-900" value={regionName} onChange={(e) => setRegionName(e.target.value)} />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Zone */}
|
{/* Zone */}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { useSelector } from 'react-redux';
|
|||||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/dialog';
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/dialog';
|
||||||
import { Button } from '../../ui/button';
|
import { Button } from '../../ui/button';
|
||||||
import { Label } from '../../ui/label';
|
import { Label } from '../../ui/label';
|
||||||
import { Input } from '../../ui/input';
|
|
||||||
import { Checkbox } from '../../ui/checkbox';
|
import { Checkbox } from '../../ui/checkbox';
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
|
||||||
import { RootState } from '../../../store';
|
import { RootState } from '../../../store';
|
||||||
@ -14,12 +13,6 @@ interface ZMDialogProps {
|
|||||||
editingZMId: string | null;
|
editingZMId: string | null;
|
||||||
zmManagerId: string;
|
zmManagerId: string;
|
||||||
setZmManagerId: (id: string) => void;
|
setZmManagerId: (id: string) => void;
|
||||||
zmName: string;
|
|
||||||
setZmName: (name: string) => void;
|
|
||||||
zmCode: string;
|
|
||||||
setZmCode: (code: string) => void;
|
|
||||||
zmEmployeeId: string;
|
|
||||||
setZmEmployeeId: (id: string) => void;
|
|
||||||
zmStatus: 'active' | 'inactive';
|
zmStatus: 'active' | 'inactive';
|
||||||
setZmStatus: (status: 'active' | 'inactive') => void;
|
setZmStatus: (status: 'active' | 'inactive') => void;
|
||||||
selectedZone: string;
|
selectedZone: string;
|
||||||
@ -32,7 +25,6 @@ interface ZMDialogProps {
|
|||||||
|
|
||||||
export const ZMDialog: React.FC<ZMDialogProps> = ({
|
export const ZMDialog: React.FC<ZMDialogProps> = ({
|
||||||
isOpen, onOpenChange, editingZMId, zmManagerId, setZmManagerId,
|
isOpen, onOpenChange, editingZMId, zmManagerId, setZmManagerId,
|
||||||
zmName, setZmName, zmCode, setZmCode, zmEmployeeId, setZmEmployeeId,
|
|
||||||
zmStatus, setZmStatus, selectedZone, setSelectedZone,
|
zmStatus, setZmStatus, selectedZone, setSelectedZone,
|
||||||
selectedRegions, setSelectedRegions, onSave,
|
selectedRegions, setSelectedRegions, onSave,
|
||||||
userAssignedData
|
userAssignedData
|
||||||
@ -66,10 +58,6 @@ export const ZMDialog: React.FC<ZMDialogProps> = ({
|
|||||||
setZmManagerId(value);
|
setZmManagerId(value);
|
||||||
const selectedUser = userAssignedData.find(u => u.id === value);
|
const selectedUser = userAssignedData.find(u => u.id === value);
|
||||||
if (selectedUser) {
|
if (selectedUser) {
|
||||||
setZmName(selectedUser.name);
|
|
||||||
setZmEmployeeId(selectedUser.employeeId || '');
|
|
||||||
setZmCode(selectedUser.zmCode || selectedUser.employeeId || '');
|
|
||||||
|
|
||||||
if (selectedUser.zoneId) setSelectedZone(selectedUser.zoneId);
|
if (selectedUser.zoneId) setSelectedZone(selectedUser.zoneId);
|
||||||
if (selectedUser.assignedRegionIds) setSelectedRegions(selectedUser.assignedRegionIds);
|
if (selectedUser.assignedRegionIds) setSelectedRegions(selectedUser.assignedRegionIds);
|
||||||
}
|
}
|
||||||
@ -92,17 +80,6 @@ export const ZMDialog: React.FC<ZMDialogProps> = ({
|
|||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
|
||||||
<div>
|
|
||||||
<Label>Employee ID</Label>
|
|
||||||
<Input readOnly className="mt-2 bg-slate-50 border-slate-200" value={zmEmployeeId} />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label>ZM Code</Label>
|
|
||||||
<Input placeholder="Enter ZM Code" className="mt-2" value={zmCode} onChange={(e) => setZmCode(e.target.value)} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Label>Managed Zone <span className="text-red-500">*</span></Label>
|
<Label>Managed Zone <span className="text-red-500">*</span></Label>
|
||||||
<Select value={selectedZone} onValueChange={(value) => {
|
<Select value={selectedZone} onValueChange={(value) => {
|
||||||
|
|||||||
@ -31,14 +31,15 @@ export const ZoneDialog: React.FC<ZoneDialogProps> = ({
|
|||||||
// Always include the currently assigned head to ensure pre-filling works
|
// Always include the currently assigned head to ensure pre-filling works
|
||||||
if (zonalBusinessHeadId !== 'none' && u.id === zonalBusinessHeadId) return true;
|
if (zonalBusinessHeadId !== 'none' && u.id === zonalBusinessHeadId) return true;
|
||||||
|
|
||||||
const roles = u.allRoles || [];
|
const roles = (u.allRoles || []).map((r: string) => String(r || '').toUpperCase());
|
||||||
const topLevelRole = (u.roleCode || '').toUpperCase();
|
const topLevelRole = String(u.roleCode || u.role || '').toUpperCase();
|
||||||
|
|
||||||
return topLevelRole === 'ZBH' || roles.some((r: string) => {
|
return topLevelRole === 'ZBH' || topLevelRole.includes('ZONAL BUSINESS HEAD') || roles.some((r: string) => {
|
||||||
const roleStr = (r || '').toUpperCase();
|
const roleStr = String(r || '').toUpperCase();
|
||||||
return roleStr === 'ZBH' || roleStr === 'ZONE BUSINESS HEAD' || roleStr === 'ZONAL BUSINESS HEAD';
|
return roleStr === 'ZBH' || roleStr === 'ZONE BUSINESS HEAD' || roleStr === 'ZONAL BUSINESS HEAD';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
const dropdownUsers = filteredZBHUsers.length > 0 ? filteredZBHUsers : (userAssignedData || []);
|
||||||
|
|
||||||
// PRE-FILLING: When editing an existing zone, find its current ZBH from master data
|
// PRE-FILLING: When editing an existing zone, find its current ZBH from master data
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
@ -84,7 +85,7 @@ export const ZoneDialog: React.FC<ZoneDialogProps> = ({
|
|||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent className="max-h-60">
|
<SelectContent className="max-h-60">
|
||||||
<SelectItem value="none">None / Unassigned</SelectItem>
|
<SelectItem value="none">None / Unassigned</SelectItem>
|
||||||
{filteredZBHUsers.map((user) => (
|
{dropdownUsers.map((user) => (
|
||||||
<SelectItem key={user.id} value={user.id}>
|
<SelectItem key={user.id} value={user.id}>
|
||||||
{user.name} ({user.email})
|
{user.name} ({user.email})
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
|
|||||||
@ -50,14 +50,29 @@ export const useMasterData = () => {
|
|||||||
const bodyZms = getBody(zmsRes);
|
const bodyZms = getBody(zmsRes);
|
||||||
const bodyDdLeads = getBody(ddLeadsRes);
|
const bodyDdLeads = getBody(ddLeadsRes);
|
||||||
|
|
||||||
const users = (bodyUsers?.users || bodyUsers?.data || []).map((u: any) => ({
|
const users = (bodyUsers?.users || bodyUsers?.data || []).map((u: any) => {
|
||||||
...u,
|
const territory = Array.isArray(u.territoryProfile) ? u.territoryProfile : [];
|
||||||
name: u.fullName || u.name,
|
const territoryZones = territory
|
||||||
role: u.role?.roleName || 'System User',
|
.filter((t: any) => String(t.locationType || '').toLowerCase() === 'zone')
|
||||||
zone: u.allZones?.join(', ') || 'Global',
|
.map((t: any) => t.locationName || t.zone)
|
||||||
region: u.allRegions?.join(', ') || 'Unassigned',
|
.filter(Boolean);
|
||||||
status: u.isActive !== false ? 'Active' : 'Inactive'
|
const territoryRegions = territory
|
||||||
}));
|
.filter((t: any) => String(t.locationType || '').toLowerCase() === 'region')
|
||||||
|
.map((t: any) => t.locationName || t.region)
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
|
const zones = Array.from(new Set([...(u.allZones || []), ...territoryZones]));
|
||||||
|
const regions = Array.from(new Set([...(u.allRegions || []), ...territoryRegions]));
|
||||||
|
|
||||||
|
return {
|
||||||
|
...u,
|
||||||
|
name: u.fullName || u.name,
|
||||||
|
role: u.role?.roleName || (Array.isArray(u.allRoles) && u.allRoles.length > 0 ? u.allRoles[0] : 'System User'),
|
||||||
|
zone: zones.length > 0 ? zones.join(', ') : 'Global',
|
||||||
|
region: regions.length > 0 ? regions.join(', ') : 'Unassigned',
|
||||||
|
status: u.isActive !== false ? 'Active' : 'Inactive'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
const roles = (bodyRoles?.roles || bodyRoles?.data || []).map((r: any) => ({
|
const roles = (bodyRoles?.roles || bodyRoles?.data || []).map((r: any) => ({
|
||||||
id: r.id, name: r.roleName, permissions: r.permissions?.map((p: any) => p.permissionCode) || [], userCount: r.userCount || 0
|
id: r.id, name: r.roleName, permissions: r.permissions?.map((p: any) => p.permissionCode) || [], userCount: r.userCount || 0
|
||||||
|
|||||||
@ -14,6 +14,10 @@ export const masterService = {
|
|||||||
const response = await API.updateRole(id, data);
|
const response = await API.updateRole(id, data);
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
|
createRole: async (data: any) => {
|
||||||
|
const response = await (API as any).createRole(data);
|
||||||
|
return response.data;
|
||||||
|
},
|
||||||
|
|
||||||
// Zones & Regions
|
// Zones & Regions
|
||||||
getZones: async () => {
|
getZones: async () => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user