From 12e65d612afb649761dac35ddad41bddd4b06060 Mon Sep 17 00:00:00 2001 From: hallj Date: Sun, 2 Nov 2025 21:12:24 -0500 Subject: [PATCH 1/5] frontend --- Waypoint_Flask_Project/app.py | 24 ++++ Waypoint_Flask_Project/requirements.txt | 1 + Waypoint_Flask_Project/static/reverse.png | Bin 0 -> 11055 bytes Waypoint_Flask_Project/static/script.js | 54 +++++++ Waypoint_Flask_Project/static/styles.css | 149 ++++++++++++++++++++ Waypoint_Flask_Project/templates/index.html | 42 ++++++ 6 files changed, 270 insertions(+) create mode 100644 Waypoint_Flask_Project/app.py create mode 100644 Waypoint_Flask_Project/requirements.txt create mode 100644 Waypoint_Flask_Project/static/reverse.png create mode 100644 Waypoint_Flask_Project/static/script.js create mode 100644 Waypoint_Flask_Project/static/styles.css create mode 100644 Waypoint_Flask_Project/templates/index.html diff --git a/Waypoint_Flask_Project/app.py b/Waypoint_Flask_Project/app.py new file mode 100644 index 0000000..8586bfe --- /dev/null +++ b/Waypoint_Flask_Project/app.py @@ -0,0 +1,24 @@ +from flask import Flask, render_template, request, jsonify +import random + +app = Flask(__name__) + +@app.route('/') +def index(): + return render_template('index.html') + +@app.route('/process', methods=['POST']) +def process(): + data = request.get_json() + start = data["start"] + end = data["end"] + + # find dest using djikstra or bfs + + message = f"Fastest route calculated from {start} to {end}" + return jsonify({ + "message": message + }) + +if __name__ == '__main__': + app.run(debug=True) diff --git a/Waypoint_Flask_Project/requirements.txt b/Waypoint_Flask_Project/requirements.txt new file mode 100644 index 0000000..8ab6294 --- /dev/null +++ b/Waypoint_Flask_Project/requirements.txt @@ -0,0 +1 @@ +flask \ No newline at end of file diff --git a/Waypoint_Flask_Project/static/reverse.png b/Waypoint_Flask_Project/static/reverse.png new file mode 100644 index 0000000000000000000000000000000000000000..7ca4df3d17d9869681d33097d51acdd2373ac205 GIT binary patch literal 11055 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 literal 0 HcmV?d00001 diff --git a/Waypoint_Flask_Project/static/script.js b/Waypoint_Flask_Project/static/script.js new file mode 100644 index 0000000..9594b69 --- /dev/null +++ b/Waypoint_Flask_Project/static/script.js @@ -0,0 +1,54 @@ +const startInput = document.getElementById("startInput"); +const endInput = document.getElementById("endInput"); +const reverseBtn = document.getElementById("reverseBtn"); +const routeBtn = document.getElementById("routeBtn"); +const output = document.getElementById("output"); + +reverseBtn.addEventListener("click", () => { + const temp = startInput.value; + startInput.value = endInput.value; + endInput.value = temp; +}); + +//Placeholder bhvr already handled by browser and CSS opacity +//Ensure placeholder reappears if text removed + +[startInput, endInput].forEach(input => { + input.addEventListener("focus", () => { + input.classList.add('has-focus'); + }); + + input.addEventListener("blur", () => { + input.classList.remove('has-focus'); + }); +}); + +routeBtn.addEventListener("click", async () => { + const start = startInput.value.trim(); + const end = endInput.value.trim(); + + if (!start || !end) { + output.textContent = "Please enter a start location and an end destination."; + return; + } + + output.textContent = "Loading route..."; + + try { + const res = await fetch("/process", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ start, end }) + }); + + if (!res.ok) throw new Error('Server error: ${res.status}'); + + const json = await res.json(); + output.textContent = json.message || "Route calculated."; + } + catch (err) { + output.textContent = "Error: ${err.message}"; + console.error(err); + } +}); + diff --git a/Waypoint_Flask_Project/static/styles.css b/Waypoint_Flask_Project/static/styles.css new file mode 100644 index 0000000..f2bb5c5 --- /dev/null +++ b/Waypoint_Flask_Project/static/styles.css @@ -0,0 +1,149 @@ +:root { + --header-blue: #1800ad; + --bg-purple: #5944dd; + --card-white: #ffffff; + --box-grey: #bbb8b8; + --btn-blue: #2e15c6; +} + +* { + box-sizing: border-box; +} + +html, +body { + height: 100% +} + +body { + margin: 0; + font-family: "Segoe UI", sans-serif; + background: var(--bg-purple); + color: #0b0b0b; +} + +.header { + width: 100%; + background: var(--header-blue); + box-shadow: 0 2px 0 rgba(0, 0, 0, .15); + position: relative; +} + +.header-inner { + max-width: 1400px; + margin: 0 auto; + display: flex; + align-items: center; + justify-content: space-between; + padding: 18px 28px; +} + +.site-title { + margin: 0; + color: white; + font-weight: 800; + letter-spacing: 1px; + font-size: 28px; +} + +.page { + display: flex; + justify-content: center; + align-items: flex-start; + padding: 70px 20px; + min-height: calc(100vh-70px); +} + +.card { + background: var(--card-white); + width: 560px; + max-width: calc(100%-40px); + padding: 48px 40px; + border-radius: 28px; + text-align: center; + box-shadow: 0 10px 35px rgba(0, 0, 0, 0.25); +} + +.input-label { + display: block; + font-size: 20px; + margin-bottom: 10px; + text-align: left; + color: #1f1f1f; +} + +.input-box { + display: block; + width: 70%; + margin: 0 auto 28px auto; + padding: 14px 18px; + border-radius: 22px; + border: none; + background: var(--box-grey); + text-align: center; + font-size: 16px; + outline: none; + transition: box-shadow .12s ease; +} + +input::placeholder { + opacity: .45; + color: #2a2a2a; + transition: opacity .12s ease; +} + +input:focus::placeholder { + opacity: 0; +} + +input-box:focus { + box-shadow: 0 0 0 4px rgba(46, 21, 198, .08); +} + +.reverse-btn { + display: inline-block; + margin: 8px auto 28px auto; + background: transparent; + border: none; + cursor: pointer; + padding: 6px; +} + +.reverse-icon { + width: 36px; + height: 36px; + display: block; +} + +.submit-btn { + display: block; + width: 86%; + margin: 12px auto 0 auto; + padding: 16px 18px; + background: var(--btn-blue); + color: white; + border: none; + font-size: 18px; + font-weight: 600; + border-radius: 28px; + cursor: pointer; + box-shadow: 0 8px 18px rgba(46, 21, 198, .18); + transition: transform .12s ease, opacity .12s ease; +} + +.submit-btn:hover { + transform: translateY(-2px); + opacity: .98; +} + +.submit-btn:active { + transform: translateY(0); +} + +.output-box { + margin-top: 18px; + font-size: 15px; + min-height: 1.2em; + color: #111; + text-align: center; +} \ No newline at end of file diff --git a/Waypoint_Flask_Project/templates/index.html b/Waypoint_Flask_Project/templates/index.html new file mode 100644 index 0000000..d9911ba --- /dev/null +++ b/Waypoint_Flask_Project/templates/index.html @@ -0,0 +1,42 @@ + + + + + + + Waypoint_WIP + + + + + +
+
+

WAYPOINT

+
+
+
+ +
+
+ + + + + + + + + + + +
+
+
+ + + + + \ No newline at end of file From bbfe8b5c224be349dfe96e1caf6785612725b209 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 3 Nov 2025 02:12:56 +0000 Subject: [PATCH 2/5] style: apply formatting --- Waypoint_Flask_Project/app.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Waypoint_Flask_Project/app.py b/Waypoint_Flask_Project/app.py index 8586bfe..fc13b95 100644 --- a/Waypoint_Flask_Project/app.py +++ b/Waypoint_Flask_Project/app.py @@ -3,11 +3,13 @@ app = Flask(__name__) -@app.route('/') + +@app.route("/") def index(): - return render_template('index.html') + return render_template("index.html") + -@app.route('/process', methods=['POST']) +@app.route("/process", methods=["POST"]) def process(): data = request.get_json() start = data["start"] @@ -16,9 +18,8 @@ def process(): # find dest using djikstra or bfs message = f"Fastest route calculated from {start} to {end}" - return jsonify({ - "message": message - }) + return jsonify({"message": message}) + -if __name__ == '__main__': +if __name__ == "__main__": app.run(debug=True) From 1409cd7ee77629cb91844576da17fd4e369eea29 Mon Sep 17 00:00:00 2001 From: Oliver Deng Date: Sun, 2 Nov 2025 22:32:49 -0500 Subject: [PATCH 3/5] feat: integrate frontend BREAKING CHANGE: --- Waypoint_Flask_Project/app.py | 25 ---- Waypoint_Flask_Project/requirements.txt | 1 - Waypoint_Flask_Project/static/script.js | 54 ------- Waypoint_Flask_Project/templates/index.html | 42 ------ pyproject.toml | 3 + uv.lock | 138 ++++++++++++++++++ web/app.py | 54 +++++++ web/config.py | 2 + .../static/reverse.png | Bin web/static/script.js | 58 ++++++++ .../static/styles.css | 0 web/templates/index.html | 57 ++++++++ 12 files changed, 312 insertions(+), 122 deletions(-) delete mode 100644 Waypoint_Flask_Project/app.py delete mode 100644 Waypoint_Flask_Project/requirements.txt delete mode 100644 Waypoint_Flask_Project/static/script.js delete mode 100644 Waypoint_Flask_Project/templates/index.html create mode 100644 web/app.py create mode 100644 web/config.py rename {Waypoint_Flask_Project => web}/static/reverse.png (100%) create mode 100644 web/static/script.js rename {Waypoint_Flask_Project => web}/static/styles.css (100%) create mode 100644 web/templates/index.html diff --git a/Waypoint_Flask_Project/app.py b/Waypoint_Flask_Project/app.py deleted file mode 100644 index fc13b95..0000000 --- a/Waypoint_Flask_Project/app.py +++ /dev/null @@ -1,25 +0,0 @@ -from flask import Flask, render_template, request, jsonify -import random - -app = Flask(__name__) - - -@app.route("/") -def index(): - return render_template("index.html") - - -@app.route("/process", methods=["POST"]) -def process(): - data = request.get_json() - start = data["start"] - end = data["end"] - - # find dest using djikstra or bfs - - message = f"Fastest route calculated from {start} to {end}" - return jsonify({"message": message}) - - -if __name__ == "__main__": - app.run(debug=True) diff --git a/Waypoint_Flask_Project/requirements.txt b/Waypoint_Flask_Project/requirements.txt deleted file mode 100644 index 8ab6294..0000000 --- a/Waypoint_Flask_Project/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -flask \ No newline at end of file diff --git a/Waypoint_Flask_Project/static/script.js b/Waypoint_Flask_Project/static/script.js deleted file mode 100644 index 9594b69..0000000 --- a/Waypoint_Flask_Project/static/script.js +++ /dev/null @@ -1,54 +0,0 @@ -const startInput = document.getElementById("startInput"); -const endInput = document.getElementById("endInput"); -const reverseBtn = document.getElementById("reverseBtn"); -const routeBtn = document.getElementById("routeBtn"); -const output = document.getElementById("output"); - -reverseBtn.addEventListener("click", () => { - const temp = startInput.value; - startInput.value = endInput.value; - endInput.value = temp; -}); - -//Placeholder bhvr already handled by browser and CSS opacity -//Ensure placeholder reappears if text removed - -[startInput, endInput].forEach(input => { - input.addEventListener("focus", () => { - input.classList.add('has-focus'); - }); - - input.addEventListener("blur", () => { - input.classList.remove('has-focus'); - }); -}); - -routeBtn.addEventListener("click", async () => { - const start = startInput.value.trim(); - const end = endInput.value.trim(); - - if (!start || !end) { - output.textContent = "Please enter a start location and an end destination."; - return; - } - - output.textContent = "Loading route..."; - - try { - const res = await fetch("/process", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ start, end }) - }); - - if (!res.ok) throw new Error('Server error: ${res.status}'); - - const json = await res.json(); - output.textContent = json.message || "Route calculated."; - } - catch (err) { - output.textContent = "Error: ${err.message}"; - console.error(err); - } -}); - diff --git a/Waypoint_Flask_Project/templates/index.html b/Waypoint_Flask_Project/templates/index.html deleted file mode 100644 index d9911ba..0000000 --- a/Waypoint_Flask_Project/templates/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - Waypoint_WIP - - - - - -
-
-

WAYPOINT

-
-
-
- -
-
- - - - - - - - - - - -
-
-
- - - - - \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 8ee2391..c10dbba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,6 +4,9 @@ version = "0.1.0" description = "Finding the shortest flight combination between two airports." readme = "README.md" requires-python = ">=3.12" +dependencies = [ + "flask>=3.1.2", +] [dependency-groups] dev = [ diff --git a/uv.lock b/uv.lock index 744f224..470180c 100644 --- a/uv.lock +++ b/uv.lock @@ -2,6 +2,27 @@ version = 1 revision = 2 requires-python = ">=3.12" +[[package]] +name = "blinker" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/21/28/9b3f50ce0e048515135495f198351908d99540d69bfdc8c1d15b73dc55ce/blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf", size = 22460, upload-time = "2024-11-08T17:25:47.436Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc", size = 8458, upload-time = "2024-11-08T17:25:46.184Z" }, +] + +[[package]] +name = "click" +version = "8.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, +] + [[package]] name = "colorama" version = "0.4.6" @@ -11,6 +32,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "flask" +version = "3.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "blinker" }, + { name = "click" }, + { name = "itsdangerous" }, + { name = "jinja2" }, + { name = "markupsafe" }, + { name = "werkzeug" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/dc/6d/cfe3c0fcc5e477df242b98bfe186a4c34357b4847e87ecaef04507332dab/flask-3.1.2.tar.gz", hash = "sha256:bf656c15c80190ed628ad08cdfd3aaa35beb087855e2f494910aa3774cc4fd87", size = 720160, upload-time = "2025-08-19T21:03:21.205Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/f9/7f9263c5695f4bd0023734af91bedb2ff8209e8de6ead162f35d8dc762fd/flask-3.1.2-py3-none-any.whl", hash = "sha256:ca1d8112ec8a6158cc29ea4858963350011b5c846a414cdb7a954aa9e967d03c", size = 103308, upload-time = "2025-08-19T21:03:19.499Z" }, +] + [[package]] name = "iniconfig" version = "2.1.0" @@ -20,6 +58,90 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] +[[package]] +name = "itsdangerous" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + [[package]] name = "packaging" version = "25.0" @@ -67,6 +189,9 @@ wheels = [ name = "waypoint" version = "0.1.0" source = { editable = "." } +dependencies = [ + { name = "flask" }, +] [package.dev-dependencies] dev = [ @@ -74,6 +199,19 @@ dev = [ ] [package.metadata] +requires-dist = [{ name = "flask", specifier = ">=3.1.2" }] [package.metadata.requires-dev] dev = [{ name = "pytest", specifier = ">=8.4.2" }] + +[[package]] +name = "werkzeug" +version = "3.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9f/69/83029f1f6300c5fb2471d621ab06f6ec6b3324685a2ce0f9777fd4a8b71e/werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746", size = 806925, upload-time = "2024-11-08T15:52:18.093Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e", size = 224498, upload-time = "2024-11-08T15:52:16.132Z" }, +] diff --git a/web/app.py b/web/app.py new file mode 100644 index 0000000..78ec8b8 --- /dev/null +++ b/web/app.py @@ -0,0 +1,54 @@ +from typing import cast, TypedDict + +from flask import Flask, render_template, request, jsonify + +from waypoint.preprocessing import file_to_graph, file_to_airports +from waypoint.algorithms import djikstra +from waypoint.path import Path + +app = Flask(__name__) + +_ = app.config.from_pyfile("config.py") + +data_path = cast(str, app.config["DATA_PATH"]) +graph: dict[int, dict[int, float]] = file_to_graph(data_path) + +airports_path = cast(str, app.config["AIRPORTS_PATH"]) +airports: dict[int, str] = file_to_airports(airports_path) + + +class RequestData(TypedDict): + start: int + end: int + + +@app.route("/") +def index(): + return render_template("index.html") + + +@app.route("/process", methods=["POST"]) +def process(): + data: RequestData = cast(RequestData, request.get_json()) + start = int(data["start"]) + end = int(data["end"]) + + path = djikstra(graph, start, end) + + if path == Path.empty(): + return jsonify({"message": "No path found."}) + + return jsonify( + { + "flights": ( + [airports[airport_id] for airport_id in path.flights] + if path.flights is not None + else [] + ), + "time": path.time, + } + ) + + +if __name__ == "__main__": + app.run(debug=True) diff --git a/web/config.py b/web/config.py new file mode 100644 index 0000000..7f1f0cb --- /dev/null +++ b/web/config.py @@ -0,0 +1,2 @@ +DATA_PATH = "../data/data.csv" +AIRPORTS_PATH = "../data/airports.csv" diff --git a/Waypoint_Flask_Project/static/reverse.png b/web/static/reverse.png similarity index 100% rename from Waypoint_Flask_Project/static/reverse.png rename to web/static/reverse.png diff --git a/web/static/script.js b/web/static/script.js new file mode 100644 index 0000000..96ce10d --- /dev/null +++ b/web/static/script.js @@ -0,0 +1,58 @@ +const startInput = document.getElementById("startInput"); +const endInput = document.getElementById("endInput"); +const reverseBtn = document.getElementById("reverseBtn"); +const routeBtn = document.getElementById("routeBtn"); +const output = document.getElementById("output"); + +reverseBtn.addEventListener("click", () => { + const temp = startInput.value; + startInput.value = endInput.value; + endInput.value = temp; +}); + +//Placeholder bhvr already handled by browser and CSS opacity +//Ensure placeholder reappears if text removed + +[startInput, endInput].forEach((input) => { + input.addEventListener("focus", () => { + input.classList.add("has-focus"); + }); + + input.addEventListener("blur", () => { + input.classList.remove("has-focus"); + }); +}); + +routeBtn.addEventListener("click", async () => { + const start = startInput.value.trim(); + const end = endInput.value.trim(); + + if (!start || !end) { + output.textContent = + "Please enter a start location and an end destination."; + return; + } + + output.textContent = "Loading route..."; + + try { + const res = await fetch("/process", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ start, end }), + }); + + if (!res.ok) throw new Error(`Server error: ${res.status}`); + + const json = await res.json(); + if (json.message) output.textContent = json.message; + else { + output.textContent = + json.flights.map((airport) => `${airport}`).join("\n") + + `\nTotal travel time: ${json.time} minutes`; + } + } catch (err) { + output.textContent = `Error: ${err.message}`; + console.error(err); + } +}); diff --git a/Waypoint_Flask_Project/static/styles.css b/web/static/styles.css similarity index 100% rename from Waypoint_Flask_Project/static/styles.css rename to web/static/styles.css diff --git a/web/templates/index.html b/web/templates/index.html new file mode 100644 index 0000000..454ccae --- /dev/null +++ b/web/templates/index.html @@ -0,0 +1,57 @@ + + + + + + Waypoint_WIP + + + + + +
+
+

WAYPOINT

+
+
+
+ +
+
+ + + + + + + + + + +

+      
+
+ + + + + From 153b2bae1f496a505f2a4ccb4c72659f2730f206 Mon Sep 17 00:00:00 2001 From: Oliver Deng Date: Sun, 2 Nov 2025 22:34:22 -0500 Subject: [PATCH 4/5] =?UTF-8?q?bump:=20version=200.1.0=20=E2=86=92=200.2.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 25 +++++++++++++++++++++++++ pyproject.toml | 10 +++++++++- uv.lock | 2 +- 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..f27e0cf --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,25 @@ +## 0.2.0 (2025-11-02) + +### Feat + +- integrate frontend +- **path.py**: validation of path objects (#28) +- add a* algorithm (#6) +- **preprocessing.py**: added map from id to name (#5) + +### Fix + +- **main.py**: small import fix (#22) +- fixed type of parameter for graph in algorithms (#20) +- absolute imports rather than relative (#8) +- skip node if empty data +- path dataclass fix + +### Refactor + +- **path.py**: force use of factory methods (#37) +- delete bfs.py (#31) +- more path invariants (#30) +- import shenanigans (#29) +- remove raising errors and just return empty path (#27) +- **path.py**: rename distance to time (#26) diff --git a/pyproject.toml b/pyproject.toml index c10dbba..6ab76a8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "waypoint" -version = "0.1.0" +version = "0.2.0" description = "Finding the shortest flight combination between two airports." readme = "README.md" requires-python = ">=3.12" @@ -19,3 +19,11 @@ build-backend = "setuptools.build_meta" [tool.setuptools] packages = ["waypoint"] + +[tool.commitizen] +name = "cz_conventional_commits" +tag_format = "$version" +version_scheme = "semver2" +version_provider = "uv" +update_changelog_on_bump = true +major_version_zero = true diff --git a/uv.lock b/uv.lock index 470180c..e662d12 100644 --- a/uv.lock +++ b/uv.lock @@ -187,7 +187,7 @@ wheels = [ [[package]] name = "waypoint" -version = "0.1.0" +version = "0.2.0" source = { editable = "." } dependencies = [ { name = "flask" }, From 4b6a9fa7cbe471bfa772d4656cf04d380361ceea Mon Sep 17 00:00:00 2001 From: Oliver Deng Date: Sun, 2 Nov 2025 22:37:24 -0500 Subject: [PATCH 5/5] Update README --- README.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8cf185f..8cd3f40 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Project 2 for COP3530 --- Table of Contents + - [Overview](#overview) - [Features](#features) - [Requirements](#requirements) @@ -55,6 +56,12 @@ Run the script directly (inside waypoint/waypoint): uv run main.py ``` +Run the website (inside waypoint/web): + +```bash +uv run app.py +``` + ## Testing Run tests in the main directory: @@ -65,9 +72,10 @@ uv run pytest ## Repository Structure -- `waypoint/` - Source code -- `data/` - Data is small enough to easily include in repo -- `tests/` - Unit tests +- `waypoint/` - Source code +- `data/` - Data is small enough to easily include in repo +- `tests/` - Unit tests +- `web/` - Web application code ## Contributing