x /** @jsxImportSource react */ import React, { useState, useEffect } from 'react'; import ReactDOM from 'react-dom'; import styled from 'styled-components'; // Theme const theme = { colors: { primary: '#3B82F6', accent: '#10B981', background: '#F9FAFB', text: '#111827', secondary: '#6366F1', white: '#FFFFFF', gray100: '#F3F4F6', gray200: '#E5E7EB', gray500: '#6B7280', gray700: '#374151', }, shadows: { sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', }, radii: { sm: '4px', md: '8px', lg: '12px', full: '9999px', }, }; // Styled Components const Container = styled.div` width: 100%; height: 100%; position: relative; overflow: hidden; `; const MapContainer = styled.div` width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 0; `; const BottomSheet = styled.div` position: fixed; bottom: 0; left: 0; right: 0; background: ${theme.colors.white}; border-top-left-radius: ${theme.radii.lg}; border-top-right-radius: ${theme.radii.lg}; box-shadow: ${theme.shadows.lg}; padding: 16px; padding-bottom: env(safe-area-inset-bottom, 16px); transform: ${props => props.open ? 'translateY(0)' : 'translateY(80%)'}; transition: transform 0.3s ease-out; z-index: 10; max-height: 70vh; overflow-y: auto; `; const ListingCard = styled.div` background: ${theme.colors.white}; border-radius: ${theme.radii.md}; box-shadow: ${theme.shadows.sm}; padding: 12px; margin-bottom: 12px; transition: all 0.2s ease; &:active { transform: scale(0.98); } `; // Main App Component function App() { const [map, setMap] = useState(null); const [userLocation, setUserLocation] = useState(null); const [showForm, setShowForm] = useState(false); const [listings, setListings] = useState([]); const [bottomSheetOpen, setBottomSheetOpen] = useState(true); useEffect(() => { // Initialize map const mapInstance = L.map('map').setView([41.2995, 69.2401], 13); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© OpenStreetMap contributors' }).addTo(mapInstance); setMap(mapInstance); // Get user location if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( position => { const { latitude, longitude } = position.coords; setUserLocation({ lat: latitude, lng: longitude }); mapInstance.setView([latitude, longitude], 15); // Add user marker L.marker([latitude, longitude], { icon: L.divIcon({ className: 'user-location-marker', html: `
` }) }).addTo(mapInstance); // Fetch nearby listings fetchListings(latitude, longitude); }, error => { console.error('Geolocation error:', error); // Default to Tashkent coordinates setUserLocation({ lat: 41.2995, lng: 69.2401 }); fetchListings(41.2995, 69.2401); } ); } return () => { mapInstance.remove(); }; }, []); const fetchListings = async (lat, lng) => { try { // Mock data for demo const mockListings = [ { id: '1', title: 'Cozy Apartment for Students', price: 300, category: 'house', tags: ['For students'], description: 'Nice apartment near university', lat: lat + 0.005, lng: lng + 0.005, images: ['http://static.photos/house/640x360/1'] }, { id: '2', title: 'Office Space for Rent', price: 500, category: 'office', tags: ['For office staff'], description: 'Modern office in business district', lat: lat - 0.003, lng: lng + 0.007, images: ['http://static.photos/office/640x360/1'] } ]; setListings(mockListings); // Add markers for listings mockListings.forEach(listing => { L.marker([listing.lat, listing.lng], { icon: L.divIcon({ className: 'listing-marker', html: `` }) }).addTo(map).on('click', () => { // Center map on listing map.setView([listing.lat, listing.lng], 15); }); }); } catch (error) { console.error('Error fetching listings:', error); } }; return (${listing.price}/month