import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { ClipLoader } from "react-spinners";
import { v4 as uuidv4 } from "uuid";
import LoanRepayment from "./LoanRepayment.js";
import "./PopoutPanel.css"; // You can keep or remove depending on your needs
function PopoutPanel({
isVisible,
data = {},
userState = "N/A",
loading = false,
error = null,
closePanel,
updateChatbotContext,
}) {
// Original local states
const [isCalculated, setIsCalculated] = useState(false);
const [results, setResults] = useState([]);
const [loadingCalculation, setLoadingCalculation] = useState(false);
const [persistedROI, setPersistedROI] = useState({});
const [programLengths, setProgramLengths] = useState([]);
const [sortBy, setSortBy] = useState("tuition");
const [maxTuition, setMaxTuition] = useState(50000);
const [maxDistance, setMaxDistance] = useState(200);
const token = localStorage.getItem("token");
const navigate = useNavigate();
// Destructure your data
const {
jobDescription = null,
tasks = null,
title = "Career Details",
economicProjections = {},
salaryData = [],
schools = [],
} = data || {};
// Clear results if sorting or filters change
useEffect(() => {
setResults([]);
setIsCalculated(false);
}, [sortBy, maxTuition, maxDistance]);
// Derive program lengths from school CREDDESC
useEffect(() => {
setProgramLengths(
schools.map((school) => getProgramLength(school["CREDDESC"]))
);
}, [schools]);
// Update chatbot context if data is present
useEffect(() => {
if (data && Object.keys(data).length > 0) {
updateChatbotContext({
careerDetails: data,
schools,
salaryData,
economicProjections,
results,
persistedROI,
});
}
}, [
data,
schools,
salaryData,
economicProjections,
results,
persistedROI,
updateChatbotContext,
]);
// If panel isn't visible, don't render
if (!isVisible) return null;
// If the panel or the loan calc is loading, show a spinner
if (loading || loadingCalculation) {
return (
Loading Career Details...
);
}
// Original helper
function getProgramLength(degreeType) {
if (degreeType?.includes("Associate")) return 2;
if (degreeType?.includes("Bachelor")) return 4;
if (degreeType?.includes("Master")) return 6;
if (degreeType?.includes("Doctoral") || degreeType?.includes("First Professional"))
return 8;
if (degreeType?.includes("Certificate")) return 1;
return 4;
}
// Original close logic
function handleClosePanel() {
setResults([]);
setIsCalculated(false);
closePanel();
}
async function handlePlanMyPath() {
if (!token) {
alert("You need to be logged in to create a career path.");
return;
}
try {
// 1) Fetch existing career profiles (a.k.a. "careerPaths")
const allPathsResponse = await fetch(
`${process.env.REACT_APP_API_URL}/premium/career-profile/all`,
{
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
}
);
if (!allPathsResponse.ok) {
throw new Error(`HTTP error ${allPathsResponse.status}`);
}
// The server returns { careerPaths: [...] }
const { careerPaths } = await allPathsResponse.json();
// 2) Check if there's already a career path with the same name
const match = careerPaths.find((cp) => cp.career_name === data.title);
if (match) {
// If a path already exists for this career, confirm with the user
const decision = window.confirm(
`A career path (scenario) for "${data.title}" already exists.\n\n` +
`Click OK to RELOAD the existing path.\nClick Cancel to CREATE a new one.`
);
if (decision) {
// Reload existing path → go to Paywall
navigate("/paywall", {
state: {
selectedCareer: {
career_path_id: match.id, // 'id' is the primary key from the DB
career_name: data.title,
},
},
});
return;
}
}
// 3) Otherwise, create a new career profile using POST /premium/career-profile
const newResponse = await fetch(
`${process.env.REACT_APP_API_URL}/premium/career-profile`,
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
// The server expects at least career_name
career_name: data.title,
// Optionally pass scenario_title, start_date, etc.
}),
}
);
if (!newResponse.ok) {
throw new Error("Failed to create new career path.");
}
// The server returns something like { message: 'Career profile upserted.', career_path_id: 'xxx-xxx' }
const result = await newResponse.json();
const newlyCreatedId = result?.career_path_id;
// 4) Navigate to /paywall, passing the newly created career_path_id
navigate("/paywall", {
state: {
selectedCareer: {
career_path_id: newlyCreatedId,
career_name: data.title,
},
},
});
} catch (error) {
console.error("Error in Plan My Path:", error);
}
}
// Filter & sort schools
const filteredAndSortedSchools = [...schools]
.filter((school) => {
const inStateCost = parseFloat(school["In_state cost"]) || 0;
const distance = parseFloat((school["distance"] || "0").replace(" mi", ""));
return inStateCost <= maxTuition && distance <= maxDistance;
})
.sort((a, b) => {
if (sortBy === "tuition") return a["In_state cost"] - b["In_state cost"];
if (sortBy === "distance") {
const distA = parseFloat((a["distance"] || "0").replace(" mi", ""));
const distB = parseFloat((b["distance"] || "0").replace(" mi", ""));
return distA - distB;
}
return 0;
});
return (