dev1/src/components/EconomicProjections.js

124 lines
4.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect, useState } from 'react';
/**
* Props:
* - socCode: e.g. "17-1011"
* - stateName: e.g. "Kentucky" (optional; if not provided, defaults to "United States")
*/
function EconomicProjections({ socCode, stateName }) {
const [data, setData] = useState(null); // { state: {...}, national: {...} }
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
if (!socCode) return;
const fetchData = async () => {
setLoading(true);
setError(null);
try {
const encodedState = stateName ? encodeURIComponent(stateName) : '';
const url = `/api/projections/${socCode}?state=${encodedState}`;
const res = await fetch(url);
if (!res.ok) {
throw new Error(`Server responded with status ${res.status}`);
}
const json = await res.json();
setData(json);
} catch (err) {
console.error("Error fetching economic projections:", err);
setError("Failed to load economic projections.");
} finally {
setLoading(false);
}
};
fetchData();
}, [socCode, stateName]);
if (loading) return <div>Loading Projections...</div>;
if (error) return <div style={{ color: 'red' }}>{error}</div>;
if (!data) return null;
const { state, national } = data;
/**
* Safely parse the value to a number. If parsing fails, we just return the original string.
* Then we format with toLocaleString() if numeric.
*/
const formatNumber = (val) => {
if (val == null || val === '') return 'N/A';
// Coerce string -> number
const parsed = Number(val);
if (!isNaN(parsed)) {
// If its actually numeric
return parsed.toLocaleString();
} else {
// If its truly not numeric, return the raw value
return val;
}
};
return (
<div className="border p-2 my-3">
<h3 className="text-lg font-bold mb-3">
Economic Projections: {state?.occupationName ?? 'N/A'}
</h3>
<table className="w-full border text-sm">
<thead>
<tr className="bg-gray-100">
<th className="p-2 text-left">Metric</th>
<th className="p-2 text-left">{state?.area || 'State'}</th>
<th className="p-2 text-left">{national?.area || 'U.S.'}</th>
</tr>
</thead>
<tbody>
<tr>
<td className="p-2">Base Year</td>
<td className="p-2">{state?.baseYear ?? 'N/A'}</td>
<td className="p-2">{national?.baseYear ?? 'N/A'}</td>
</tr>
<tr>
<td className="p-2">Base Employment</td>
<td className="p-2">{formatNumber(state?.base)}</td>
<td className="p-2">{formatNumber(national?.base)}</td>
</tr>
<tr>
<td className="p-2">Projected Year</td>
<td className="p-2">{state?.projectedYear ?? 'N/A'}</td>
<td className="p-2">{national?.projectedYear ?? 'N/A'}</td>
</tr>
<tr>
<td className="p-2">Projected Employment</td>
<td className="p-2">{formatNumber(state?.projection)}</td>
<td className="p-2">{formatNumber(national?.projection)}</td>
</tr>
<tr>
<td className="p-2">Employment Change</td>
<td className="p-2">{formatNumber(state?.change)}</td>
<td className="p-2">{formatNumber(national?.change)}</td>
</tr>
<tr>
<td className="p-2">Percent Change</td>
<td className="p-2">
{state?.percentChange != null ? `${state.percentChange}%` : 'N/A'}
</td>
<td className="p-2">
{national?.percentChange != null ? `${national.percentChange}%` : 'N/A'}
</td>
</tr>
<tr>
<td className="p-2">Annual Openings</td>
<td className="p-2">{formatNumber(state?.annualOpenings)}</td>
<td className="p-2">{formatNumber(national?.annualOpenings)}</td>
</tr>
</tbody>
</table>
</div>
);
}
export default EconomicProjections;