From 716a4af60c31178ade5f428b96c787c738aeb8b8 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 17 Jul 2025 12:55:14 +0000 Subject: [PATCH] removed version from yml, fixed env file paths in compose files --- .env | 5 +++ backend/utils/apiUtils.js | 87 ++++++++++++++++++++++++++++++++++++++ docker-compose.dev.yml | 8 ++-- docker-compose.prod.yml | 8 ++-- docker-compose.staging.yml | 8 ++-- docker-compose.yml | 2 - package.json | 4 +- src/components/SignIn.js | 2 +- 8 files changed, 106 insertions(+), 18 deletions(-) create mode 100644 .env create mode 100644 backend/utils/apiUtils.js diff --git a/.env b/.env new file mode 100644 index 0000000..559565b --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +IMG_TAG=20250716 +SERVER1_PORT=5000 +SERVER2_PORT=5001 +SERVER3_PORT=5002 +SALARY_DB=/salary_info.db \ No newline at end of file diff --git a/backend/utils/apiUtils.js b/backend/utils/apiUtils.js new file mode 100644 index 0000000..4d26c15 --- /dev/null +++ b/backend/utils/apiUtils.js @@ -0,0 +1,87 @@ +// src/utils/apiUtils.js +import axios from 'axios'; + +/* ------------------------------------------------------------------ + Single authority for “baseURL + path” so we never worry + about trailing slashes again. + ------------------------------------------------------------------*/ +const BASE = ( + import.meta.env.VITE_API_BASE || + process.env.REACT_APP_API_URL || + '' +).replace(/\/+$/, ''); // trim *all* trailing “/” + +export const api = (path = '') => + `${BASE}${path.startsWith('/') ? '' : '/'}${path}`; + +/* ------------------------------------------------------------------ + Fetch areas-by-state (static JSON in public/ or served by nginx) + ------------------------------------------------------------------*/ +export const fetchAreasByState = async (state) => { + try { + // NOTE: if Institution_data.json is in /public, nginx serves it + const res = await fetch(api('/Institution_data.json')); + if (!res.ok) throw new Error(`HTTP ${res.status}`); + // Adjust this part if your JSON structure is different + const json = await res.json(); + return json[state]?.areas || []; + } catch (err) { + console.error('Error fetching areas:', err.message); + return []; + } +}; + +/* ------------------------------------------------------------------ + Client-side Google Maps geocode + ------------------------------------------------------------------*/ +export async function clientGeocodeZip(zip) { + const apiKey = import.meta.env.VITE_GOOGLE_MAPS_API_KEY ?? + process.env.REACT_APP_GOOGLE_MAPS_API_KEY; + const url = `https://maps.googleapis.com/maps/api/geocode/json` + + `?address=${encodeURIComponent(zip)}&key=${apiKey}`; + + const resp = await axios.get(url); + const { status, results } = resp.data; + if (status === 'OK' && results.length) { + return results[0].geometry.location; // { lat, lng } + } + throw new Error('Geocoding failed.'); +} + +/* ------------------------------------------------------------------ + Haversine distance helper (miles) + ------------------------------------------------------------------*/ +export function haversineDistance(lat1, lon1, lat2, lon2) { + const R = 3959; // earth radius in miles + const toRad = (v) => (v * Math.PI) / 180; + + const dLat = toRad(lat2 - lat1); + const dLon = toRad(lon2 - lon1); + + const a = Math.sin(dLat / 2) ** 2 + + Math.cos(toRad(lat1)) * + Math.cos(toRad(lat2)) * + Math.sin(dLon / 2) ** 2; + + return 2 * R * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); +} + +/* ------------------------------------------------------------------ + Fetch schools for one or many CIP prefixes + ------------------------------------------------------------------*/ +export async function fetchSchools(cipCodes) { + try { + // 1) Ensure array-ness, then join with commas + const codes = Array.isArray(cipCodes) ? cipCodes : [cipCodes]; + const cipParam = codes.join(','); + + // 2) Hit backend + const res = await axios.get(api('/api/schools'), { + params: { cipCodes: cipParam }, + }); + return res.data; + } catch (err) { + console.error('Error fetching schools:', err.message); + return []; + } +} diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index d5fed1f..da1a950 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -1,5 +1,5 @@ services: - server1: { env_file: .env.dev } - server2: { env_file: .env.dev } - server3: { env_file: .env.dev } - nginx : { env_file: .env.dev } \ No newline at end of file + server1: { env_file: ./env/dev.env } + server2: { env_file: ./env/dev.env } + server3: { env_file: ./env/dev.env } + nginx : { env_file: ./env/dev.env } \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index d83a12e..7712cd4 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,5 +1,5 @@ services: - server1: { env_file: .env.prod } - server2: { env_file: .env.prod } - server3: { env_file: .env.prod } - nginx : { env_file: .env.prod } \ No newline at end of file + server1: { env_file: ./env/prod.env } + server2: { env_file: ./env/prod.env } + server3: { env_file: ./env/prod.env } + nginx : { env_file: ./env/prod.env } \ No newline at end of file diff --git a/docker-compose.staging.yml b/docker-compose.staging.yml index 053cc6f..c324693 100644 --- a/docker-compose.staging.yml +++ b/docker-compose.staging.yml @@ -1,5 +1,5 @@ services: - server1: { env_file: .env.staging } - server2: { env_file: .env.staging } - server3: { env_file: .env.staging } - nginx : { env_file: .env.staging } \ No newline at end of file + server1: { env_file: ./env/staging.env } + server2: { env_file: ./env/staging.env } + server3: { env_file: ./env/staging.env } + nginx : { env_file: ./env/staging.env } \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 408dfa4..005f9bb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3.9" - services: server1: image: us-central1-docker.pkg.dev/aptivaai-dev/aptiva-repo/server1:${IMG_TAG} diff --git a/package.json b/package.json index 23101a5..bf802c4 100644 --- a/package.json +++ b/package.json @@ -58,9 +58,7 @@ "start": "react-scripts start --host 0.0.0.0", "build": "react-scripts build", "test": "react-scripts test", - "eject": "react-scripts eject", - "gen:tools": "node scripts/genTools.cjs", - "postinstall": "npm run gen:tools" + "eject": "react-scripts eject" }, "eslintConfig": { "extends": [ diff --git a/src/components/SignIn.js b/src/components/SignIn.js index 1f5d2b9..3f9f9f8 100644 --- a/src/components/SignIn.js +++ b/src/components/SignIn.js @@ -46,7 +46,7 @@ function SignIn({ setIsAuthenticated, setUser }) { const resp = await fetch(`${apiUrl}/signin`, { method : 'POST', headers: { 'Content-Type': 'application/json' }, - body : JSON.stringify(formData), + body : JSON.stringify(username, password), }); const data = await resp.json(); // ← read ONCE