diff --git a/package.json b/package.json index 6dc3028..0fe4eca 100644 --- a/package.json +++ b/package.json @@ -14,13 +14,16 @@ "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", "@material-tailwind/react": "^2.1.10", + "@mui/icons-material": "^6.1.6", "@mui/lab": "^6.0.0-beta.10", "@mui/material": "^6.1.2", "@mui/system": "^6.1.2", "@mui/x-date-pickers": "^7.19.0", - "@react-google-maps/api": "^2.19.3", + "@react-google-maps/api": "^2.20.3", "aws-sdk": "^2.1691.0", "axios": "^1.7.7", + "browser-image-compression": "^2.0.2", + "compress.js": "1.1.2", "date-fns": "2.29.3", "react": "^18.3.1", "react-dom": "^18.3.1", diff --git a/src/components/ImageUpload.css b/src/components/ImageUpload.css new file mode 100644 index 0000000..0b277c7 --- /dev/null +++ b/src/components/ImageUpload.css @@ -0,0 +1,43 @@ +.image-upload-container { + max-width: 800px; + margin: 0 auto; + } + + .dropzone { + background-color: #f9fafb; /* Color de fondo más claro */ + transition: background-color 0.2s; + } + + .dropzone:hover { + background-color: #e5e7eb; /* Color de fondo al pasar el mouse */ + } + + .image-preview { + margin-top: 0.5rem; + width: 100%; /* Asegúrate de que ocupe todo el ancho de su contenedor */ + height: 150px; /* Altura fija para todas las imágenes */ + object-fit: cover; /* Mantener la relación de aspecto y recortar si es necesario */ + } + + .font-medium { + padding-left: 10px; + margin-bottom: 70px; + } + .absolute{ + position: absolute; + border: none; + background-color: transparent; + } + .absolute:hover{ + color: #666; + } + .flex{ + display: flex flex-wrap; + } + + + + + + + \ No newline at end of file diff --git a/src/components/ImageUpload2.jsx b/src/components/ImageUpload2.jsx new file mode 100644 index 0000000..dfad842 --- /dev/null +++ b/src/components/ImageUpload2.jsx @@ -0,0 +1,114 @@ +import React, { useState } from 'react'; +import { useDropzone } from 'react-dropzone'; +import DeleteIcon from '@mui/icons-material/Cancel'; +import './ImageUpload.css'; +import logo from '../assets/logoo.png'; +import imageCompression from 'browser-image-compression'; // Importa la nueva librería + +function ImageUpload({ files, setFiles }) { + const [error, setError] = useState(''); + + const onDrop = async acceptedFiles => { + if (acceptedFiles.length + files.length > 5) { + setError('Solo se permiten un máximo de 5 imágenes'); + return; + } + + setError(''); + + const newFiles = await Promise.all( + acceptedFiles.map(async file => { + const options = { + maxSizeMB: 1, // Ajusta el tamaño máximo de la imagen + maxWidthOrHeight: 800, // Cambia el tamaño máximo + useWebWorker: true, + }; + const compressedFile = await imageCompression(file, options); + return Object.assign(compressedFile, { + preview: URL.createObjectURL(compressedFile) + }); + }) + ); + + setFiles(prevFiles => [...prevFiles, ...newFiles]); + }; + + const { getRootProps, getInputProps } = useDropzone({ + onDrop, + accept: 'image/jpeg, image/png', + maxFiles: 5, + maxSize: 5000000 // 5MB + }); + + return ( +
+ +
+
+ +
+
+ + Hasta 5 imágenes en formato PNG o JPG + +
+ +
+ + {/* Aquí es donde renderizamos las imágenes dentro del dropzone */} +
+ {files.map((file, index) => ( +
+ {file.name} + Watermark + +
+ ))} +
+
+
+ + {error &&

{error}

} +
+ ); +} + +export default ImageUpload; diff --git a/src/components/TailwinSvgIcons/CrossDeleteIcon2.jsx b/src/components/TailwinSvgIcons/CrossDeleteIcon2.jsx new file mode 100644 index 0000000..31cca8d --- /dev/null +++ b/src/components/TailwinSvgIcons/CrossDeleteIcon2.jsx @@ -0,0 +1,19 @@ +export default function CrossDeleteIcon() { + return ( + + + + ); + } + \ No newline at end of file diff --git a/src/pages/users/publicar.jsx b/src/pages/users/publicar.jsx index f9ca89a..9497f01 100644 --- a/src/pages/users/publicar.jsx +++ b/src/pages/users/publicar.jsx @@ -3,7 +3,7 @@ import { Stepper, Step, StepLabel, Button, Typography, Box, Tab, Tabs, FormHelpe import { Link } from 'react-router-dom'; import Navbar from '../../components/Navbar'; import Footer from '../../components/Footer'; -import ImageUpload from '../../components/ImageUpload'; +import ImageUpload from '../../components/ImageUpload2'; import TurismoForm from './zturismo.jsx'; import CentrosDeportivosForm from './zcentros.jsx'; import EventosForm from './zeventos.jsx'; diff --git a/src/pages/users/zcamping.jsx b/src/pages/users/zcamping.jsx new file mode 100644 index 0000000..a3270d4 --- /dev/null +++ b/src/pages/users/zcamping.jsx @@ -0,0 +1,440 @@ +import '../../styles/users/zhospedaje.css'; +import { useState, useEffect } from 'react'; +import PropTypes from 'prop-types'; +import { + TextField, + MenuItem, + FormControl, + InputLabel, + Select, + Button, + Checkbox, + FormControlLabel, + Grid, + Typography, +} from '@mui/material'; +//------------new +import { GoogleMap, LoadScript, Marker } from '@react-google-maps/api'; // Importar componentes de Google Maps +const mapContainerStyle = { + height: "400px", + width: "100%" +}; + +const center = { + lat: -33.4489, // Cambia esto a la latitud de tu ubicación inicial + lng: -70.6693 // Cambia esto a la longitud de tu ubicación inicial +}; +//-----------new + + +const subcategories = [ + { label: 'Arriendo', value: 'arriendo' }, + { label: 'Cabaña', value: 'cabaña' }, + { label: 'Departamento', value: 'departamento' }, + { label: 'Casa', value: 'casa' }, + { label: 'Hospedaje', value: 'hospedaje' }, + { label: 'Hotel', value: 'hotel' } +]; + +function HospedajeForm({ onNext }) { + //-----------new + const [markerPosition, setMarkerPosition] = useState(center); // Estado para la posición del marcador + const [userLocation, setUserLocation] = useState(null); // Estado para la ubicación del usuario + + const handleMapClick = async (event) => { + const lat = event.latLng.lat(); + const lng = event.latLng.lng(); + setMarkerPosition({ lat, lng }); // Actualiza la posición del marcador + // Aquí puedes agregar lógica para convertir las coordenadas en una dirección si lo deseas + //const address = await getAddressFromLatLng(lat, lng); //new + setFormData((prev) => ({ ...prev, ubicacion: `Lat: ${lat}, Lng: ${lng}` })); // Actualiza el campo de ubicación + }; + + useEffect(() => { + // Obtener ubicación actual del usuario + if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition(position => { + const newLocation = { + lat: position.coords.latitude, + lng: position.coords.longitude, + }; + setUserLocation(newLocation); + setMarkerPosition(newLocation); + //setFormData(prev => ({ ...prev, ubicacion: address })); //new + setFormData(prev => ({ ...prev, ubicacion: `Lat: ${position.coords.latitude}, Lng: ${position.coords.longitude}` })); + }, () => { + alert("No se pudo obtener la ubicación."); + }); + } else { + alert("Geolocalización no es soportada en este navegador."); + } + }, []); + + /*const getAddressFromLatLng = async (lat, lng) => { + const apiKey = "AIzaSyAJuzF9SX5VP6CU38hq-lgRopJ66jYgb5E"; // Reemplaza con tu API key + const response = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${apiKey}`); + const data = await response.json(); + if (data.results && data.results.length > 0) { + return data.results[0].formatted_address; // Retorna la primera dirección formateada + } else { + return ''; // Retorna vacío si no se encuentra dirección + } + };*/ + //-----------new + + const [formData, setFormData] = useState({ + subcategoria: '', + titulo: '', + descripcion: '', + ubicacion: '', + numeroUbicacion: '', + dormitorios: '', + camasSimples: '', + camasDobles: '', + cantidadMinima: '', + cantidadMaxima: '', + nombreContacto: '', + celularContacto: '', + mailContacto: '', + instagram: '', + facebook: '', + paginaWeb: '', + precioPorNoche: '', + disponible: false, + incluyeDesayuno: false, + incluyeToallasSabanas: false + }); + + const [errors, setErrors] = useState({}); + + + const handleInputChange = (field, value) => { + setFormData(prev => ({ ...prev, [field]: value })); + if (errors[name]) { + setErrors((prevErrors) => ({ ...prevErrors, [name]: undefined })); + } + //setErrors(prev => ({ ...prev, [field]: '' })); // Reset error when value changes + }; + + const validateForm = () => { + const newErrors = {}; + + if (!formData.subcategoria) {newErrors.subcategoria = 'Selecciona un tipo de acomodación.';} + if (!formData.titulo) {newErrors.titulo = 'Escribe un título.';} + if (!formData.descripcion) {newErrors.descripcion = 'Escribe una descripción.';} + if (!formData.ubicacion) { + newErrors.ubicacion = 'Escribe una ubicación (Ej: Calle 123, Comuna, Ciudad).'; + } else if (!/^[\w\s,.-]+$/.test(formData.ubicacion)) { // Simple regex for address format + newErrors.ubicacion = 'Debes seguir el formato de dirección: Calle 123, Comuna, Ciudad.'; + } + + if (!formData.dormitorios) {newErrors.dormitorios = 'Ingresa cantidad de dormitorios.';} + if (!formData.camasSimples) {newErrors.camasSimples = 'Ingresa cantidad de camas simples.';} + if (!formData.camasDobles) {newErrors.camasDobles = 'Ingresa cantidad de camas dobles.';} + if (!formData.cantidadMaxima) {newErrors.cantidadMaxima = 'Ingresa cantidad máxima de personas para la acomodación.';} + if (!formData.cantidadMinima) {newErrors.cantidadMinima = 'Ingresa cantidad mínima de personas para la acomodación.';} + + if (!formData.celularContacto && !formData.mailContacto) { + newErrors.contacto = 'Debes incluir al menos el número de celular de contacto o el mail de contacto.'; + } else { + if (formData.celularContacto && !/^\d+$/.test(formData.celularContacto)) { // Validar que solo incluya números + newErrors.celularContacto = 'El número de celular debe contener solo números. Ej: 9 8765 4321.'; + } + if (formData.mailContacto && !/^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/.test(formData.mailContacto)) { // Simple regex for email + newErrors.mailContacto = 'Escribir el email en su debido formato. Ej: usuario@dominio.com'; + } + } + if (!formData.precioPorNoche) { + newErrors.precioPorNoche = 'Se debe escribir un precio por noche.'; + } + if (formData.paginaWeb && !/^(https?:\/\/)?([\w\-]+\.)+[\w\-]{2,4}(\/[\w\-\.]*)*$/.test(formData.paginaWeb)) { + newErrors.paginaWeb = 'Debes escribir en el formato indicado de página web. Ej: https://www.ejemplo.com'; + } + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; + + //const handleSubmit = (e) => { + // e.preventDefault(); + // if (validateForm()) { + // console.log('Formulario válido, proceder...'); + // handleNext(); + //} else { + // console.log('Errores en el formulario:', errors); + //} + //} + const handleSubmit = (event) => { + event.preventDefault(); + if (validateForm()) { + // Aquí puedes manejar la lógica de envío del formulario + // Luego, llama a onNext para avanzar al siguiente paso + onNext();} else { + console.log('Errores en el formulario:', errors); + } +}; + + + + return ( +
+

Propiedad

+

Ingresa la información de tu publicación

+ + + + Tipo de Acomodación + + {errors.subcategoria && {errors.subcategoria} || 'Campo Obligatorio'} + + + + handleInputChange('titulo', e.target.value)} + margin="normal" + error={Boolean(errors.titulo)} + helperText={errors.titulo|| 'Campo Obligatorio'} + /> + + handleInputChange('descripcion', e.target.value)} + margin="normal" + multiline + rows={4} + error={Boolean(errors.descripcion)} + helperText={errors.descripcion|| 'Campo Obligatorio'} + /> + +
+ handleInputChange('ubicacion', e.target.value)} + margin="normal" + error={Boolean(errors.ubicacion)} + helperText={errors.ubicacion|| 'Campo Obligatorio'} + /> + + handleInputChange('ubicacion', e.target.value)} + margin="normal" + /> +
+ + {/* Reemplaza con tu API key */} + + {/* Muestra un marcador en la posición seleccionada */} + + + + +
+ handleInputChange('cantidadMinima', e.target.value)} + margin="normal" + error={Boolean(errors.cantidadMinima)} + helperText={errors.cantidadMinima|| 'Campo Obligatorio'} + /> + + handleInputChange('cantidadMaxima', e.target.value)} + margin="normal" + error={Boolean(errors.cantidadMaxima)} + helperText={errors.cantidadMaxima|| 'Campo Obligatorio'} + /> +
+ +
+ handleInputChange('dormitorios', e.target.value)} + error={Boolean(errors.dormitorios)} + helperText={errors.dormitorios|| 'Campo Obligatorio'} + /> + + handleInputChange('camasSimples', e.target.value)} + margin="normal" + error={Boolean(errors.camasSimples)} + helperText={errors.camasSimples|| 'Campo Obligatorio'} + /> + + handleInputChange('camasDobles', e.target.value)} + margin="normal" + error={Boolean(errors.camasDobles)} + helperText={errors.camasDobles|| 'Campo Obligatorio'} + /> +
+ + + +
+ handleInputChange('nombreContacto', e.target.value)} + margin="normal" + /> + + handleInputChange('celularContacto', e.target.value)} + margin="normal" + type = "number" + error={Boolean(errors.celularContacto)} + helperText={errors.celularContacto} + /> + + handleInputChange('mailContacto', e.target.value)} + margin="normal" + error={Boolean(errors.mailContacto)} + helperText={errors.mailContacto} + /> +
+ + {errors.contacto && {errors.contacto} || 'Incluir al menos el número de celular o mail de contacto'} {/* Mensaje de error de contacto */} + +
+ handleInputChange('instagram', e.target.value)} + margin="normal" + /> + + handleInputChange('facebook', e.target.value)} + margin="normal" + /> + + handleInputChange('paginaWeb', e.target.value)} + margin="normal" + error={Boolean(errors.paginaWeb)} + helperText={errors.paginaWeb} + /> +
+ + handleInputChange('precioPorNoche', e.target.value)} + margin="normal" + error={Boolean(errors.precioPorNoche)} + helperText={errors.precioPorNoche|| 'Campo Obligatorio'} + /> + +
+ handleInputChange('disponible', e.target.checked)} + className='checkboxs-orange' + /> + } + label="Actualmente Disponible" + /> + + handleInputChange('incluyeDesayuno', e.target.checked)} + className='checkboxs-orange' + /> + } + label="Incluye Desayuno" + /> + + handleInputChange('incluyeToallasSabanas', e.target.checked)} + className='checkboxs-orange' + /> + } + label="Incluye Toallas y Sábanas" + /> +
+ + + + + + ); +} + +/*HospedajeForm.propTypes = { + handleNext: PropTypes.func.isRequired, +};*/ + +HospedajeForm.propTypes = { + onNext: PropTypes.func.isRequired, +}; +export default HospedajeForm; \ No newline at end of file diff --git a/src/pages/users/zhospedaje.jsx b/src/pages/users/zhospedaje.jsx index 5876326..a3270d4 100644 --- a/src/pages/users/zhospedaje.jsx +++ b/src/pages/users/zhospedaje.jsx @@ -13,6 +13,19 @@ import { Grid, Typography, } from '@mui/material'; +//------------new +import { GoogleMap, LoadScript, Marker } from '@react-google-maps/api'; // Importar componentes de Google Maps +const mapContainerStyle = { + height: "400px", + width: "100%" +}; + +const center = { + lat: -33.4489, // Cambia esto a la latitud de tu ubicación inicial + lng: -70.6693 // Cambia esto a la longitud de tu ubicación inicial +}; +//-----------new + const subcategories = [ { label: 'Arriendo', value: 'arriendo' }, @@ -24,6 +37,51 @@ const subcategories = [ ]; function HospedajeForm({ onNext }) { + //-----------new + const [markerPosition, setMarkerPosition] = useState(center); // Estado para la posición del marcador + const [userLocation, setUserLocation] = useState(null); // Estado para la ubicación del usuario + + const handleMapClick = async (event) => { + const lat = event.latLng.lat(); + const lng = event.latLng.lng(); + setMarkerPosition({ lat, lng }); // Actualiza la posición del marcador + // Aquí puedes agregar lógica para convertir las coordenadas en una dirección si lo deseas + //const address = await getAddressFromLatLng(lat, lng); //new + setFormData((prev) => ({ ...prev, ubicacion: `Lat: ${lat}, Lng: ${lng}` })); // Actualiza el campo de ubicación + }; + + useEffect(() => { + // Obtener ubicación actual del usuario + if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition(position => { + const newLocation = { + lat: position.coords.latitude, + lng: position.coords.longitude, + }; + setUserLocation(newLocation); + setMarkerPosition(newLocation); + //setFormData(prev => ({ ...prev, ubicacion: address })); //new + setFormData(prev => ({ ...prev, ubicacion: `Lat: ${position.coords.latitude}, Lng: ${position.coords.longitude}` })); + }, () => { + alert("No se pudo obtener la ubicación."); + }); + } else { + alert("Geolocalización no es soportada en este navegador."); + } + }, []); + + /*const getAddressFromLatLng = async (lat, lng) => { + const apiKey = "AIzaSyAJuzF9SX5VP6CU38hq-lgRopJ66jYgb5E"; // Reemplaza con tu API key + const response = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${apiKey}`); + const data = await response.json(); + if (data.results && data.results.length > 0) { + return data.results[0].formatted_address; // Retorna la primera dirección formateada + } else { + return ''; // Retorna vacío si no se encuentra dirección + } + };*/ + //-----------new + const [formData, setFormData] = useState({ subcategoria: '', titulo: '', @@ -116,15 +174,7 @@ function HospedajeForm({ onNext }) { } }; - // - const handleNext = () => { - if (validateForm()) { - onNext(); // Llama a la función para ir al siguiente paso si es válido - } - }; - // - - + return (
@@ -182,6 +232,7 @@ function HospedajeForm({ onNext }) { error={Boolean(errors.ubicacion)} helperText={errors.ubicacion|| 'Campo Obligatorio'} /> + + {/* Reemplaza con tu API key */} + + {/* Muestra un marcador en la posición seleccionada */} + + +
handleInputChange('disponible', e.target.checked)} + className='checkboxs-orange' /> } label="Actualmente Disponible" @@ -342,6 +405,7 @@ function HospedajeForm({ onNext }) { handleInputChange('incluyeDesayuno', e.target.checked)} + className='checkboxs-orange' /> } label="Incluye Desayuno" @@ -352,6 +416,7 @@ function HospedajeForm({ onNext }) { handleInputChange('incluyeToallasSabanas', e.target.checked)} + className='checkboxs-orange' /> } label="Incluye Toallas y Sábanas" @@ -365,7 +430,11 @@ function HospedajeForm({ onNext }) { ); } -HospedajeForm.propTypes = { +/*HospedajeForm.propTypes = { handleNext: PropTypes.func.isRequired, +};*/ + +HospedajeForm.propTypes = { + onNext: PropTypes.func.isRequired, }; export default HospedajeForm; \ No newline at end of file diff --git a/src/styles/users/zhospedaje.css b/src/styles/users/zhospedaje.css index b5f1210..6402f29 100644 --- a/src/styles/users/zhospedaje.css +++ b/src/styles/users/zhospedaje.css @@ -55,4 +55,3 @@ html, body { align-items: flex-start; /* Alinea los campos en la parte superior */ gap: 16px; /* Espacio entre los campos */ } - diff --git a/yarn.lock b/yarn.lock index a58c90d..224e621 100644 --- a/yarn.lock +++ b/yarn.lock @@ -169,6 +169,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.26.0.tgz#8600c2f595f277c60815256418b85356a65173c1" + integrity sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.25.7": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.7.tgz#27f69ce382855d915b14ab0fe5fb4cbf88fa0769" @@ -535,12 +542,10 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.8.tgz#21a907684723bbbaa5f0974cf7730bd797eb8e62" integrity sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig== -"@googlemaps/js-api-loader@1.16.2": - version "1.16.2" - resolved "https://registry.yarnpkg.com/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz#3fe748e21243f8e8322c677a5525c569ae9cdbe9" - integrity sha512-psGw5u0QM6humao48Hn4lrChOM2/rA43ZCm3tKK9qQsEj1/VzqkCqnvGfEOshDbBQflydfaRovbKwZMF4AyqbA== - dependencies: - fast-deep-equal "^3.1.3" +"@googlemaps/js-api-loader@1.16.8": + version "1.16.8" + resolved "https://registry.yarnpkg.com/@googlemaps/js-api-loader/-/js-api-loader-1.16.8.tgz#1595a2af80ca07e551fc961d921a2437d1cb3643" + integrity sha512-CROqqwfKotdO6EBjZO/gQGVTbeDps5V7Mt9+8+5Q+jTg5CRMi3Ii/L9PmV3USROrt2uWxtGzJHORmByxyo9pSQ== "@googlemaps/markerclusterer@2.5.3": version "2.5.3" @@ -691,6 +696,13 @@ resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-6.1.2.tgz#a15eb14d433100f734e56929f842c2ccc7cab691" integrity sha512-1oE4U38/TtzLWRYWEm/m70dUbpcvBx0QvDVg6NtpOmSNQC1Mbx0X/rNvYDdZnn8DIsAiVQ+SZ3am6doSswUQ4g== +"@mui/icons-material@^6.1.6": + version "6.1.6" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-6.1.6.tgz#bfaf32874a9f9ec88c07d1ca132d1a0671e9ed7c" + integrity sha512-5r9urIL2lxXb/sPN3LFfFYEibsXJUb986HhhIeu1gOcte460pwdSiEhBSxkAuyT8Dj7jvu9MjqSBmSumQELo8A== + dependencies: + "@babel/runtime" "^7.26.0" + "@mui/lab@^6.0.0-beta.10": version "6.0.0-beta.10" resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-6.0.0-beta.10.tgz#cf6dce21e8491aa00facc0d6b1cd357bfb2ed58e" @@ -823,27 +835,27 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== -"@react-google-maps/api@^2.19.3": - version "2.19.3" - resolved "https://registry.yarnpkg.com/@react-google-maps/api/-/api-2.19.3.tgz#6bb307c6e9d06344badd77facb6dc9eaac5b9b32" - integrity sha512-jiLqvuOt5lOowkLeq7d077AByTyJp+s6hZVlLhlq7SBacBD37aUNpXBz2OsazfeR6Aw4a+9RRhAEjEFvrR1f5A== +"@react-google-maps/api@^2.20.3": + version "2.20.3" + resolved "https://registry.yarnpkg.com/@react-google-maps/api/-/api-2.20.3.tgz#0d30e6753d7cddc34f2cd9cc7c5a5a7460adb438" + integrity sha512-ndXC8nZDPT78nCceZnftGSvA/iVhwx2XhlfEYaoUy2biGelhrE2vDzjyTuZhb4RV+bVYpd4LkIf3hzyxAFd+Qg== dependencies: - "@googlemaps/js-api-loader" "1.16.2" + "@googlemaps/js-api-loader" "1.16.8" "@googlemaps/markerclusterer" "2.5.3" - "@react-google-maps/infobox" "2.19.2" - "@react-google-maps/marker-clusterer" "2.19.2" - "@types/google.maps" "3.55.2" + "@react-google-maps/infobox" "2.20.0" + "@react-google-maps/marker-clusterer" "2.20.0" + "@types/google.maps" "3.58.1" invariant "2.2.4" -"@react-google-maps/infobox@2.19.2": - version "2.19.2" - resolved "https://registry.yarnpkg.com/@react-google-maps/infobox/-/infobox-2.19.2.tgz#b6bda962a4fa1074fdd3dfd63bc4c7d68b1dd745" - integrity sha512-6wvBqeJsQ/eFSvoxg+9VoncQvNoVCdmxzxRpLvmjPD+nNC6mHM0vJH1xSqaKijkMrfLJT0nfkTGpovrF896jwg== +"@react-google-maps/infobox@2.20.0": + version "2.20.0" + resolved "https://registry.yarnpkg.com/@react-google-maps/infobox/-/infobox-2.20.0.tgz#7c3dd1821c9f1e1e92570f37419b97f6f956c7ee" + integrity sha512-03PJHjohhaVLkX6+NHhlr8CIlvUxWaXhryqDjyaZ8iIqqix/nV8GFdz9O3m5OsjtxtNho09F/15j14yV0nuyLQ== -"@react-google-maps/marker-clusterer@2.19.2": - version "2.19.2" - resolved "https://registry.yarnpkg.com/@react-google-maps/marker-clusterer/-/marker-clusterer-2.19.2.tgz#24d9fb9aa555bb063ba5fe82f80fcd7d48662184" - integrity sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw== +"@react-google-maps/marker-clusterer@2.20.0": + version "2.20.0" + resolved "https://registry.yarnpkg.com/@react-google-maps/marker-clusterer/-/marker-clusterer-2.20.0.tgz#6b64177843a60c66e0ebaf85037a47ecd07007df" + integrity sha512-tieX9Va5w1yP88vMgfH1pHTacDQ9TgDTjox3tLlisKDXRQWdjw+QeVVghhf5XqqIxXHgPdcGwBvKY6UP+SIvLw== "@remix-run/router@1.19.2": version "1.19.2" @@ -968,10 +980,10 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== -"@types/google.maps@3.55.2": - version "3.55.2" - resolved "https://registry.yarnpkg.com/@types/google.maps/-/google.maps-3.55.2.tgz#6e5a1c257aeda3861a919a56fb9f369468e79e15" - integrity sha512-JcTwzkxskR8DN/nnX96Pie3gGN3WHiPpuxzuQ9z3516o1bB243d8w8DHUJ8BohuzoT1o3HUFta2ns/mkZC8KRw== +"@types/google.maps@3.58.1": + version "3.58.1" + resolved "https://registry.yarnpkg.com/@types/google.maps/-/google.maps-3.58.1.tgz#71ce3dec44de1452f56641d2c87c7dd8ea964b4d" + integrity sha512-X9QTSvGJ0nCfMzYOnaVs/k6/4L+7F5uCS+4iUmkLEls6J9S/Phv+m/i3mDeyc49ZBgwab3EFO1HEoBY7k98EGQ== "@types/json-schema@^7.0.15": version "7.0.15" @@ -1213,6 +1225,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +browser-image-compression@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/browser-image-compression/-/browser-image-compression-2.0.2.tgz#4d5ef8882e9e471d6d923715ceb9034499d14eaa" + integrity sha512-pBLlQyUf6yB8SmmngrcOw3EoS4RpQ1BcylI3T9Yqn7+4nrQTXJD4sJDe5ODnJdrvNMaio5OicFo75rDyJD2Ucw== + dependencies: + uzip "0.20201231.0" + browserslist@^4.24.0: version "4.24.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.0.tgz#a1325fe4bc80b64fda169629fc01b3d6cecd38d4" @@ -1311,6 +1330,11 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +compress.js@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/compress.js/-/compress.js-1.1.2.tgz#2c19528a017b7d500673f2df69e66b04074d1464" + integrity sha512-92bBngXANtmZpyBqO7E5nQMt6TOJtso8FO5fEx85WeF2t/CDAxs8K+KSu8EuLGMZWWMOdxvFf/bsXG7rOPmAyw== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -3040,6 +3064,11 @@ uuid@8.0.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.0.0.tgz#bc6ccf91b5ff0ac07bbcdbf1c7c4e150db4dbb6c" integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw== +uzip@0.20201231.0: + version "0.20201231.0" + resolved "https://registry.yarnpkg.com/uzip/-/uzip-0.20201231.0.tgz#9e64b065b9a8ebf26eb7583fe8e77e1d9a15ed14" + integrity sha512-OZeJfZP+R0z9D6TmBgLq2LHzSSptGMGDGigGiEe0pr8UBe/7fdflgHlHBNDASTXB5jnFuxHpNaJywSg8YFeGng== + vite@^5.4.8: version "5.4.8" resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.8.tgz#af548ce1c211b2785478d3ba3e8da51e39a287e8"