@@ -19,6 +19,8 @@ import {
1919 UploadProps ,
2020 SelectProps ,
2121 List ,
22+ Tag ,
23+ Cascader ,
2224} from "antd" ;
2325import { useEffect , useState } from "react" ;
2426import axios from "axios" ;
@@ -67,7 +69,10 @@ const JobDetails = ({
6769 const [ testType , setTestType ] = useState ( [ ] ) ;
6870 const [ seasonType , setSeasonType ] = useState ( "" ) ;
6971 const [ interviewType , setInterviewType ] = useState ( [ ] ) ;
70- const [ programs , setPrograms ] = useState < SelectProps [ "options" ] > ( [ ] ) ;
72+ const [ programsData , setProgramsData ] = useState < any > ( {
73+ programs : [ ] ,
74+ coursesMap : new Map ( ) ,
75+ } ) ;
7176 let testTypeOptions : any = [ ] ;
7277 let interviewTypeOptions : any = [ ] ;
7378 const programsOptions : SelectProps [ "options" ] = [ ] ;
@@ -120,16 +125,170 @@ const JobDetails = ({
120125 if ( matchingSeason ) {
121126 setSeasonType ( matchingSeason . type ) ;
122127 }
123- res . data . programs . map ( ( it : any ) => {
124- programsOptions . push ( {
125- value : it . id ,
126- label : `${ it . branch } - ${ it . course } - ${ it . year } ` ,
127- } ) ;
128+ // Process programs data
129+ const uniqueYears = new Set < string > ( ) ;
130+ const programsMap = new Map < string , Set < string > > ( ) ;
131+ const branchesMap = new Map < string , Set < string > > ( ) ;
132+
133+ res . data . programs . forEach ( ( program : any ) => {
134+ uniqueYears . add ( program . year ) ;
135+
136+ const yearCourseKey = program . year ;
137+ if ( ! programsMap . has ( yearCourseKey ) ) {
138+ programsMap . set ( yearCourseKey , new Set ( ) ) ;
139+ }
140+ programsMap . get ( yearCourseKey ) ?. add ( program . course ) ;
141+
142+ const courseBranchKey = `${ program . year } -${ program . course } ` ;
143+ if ( ! branchesMap . has ( courseBranchKey ) ) {
144+ branchesMap . set ( courseBranchKey , new Set ( ) ) ;
145+ }
146+ branchesMap . get ( courseBranchKey ) ?. add ( program . branch ) ;
147+ } ) ;
148+
149+ setYears ( Array . from ( uniqueYears ) ) ;
150+ setProgramsData ( {
151+ programs : res . data . programs ,
152+ coursesMap : programsMap ,
153+ branchesMap : branchesMap ,
128154 } ) ;
129- setPrograms ( programsOptions ) ;
130155 } ) ;
131156 } , [ ] ) ;
132157
158+ const [ years , setYears ] = useState < string [ ] > ( [ ] ) ;
159+ const [ courses , setCourses ] = useState < string [ ] > ( [ ] ) ;
160+ const [ branches , setBranches ] = useState < string [ ] > ( [ ] ) ;
161+
162+ const [ selectedYear , setSelectedYear ] = useState < string > ( "" ) ;
163+ const [ selectedCourse , setSelectedCourse ] = useState < string > ( "" ) ;
164+ const [ selectedBranch , setSelectedBranch ] = useState < string > ( "" ) ;
165+ const [ dropdownVisible , setDropdownVisible ] = useState ( false ) ;
166+
167+ const handleYearChange = ( year : string ) => {
168+ setSelectedYear ( year ) ;
169+ setSelectedCourse ( "" ) ;
170+ setSelectedBranch ( "" ) ;
171+
172+ const availableCourses = Array . from (
173+ programsData . coursesMap . get ( year ) || [ ] ,
174+ ) as string [ ] ;
175+ setCourses ( availableCourses ) ;
176+ } ;
177+
178+ const handleCourseChange = ( course : string ) => {
179+ setSelectedCourse ( course ) ;
180+ setSelectedBranch ( "" ) ;
181+
182+ const key = `${ selectedYear } -${ course } ` ;
183+ const availableBranches = Array . from (
184+ programsData . branchesMap . get ( key ) || [ ] ,
185+ ) as string [ ] ;
186+ setBranches ( availableBranches ) ;
187+ } ;
188+
189+ const handleBranchChange = ( branch : string , fieldIndex : number ) => {
190+ if ( branch === "ALL" ) {
191+ const allBranchesSelected = branches . every ( ( branch ) =>
192+ selectedPrograms . some (
193+ ( p ) =>
194+ p . year === selectedYear &&
195+ p . course === selectedCourse &&
196+ p . branch === branch ,
197+ ) ,
198+ ) ;
199+
200+ if ( allBranchesSelected ) {
201+ const updatedPrograms = selectedPrograms . filter (
202+ ( p ) => ! ( p . year === selectedYear && p . course === selectedCourse ) ,
203+ ) ;
204+ setSelectedPrograms ( updatedPrograms ) ;
205+ form . setFieldValue (
206+ [ "salaries" , fieldIndex , "programs" ] ,
207+ updatedPrograms . map ( ( p ) => p . id ) ,
208+ ) ;
209+ } else {
210+ const allPrograms = programsData . programs
211+ . filter ( ( p ) => p . year === selectedYear && p . course === selectedCourse )
212+ . map ( ( p ) => ( {
213+ year : p . year ,
214+ course : p . course ,
215+ branch : p . branch ,
216+ id : p . id ,
217+ } ) ) ;
218+
219+ const newPrograms = allPrograms . filter (
220+ ( newProg ) =>
221+ ! selectedPrograms . some (
222+ ( existingProg ) => existingProg . id === newProg . id ,
223+ ) ,
224+ ) ;
225+
226+ const updatedPrograms = [ ...selectedPrograms , ...newPrograms ] ;
227+ setSelectedPrograms ( updatedPrograms ) ;
228+ form . setFieldValue (
229+ [ "salaries" , fieldIndex , "programs" ] ,
230+ updatedPrograms . map ( ( p ) => p . id ) ,
231+ ) ;
232+ }
233+ } else {
234+ const program = programsData . programs . find (
235+ ( p ) =>
236+ p . year === selectedYear &&
237+ p . course === selectedCourse &&
238+ p . branch === branch ,
239+ ) ;
240+
241+ if ( program ) {
242+ const isSelected = selectedPrograms . some ( ( p ) => p . id === program . id ) ;
243+
244+ if ( isSelected ) {
245+ const updatedPrograms = selectedPrograms . filter (
246+ ( p ) => p . id !== program . id ,
247+ ) ;
248+ setSelectedPrograms ( updatedPrograms ) ;
249+ form . setFieldValue (
250+ [ "salaries" , fieldIndex , "programs" ] ,
251+ updatedPrograms . map ( ( p ) => p . id ) ,
252+ ) ;
253+ } else {
254+ const newProgram = {
255+ year : program . year ,
256+ course : program . course ,
257+ branch : program . branch ,
258+ id : program . id ,
259+ } ;
260+
261+ const updatedPrograms = [ ...selectedPrograms , newProgram ] ;
262+ setSelectedPrograms ( updatedPrograms ) ;
263+ form . setFieldValue (
264+ [ "salaries" , fieldIndex , "programs" ] ,
265+ updatedPrograms . map ( ( p ) => p . id ) ,
266+ ) ;
267+ }
268+ }
269+ }
270+
271+ setSelectedBranch ( "" ) ;
272+ } ;
273+
274+ const handleRemoveProgram = ( programId : string , fieldIndex : number ) => {
275+ const updatedPrograms = selectedPrograms . filter ( ( p ) => p . id !== programId ) ;
276+ setSelectedPrograms ( updatedPrograms ) ;
277+ form . setFieldValue (
278+ [ "salaries" , fieldIndex , "programs" ] ,
279+ updatedPrograms . map ( ( p ) => p . id ) ,
280+ ) ;
281+ } ;
282+
283+ const [ selectedPrograms , setSelectedPrograms ] = useState <
284+ Array < {
285+ year : string ;
286+ course : string ;
287+ branch : string ;
288+ id : string ;
289+ } >
290+ > ( [ ] ) ;
291+
133292 return (
134293 < Form
135294 layout = "vertical"
@@ -585,15 +744,99 @@ const JobDetails = ({
585744 >
586745 < h2 className = "text-sm " > Criteria</ h2 >
587746 < Row gutter = { 24 } >
588- < Col span = { 12 } >
747+ < Col span = { 24 } >
589748 < Form . Item label = "Programs" name = { [ field . name , "programs" ] } >
590- < Select
591- mode = "multiple"
592- placeholder = "Please Select"
593- options = { programs }
594- > </ Select >
749+ < div >
750+ < div style = { { marginBottom : "10px" } } >
751+ < Select
752+ style = { { width : "24%" , marginRight : "1%" } }
753+ placeholder = "Select Year"
754+ value = { selectedYear || undefined }
755+ onChange = { handleYearChange }
756+ options = { years . map ( ( year ) => ( {
757+ value : year ,
758+ label : year ,
759+ } ) ) }
760+ />
761+ < Select
762+ style = { { width : "24%" , marginRight : "1%" } }
763+ placeholder = "Select Course"
764+ value = { selectedCourse || undefined }
765+ onChange = { handleCourseChange }
766+ disabled = { ! selectedYear }
767+ options = { courses . map ( ( course ) => ( {
768+ value : course ,
769+ label : course ,
770+ } ) ) }
771+ />
772+ < Select
773+ style = { { width : "50%" } }
774+ placeholder = "Select Branch"
775+ value = { selectedBranch }
776+ onChange = { ( value ) =>
777+ handleBranchChange ( value , field . name )
778+ }
779+ disabled = { ! selectedCourse }
780+ options = { [
781+ { value : "ALL" , label : "Open For All" } ,
782+ ...branches . map ( ( branch ) => {
783+ const isSelected = selectedPrograms . some (
784+ ( p ) =>
785+ p . year === selectedYear &&
786+ p . course === selectedCourse &&
787+ p . branch === branch ,
788+ ) ;
789+ return {
790+ value : branch ,
791+ label : branch ,
792+ className : isSelected
793+ ? "ant-select-item-option-selected"
794+ : "" ,
795+ } ;
796+ } ) ,
797+ ] }
798+ />
799+ </ div >
800+
801+ { selectedPrograms . length > 0 && (
802+ < div
803+ style = { {
804+ marginTop : "10px" ,
805+ border : "1px solid #d9d9d9" ,
806+ borderRadius : "4px" ,
807+ padding : "8px" ,
808+ minHeight : "50px" ,
809+ maxHeight : "150px" ,
810+ overflowY : "auto" ,
811+ } }
812+ >
813+ < h3 className = "ml-2" > Selected Programs :</ h3 >
814+ { selectedPrograms . map ( ( program ) => (
815+ < Tag
816+ key = { program . id }
817+ closable
818+ onClose = { ( ) =>
819+ handleRemoveProgram ( program . id , field . name )
820+ }
821+ style = { {
822+ fontSize : "14px" ,
823+ margin : "4px" ,
824+ maxWidth : "100%" ,
825+ overflow : "hidden" ,
826+ textOverflow : "ellipsis" ,
827+ whiteSpace : "nowrap" ,
828+ } }
829+ >
830+ { `${ program . branch } - ${ program . course } - ${ program . year } ` }
831+ </ Tag >
832+ ) ) }
833+ </ div >
834+ ) }
835+ </ div >
595836 </ Form . Item >
596837 </ Col >
838+ </ Row >
839+ < Row gutter = { 24 } >
597840 < Col span = { 12 } >
598841 < Form . Item label = "Genders" name = { [ field . name , "genders" ] } >
599842 < Select
@@ -607,8 +850,6 @@ const JobDetails = ({
607850 > </ Select >
608851 </ Form . Item >
609852 </ Col >
610- </ Row >
611- < Row gutter = { 24 } >
612853 < Col span = { 12 } >
613854 < Form . Item
614855 label = "Categories"
@@ -627,6 +868,8 @@ const JobDetails = ({
627868 > </ Select >
628869 </ Form . Item >
629870 </ Col >
871+ </ Row >
872+ < Row gutter = { 24 } >
630873 < Col span = { 12 } >
631874 < Form . Item
632875 label = "Backlogs"
@@ -644,6 +887,11 @@ const JobDetails = ({
644887 />
645888 </ Form . Item >
646889 </ Col >
890+ < Col span = { 12 } >
891+ < Form . Item label = "Min CPI" name = { [ field . name , "minCPI" ] } >
892+ < Input placeholder = "Min CPI" />
893+ </ Form . Item >
894+ </ Col >
647895 </ Row >
648896 < Row gutter = { 24 } >
649897 < Col span = { 12 } >
@@ -713,41 +961,6 @@ const JobDetails = ({
713961 </ Form . Item >
714962 </ Col >
715963 </ Row >
716- < Row gutter = { 24 } >
717- < Col span = { 12 } >
718- < Form . Item
719- label = "Min CPI"
720- name = { [ field . name , "minCPI" ] }
721- rules = { [
722- {
723- pattern : / ^ \d * \. ? \d * $ / ,
724- message : "Please enter a positive decimal value" ,
725- } ,
726- {
727- validator : ( _ , value ) => {
728- if ( value === undefined || value === "" )
729- return Promise . resolve ( ) ;
730- if ( ! / ^ \d * \. ? \d * $ / . test ( value ) )
731- return Promise . resolve ( ) ;
732- const num = parseFloat ( value ) ;
733- if ( isNaN ( num ) || num > 10 ) {
734- return Promise . reject (
735- "Value must be less than or equal to 10" ,
736- ) ;
737- }
738- return Promise . resolve ( ) ;
739- } ,
740- } ,
741- ] }
742- getValueFromEvent = { ( e ) => {
743- const value = e . target . value . replace ( / \s + / g, "" ) ;
744- return value ;
745- } }
746- >
747- < Input placeholder = "Min CPI" />
748- </ Form . Item >
749- </ Col >
750- </ Row >
751964 { seasonType === "PLACEMENT" ? (
752965 < >
753966 < h2 className = "text-sm" > Placement Details</ h2 >
0 commit comments