From 8a05ba2faf7b1825e3c1733f2764895c382792d2 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Sat, 25 Apr 2026 00:17:35 +0000 Subject: [PATCH] Initial reimplementation in VueJS of address or report suggestion --- .../AddressOrReportSuggestionInput.vue | 223 ++++++++++++++++++ ts/rmo/content/Status.vue | 7 +- ts/rmo/store/address-or-report-suggestion.ts | 145 ++++++++++++ 3 files changed, 371 insertions(+), 4 deletions(-) create mode 100644 ts/components/AddressOrReportSuggestionInput.vue create mode 100644 ts/rmo/store/address-or-report-suggestion.ts diff --git a/ts/components/AddressOrReportSuggestionInput.vue b/ts/components/AddressOrReportSuggestionInput.vue new file mode 100644 index 00000000..f5e83d90 --- /dev/null +++ b/ts/components/AddressOrReportSuggestionInput.vue @@ -0,0 +1,223 @@ + + + + diff --git a/ts/rmo/content/Status.vue b/ts/rmo/content/Status.vue index ef459279..0d72319a 100644 --- a/ts/rmo/content/Status.vue +++ b/ts/rmo/content/Status.vue @@ -73,12 +73,10 @@
- + />
({ + addresses: [], + reports: [], + loading: false, + error: null, + }), + + actions: { + async fetchSuggestions(searchText: string): Promise { + this.loading = true; + this.error = null; + + try { + await Promise.all([ + this.fetchAddressSuggestions(searchText), + this.fetchReportSuggestions(searchText), + ]); + } catch (error) { + this.error = + error instanceof Error ? error.message : "Unknown error occurred"; + console.error("Error fetching suggestions:", error); + } finally { + this.loading = false; + } + }, + + async fetchAddressSuggestions(text: string): Promise { + try { + const url = `https://api.stadiamaps.com/geocoding/v2/autocomplete?text=${encodeURIComponent(text)}&focus.point.lat=35&focus.point.lon=-115`; + + const response = await fetch(url); + + if (!response.ok) { + throw new Error(`Address API error: ${response.status}`); + } + + const data: GeocodeResponse = await response.json(); + this.addresses = data.features || []; + } catch (error) { + console.error("Error fetching geocoding suggestions:", error); + this.addresses = []; + throw error; + } + }, + + async fetchReportSuggestions(text: string): Promise { + try { + const url = `/report/suggest?r=${encodeURIComponent(text)}`; + const response = await fetch(url); + + if (!response.ok) { + throw new Error(`Report API error: ${response.status}`); + } + + const data: ReportResponse = await response.json(); + this.reports = data.reports || []; + } catch (error) { + console.error("Error fetching report suggestions:", error); + this.reports = []; + throw error; + } + }, + + async fetchAddressDetails(gid: string): Promise
{ + try { + const url = `https://api.stadiamaps.com/geocoding/v2/place_details?ids=${gid}`; + const response = await fetch(url); + + if (!response.ok) { + throw new Error(`Address details API error: ${response.status}`); + } + + const data: PlaceDetailsResponse = await response.json(); + return data.features?.[0] || null; + } catch (error) { + console.error("Error fetching address details:", error); + throw error; + } + }, + + clearSuggestions(): void { + this.addresses = []; + this.reports = []; + this.error = null; + }, + }, + + getters: { + hasAddresses: (state): boolean => state.addresses.length > 0, + hasReports: (state): boolean => state.reports.length > 0, + hasSuggestions: (state): boolean => + state.addresses.length > 0 || state.reports.length > 0, + totalSuggestions: (state): number => + state.addresses.length + state.reports.length, + }, +}); + +// Export types for use in components +export type { Address, Report, AddressProperties, SuggestionsState };