From 11acd7b056fdb66f4f04ecfb53fe09fdd2ccedfd Mon Sep 17 00:00:00 2001 From: jmayer913 <72579603+jmayer913@users.noreply.github.com> Date: Thu, 22 Jan 2026 17:15:18 -0500 Subject: [PATCH 1/7] Updated the Version, Updated the Packages --- .../JMayer.Example.ASPReact.Server.csproj | 6 +++--- TestProject/TestProject.csproj | 4 ++-- jmayer.example.aspreact.client/package.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/JMayer.Example.ASPReact.Server/JMayer.Example.ASPReact.Server.csproj b/JMayer.Example.ASPReact.Server/JMayer.Example.ASPReact.Server.csproj index c8372a6..b575935 100644 --- a/JMayer.Example.ASPReact.Server/JMayer.Example.ASPReact.Server.csproj +++ b/JMayer.Example.ASPReact.Server/JMayer.Example.ASPReact.Server.csproj @@ -7,16 +7,16 @@ ..\jmayer.example.aspreact.client npm run dev https://localhost:5173 - 9.0.0 + 9.0.1 jmayer913 jmayer913 https://github.com/jmayer913/JMayer-Example-ASPReact - + - 9.0.11 + 9.0.12 diff --git a/TestProject/TestProject.csproj b/TestProject/TestProject.csproj index 2ffc64f..dd51fa0 100644 --- a/TestProject/TestProject.csproj +++ b/TestProject/TestProject.csproj @@ -7,7 +7,7 @@ false true - 9.0.0 + 9.0.1 @@ -15,7 +15,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/jmayer.example.aspreact.client/package.json b/jmayer.example.aspreact.client/package.json index 9e63522..dff1ce0 100644 --- a/jmayer.example.aspreact.client/package.json +++ b/jmayer.example.aspreact.client/package.json @@ -1,7 +1,7 @@ { "name": "jmayer.example.aspreact.client", "private": true, - "version": "9.0.0", + "version": "9.0.1", "type": "module", "scripts": { "dev": "vite", From bf97d7cfaf321c26722d26afcb593090477560db Mon Sep 17 00:00:00 2001 From: jmayer913 <72579603+jmayer913@users.noreply.github.com> Date: Fri, 23 Jan 2026 08:25:08 -0500 Subject: [PATCH 2/7] Update README.md --- README.md | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 11f7ecb..9845c76 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,30 @@ find a flight in the flight schedule to determine what sort destination the bag On startup, the example project pregenerates a few airlines, gates and sort destinations and then, a flight schedule is pregenerated; a flight every 10 minutes between 4AM and 10PM. The example has two pages, airlines and flight schedule. -## Airline +## Airlines Page + The airlines page allows the user to add/edit/delete airlines. -image +image + +### Add / Edit + +On the airlines page, the user can create a new airline or edit an existing airline. + +* Name - The friendly name for the airline; required and must be unique. +* Description - A description about the airline; optional. +* IATA - The code assigned by the International Air Transport Association to the airline; required and must be two letters or a letter and a number. +* ICAO - The code assigned by the International Civil Aviation Organization to the airline; required, must be 3 letters and must be unique. +* Number Code - The number code assigned by the International Air Transport Association to the airline; required, must be 3 digits and must be unique unless 000 (unassigned). +* Sort Destination - The default sort destination for the airline; required. + +image + +image -image +### Delete -image +On the airlines page, the user can delete an airline. The user will be required to confirm the deletion or cancel. On confirmation, the airline will be deleted. image @@ -21,13 +37,26 @@ The flight schedule page allows the user to add/edit/delete flights in the sched image +### Add / Edit + +On the flight schedule page, the user can create a new flight or edit an existing flight. + +* Gate - The gate the flight will be docked at for departure; required. +* Airline - The airline which owns the plane; required. +* Flight Number - The number assigned to the flight; required and must be 4 digits or 4 digits and a letter. +* Destination - The next destination for the flight; required and must be 3 letters. +* Depart Time - The schedule time the plane will depart from the gate; required. +* Sort Destination - The sort destination bags will be sorted too for the flight; required. + image image -image +### Delete +On the flight schedule page, the user can delete a flight. The user will be required to confirm the deletion or cancel. On confirmation, the flight will be deleted. +image From fb030f023c50603d4a2958c1b714306ced43a218 Mon Sep 17 00:00:00 2001 From: jmayer913 <72579603+jmayer913@users.noreply.github.com> Date: Fri, 23 Jan 2026 08:50:53 -0500 Subject: [PATCH 3/7] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 9845c76..4245a82 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,9 @@ On the flight schedule page, the user can delete a flight. The user will be requ image +## Edit Conflict +When two users are editing an airline or flight at the same time, whoever submits first will win; the other user will be told to try again. +image From c4a849274a69e16227e8e5f8e6986d02dcc21404 Mon Sep 17 00:00:00 2001 From: jmayer913 <72579603+jmayer913@users.noreply.github.com> Date: Fri, 23 Jan 2026 09:14:31 -0500 Subject: [PATCH 4/7] Added not found handling Also added constants for the codes --- jmayer.example.aspreact.client/package-lock.json | 4 ++-- .../src/datalayers/AirlineDataLayer.jsx | 16 +++++++++++----- .../src/datalayers/FlightDataLayer.jsx | 16 +++++++++++----- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/jmayer.example.aspreact.client/package-lock.json b/jmayer.example.aspreact.client/package-lock.json index e92703b..71b8deb 100644 --- a/jmayer.example.aspreact.client/package-lock.json +++ b/jmayer.example.aspreact.client/package-lock.json @@ -1,12 +1,12 @@ { "name": "jmayer.example.aspreact.client", - "version": "9.0.0", + "version": "9.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "jmayer.example.aspreact.client", - "version": "9.0.0", + "version": "9.0.1", "dependencies": { "globals": "^16.2.0", "primeflex": "^4.0.0", diff --git a/jmayer.example.aspreact.client/src/datalayers/AirlineDataLayer.jsx b/jmayer.example.aspreact.client/src/datalayers/AirlineDataLayer.jsx index 08aef90..d4a81c2 100644 --- a/jmayer.example.aspreact.client/src/datalayers/AirlineDataLayer.jsx +++ b/jmayer.example.aspreact.client/src/datalayers/AirlineDataLayer.jsx @@ -23,6 +23,12 @@ export function useAirlineDataLayer() { const [updateAirlineSuccess, setUpdateAirlineSuccess] = useState(false); const [updateAirlineValidationProblemDetails, setUpdateAirlineValidationProblemDetails] = useState(null); + //Constants for the status codes returned by the server. + const BadRequestCode = 400; + const NotFoundCode = 404; + const ConflictCode = 409; + const InternalServerError = 500; + //The function adds an airline to the server. //@param {object} airline The airline to add. const addAirline = (airline) => { @@ -39,10 +45,10 @@ export function useAirlineDataLayer() { if (response.ok) { setAddAirlineSuccess(true); } - else if (response.status === 400) { + else if (response.status === BadRequestCode) { response.json().then(validationProblemDetails => setAddAirlineValidationProblemDetails(validationProblemDetails)); } - else if (response.status === 500) { + else if (response.status === InternalServerError) { response.json().then(problemDetails => showError(problemDetails.detail)); } else { @@ -73,7 +79,7 @@ export function useAirlineDataLayer() { if (response.ok) { setDeleteAirlineSuccess(true); } - else if (response.status === 500) { + else if (response.status === NotFoundCode || response.status === InternalServerError) { response.json().then(problemDetails => showError(problemDetails.detail)); } else { @@ -107,10 +113,10 @@ export function useAirlineDataLayer() { if (response.ok) { setUpdateAirlineSuccess(true); } - else if (response.status === 400) { + else if (response.status === BadRequestCode) { response.json().then(validationProblemDetails => setUpdateAirlineValidationProblemDetails(validationProblemDetails)); } - else if (response.status == 409 || response.status === 500) { + else if (response.status === NotFoundCode || response.status == ConflictCode || response.status === InternalServerError) { response.json().then(problemDetails => showError(problemDetails.detail)); } else { diff --git a/jmayer.example.aspreact.client/src/datalayers/FlightDataLayer.jsx b/jmayer.example.aspreact.client/src/datalayers/FlightDataLayer.jsx index a5cdb1a..2d3334d 100644 --- a/jmayer.example.aspreact.client/src/datalayers/FlightDataLayer.jsx +++ b/jmayer.example.aspreact.client/src/datalayers/FlightDataLayer.jsx @@ -27,6 +27,12 @@ export function useFlightDataLayer() { const [updateFlightSuccess, setUpdateFlightSuccess] = useState(false); const [updateFlightValidationProblemDetails, setUpdateFlightValidationProblemDetails] = useState(null); + //Constants for the status codes returned by the server. + const BadRequestCode = 400; + const NotFoundCode = 404; + const ConflictCode = 409; + const InternalServerError = 500; + //The function adds a flight to the server. //@param {object} flight The flight to add. const addFlight = (flight) => { @@ -45,10 +51,10 @@ export function useFlightDataLayer() { if (response.ok) { setAddFlightSuccess(true); } - else if (response.status === 400) { + else if (response.status === BadRequestCode) { response.json().then(validationProblemDetails => setAddFlightValidationProblemDetails(validationProblemDetails)); } - else if (response.status === 500) { + else if (response.status === InternalServerError) { response.json().then(problemDetails => showError(problemDetails.detail)); } else { @@ -79,7 +85,7 @@ export function useFlightDataLayer() { if (response.ok) { setDeleteFlightSuccess(true); } - else if (response.status === 500) { + else if (response.status === NotFoundCode || response.status === InternalServerError) { response.json().then(problemDetails => showError(problemDetails.detail)); } else { @@ -125,10 +131,10 @@ export function useFlightDataLayer() { if (response.ok) { setUpdateFlightSuccess(true); } - else if (response.status === 400) { + else if (response.status === BadRequestCode) { response.json().then(validationProblemDetails => setUpdateFlightValidationProblemDetails(validationProblemDetails)); } - else if (response.status == 409 || response.status === 500) { + else if (response.status === NotFoundCode || response.status == ConflictCode || response.status === InternalServerError) { response.json().then(problemDetails => showError(problemDetails.detail)); } else { From 6fc613ad19680422f01e71ebb2bd5e0ca32b12dd Mon Sep 17 00:00:00 2001 From: jmayer913 <72579603+jmayer913@users.noreply.github.com> Date: Fri, 23 Jan 2026 09:20:13 -0500 Subject: [PATCH 5/7] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4245a82..b343e8e 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,8 @@ On the flight schedule page, the user can create a new flight or edit an existin * Depart Time - The schedule time the plane will depart from the gate; required. * Sort Destination - The sort destination bags will be sorted too for the flight; required. +If the flight's airline, flight number and destination match another flight, the add or edit will be rejected by the server. + image image From 13b87c3313b5f2755080a1ee38895c6cdb19144a Mon Sep 17 00:00:00 2001 From: jmayer913 <72579603+jmayer913@users.noreply.github.com> Date: Fri, 23 Jan 2026 09:33:05 -0500 Subject: [PATCH 6/7] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b343e8e..73cf8b6 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ On the airlines page, the user can create a new airline or edit an existing airl ### Delete -On the airlines page, the user can delete an airline. The user will be required to confirm the deletion or cancel. On confirmation, the airline will be deleted. +On the airlines page, the user can delete an airline. The user will be required to confirm the deletion or cancel. On confirmation, the airline and its associated flights will be deleted. image From 1e07a710b49a8da9934cca5915d06cb6d1eac275 Mon Sep 17 00:00:00 2001 From: jmayer913 <72579603+jmayer913@users.noreply.github.com> Date: Fri, 23 Jan 2026 09:35:37 -0500 Subject: [PATCH 7/7] Updated react packages --- .../package-lock.json | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/jmayer.example.aspreact.client/package-lock.json b/jmayer.example.aspreact.client/package-lock.json index 71b8deb..042526a 100644 --- a/jmayer.example.aspreact.client/package-lock.json +++ b/jmayer.example.aspreact.client/package-lock.json @@ -789,9 +789,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", - "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1227,9 +1227,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "19.2.7", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", - "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", + "version": "19.2.9", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.9.tgz", + "integrity": "sha512-Lpo8kgb/igvMIPeNV2rsYKTgaORYdO1XGVZ4Qz3akwOj0ySGYMPlQWa8BaLn0G63D1aSaAQ5ldR06wCpChQCjA==", "dependencies": { "csstype": "^3.2.2" } @@ -2060,9 +2060,9 @@ } }, "node_modules/eslint": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", - "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", @@ -2071,7 +2071,7 @@ "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.1", + "@eslint/js": "9.39.2", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -2163,9 +2163,9 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.24.tgz", - "integrity": "sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w==", + "version": "0.4.26", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.26.tgz", + "integrity": "sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==", "dev": true, "peerDependencies": { "eslint": ">=8.40" @@ -3548,28 +3548,28 @@ } }, "node_modules/react": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", - "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", + "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", - "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.0" + "react": "^19.2.3" } }, "node_modules/react-is": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz", - "integrity": "sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==" + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.3.tgz", + "integrity": "sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA==" }, "node_modules/react-refresh": { "version": "0.17.0", @@ -3581,9 +3581,9 @@ } }, "node_modules/react-router": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.6.tgz", - "integrity": "sha512-Y1tUp8clYRXpfPITyuifmSoE2vncSME18uVLgaqyxh9H35JWpIfzHo+9y3Fzh5odk/jxPW29IgLgzcdwxGqyNA==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.12.0.tgz", + "integrity": "sha512-kTPDYPFzDVGIIGNLS5VJykK0HfHLY5MF3b+xj0/tTyNYL1gF1qs7u67Z9jEhQk2sQ98SUaHxlG31g1JtF7IfVw==", "dependencies": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" @@ -3602,11 +3602,11 @@ } }, "node_modules/react-router-dom": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.6.tgz", - "integrity": "sha512-2MkC2XSXq6HjGcihnx1s0DBWQETI4mlis4Ux7YTLvP67xnGxCvq+BcCQSO81qQHVUTM1V53tl4iVVaY5sReCOA==", + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.12.0.tgz", + "integrity": "sha512-pfO9fiBcpEfX4Tx+iTYKDtPbrSLLCbwJ5EqP+SPYQu1VYCXdy79GSj0wttR0U4cikVdlImZuEZ/9ZNCgoaxwBA==", "dependencies": { - "react-router": "7.9.6" + "react-router": "7.12.0" }, "engines": { "node": ">=20.0.0"