| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- import React, { useState, useEffect } from 'react';
- import { Container, Typography, TextField, Button, Box, Grid, Card, CardContent, CardMedia, Rating, IconButton } from '@mui/material';
- import MyLocationIcon from '@mui/icons-material/MyLocation';
- import SearchIcon from '@mui/icons-material/Search';
- const Home = () => {
- const [restaurants, setRestaurants] = useState([]);
- const [location, setLocation] = useState(null);
- const [searchQuery, setSearchQuery] = useState('');
- useEffect(() => {
- fetchRestaurants();
- }, []);
- const fetchRestaurants = async (lat, lng) => {
- let url = '/restaurants';
- if (lat && lng) {
- url += `?lat=${lat}&lng=${lng}`;
- }
- try {
- const response = await fetch(url);
- if (response.ok) {
- const data = await response.json();
- setRestaurants(data);
- }
- } catch (error) {
- console.error('Error fetching restaurants:', error);
- }
- };
- const handleUseCurrentLocation = () => {
- if (navigator.geolocation) {
- navigator.geolocation.getCurrentPosition(
- (position) => {
- const { latitude, longitude } = position.coords;
- setLocation({ latitude, longitude });
- fetchRestaurants(latitude, longitude);
- },
- (error) => {
- console.error('Error getting location:', error);
- }
- );
- } else {
- alert('Geolocation is not supported by this browser.');
- }
- };
- const handleSearch = () => {
- if (!searchQuery) {
- fetchRestaurants(location?.latitude, location?.longitude);
- return;
- }
- const filtered = restaurants.filter(r => r.name.toLowerCase().includes(searchQuery.toLowerCase()));
- setRestaurants(filtered);
- };
- return (
- <Container maxWidth="xl">
- <Box sx={{ my: 4, textAlign: 'center' }}>
- <Typography variant="h3" component="h1" gutterBottom>
- Find the Best Lunch Deals Near You
- </Typography>
- <Typography variant="h6" color="text.secondary" paragraph>
- Discover restaurants with amazing lunch specials shared by the community.
- </Typography>
- <Box sx={{ display: 'flex', justifyContent: 'center', mt: 4, mb: 6 }}>
- <TextField
- label="Search restaurants or location"
- variant="outlined"
- size="medium"
- sx={{ width: '50%', mr: 1 }}
- value={searchQuery}
- onChange={(e) => setSearchQuery(e.target.value)}
- />
- <Button variant="contained" size="large" onClick={handleSearch} startIcon={<SearchIcon />}>
- Search
- </Button>
- <IconButton color="primary" sx={{ ml: 1 }} onClick={handleUseCurrentLocation} title="Use Current Location">
- <MyLocationIcon />
- </IconButton>
- </Box>
- </Box>
- <Grid container spacing={4}>
- {restaurants.map((restaurant) => (
- <Grid item key={restaurant.id} xs={12} sm={6} md={4}>
- <Card sx={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
- <CardMedia
- component="img"
- height="200"
- image={restaurant.images[0] || 'https://via.placeholder.com/300x200?text=No+Image'}
- alt={restaurant.name}
- />
- <CardContent sx={{ flexGrow: 1 }}>
- <Typography gutterBottom variant="h5" component="h2">
- {restaurant.name}
- </Typography>
- <Typography variant="body2" color="text.secondary" gutterBottom>
- {restaurant.address}
- </Typography>
- <Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}>
- <Rating value={restaurant.user_rating} readOnly precision={0.5} size="small" />
- <Typography variant="body2" color="text.secondary" sx={{ ml: 1 }}>
- ({restaurant.user_rating}/10)
- </Typography>
- </Box>
- <Typography variant="h6" color="primary">
- ${restaurant.min_price} - ${restaurant.max_price}
- </Typography>
- </CardContent>
- </Card>
- </Grid>
- ))}
- </Grid>
- </Container>
- );
- };
- export default Home;
|