From bcd47dbdc5386269a578edb9cc704e1c2059e7a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Loureiro?= Date: Wed, 11 Jun 2025 18:32:34 -0300 Subject: [PATCH] feat: implement CreateOrphanage and Orphanage pages with map integration and styling --- web/src/images/map_marker.svg | 6 + web/src/pages/CreateOrphanage.tsx | 210 ++++++++++++++++++++++++++++ web/src/pages/Orphanage.tsx | 150 ++++++++++++++++++++ web/src/styles/create-orphanage.css | 175 +++++++++++++++++++++++ web/src/styles/orphanage.css | 168 ++++++++++++++++++++++ 5 files changed, 709 insertions(+) create mode 100644 web/src/images/map_marker.svg create mode 100644 web/src/pages/CreateOrphanage.tsx create mode 100644 web/src/pages/Orphanage.tsx create mode 100644 web/src/styles/create-orphanage.css create mode 100644 web/src/styles/orphanage.css diff --git a/web/src/images/map_marker.svg b/web/src/images/map_marker.svg new file mode 100644 index 0000000..4289ae7 --- /dev/null +++ b/web/src/images/map_marker.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/web/src/pages/CreateOrphanage.tsx b/web/src/pages/CreateOrphanage.tsx new file mode 100644 index 0000000..1033e2b --- /dev/null +++ b/web/src/pages/CreateOrphanage.tsx @@ -0,0 +1,210 @@ +import React, { useState, FormEvent, ChangeEvent } from "react"; +import { useNavigate } from "react-router-dom"; +import { FiPlus } from "react-icons/fi"; +import { GoogleMap, useJsApiLoader, Marker } from '@react-google-maps/api'; +import { toast } from 'react-toastify'; + +import mapMarkerImg from '../images/map_marker.svg'; +import '../styles/create-orphanage.css'; +import Sidebar from "../components/Sidebar"; +import api from "../services/api"; + +export default function CreateOrphanage() { + const { isLoaded } = useJsApiLoader({ + id: 'google-map-script', + googleMapsApiKey: process.env.REACT_APP_MAPS_API_KEY! + }); + + const navigate = useNavigate(); + + const [position, setPosition] = useState({ lat: 0, lng: 0 }); + const [name, setName] = useState(''); + const [about, setAbout] = useState(''); + const [instructions, setInstructions] = useState(''); + const [opening_hours, setOpeningHours] = useState(''); + const [open_on_weekends, setOpenOnWeekends] = useState(true); + const [phone, setPhone] = useState(''); + const [images, setImages] = useState([]); + const [previewImages, setPreviewImages] = useState([]); + + function handleMapClick(event: google.maps.MapMouseEvent) { + const { latLng } = event; + if (latLng) { + setPosition({ + lat: latLng.lat(), + lng: latLng.lng(), + }); + } + } + + function handleSelectImages(event: ChangeEvent) { + if (!event.target.files) { + return; + } + const selectedImages = Array.from(event.target.files); + setImages(selectedImages); + + const selectedImagesPreview = selectedImages.map(image => { + return URL.createObjectURL(image); + }); + + setPreviewImages(selectedImagesPreview); + } + + async function handleSubmit(event: FormEvent) { + event.preventDefault(); + + if (!name.trim()) { + toast.error('O campo "Nome" é obrigatório.'); + return; + } + if (!about.trim()) { + toast.error('O campo "Sobre" é obrigatório.'); + return; + } + if (!opening_hours.trim()) { + toast.error('O campo "Horário de funcionamento" é obrigatório.'); + return; + } + if (position.lat === 0) { + toast.error('Por favor, selecione a localização do orfanato no mapa.'); + return; + } + if (images.length === 0) { + toast.error('Por favor, adicione pelo menos uma foto do orfanato.'); + return; + } + if (!phone.trim()) { + toast.error('O campo "Número de Whatsapp" é obrigatório.'); + return; + } + + const { lat, lng } = position; + + const data = new FormData(); + data.append('name', name); + data.append('about', about); + data.append('latitude', String(lat)); + data.append('longitude', String(lng)); + data.append('instructions', instructions); + data.append('opening_hours', opening_hours); + data.append('open_on_weekends', String(open_on_weekends)); + data.append('phone', phone); + + images.forEach(image => { + data.append('images', image); + }); + + try { + await api.post('orphanages', data); + toast.success('Cadastro realizado com sucesso!'); + navigate('/app'); + } catch (error) { + toast.error('Erro ao realizar o cadastro. Tente novamente.'); + console.error('Failed to create orphanage:', error); + } + } + + if (!isLoaded) { + return
Loading Map...
; + } + + return ( +
+ +
+
+
+ Dados + + + {position.lat !== 0 && ( + + )} + + +
+ + setName(e.target.value)} /> +
+ +
+ +