aether-rides / LocationsPage.tsx
lattmamb's picture
Upload 32 files (#1)
a1a9b91 verified
import { useState } from 'react';
import { Search, MapPin } from 'lucide-react';
interface Location {
id: string;
name: string;
address: string;
city: string;
state: string;
zip: string;
hours: string;
phone: string;
amenities: string[];
coordinates: {
lat: number;
lng: number;
};
}
const locations: Location[] = [
{
id: 'sf-downtown',
name: 'San Francisco Downtown',
address: '123 Market Street',
city: 'San Francisco',
state: 'CA',
zip: '94105',
hours: 'Mon-Sun: 7am-10pm',
phone: '(415) 555-1234',
amenities: ['Tesla Superchargers', 'Waiting Lounge', 'Accessories Shop', 'Restrooms'],
coordinates: {
lat: 37.7749,
lng: -122.4194,
},
},
{
id: 'la-century',
name: 'Los Angeles Century City',
address: '1888 Century Park East',
city: 'Los Angeles',
state: 'CA',
zip: '90067',
hours: 'Mon-Sun: 8am-9pm',
phone: '(310) 555-6789',
amenities: ['Tesla Superchargers', 'Waiting Lounge', 'Car Wash', 'Restrooms'],
coordinates: {
lat: 34.0522,
lng: -118.2437,
},
},
{
id: 'nyc-manhattan',
name: 'New York - Manhattan',
address: '347 West 34th Street',
city: 'New York',
state: 'NY',
zip: '10001',
hours: 'Mon-Sun: 9am-8pm',
phone: '(212) 555-8901',
amenities: ['Tesla Superchargers', 'Waiting Lounge', 'Accessories Shop', 'Coffee Bar'],
coordinates: {
lat: 40.7128,
lng: -74.006,
},
},
{
id: 'miami-beach',
name: 'Miami Beach',
address: '1100 Collins Avenue',
city: 'Miami Beach',
state: 'FL',
zip: '33139',
hours: 'Mon-Sun: 8am-10pm',
phone: '(305) 555-2345',
amenities: ['Tesla Superchargers', 'Waiting Lounge', 'Car Wash', 'Coffee Bar', 'Restrooms'],
coordinates: {
lat: 25.7617,
lng: -80.1918,
},
},
{
id: 'chicago-loop',
name: 'Chicago - The Loop',
address: '333 South Wabash Avenue',
city: 'Chicago',
state: 'IL',
zip: '60604',
hours: 'Mon-Sun: 7am-9pm',
phone: '(312) 555-3456',
amenities: ['Tesla Superchargers', 'Waiting Lounge', 'Restrooms'],
coordinates: {
lat: 41.8781,
lng: -87.6298,
},
},
{
id: 'seattle-downtown',
name: 'Seattle Downtown',
address: '500 Pine Street',
city: 'Seattle',
state: 'WA',
zip: '98101',
hours: 'Mon-Sun: 7am-8pm',
phone: '(206) 555-4567',
amenities: ['Tesla Superchargers', 'Waiting Lounge', 'Accessories Shop', 'Restrooms'],
coordinates: {
lat: 47.6062,
lng: -122.3321,
},
},
];
const cities = ['All Cities', 'San Francisco', 'Los Angeles', 'New York', 'Miami Beach', 'Chicago', 'Seattle'];
const LocationsPage = () => {
const [searchQuery, setSearchQuery] = useState('');
const [selectedCity, setSelectedCity] = useState('All Cities');
const [selectedLocation, setSelectedLocation] = useState<Location | null>(null);
const filteredLocations = locations.filter((location) => {
const matchesSearch = searchQuery === '' ||
location.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
location.address.toLowerCase().includes(searchQuery.toLowerCase()) ||
location.city.toLowerCase().includes(searchQuery.toLowerCase()) ||
location.state.toLowerCase().includes(searchQuery.toLowerCase()) ||
location.zip.toLowerCase().includes(searchQuery.toLowerCase());
const matchesCity = selectedCity === 'All Cities' || location.city === selectedCity;
return matchesSearch && matchesCity;
});
const handleLocationClick = (location: Location) => {
setSelectedLocation(location);
};
return (
<div className="bg-[#0a0a0a] text-white min-h-screen">
<div className="container mx-auto px-4 py-12">
{/* Header */}
<div className="max-w-3xl mx-auto text-center mb-12">
<h1 className="text-4xl md:text-5xl font-bold mb-4">Our Locations</h1>
<p className="text-gray-300 text-lg">
Find the nearest pickup and dropoff location for your electric vehicle rental.
</p>
</div>
{/* Search and Filter */}
<div className="mb-8">
<div className="flex flex-col md:flex-row gap-4 mb-4">
<div className="relative flex-1">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Search className="h-5 w-5 text-gray-400" />
</div>
<input
type="text"
placeholder="Search by location name, address, or zip code"
className="block w-full pl-10 pr-3 py-3 bg-[#161617] border border-gray-700 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-600 focus:border-transparent text-white"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
<select
value={selectedCity}
onChange={(e) => setSelectedCity(e.target.value)}
className="bg-[#161617] border border-gray-700 text-white rounded-md py-3 px-4 appearance-none md:max-w-xs focus:outline-none focus:ring-2 focus:ring-blue-600 focus:border-transparent"
>
{cities.map((city) => (
<option key={city} value={city}>
{city}
</option>
))}
</select>
</div>
</div>
{/* Main Content */}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* Locations List */}
<div className="lg:col-span-1">
<div className="bg-[#161617] rounded-lg overflow-hidden border border-gray-800">
<div className="p-4 border-b border-gray-800">
<h3 className="font-medium">{filteredLocations.length} {filteredLocations.length === 1 ? 'Location' : 'Locations'} Found</h3>
</div>
<div className="divide-y divide-gray-800 max-h-[600px] overflow-y-auto">
{filteredLocations.length > 0 ? (
filteredLocations.map((location) => (
<button
key={location.id}
onClick={() => handleLocationClick(location)}
className={`w-full px-4 py-3 flex items-start text-left transition-colors hover:bg-gray-800 ${
selectedLocation?.id === location.id ? 'bg-gray-800' : ''
}`}
>
<MapPin className="h-5 w-5 text-blue-500 flex-shrink-0 mt-0.5 mr-3" />
<div>
<h4 className="font-medium">{location.name}</h4>
<p className="text-gray-400 text-sm">{location.address}, {location.city}, {location.state} {location.zip}</p>
<p className="text-gray-500 text-xs mt-1">{location.hours}</p>
</div>
</button>
))
) : (
<div className="p-6 text-center">
<p className="text-gray-400">No locations found matching your search criteria.</p>
</div>
)}
</div>
</div>
</div>
{/* Map and Location Details */}
<div className="lg:col-span-2">
{selectedLocation ? (
<div className="grid grid-cols-1 gap-6">
{/* Map Placeholder */}
<div className="bg-[#161617] rounded-lg overflow-hidden border border-gray-800 h-[300px] flex items-center justify-center">
<div className="text-center px-4">
<p className="text-gray-400 mb-2">Interactive map would be displayed here with location:</p>
<p className="font-medium">{selectedLocation.name}</p>
<p className="text-sm text-gray-500">Coordinates: {selectedLocation.coordinates.lat}, {selectedLocation.coordinates.lng}</p>
</div>
</div>
{/* Location Details */}
<div className="bg-[#161617] rounded-lg overflow-hidden border border-gray-800">
<div className="p-5 border-b border-gray-800">
<h3 className="text-xl font-bold">{selectedLocation.name}</h3>
<p className="text-gray-400 mt-1">{selectedLocation.address}, {selectedLocation.city}, {selectedLocation.state} {selectedLocation.zip}</p>
</div>
<div className="p-5 grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<h4 className="text-lg font-medium mb-3">Hours & Contact</h4>
<div className="space-y-3">
<div>
<p className="text-gray-400 text-sm">Hours</p>
<p>{selectedLocation.hours}</p>
</div>
<div>
<p className="text-gray-400 text-sm">Phone</p>
<p>{selectedLocation.phone}</p>
</div>
</div>
</div>
<div>
<h4 className="text-lg font-medium mb-3">Amenities</h4>
<ul className="space-y-2">
{selectedLocation.amenities.map((amenity, index) => (
<li key={index} className="flex items-center gap-2">
<div className="h-2 w-2 rounded-full bg-blue-500"></div>
<span>{amenity}</span>
</li>
))}
</ul>
</div>
</div>
<div className="p-5 bg-[#1c1c1e] border-t border-gray-800">
<button className="bg-blue-600 hover:bg-blue-700 text-white font-medium px-4 py-2 rounded-md transition-colors">
Book a Vehicle at This Location
</button>
</div>
</div>
</div>
) : (
<div className="bg-[#161617] rounded-lg border border-gray-800 h-full flex items-center justify-center p-10">
<div className="text-center max-w-md">
<MapPin className="h-12 w-12 text-blue-500 mb-4 mx-auto" />
<h3 className="text-xl font-bold mb-2">Select a Location</h3>
<p className="text-gray-400">
Choose a location from the list to view details and availability information.
</p>
</div>
</div>
)}
</div>
</div>
</div>
</div>
);
};
export default LocationsPage;