import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../app/app_router.dart'; import '../app/app_state.dart'; /// Screen to invite additional Payfrit users to join a group order /// Shown after selecting Delivery or Takeaway class GroupOrderInviteScreen extends StatefulWidget { const GroupOrderInviteScreen({super.key}); @override State createState() => _GroupOrderInviteScreenState(); } class _GroupOrderInviteScreenState extends State { final List _invitedUsers = []; final TextEditingController _searchController = TextEditingController(); bool _isSearching = false; // Mock search results - in production this would come from API final List<_UserResult> _searchResults = []; @override void dispose() { _searchController.dispose(); super.dispose(); } void _searchUsers(String query) { if (query.isEmpty) { setState(() { _searchResults.clear(); _isSearching = false; }); return; } setState(() => _isSearching = true); // TODO: Replace with actual API call to search users by phone/email/username // For now, show placeholder Future.delayed(const Duration(milliseconds: 500), () { if (mounted && _searchController.text == query) { setState(() { _searchResults.clear(); // Mock results - would come from API if (query.length >= 3) { _searchResults.addAll([ _UserResult( userId: 1, name: 'John D.', phone: '***-***-${query.substring(0, 4)}', ), ]); } _isSearching = false; }); } }); } void _inviteUser(_UserResult user) { if (!_invitedUsers.contains(user.name)) { setState(() { _invitedUsers.add(user.name); _searchResults.clear(); _searchController.clear(); }); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Invitation sent to ${user.name}', style: const TextStyle(color: Colors.black)), backgroundColor: const Color(0xFF90EE90), behavior: SnackBarBehavior.floating, margin: const EdgeInsets.only(bottom: 80, left: 16, right: 16), ), ); } } void _removeInvite(String userName) { setState(() { _invitedUsers.remove(userName); }); } void _continueToRestaurants() { // Store invited users in app state if needed final appState = context.read(); // TODO: appState.setGroupOrderInvites(_invitedUsers); Navigator.of(context).pushReplacementNamed(AppRoutes.restaurantSelect); } void _skipInvites() { Navigator.of(context).pushReplacementNamed(AppRoutes.restaurantSelect); } @override Widget build(BuildContext context) { final appState = context.watch(); final orderTypeLabel = appState.isDelivery ? 'Delivery' : 'Takeaway'; return Scaffold( backgroundColor: Colors.black, appBar: AppBar( backgroundColor: Colors.black, foregroundColor: Colors.white, title: Text('$orderTypeLabel Order'), elevation: 0, ), body: SafeArea( child: Padding( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Header const Icon( Icons.group_add, color: Colors.white54, size: 48, ), const SizedBox(height: 16), const Text( "Invite others to join", style: TextStyle( color: Colors.white, fontSize: 22, fontWeight: FontWeight.bold, ), textAlign: TextAlign.center, ), const SizedBox(height: 8), Text( "Add Payfrit users to share this order.\n${appState.isDelivery ? 'Split the delivery fee between everyone!' : 'Everyone pays for their own items.'}", style: const TextStyle( color: Colors.white70, fontSize: 14, ), textAlign: TextAlign.center, ), const SizedBox(height: 24), // Search field TextField( controller: _searchController, onChanged: _searchUsers, style: const TextStyle(color: Colors.white), decoration: InputDecoration( hintText: 'Search by phone or email...', hintStyle: const TextStyle(color: Colors.white38), prefixIcon: const Icon(Icons.search, color: Colors.white54), suffixIcon: _isSearching ? const Padding( padding: EdgeInsets.all(12), child: SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white54, ), ), ) : null, filled: true, fillColor: Colors.grey.shade900, border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none, ), ), ), // Search results if (_searchResults.isNotEmpty) ...[ const SizedBox(height: 8), Container( decoration: BoxDecoration( color: Colors.grey.shade900, borderRadius: BorderRadius.circular(12), ), child: Column( children: _searchResults.map((user) { return ListTile( leading: CircleAvatar( backgroundColor: Colors.blue.withAlpha(50), child: Text( user.name[0].toUpperCase(), style: const TextStyle(color: Colors.blue), ), ), title: Text( user.name, style: const TextStyle(color: Colors.white), ), subtitle: Text( user.phone, style: const TextStyle(color: Colors.white54), ), trailing: IconButton( icon: const Icon(Icons.person_add, color: Colors.blue), onPressed: () => _inviteUser(user), ), ); }).toList(), ), ), ], const SizedBox(height: 16), // Invited users list if (_invitedUsers.isNotEmpty) ...[ const Text( 'Invited:', style: TextStyle( color: Colors.white70, fontSize: 14, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), Wrap( spacing: 8, runSpacing: 8, children: _invitedUsers.map((name) { return Chip( avatar: CircleAvatar( backgroundColor: Colors.green.withAlpha(50), child: const Icon( Icons.check, size: 16, color: Colors.green, ), ), label: Text(name), deleteIcon: const Icon(Icons.close, size: 18), onDeleted: () => _removeInvite(name), backgroundColor: Colors.grey.shade800, labelStyle: const TextStyle(color: Colors.white), ); }).toList(), ), ], const Spacer(), // Continue button if (_invitedUsers.isNotEmpty) FilledButton.icon( onPressed: _continueToRestaurants, icon: const Icon(Icons.group), label: Text('Continue with ${_invitedUsers.length + 1} people'), style: FilledButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), ) else FilledButton( onPressed: _continueToRestaurants, style: FilledButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), child: const Text('Continue Alone'), ), const SizedBox(height: 12), // Skip button TextButton( onPressed: _skipInvites, child: const Text( 'Skip this step', style: TextStyle(color: Colors.white54), ), ), ], ), ), ), ); } } class _UserResult { final int userId; final String name; final String phone; const _UserResult({ required this.userId, required this.name, required this.phone, }); }