Added National Salary data
This commit is contained in:
parent
ca7b230b25
commit
a16fe7f19a
@ -22,12 +22,6 @@ const envPath = path.resolve(rootPath, `.env.${env}`); // Use root directory for
|
|||||||
// Load environment variables as soon as the server starts
|
// Load environment variables as soon as the server starts
|
||||||
dotenv.config({ path: envPath }); // Ensure this is called at the very top to load all environment variables
|
dotenv.config({ path: envPath }); // Ensure this is called at the very top to load all environment variables
|
||||||
|
|
||||||
// Logging environment variables for debugging
|
|
||||||
console.log(`Loaded environment variables from: ${envPath}`);
|
|
||||||
console.log('ONET_USERNAME:', process.env.ONET_USERNAME);
|
|
||||||
console.log('ONET_PASSWORD:', process.env.ONET_PASSWORD);
|
|
||||||
console.log('Google Maps API Key:', process.env.GOOGLE_MAPS_API_KEY);
|
|
||||||
|
|
||||||
|
|
||||||
const allowedOrigins = ['http://localhost:3000', 'http://34.16.120.118:3000', 'https://dev1.aptivaai.com'];
|
const allowedOrigins = ['http://localhost:3000', 'http://34.16.120.118:3000', 'https://dev1.aptivaai.com'];
|
||||||
const mappingFilePath = '/home/jcoakley/aptiva-dev1-app/public/CIP_to_ONET_SOC.xlsx';
|
const mappingFilePath = '/home/jcoakley/aptiva-dev1-app/public/CIP_to_ONET_SOC.xlsx';
|
||||||
@ -124,7 +118,6 @@ app.use(express.json());
|
|||||||
app.use(express.static(path.join(__dirname, 'public')));
|
app.use(express.static(path.join(__dirname, 'public')));
|
||||||
|
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
console.log(`Path: ${req.path}, Method: ${req.method}, Body:`, req.body);
|
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -153,7 +146,6 @@ app.get('/api/onet/questions', async (req, res) => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
console.log('O*Net Response:', response.data);
|
|
||||||
|
|
||||||
// Add questions to the result set
|
// Add questions to the result set
|
||||||
if (response.data.question && Array.isArray(response.data.question)) {
|
if (response.data.question && Array.isArray(response.data.question)) {
|
||||||
@ -185,11 +177,10 @@ const geocodeZipCode = async (zipCode) => {
|
|||||||
if (!apiKey) {
|
if (!apiKey) {
|
||||||
console.error('Google Maps API Key is missing.');
|
console.error('Google Maps API Key is missing.');
|
||||||
} else {
|
} else {
|
||||||
console.log('Google Maps API Key loaded:', apiKey);
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const geocodeUrl = `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(zipCode)}&components=country:US&key=${apiKey}`;
|
const geocodeUrl = `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(zipCode)}&components=country:US&key=${apiKey}`;
|
||||||
console.log('Constructed Geocode URL:', geocodeUrl); // Log the geocoding URL for debugging
|
|
||||||
|
|
||||||
const response = await axios.get(geocodeUrl);
|
const response = await axios.get(geocodeUrl);
|
||||||
|
|
||||||
@ -225,12 +216,9 @@ app.post('/api/maps/distance', async (req, res) => {
|
|||||||
|
|
||||||
const origins = `${userLocation.lat},${userLocation.lng}`; // User's location as lat/lng
|
const origins = `${userLocation.lat},${userLocation.lng}`; // User's location as lat/lng
|
||||||
|
|
||||||
console.log('Request Payload:', { userZipcode, destinations }); // Log the parameters
|
|
||||||
|
|
||||||
// Call the Distance Matrix API using the geocoded user location and school address
|
// Call the Distance Matrix API using the geocoded user location and school address
|
||||||
const distanceUrl = `https://maps.googleapis.com/maps/api/distancematrix/json?origins=${origins}&destinations=${encodeURIComponent(destinations)}&units=imperial&key=${googleMapsApiKey}`;
|
const distanceUrl = `https://maps.googleapis.com/maps/api/distancematrix/json?origins=${origins}&destinations=${encodeURIComponent(destinations)}&units=imperial&key=${googleMapsApiKey}`;
|
||||||
const distanceResponse = await axios.get(distanceUrl);
|
const distanceResponse = await axios.get(distanceUrl);
|
||||||
console.log('Distance API Request URL:', distanceUrl); // Log the final request URL
|
|
||||||
|
|
||||||
if (distanceResponse.data.status !== 'OK') {
|
if (distanceResponse.data.status !== 'OK') {
|
||||||
return res.status(500).json({ error: 'Error fetching distance from Google Maps API' });
|
return res.status(500).json({ error: 'Error fetching distance from Google Maps API' });
|
||||||
@ -561,38 +549,57 @@ app.get('/api/salary', async (req, res) => {
|
|||||||
|
|
||||||
console.log('Received /api/salary request:', { socCode, area });
|
console.log('Received /api/salary request:', { socCode, area });
|
||||||
|
|
||||||
if (!socCode || !area) {
|
if (!socCode) {
|
||||||
console.error('Missing required parameters:', { socCode, area });
|
console.error('Missing required parameters:', { socCode });
|
||||||
return res.status(400).json({ error: 'SOC Code and Area are required' });
|
return res.status(400).json({ error: 'SOC Code is required' });
|
||||||
}
|
}
|
||||||
|
|
||||||
const query = `
|
// Query for regional salary data
|
||||||
SELECT A_PCT10, A_PCT25, A_MEDIAN, A_PCT75, A_PCT90
|
const regionalQuery = `
|
||||||
|
SELECT A_PCT10 AS regional_PCT10, A_PCT25 AS regional_PCT25,
|
||||||
|
A_MEDIAN AS regional_MEDIAN, A_PCT75 AS regional_PCT75,
|
||||||
|
A_PCT90 AS regional_PCT90
|
||||||
FROM salary_data
|
FROM salary_data
|
||||||
WHERE OCC_CODE = ? AND AREA_TITLE = ?
|
WHERE OCC_CODE = ? AND AREA_TITLE = ?
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
// Query for national salary data (updated AREA_TITLE = 'U.S.')
|
||||||
|
const nationalQuery = `
|
||||||
|
SELECT A_PCT10 AS national_PCT10, A_PCT25 AS national_PCT25,
|
||||||
|
A_MEDIAN AS national_MEDIAN, A_PCT75 AS national_PCT75,
|
||||||
|
A_PCT90 AS national_PCT90
|
||||||
|
FROM salary_data
|
||||||
|
WHERE OCC_CODE = ? AND AREA_TITLE = 'U.S.'
|
||||||
|
`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (process.env.DEBUG === 'true') {
|
let regionalRow = null;
|
||||||
console.log('Executing query:', query, 'with params:', [socCode, area]);
|
let nationalRow = null;
|
||||||
|
|
||||||
|
if (area) {
|
||||||
|
regionalRow = await db.get(regionalQuery, [socCode, area]);
|
||||||
}
|
}
|
||||||
|
nationalRow = await db.get(nationalQuery, [socCode]);
|
||||||
|
|
||||||
// Use async/await for better error handling
|
if (!regionalRow && !nationalRow) {
|
||||||
const row = await db.get(query, [socCode, area]);
|
|
||||||
|
|
||||||
if (!row) {
|
|
||||||
console.log('No salary data found for:', { socCode, area });
|
console.log('No salary data found for:', { socCode, area });
|
||||||
return res.status(404).json({ error: 'No salary data found for the given SOC Code and Area' });
|
return res.status(404).json({ error: 'No salary data found for the given SOC Code' });
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Salary data retrieved:', row);
|
const salaryData = {
|
||||||
res.json(row);
|
regional: regionalRow || {},
|
||||||
|
national: nationalRow || {}
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('Salary data retrieved:', salaryData);
|
||||||
|
res.json(salaryData);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error executing query:', error.message);
|
console.error('Error executing query:', error.message);
|
||||||
res.status(500).json({ error: 'Failed to fetch salary data' });
|
res.status(500).json({ error: 'Failed to fetch salary data' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Route to fetch job zones and check for missing salary data
|
// Route to fetch job zones and check for missing salary data
|
||||||
app.post('/api/job-zones', async (req, res) => {
|
app.post('/api/job-zones', async (req, res) => {
|
||||||
const { socCodes } = req.body;
|
const { socCodes } = req.body;
|
||||||
|
@ -234,13 +234,15 @@ async (career) => {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Process Salary Data
|
// Process Salary Data
|
||||||
const salaryDataPoints = salaryResponse.data && Object.keys(salaryResponse.data).length > 0 ? [
|
const salaryDataPoints = salaryResponse.data && Object.keys(salaryResponse.data).length > 0
|
||||||
{ percentile: '10th Percentile', value: salaryResponse.data.A_PCT10 || 0 },
|
? [
|
||||||
{ percentile: '25th Percentile', value: salaryResponse.data.A_PCT25 || 0 },
|
{ percentile: "10th Percentile", regionalSalary: parseInt(salaryResponse.data.regional?.regional_PCT10, 10) || 0, nationalSalary: parseInt(salaryResponse.data.national?.national_PCT10, 10) || 0 },
|
||||||
{ percentile: 'Median', value: salaryResponse.data.A_MEDIAN || 0 },
|
{ percentile: "25th Percentile", regionalSalary: parseInt(salaryResponse.data.regional?.regional_PCT25, 10) || 0, nationalSalary: parseInt(salaryResponse.data.national?.national_PCT25, 10) || 0 },
|
||||||
{ percentile: '75th Percentile', value: salaryResponse.data.A_PCT75 || 0 },
|
{ percentile: "Median", regionalSalary: parseInt(salaryResponse.data.regional?.regional_MEDIAN, 10) || 0, nationalSalary: parseInt(salaryResponse.data.national?.national_MEDIAN, 10) || 0 },
|
||||||
{ percentile: '90th Percentile', value: salaryResponse.data.A_PCT90 || 0 },
|
{ percentile: "75th Percentile", regionalSalary: parseInt(salaryResponse.data.regional?.regional_PCT75, 10) || 0, nationalSalary: parseInt(salaryResponse.data.national?.national_PCT75, 10) || 0 },
|
||||||
] : [];
|
{ percentile: "90th Percentile", regionalSalary: parseInt(salaryResponse.data.regional?.regional_PCT90, 10) || 0, nationalSalary: parseInt(salaryResponse.data.national?.national_PCT90, 10) || 0 },
|
||||||
|
]
|
||||||
|
: [];
|
||||||
|
|
||||||
setCareerDetails({
|
setCareerDetails({
|
||||||
...career,
|
...career,
|
||||||
|
@ -105,14 +105,16 @@ function PopoutPanel({
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Percentile</th>
|
<th>Percentile</th>
|
||||||
<th>Salary</th>
|
<th>Regional Salary</th>
|
||||||
|
<th>US Salary</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{salaryData.map((point, index) => (
|
{salaryData.map((point, index) => (
|
||||||
<tr key={index}>
|
<tr key={index}>
|
||||||
<td>{point.percentile}</td>
|
<td>{point.percentile}</td>
|
||||||
<td>{point.value > 0 ? `$${parseInt(point.value, 10).toLocaleString()}` : 'N/A'}</td>
|
<td>{point.regionalSalary > 0 ? `$${parseInt(point.regionalSalary, 10).toLocaleString()}` : 'N/A'}</td>
|
||||||
|
<td>{point.nationalSalary > 0 ? `$${parseInt(point.nationalSalary, 10).toLocaleString()}` : 'N/A'}</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
Loading…
Reference in New Issue
Block a user