@@ -59,6 +59,9 @@ interface WorkingVillageAssignmentWidgetProps {
5959 onSelectionChange ?: ( centerId : string , selectedVillages : Set < string > , villagesByBlock : Record < string , Array < { id : string ; name : string ; blockId : string ; unavailable : boolean ; assigned : boolean } > > ) => void ;
6060 hideConfirmButton ?: boolean ; // Hide the Confirm Assignment button
6161 onCenterOptionsChange ?: ( centerOptions : any [ ] ) => void ; // Callback to get center options
62+ // Restore props: keep existing behaviors unless enabled
63+ isForRestore ?: boolean ; // Flag to indicate restore/reactivate mode
64+ centerOptionsOverride ?: Array < { id : string ; name : string ; cohortMembershipId ?: string ; customFields ?: any [ ] } > ; // Override center dropdown options (e.g. from getCohortList)
6265 // Reassign props
6366 centerId ?: string ; // Center ID to pre-select in reassign flow
6467 existingWorkingVillageIds ?: string ; // Comma-separated string of existing village IDs (e.g., "648579, 648570")
@@ -75,6 +78,8 @@ const WorkingVillageAssignmentWidget: React.FC<WorkingVillageAssignmentWidgetPro
7578 onSelectionChange,
7679 hideConfirmButton = false ,
7780 onCenterOptionsChange,
81+ isForRestore = false ,
82+ centerOptionsOverride,
7883 centerId : propCenterId ,
7984 existingWorkingVillageIds,
8085 isForReassign = false ,
@@ -158,6 +163,44 @@ const WorkingVillageAssignmentWidget: React.FC<WorkingVillageAssignmentWidgetPro
158163 selectedValues : any [ ] | null ;
159164 } | null > ( null ) ;
160165
166+ // Store center's CATCHMENT_AREA fetched via API in restore mode (keyed by centerId)
167+ const [ restoreCenterCatchmentArea , setRestoreCenterCatchmentArea ] = useState < {
168+ centerId : string ;
169+ selectedValues : any [ ] | null ;
170+ } | null > ( null ) ;
171+
172+ const __overrideCenterOptions = useMemo ( ( ) => {
173+ if ( ! Array . isArray ( centerOptionsOverride ) ) return null ;
174+ return centerOptionsOverride . map ( ( c ) => ( {
175+ id : String ( c . id ) ,
176+ name : c . name ?. trim ?.( ) || String ( c . name || c . id ) ,
177+ stateId : null ,
178+ districtId : null ,
179+ blockId : null ,
180+ villages : 0 ,
181+ blocks : 0 ,
182+ customFields : c . customFields || [ ] ,
183+ cohortMembershipId : c . cohortMembershipId ,
184+ } ) ) ;
185+ } , [ centerOptionsOverride ] ) ;
186+
187+ // If center options are overridden (e.g. restore flow), use them and skip internal center loading.
188+ useEffect ( ( ) => {
189+ if ( ! Array . isArray ( centerOptionsOverride ) ) return ;
190+
191+ const centers = __overrideCenterOptions || [ ] ;
192+ setCenterOptions ( centers ) ;
193+
194+ // Auto-select center when only one option is available (consistent with LMP behavior)
195+ if ( ! selectedCenter ) {
196+ if ( propCenterId && centers . some ( ( c : any ) => c . id === propCenterId ) ) {
197+ setSelectedCenter ( String ( propCenterId ) ) ;
198+ } else if ( centers . length === 1 ) {
199+ setSelectedCenter ( String ( centers [ 0 ] . id ) ) ;
200+ }
201+ }
202+ } , [ centerOptionsOverride , __overrideCenterOptions , propCenterId , selectedCenter ] ) ;
203+
161204 // Load villages for all catchment blocks
162205 const loadVillagesForBlocks = useCallback ( async ( ) => {
163206 const __seq = ++ __villagesLoadSeqRef . current ;
@@ -884,8 +927,10 @@ const WorkingVillageAssignmentWidget: React.FC<WorkingVillageAssignmentWidgetPro
884927
885928 // Load centers whenever state/district/block changes
886929 useEffect ( ( ) => {
930+ // If parent provides center options explicitly, do not call center-loading APIs
931+ if ( Array . isArray ( centerOptionsOverride ) ) return ;
887932 loadCenters ( ) ;
888- } , [ loadCenters ] ) ;
933+ } , [ loadCenters , centerOptionsOverride ] ) ;
889934
890935 // Fetch selected center's CATCHMENT_AREA via API in reassign mode (so villages update when user changes center)
891936 useEffect ( ( ) => {
@@ -972,8 +1017,142 @@ const WorkingVillageAssignmentWidget: React.FC<WorkingVillageAssignmentWidgetPro
9721017 } ;
9731018 } , [ isForReassign , selectedCenter ] ) ;
9741019
1020+ // Fetch selected center's CATCHMENT_AREA via API in restore mode
1021+ // (getCohortList centers may not include customFields, but villages need CATCHMENT_AREA)
1022+ useEffect ( ( ) => {
1023+ if ( ! isForRestore || ! selectedCenter ) {
1024+ setRestoreCenterCatchmentArea ( null ) ;
1025+ return ;
1026+ }
1027+
1028+ // If current center already contains a usable CATCHMENT_AREA, no need to fetch
1029+ const currentCenter = centerOptions . find ( ( c ) => c . id === selectedCenter ) ;
1030+ const existingCatchmentAreaField = currentCenter ?. customFields ?. find (
1031+ ( field : any ) =>
1032+ field ?. label === 'CATCHMENT_AREA' &&
1033+ Array . isArray ( field ?. selectedValues ) &&
1034+ field . selectedValues . length > 0
1035+ ) ;
1036+ if ( existingCatchmentAreaField ?. selectedValues ) {
1037+ setRestoreCenterCatchmentArea ( {
1038+ centerId : selectedCenter ,
1039+ selectedValues : existingCatchmentAreaField . selectedValues ,
1040+ } ) ;
1041+ return ;
1042+ }
1043+
1044+ // Clear previous catchment while loading
1045+ setRestoreCenterCatchmentArea ( { centerId : selectedCenter , selectedValues : null } ) ;
1046+ let isMounted = true ;
1047+ const centerIdToFetch = selectedCenter ;
1048+
1049+ const fetchCenterCatchmentArea = async ( ) => {
1050+ try {
1051+ const tenantId = localStorage . getItem ( 'tenantId' ) || '' ;
1052+ const token = localStorage . getItem ( 'token' ) || '' ;
1053+ const academicYearId = localStorage . getItem ( 'academicYearId' ) || '' ;
1054+
1055+ const response = await axios . post (
1056+ `${ process . env . NEXT_PUBLIC_MIDDLEWARE_URL } /cohort/search` ,
1057+ {
1058+ limit : 200 ,
1059+ offset : 0 ,
1060+ filters : {
1061+ type : 'COHORT' ,
1062+ status : [ 'active' ] ,
1063+ cohortId : [ centerIdToFetch ] ,
1064+ } ,
1065+ } ,
1066+ {
1067+ headers : {
1068+ 'Content-Type' : 'application/json' ,
1069+ tenantId : tenantId ,
1070+ Authorization : `Bearer ${ token } ` ,
1071+ academicyearid : academicYearId ,
1072+ } ,
1073+ }
1074+ ) ;
1075+
1076+ if ( ! isMounted ) return ;
1077+
1078+ const cohortDetails = response ?. data ?. result ?. results ?. cohortDetails || [ ] ;
1079+ const center = cohortDetails . find ( ( c : any ) => c . cohortId === centerIdToFetch ) ;
1080+
1081+ if ( center && center . customFields ) {
1082+ const catchmentAreaField = center . customFields . find (
1083+ ( field : any ) => field . label === 'CATCHMENT_AREA'
1084+ ) ;
1085+
1086+ setRestoreCenterCatchmentArea ( {
1087+ centerId : centerIdToFetch ,
1088+ selectedValues : catchmentAreaField ?. selectedValues || null ,
1089+ } ) ;
1090+ } else {
1091+ setRestoreCenterCatchmentArea ( { centerId : centerIdToFetch , selectedValues : null } ) ;
1092+ }
1093+ } catch ( error ) {
1094+ console . error ( 'Error fetching center CATCHMENT_AREA (restore):' , error ) ;
1095+ if ( isMounted ) {
1096+ setRestoreCenterCatchmentArea ( { centerId : centerIdToFetch , selectedValues : null } ) ;
1097+ }
1098+ }
1099+ } ;
1100+
1101+ fetchCenterCatchmentArea ( ) ;
1102+
1103+ return ( ) => {
1104+ isMounted = false ;
1105+ } ;
1106+ } , [ isForRestore , selectedCenter , centerOptions ] ) ;
1107+
9751108 // Extract catchment blocks from selected center's CATCHMENT_AREA or fetched CATCHMENT_AREA (in reassign mode)
9761109 useEffect ( ( ) => {
1110+ // Priority 0: In restore mode, prefer fetched CATCHMENT_AREA for the currently selected center
1111+ if (
1112+ isForRestore &&
1113+ selectedCenter &&
1114+ restoreCenterCatchmentArea &&
1115+ restoreCenterCatchmentArea . centerId === selectedCenter &&
1116+ Array . isArray ( restoreCenterCatchmentArea . selectedValues ) &&
1117+ restoreCenterCatchmentArea . selectedValues . length > 0
1118+ ) {
1119+ const extractedBlocks : Array < {
1120+ id : string | number ;
1121+ name : string ;
1122+ districtId : string | number ;
1123+ districtName : string ;
1124+ stateId : string | number ;
1125+ stateName : string ;
1126+ } > = [ ] ;
1127+
1128+ const __selectedValues = restoreCenterCatchmentArea . selectedValues ;
1129+ __selectedValues . forEach ( ( stateData : any ) => {
1130+ const stateId = stateData . stateId ;
1131+ const stateName = stateData . stateName || '' ;
1132+ if ( stateData . districts && Array . isArray ( stateData . districts ) ) {
1133+ stateData . districts . forEach ( ( district : any ) => {
1134+ const districtId = district . districtId ;
1135+ const districtName = district . districtName || '' ;
1136+ if ( district . blocks && Array . isArray ( district . blocks ) ) {
1137+ district . blocks . forEach ( ( block : any ) => {
1138+ extractedBlocks . push ( {
1139+ id : block . id ,
1140+ name : block . name || '' ,
1141+ districtId,
1142+ districtName,
1143+ stateId,
1144+ stateName,
1145+ } ) ;
1146+ } ) ;
1147+ }
1148+ } ) ;
1149+ }
1150+ } ) ;
1151+
1152+ setCatchmentBlocks ( extractedBlocks ) ;
1153+ return ;
1154+ }
1155+
9771156 // Priority 1: In reassign mode, use fetched CATCHMENT_AREA for the currently selected center (fetched when selectedCenter changes)
9781157 if (
9791158 isForReassign &&
@@ -1090,7 +1269,15 @@ const WorkingVillageAssignmentWidget: React.FC<WorkingVillageAssignmentWidgetPro
10901269 } ) ;
10911270
10921271 setCatchmentBlocks ( extractedBlocks ) ;
1093- } , [ selectedCenter , centerOptions , isForReassign , propCenterId , reassignCenterCatchmentArea ] ) ;
1272+ } , [
1273+ selectedCenter ,
1274+ centerOptions ,
1275+ isForRestore ,
1276+ restoreCenterCatchmentArea ,
1277+ isForReassign ,
1278+ propCenterId ,
1279+ reassignCenterCatchmentArea ,
1280+ ] ) ;
10941281
10951282 // Clear villages when center is reset to empty
10961283 useEffect ( ( ) => {
0 commit comments