Add pending chat requests CTA on mitra home screen

- Backend: new GET /api/mitra/chat-requests/pending endpoint
- Backend: getPendingRequestsForMitra() queries unresponded notifications
  for sessions still in pending_acceptance status
- Mitra app: loadPendingRequests() fetches on screen load + status toggle
- Mitra app: activeRequestCount getter exposes queue size
- Mitra app: _PendingRequestsBanner widget shows count with tap-to-view

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-10 21:21:00 +08:00
parent b043b92b57
commit 1920507ec5
4 changed files with 124 additions and 1 deletions

View File

@@ -17,10 +17,23 @@ class HomeScreen extends ConsumerWidget {
? authData.profile['display_name'] as String
: '';
// Load pending requests if mitra is already online
final statusState = ref.watch(onlineStatusProvider);
if (statusState is StatusLoadedData && statusState.isOnline) {
final requestState = ref.watch(chatRequestProvider);
if (requestState is ChatRequestIdleData) {
Future.microtask(() {
ref.read(chatRequestProvider.notifier).startListening();
ref.read(chatRequestProvider.notifier).loadPendingRequests();
});
}
}
// Listen for status changes to start/stop chat request listening
ref.listen(onlineStatusProvider, (prev, next) {
if (next is StatusLoadedData && next.isOnline) {
ref.read(chatRequestProvider.notifier).startListening();
ref.read(chatRequestProvider.notifier).loadPendingRequests();
} else if (next is StatusLoadedData && !next.isOnline) {
ref.read(chatRequestProvider.notifier).stopListening();
}
@@ -44,6 +57,7 @@ class HomeScreen extends ConsumerWidget {
const SizedBox(height: 32),
const _StatusToggle(),
const SizedBox(height: 16),
const _PendingRequestsBanner(),
const _ActiveSessionsButton(),
],
),
@@ -111,6 +125,51 @@ class _StatusToggle extends ConsumerWidget {
}
}
class _PendingRequestsBanner extends ConsumerWidget {
const _PendingRequestsBanner();
@override
Widget build(BuildContext context, WidgetRef ref) {
final requestState = ref.watch(chatRequestProvider);
final count = ref.read(chatRequestProvider.notifier).activeRequestCount;
if (count == 0) return const SizedBox.shrink();
final isShowingOverlay = requestState is ChatRequestIncomingData ||
requestState is ChatRequestStaleData;
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Card(
color: Colors.blue.shade50,
child: ListTile(
leading: Badge(
label: Text('$count'),
child: const Icon(Icons.notifications_active, color: Colors.blue),
),
title: Text(
'$count permintaan chat menunggu',
style: const TextStyle(fontWeight: FontWeight.bold),
),
subtitle: isShowingOverlay
? null
: const Text('Ketuk untuk melihat'),
onTap: isShowingOverlay
? null
: () {
// Re-advance queue to show the next request overlay
final notifier = ref.read(chatRequestProvider.notifier);
if (requestState is ChatRequestListeningData) {
// Requests are queued but none is displayed — trigger next
notifier.ignore();
}
},
),
),
);
}
}
class _ActiveSessionsButton extends ConsumerWidget {
const _ActiveSessionsButton();