diff --git a/.env.example b/.env.example
index c4c451c5..8b8552c1 100644
--- a/.env.example
+++ b/.env.example
@@ -1,2 +1,4 @@
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
+
+API_KEY=
diff --git a/src/app/api/address/route.ts b/src/app/api/address/route.ts
new file mode 100644
index 00000000..bd5dc153
--- /dev/null
+++ b/src/app/api/address/route.ts
@@ -0,0 +1,77 @@
+import { NextRequest } from 'next/server';
+
+const mapsTranslationToDbTowns: { [key: string]: string } = {
+ Aldaya: 'Aldaia',
+ 'Ribarroja de Turia': 'Riba-roja de Túria',
+ Benetuser: 'Benetusser',
+ Benetússer: 'Benetusser',
+ Benetúser: 'Benetusser',
+ Toris: 'Turís',
+ Picaña: 'Picanya',
+ 'La Alcudia': "L'Alcúdia",
+ 'Lugar Nuevo de la Corona': 'Llocnou de la Corona',
+ 'Castellón de la Plana': 'Castelló de la Plana',
+ Alcudia: "L'Alcúdia",
+ Guadasuar: 'Guadassuar',
+ València: 'Valencia',
+};
+
+const GOOGLE_URL = `https://maps.googleapis.com/maps/api/geocode/json?key=${process.env.API_KEY}&latlng=`;
+
+export type AddressAndTown = { address: string; town: string };
+
+function normalizeData({ address, town }: AddressAndTown): AddressAndTown {
+ const normalizedTown = Object.keys(mapsTranslationToDbTowns).includes(town) ? mapsTranslationToDbTowns[town] : town;
+ const normalizedAddress = address.replace(town, normalizedTown);
+ return { address: normalizedAddress, town: normalizedTown };
+}
+
+function extractAddressAndTown(googleResponse: any) {
+ // for response refer to documentation: https://developers.google.com/maps/documentation/geocoding/requests-reverse-geocoding
+ // it returns many due to inaccuracies but they only differ from street number(normally) - we look for a good result - contains sublocality
+ let town = '';
+ let address = '';
+ for (const result of googleResponse['results']) {
+ for (const addressComponent of result['address_components']) {
+ let localityFound = false;
+
+ // max three, not really a performance issue
+ for (const type of addressComponent['types']) {
+ if (type === 'locality') {
+ localityFound = true;
+ town = addressComponent['long_name'];
+ break;
+ }
+ }
+
+ if (localityFound) {
+ address = result['formatted_address'];
+
+ return normalizeData({ address, town });
+ }
+ }
+ }
+
+ return { address, town };
+}
+
+export async function POST(request: NextRequest) {
+ const body = await request.json();
+ if (!body.latitude || !body.longitude) {
+ return Response.json({
+ error: 'Latitude and longitude are mandatory fields!',
+ });
+ }
+
+ try {
+ const response = await fetch(`${GOOGLE_URL}${body.latitude},${body.longitude}`);
+ const extractedData = extractAddressAndTown(await response.json());
+
+ return Response.json(extractedData);
+ } catch (exception) {
+ console.error(exception);
+ return Response.json({
+ error: 'An error occured calling google - check logs',
+ });
+ }
+}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 5b8b4e43..47801201 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -1,6 +1,5 @@
import { AlertCircle, Clock, Cross, Heart, MapPin, Navigation, Package, Thermometer, Users } from 'lucide-react';
-// @ts-expect-error
import PhoneNumberDialog from '@/components/auth/PhoneNumberDialog';
import Image from 'next/image';
diff --git a/src/components/AddressAutocomplete.js b/src/components/AddressAutocomplete.js
index 70236609..2cabb82c 100644
--- a/src/components/AddressAutocomplete.js
+++ b/src/components/AddressAutocomplete.js
@@ -3,7 +3,12 @@
import { useState, useEffect, useRef, useCallback } from 'react';
import { MapPin } from 'lucide-react';
-export default function AddressAutocomplete({ onSelect, placeholder = 'Buscar dirección...', initialValue = '' }) {
+export default function AddressAutocomplete({
+ onSelect,
+ placeholder = 'Buscar dirección...',
+ initialValue = '',
+ required = false,
+}) {
const [query, setQuery] = useState(initialValue);
const [suggestions, setSuggestions] = useState([]);
const [isLoading, setIsLoading] = useState(false);
@@ -150,6 +155,7 @@ export default function AddressAutocomplete({ onSelect, placeholder = 'Buscar di
{suggestions.map((suggestion, index) => (