From 2682bfb9c113a0b9be61826195a59a30c2ff853f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Loureiro?= Date: Wed, 11 Jun 2025 18:32:20 -0300 Subject: [PATCH] feat: add sidebar, landing page, orphanages map, and API service with styles --- web/src/components/Sidebar.tsx | 22 +++++ web/src/pages/landing-page.tsx | 32 ++++++++ web/src/pages/orphanages-page.tsx | 112 ++++++++++++++++++++++++++ web/src/services/api.ts | 7 ++ web/src/styles/components/sidebar.css | 39 +++++++++ web/src/styles/orphanages.css | 109 +++++++++++++++++++++++++ 6 files changed, 321 insertions(+) create mode 100644 web/src/components/Sidebar.tsx create mode 100644 web/src/pages/landing-page.tsx create mode 100644 web/src/pages/orphanages-page.tsx create mode 100644 web/src/services/api.ts create mode 100644 web/src/styles/components/sidebar.css create mode 100644 web/src/styles/orphanages.css diff --git a/web/src/components/Sidebar.tsx b/web/src/components/Sidebar.tsx new file mode 100644 index 0000000..e8375a0 --- /dev/null +++ b/web/src/components/Sidebar.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import { FiArrowLeft } from 'react-icons/fi'; +import { useNavigate } from 'react-router-dom'; // Changed from useHistory +import mapMarkerImg from '../images/map_marker.svg'; + +import '../styles/components/sidebar.css'; + +export default function Sidebar () { + const navigate = useNavigate(); // Changed from useHistory + + return ( + + ) +} \ No newline at end of file diff --git a/web/src/pages/landing-page.tsx b/web/src/pages/landing-page.tsx new file mode 100644 index 0000000..c87a35c --- /dev/null +++ b/web/src/pages/landing-page.tsx @@ -0,0 +1,32 @@ +import { FiArrowRight } from 'react-icons/fi'; +import { Link } from 'react-router-dom'; + +import '../styles/landing-page.css'; + +import logoimg from '../images/logo.svg'; + +function LandingPage() { + return ( +
+
+ Happy + +
+

Leve felicidade para o mundo!

+

Visite orfanatos e mude o dia de muitas crianças.

+
+ +
+ Santos + São Paulo +
+ + + + +
+
+ ); +} + +export default LandingPage; diff --git a/web/src/pages/orphanages-page.tsx b/web/src/pages/orphanages-page.tsx new file mode 100644 index 0000000..2d20533 --- /dev/null +++ b/web/src/pages/orphanages-page.tsx @@ -0,0 +1,112 @@ +import { useEffect, useState } from 'react'; +import { Link } from 'react-router-dom'; +import { FiPlus, FiArrowRight } from 'react-icons/fi'; +import { GoogleMap, useJsApiLoader, Marker, InfoWindow } from '@react-google-maps/api'; + +import '../styles/orphanages.css'; +import MapMarker from '../images/map_marker.svg'; +import api from '../services/api'; + +interface Orphanage { + id: number; + latitude: number; + longitude: number; + name: string; +} + +const containerStyle = { + width: '100%', + height: '100%' +}; + +const center = { + lat: -23.9550537, + lng: -46.3204442 +}; + +function OrphanagesMap() { + const { isLoaded } = useJsApiLoader({ + id: 'google-map-script', + googleMapsApiKey: process.env.REACT_APP_MAPS_API_KEY! + }); + + const [orphanages, setOrphanages] = useState([]); + const [selectedOrphanage, setSelectedOrphanage] = useState(null); + + useEffect(() => { + api.get('orphanages').then(response => { + setOrphanages(response.data); + }); + }, []); + + if (!isLoaded) { + return
Loading Map...
; + } + + return ( +
+ + + setSelectedOrphanage(null)} + > + {orphanages.map(orphanage => ( + { + setSelectedOrphanage(orphanage); + }} + /> + ))} + + {selectedOrphanage && ( + { + setSelectedOrphanage(null); + }} + > +
+ {selectedOrphanage.name} + + + +
+
+ )} +
+ + + + +
+ ); +} + +export default OrphanagesMap; \ No newline at end of file diff --git a/web/src/services/api.ts b/web/src/services/api.ts new file mode 100644 index 0000000..df5a262 --- /dev/null +++ b/web/src/services/api.ts @@ -0,0 +1,7 @@ +import axios from 'axios'; + +const api = axios.create({ + baseURL: process.env.BACKEND_URL || 'http://localhost:3101', +}); + +export default api; \ No newline at end of file diff --git a/web/src/styles/components/sidebar.css b/web/src/styles/components/sidebar.css new file mode 100644 index 0000000..d3d4978 --- /dev/null +++ b/web/src/styles/components/sidebar.css @@ -0,0 +1,39 @@ +aside.app-sidebar { + position: fixed; + height: 100%; + padding: 32px 24px; + background: linear-gradient(329.54deg, #15B6D6 0%, #15D6D6 100%); + + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; +} + +aside.app-sidebar img { + width: 48px; +} + +aside.app-sidebar footer a, +aside.app-sidebar footer button { + width: 48px; + height: 48px; + + border: 0; + + background: #12AFCB; + border-radius: 16px; + + cursor: pointer; + + transition: background-color 0.2s; + + display: flex; + justify-content: center; + align-items: center; +} + +aside.app-sidebar footer a:hover, +aside.app-sidebar footer button:hover { + background: #17D6EB; +} \ No newline at end of file diff --git a/web/src/styles/orphanages.css b/web/src/styles/orphanages.css new file mode 100644 index 0000000..a3f253b --- /dev/null +++ b/web/src/styles/orphanages.css @@ -0,0 +1,109 @@ +#page-map { + width: 100vw; + height: 100vh; + + position: relative; + display: flex; +} + +#page-map aside { + width: 440px; + background: linear-gradient(329.54deg, #29b6d1 0%, #00c7c7 100%); + + padding: 80px; + + display: flex; + flex-direction: column; + justify-content: space-between; +} + +#page-map aside h1 { + font-weight: 800; + font-size: 40px; + line-height: 42px; + margin-top: 64px; +} + +#page-map aside p { + font-weight: 600; + font-size: 18px; + line-height: 28px; + margin-top: 24px; +} + +#page-map aside footer { + display: flex; + flex-direction: column; +} + +#page-map aside footer { + font-size: 18px; + line-height: 28px; +} + +#page-map aside footer strong { + font-weight: 800; +} + +#page-map .create-orphanage { + z-index: 10; + position: absolute; + bottom: 40px; + right: 40px; + + width: 64px; + height: 64px; + + display: flex; + align-items: center; + justify-content: center; + + background-color: #15C3D6; + border-radius: 20px; + box-shadow: 0px 4px 10px rgba(23, 142, 166, 0.4); /* Shadow added */ + + transition: background-color 0.2s; +} + +#page-map .create-orphanage:hover { + background-color: #17d6eb; +} + +/* --- NEW STYLING FOR GOOGLE MAPS INFO WINDOW --- */ +.map-popup { + color: #0089a5; + font-size: 20px; + font-weight: bold; + + display: flex; + justify-content: space-between; + align-items: center; +} + +.map-popup a { + width: 40px; + height: 40px; + background: #15c3d6; + box-shadow: 17.2868px 27.6589px 41.4884px rgba(23, 142, 166, 0.16); + border-radius: 12px; + margin-left: 12px; + + display: flex; + justify-content: center; + align-items: center; +} + +/* This targets the default close button on the Google InfoWindow */ +.gm-ui-hover-effect { + top: 4px !important; + right: 4px !important; +} + +/* This targets the default white background and arrow of the Google InfoWindow */ +.gm-style-iw-c { + padding: 12px !important; + border-radius: 20px !important; +} +.gm-style-iw-d { + overflow: hidden !important; +} \ No newline at end of file