155 lines
5.3 KiB
JavaScript
155 lines
5.3 KiB
JavaScript
// src/components/CollegeProfileList.js
|
||
import React, { useEffect, useState } from "react";
|
||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||
import CareerSelectDropdown from "./CareerSelectDropdown.js";
|
||
import authFetch from "../utils/authFetch.js";
|
||
|
||
export default function CollegeProfileList() {
|
||
const { careerId } = useParams(); // may be undefined
|
||
const navigate = useNavigate();
|
||
const token = localStorage.getItem("token");
|
||
|
||
/* ───────── existing lists ───────── */
|
||
const [rows, setRows] = useState([]);
|
||
const [careerRows, setCareerRows] = useState([]);
|
||
|
||
/* ───────── ui state ───────── */
|
||
const [showPicker, setShowPicker] = useState(false);
|
||
const [loadingCareers, setLoadingCareers] = useState(true);
|
||
|
||
/* ───────── load college plans ───────── */
|
||
useEffect(() => {
|
||
fetch("/api/premium/college-profile/all", {
|
||
headers: { Authorization: `Bearer ${token}` }
|
||
})
|
||
.then((r) => r.json())
|
||
.then((d) => setRows(d.collegeProfiles || []));
|
||
}, [token]);
|
||
|
||
/* ───────── load career profiles for the picker ───────── */
|
||
useEffect(() => {
|
||
(async () => {
|
||
try {
|
||
const res = await authFetch("/api/premium/career-profile/all");
|
||
const data = await res.json();
|
||
setCareerRows(data.careerProfiles || []);
|
||
} catch (err) {
|
||
console.error("Career profiles load failed:", err);
|
||
} finally {
|
||
setLoadingCareers(false);
|
||
}
|
||
})();
|
||
}, []);
|
||
|
||
/* ───────── delete helper ───────── */
|
||
async function handleDelete(id) {
|
||
if (!window.confirm("Delete this college plan?")) return;
|
||
try {
|
||
await fetch(`/api/premium/college-profile/${id}`, {
|
||
method: "DELETE",
|
||
headers: { Authorization: `Bearer ${token}` }
|
||
});
|
||
setRows((r) => r.filter((row) => row.id !== id));
|
||
} catch (err) {
|
||
console.error("Delete failed:", err);
|
||
alert("Could not delete – see console.");
|
||
}
|
||
}
|
||
|
||
return (
|
||
<div className="max-w-5xl mx-auto space-y-6">
|
||
{/* ───────── header row ───────── */}
|
||
<div className="flex items-center justify-between">
|
||
<h2 className="text-2xl font-semibold">College Plans</h2>
|
||
|
||
{/* new‑plan button & inline picker */}
|
||
{!showPicker ? (
|
||
<button
|
||
onClick={() => setShowPicker(true)}
|
||
className="px-3 py-2 bg-blue-600 text-white rounded"
|
||
>
|
||
+ New College Plan
|
||
</button>
|
||
) : (
|
||
<div className="p-4 border rounded bg-gray-50 max-w-md">
|
||
<CareerSelectDropdown
|
||
existingCareerProfiles={careerRows}
|
||
selectedCareer={null}
|
||
loading={loadingCareers}
|
||
authFetch={authFetch}
|
||
onChange={(careerObj) => {
|
||
if (!careerObj?.id) return;
|
||
navigate(`/profile/college/${careerObj.id}/new`);
|
||
}}
|
||
/>
|
||
<div className="mt-2 text-right">
|
||
<button
|
||
onClick={() => setShowPicker(false)}
|
||
className="text-sm text-gray-600 underline"
|
||
>
|
||
cancel
|
||
</button>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* ───────── table of existing college plans ───────── */}
|
||
<table className="w-full border text-sm">
|
||
<thead className="bg-gray-100">
|
||
<tr>
|
||
<th className="p-2 text-left">Career</th>
|
||
<th className="p-2 text-left">School</th>
|
||
<th className="p-2 text-left">Program</th>
|
||
<th className="p-2">Created</th>
|
||
<th className="p-2"></th>
|
||
</tr>
|
||
</thead>
|
||
|
||
<tbody>
|
||
{rows.map((r) => (
|
||
<tr key={r.id} className="border-t">
|
||
<td className="p-2">{r.career_title}</td>
|
||
<td className="p-2">{r.selected_school}</td>
|
||
<td className="p-2">{r.selected_program}</td>
|
||
<td className="p-2">{r.created_at?.slice(0, 10)}</td>
|
||
<td className="p-2 space-x-2 whitespace-nowrap">
|
||
<Link
|
||
to={`/profile/college/${r.career_profile_id}/${r.id}`}
|
||
className="underline text-blue-600"
|
||
>
|
||
edit
|
||
</Link>
|
||
<button
|
||
onClick={() => handleDelete(r.id)}
|
||
className="underline text-red-600"
|
||
>
|
||
delete
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
))}
|
||
|
||
{rows.length === 0 && (
|
||
<tr>
|
||
<td colSpan={6} className="p-8 text-center text-gray-500">
|
||
No college profiles yet.
|
||
<button
|
||
className="text-blue-600 underline"
|
||
onClick={() =>
|
||
careerId
|
||
? navigate(`/profile/college/${careerId}/new`)
|
||
: setShowPicker(true)
|
||
}
|
||
>
|
||
Create one now.
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
)}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
);
|
||
}
|