console.log("Javascript is executing properly..."); const QueryParams = { SSN: "", LicenseId: "", LocationIds: [], examType: "", // Unused for now } const AppState = { LocationsFetched: "", SearchMessage: "", SearchResults: [], LocationIndex: {}, } // Clear the state and the UI async function clearState() { AppState.SearchResults = []; // AppState.LocationIndex = {}; // AppState.SearchMessage = ""; // searchResults.innerHTML = ""; resultsTable.innerHTML = ""; // locationSelector.innerHTML = ""; // locationSelector.disabled = true; } async function readState() { clearState(); console.log("Checking state...") if (ssnInput.value.length == 12 && !isNaN(ssnInput.value)) { console.log("SSN is valid...") QueryParams.SSN = ssnInput.value; // if (!AppState.LocationsFetched) await populateLicenses(); QueryParams.LicenseId = licenseSelector.value; await populateLocations(await queryMetadata(QueryParams.SSN, QueryParams.LicenseId)); licenseSelector.disabled = false; locationSelector.disabled = false; } else { // SSN was changed, but is not valid QueryParams.SSN = ""; licenseSelector.disabled = true; locationSelector.disabled = true; return } if (licenseSelector.value.length > 0 && licenseSelector.value != AppState.LocationsFetched) { AppState.LocationsFetched = licenseSelector.value; QueryParams.LicenseId = licenseSelector.value; QueryParams.examType = (await querySuggested(QueryParams.SSN, QueryParams.LicenseId)).data[0].examinationTypeId; // await populateLocations(await queryMetadata(QueryParams.SSN, QueryParams.LicenseId)); return } if (locationSelector.value.length > 0 && AppState.LocationsFetched) { // console.log(locationSelector.value) if (locationSelector.value == "all") { QueryParams.LocationIds = Object.keys(AppState.LocationIndex) } else { QueryParams.LocationIds = [locationSelector.value]; } // console.log(QueryParams) } return } function readyForSearch() { console.log("State is ready for search...") return QueryParams.SSN.length == 12 && QueryParams.LicenseId.length > 0 && QueryParams.LocationIds.length > 0; } const licenseSelector = document.getElementById("license-selector"); const ssnInput = document.getElementById("ssn-input"); const locationSelector = document.getElementById("location-selector"); const searchButton = document.getElementById("searchButton"); const resultsTable = document.getElementById("results-table"); // const resultsContainer = document.getElementById("results-container"); async function executeSearch() { console.log("Executing search...") await readState() console.log(QueryParams) if (!readyForSearch()) { console.log("Not ready for search...") return; } await querySeveralOccasions(); // console.log(AppState.SearchResults) await displaySearchResults(); } async function displaySearchResults() { // console.log(AppState.SearchResults) console.log("Displaying search results...") AppState.SearchResults.sort((a, b) => { if (a.date < b.date) return -1; if (a.date > b.date) return 1; return 0; }) console.log(AppState.SearchResults) resultsTable.innerHTML = " Kort Ort Pris Datum Tid Länk " for (let occ of AppState.SearchResults) { let tr = document.createElement("tr"); tr.className = "table-row"; let td_license = document.createElement("td"); let td_location = document.createElement("td"); let td_price = document.createElement("td"); let td_date = document.createElement("td"); let td_time = document.createElement("td"); let td_link = document.createElement("td"); td_license.innerText = occ.name; td_location.innerText = occ.location; td_price.innerText = occ.cost; td_date.innerText = occ.date; td_time.innerText = occ.time; td_link.innerText = "-" tr.appendChild(td_license); tr.appendChild(td_location); tr.appendChild(td_price); tr.appendChild(td_date); tr.appendChild(td_time); tr.appendChild(td_link); resultsTable.appendChild(tr); } } async function querySuggested(ssn, licenseId) { let msg = await (await fetch('/suggested', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ licenceId: licenseId, ssn: ssn, }), })).json() return msg } // The metadata is specific to the license type async function queryMetadata(ssn, licenseId) { console.log("Getting metadata...") let msg = await (await fetch('/metadata', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ licenceId: licenseId, ssn: ssn, }), })).json() return msg } async function queryOccasions() { console.log("Querying occasions...") let occasions = [] // console.log(QueryParams) for (const locationId of QueryParams.LocationIds) { let msg = await (await fetch('/occasions', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ licenceId: QueryParams.LicenseId, ssn: QueryParams.SSN, locationId: locationId, examType: QueryParams.examType, }), })).json() if (!msg || !msg.data || !msg.data.bundles) continue; for (let occasion of msg.data.bundles) { occ = occasion.occasions[0]; occasions.push({ name: occ.name, location: occ.locationName, cost: occasion.cost, date: occ.date, time: occ.time, }); } console.log(occasions) // return msg // break } AppState.locationResults = occasions; } async function querySeveralOccasions() { console.log("Querying several occasions...") i = 0 while (i < QueryParams.LocationIds.length) { let current_array = QueryParams.LocationIds.slice(i, i + 4) console.log(current_array) let request = await (await fetch('/occasions', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ licenceId: QueryParams.LicenseId, ssn: QueryParams.SSN, locationId: current_array[0], // The first nearbyIds: current_array.slice(1), // The rest examType: QueryParams.examType, }), })).json() if (!request || !request.data || !request.data.bundles) continue; let bundles = request.data.bundles for (let occasion of bundles) { let occ = occasion.occasions[0]; AppState.SearchResults.push({ name: occ.name, location: occ.locationName, cost: occasion.cost, date: occ.date, time: occ.time, }); } i += 4 } } async function queryLicenseinfo() { console.log("Querying license info...") let msg = await (await fetch('/licenseinfo', { method: 'POST', headers: { 'Content-Type': 'application/json', }, })).json() return msg // console.log(msg) } // let selector = document.getElementById('license-selector') async function populateLicenses() { console.log("Populating licenses...") let licenseinfo = await queryLicenseinfo() // slice(0, 2) to only show the first two license types (car and motorcycle) for (const license_cat of licenseinfo.data.licenceCategories.slice(0, 2)) { for (const license of license_cat.licences) { const new_option = document.createElement('option') new_option.value = license.id new_option.innerText = `${license.name} ${license.description}` licenseSelector.appendChild(new_option) } } } // Executed each time the license type is changed async function licenceChanged(field) { QueryParams.LicenseId = field.value readState() // let metadata_response = await querySuggested(QueryParams.SSN, QueryParams.LicenseId) // if (!metadata_response.data[0]) { // QueryParams.SearchMessage = "This license type is not available for this person." // return // } // QueryParams.examType = metadata_response.data[0].examinationTypeId // console.log(QueryParams) // let metadata = await queryMetadata(QueryParams.SSN, QueryParams.LicenseId) // populateLocations(metadata) } async function populateLocations(response_json) { if (!response_json.data) { console.log("No locations found, likely throttled") return; } for (const location of response_json.data.locations) { // Populate the location index so that we can retrieve other data later AppState.LocationIndex[location.location.id] = location let name = location.location.name let id = location.location.id const new_option = document.createElement('option') new_option.value = id new_option.innerText = `${name}` locationSelector.appendChild(new_option) locationSelector.disabled = false searchButton.disabled = false // console.log(name, id) // const new_option = document.createElement('option') // new_option.value = location.id // new_option.innerText = location.name // locationSelector.appendChild(new_option) } // console.log(AppState.LocationIndex) } async function locationChanged(field) { readState() } let ssn_input_element = document.getElementById('ssn-input') async function ssnChanged(field) { readState() } readState()