Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
313 changes: 263 additions & 50 deletions src/components/JAF/JobDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
UploadProps,
SelectProps,
List,
Tag,
Cascader,
} from "antd";
import { useEffect, useState } from "react";
import axios from "axios";
Expand Down Expand Up @@ -67,7 +69,10 @@ const JobDetails = ({
const [testType, setTestType] = useState([]);
const [seasonType, setSeasonType] = useState("");
const [interviewType, setInterviewType] = useState([]);
const [programs, setPrograms] = useState<SelectProps["options"]>([]);
const [programsData, setProgramsData] = useState<any>({
programs: [],
coursesMap: new Map(),
});
let testTypeOptions: any = [];
let interviewTypeOptions: any = [];
const programsOptions: SelectProps["options"] = [];
Expand Down Expand Up @@ -120,16 +125,170 @@ const JobDetails = ({
if (matchingSeason) {
setSeasonType(matchingSeason.type);
}
res.data.programs.map((it: any) => {
programsOptions.push({
value: it.id,
label: `${it.branch} - ${it.course} - ${it.year}`,
});
// Process programs data
const uniqueYears = new Set<string>();
const programsMap = new Map<string, Set<string>>();
const branchesMap = new Map<string, Set<string>>();

res.data.programs.forEach((program: any) => {
uniqueYears.add(program.year);

const yearCourseKey = program.year;
if (!programsMap.has(yearCourseKey)) {
programsMap.set(yearCourseKey, new Set());
}
programsMap.get(yearCourseKey)?.add(program.course);

const courseBranchKey = `${program.year}-${program.course}`;
if (!branchesMap.has(courseBranchKey)) {
branchesMap.set(courseBranchKey, new Set());
}
branchesMap.get(courseBranchKey)?.add(program.branch);
});

setYears(Array.from(uniqueYears));
setProgramsData({
programs: res.data.programs,
coursesMap: programsMap,
branchesMap: branchesMap,
});
setPrograms(programsOptions);
});
}, []);

const [years, setYears] = useState<string[]>([]);
const [courses, setCourses] = useState<string[]>([]);
const [branches, setBranches] = useState<string[]>([]);

const [selectedYear, setSelectedYear] = useState<string>("");
const [selectedCourse, setSelectedCourse] = useState<string>("");
const [selectedBranch, setSelectedBranch] = useState<string>("");
const [dropdownVisible, setDropdownVisible] = useState(false);

const handleYearChange = (year: string) => {
setSelectedYear(year);
setSelectedCourse("");
setSelectedBranch("");

const availableCourses = Array.from(
programsData.coursesMap.get(year) || [],
) as string[];
setCourses(availableCourses);
};

const handleCourseChange = (course: string) => {
setSelectedCourse(course);
setSelectedBranch("");

const key = `${selectedYear}-${course}`;
const availableBranches = Array.from(
programsData.branchesMap.get(key) || [],
) as string[];
setBranches(availableBranches);
};

const handleBranchChange = (branch: string, fieldIndex: number) => {
if (branch === "ALL") {
const allBranchesSelected = branches.every((branch) =>
selectedPrograms.some(
(p) =>
p.year === selectedYear &&
p.course === selectedCourse &&
p.branch === branch,
),
);

if (allBranchesSelected) {
const updatedPrograms = selectedPrograms.filter(
(p) => !(p.year === selectedYear && p.course === selectedCourse),
);
setSelectedPrograms(updatedPrograms);
form.setFieldValue(
["salaries", fieldIndex, "programs"],
updatedPrograms.map((p) => p.id),
);
} else {
const allPrograms = programsData.programs
.filter((p) => p.year === selectedYear && p.course === selectedCourse)
.map((p) => ({
year: p.year,
course: p.course,
branch: p.branch,
id: p.id,
}));

const newPrograms = allPrograms.filter(
(newProg) =>
!selectedPrograms.some(
(existingProg) => existingProg.id === newProg.id,
),
);

const updatedPrograms = [...selectedPrograms, ...newPrograms];
setSelectedPrograms(updatedPrograms);
form.setFieldValue(
["salaries", fieldIndex, "programs"],
updatedPrograms.map((p) => p.id),
);
}
} else {
const program = programsData.programs.find(
(p) =>
p.year === selectedYear &&
p.course === selectedCourse &&
p.branch === branch,
);

if (program) {
const isSelected = selectedPrograms.some((p) => p.id === program.id);

if (isSelected) {
const updatedPrograms = selectedPrograms.filter(
(p) => p.id !== program.id,
);
setSelectedPrograms(updatedPrograms);
form.setFieldValue(
["salaries", fieldIndex, "programs"],
updatedPrograms.map((p) => p.id),
);
} else {
const newProgram = {
year: program.year,
course: program.course,
branch: program.branch,
id: program.id,
};

const updatedPrograms = [...selectedPrograms, newProgram];
setSelectedPrograms(updatedPrograms);
form.setFieldValue(
["salaries", fieldIndex, "programs"],
updatedPrograms.map((p) => p.id),
);
}
}
}

setSelectedBranch("");
};

const handleRemoveProgram = (programId: string, fieldIndex: number) => {
const updatedPrograms = selectedPrograms.filter((p) => p.id !== programId);
setSelectedPrograms(updatedPrograms);
form.setFieldValue(
["salaries", fieldIndex, "programs"],
updatedPrograms.map((p) => p.id),
);
};

const [selectedPrograms, setSelectedPrograms] = useState<
Array<{
year: string;
course: string;
branch: string;
id: string;
}>
>([]);

return (
<Form
layout="vertical"
Expand Down Expand Up @@ -585,15 +744,99 @@ const JobDetails = ({
>
<h2 className="text-sm ">Criteria</h2>
<Row gutter={24}>
<Col span={12}>
<Col span={24}>
<Form.Item label="Programs" name={[field.name, "programs"]}>
<Select
mode="multiple"
placeholder="Please Select"
options={programs}
></Select>
<div>
<div style={{ marginBottom: "10px" }}>
<Select
style={{ width: "24%", marginRight: "1%" }}
placeholder="Select Year"
value={selectedYear || undefined}
onChange={handleYearChange}
options={years.map((year) => ({
value: year,
label: year,
}))}
/>
<Select
style={{ width: "24%", marginRight: "1%" }}
placeholder="Select Course"
value={selectedCourse || undefined}
onChange={handleCourseChange}
disabled={!selectedYear}
options={courses.map((course) => ({
value: course,
label: course,
}))}
/>
<Select
style={{ width: "50%" }}
placeholder="Select Branch"
value={selectedBranch}
onChange={(value) =>
handleBranchChange(value, field.name)
}
disabled={!selectedCourse}
options={[
{ value: "ALL", label: "Open For All" },
...branches.map((branch) => {
const isSelected = selectedPrograms.some(
(p) =>
p.year === selectedYear &&
p.course === selectedCourse &&
p.branch === branch,
);
return {
value: branch,
label: branch,
className: isSelected
? "ant-select-item-option-selected"
: "",
};
}),
]}
/>
</div>

{selectedPrograms.length > 0 && (
<div
style={{
marginTop: "10px",
border: "1px solid #d9d9d9",
borderRadius: "4px",
padding: "8px",
minHeight: "50px",
maxHeight: "150px",
overflowY: "auto",
}}
>
<h3 className="ml-2">Selected Programs :</h3>
{selectedPrograms.map((program) => (
<Tag
key={program.id}
closable
onClose={() =>
handleRemoveProgram(program.id, field.name)
}
style={{
fontSize: "14px",
margin: "4px",
maxWidth: "100%",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
}}
>
{`${program.branch} - ${program.course} - ${program.year}`}
</Tag>
))}
</div>
)}
</div>
</Form.Item>
</Col>
</Row>
<Row gutter={24}>
<Col span={12}>
<Form.Item label="Genders" name={[field.name, "genders"]}>
<Select
Expand All @@ -607,8 +850,6 @@ const JobDetails = ({
></Select>
</Form.Item>
</Col>
</Row>
<Row gutter={24}>
<Col span={12}>
<Form.Item
label="Categories"
Expand All @@ -627,6 +868,8 @@ const JobDetails = ({
></Select>
</Form.Item>
</Col>
</Row>
<Row gutter={24}>
<Col span={12}>
<Form.Item
label="Backlogs"
Expand All @@ -644,6 +887,11 @@ const JobDetails = ({
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="Min CPI" name={[field.name, "minCPI"]}>
<Input placeholder="Min CPI" />
</Form.Item>
</Col>
</Row>
<Row gutter={24}>
<Col span={12}>
Expand Down Expand Up @@ -713,41 +961,6 @@ const JobDetails = ({
</Form.Item>
</Col>
</Row>
<Row gutter={24}>
<Col span={12}>
<Form.Item
label="Min CPI"
name={[field.name, "minCPI"]}
rules={[
{
pattern: /^\d*\.?\d*$/,
message: "Please enter a positive decimal value",
},
{
validator: (_, value) => {
if (value === undefined || value === "")
return Promise.resolve();
if (!/^\d*\.?\d*$/.test(value))
return Promise.resolve();
const num = parseFloat(value);
if (isNaN(num) || num > 10) {
return Promise.reject(
"Value must be less than or equal to 10",
);
}
return Promise.resolve();
},
},
]}
getValueFromEvent={(e) => {
const value = e.target.value.replace(/\s+/g, "");
return value;
}}
>
<Input placeholder="Min CPI" />
</Form.Item>
</Col>
</Row>
{seasonType === "PLACEMENT" ? (
<>
<h2 className="text-sm">Placement Details</h2>
Expand Down