hey ia watn to add a nice weciing effect to the users everytime they ope nthe app like the first not if its from the backeground and also it should be nice super good fantastic opeingin screen best and super nice fro a restaurant app make it as perfecgt and super bet as possible
"""
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 '../models/food.dart';
import '../widgets/food_card.dart';
import '../screens/cart_screen.dart';
import '../services/food_service.dart';
import '../providers/cart_provider.dart';
import 'offline_screen.dart'; // Import the OfflineScreen

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;
      });
      // Instead of showing a SnackBar, we leverage the OfflineScreen
    }
  }

  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(
              onPressed: () {
                Navigator.of(context).pop(); // Dismiss the dialog
                _initiatePhoneCall(); // Initiate the call
              },
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.green,
              ),
              child: const Text('Call'),
            ),
          ],
        );
      },
    );
  }

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

  @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: errorMessage != null
            ? OfflineScreen(
          onRetry: _fetchFoods,
        )
            : Column(
          children: [
            _buildFilterChips(),
            Expanded(
              child: isLoading
                  ? const Center(child: CircularProgressIndicator())
                  : filteredFoods.isEmpty
                  ? Center(
                child: Text(
                  'No items found',
                  style: TextStyle(
                    color: Colors.grey[600],
                    fontSize: 18,
                  ),
                ),
              )
                  : 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);
                  },
                ),
              ),
            ),
          ],
        ),
      ),
      // 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'),
            ),
          ],
        ),
      ),
    );
  }
}
"""
""""