freealberta/influence/app/public/js/postal-lookup.js

158 lines
5.4 KiB
JavaScript

// Postal Code Lookup Module
class PostalLookup {
constructor() {
this.form = document.getElementById('postal-form');
this.input = document.getElementById('postal-code');
this.refreshBtn = document.getElementById('refresh-btn');
this.loadingDiv = document.getElementById('loading');
this.errorDiv = document.getElementById('error-message');
this.representativesSection = document.getElementById('representatives-section');
this.locationDetails = document.getElementById('location-details');
this.currentPostalCode = null;
this.init();
}
init() {
this.form.addEventListener('submit', (e) => this.handleSubmit(e));
this.refreshBtn.addEventListener('click', () => this.handleRefresh());
this.input.addEventListener('input', (e) => this.formatPostalCode(e));
}
formatPostalCode(e) {
let value = e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, '');
// Format as A1A 1A1
if (value.length > 3) {
value = value.slice(0, 3) + ' ' + value.slice(3, 6);
}
e.target.value = value;
}
validatePostalCode(postalCode) {
const cleaned = postalCode.replace(/\s/g, '');
// Check format: Letter-Number-Letter Number-Letter-Number
const regex = /^[A-Z]\d[A-Z]\d[A-Z]\d$/;
if (!regex.test(cleaned)) {
return { valid: false, message: 'Please enter a valid postal code format (A1A 1A1)' };
}
// Check if it's an Alberta postal code (starts with T)
if (!cleaned.startsWith('T')) {
return { valid: false, message: 'This tool is designed for Alberta postal codes only (starting with T)' };
}
return { valid: true };
}
showError(message) {
this.errorDiv.textContent = message;
this.errorDiv.style.display = 'block';
this.representativesSection.style.display = 'none';
}
hideError() {
this.errorDiv.style.display = 'none';
}
showLoading() {
this.loadingDiv.style.display = 'block';
this.hideError();
this.representativesSection.style.display = 'none';
}
hideLoading() {
this.loadingDiv.style.display = 'none';
}
async handleSubmit(e) {
e.preventDefault();
const postalCode = this.input.value.trim();
if (!postalCode) {
this.showError('Please enter a postal code');
return;
}
const validation = this.validatePostalCode(postalCode);
if (!validation.valid) {
this.showError(validation.message);
return;
}
await this.lookupRepresentatives(postalCode);
}
async handleRefresh() {
if (!this.currentPostalCode) return;
try {
this.showLoading();
this.refreshBtn.disabled = true;
const data = await window.apiClient.refreshRepresentatives(this.currentPostalCode);
this.displayResults(data);
window.messageDisplay.show('Representatives data refreshed successfully!', 'success');
} catch (error) {
console.error('Refresh failed:', error);
this.showError(`Failed to refresh data: ${error.message}`);
} finally {
this.hideLoading();
this.refreshBtn.disabled = false;
}
}
async lookupRepresentatives(postalCode) {
try {
this.showLoading();
const data = await window.apiClient.getRepresentativesByPostalCode(postalCode);
this.currentPostalCode = postalCode;
this.displayResults(data);
} catch (error) {
console.error('Lookup failed:', error);
this.showError(`Failed to find representatives: ${error.message}`);
} finally {
this.hideLoading();
}
}
displayResults(apiResponse) {
this.hideError();
this.hideLoading();
// Handle the API response structure
const data = apiResponse.data || apiResponse; // Handle both new and old response formats
// Update location info
let locationText = `Postal Code: ${data.postalCode}`;
if (data.location && data.location.city && data.location.province) {
locationText += `${data.location.city}, ${data.location.province}`;
} else if (data.city && data.province) {
locationText += `${data.city}, ${data.province}`;
}
if (data.source || apiResponse.source) {
locationText += ` • Data source: ${data.source || apiResponse.source}`;
}
locationText += ` • Data source: api`;
this.locationDetails.textContent = locationText;
// Show representatives
const representatives = data.representatives || [];
console.log('Displaying representatives:', representatives.length, representatives);
window.representativesDisplay.displayRepresentatives(representatives);
// Show section and refresh button
this.representativesSection.style.display = 'block';
this.refreshBtn.style.display = 'inline-block';
}
}
// Initialize when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
window.postalLookup = new PostalLookup();
});