Initial
This commit is contained in:
parent
542ca5a14e
commit
aff781e04a
8 changed files with 548 additions and 37 deletions
319
static/script.js
319
static/script.js
|
|
@ -1 +1,318 @@
|
|||
console.log("Javascript is executing properly...");
|
||||
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 = "<tbody><tr> <th>Kort</th> <th>Ort</th> <th>Pris</th> <th>Datum</th> <th>Tid</th> <th>Länk</th> </tr></tbody>"
|
||||
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()
|
||||
|
|
@ -29,9 +29,11 @@
|
|||
}
|
||||
|
||||
#search-container {
|
||||
max-width: 800px;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#search-container input {
|
||||
|
|
@ -55,6 +57,12 @@
|
|||
font-size: 16px;
|
||||
}
|
||||
|
||||
#search-container select {
|
||||
width: 100%;
|
||||
padding: 0 20px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#results-container {}
|
||||
|
||||
table {
|
||||
|
|
@ -66,7 +74,7 @@ th,
|
|||
td {
|
||||
border-bottom: 1px solid #ddd;
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
padding: 4px 16px;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue