Skip to content

Commit 1f22b1b

Browse files
Delete endpoints (#417)
1 parent 5eee1f8 commit 1f22b1b

10 files changed

Lines changed: 362 additions & 55 deletions

File tree

src/app/(routes)/admin/companies/page.tsx

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
"use client";
2-
import { fetchcompanies } from "@/helpers/api";
2+
import { fetchcompanies, deleteCompanies } from "@/helpers/api";
33
import generateColumns from "@/components/NewTableComponent/ColumnMapping";
44
import { companyDTO } from "@/dto/CompanyDto";
55
import Table from "@/components/NewTableComponent/Table";
66
import { useEffect, useState } from "react";
77
import Loader from "@/components/Loader/loader";
8+
import toast from "react-hot-toast";
89

910
const hiddenColumns = ["id"];
1011

@@ -16,15 +17,43 @@ const JobPage = () => {
1617
(column: any) => !hiddenColumns.includes(column?.accessorKey),
1718
);
1819

19-
useEffect(() => {
20-
const getData = async () => {
20+
const getData = async () => {
21+
setLoading(true);
22+
try {
2123
const data = await fetchcompanies();
2224
setAllCompanies(data);
25+
} catch (error) {
26+
toast.error("Failed to fetch companies");
27+
} finally {
2328
setLoading(false);
24-
};
29+
}
30+
};
31+
32+
useEffect(() => {
2533
getData();
2634
}, []);
2735

36+
const handleDelete = async (selectedCompanies: any[]) => {
37+
if (selectedCompanies.length === 0) {
38+
toast.error("Please select at least one company to delete");
39+
return;
40+
}
41+
42+
const confirmMessage = `Are you sure you want to delete ${selectedCompanies.length} company/companies? This action cannot be undone.`;
43+
if (!window.confirm(confirmMessage)) {
44+
return;
45+
}
46+
47+
try {
48+
const ids = selectedCompanies.map((company) => company.id);
49+
await deleteCompanies(ids);
50+
toast.success(`Successfully deleted ${selectedCompanies.length} company/companies`);
51+
await getData(); // Refresh the list
52+
} catch (error) {
53+
toast.error("Failed to delete companies. They might have associated jobs.");
54+
}
55+
};
56+
2857
return (
2958
<div className="m-2 md:m-6 lg:m-10">
3059
<h1 className="text-center font-bold text-2xl md:text-3xl my-3 md:my-5 py-3 md:py-5">
@@ -41,6 +70,8 @@ const JobPage = () => {
4170
data={allCompanies}
4271
columns={visibleColumns}
4372
type={"company"}
73+
buttonText="Delete Selected"
74+
buttonAction={handleDelete}
4475
/>
4576
)}
4677
</div>

src/app/(routes)/admin/jobs/page.tsx

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
"use client";
2-
import { fetchAllJobs } from "@/helpers/api";
2+
import { fetchAllJobs, deleteJobs } from "@/helpers/api";
33
import generateColumns from "@/components/NewTableComponent/ColumnMapping";
44
import type { RecruitmentDTO } from "@/dto/JobDto";
55
import { recruitmentDTO } from "@/dto/JobDto";
66
import { createMRTColumnHelper } from "material-react-table";
77
import Table from "@/components/NewTableComponent/Table";
88
import { useEffect, useState } from "react";
99
import Loader from "@/components/Loader/loader";
10+
import toast from "react-hot-toast";
1011

1112
const hiddenColumns = [
1213
"id",
@@ -25,19 +26,47 @@ const JobPage = () => {
2526
(column: any) => !hiddenColumns.includes(column?.accessorKey),
2627
);
2728

28-
useEffect(() => {
29-
const getData = async () => {
29+
const getData = async () => {
30+
setLoading(true);
31+
try {
3032
const data = await fetchAllJobs();
3133
const newData = data.map((d: any) => ({
3234
...d,
3335
active: d.active ? "Active" : "Inactive",
3436
}));
3537
setAllJobs(newData);
38+
} catch (error) {
39+
toast.error("Failed to fetch jobs");
40+
} finally {
3641
setLoading(false);
37-
};
42+
}
43+
};
44+
45+
useEffect(() => {
3846
getData();
3947
}, []);
4048

49+
const handleDelete = async (selectedJobs: any[]) => {
50+
if (selectedJobs.length === 0) {
51+
toast.error("Please select at least one job to delete");
52+
return;
53+
}
54+
55+
const confirmMessage = `Are you sure you want to delete ${selectedJobs.length} job(s)? This will also delete associated events, salaries, and offers. This action cannot be undone.`;
56+
if (!window.confirm(confirmMessage)) {
57+
return;
58+
}
59+
60+
try {
61+
const ids = selectedJobs.map((job) => job.id);
62+
await deleteJobs(ids);
63+
toast.success(`Successfully deleted ${selectedJobs.length} job(s)`);
64+
await getData(); // Refresh the list
65+
} catch (error) {
66+
toast.error("Failed to delete jobs");
67+
}
68+
};
69+
4170
return (
4271
<div className="m-2 md:m-6 lg:m-10">
4372
<h1 className="text-center font-bold text-2xl md:text-3xl my-3 md:my-5 py-3 md:py-5">
@@ -50,7 +79,13 @@ const JobPage = () => {
5079
</div>
5180
)}
5281
{allJobs && (
53-
<Table data={allJobs} columns={visibleColumns} type={"job"} />
82+
<Table
83+
data={allJobs}
84+
columns={visibleColumns}
85+
type={"job"}
86+
buttonText="Delete Selected"
87+
buttonAction={handleDelete}
88+
/>
5489
)}
5590
</div>
5691
</div>

src/app/(routes)/admin/oncampus-offers/page.tsx

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"use client";
2-
import { fetchAllSeasons, fetchOnCampusOffers } from "@/helpers/api";
2+
import { fetchAllSeasons, fetchOnCampusOffers, deleteOnCampusOffers } from "@/helpers/api";
33
import generateColumns from "@/components/NewTableComponent/ColumnMapping";
44
import { onCampusOfferDTO } from "@/dto/onCampusOfferDTO";
55
import Table from "@/components/NewTableComponent/Table";
@@ -19,6 +19,26 @@ const OnCampusOffersPage = () => {
1919
const [allOffers, setAllOffers] = useState();
2020
const [visibleColumns, setVisibleColumns] = useState<any[]>([]);
2121

22+
const loadOffers = async () => {
23+
if (!selectedSeason) return;
24+
25+
setLoading(true);
26+
try {
27+
const data = await fetchOnCampusOffers(selectedSeason);
28+
setAllOffers(data);
29+
30+
if (seasons.find(season => season.id === selectedSeason)?.type === "INTERN") {
31+
setVisibleColumns(columns.filter((column: any) => !internHiddenColumns.includes(column?.accessorKey)));
32+
} else {
33+
setVisibleColumns(columns.filter((column: any) => !placementHiddenColumns.includes(column?.accessorKey)));
34+
}
35+
} catch (error) {
36+
toast.error("Failed to fetch on campus offers");
37+
} finally {
38+
setLoading(false);
39+
}
40+
};
41+
2242
useEffect(() => {
2343
const getData = async () => {
2444
try {
@@ -42,25 +62,30 @@ const OnCampusOffersPage = () => {
4262
}, []);
4363

4464
useEffect(() => {
45-
if (selectedSeason) {
46-
try {
47-
setLoading(true);
48-
fetchOnCampusOffers(selectedSeason).then((data) => {
49-
setAllOffers(data);
50-
});
51-
if (seasons.find(season => season.id === selectedSeason)?.type === "INTERN") {
52-
setVisibleColumns(columns.filter((column: any) => !internHiddenColumns.includes(column?.accessorKey)));
53-
} else {
54-
setVisibleColumns(columns.filter((column: any) => !placementHiddenColumns.includes(column?.accessorKey)));
55-
}
56-
} catch (error) {
57-
toast.error("Failed to fetch on campus offers");
58-
} finally {
59-
setLoading(false);
60-
}
61-
}
65+
loadOffers();
6266
}, [selectedSeason]);
6367

68+
const handleDelete = async (selectedOffers: any[]) => {
69+
if (selectedOffers.length === 0) {
70+
toast.error("Please select at least one offer to delete");
71+
return;
72+
}
73+
74+
const confirmMessage = `Are you sure you want to delete ${selectedOffers.length} on-campus offer(s)? This action cannot be undone.`;
75+
if (!window.confirm(confirmMessage)) {
76+
return;
77+
}
78+
79+
try {
80+
const ids = selectedOffers.map((offer) => offer.id);
81+
await deleteOnCampusOffers(ids);
82+
toast.success(`Successfully deleted ${selectedOffers.length} offer(s)`);
83+
await loadOffers(); // Refresh the list
84+
} catch (error) {
85+
toast.error("Failed to delete offers");
86+
}
87+
};
88+
6489
return (
6590
<div className="container mx-auto my-4 md:my-8 px-2 md:px-4">
6691
<h1 className="text-2xl md:text-3xl mb-4 md:mb-8 font-bold mx-auto text-center">
@@ -93,6 +118,8 @@ const OnCampusOffersPage = () => {
93118
data={allOffers}
94119
columns={visibleColumns}
95120
type={"on-campus-offers"}
121+
buttonText="Delete Selected"
122+
buttonAction={handleDelete}
96123
/>
97124
</div>
98125
)}

src/app/(routes)/admin/programs/page.tsx

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client";
22
import { useEffect, useState } from "react";
3-
import { fetchPrograms, postPrograms } from "@/helpers/api";
3+
import { fetchPrograms, postPrograms, deletePrograms } from "@/helpers/api";
44
import generateColumns from "@/components/NewTableComponent/ColumnMapping";
55
import Table from "@/components/NewTableComponent/Table";
66
import Loader from "@/components/Loader/loader";
@@ -126,6 +126,27 @@ const ProgramsPage = () => {
126126
setSubmitting(false);
127127
};
128128

129+
const handleDelete = async (selectedPrograms: any[]) => {
130+
if (selectedPrograms.length === 0) {
131+
toast.error("Please select at least one program to delete");
132+
return;
133+
}
134+
135+
const confirmMessage = `Are you sure you want to delete ${selectedPrograms.length} program(s)? This action cannot be undone.`;
136+
if (!window.confirm(confirmMessage)) {
137+
return;
138+
}
139+
140+
try {
141+
const ids = selectedPrograms.map((program) => program.id);
142+
await deletePrograms(ids);
143+
toast.success(`Successfully deleted ${selectedPrograms.length} program(s)`);
144+
await getPrograms(); // Refresh the list
145+
} catch (error) {
146+
toast.error("Failed to delete programs. They might have associated students.");
147+
}
148+
};
149+
129150
return (
130151
<div className="m-10">
131152
<h1 className="text-center font-bold text-3xl my-5 py-5">Programs</h1>
@@ -138,7 +159,13 @@ const ProgramsPage = () => {
138159
<Loader />
139160
</div>
140161
) : (
141-
<Table data={programs} columns={visibleColumns} type={"program"} />
162+
<Table
163+
data={programs}
164+
columns={visibleColumns}
165+
type={"program"}
166+
buttonText="Delete Selected"
167+
buttonAction={handleDelete}
168+
/>
142169
)}
143170
</div>
144171
<Dialog open={open} onOpenChange={setOpen}>

src/app/(routes)/admin/recruiters/page.tsx

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"use client";
2-
import { fetchRecruiterData } from "@/helpers/api";
2+
import { fetchRecruiterData, deleteRecruiters } from "@/helpers/api";
33
import Table from "@/components/NewTableComponent/Table";
44
import generateColumns from "@/components/NewTableComponent/ColumnMapping";
55
import { RecruiterDTO, recruiterdto } from "@/dto/RecruiterDto";
@@ -8,25 +8,48 @@ import toast from "react-hot-toast";
88

99
const hiddenColumns = ["id", "user.id", "company.id"];
1010

11-
const StudentPage = async () => {
11+
const StudentPage = () => {
1212
const columns = generateColumns(recruiterdto);
1313
const [AllRecruiters, setRecruiters] = useState<RecruiterDTO[]>([]);
14-
useEffect(() => {
15-
const fetchRecruiters = async () => {
16-
try {
17-
const data = await fetchRecruiterData();
18-
setRecruiters(data);
19-
} catch (error) {
20-
toast.error("Error fetching data:");
21-
}
22-
};
14+
15+
const fetchRecruiters = async () => {
16+
try {
17+
const data = await fetchRecruiterData();
18+
setRecruiters(data);
19+
} catch (error) {
20+
toast.error("Error fetching data");
21+
}
22+
};
2323

24+
useEffect(() => {
2425
fetchRecruiters();
2526
}, []);
27+
2628
const visibleColumns = columns.filter(
2729
(column: any) => !hiddenColumns.includes(column?.accessorKey),
2830
);
2931

32+
const handleDelete = async (selectedRecruiters: any[]) => {
33+
if (selectedRecruiters.length === 0) {
34+
toast.error("Please select at least one recruiter to delete");
35+
return;
36+
}
37+
38+
const confirmMessage = `Are you sure you want to delete ${selectedRecruiters.length} recruiter(s)? This action cannot be undone.`;
39+
if (!window.confirm(confirmMessage)) {
40+
return;
41+
}
42+
43+
try {
44+
const ids = selectedRecruiters.map((recruiter) => recruiter.id);
45+
await deleteRecruiters(ids);
46+
toast.success(`Successfully deleted ${selectedRecruiters.length} recruiter(s)`);
47+
await fetchRecruiters(); // Refresh the list
48+
} catch (error) {
49+
toast.error("Failed to delete recruiters. They might have associated jobs.");
50+
}
51+
};
52+
3053
return (
3154
<div className="m-2 md:m-6 lg:m-10">
3255
<h1 className="text-center font-bold text-2xl md:text-3xl my-3 md:my-5 py-3 md:py-5">
@@ -38,6 +61,8 @@ const StudentPage = async () => {
3861
data={AllRecruiters}
3962
columns={visibleColumns}
4063
type={"recruiter"}
64+
buttonText="Delete Selected"
65+
buttonAction={handleDelete}
4166
/>
4267
)}
4368
</div>

0 commit comments

Comments
 (0)