diff --git a/src/App.tsx b/src/App.tsx index a36d941..b788bf3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,6 +11,7 @@ import AddEvent from './pages/AddEvent' import AddEventSuccess from './pages/AddEventSuccess' import AddEventFail from './pages/AddEventFail' import EventReservations from './pages/EventReservations' +import CafeMapPage from './pages/CafeMapPage' import MyReservations from './pages/MyReservations' import Login from './pages/Login' import LoginOtp from './pages/LoginOtp' @@ -35,6 +36,7 @@ export default function App() { } /> } /> } /> + } /> } /> } /> } /> diff --git a/src/pages/CafeMapPage.tsx b/src/pages/CafeMapPage.tsx new file mode 100644 index 0000000..37b143d --- /dev/null +++ b/src/pages/CafeMapPage.tsx @@ -0,0 +1,72 @@ +import { useEffect } from 'react' +import { useLocation, useNavigate } from 'react-router-dom' +import { MapContainer, TileLayer, Marker, ZoomControl, useMap } from 'react-leaflet' +import 'leaflet/dist/leaflet.css' +import '../utils/leafletIcons' +import { Cafe } from '../services/campaignApi' +import Icon from '../components/Icon' + +function FitBounds({ cafes }: { cafes: Cafe[] }) { + const map = useMap() + useEffect(() => { + if (cafes.length === 0) return + if (cafes.length === 1) { + const [lng, lat] = cafes[0].location.coordinates + map.setView([lat, lng], 15) + return + } + const bounds = cafes.map( + (c) => [c.location.coordinates[1], c.location.coordinates[0]] as [number, number], + ) + map.fitBounds(bounds, { padding: [60, 60] }) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + return null +} + +export default function CafeMapPage() { + const navigate = useNavigate() + const location = useLocation() + const cafes = (location.state as { cafes: Cafe[] } | null)?.cafes ?? [] + + const defaultCenter: [number, number] = + cafes.length > 0 + ? [cafes[0].location.coordinates[1], cafes[0].location.coordinates[0]] + : [35.6892, 51.389] + + return ( +
+ + + + + + + {cafes.map((cafe) => ( + navigate(`/cafe/${cafe.uuid}`, { state: { cafe } }) }} + /> + ))} + +
+ ) +} diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx index 6226168..2da0a6c 100644 --- a/src/pages/Home.tsx +++ b/src/pages/Home.tsx @@ -1,5 +1,8 @@ import { useEffect, useState } from 'react' import { useNavigate } from 'react-router-dom' +import { MapContainer, TileLayer, Marker } from 'react-leaflet' +import 'leaflet/dist/leaflet.css' +import '../utils/leafletIcons' import Icon from '../components/Icon' import HomeBanner from '../components/HomeBanner' import { Cafe, City, fetchCafes, fetchCities, MatchEvent } from '../services/campaignApi' @@ -11,45 +14,75 @@ function findTehran(cities: City[]): City | undefined { return cities.find((c) => c.city_name === 'تهران' || c.city_name.toLowerCase() === 'tehran') } -// MapIcon/ListIcon — only used by the disabled نقشه/لیست toggle above, commented out together with it -// function MapIcon() { -// return ( -// -// -// -// -// -// ) -// } -// -// function ListIcon() { -// return ( -// -// -// -// -// -// -// -// -// ) -// } +function MapIcon() { + return ( + + + + + + ) +} -// MapPlaceholder — only used by the disabled نقشه/لیست toggle below (the cafes-on-a-map -// view isn't built yet); the top-of-page بنر slot it used to fill is now HomeBanner. -// function MapPlaceholder() { -// return ( -//
-// بنر -//
-// ) -// } +function ListIcon() { + return ( + + + + + + + + + ) +} + +function CafesMapPreview({ cafes }: { cafes: Cafe[] }) { + const navigate = useNavigate() + const center: [number, number] = + cafes.length > 0 + ? [cafes[0].location.coordinates[1], cafes[0].location.coordinates[0]] + : [35.6892, 51.389] + + return ( +
+ + + {cafes.map((cafe) => ( + + ))} + + {/* transparent overlay — captures all clicks and opens the full-page map */} +
navigate('/map', { state: { cafes } })} + /> +
+ ) +} function CitySelectorRow({ label, @@ -205,9 +238,7 @@ function CafeCard({ cafe }: { cafe: Cafe }) { } export default function Home() { - // نقشه/لیست toggle — disabled for now, the map view isn't part of the app yet - // (will be added in a later version); uncomment together with its JSX below - // const [view, setView] = useState<'list' | 'map'>('list') + const [view, setView] = useState<'list' | 'map'>('list') const [cities, setCities] = useState([]) const [selectedCityUuid, setSelectedCityUuid] = useState('') const [selectedMatchUuid, setSelectedMatchUuid] = useState('') @@ -252,7 +283,6 @@ export default function Home() {

کافه‌ها

- {/* نقشه/لیست toggle — commented out together with the `view` state above, see that comment
- */}
-
- {/* always the list view for now — restore the `view === 'list' ? ... : ` ternary when the map toggle above is restored */} -
- {cafes.map((cafe) => ( - - ))} + {view === 'map' ? ( + + ) : ( +
+
+ {cafes.map((cafe) => ( + + ))} +
-
+ )}