payment confirmation for renter after rental request approval, first listing celebration email, removed burstprotection for google places autocomplete, renamed email templates

This commit is contained in:
jackiettran
2025-10-28 22:23:41 -04:00
parent 502d84a741
commit d1cb857aa7
25 changed files with 2171 additions and 53 deletions

View File

@@ -29,6 +29,8 @@ export interface AutocompletePrediction {
class PlacesService {
private sessionToken: string | null = null;
private debounceTimer: NodeJS.Timeout | null = null;
private abortController: AbortController | null = null;
/**
* Generate a new session token for cost optimization
@@ -41,7 +43,7 @@ class PlacesService {
}
/**
* Get autocomplete predictions for a query
* Get autocomplete predictions for a query (debounced)
*/
async getAutocompletePredictions(
input: string,
@@ -55,14 +57,54 @@ class PlacesService {
return [];
}
// Clear existing debounce timer
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
}
// Cancel any pending request
if (this.abortController) {
this.abortController.abort();
}
// Return a promise that resolves after debounce delay
return new Promise((resolve, reject) => {
this.debounceTimer = setTimeout(async () => {
try {
const predictions = await this.makeAutocompleteRequest(
input.trim(),
options
);
resolve(predictions);
} catch (error) {
reject(error);
}
}, 300); // 300ms debounce delay
});
}
/**
* Make the actual autocomplete API request
*/
private async makeAutocompleteRequest(
input: string,
options?: {
types?: string[];
componentRestrictions?: { country: string };
bounds?: any;
}
): Promise<AutocompletePrediction[]> {
// Generate new session token if not exists
if (!this.sessionToken) {
this.sessionToken = this.generateSessionToken();
}
// Create new abort controller for this request
this.abortController = new AbortController();
try {
const response = await mapsAPI.placesAutocomplete({
input: input.trim(),
input: input,
types: options?.types || ["address"],
componentRestrictions: options?.componentRestrictions,
sessionToken: this.sessionToken || undefined,
@@ -77,6 +119,11 @@ class PlacesService {
return [];
} catch (error: any) {
// Don't throw error if request was aborted (user is still typing)
if (error.name === "AbortError" || error.code === "ERR_CANCELED") {
return [];
}
console.error("Error fetching place predictions:", error.message);
if (error.response?.status === 429) {
throw new Error("Too many requests. Please slow down.");