zonal manager changed to
regions manged
This commit is contained in:
parent
ec51a6cf9b
commit
d2228543b1
@ -29,6 +29,9 @@ export const API = {
|
||||
getASMs: () => client.get('/master/asms'),
|
||||
getZonalManagers: () => client.get('/master/zonal-managers'),
|
||||
saveZonalManager: (data: any) => client.post('/master/zonal-managers', data),
|
||||
getDDLeads: () => client.get('/master/dd-leads'),
|
||||
saveDDLead: (data: any) => client.post('/master/dd-leads', data),
|
||||
|
||||
|
||||
// Onboarding
|
||||
submitApplication: (data: any) => client.post('/onboarding/apply', data),
|
||||
|
||||
@ -25,6 +25,8 @@ import { EmailTemplates } from './MasterPage/EmailTemplates';
|
||||
import { LocationManagement } from './MasterPage/LocationManagement';
|
||||
import { ASMDialog } from './MasterPage/ASMDialog';
|
||||
import { ZMDialog } from './MasterPage/ZMDialog';
|
||||
import { DDLeadManagement } from './MasterPage/DDLeadManagement';
|
||||
import { DDLeadDialog } from './MasterPage/DDLeadDialog';
|
||||
import { ZoneDialog } from './MasterPage/ZoneDialog';
|
||||
import { RegionDialog } from './MasterPage/RegionDialog';
|
||||
import { TemplateDialog } from './MasterPage/TemplateDialog';
|
||||
@ -35,7 +37,7 @@ import { RootState } from '../../store';
|
||||
export const MasterPage: React.FC = () => {
|
||||
const { fetchInitialData, fetchAreas } = useMasterData();
|
||||
const {
|
||||
asms, zonalManagerMappings,
|
||||
asms, zonalManagerMappings, ddLeads,
|
||||
allDistricts,
|
||||
users,
|
||||
roles,
|
||||
@ -75,8 +77,17 @@ export const MasterPage: React.FC = () => {
|
||||
const [zmEmployeeId, setZmEmployeeId] = useState('');
|
||||
const [zmStatus, setZmStatus] = useState<'active' | 'inactive'>('active');
|
||||
const [selectedZMZone, setSelectedZMZone] = useState('');
|
||||
const [selectedZMStates, setSelectedZMStates] = useState<string[]>([]);
|
||||
const [selectedZMDistricts, setSelectedZMDistricts] = useState<string[]>([]);
|
||||
const [selectedZMRegions, setSelectedZMRegions] = useState<string[]>([]);
|
||||
|
||||
// DD-Lead Management State
|
||||
const [showDDLeadDialog, setShowDDLeadDialog] = useState(false);
|
||||
const [editingDDLeadId, setEditingDDLeadId] = useState<string | null>(null);
|
||||
const [ddLeadManagerId, setDdLeadManagerId] = useState('');
|
||||
const [ddLeadName, setDdLeadName] = useState('');
|
||||
const [ddLeadCode, setDdLeadCode] = useState('');
|
||||
const [ddLeadEmployeeId, setDdLeadEmployeeId] = useState('');
|
||||
const [ddLeadStatus, setDdLeadStatus] = useState<'active' | 'inactive'>('active');
|
||||
const [selectedDDLeadZones, setSelectedDDLeadZones] = useState<string[]>([]);
|
||||
|
||||
// Role Management State
|
||||
const [showRoleDialog, setShowRoleDialog] = useState(false);
|
||||
@ -204,11 +215,21 @@ export const MasterPage: React.FC = () => {
|
||||
setZmEmployeeId(zm.employeeId || '');
|
||||
setZmStatus(zm.status?.toLowerCase() === 'active' ? 'active' : 'inactive');
|
||||
setSelectedZMZone(zm.zoneId || '');
|
||||
setSelectedZMStates(zm.stateNames || []);
|
||||
setSelectedZMDistricts(zm.districts?.map((d: any) => d.id) || []);
|
||||
setSelectedZMRegions(zm.assignedRegionIds || []);
|
||||
setShowZMDialog(true);
|
||||
};
|
||||
|
||||
const handleEditDDLead = (lead: any) => {
|
||||
setEditingDDLeadId(lead.id);
|
||||
setDdLeadManagerId(lead.id);
|
||||
setDdLeadName(lead.name);
|
||||
setDdLeadCode(lead.leadCode || '');
|
||||
setDdLeadEmployeeId(lead.employeeId || '');
|
||||
setDdLeadStatus(lead.status?.toLowerCase() === 'active' ? 'active' : 'inactive');
|
||||
setSelectedDDLeadZones(lead.assignedZoneIds || []);
|
||||
setShowDDLeadDialog(true);
|
||||
};
|
||||
|
||||
const handleSaveZM = async () => {
|
||||
if (!zmManagerId || !selectedZMZone) {
|
||||
toast.error('Manager and Zone are required');
|
||||
@ -219,7 +240,7 @@ export const MasterPage: React.FC = () => {
|
||||
userId: zmManagerId,
|
||||
zmCode,
|
||||
zoneId: selectedZMZone,
|
||||
districts: selectedZMDistricts,
|
||||
regionIds: selectedZMRegions,
|
||||
status: zmStatus
|
||||
};
|
||||
|
||||
@ -237,6 +258,34 @@ export const MasterPage: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleSaveDDLead = async () => {
|
||||
if (!ddLeadManagerId) {
|
||||
toast.error('Manager user is required');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const payload = {
|
||||
userId: ddLeadManagerId,
|
||||
leadCode: ddLeadCode,
|
||||
zoneIds: selectedDDLeadZones,
|
||||
status: ddLeadStatus
|
||||
};
|
||||
|
||||
const res = await (masterService as any).saveDDLead(payload) as any;
|
||||
if (res.success) {
|
||||
toast.success(`DD Lead ${editingDDLeadId ? 'updated' : 'assigned'} successfully`);
|
||||
setShowDDLeadDialog(false);
|
||||
fetchInitialData();
|
||||
} else {
|
||||
toast.error(res.message || 'Failed to save DD Lead');
|
||||
}
|
||||
} catch (error: any) {
|
||||
const msg = error?.response?.data?.message || error?.message || 'Failed to save DD Lead';
|
||||
toast.error(msg);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const handleSaveZone = async () => {
|
||||
try {
|
||||
const payload = { id: editingZoneId, name: zoneName, code: zoneCode, description: zoneDescription, managerId: zonalBusinessHeadId };
|
||||
@ -426,7 +475,7 @@ export const MasterPage: React.FC = () => {
|
||||
onAddZM={() => {
|
||||
setEditingZMId(null); setZmManagerId(''); setZmName(''); setZmCode(''); setZmEmployeeId('');
|
||||
setZmStatus('active'); setSelectedZMZone(selectedZone === 'all' ? '' : selectedZone);
|
||||
setSelectedZMStates([]); setSelectedZMDistricts([]);
|
||||
setSelectedZMRegions([]);
|
||||
setShowZMDialog(true);
|
||||
}}
|
||||
onEditZM={handleEditZM}
|
||||
@ -435,6 +484,15 @@ export const MasterPage: React.FC = () => {
|
||||
<ASMManagement selectedZone={selectedZone} onAddASM={() => { setEditingASMId(null); setAsmManagerId(''); setAsmName(''); setAsmCode(''); setAsmEmployeeId(''); setSelectedASMZone(selectedZone === 'all' ? '' : selectedZone); setSelectedASMRegion(''); setSelectedASMStates([]); setSelectedASMDistricts([]); setShowASMDialog(true); }}
|
||||
onEditASM={handleEditASM} onDeleteASM={() => toast.error('ASM deletion restricted')} />
|
||||
|
||||
<DDLeadManagement selectedZone={selectedZone}
|
||||
onAddLead={() => {
|
||||
setEditingDDLeadId(null); setDdLeadManagerId(''); setDdLeadName(''); setDdLeadCode(''); setDdLeadEmployeeId('');
|
||||
setDdLeadStatus('active'); setSelectedDDLeadZones([]);
|
||||
setShowDDLeadDialog(true);
|
||||
}}
|
||||
onEditLead={handleEditDDLead}
|
||||
onDeleteLead={() => toast.error('DD-Lead deletion restricted')} />
|
||||
|
||||
<UserManagementTable userAssignedData={users.length > 0 ? users : asms} />
|
||||
</TabsContent>
|
||||
|
||||
@ -508,16 +566,31 @@ export const MasterPage: React.FC = () => {
|
||||
setZmEmployeeId={setZmEmployeeId}
|
||||
zmStatus={zmStatus}
|
||||
setZmStatus={setZmStatus}
|
||||
selectedZMZone={selectedZMZone}
|
||||
setSelectedZMZone={setSelectedZMZone}
|
||||
selectedZMStates={selectedZMStates}
|
||||
setSelectedZMStates={setSelectedZMStates}
|
||||
selectedZMDistricts={selectedZMDistricts}
|
||||
setSelectedZMDistricts={setSelectedZMDistricts}
|
||||
selectedZone={selectedZMZone}
|
||||
setSelectedZone={setSelectedZMZone}
|
||||
selectedRegions={selectedZMRegions}
|
||||
setSelectedRegions={setSelectedZMRegions}
|
||||
onSave={handleSaveZM}
|
||||
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={getDistrictsForSelectedState}
|
||||
/>
|
||||
<DDLeadDialog
|
||||
isOpen={showDDLeadDialog}
|
||||
onOpenChange={setShowDDLeadDialog}
|
||||
editingLeadId={editingDDLeadId}
|
||||
leadManagerId={ddLeadManagerId}
|
||||
setLeadManagerId={setDdLeadManagerId}
|
||||
leadName={ddLeadName}
|
||||
setLeadName={setDdLeadName}
|
||||
leadCode={ddLeadCode}
|
||||
setLeadCode={setDdLeadCode}
|
||||
leadEmployeeId={ddLeadEmployeeId}
|
||||
setLeadEmployeeId={setDdLeadEmployeeId}
|
||||
leadStatus={ddLeadStatus}
|
||||
setLeadStatus={setDdLeadStatus}
|
||||
selectedZones={selectedDDLeadZones}
|
||||
setSelectedZones={setSelectedDDLeadZones}
|
||||
onSave={handleSaveDDLead}
|
||||
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} />
|
||||
<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} />
|
||||
|
||||
164
src/components/applications/MasterPage/DDLeadDialog.tsx
Normal file
164
src/components/applications/MasterPage/DDLeadDialog.tsx
Normal file
@ -0,0 +1,164 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../ui/dialog';
|
||||
import { Button } from '../../ui/button';
|
||||
import { Label } from '../../ui/label';
|
||||
import { Input } from '../../ui/input';
|
||||
import { Checkbox } from '../../ui/checkbox';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
|
||||
import { RootState } from '../../../store';
|
||||
|
||||
interface DDLeadDialogProps {
|
||||
isOpen: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
editingLeadId: string | null;
|
||||
leadManagerId: string;
|
||||
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';
|
||||
setLeadStatus: (status: 'active' | 'inactive') => void;
|
||||
selectedZones: string[];
|
||||
setSelectedZones: (zones: string[]) => void;
|
||||
onSave: () => void;
|
||||
userAssignedData: any[]; // All users to pick from
|
||||
}
|
||||
|
||||
export const DDLeadDialog: React.FC<DDLeadDialogProps> = ({
|
||||
isOpen, onOpenChange, editingLeadId, leadManagerId, setLeadManagerId,
|
||||
leadName, setLeadName, leadCode, setLeadCode, leadEmployeeId, setLeadEmployeeId,
|
||||
leadStatus, setLeadStatus, selectedZones, setSelectedZones, onSave,
|
||||
userAssignedData
|
||||
}) => {
|
||||
const { zones } = useSelector((state: RootState) => state.master);
|
||||
|
||||
// Filter users that have DD-related roles or are already DD-Leads
|
||||
const filteredLeadUsers = userAssignedData.filter(u => {
|
||||
const roles = u.allRoles || [];
|
||||
return roles.some((r: string) => {
|
||||
const roleStr = (r || '').toUpperCase();
|
||||
return ['DD-ZM', 'ZM', 'ZBH', 'ZONE BUSINESS HEAD', 'DD LEAD', 'DD_LEAD'].includes(roleStr) ||
|
||||
roleStr.includes('ZONAL') || roleStr.includes('LEAD');
|
||||
});
|
||||
});
|
||||
|
||||
const toggleZone = (zoneId: string) => {
|
||||
if (selectedZones.includes(zoneId)) {
|
||||
setSelectedZones(selectedZones.filter(id => id !== zoneId));
|
||||
} else {
|
||||
setSelectedZones([...selectedZones, zoneId]);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{editingLeadId ? 'Edit' : 'Add'} DD Lead</DialogTitle>
|
||||
<DialogDescription>Assign a user to the DD Lead role and map them to Zones.</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div className="border-t border-slate-100 pt-4">
|
||||
<Label>Select DD Lead User <span className="text-red-500">*</span></Label>
|
||||
<Select
|
||||
value={leadManagerId}
|
||||
onValueChange={(value) => {
|
||||
setLeadManagerId(value);
|
||||
const selectedUser = userAssignedData.find(u => u.id === value);
|
||||
if (selectedUser) {
|
||||
setLeadName(selectedUser.name);
|
||||
setLeadEmployeeId(selectedUser.employeeId || '');
|
||||
setLeadCode(selectedUser.leadCode || selectedUser.employeeId || '');
|
||||
|
||||
// If they have existing assigned zones
|
||||
if (selectedUser.assignedZoneIds) {
|
||||
setSelectedZones(selectedUser.assignedZoneIds);
|
||||
} else {
|
||||
setSelectedZones([]);
|
||||
}
|
||||
}
|
||||
}}
|
||||
disabled={!!editingLeadId}
|
||||
>
|
||||
<SelectTrigger className="mt-2 w-full text-slate-900 border-slate-200">
|
||||
<SelectValue placeholder="Select User" />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="max-h-60">
|
||||
{filteredLeadUsers.length > 0 ? (
|
||||
filteredLeadUsers.map((user) => (
|
||||
<SelectItem key={user.id} value={user.id}>
|
||||
<div className="flex flex-col text-left">
|
||||
<span className="font-medium text-slate-900">{user.name}</span>
|
||||
<span className="text-xs text-slate-500">{user.email}</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
))
|
||||
) : (
|
||||
<div className="p-2 text-sm text-slate-500 text-center">No suitable users found</div>
|
||||
)}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label>Assigned Zones (Review Mapping)</Label>
|
||||
<div className="mt-2 border border-slate-200 rounded-lg p-3 max-h-48 overflow-y-auto bg-slate-50/50">
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
{zones.map((zone) => (
|
||||
<div key={zone.id} className="flex items-center space-x-2 py-1">
|
||||
<Checkbox
|
||||
id={`lead-zone-${zone.id}`}
|
||||
checked={selectedZones.includes(zone.id)}
|
||||
onCheckedChange={() => toggleZone(zone.id)}
|
||||
/>
|
||||
<label htmlFor={`lead-zone-${zone.id}`} className="text-sm cursor-pointer text-slate-700 font-medium">
|
||||
{zone.name}
|
||||
</label>
|
||||
</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>
|
||||
<Label>Status</Label>
|
||||
<Select value={leadStatus} onValueChange={(val: 'active' | 'inactive') => setLeadStatus(val)}>
|
||||
<SelectTrigger className="mt-2 text-slate-900 border-slate-200">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="active">Active</SelectItem>
|
||||
<SelectItem value="inactive">Inactive</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-3 pt-6">
|
||||
<Button variant="outline" className="flex-1 border-slate-200" onClick={() => onOpenChange(false)}>Cancel</Button>
|
||||
<Button className="flex-1 bg-amber-600 hover:bg-amber-700 shadow-sm" onClick={onSave}>Save DD Lead</Button>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
117
src/components/applications/MasterPage/DDLeadManagement.tsx
Normal file
117
src/components/applications/MasterPage/DDLeadManagement.tsx
Normal file
@ -0,0 +1,117 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../../ui/card';
|
||||
import { Button } from '../../ui/button';
|
||||
import { Badge } from '../../ui/badge';
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '../../ui/table';
|
||||
import { Users, Plus, Edit2, Trash2, MapPin } from 'lucide-react';
|
||||
import { RootState } from '../../../store';
|
||||
|
||||
interface DDLeadManagementProps {
|
||||
selectedZone: string;
|
||||
onAddLead: () => void;
|
||||
onEditLead: (lead: any) => void;
|
||||
onDeleteLead: (id: string, name: string) => void;
|
||||
}
|
||||
|
||||
export const DDLeadManagement: React.FC<DDLeadManagementProps> = ({
|
||||
selectedZone, onAddLead, onEditLead, onDeleteLead
|
||||
}) => {
|
||||
const { ddLeads, zones } = useSelector((state: RootState) => state.master);
|
||||
|
||||
const filteredLeads = (ddLeads || []).filter((lead: any) =>
|
||||
selectedZone === 'all' ||
|
||||
(lead.assignedZoneIds && lead.assignedZoneIds.includes(selectedZone))
|
||||
);
|
||||
|
||||
const getZoneName = (zoneId: string) => {
|
||||
return zones.find(z => z.id === zoneId)?.name || 'Unknown Zone';
|
||||
};
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<CardTitle>DD-Leads (Dealer Development Lead)</CardTitle>
|
||||
<CardDescription>Manage DD-Leads and their zonal assignments</CardDescription>
|
||||
</div>
|
||||
<Button onClick={onAddLead} className="bg-amber-600 hover:bg-amber-700">
|
||||
<Plus className="w-4 h-4 mr-2" />
|
||||
Add DD-Lead
|
||||
</Button>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Lead Code</TableHead>
|
||||
<TableHead>Name</TableHead>
|
||||
<TableHead>Assigned Zones</TableHead>
|
||||
<TableHead>Contact</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead className="text-right">Actions</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{filteredLeads.length > 0 ? (
|
||||
filteredLeads.map((lead: any) => (
|
||||
<TableRow key={lead.id}>
|
||||
<TableCell>
|
||||
<div className="flex items-center gap-2">
|
||||
<Users className="w-4 h-4 text-amber-600" />
|
||||
<span className="font-medium">{lead.leadCode || 'N/A'}</span>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>{lead.name}</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{lead.assignedZoneIds && lead.assignedZoneIds.length > 0 ? (
|
||||
lead.assignedZoneIds.map((zoneId: string) => (
|
||||
<Badge key={zoneId} variant="outline" className="flex items-center gap-1">
|
||||
<MapPin className="w-3 h-3" />
|
||||
{getZoneName(zoneId)}
|
||||
</Badge>
|
||||
))
|
||||
) : (
|
||||
<Badge variant="secondary">National / No Zone</Badge>
|
||||
)}
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="text-sm">
|
||||
<p className="text-slate-900">{lead.email}</p>
|
||||
<p className="text-slate-500">{lead.phone || 'N/A'}</p>
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Badge variant={lead.status === 'active' ? 'default' : 'secondary'} className={lead.status === 'active' ? 'bg-emerald-100 text-emerald-700' : ''}>
|
||||
{lead.status.charAt(0).toUpperCase() + lead.status.slice(1)}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<div className="flex items-center justify-end gap-2">
|
||||
<Button variant="ghost" size="sm" onClick={() => onEditLead(lead)}>
|
||||
<Edit2 className="w-4 h-4" />
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" onClick={() => onDeleteLead(lead.id, lead.name)} className="text-red-600 hover:text-red-700 hover:bg-red-50">
|
||||
<Trash2 className="w-4 h-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
) : (
|
||||
<TableRow>
|
||||
<TableCell colSpan={6} className="text-center py-8 text-slate-500">
|
||||
No DD-Leads found. Click the button above to add one.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
@ -6,7 +6,6 @@ import { Label } from '../../ui/label';
|
||||
import { Input } from '../../ui/input';
|
||||
import { Checkbox } from '../../ui/checkbox';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../ui/select';
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip';
|
||||
import { RootState } from '../../../store';
|
||||
|
||||
interface ZMDialogProps {
|
||||
@ -23,25 +22,20 @@ interface ZMDialogProps {
|
||||
setZmEmployeeId: (id: string) => void;
|
||||
zmStatus: 'active' | 'inactive';
|
||||
setZmStatus: (status: 'active' | 'inactive') => void;
|
||||
selectedZMZone: string;
|
||||
setSelectedZMZone: (id: string) => void;
|
||||
selectedZMStates: string[];
|
||||
setSelectedZMStates: (states: string[]) => void;
|
||||
selectedZMDistricts: string[];
|
||||
setSelectedZMDistricts: (districts: string[]) => void;
|
||||
selectedZone: string;
|
||||
setSelectedZone: (id: string) => void;
|
||||
selectedRegions: string[];
|
||||
setSelectedRegions: (regions: string[]) => void;
|
||||
onSave: () => void;
|
||||
userAssignedData: any[];
|
||||
districtsAssignedToOthers: Record<string, string[]>;
|
||||
getDistrictsForSelectedState: (state: string) => { id: string; name: string }[];
|
||||
}
|
||||
|
||||
export const ZMDialog: React.FC<ZMDialogProps> = ({
|
||||
isOpen, onOpenChange, editingZMId, zmManagerId, setZmManagerId,
|
||||
zmName, setZmName, zmCode, setZmCode, zmEmployeeId, setZmEmployeeId,
|
||||
zmStatus, setZmStatus, selectedZMZone, setSelectedZMZone,
|
||||
selectedZMStates, setSelectedZMStates,
|
||||
selectedZMDistricts, setSelectedZMDistricts, onSave,
|
||||
userAssignedData, districtsAssignedToOthers, getDistrictsForSelectedState
|
||||
zmStatus, setZmStatus, selectedZone, setSelectedZone,
|
||||
selectedRegions, setSelectedRegions, onSave,
|
||||
userAssignedData
|
||||
}) => {
|
||||
const { zones, regionalOffices } = useSelector((state: RootState) => state.master);
|
||||
|
||||
@ -49,131 +43,22 @@ export const ZMDialog: React.FC<ZMDialogProps> = ({
|
||||
const roles = u.allRoles || [];
|
||||
return roles.some((r: string) => {
|
||||
const roleStr = (r || '').toUpperCase();
|
||||
return ['ZM', 'ZONAL MANAGER', 'ZBH', 'ZONE BUSINESS HEAD', 'RM', 'RBM', 'REGIONAL MANAGER', 'ASM', 'AREA SALES MANAGER'].includes(roleStr) ||
|
||||
roleStr.includes('ZONAL') || roleStr.includes('REGIONAL') || roleStr.includes('AREA SALES');
|
||||
return ['ZM', 'ZONAL MANAGER', 'ZBH', 'ZONE BUSINESS HEAD', 'RM', 'RBM', 'REGIONAL MANAGER'].includes(roleStr) ||
|
||||
roleStr.includes('ZONAL') || roleStr.includes('REGIONAL');
|
||||
});
|
||||
});
|
||||
|
||||
const availableRegions = regionalOffices.filter(r => r.zoneId === selectedZone);
|
||||
|
||||
return (
|
||||
<Dialog open={isOpen} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
|
||||
<DialogContent className="max-w-xl max-h-[90vh] overflow-y-auto">
|
||||
<DialogHeader>
|
||||
<DialogTitle>{editingZMId ? 'Edit' : 'Add'} Zonal Manager</DialogTitle>
|
||||
<DialogDescription>Configure ZM details and district-level assignments</DialogDescription>
|
||||
<DialogDescription>Assign Zonal Manager to Regions within a Zone</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Label>Managed Zone <span className="text-red-500">*</span></Label>
|
||||
<Select value={selectedZMZone} onValueChange={(value) => {
|
||||
setSelectedZMZone(value);
|
||||
setSelectedZMStates([]);
|
||||
setSelectedZMDistricts([]);
|
||||
}}>
|
||||
<SelectTrigger className="mt-2 text-slate-900 border-slate-200">
|
||||
<SelectValue placeholder="Select zone" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{zones.map((zone) => (
|
||||
<SelectItem key={zone.id} value={zone.id}>{zone.name}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
{selectedZMZone && (
|
||||
<div>
|
||||
<Label>States Covered (within Zone)</Label>
|
||||
<div className="mt-2 border border-slate-200 rounded-lg p-3 max-h-48 overflow-y-auto bg-slate-50/50">
|
||||
{(() => {
|
||||
const relevantRegions = regionalOffices.filter(r => r.zoneId === selectedZMZone);
|
||||
const availableStates = Array.from(new Set(relevantRegions.flatMap(r => r.states || []).map((s: any) => typeof s === 'string' ? s : s.name))).sort();
|
||||
|
||||
return availableStates.length > 0 ? (
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
{availableStates.map((state) => (
|
||||
<div key={state} className="flex items-center space-x-2 py-1">
|
||||
<Checkbox
|
||||
id={`zm-state-${state}`}
|
||||
checked={selectedZMStates.includes(state)}
|
||||
onCheckedChange={(checked) => {
|
||||
if (checked) {
|
||||
setSelectedZMStates([...selectedZMStates, state]);
|
||||
} else {
|
||||
setSelectedZMStates(selectedZMStates.filter(s => s !== state));
|
||||
const stateDistricts = getDistrictsForSelectedState(state);
|
||||
setSelectedZMDistricts(selectedZMDistricts.filter(dId => !stateDistricts.some(sd => sd.id === dId)));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<label htmlFor={`zm-state-${state}`} className="text-sm cursor-pointer text-slate-700 font-medium">
|
||||
{state}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<p className="text-sm text-slate-500 italic">No states found for this zone</p>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{selectedZMStates.length > 0 && (
|
||||
<div>
|
||||
<Label>Specific Districts Managed</Label>
|
||||
<div className="mt-2 border border-slate-200 rounded-lg p-3 max-h-64 overflow-y-auto bg-slate-50/50">
|
||||
<TooltipProvider>
|
||||
{selectedZMStates.map((state) => {
|
||||
const districts = getDistrictsForSelectedState(state);
|
||||
if (districts.length === 0) return null;
|
||||
|
||||
return (
|
||||
<div key={state} className="mb-4 last:mb-0">
|
||||
<h4 className="text-xs font-bold text-amber-700 mb-2 pb-1 border-b border-slate-100 uppercase tracking-wider">{state}</h4>
|
||||
<div className="grid grid-cols-2 gap-x-4 gap-y-1 ml-1">
|
||||
{districts.map((district: any) => (
|
||||
<div key={district.id}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<div className="flex items-center space-x-2 py-0.5">
|
||||
<Checkbox
|
||||
id={`zm-district-${district.id}`}
|
||||
checked={selectedZMDistricts.includes(district.id)}
|
||||
onCheckedChange={(checked) => {
|
||||
if (checked) {
|
||||
setSelectedZMDistricts([...selectedZMDistricts, district.id]);
|
||||
} else {
|
||||
setSelectedZMDistricts(selectedZMDistricts.filter(id => id !== district.id));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<label
|
||||
htmlFor={`zm-district-${district.id}`}
|
||||
className="text-sm cursor-pointer text-slate-600 truncate max-w-[180px]"
|
||||
>
|
||||
{district.name}
|
||||
</label>
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
{districtsAssignedToOthers[district.id] && (
|
||||
<TooltipContent side="right">
|
||||
<p className="text-xs">Also assigned to: {districtsAssignedToOthers[district.id].join(', ')}</p>
|
||||
</TooltipContent>
|
||||
)}
|
||||
</Tooltip>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</TooltipProvider>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="border-t border-slate-100 pt-4">
|
||||
<div className="space-y-6">
|
||||
<div className="border-b border-slate-100 pb-4">
|
||||
<Label>Select Zonal Manager User <span className="text-red-500">*</span></Label>
|
||||
<Select
|
||||
value={zmManagerId}
|
||||
@ -183,18 +68,10 @@ export const ZMDialog: React.FC<ZMDialogProps> = ({
|
||||
if (selectedUser) {
|
||||
setZmName(selectedUser.name);
|
||||
setZmEmployeeId(selectedUser.employeeId || '');
|
||||
setZmCode(selectedUser.zmCode || selectedUser.employeeId || '');
|
||||
|
||||
// Search territoryProfile for ZM/DD-ZM role to find the existing managerCode
|
||||
const zmProfile = (selectedUser.territoryProfile || []).find((tp: any) => tp.roleCode === 'ZM' || tp.roleCode === 'DD-ZM');
|
||||
const existingCode = zmProfile?.managerCode || selectedUser.zmCode || selectedUser.employeeId || '';
|
||||
setZmCode(existingCode);
|
||||
|
||||
if (zmProfile?.zoneId) {
|
||||
setSelectedZMZone(zmProfile.zoneId);
|
||||
}
|
||||
|
||||
setSelectedZMDistricts(selectedUser.districts?.map((d: any) => d.id) || []);
|
||||
if (selectedUser.stateNames) setSelectedZMStates(selectedUser.stateNames);
|
||||
if (selectedUser.zoneId) setSelectedZone(selectedUser.zoneId);
|
||||
if (selectedUser.assignedRegionIds) setSelectedRegions(selectedUser.assignedRegionIds);
|
||||
}
|
||||
}}
|
||||
disabled={!!editingZMId}
|
||||
@ -203,18 +80,14 @@ export const ZMDialog: React.FC<ZMDialogProps> = ({
|
||||
<SelectValue placeholder="Select ZM User" />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="max-h-60">
|
||||
{filteredZMUsers.length > 0 ? (
|
||||
filteredZMUsers.map((user) => (
|
||||
{filteredZMUsers.map((user) => (
|
||||
<SelectItem key={user.id} value={user.id}>
|
||||
<div className="flex flex-col text-left">
|
||||
<span className="font-medium text-slate-900">{user.name}</span>
|
||||
<span className="text-xs text-slate-500">{user.email}</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
))
|
||||
) : (
|
||||
<div className="p-2 text-sm text-slate-500 text-center">No Zonal Managers found</div>
|
||||
)}
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
@ -222,23 +95,69 @@ export const ZMDialog: React.FC<ZMDialogProps> = ({
|
||||
<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={zmEmployeeId} />
|
||||
<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 text-slate-900 border-slate-200" value={zmCode} onChange={(e) => setZmCode(e.target.value)} />
|
||||
<Input placeholder="Enter ZM Code" className="mt-2" value={zmCode} onChange={(e) => setZmCode(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={zmName} onChange={(e) => setZmName(e.target.value)} />
|
||||
<Label>Managed Zone <span className="text-red-500">*</span></Label>
|
||||
<Select value={selectedZone} onValueChange={(value) => {
|
||||
setSelectedZone(value);
|
||||
setSelectedRegions([]);
|
||||
}}>
|
||||
<SelectTrigger className="mt-2">
|
||||
<SelectValue placeholder="Select zone" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{zones.map((z) => (
|
||||
<SelectItem key={z.id} value={z.id}>{z.name}</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
{selectedZone && (
|
||||
<div>
|
||||
<Label className="mb-2 block">Assigned Regions <span className="text-red-500">*</span></Label>
|
||||
<div className="border border-slate-200 rounded-lg p-4 bg-slate-50/50 max-h-60 overflow-y-auto">
|
||||
<div className="grid grid-cols-1 gap-3">
|
||||
{availableRegions.map((region) => (
|
||||
<div key={region.id} className="flex items-center space-x-3 p-2 rounded hover:bg-white transition-colors">
|
||||
<Checkbox
|
||||
id={`region-${region.id}`}
|
||||
checked={selectedRegions.includes(region.id)}
|
||||
onCheckedChange={(checked) => {
|
||||
if (checked) {
|
||||
setSelectedRegions([...selectedRegions, region.id]);
|
||||
} else {
|
||||
setSelectedRegions(selectedRegions.filter(id => id !== region.id));
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<label htmlFor={`region-${region.id}`} className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer flex-1">
|
||||
{region.name}
|
||||
<span className="text-xs text-slate-500 block mt-1">
|
||||
{region.code || 'No Code'}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
{availableRegions.length === 0 && (
|
||||
<p className="text-sm text-slate-500 italic text-center py-4">No regions found for this zone</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<Label>Status</Label>
|
||||
<Select value={zmStatus} onValueChange={(val: 'active' | 'inactive') => setZmStatus(val)}>
|
||||
<SelectTrigger className="mt-2 text-slate-900 border-slate-200">
|
||||
<SelectTrigger className="mt-2">
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
@ -249,8 +168,8 @@ export const ZMDialog: React.FC<ZMDialogProps> = ({
|
||||
</div>
|
||||
|
||||
<div className="flex gap-3 pt-6">
|
||||
<Button variant="outline" className="flex-1 border-slate-200" onClick={() => onOpenChange(false)}>Cancel</Button>
|
||||
<Button className="flex-1 bg-amber-600 hover:bg-amber-700 shadow-sm" onClick={onSave}>Save Zonal Manager</Button>
|
||||
<Button variant="outline" className="flex-1" onClick={() => onOpenChange(false)}>Cancel</Button>
|
||||
<Button className="flex-1 bg-amber-600 hover:bg-amber-700" onClick={onSave}>Save Zonal Manager</Button>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
|
||||
@ -46,7 +46,7 @@ export const ZMManagement: React.FC<ZMManagementProps> = ({
|
||||
<TableHead>ZM Code</TableHead>
|
||||
<TableHead>Name</TableHead>
|
||||
<TableHead>Zone</TableHead>
|
||||
<TableHead>Districts Managed</TableHead>
|
||||
<TableHead>Regions Managed</TableHead>
|
||||
<TableHead>Contact</TableHead>
|
||||
<TableHead>Status</TableHead>
|
||||
<TableHead className="text-right">Actions</TableHead>
|
||||
@ -71,14 +71,14 @@ export const ZMManagement: React.FC<ZMManagementProps> = ({
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{zm.districts.slice(0, 3).map((district: any, idx: number) => (
|
||||
{(zm.regionNames || []).slice(0, 3).map((regionName: string, idx: number) => (
|
||||
<Badge key={idx} variant="secondary" className="text-xs">
|
||||
{district.name}
|
||||
{regionName}
|
||||
</Badge>
|
||||
))}
|
||||
{zm.districts.length > 3 && (
|
||||
{(zm.regionNames || []).length > 3 && (
|
||||
<Badge variant="secondary" className="text-xs">
|
||||
+{zm.districts.length - 3}
|
||||
+{(zm.regionNames || []).length - 3}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -17,7 +17,7 @@ export const useMasterData = () => {
|
||||
const [
|
||||
rolesRes, zonesRes, permsRes, regionsRes, usersRes,
|
||||
statesRes, emailTemplatesRes, districtsRes, areasRes, slaRes,
|
||||
asmsRes, zmsRes
|
||||
asmsRes, zmsRes, ddLeadsRes
|
||||
] = await Promise.all([
|
||||
masterService.getRoles().catch(() => ({ success: false })),
|
||||
masterService.getZones().catch(() => ({ success: false })),
|
||||
@ -30,7 +30,8 @@ export const useMasterData = () => {
|
||||
masterService.getAreas({ limit: 'all' }).catch(() => ({ success: false })),
|
||||
masterService.getSlaConfigs().catch(() => ({ success: false })),
|
||||
(masterService as any).getASMs().catch(() => ({ success: false })),
|
||||
(masterService as any).getZonalManagers().catch(() => ({ success: false }))
|
||||
(masterService as any).getZonalManagers().catch(() => ({ success: false })),
|
||||
(masterService as any).getDDLeads().catch(() => ({ success: false }))
|
||||
]);
|
||||
|
||||
const getBody = (res: any) => res.success ? res : (res.data ? res.data : res);
|
||||
@ -47,6 +48,7 @@ export const useMasterData = () => {
|
||||
const bodySla = getBody(slaRes);
|
||||
const bodyAsms = getBody(asmsRes);
|
||||
const bodyZms = getBody(zmsRes);
|
||||
const bodyDdLeads = getBody(ddLeadsRes);
|
||||
|
||||
const users = (bodyUsers?.users || bodyUsers?.data || []).map((u: any) => ({
|
||||
...u,
|
||||
@ -64,7 +66,6 @@ export const useMasterData = () => {
|
||||
const zones = (bodyZones?.zones || bodyZones?.data || []).map((z: any) => {
|
||||
const zoneName = (z.name || z.zoneName || '').toUpperCase();
|
||||
const zoneUsers = users.filter((u: any) => u.allZones?.includes(zoneName));
|
||||
const zoneZmUsers = zoneUsers.filter((u: any) => u.allRoles?.some((r: string) => (r === 'ZM' || r.includes('ZONAL MANAGER')) && !r.includes('HEAD')));
|
||||
|
||||
return {
|
||||
id: z.id, name: zoneName, description: z.description || '',
|
||||
@ -112,18 +113,27 @@ export const useMasterData = () => {
|
||||
const asms = (bodyAsms?.data || bodyAsms || []);
|
||||
const zonalManagers = (bodyZms?.data || bodyZms || []);
|
||||
|
||||
const zonalManagerMappings = zonalManagers.length > 0 ? zonalManagers : users.filter((u: any) => u.allRoles?.some((r: string) => (r === 'ZM' || r === 'DD-ZM' || r.includes('ZONAL MANAGER')) && !r.includes('HEAD')))
|
||||
.map((u: any) => {
|
||||
const zmT = u.territoryProfile?.find((t: any) => (t.roleCode === 'ZM' || t.roleCode === 'DD-ZM' || t.role === 'ZONAL MANAGER')) || {};
|
||||
const districts = u.territoryProfile?.filter((t: any) => (t.roleCode === 'ZM' || t.roleCode === 'DD-ZM' || t.role === 'ZONAL MANAGER') && t.locationType === 'district').map((t: any) => ({ id: t.locationId, name: t.locationName })) || [];
|
||||
const zonalManagerMappings = zonalManagers.length > 0 ? zonalManagers : users.filter((u: any) =>
|
||||
u.allRoles?.some((r: string) => (r === 'ZM' || r === 'DD-ZM' || r.includes('ZONAL MANAGER')) && !r.includes('HEAD'))
|
||||
).map((u: any) => {
|
||||
const zmT = (u.territoryProfile || []).find((t: any) => (t.roleCode === 'ZM' || t.roleCode === 'DD-ZM')) || {};
|
||||
const regions = (u.territoryProfile || [])
|
||||
.filter((t: any) => (t.roleCode === 'ZM' || t.roleCode === 'DD-ZM') && t.locationType === 'region')
|
||||
.map((t: any) => t.locationName);
|
||||
const regionIds = (u.territoryProfile || [])
|
||||
.filter((t: any) => (t.roleCode === 'ZM' || t.roleCode === 'DD-ZM') && t.locationType === 'region')
|
||||
.map((t: any) => t.locationId);
|
||||
|
||||
return {
|
||||
id: u.id, name: u.fullName, code: u.employeeId || 'N/A', email: u.email, phone: u.mobileNumber,
|
||||
id: u.id,
|
||||
name: u.fullName,
|
||||
zmCode: u.employeeId || 'N/A',
|
||||
email: u.email,
|
||||
phone: u.mobileNumber,
|
||||
zoneId: zmT.zoneId,
|
||||
regionId: zmT.regionId,
|
||||
zoneName: zmT.zone || u.zone || 'Not Assigned',
|
||||
regionName: zmT.region || u.region || 'Not Assigned',
|
||||
districts: districts,
|
||||
regionNames: regions,
|
||||
assignedRegionIds: regionIds,
|
||||
status: u.status
|
||||
};
|
||||
});
|
||||
@ -159,6 +169,7 @@ export const useMasterData = () => {
|
||||
emailTemplates: bodyEmail?.data || [],
|
||||
slaConfigs,
|
||||
users,
|
||||
ddLeads: bodyDdLeads?.data || bodyDdLeads || [],
|
||||
loading: false
|
||||
}));
|
||||
|
||||
|
||||
@ -79,6 +79,14 @@ export const masterService = {
|
||||
saveZonalManager: async (data: any) => {
|
||||
return (API as any).saveZonalManager(data).then((res: any) => res.data);
|
||||
},
|
||||
getDDLeads: async () => {
|
||||
const response = await (API as any).getDDLeads();
|
||||
return response.data;
|
||||
},
|
||||
saveDDLead: async (data: any) => {
|
||||
return (API as any).saveDDLead(data).then((res: any) => res.data);
|
||||
},
|
||||
|
||||
|
||||
// User Management
|
||||
getUsers: async () => {
|
||||
|
||||
@ -91,6 +91,7 @@ export interface MasterState {
|
||||
emailTemplates: any[];
|
||||
slaConfigs: any[];
|
||||
users: any[];
|
||||
ddLeads: any[];
|
||||
areasPagination: {
|
||||
total: number;
|
||||
page: number;
|
||||
@ -116,6 +117,7 @@ const initialState: MasterState = {
|
||||
emailTemplates: [],
|
||||
slaConfigs: [],
|
||||
users: [],
|
||||
ddLeads: [],
|
||||
areasPagination: {
|
||||
total: 0,
|
||||
page: 1,
|
||||
@ -162,13 +164,16 @@ const masterSlice = createSlice({
|
||||
setError: (state, action: PayloadAction<string | null>) => {
|
||||
state.error = action.payload;
|
||||
},
|
||||
setDdLeads: (state, action: PayloadAction<any[]>) => {
|
||||
state.ddLeads = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const {
|
||||
setMasterData, setZones, setRegionalOffices, setAsms,
|
||||
setZonalManagerMappings, setUsers, setLoading, setError,
|
||||
setAreasData, setAreasLoading
|
||||
setAreasData, setAreasLoading, setDdLeads
|
||||
} = masterSlice.actions;
|
||||
|
||||
export default masterSlice.reducer;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user