cna you add a offline screen when theres no server response liek if server is offline 
"""
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/cart_provider.dart';
import '../screens/home_page.dart';

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => CartProvider(),
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Restaurant App',
      theme: ThemeData(
        primarySwatch: Colors.red,
        scaffoldBackgroundColor: Colors.grey[50],
        appBarTheme: const AppBarTheme(
          elevation: 0,
          backgroundColor: Colors.white,
          foregroundColor: Colors.black,
        ),
      ),
      home: const HomePage(),
    );
  }
}

"""
"""
// screens/home_page.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart'; // Import url_launcher
import '../models/food.dart';
import '../widgets/food_card.dart';
import '../screens/cart_screen.dart';
import '../services/food_service.dart';
import '../providers/cart_provider.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
  List<Food> foods = [];
  String? filterCategory;
  bool isLoading = true;
  String? errorMessage;
  final FoodService _foodService = FoodService();

  late AnimationController _controller;
  late Animation<double> _animation;

  // Define the restaurant's phone number
  final String _restaurantPhoneNumber = '+1234567890'; // Replace with actual number

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(milliseconds: 800),
      vsync: this,
    );
    _animation = CurvedAnimation(parent: _controller, curve: Curves.easeInOut);

    Future.microtask(() => _fetchFoods());
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  Future<void> _fetchFoods() async {
    setState(() {
      isLoading = true;
      errorMessage = null;
    });

    try {
      final fetchedFoods = await _foodService.getFoods();
      setState(() {
        foods = fetchedFoods;
        isLoading = false;
        _controller.forward(); // Start the animation when data is loaded
      });
    } catch (e) {
      setState(() {
        errorMessage = 'Network error. Please check your connection.';
        isLoading = false;
      });
      _showErrorSnackBar('Network error. Please check your connection.');
    }
  }

  void _showErrorSnackBar(String message) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
        duration: const Duration(seconds: 4),
        action: SnackBarAction(
          label: 'Retry',
          onPressed: _fetchFoods,
        ),
      ),
    );
  }

  void _navigateToCart() {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => const CartScreen()),
    );
  }

  void _updateFilter(String? newFilter) {
    setState(() {
      filterCategory = newFilter;
    });
  }

  // Function to initiate phone call
  Future<void> _initiatePhoneCall() async {
    final Uri phoneUri = Uri(scheme: 'tel', path: _restaurantPhoneNumber);

    try {
      // Check if the device can make phone calls
      if (await canLaunchUrl(phoneUri)) {
        await launchUrl(phoneUri);
      } else {
        _showErrorSnackBar('Unable to make the call.');
      }
    } catch (e) {
      _showErrorSnackBar('Failed to initiate call.');
    }
  }

  // Function to show confirmation dialog
  void _showCallConfirmationDialog() {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: const Text('Call Restaurant'),
          content: const Text('Do you want to call the restaurant?'),
          actions: [
            TextButton(
              child: const Text('Cancel'),
              onPressed: () {
                Navigator.of(context).pop(); // Dismiss the dialog
              },
            ),
            ElevatedButton(
              child: const Text('Call'),
              onPressed: () {
                Navigator.of(context).pop(); // Dismiss the dialog
                _initiatePhoneCall(); // Initiate the call
              },
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.green,
              ),
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    final cart = Provider.of<CartProvider>(context); // Listen to CartProvider changes

    final filteredFoods = filterCategory == null
        ? foods
        : foods.where((food) => food.category.toLowerCase() == filterCategory).toList();

    return Scaffold(
      appBar: AppBar(
        title: const Text('Restaurant Menu'),
        actions: [
          IconButton(
            icon: const Icon(Icons.call),
            tooltip: 'Call Restaurant',
            onPressed: _showCallConfirmationDialog, // Show confirmation dialog
          ),
        ],
      ),
      body: RefreshIndicator(
        onRefresh: _fetchFoods,
        child: Column(
          children: [
            _buildFilterChips(),
            Expanded(
              child: isLoading
                  ? const Center(child: CircularProgressIndicator())
                  : filteredFoods.isEmpty
                  ? Center(
                child: Text(errorMessage ?? 'No items found'),
              )
                  : FadeTransition(
                opacity: _animation,
                child: GridView.builder(
                  padding: const EdgeInsets.all(8),
                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                    crossAxisCount: 2,
                    childAspectRatio: 0.75,
                    crossAxisSpacing: 10,
                    mainAxisSpacing: 10,
                  ),
                  itemCount: filteredFoods.length,
                  itemBuilder: (context, index) {
                    final food = filteredFoods[index];
                    return FoodCard(food: food);
                  },
                ),
              ),
            ),
          ],
        ),
      ),
      // Removed the floatingActionButton

      // Persistent bottom cart button
      bottomNavigationBar: Container(
        padding: const EdgeInsets.all(16),
        decoration: BoxDecoration(
          color: Colors.white,
          boxShadow: [
            BoxShadow(
              color: Colors.black.withOpacity(0.1),
              blurRadius: 10,
              offset: const Offset(0, -1),
            ),
          ],
        ),
        child: ElevatedButton.icon(
          onPressed: _navigateToCart,
          icon: const Icon(Icons.shopping_cart),
          label: Text(
            'View Cart (${cart.totalItems})', // Display total items
            style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
          ),
          style: ElevatedButton.styleFrom(
            backgroundColor: Colors.deepOrange,
            padding: const EdgeInsets.symmetric(vertical: 16),
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(8),
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildFilterChips() {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
      child: SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: Row(
          children: [
            ChoiceChip(
              label: const Text('All'),
              selected: filterCategory == null,
              onSelected: (_) => _updateFilter(null),
            ),
            const SizedBox(width: 8),
            ChoiceChip(
              label: const Text('Veg'),
              selected: filterCategory == 'veg',
              onSelected: (_) => _updateFilter('veg'),
            ),
            const SizedBox(width: 8),
            ChoiceChip(
              label: const Text('Non-Veg'),
              selected: filterCategory == 'non-veg',
              onSelected: (_) => _updateFilter('non-veg'),
            ),
          ],
        ),
      ),
    );
  }
}
"""
"""
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../models/food.dart';

class FoodService {
  static const String baseUrl = 'http://localhost:3000'; // Replace with your API URL

  Future<List<Food>> getFoods() async {
    try {
      final response = await http.get(Uri.parse('$baseUrl/foods'));

      if (response.statusCode == 200) {
        final List<dynamic> foodsJson = json.decode(response.body);
        return foodsJson.map((json) => Food.fromJson(json)).toList();
      } else {
        throw Exception('Failed to load foods');
      }
    } catch (e) {
      throw Exception('Error connecting to the server');
    }
  }

  Future<List<dynamic>> getFoodReviews(String foodId) async {
    try {
      final response = await http.get(Uri.parse('$baseUrl/foods/$foodId/reviews'));

      if (response.statusCode == 200) {
        return json.decode(response.body);
      } else {
        throw Exception('Failed to load reviews');
      }
    } catch (e) {
      throw Exception('Error fetching reviews');
    }
  }

  Future<void> submitReview(String foodId, double rating, String name, String description) async {
    try {
      final response = await http.post(
        Uri.parse('$baseUrl/foods/$foodId/review'),
        headers: {'Content-Type': 'application/json'},
        body: json.encode({
          'rating': rating,
          'name': name,
          'description': description,
        }),
      );

      if (response.statusCode != 200) {
        throw Exception('Failed to submit review');
      }
    } catch (e) {
      throw Exception('Error submitting review');
    }
  }
}

"""