diff --git a/front/src/index.ts b/front/src/index.ts index c1a06f3..a82e0f4 100644 --- a/front/src/index.ts +++ b/front/src/index.ts @@ -1,223 +1,6 @@ // eslint-disable-next-line spaced-comment /// -let phone = 0; -const leafletLoaderJS = document.createElement("script"); -leafletLoaderJS.setAttribute("src", "https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"); -leafletLoaderJS.setAttribute( - "integrity", - "sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==", -); -leafletLoaderJS.setAttribute("crossorigin", "anonymous"); -const leafletLoaderCSS = document.createElement("link"); -leafletLoaderCSS.setAttribute("rel", "stylesheet"); -leafletLoaderCSS.setAttribute("href", "https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"); -leafletLoaderCSS.setAttribute( - "integrity", - "sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==", -); -leafletLoaderCSS.setAttribute("crossorigin", "anonymous"); - -const request = (resource: string, data: any) => - fetch(`/api/${resource}.shs`, { - method: "POST", - body: new URLSearchParams(data).toString(), - credentials: "include", - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - }).then((res) => res.json()); - -const openError = (content: string) => { - const errorBox = document.querySelector(".error-box")!; - const txt = errorBox.querySelector(".error-box-text")!; - txt.innerText = content; - errorBox.style.display = "block"; -}; - -const openLockerConfirm = (lat: string, lon: string, openCode: string, id: string) => { - (document.querySelector(".areyousure-box") as HTMLElement).style.display = "none"; - request("collect", { - lat, - lon, - openCode, - id, - }).then((res) => { - if (res.status != 200) { - openError(res.description || res.msg); - } - }); -}; - -const openLocker = (lat: string, lon: string, openCode: string, id: string) => { - (document.querySelector(".areyousure-box") as HTMLElement).style.display = "block"; - (document.querySelector(".areyousure-button") as HTMLElement)!.onclick = () => { - openLockerConfirm(lat, lon, openCode, id); - }; -}; - -const refreshPackages = () => - request("packages", {}).then((res) => { - const table = document.querySelector("tbody")!; - res.forEach((shipment: Package) => { - const row = table.insertRow(); - const id = row.insertCell(0); - const sender = row.insertCell(1); - const status = row.insertCell(2); - const locker = row.insertCell(3); - const details = row.insertCell(4); - const opener = row.insertCell(5); - - row.dataset.pickupPointLat = shipment.pickupPoint.location.latitude.toString(); - row.dataset.pickupPointLon = shipment.pickupPoint.location.longitude.toString(); - row.dataset.pickupPointDescription = shipment.pickupPoint.description; - row.dataset.pickupPointName = shipment.pickupPoint.name; - row.dataset.pickupPointStatus = shipment.pickupPoint.status; - row.dataset.pickupPointStreet = shipment.pickupPoint.address.street; - row.dataset.pickupPointStreetNumber = shipment.pickupPoint.address.buildingNumber; - row.dataset.pickupPointCity = shipment.pickupPoint.address.city; - row.dataset.pickupPointProvince = shipment.pickupPoint.address.province; - row.dataset.pickupPointPostCode = shipment.pickupPoint.address.postCode; - row.dataset.openCode = shipment.openCode; - row.dataset.id = shipment.shipmentNumber; - row.dataset.sender = shipment.senderName; - row.dataset.status = shipment.status; - - id.innerText = shipment.shipmentNumber; - sender.innerText = shipment.senderName; - status.innerText = shipment.status; - locker.innerText = `${shipment.pickupPoint.name} - ${shipment.pickupPoint.description}`; - - const showDetailsAction = document.createElement("a"); - showDetailsAction.classList.add("button", "is-light", "is-small"); - showDetailsAction.innerHTML = "Info"; - - showDetailsAction.addEventListener("click", (event) => { - const data = ((event.target as Element).parentNode!.parentNode as HTMLElement).dataset; - document.querySelector("head")!.appendChild(leafletLoaderCSS); - document.querySelector("head")!.appendChild(leafletLoaderJS); - leafletLoaderJS.addEventListener("load", () => { - const map = L.map("map").setView( - [parseFloat(data.pickupPointLat!), parseFloat(data.pickupPointLon!)], - 17, - ); - L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", { - attribution: - 'Map data © OpenStreetMap contributors', - maxZoom: 19, - }).addTo(map); - L.marker([parseFloat(data.pickupPointLat!), parseFloat(data.pickupPointLon!)]).addTo(map); - }); - }); - - const openAction = document.createElement("a"); - openAction.classList.add("button", "is-light", "is-small"); - openAction.innerHTML = "Open"; - if (shipment.status == "ready_to_pickup") { - openAction.addEventListener("click", (event) => { - const data = ((event.target as Element).parentNode!.parentNode as HTMLElement).dataset; - openLocker(data.pickupPointLat!, data.pickupPointLon!, data.openCode!, data.id!); - }); - } else { - openAction.setAttribute("disabled", ""); - } - - opener.appendChild(openAction); - details.appendChild(showDetailsAction); - }); - }); -window.addEventListener("load", () => { - const login = document.querySelector(".login-form")!; - login.addEventListener("submit", (event) => { - event.preventDefault(); - const form = event.target as HTMLFormElement; - request("login", { - login: form.login.value, - password: form.password.value, - }).then((res) => { - if (res.status == 200) { - refreshPackages().then(() => { - [".login-box", ".register-box"].forEach((elementName) => { - (document.querySelector(elementName)! as HTMLDivElement).style.display = "none"; - }); - (document.querySelector(".package-list")! as HTMLDivElement).style.display = "block"; - }); - } else { - openError(res.msg || "Error during login. Try again in a while?"); - } - }); - }); - - const logout = document.querySelector(".logout-button")!; - logout.addEventListener("click", () => { - request("logout", {}).then(() => { - document.location.reload(); - }); - }); - - const register = document.querySelector(".register-form")!; - register.addEventListener("submit", async (event) => { - event.preventDefault(); - const form = event.target as HTMLFormElement; - phone = form.phone.value; - const res = await request("register", { - login: form.login.value, - password: form.password.value, - phone: form.phone.value, - }); - if (res.status == 200) { - [".register-box", ".login-box"].forEach((element) => { - (document.querySelector(element)! as HTMLDivElement).style.display = "none"; - }); - (document.querySelector(".sms-box")! as HTMLDivElement).style.display = "block"; - } else { - openError(res.description || res.msg); - } - }); - - const sms = document.querySelector(".sms-form")!; - sms.addEventListener("submit", async (event) => { - event.preventDefault(); - const form = event.target as HTMLFormElement; - const res = await request("smscode", { - code: form.code.value, - phone, - }); - if (res.status == 200) { - (document.querySelector(".sms-box")! as HTMLDivElement).style.display = "none"; - await refreshPackages(); - (document.querySelector(".package-list")! as HTMLDivElement).style.display = "block"; - } else { - openError(res.description || res.msg); - } - }); - - const errorBoxWindow = document.querySelector(".error-box")!; - const errorBoxButton = document.querySelector(".error-box-button")!; - errorBoxButton.addEventListener("click", () => { - errorBoxWindow.style.display = "none"; - }); - - const areYouNotSureButton = document.querySelector(".areyousure-button-deny")!; - areYouNotSureButton.addEventListener("click", () => { - (document.querySelector(".areyousure-box") as HTMLElement).style.display = "none"; - }); - - request("session", {}).then((res) => { - if (res.status == 200) { - // logged in - refreshPackages().then(() => { - (document.querySelector(".package-list")! as HTMLDivElement).style.display = "block"; - }); - } else { - // not logged in - [".login-box", ".register-box"].forEach((elementName) => { - (document.querySelector(elementName)! as HTMLDivElement).style.display = "block"; - }); - } - }); -}); - interface Package { openCode: string; pickupPoint: Locker; @@ -355,3 +138,225 @@ enum PackageStatus { /** Upłynął termin odebrania paczki z Paczkomatu tymczasowego, ale paczka nadal jest w nim magazynowana - czeka na przyjazd kuriera, który ją zabierze do pierwotnie wybranego Paczkomatu. */ STACK_PARCEL_IN_BOX_MACHINE_PICKUP_TIME_EXPIRED = "stack_parcel_in_box_machine_pickup_time_expired", } + +let phone = 0; +const leafletLoaderJS = document.createElement("script"); +leafletLoaderJS.setAttribute("src", "https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"); +leafletLoaderJS.setAttribute( + "integrity", + "sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==", +); +leafletLoaderJS.setAttribute("crossorigin", "anonymous"); +const leafletLoaderCSS = document.createElement("link"); +leafletLoaderCSS.setAttribute("rel", "stylesheet"); +leafletLoaderCSS.setAttribute("href", "https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"); +leafletLoaderCSS.setAttribute( + "integrity", + "sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==", +); +leafletLoaderCSS.setAttribute("crossorigin", "anonymous"); + +const openError = (content: string) => { + const errorBox = document.querySelector(".error-box")!; + const txt = errorBox.querySelector(".error-box-text")!; + txt.innerText = content; + errorBox.style.display = "block"; +}; + +const request = (resource: string, data: any) => + fetch(`/api/${resource}.shs`, { + method: "POST", + body: new URLSearchParams(data).toString(), + credentials: "include", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + }, + }) + .then((res) => res.json()) + .catch((err: Error) => { + openError(err.message); + throw new Error(`Rejected promise ${err.message}`); + }); + +const openLockerConfirm = (lat: string, lon: string, openCode: string, id: string) => { + (document.querySelector(".areyousure-box") as HTMLElement).style.display = "none"; + request("collect", { + lat, + lon, + openCode, + id, + }).then((res) => { + if (res.status != 200) { + openError(res.description || res.msg); + } + }); +}; + +const openLocker = (lat: string, lon: string, openCode: string, id: string) => { + (document.querySelector(".areyousure-box") as HTMLElement).style.display = "block"; + (document.querySelector(".areyousure-button") as HTMLElement)!.onclick = () => { + openLockerConfirm(lat, lon, openCode, id); + }; +}; + +const refreshPackages = () => + request("packages", {}).then((res: Package[]) => { + const table = document.querySelector("tbody")!; + res.reverse().forEach((shipment) => { + const row = table.insertRow(); + const id = row.insertCell(0); + const sender = row.insertCell(1); + const status = row.insertCell(2); + const locker = row.insertCell(3); + const details = row.insertCell(4); + const opener = row.insertCell(5); + + row.dataset.pickupPointLat = shipment.pickupPoint.location.latitude.toString(); + row.dataset.pickupPointLon = shipment.pickupPoint.location.longitude.toString(); + row.dataset.pickupPointDescription = shipment.pickupPoint.description; + row.dataset.pickupPointName = shipment.pickupPoint.name; + row.dataset.pickupPointStatus = shipment.pickupPoint.status; + row.dataset.pickupPointStreet = shipment.pickupPoint.address.street; + row.dataset.pickupPointStreetNumber = shipment.pickupPoint.address.buildingNumber; + row.dataset.pickupPointCity = shipment.pickupPoint.address.city; + row.dataset.pickupPointProvince = shipment.pickupPoint.address.province; + row.dataset.pickupPointPostCode = shipment.pickupPoint.address.postCode; + row.dataset.openCode = shipment.openCode; + row.dataset.id = shipment.shipmentNumber; + row.dataset.sender = shipment.senderName; + row.dataset.status = shipment.status; + + id.innerText = shipment.shipmentNumber; + sender.innerText = shipment.senderName; + status.innerText = shipment.status; + locker.innerText = `${shipment.pickupPoint.name} - ${shipment.pickupPoint.description}`; + + const showDetailsAction = document.createElement("a"); + showDetailsAction.classList.add("button", "is-light", "is-small"); + showDetailsAction.innerHTML = "Info"; + + showDetailsAction.addEventListener("click", (event) => { + const data = ((event.target as Element).parentNode!.parentNode as HTMLElement).dataset; + document.querySelector("head")!.appendChild(leafletLoaderCSS); + document.querySelector("head")!.appendChild(leafletLoaderJS); + leafletLoaderJS.addEventListener("load", () => { + const map = L.map("map").setView( + [parseFloat(data.pickupPointLat!), parseFloat(data.pickupPointLon!)], + 17, + ); + L.tileLayer("https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png", { + attribution: + 'Map data © OpenStreetMap contributors', + maxZoom: 19, + }).addTo(map); + L.marker([parseFloat(data.pickupPointLat!), parseFloat(data.pickupPointLon!)]).addTo(map); + }); + }); + + const openAction = document.createElement("a"); + openAction.classList.add("button", "is-light", "is-small"); + openAction.innerHTML = "Open"; + if (shipment.status == PackageStatus.READY_TO_PICKUP) { + openAction.addEventListener("click", (event) => { + const data = ((event.target as Element).parentNode!.parentNode as HTMLElement).dataset; + openLocker(data.pickupPointLat!, data.pickupPointLon!, data.openCode!, data.id!); + }); + } else { + openAction.setAttribute("disabled", ""); + } + + opener.appendChild(openAction); + details.appendChild(showDetailsAction); + }); + }); +window.addEventListener("load", () => { + const login = document.querySelector(".login-form")!; + login.addEventListener("submit", (event) => { + event.preventDefault(); + const form = event.target as HTMLFormElement; + request("login", { + login: form.login.value, + password: form.password.value, + }).then((res) => { + if (res.status == 200) { + refreshPackages().then(() => { + [".login-box", ".register-box"].forEach((elementName) => { + (document.querySelector(elementName)! as HTMLDivElement).style.display = "none"; + }); + (document.querySelector(".package-list")! as HTMLDivElement).style.display = "block"; + }); + } else { + openError(res.msg || "Error during login. Try again in a while?"); + } + }); + }); + + const logout = document.querySelector(".logout-button")!; + logout.addEventListener("click", () => { + request("logout", {}).then(() => { + document.location.reload(); + }); + }); + + const register = document.querySelector(".register-form")!; + register.addEventListener("submit", async (event) => { + event.preventDefault(); + const form = event.target as HTMLFormElement; + phone = form.phone.value; + const res = await request("register", { + login: form.login.value, + password: form.password.value, + phone: form.phone.value, + }); + if (res.status == 200) { + [".register-box", ".login-box"].forEach((element) => { + (document.querySelector(element)! as HTMLDivElement).style.display = "none"; + }); + (document.querySelector(".sms-box")! as HTMLDivElement).style.display = "block"; + } else { + openError(res.description || res.msg); + } + }); + + const sms = document.querySelector(".sms-form")!; + sms.addEventListener("submit", async (event) => { + event.preventDefault(); + const form = event.target as HTMLFormElement; + const res = await request("smscode", { + code: form.code.value, + phone, + }); + if (res.status == 200) { + (document.querySelector(".sms-box")! as HTMLDivElement).style.display = "none"; + await refreshPackages(); + (document.querySelector(".package-list")! as HTMLDivElement).style.display = "block"; + } else { + openError(res.description || res.msg); + } + }); + + const errorBoxWindow = document.querySelector(".error-box")!; + const errorBoxButton = document.querySelector(".error-box-button")!; + errorBoxButton.addEventListener("click", () => { + errorBoxWindow.style.display = "none"; + }); + + const areYouNotSureButton = document.querySelector(".areyousure-button-deny")!; + areYouNotSureButton.addEventListener("click", () => { + (document.querySelector(".areyousure-box") as HTMLElement).style.display = "none"; + }); + + request("session", {}).then((res) => { + if (res.status == 200) { + // logged in + refreshPackages().then(() => { + (document.querySelector(".package-list")! as HTMLDivElement).style.display = "block"; + }); + } else { + // not logged in + [".login-box", ".register-box"].forEach((elementName) => { + (document.querySelector(elementName)! as HTMLDivElement).style.display = "block"; + }); + } + }); +}); diff --git a/front/src/style.scss b/front/src/style.scss index 3b355dd..0383bdf 100644 --- a/front/src/style.scss +++ b/front/src/style.scss @@ -12,6 +12,10 @@ $family-sans-serif: BlinkMacSystemFont, -apple-system, sans-serif; } #map { - width: 400px; - height: 400px; + width: 400px; + height: 400px; +} + +.error-box-text { + font-family: monospace; } diff --git a/webroot/index.html b/webroot/index.html index 9d2dedd..296325a 100644 --- a/webroot/index.html +++ b/webroot/index.html @@ -81,9 +81,9 @@
Error
- +
- OK + OK