diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 2d821e5..8054142 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -47,6 +47,10 @@
+ LSApplicationQueriesSchemes
+
+ mailto
+
NSPhotoLibraryUsageDescription
We need access to your photo library to set your profile photo.
NSCameraUsageDescription
diff --git a/lib/features/agents/presentation/screens/agent_edit_profile_screen.dart b/lib/features/agents/presentation/screens/agent_edit_profile_screen.dart
index a4b025f..9479350 100644
--- a/lib/features/agents/presentation/screens/agent_edit_profile_screen.dart
+++ b/lib/features/agents/presentation/screens/agent_edit_profile_screen.dart
@@ -341,42 +341,36 @@ class _AgentEditProfileScreenState
Widget build(BuildContext context) {
final asyncData = ref.watch(_editProfileDataProvider);
- return Scaffold(
- backgroundColor: const Color(0xFFF5F7FA),
- body: SafeArea(
- bottom: false,
- child: Column(
- children: [
- // Header with circular back button (SVG) matching Figma
- Padding(
- padding: const EdgeInsets.fromLTRB(16, 4, 16, 8),
- child: Row(
- children: [
- GestureDetector(
- onTap: () => context.pop(),
- child: SvgPicture.asset(
- 'assets/icons/back_circle_icon.svg',
- width: 32,
- height: 32,
- ),
+ return Column(
+ children: [
+ // Header with circular back button (SVG) matching Figma
+ Padding(
+ padding: const EdgeInsets.fromLTRB(16, 4, 16, 8),
+ child: Row(
+ children: [
+ GestureDetector(
+ onTap: () => context.pop(),
+ child: SvgPicture.asset(
+ 'assets/icons/back_circle_icon.svg',
+ width: 32,
+ height: 32,
),
- const SizedBox(width: 12),
- const Text(
- 'Edit Profile',
- style: TextStyle(
- fontFamily: 'Fractul',
- fontSize: 16,
- fontWeight: FontWeight.w700,
- color: AppColors.primaryDark,
- ),
+ ),
+ const SizedBox(width: 12),
+ const Text(
+ 'Edit Profile',
+ style: TextStyle(
+ fontFamily: 'Fractul',
+ fontSize: 16,
+ fontWeight: FontWeight.w700,
+ color: AppColors.primaryDark,
),
- ],
- ),
+ ),
+ ],
),
- Expanded(child: _buildBody(asyncData)),
- ],
),
- ),
+ Expanded(child: _buildBody(asyncData)),
+ ],
);
}
@@ -667,6 +661,13 @@ class _AgentEditProfileScreenState
onTap: () {
setState(() {
entries.removeAt(i);
+ // Clear cached controllers for this section's entries
+ // so they get recreated with correct values after
+ // re-indexing
+ final fieldSlugs =
+ fields.map((f) => f['slug'] as String? ?? '');
+ _tagControllers.removeWhere((key, _) =>
+ fieldSlugs.any((s) => key.startsWith('${s}_entry')));
});
},
child: const Icon(
@@ -688,6 +689,7 @@ class _AgentEditProfileScreenState
entries[i][slug] = val;
});
},
+ controllerKeySuffix: 'entry$i',
);
}),
],
@@ -731,6 +733,7 @@ class _AgentEditProfileScreenState
Map field, {
dynamic Function()? getValue,
void Function(dynamic)? setValue,
+ String? controllerKeySuffix,
}) {
final slug = field['slug'] as String? ?? '';
final fieldType = field['fieldType'] as String? ?? 'TEXT';
@@ -770,6 +773,7 @@ class _AgentEditProfileScreenState
placeholder,
validation,
false,
+ controllerKeySuffix: controllerKeySuffix,
);
break;
case 'TEXTAREA':
@@ -780,6 +784,7 @@ class _AgentEditProfileScreenState
placeholder,
validation,
true,
+ controllerKeySuffix: controllerKeySuffix,
);
break;
case 'NUMBER':
@@ -789,6 +794,7 @@ class _AgentEditProfileScreenState
updateValue,
placeholder,
validation,
+ controllerKeySuffix: controllerKeySuffix,
);
break;
case 'DATE':
@@ -851,6 +857,7 @@ class _AgentEditProfileScreenState
currentValue,
updateValue,
placeholder,
+ controllerKeySuffix: controllerKeySuffix,
);
break;
case 'RANGE':
@@ -870,6 +877,7 @@ class _AgentEditProfileScreenState
placeholder,
validation,
false,
+ controllerKeySuffix: controllerKeySuffix,
);
}
@@ -937,9 +945,12 @@ class _AgentEditProfileScreenState
void Function(dynamic) setValue,
String placeholder,
Map? validation,
- bool multiline,
- ) {
- final key = '${slug}_text';
+ bool multiline, {
+ String? controllerKeySuffix,
+ }) {
+ final key = controllerKeySuffix != null
+ ? '${slug}_${controllerKeySuffix}_text'
+ : '${slug}_text';
if (!_tagControllers.containsKey(key)) {
final controller = TextEditingController(text: '${getValue() ?? ''}');
_tagControllers[key] = controller;
@@ -974,9 +985,12 @@ class _AgentEditProfileScreenState
dynamic Function() getValue,
void Function(dynamic) setValue,
String placeholder,
- Map? validation,
- ) {
- final key = '${slug}_number';
+ Map? validation, {
+ String? controllerKeySuffix,
+ }) {
+ final key = controllerKeySuffix != null
+ ? '${slug}_${controllerKeySuffix}_number'
+ : '${slug}_number';
if (!_tagControllers.containsKey(key)) {
final val = getValue();
final controller = TextEditingController(text: val != null ? '$val' : '');
@@ -1377,16 +1391,20 @@ class _AgentEditProfileScreenState
String slug,
dynamic Function() getValue,
void Function(dynamic) setValue,
- String placeholder,
- ) {
+ String placeholder, {
+ String? controllerKeySuffix,
+ }) {
final tags = List.from((getValue() ?? []) as List);
- if (!_tagControllers.containsKey(slug)) {
+ final tagKey = controllerKeySuffix != null
+ ? '${slug}_${controllerKeySuffix}'
+ : slug;
+ if (!_tagControllers.containsKey(tagKey)) {
final controller = TextEditingController();
- _tagControllers[slug] = controller;
+ _tagControllers[tagKey] = controller;
_controllers.add(controller);
}
- final controller = _tagControllers[slug]!;
+ final controller = _tagControllers[tagKey]!;
void addTag(String text) {
final trimmed = text.trim();
diff --git a/lib/features/faq/presentation/screens/faq_screen.dart b/lib/features/faq/presentation/screens/faq_screen.dart
index c5da0a5..83b04c1 100644
--- a/lib/features/faq/presentation/screens/faq_screen.dart
+++ b/lib/features/faq/presentation/screens/faq_screen.dart
@@ -400,17 +400,15 @@ class _StillNeedHelpSection extends ConsumerWidget {
_buildSupportButton(
icon: Icons.email_outlined,
label: 'Email Support',
- onTap: () async {
+ onTap: () {
final uri = Uri(
scheme: 'mailto',
- path: 'support@requesn.com',
+ path: 'support@re-quest.co',
queryParameters: {
'subject': 'Support Request',
},
);
- if (await canLaunchUrl(uri)) {
- await launchUrl(uri);
- }
+ launchUrl(uri, mode: LaunchMode.externalApplication);
},
),
],
diff --git a/lib/features/messaging/presentation/screens/chat_screen.dart b/lib/features/messaging/presentation/screens/chat_screen.dart
index 4c0c7c4..46c0f06 100644
--- a/lib/features/messaging/presentation/screens/chat_screen.dart
+++ b/lib/features/messaging/presentation/screens/chat_screen.dart
@@ -1158,7 +1158,7 @@ class _ChatScreenState extends ConsumerState {
void _showImageFullScreen(BuildContext context, String imageUrl) {
final isDirectUrl = imageUrl.startsWith('http://') || imageUrl.startsWith('https://');
- Navigator.of(context).push(
+ Navigator.of(context, rootNavigator: true).push(
MaterialPageRoute(
builder: (_) => Scaffold(
backgroundColor: Colors.black,
diff --git a/lib/features/profile/presentation/widgets/billing_tab.dart b/lib/features/profile/presentation/widgets/billing_tab.dart
index a9c53a7..77637bd 100644
--- a/lib/features/profile/presentation/widgets/billing_tab.dart
+++ b/lib/features/profile/presentation/widgets/billing_tab.dart
@@ -173,7 +173,7 @@ class _BillingTabState extends ConsumerState {
text: TextSpan(
children: [
TextSpan(
- text: '\$${plan!['amount']}',
+ text: '\$${_formatAmount(plan!['amount'])}',
style: const TextStyle(
fontFamily: 'Fractul',
fontSize: 35,
@@ -340,25 +340,24 @@ class _BillingTabState extends ConsumerState {
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- SizedBox(
- width: 155,
- height: 43,
- child: ElevatedButton(
- onPressed: _startCheckout,
- style: ElevatedButton.styleFrom(
- backgroundColor: AppColors.accentOrange,
- side: const BorderSide(color: AppColors.accentOrange),
- padding: EdgeInsets.zero,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(15)),
- ),
- child: const Text('Get Premium Access',
- style: TextStyle(
- fontFamily: 'Fractul',
- fontSize: 14,
- fontWeight: FontWeight.w700,
- color: Colors.white)),
+ ElevatedButton(
+ onPressed: _startCheckout,
+ style: ElevatedButton.styleFrom(
+ backgroundColor: AppColors.accentOrange,
+ side: const BorderSide(color: AppColors.accentOrange),
+ padding: const EdgeInsets.symmetric(
+ horizontal: 20, vertical: 12),
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(15)),
),
+ child: const Text('Get Premium Access',
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ style: TextStyle(
+ fontFamily: 'Fractul',
+ fontSize: 14,
+ fontWeight: FontWeight.w700,
+ color: Colors.white)),
),
const Spacer(),
ClipRRect(
@@ -556,7 +555,7 @@ class _BillingTabState extends ConsumerState {
final repo = ref.read(profileRepositoryProvider);
final url = await repo.createPortalSession();
if (!mounted) return;
- await Navigator.of(context).push