diff --git a/mitra_app/lib/core/chat/chat_request_notifier.dart b/mitra_app/lib/core/chat/chat_request_notifier.dart index 1478c39..f05667f 100644 --- a/mitra_app/lib/core/chat/chat_request_notifier.dart +++ b/mitra_app/lib/core/chat/chat_request_notifier.dart @@ -130,6 +130,22 @@ class ChatRequest extends _$ChatRequest { } } + /// Check if the current incoming request is still valid (pending_acceptance). + /// If stale, reset to listening state. + Future validateIncomingRequest() async { + if (state is! ChatRequestIncomingData) return; + final sessionId = (state as ChatRequestIncomingData).sessionId; + try { + final response = await _apiClient.get('/api/shared/chat/$sessionId/info'); + final status = response['data']?['status'] as String?; + if (status != 'pending_acceptance') { + state = const ChatRequestListeningData(); + } + } catch (_) { + state = const ChatRequestListeningData(); + } + } + Future accept(String sessionId) async { state = const ChatRequestAcceptingData(); try { diff --git a/mitra_app/lib/features/chat/widgets/incoming_request_sheet.dart b/mitra_app/lib/features/chat/widgets/incoming_request_sheet.dart index a8b52e7..8c821d2 100644 --- a/mitra_app/lib/features/chat/widgets/incoming_request_sheet.dart +++ b/mitra_app/lib/features/chat/widgets/incoming_request_sheet.dart @@ -8,6 +8,18 @@ class IncomingRequestSheet extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + final requestState = ref.watch(chatRequestProvider); + + // Request is still active — show accept/decline + if (requestState is ChatRequestIncomingData) { + return _buildActiveRequest(context, ref); + } + + // Request was taken by another mitra or cancelled — show info + return _buildStaleRequest(context); + } + + Widget _buildActiveRequest(BuildContext context, WidgetRef ref) { return Container( padding: const EdgeInsets.all(24), child: Column( @@ -52,4 +64,35 @@ class IncomingRequestSheet extends ConsumerWidget { ), ); } + + Widget _buildStaleRequest(BuildContext context) { + return Container( + padding: const EdgeInsets.all(24), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon(Icons.info_outline, size: 48, color: Colors.orange), + const SizedBox(height: 16), + const Text( + 'Permintaan tidak tersedia', + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), + ), + const SizedBox(height: 8), + const Text( + 'Permintaan ini sudah dibatalkan oleh customer atau diterima oleh Bestie lain.', + style: TextStyle(fontSize: 14, color: Colors.grey), + textAlign: TextAlign.center, + ), + const SizedBox(height: 24), + SizedBox( + width: double.infinity, + child: ElevatedButton( + onPressed: () => Navigator.of(context).pop(), + child: const Text('OK'), + ), + ), + ], + ), + ); + } } diff --git a/mitra_app/lib/features/home/home_screen.dart b/mitra_app/lib/features/home/home_screen.dart index 744a1c1..fc01918 100644 --- a/mitra_app/lib/features/home/home_screen.dart +++ b/mitra_app/lib/features/home/home_screen.dart @@ -32,7 +32,13 @@ class _HomeScreenState extends ConsumerState with WidgetsBindingObse if (state == AppLifecycleState.resumed) { final chatState = ref.read(chatRequestProvider); if (chatState is ChatRequestIncomingData) { - _showIncomingRequest(chatState.sessionId); + // Validate the request is still pending before showing + ref.read(chatRequestProvider.notifier).validateIncomingRequest().then((_) { + final current = ref.read(chatRequestProvider); + if (current is ChatRequestIncomingData) { + _showIncomingRequest(current.sessionId); + } + }); } } } @@ -65,7 +71,13 @@ class _HomeScreenState extends ConsumerState with WidgetsBindingObse // Listen for incoming chat requests ref.listen(chatRequestProvider, (prev, next) { if (next is ChatRequestIncomingData) { - _showIncomingRequest(next.sessionId); + // Validate request is still pending before showing sheet + ref.read(chatRequestProvider.notifier).validateIncomingRequest().then((_) { + final current = ref.read(chatRequestProvider); + if (current is ChatRequestIncomingData) { + _showIncomingRequest(current.sessionId); + } + }); } else if (next is ChatRequestAcceptedData) { final session = next.session; final sessionId = session['session_id'] as String? ?? session['id'] as String;