Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Feat/address map" #136

Merged
merged 1 commit into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/app/api/address/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ const mapsTranslationToDbTowns: { [key: string]: string } = {
Alcudia: "L'Alcúdia",
Guadasuar: 'Guadassuar',
València: 'Valencia',
Almusafes: 'Almussafes',
Montroi: 'Montroy',
};

const GOOGLE_URL = `https://maps.googleapis.com/maps/api/geocode/json?key=${process.env.API_KEY}&latlng=`;
Expand Down
55 changes: 33 additions & 22 deletions src/app/solicitar-ayuda/_components/Form/FormContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
'use client';

import React, { useCallback, useMemo, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useState } from 'react';

import { FormRenderer } from './FormRenderer';
import { FormData, Status } from '../types';
import { formatPhoneNumber, isValidPhone } from '@/helpers/utils';
import { helpRequestService, locationService, townService } from '@/lib/service';
import { helpRequestService } from '@/lib/service';
import { Database } from '@/types/database';
import { Enums } from '@/types/common';
import { useRouter } from 'next/navigation';

import { TIPOS_DE_AYUDA, TIPOS_DE_AYUDA_MAP } from '../constants';
import { useSession } from '@/context/SessionProvider';
import { LngLat } from '@/components/map/GeolocationMap';

const mapHelpToEnum = (helpTypeMap: FormData['tiposDeAyuda']): Enums['help_type_enum'][] =>
Array.from(helpTypeMap).reduce(
Expand All @@ -34,7 +33,8 @@ export function FormContainer() {
const session = useSession();

const [formData, setFormData] = useState<FormData>({
nombre: session?.user?.user_metadata?.full_name || '',
nombre: session?.user?.user_metadata?.full_name.split(" ")[0]|| '',
ubicacion: '',
coordinates: null,
tiposDeAyuda: new Map(TIPOS_DE_AYUDA.map(({ id }) => [id, false])),
numeroDePersonas: undefined,
Expand All @@ -43,9 +43,18 @@ export function FormContainer() {
situacionEspecial: '',
contacto: session?.user?.user_metadata?.telefono || '',
consentimiento: false,
pueblo: '',
email: session?.user?.user_metadata?.email || '',
});

useEffect(() => {
console.log('Component mounted');
}, []);

useEffect(() => {
console.log('formData changed: ', formData);
}, [formData]);

const [status, setStatus] = useState<Status>({
isSubmitting: false,
error: null,
Expand All @@ -57,8 +66,8 @@ export function FormContainer() {
e.preventDefault();

/* Form validation */
if (!formData.coordinates) {
alert('Elige una ubicacion valida');
if (!formData.ubicacion) {
alert('La ubicación es un campo obligatorio');
return;
}

Expand All @@ -80,20 +89,12 @@ export function FormContainer() {
setStatus({ isSubmitting: true, error: null, success: false });

try {
const latitude = String(formData.coordinates.lat);
const longitude = String(formData.coordinates.lng);

const { address, town } = await locationService.getFormattedAddress(longitude, latitude);

const { data: townResponse, error: townError } = await townService.createIfNotExists(town);
if (townError) throw townError;

const helpRequestData: Database['public']['Tables']['help_requests']['Insert'] = {
type: 'necesita',
name: formData.nombre,
location: address,
latitude: formData.coordinates ? parseFloat(latitude) : null,
longitude: formData.coordinates ? parseFloat(longitude) : null,
name: formData.nombre.split(" ")[0],
location: formData.ubicacion,
latitude: formData.coordinates ? parseFloat(formData.coordinates.lat) : null,
longitude: formData.coordinates ? parseFloat(formData.coordinates.lng) : null,
help_type: mapHelpToEnum(formData.tiposDeAyuda),
description: formData.descripcion,
urgency: formData.urgencia,
Expand All @@ -104,7 +105,7 @@ export function FormContainer() {
consent: true,
email: formData.email,
},
town_id: townResponse[0].id,
town_id: parseInt(formData.pueblo),
status: 'active',
};

Expand All @@ -113,13 +114,15 @@ export function FormContainer() {
// Limpiar formulario
setFormData({
nombre: '',
ubicacion: '',
coordinates: null,
tiposDeAyuda: new Map(),
numeroDePersonas: undefined,
descripcion: '',
urgencia: 'alta',
situacionEspecial: '',
contacto: '',
pueblo: '',
consentimiento: false,
email: '',
});
Expand Down Expand Up @@ -163,11 +166,18 @@ export function FormContainer() {
}));
}, []);

const handleCoordinatesChange = useCallback((lngLat: LngLat) => {
const handleAddressSelection = useCallback((address: any) => {
setFormData((formData) => ({
...formData,
coordinates: lngLat ?? null,
ubicacion: address.fullAddress,
coordinates: address.coordinates
? {
lat: address.coordinates.lat,
lng: address.coordinates.lon,
}
: null,
}));
console.log('address: ', address);
}, []);

const handlePhoneChange = useCallback((phoneNumber: string) => {
Expand Down Expand Up @@ -200,13 +210,14 @@ export function FormContainer() {
isUserLoggedIn={Boolean(session?.user)}
handleConsentChange={handleInputElementChange}
handleEmailChange={handleInputElementChange}
handleCoordinatesChange={handleCoordinatesChange}
handleAddressSelection={handleAddressSelection}
handleDescriptionChange={handleTextAreaElementChange}
handleNameChange={handleInputElementChange}
handleNumberPeopleChange={handleInputElementChange}
handlePhoneChange={handlePhoneChange}
handleSituacionEspecialChange={handleTextAreaElementChange}
handleTipoAyudaChange={handleHelpTypeChange}
handleTownChange={handleSelectElementChange}
handleUrgencyChange={handleSelectElementChange}
handleSubmit={handleSubmit}
status={status}
Expand Down
35 changes: 22 additions & 13 deletions src/app/solicitar-ayuda/_components/Form/FormRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import React from 'react';
import { Check } from 'lucide-react';

import { PhoneInput } from '@/components/PhoneInput';
import AddressAutocomplete from '@/components/AddressAutocomplete.js';
import { TIPOS_DE_AYUDA } from '../constants';
import { TipoDeAyudaInputRenderer } from '../TipoDeAyudaInputRenderer';
import { FormData, HelpCategory, Status } from '../types';
import AddressMap from '../../../../components/AddressMap';
import { LngLat } from '@/components/map/GeolocationMap';
import { TownSelector } from '../TownSelector';

type FormRendererProps = {
status: Status;
Expand All @@ -16,10 +16,11 @@ type FormRendererProps = {
selectedHelp: Map<HelpCategory['id'], boolean>;
handleSubmit: React.FormEventHandler<HTMLFormElement>;
handlePhoneChange: (phoneNumber: string) => void;
handleCoordinatesChange: (lngLat: LngLat) => void;
handleAddressSelection: (address: string) => void;
handleSituacionEspecialChange: React.ChangeEventHandler<HTMLTextAreaElement>;
handleUrgencyChange: React.ChangeEventHandler<HTMLSelectElement>;
handleDescriptionChange: React.ChangeEventHandler<HTMLTextAreaElement>;
handleTownChange: React.ChangeEventHandler<HTMLSelectElement>;
handleTipoAyudaChange: React.ChangeEventHandler<HTMLInputElement>;
handleNameChange: React.ChangeEventHandler<HTMLInputElement>;
handleEmailChange: React.ChangeEventHandler<HTMLInputElement>;
Expand All @@ -33,10 +34,11 @@ export function FormRenderer({
formData,
isUserLoggedIn,
handlePhoneChange,
handleCoordinatesChange,
handleAddressSelection,
handleSituacionEspecialChange,
handleUrgencyChange,
handleDescriptionChange,
handleTownChange,
handleTipoAyudaChange,
handleNameChange,
handleEmailChange,
Expand Down Expand Up @@ -82,11 +84,23 @@ export function FormRenderer({
className="w-full p-2 border rounded focus:ring-2 focus:ring-green-500 focus:border-green-500"
/>
<p className="mt-1 text-sm text-gray-500">
{isUserLoggedIn
? 'Se utilizará para que puedas eliminar o editar la información de tu solicitud'
{isUserLoggedIn ? 'Se utilizará para que puedas eliminar o editar la información de tu solicitud'
: 'Se utilizará para que puedas actualizar tu solicitud y marcarla como completada. Para realizar cambios, deberás registrarte con el mismo email'}
</p>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Ubicación exacta <span className="text-red-500">*</span>
</label>
<AddressAutocomplete
onSelect={handleAddressSelection}
placeholder="Calle, número, piso, ciudad..."
required
/>
<p className="mt-1 text-sm text-gray-500">
Incluya todos los detalles posibles para poder localizarle (campo obligatorio)
</p>
</div>

<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Tipo de ayuda necesaria</label>
Expand Down Expand Up @@ -152,13 +166,8 @@ export function FormRenderer({
placeholder="Personas mayores, niños pequeños, personas con movilidad reducida, necesidades médicas, mascotas..."
/>
</div>

<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Ubicación exacta <span className="text-red-500">*</span>
</label>
<AddressMap onNewCoordinatesCallback={handleCoordinatesChange} />
</div>
{/* Pueblos */}
<TownSelector handleChange={handleTownChange} selectedTown={formData.pueblo} />

{/* Consentimiento */}
<div className="flex items-start">
Expand Down
5 changes: 3 additions & 2 deletions src/app/solicitar-ayuda/_components/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Town as SupabaseTown } from '@/types/Town';
import { Enums } from '@/types/common';
import { LngLat } from '@/components/map/GeolocationMap';

export type FormData = {
nombre: string;
Expand All @@ -10,8 +9,10 @@ export type FormData = {
descripcion: string;
urgencia: string;
situacionEspecial: string;
pueblo: string;
consentimiento: boolean;
coordinates: LngLat | null;
ubicacion: string;
coordinates: any;
tiposDeAyuda: Map<HelpCategory['id'], boolean>;
};

Expand Down
52 changes: 36 additions & 16 deletions src/components/AddressMap.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,49 @@
'use client';

import GeoLocationMap, { LngLat } from '@/components/map/GeolocationMap';
import { useEffect, useState } from 'react';
import { useState } from 'react';

export type AddressDescriptopr = { address: string; town: string; coordinates: LngLat };
export type AddressAndTownCallback = (addressAndTown: AddressDescriptopr) => void;
export type AddressMapProps = {
onNewCoordinatesCallback: (lngLat: LngLat) => void;
onNewAddressCallback: AddressAndTownCallback;
};

export default function AddressMap({ onNewCoordinatesCallback }: AddressMapProps) {
const [status, setStatus] = useState<PermissionState | 'unknown'>('unknown');
export default function AddressMap({ onNewAddressCallback }: AddressMapProps) {
const [address, setAddress] = useState('');
const [town, setTown] = useState('');

const onNewPosition = async (lngLat: LngLat) => {
if (address !== '') {
return;
}

const response = await fetch('/api/address', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
longitude: lngLat.lng,
latitude: lngLat.lat,
}),
}).then((res) => res.json());

setAddress(response.address);
setTown(response.town);
if (typeof onNewAddressCallback === 'function') {
onNewAddressCallback({ address: response.address, town: response.town, coordinates: lngLat });
}
};

return (
<div className="space-y-2">
{/* Mensaje de error */}
{(status === 'denied' || status === 'prompt') && (
<div className="bg-red-100 border-l-4 border-red-500 p-4 rounded">
<p className="text-red-700">Debes activar la ubicación para que podamos localizarte</p>
</div>
)}
<GeoLocationMap
onPermissionStatusChanged={(permission) => {
setStatus(permission);
}}
onNewPositionCallback={(lngLat) => {}}
onNewCenterCallback={onNewCoordinatesCallback}
<GeoLocationMap onNewPositionCallback={onNewPosition} />
{/* Address */}
<input
disabled
type="text"
value={address}
onChange={(e) => setAddress(e.target.value)}
className="w-full p-2 border rounded focus:ring-2 focus:ring-green-500 focus:border-green-500"
/>
</div>
);
Expand Down
Loading
Loading