feat: redirect agents to profile on login, update UI layouts, and add analytics dependencies.

This commit is contained in:
pradeepkumar
2026-05-06 13:19:31 +05:30
parent c6b96e19dc
commit 8845e77274
10 changed files with 293 additions and 175 deletions

View File

@@ -9,9 +9,13 @@ PODS:
- GoogleUtilities/Environment (~> 8.0)
- GoogleUtilities/UserDefaults (~> 8.0)
- PromisesObjC (~> 2.4)
- connectivity_plus (0.0.1):
- Flutter
- CwlCatchException (2.2.1):
- CwlCatchExceptionSupport (~> 2.2.1)
- CwlCatchExceptionSupport (2.2.1)
- device_info_plus (0.0.1):
- Flutter
- emoji_picker_flutter (0.0.1):
- Flutter
- FBAEMKit (18.0.2):
@@ -22,11 +26,20 @@ PODS:
- FBSDKCoreKit_Basics (18.0.2)
- FBSDKLoginKit (18.0.2):
- FBSDKCoreKit (= 18.0.2)
- Firebase/Analytics (11.15.0):
- Firebase/Core
- Firebase/Core (11.15.0):
- Firebase/CoreOnly
- FirebaseAnalytics (~> 11.15.0)
- Firebase/CoreOnly (11.15.0):
- FirebaseCore (~> 11.15.0)
- Firebase/Messaging (11.15.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 11.15.0)
- firebase_analytics (11.6.0):
- Firebase/Analytics (= 11.15.0)
- firebase_core
- Flutter
- firebase_core (3.15.2):
- Firebase/CoreOnly (= 11.15.0)
- Flutter
@@ -34,6 +47,24 @@ PODS:
- Firebase/Messaging (= 11.15.0)
- firebase_core
- Flutter
- FirebaseAnalytics (11.15.0):
- FirebaseAnalytics/Default (= 11.15.0)
- FirebaseCore (~> 11.15.0)
- FirebaseInstallations (~> 11.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseAnalytics/Default (11.15.0):
- FirebaseCore (~> 11.15.0)
- FirebaseInstallations (~> 11.0)
- GoogleAppMeasurement/Default (= 11.15.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- FirebaseCore (11.15.0):
- FirebaseCoreInternal (~> 11.15.0)
- GoogleUtilities/Environment (~> 8.1)
@@ -68,6 +99,32 @@ PODS:
- FlutterMacOS
- GoogleSignIn (~> 8.0)
- GTMSessionFetcher (>= 3.4.0)
- GoogleAdsOnDeviceConversion (2.1.0):
- GoogleUtilities/Logger (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Core (11.15.0):
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/Default (11.15.0):
- GoogleAdsOnDeviceConversion (= 2.1.0)
- GoogleAppMeasurement/Core (= 11.15.0)
- GoogleAppMeasurement/IdentitySupport (= 11.15.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleAppMeasurement/IdentitySupport (11.15.0):
- GoogleAppMeasurement/Core (= 11.15.0)
- GoogleUtilities/AppDelegateSwizzler (~> 8.1)
- GoogleUtilities/MethodSwizzler (~> 8.1)
- GoogleUtilities/Network (~> 8.1)
- "GoogleUtilities/NSData+zlib (~> 8.1)"
- nanopb (~> 3.30910.0)
- GoogleDataTransport (10.1.0):
- nanopb (~> 3.30910.0)
- PromisesObjC (~> 2.4)
@@ -86,6 +143,9 @@ PODS:
- GoogleUtilities/Logger (8.1.0):
- GoogleUtilities/Environment
- GoogleUtilities/Privacy
- GoogleUtilities/MethodSwizzler (8.1.0):
- GoogleUtilities/Logger
- GoogleUtilities/Privacy
- GoogleUtilities/Network (8.1.0):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
@@ -110,6 +170,8 @@ PODS:
- GTMSessionFetcher/Core
- image_picker_ios (0.0.1):
- Flutter
- memory_info (0.0.1):
- Flutter
- nanopb (3.30910.0):
- nanopb/decode (= 3.30910.0)
- nanopb/encode (= 3.30910.0)
@@ -138,7 +200,10 @@ PODS:
- FlutterMacOS
DEPENDENCIES:
- connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
- emoji_picker_flutter (from `.symlinks/plugins/emoji_picker_flutter/ios`)
- firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
- firebase_core (from `.symlinks/plugins/firebase_core/ios`)
- firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
- Flutter (from `Flutter`)
@@ -147,6 +212,7 @@ DEPENDENCIES:
- flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
- google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/darwin`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- memory_info (from `.symlinks/plugins/memory_info/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
@@ -166,10 +232,13 @@ SPEC REPOS:
- FBSDKCoreKit_Basics
- FBSDKLoginKit
- Firebase
- FirebaseAnalytics
- FirebaseCore
- FirebaseCoreInternal
- FirebaseInstallations
- FirebaseMessaging
- GoogleAdsOnDeviceConversion
- GoogleAppMeasurement
- GoogleDataTransport
- GoogleSignIn
- GoogleUtilities
@@ -179,8 +248,14 @@ SPEC REPOS:
- PromisesObjC
EXTERNAL SOURCES:
connectivity_plus:
:path: ".symlinks/plugins/connectivity_plus/ios"
device_info_plus:
:path: ".symlinks/plugins/device_info_plus/ios"
emoji_picker_flutter:
:path: ".symlinks/plugins/emoji_picker_flutter/ios"
firebase_analytics:
:path: ".symlinks/plugins/firebase_analytics/ios"
firebase_core:
:path: ".symlinks/plugins/firebase_core/ios"
firebase_messaging:
@@ -197,6 +272,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/google_sign_in_ios/darwin"
image_picker_ios:
:path: ".symlinks/plugins/image_picker_ios/ios"
memory_info:
:path: ".symlinks/plugins/memory_info/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
@@ -215,16 +292,20 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73
AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f
connectivity_plus: 2a701ffec2c0ae28a48cf7540e279787e77c447d
CwlCatchException: 7acc161b299a6de7f0a46a6ed741eae2c8b4d75a
CwlCatchExceptionSupport: 54ccab8d8c78907b57f99717fb19d4cc3bce02dc
device_info_plus: bf2e3232933866d73fe290f2942f2156cdd10342
emoji_picker_flutter: 8e50ec5caac456a23a78637e02c6293ea0ac8771
FBAEMKit: 56a4f5a9607957b547b6458b17a98c5bb2736367
FBSDKCoreKit: 54f1240567e16862ab71c53c33dc347db5c524c5
FBSDKCoreKit_Basics: eb530cd6a79030dbb11df460aafb2767bcad9028
FBSDKLoginKit: 6a70798793e499335a98fab1a758d7da34af196e
Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e
firebase_analytics: bf93e20703c95030404d6ddbb1adf05bf5c3885b
firebase_core: 99a37263b3c27536063a7b601d9e2a49400a433c
firebase_messaging: bf6697c61f31c7cc0f654131212ff04c0115c2c7
FirebaseAnalytics: 6433dfd311ba78084fc93bdfc145e8cb75740eae
FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e
FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4
FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843
@@ -234,12 +315,15 @@ SPEC CHECKSUMS:
flutter_local_notifications: df98d66e515e1ca797af436137b4459b160ad8c9
flutter_secure_storage: d33dac7ae2ea08509be337e775f6b59f1ff45f12
google_sign_in_ios: 7411fab6948df90490dc4620ecbcabdc3ca04017
GoogleAdsOnDeviceConversion: 2be6297a4f048459e0ae17fad9bfd2844e10cf64
GoogleAppMeasurement: 700dce7541804bec33db590a5c496b663fbe2539
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleSignIn: ce8c89bb9b37fb624b92e7514cc67335d1e277e4
GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de
GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6
image_picker_ios: 4f2f91b01abdb52842a8e277617df877e40f905b
memory_info: 18a37c81d0c57151f6661fd007b05f8894427a0a
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46

View File

@@ -1336,8 +1336,10 @@ class _AgentHomeContentState extends ConsumerState<_AgentHomeContent> {
color: const Color(0xFFE6E6E6),
padding: const EdgeInsets.symmetric(vertical: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text('Specialization',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Fractul',
fontSize: 20,
@@ -1345,6 +1347,7 @@ class _AgentHomeContentState extends ConsumerState<_AgentHomeContent> {
color: AppColors.primaryDark)),
const SizedBox(height: 4),
const Text('Area Of Expertise and Focus',
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Fractul',
fontSize: 14,
@@ -1365,8 +1368,7 @@ class _AgentHomeContentState extends ConsumerState<_AgentHomeContent> {
final hasMore = card.values.length > 3;
return Container(
margin: const EdgeInsets.symmetric(horizontal: 66, vertical: 8),
width: 298,
margin: const EdgeInsets.symmetric(horizontal: 24, vertical: 8),
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 20),
decoration: BoxDecoration(
color: Colors.white,
@@ -1375,11 +1377,13 @@ class _AgentHomeContentState extends ConsumerState<_AgentHomeContent> {
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Icon(Icons.category_outlined,
size: 28, color: AppColors.accentOrange),
const SizedBox(height: 10),
Text(displayName,
textAlign: TextAlign.center,
style: const TextStyle(
fontFamily: 'Fractul',
fontSize: 14,

View File

@@ -170,7 +170,7 @@ class _AgentSearchScreenState extends ConsumerState<AgentSearchScreen> {
color: AppColors.primaryDark,
),
decoration: InputDecoration(
hintText: 'Search Agents',
hintText: 'Search Professionals',
hintStyle: TextStyle(
fontFamily: 'Fractul',
fontSize: 14,

View File

@@ -65,7 +65,10 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
// Navigate on auth state changes
ref.listen<AuthState>(authProvider, (previous, next) {
if (next.status == AuthStatus.authenticated) {
context.go('/home');
// Agents land on /profile (defaults to "Edit Profile" tab —
// their dashboard/home view). Users land on /home.
final isAgent = next.user?.role == 'AGENT';
context.go(isAgent ? '/profile' : '/home');
}
// Navigate to 2FA verification screen
if (next.requiresTwoFactor && next.tempToken != null) {

View File

@@ -95,10 +95,12 @@ class _Verify2faScreenState extends ConsumerState<Verify2faScreen> {
final authState = ref.watch(authProvider);
final isLoading = authState.status == AuthStatus.loading;
// Navigate to home when authentication succeeds, reset submit lock on error
// Navigate when authentication succeeds, reset submit lock on error.
// Agents land on /profile (Edit Profile tab — their home/dashboard view).
ref.listen<AuthState>(authProvider, (previous, next) {
if (next.status == AuthStatus.authenticated) {
context.go('/home');
final isAgent = next.user?.role == 'AGENT';
context.go(isAgent ? '/profile' : '/home');
}
if (next.status != AuthStatus.loading) {
_isSubmitting = false;

View File

@@ -479,25 +479,33 @@ class _FeaturesSectionState extends ConsumerState<FeaturesSection> {
const SizedBox(height: 8),
// Location
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SvgPicture.asset(
'assets/icons/location_filled_icon.svg',
width: 15,
height: 15,
placeholderBuilder: (_) => const Icon(
Icons.location_on,
color: AppColors.accentOrange,
size: 15,
Padding(
padding: const EdgeInsets.only(top: 2),
child: SvgPicture.asset(
'assets/icons/location_filled_icon.svg',
width: 15,
height: 15,
placeholderBuilder: (_) => const Icon(
Icons.location_on,
color: AppColors.accentOrange,
size: 15,
),
),
),
const SizedBox(width: 4),
Text(
agent.location,
style: const TextStyle(
fontFamily: 'SourceSerif4',
fontSize: 14,
fontWeight: FontWeight.w500,
color: AppColors.primaryDark,
Expanded(
child: Text(
agent.location,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontFamily: 'SourceSerif4',
fontSize: 14,
fontWeight: FontWeight.w500,
color: AppColors.primaryDark,
),
),
),
],

View File

@@ -21,18 +21,18 @@ class _OnboardingScreenState extends State<OnboardingScreen> {
iconAsset: 'assets/images/onboarding_1_icon.svg',
iconWidth: 110,
iconHeight: 100,
title: 'Connect with Top\nProfessionals',
title: 'Connect with Top Professionals',
subtitle:
'Professionals can list properties and find qualified\nbuyers faster than ever.',
'Professionals can list properties and find qualified buyers faster than ever.',
),
_OnboardingData(
bgAsset: 'assets/images/onboarding_2_bg.svg',
iconAsset: 'assets/images/onboarding_2_icon.svg',
iconWidth: 83,
iconHeight: 75,
title: 'Real help. Real professionals.\nInstantly.',
title: 'Real help. Real professionals. Instantly.',
subtitle:
'Chat with professionals and get answers about\nproperties instantly.',
'Chat with professionals and get answers about properties instantly.',
),
];
@@ -208,150 +208,151 @@ class _OnboardingPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
// Illustration section - takes upper portion
Expanded(
flex: 5,
child: Padding(
padding: const EdgeInsets.only(left: 0, top: 8),
child: Align(
alignment: Alignment.centerLeft,
child: SizedBox(
width: MediaQuery.of(context).size.width - 24,
child: Stack(
alignment: Alignment.center,
children: [
// Background oval/pill shape with orange gradient
SvgPicture.asset(
// Scale the illustration to ~38% of screen height so it shrinks on small
// devices, leaving room for the title + subtitle without overflow.
final screenHeight = MediaQuery.of(context).size.height;
final illustrationHeight = (screenHeight * 0.38).clamp(220.0, 346.0);
return SingleChildScrollView(
physics: const ClampingScrollPhysics(),
child: Column(
children: [
// Illustration section
Padding(
padding: const EdgeInsets.only(top: 8),
child: SizedBox(
width: MediaQuery.of(context).size.width - 24,
height: illustrationHeight,
child: Stack(
alignment: Alignment.center,
children: [
// Background oval/pill shape with orange gradient
Positioned.fill(
child: SvgPicture.asset(
data.bgAsset,
width: 382,
height: 346,
fit: BoxFit.contain,
),
// Blurred decoration - bottom right
Positioned(
right: 20,
bottom: 20,
child: Container(
width: 160,
height: 160,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: AppColors.accentOrange.withValues(alpha: 0.2),
boxShadow: [
BoxShadow(
color: AppColors.accentOrange
.withValues(alpha: 0.15),
blurRadius: 40,
spreadRadius: 0,
),
],
),
),
// Blurred decoration - bottom right
Positioned(
right: 20,
bottom: 20,
child: Container(
width: 120,
height: 120,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: AppColors.accentOrange.withValues(alpha: 0.2),
boxShadow: [
BoxShadow(
color: AppColors.accentOrange
.withValues(alpha: 0.15),
blurRadius: 40,
spreadRadius: 0,
),
],
),
),
// Blurred decoration - top left
Positioned(
left: 0,
top: 0,
child: Container(
width: 160,
height: 160,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: AppColors.accentOrange.withValues(alpha: 0.1),
boxShadow: [
BoxShadow(
color: AppColors.accentOrange
.withValues(alpha: 0.08),
blurRadius: 40,
spreadRadius: 0,
),
],
),
),
// Blurred decoration - top left
Positioned(
left: 0,
top: 0,
child: Container(
width: 120,
height: 120,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: AppColors.accentOrange.withValues(alpha: 0.1),
boxShadow: [
BoxShadow(
color: AppColors.accentOrange
.withValues(alpha: 0.08),
blurRadius: 40,
spreadRadius: 0,
),
],
),
),
// Main icon + small icons
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
data.iconAsset,
width: data.iconWidth,
height: data.iconHeight,
),
const SizedBox(height: 16),
// Small property icons row
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
'assets/images/onboarding_small_icon_1.svg',
width: 27,
height: 27,
),
const SizedBox(width: 8),
SvgPicture.asset(
'assets/images/onboarding_small_icon_2.svg',
width: 31.5,
height: 31.5,
),
const SizedBox(width: 8),
SvgPicture.asset(
'assets/images/onboarding_small_icon_3.svg',
width: 24,
height: 27,
),
],
),
],
),
],
),
),
// Main icon + small icons
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
data.iconAsset,
width: data.iconWidth,
height: data.iconHeight,
),
const SizedBox(height: 12),
// Small property icons row
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(
'assets/images/onboarding_small_icon_1.svg',
width: 27,
height: 27,
),
const SizedBox(width: 8),
SvgPicture.asset(
'assets/images/onboarding_small_icon_2.svg',
width: 31.5,
height: 31.5,
),
const SizedBox(width: 8),
SvgPicture.asset(
'assets/images/onboarding_small_icon_3.svg',
width: 24,
height: 27,
),
],
),
],
),
],
),
),
),
),
// Text content section
Expanded(
flex: 3,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
// Text content section
Padding(
padding: const EdgeInsets.fromLTRB(24, 16, 24, 16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(height: 8),
// Title
Text(
data.title,
textAlign: TextAlign.center,
style: const TextStyle(
fontFamily: 'Fractul',
fontSize: 32,
fontSize: 26,
fontWeight: FontWeight.w700,
color: Color(0xFF0F172A),
height: 1.25,
letterSpacing: -0.8,
),
),
const SizedBox(height: 16),
const SizedBox(height: 12),
// Subtitle
Text(
data.subtitle,
textAlign: TextAlign.center,
style: const TextStyle(
fontFamily: 'SourceSerif4',
fontSize: 16,
fontSize: 15,
fontWeight: FontWeight.w400,
color: Color(0xFF475569),
height: 1.625,
height: 1.5,
),
),
],
),
),
),
],
],
),
);
}
}

View File

@@ -467,47 +467,54 @@ class _ProfileSettingsTabState extends ConsumerState<ProfileSettingsTab> {
}
return AlertDialog(
scrollable: true,
title: const Text('Change Email Address'),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
'A verification link will be sent to your new email. Your email changes only after you click the link.',
style: TextStyle(fontSize: 13),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const Text(
'A verification link will be sent to your new email. Your email changes only after you click the link.',
style: TextStyle(fontSize: 13),
),
const SizedBox(height: 16),
TextField(
controller: newEmailCtl,
keyboardType: TextInputType.emailAddress,
autocorrect: false,
enableSuggestions: false,
textCapitalization: TextCapitalization.none,
autofillHints: const [AutofillHints.email],
decoration: const InputDecoration(
labelText: 'New Email',
hintText: 'new@example.com',
),
const SizedBox(height: 16),
TextField(
controller: newEmailCtl,
keyboardType: TextInputType.emailAddress,
autocorrect: false,
textCapitalization: TextCapitalization.none,
decoration: const InputDecoration(
labelText: 'New Email',
hintText: 'new@example.com',
),
),
const SizedBox(height: 12),
TextField(
controller: passwordCtl,
obscureText: true,
autocorrect: false,
enableSuggestions: false,
// Empty autofillHints prevents iOS from showing the
// "Strong Password" suggestion bar, which was adding
// extra bottom inset and shifting the dialog upward.
autofillHints: const <String>[],
decoration: const InputDecoration(
labelText: 'Current Password',
),
),
if (localError != null) ...[
const SizedBox(height: 12),
TextField(
controller: passwordCtl,
obscureText: true,
decoration: const InputDecoration(
labelText: 'Current Password',
Text(
localError!,
style: const TextStyle(
color: Colors.red,
fontSize: 12,
),
),
if (localError != null) ...[
const SizedBox(height: 12),
Text(
localError!,
style: const TextStyle(
color: Colors.red,
fontSize: 12,
),
),
],
],
),
],
),
actions: [
TextButton(

View File

@@ -1,18 +1,20 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:real_estate_mobile/core/constants/app_colors.dart';
import 'package:real_estate_mobile/features/auth/presentation/providers/auth_provider.dart';
class SplashScreen extends StatefulWidget {
class SplashScreen extends ConsumerStatefulWidget {
const SplashScreen({super.key});
@override
State<SplashScreen> createState() => _SplashScreenState();
ConsumerState<SplashScreen> createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen>
class _SplashScreenState extends ConsumerState<SplashScreen>
with SingleTickerProviderStateMixin {
late final AnimationController _controller;
late final Animation<double> _fadeAnimation;
@@ -43,11 +45,15 @@ class _SplashScreenState extends State<SplashScreen>
final onboardingCompleted = prefs.getBool('onboarding_completed') ?? false;
if (!mounted) return;
if (onboardingCompleted) {
context.go('/home');
} else {
if (!onboardingCompleted) {
context.go('/onboarding');
return;
}
// Agents land on /profile (Edit Profile tab); everyone else on /home.
final authState = ref.read(authProvider);
final isAgent = authState.status == AuthStatus.authenticated &&
authState.user?.role == 'AGENT';
context.go(isAgent ? '/profile' : '/home');
}
@override

View File

@@ -23,6 +23,7 @@ import 'package:real_estate_mobile/features/agents/presentation/screens/agent_ed
import 'package:real_estate_mobile/features/profile/presentation/screens/payment_success_screen.dart';
import 'package:real_estate_mobile/features/splash/presentation/screens/splash_screen.dart';
import 'package:real_estate_mobile/features/onboarding/presentation/screens/onboarding_screen.dart';
import 'package:real_estate_mobile/features/agents/presentation/screens/agent_home_screen.dart';
import 'package:real_estate_mobile/features/auth/presentation/screens/verify_2fa_screen.dart';
import 'package:real_estate_mobile/features/support_chat/presentation/screens/support_chat_screen.dart';
import 'package:real_estate_mobile/features/coming_soon/presentation/screens/coming_soon_screen.dart';
@@ -288,8 +289,8 @@ final routerProvider = Provider<GoRouter>((ref) {
);
});
/// Always shows the user HomeScreen for /home. Agents reach their own
/// dashboard via the Edit Profile tab in the Profile section.
/// Reactively switches between HomeScreen and AgentHomeScreen based on auth.
/// Agents see their dashboard (profile view); users see the discovery home.
class _HomeRouteWrapper extends ConsumerWidget {
const _HomeRouteWrapper();
@@ -306,8 +307,10 @@ class _HomeRouteWrapper extends ConsumerWidget {
);
}
// Home icon always shows the User Home Page regardless of role.
// Agents access their own dashboard via the Edit Profile tab in /profile.
if (authState.status == AuthStatus.authenticated &&
authState.user?.role == 'AGENT') {
return const AgentHomeScreen();
}
return const HomeScreen();
}
}