feat: add unlink confirmation dialog, enable agent navigation, update notification read status UI, and increment app version

This commit is contained in:
pradeepkumar
2026-04-24 12:50:49 +05:30
parent 9c89e93476
commit 0f49b21f33
4 changed files with 93 additions and 22 deletions

View File

@@ -448,12 +448,61 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
return; return;
} }
if (state.connectionState == 'accepted') { if (state.connectionState == 'accepted') {
ref.read(agentDetailProvider(widget.agentId).notifier).cancelConnection(); _showUnlinkConfirmation(state);
return; return;
} }
_showConnectModal(state); _showConnectModal(state);
} }
void _showUnlinkConfirmation(AgentDetailState state) {
final agentName = state.agent?.fullName ?? 'this agent';
showDialog<void>(
context: context,
builder: (ctx) => AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
title: const Text(
'Unlink Agent',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Color(0xFF00293d),
),
),
content: Text(
'Are you sure you want to unlink $agentName? You will need to send a new connection request to reconnect.',
style: const TextStyle(fontSize: 14, color: Color(0xFF4B5563)),
),
actions: [
TextButton(
onPressed: () => Navigator.of(ctx).pop(),
child: const Text(
'Cancel',
style: TextStyle(color: Color(0xFF6B7280)),
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFE58625),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
onPressed: () {
Navigator.of(ctx).pop();
ref
.read(agentDetailProvider(widget.agentId).notifier)
.cancelConnection();
},
child: const Text('Unlink'),
),
],
),
);
}
void _showConnectModal(AgentDetailState state) { void _showConnectModal(AgentDetailState state) {
final controller = TextEditingController(); final controller = TextEditingController();
showModalBottomSheet( showModalBottomSheet(

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
import 'package:real_estate_mobile/core/constants/app_colors.dart'; import 'package:real_estate_mobile/core/constants/app_colors.dart';
import 'package:real_estate_mobile/core/network/api_client.dart'; import 'package:real_estate_mobile/core/network/api_client.dart';
import 'package:real_estate_mobile/core/utils/image_url_resolver.dart'; import 'package:real_estate_mobile/core/utils/image_url_resolver.dart';
@@ -84,6 +85,7 @@ const _staticAgents = [
]; ];
class _StaticAgent { class _StaticAgent {
final String id;
final String name; final String name;
final String role; final String role;
final String rating; final String rating;
@@ -93,6 +95,7 @@ class _StaticAgent {
final bool isVerified; final bool isVerified;
const _StaticAgent({ const _StaticAgent({
this.id = '',
required this.name, required this.name,
required this.role, required this.role,
required this.rating, required this.rating,
@@ -154,6 +157,7 @@ class _FeaturesSectionState extends ConsumerState<FeaturesSection> {
} }
fetched.add(_StaticAgent( fetched.add(_StaticAgent(
id: agent['id'] as String? ?? '',
name: agent['name'] as String? ?? '', name: agent['name'] as String? ?? '',
role: agent['role'] as String? ?? '', role: agent['role'] as String? ?? '',
rating: agent['rating'] as String? ?? '', rating: agent['rating'] as String? ?? '',
@@ -335,7 +339,7 @@ class _FeaturesSectionState extends ConsumerState<FeaturesSection> {
} }
Widget _buildStaticAgentCard(_StaticAgent agent) { Widget _buildStaticAgentCard(_StaticAgent agent) {
return Container( final card = Container(
width: 254, width: 254,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: Colors.white,
@@ -530,5 +534,17 @@ class _FeaturesSectionState extends ConsumerState<FeaturesSection> {
], ],
), ),
); );
if (agent.id.isNotEmpty) {
return Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(15),
onTap: () => context.push('/agents/detail/${agent.id}'),
child: card,
),
);
}
return card;
} }
} }

View File

@@ -93,26 +93,32 @@ class _NotificationsScreenState extends ConsumerState<NotificationsScreen> {
return _buildFilterChip(label, 'unread'); return _buildFilterChip(label, 'unread');
}), }),
const Spacer(), const Spacer(),
GestureDetector( Builder(builder: (context) {
onTap: () async { final hasUnread = ref.watch(unreadCountProvider) > 0;
return GestureDetector(
onTap: hasUnread
? () async {
await ref await ref
.read(notificationListProvider.notifier) .read(notificationListProvider.notifier)
.markAllAsRead(); .markAllAsRead();
// Reload current filter to reflect changes
ref ref
.read(notificationListProvider.notifier) .read(notificationListProvider.notifier)
.loadNotifications(filter: _activeFilter); .loadNotifications(filter: _activeFilter);
}, }
child: const Text( : null,
child: Text(
'Mark all as read', 'Mark all as read',
style: TextStyle( style: TextStyle(
fontFamily: 'SourceSerif4', fontFamily: 'SourceSerif4',
fontSize: 13, fontSize: 13,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: AppColors.accentOrange, color: hasUnread
), ? AppColors.accentOrange
: AppColors.accentOrange.withValues(alpha: 0.4),
), ),
), ),
);
}),
], ],
), ),
), ),

View File

@@ -2,7 +2,7 @@ name: real_estate_mobile
description: "RE-Quest Real Estate Mobile App" description: "RE-Quest Real Estate Mobile App"
publish_to: 'none' publish_to: 'none'
version: 1.0.0+2 version: 1.0.0+3
environment: environment:
sdk: ^3.10.1 sdk: ^3.10.1