From 9512f5ef8dfaf46ea062e3d502b279e93cbcda39 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Mon, 16 Mar 2026 14:23:31 +0530 Subject: [PATCH] feat: Add optional `agentTypeId` field to `RegisterRequest` model. --- .../screens/agent_detail_screen.dart | 117 +++++++++-------- .../auth/data/models/register_request.dart | 1 + .../data/models/register_request.freezed.dart | 39 +++--- .../auth/data/models/register_request.g.dart | 2 + .../presentation/providers/auth_provider.dart | 2 + .../presentation/screens/signup_screen.dart | 119 ++++++++++++++++-- .../presentation/widgets/hero_section.dart | 12 +- .../presentation/widgets/home_header.dart | 84 ++++++++----- 8 files changed, 264 insertions(+), 112 deletions(-) diff --git a/lib/features/agents/presentation/screens/agent_detail_screen.dart b/lib/features/agents/presentation/screens/agent_detail_screen.dart index 99c1f4a..7a2075b 100644 --- a/lib/features/agents/presentation/screens/agent_detail_screen.dart +++ b/lib/features/agents/presentation/screens/agent_detail_screen.dart @@ -624,70 +624,83 @@ class _AgentDetailScreenState extends ConsumerState { ), ], const SizedBox(height: 8), - // Location + Member Since (same line, matching web ProfileCard) + // Location (wrapping) + Member Since (separate line) Builder(builder: (_) { final parts = state.locationParts; - const maxVisible = 1; - final firstPart = parts.isNotEmpty ? parts.first : ''; + const maxVisible = 4; + final visibleParts = parts.take(maxVisible).join(', '); final remaining = parts.length - maxVisible; - return Row( - mainAxisAlignment: MainAxisAlignment.center, + return Column( children: [ if (parts.isNotEmpty) ...[ - SvgPicture.asset( - 'assets/icons/location_pin_icon.svg', - width: 18, - height: 18, + GestureDetector( + onTap: remaining > 0 ? () => _showLocationModal(parts) : null, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(top: 2), + child: SvgPicture.asset( + 'assets/icons/location_pin_icon.svg', + width: 18, + height: 18, + ), + ), + const SizedBox(width: 4), + Flexible( + child: Text.rich( + TextSpan( + children: [ + TextSpan( + text: visibleParts, + style: const TextStyle( + fontFamily: 'SourceSerif4', + fontSize: 14, + fontWeight: FontWeight.w700, + color: AppColors.primaryDark, + ), + ), + if (remaining > 0) + TextSpan( + text: ' +$remaining more', + style: const TextStyle( + fontFamily: 'SourceSerif4', + fontSize: 14, + fontWeight: FontWeight.w500, + color: AppColors.accentOrange, + ), + ), + ], + ), + textAlign: TextAlign.center, + ), + ), + ], + ), ), - const SizedBox(width: 4), - ConstrainedBox( - constraints: const BoxConstraints(maxWidth: 120), - child: Text( - firstPart, + const SizedBox(height: 6), + ], + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + 'assets/icons/calendar_icon.svg', + width: 18, + height: 18, + ), + const SizedBox(width: 4), + Text( + agent.memberSinceText, style: const TextStyle( fontFamily: 'SourceSerif4', - fontSize: 14, - fontWeight: FontWeight.w700, + fontSize: 13, + fontWeight: FontWeight.w500, color: AppColors.primaryDark, ), - overflow: TextOverflow.ellipsis, - maxLines: 1, ), - ), - if (remaining > 0) - GestureDetector( - onTap: () => _showLocationModal(parts), - child: Text( - ' +$remaining more', - style: const TextStyle( - fontFamily: 'SourceSerif4', - fontSize: 14, - fontWeight: FontWeight.w500, - color: AppColors.accentOrange, - ), - ), - ), - const SizedBox(width: 12), - ], - SvgPicture.asset( - 'assets/icons/calendar_icon.svg', - width: 18, - height: 18, - ), - const SizedBox(width: 4), - Flexible( - child: Text( - agent.memberSinceText, - style: const TextStyle( - fontFamily: 'SourceSerif4', - fontSize: 13, - fontWeight: FontWeight.w500, - color: AppColors.primaryDark, - ), - overflow: TextOverflow.ellipsis, - maxLines: 1, - ), + ], ), ], ); diff --git a/lib/features/auth/data/models/register_request.dart b/lib/features/auth/data/models/register_request.dart index 7b86157..bd5ff43 100644 --- a/lib/features/auth/data/models/register_request.dart +++ b/lib/features/auth/data/models/register_request.dart @@ -11,6 +11,7 @@ abstract class RegisterRequest with _$RegisterRequest { required String role, String? firstName, String? lastName, + String? agentTypeId, }) = _RegisterRequest; factory RegisterRequest.fromJson(Map json) => diff --git a/lib/features/auth/data/models/register_request.freezed.dart b/lib/features/auth/data/models/register_request.freezed.dart index 2259a83..e9a8c8b 100644 --- a/lib/features/auth/data/models/register_request.freezed.dart +++ b/lib/features/auth/data/models/register_request.freezed.dart @@ -15,7 +15,7 @@ T _$identity(T value) => value; /// @nodoc mixin _$RegisterRequest { - String get email; String get password; String get role; String? get firstName; String? get lastName; + String get email; String get password; String get role; String? get firstName; String? get lastName; String? get agentTypeId; /// Create a copy of RegisterRequest /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -28,16 +28,16 @@ $RegisterRequestCopyWith get copyWith => _$RegisterRequestCopyW @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is RegisterRequest&&(identical(other.email, email) || other.email == email)&&(identical(other.password, password) || other.password == password)&&(identical(other.role, role) || other.role == role)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is RegisterRequest&&(identical(other.email, email) || other.email == email)&&(identical(other.password, password) || other.password == password)&&(identical(other.role, role) || other.role == role)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.agentTypeId, agentTypeId) || other.agentTypeId == agentTypeId)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,email,password,role,firstName,lastName); +int get hashCode => Object.hash(runtimeType,email,password,role,firstName,lastName,agentTypeId); @override String toString() { - return 'RegisterRequest(email: $email, password: $password, role: $role, firstName: $firstName, lastName: $lastName)'; + return 'RegisterRequest(email: $email, password: $password, role: $role, firstName: $firstName, lastName: $lastName, agentTypeId: $agentTypeId)'; } @@ -48,7 +48,7 @@ abstract mixin class $RegisterRequestCopyWith<$Res> { factory $RegisterRequestCopyWith(RegisterRequest value, $Res Function(RegisterRequest) _then) = _$RegisterRequestCopyWithImpl; @useResult $Res call({ - String email, String password, String role, String? firstName, String? lastName + String email, String password, String role, String? firstName, String? lastName, String? agentTypeId }); @@ -65,13 +65,14 @@ class _$RegisterRequestCopyWithImpl<$Res> /// Create a copy of RegisterRequest /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? email = null,Object? password = null,Object? role = null,Object? firstName = freezed,Object? lastName = freezed,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? email = null,Object? password = null,Object? role = null,Object? firstName = freezed,Object? lastName = freezed,Object? agentTypeId = freezed,}) { return _then(_self.copyWith( email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable as String,role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable as String,firstName: freezed == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable as String?,lastName: freezed == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable +as String?,agentTypeId: freezed == agentTypeId ? _self.agentTypeId : agentTypeId // ignore: cast_nullable_to_non_nullable as String?, )); } @@ -157,10 +158,10 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( String email, String password, String role, String? firstName, String? lastName)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( String email, String password, String role, String? firstName, String? lastName, String? agentTypeId)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _RegisterRequest() when $default != null: -return $default(_that.email,_that.password,_that.role,_that.firstName,_that.lastName);case _: +return $default(_that.email,_that.password,_that.role,_that.firstName,_that.lastName,_that.agentTypeId);case _: return orElse(); } @@ -178,10 +179,10 @@ return $default(_that.email,_that.password,_that.role,_that.firstName,_that.last /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( String email, String password, String role, String? firstName, String? lastName) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( String email, String password, String role, String? firstName, String? lastName, String? agentTypeId) $default,) {final _that = this; switch (_that) { case _RegisterRequest(): -return $default(_that.email,_that.password,_that.role,_that.firstName,_that.lastName);case _: +return $default(_that.email,_that.password,_that.role,_that.firstName,_that.lastName,_that.agentTypeId);case _: throw StateError('Unexpected subclass'); } @@ -198,10 +199,10 @@ return $default(_that.email,_that.password,_that.role,_that.firstName,_that.last /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( String email, String password, String role, String? firstName, String? lastName)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String email, String password, String role, String? firstName, String? lastName, String? agentTypeId)? $default,) {final _that = this; switch (_that) { case _RegisterRequest() when $default != null: -return $default(_that.email,_that.password,_that.role,_that.firstName,_that.lastName);case _: +return $default(_that.email,_that.password,_that.role,_that.firstName,_that.lastName,_that.agentTypeId);case _: return null; } @@ -213,7 +214,7 @@ return $default(_that.email,_that.password,_that.role,_that.firstName,_that.last @JsonSerializable() class _RegisterRequest implements RegisterRequest { - const _RegisterRequest({required this.email, required this.password, required this.role, this.firstName, this.lastName}); + const _RegisterRequest({required this.email, required this.password, required this.role, this.firstName, this.lastName, this.agentTypeId}); factory _RegisterRequest.fromJson(Map json) => _$RegisterRequestFromJson(json); @override final String email; @@ -221,6 +222,7 @@ class _RegisterRequest implements RegisterRequest { @override final String role; @override final String? firstName; @override final String? lastName; +@override final String? agentTypeId; /// Create a copy of RegisterRequest /// with the given fields replaced by the non-null parameter values. @@ -235,16 +237,16 @@ Map toJson() { @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _RegisterRequest&&(identical(other.email, email) || other.email == email)&&(identical(other.password, password) || other.password == password)&&(identical(other.role, role) || other.role == role)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _RegisterRequest&&(identical(other.email, email) || other.email == email)&&(identical(other.password, password) || other.password == password)&&(identical(other.role, role) || other.role == role)&&(identical(other.firstName, firstName) || other.firstName == firstName)&&(identical(other.lastName, lastName) || other.lastName == lastName)&&(identical(other.agentTypeId, agentTypeId) || other.agentTypeId == agentTypeId)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,email,password,role,firstName,lastName); +int get hashCode => Object.hash(runtimeType,email,password,role,firstName,lastName,agentTypeId); @override String toString() { - return 'RegisterRequest(email: $email, password: $password, role: $role, firstName: $firstName, lastName: $lastName)'; + return 'RegisterRequest(email: $email, password: $password, role: $role, firstName: $firstName, lastName: $lastName, agentTypeId: $agentTypeId)'; } @@ -255,7 +257,7 @@ abstract mixin class _$RegisterRequestCopyWith<$Res> implements $RegisterRequest factory _$RegisterRequestCopyWith(_RegisterRequest value, $Res Function(_RegisterRequest) _then) = __$RegisterRequestCopyWithImpl; @override @useResult $Res call({ - String email, String password, String role, String? firstName, String? lastName + String email, String password, String role, String? firstName, String? lastName, String? agentTypeId }); @@ -272,13 +274,14 @@ class __$RegisterRequestCopyWithImpl<$Res> /// Create a copy of RegisterRequest /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? email = null,Object? password = null,Object? role = null,Object? firstName = freezed,Object? lastName = freezed,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? email = null,Object? password = null,Object? role = null,Object? firstName = freezed,Object? lastName = freezed,Object? agentTypeId = freezed,}) { return _then(_RegisterRequest( email: null == email ? _self.email : email // ignore: cast_nullable_to_non_nullable as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable as String,role: null == role ? _self.role : role // ignore: cast_nullable_to_non_nullable as String,firstName: freezed == firstName ? _self.firstName : firstName // ignore: cast_nullable_to_non_nullable as String?,lastName: freezed == lastName ? _self.lastName : lastName // ignore: cast_nullable_to_non_nullable +as String?,agentTypeId: freezed == agentTypeId ? _self.agentTypeId : agentTypeId // ignore: cast_nullable_to_non_nullable as String?, )); } diff --git a/lib/features/auth/data/models/register_request.g.dart b/lib/features/auth/data/models/register_request.g.dart index 5177f06..93b0ea8 100644 --- a/lib/features/auth/data/models/register_request.g.dart +++ b/lib/features/auth/data/models/register_request.g.dart @@ -13,6 +13,7 @@ _RegisterRequest _$RegisterRequestFromJson(Map json) => role: json['role'] as String, firstName: json['firstName'] as String?, lastName: json['lastName'] as String?, + agentTypeId: json['agentTypeId'] as String?, ); Map _$RegisterRequestToJson(_RegisterRequest instance) => @@ -22,4 +23,5 @@ Map _$RegisterRequestToJson(_RegisterRequest instance) => 'role': instance.role, 'firstName': instance.firstName, 'lastName': instance.lastName, + 'agentTypeId': instance.agentTypeId, }; diff --git a/lib/features/auth/presentation/providers/auth_provider.dart b/lib/features/auth/presentation/providers/auth_provider.dart index c9c4003..fe3cb14 100644 --- a/lib/features/auth/presentation/providers/auth_provider.dart +++ b/lib/features/auth/presentation/providers/auth_provider.dart @@ -168,6 +168,7 @@ class AuthNotifier extends StateNotifier { required String email, required String password, required String role, + String? agentTypeId, }) async { state = state.copyWith( status: AuthStatus.loading, @@ -188,6 +189,7 @@ class AuthNotifier extends StateNotifier { role: role, firstName: firstName, lastName: lastName, + agentTypeId: role == 'AGENT' ? agentTypeId : null, ), ); diff --git a/lib/features/auth/presentation/screens/signup_screen.dart b/lib/features/auth/presentation/screens/signup_screen.dart index 148992e..8c5c7db 100644 --- a/lib/features/auth/presentation/screens/signup_screen.dart +++ b/lib/features/auth/presentation/screens/signup_screen.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:real_estate_mobile/core/constants/app_colors.dart'; +import 'package:real_estate_mobile/features/agents/data/models/agent_type.dart'; +import 'package:real_estate_mobile/features/agents/presentation/providers/agents_provider.dart'; import 'package:real_estate_mobile/features/auth/presentation/providers/auth_provider.dart'; import 'package:real_estate_mobile/features/auth/presentation/widgets/auth_text_field.dart'; import 'package:real_estate_mobile/features/auth/presentation/widgets/or_divider.dart'; @@ -22,6 +24,16 @@ class _SignupScreenState extends ConsumerState { String _selectedRole = 'USER'; bool _obscurePassword = true; + List _agentTypes = []; + String? _selectedAgentTypeId; + bool _loadingAgentTypes = false; + + @override + void initState() { + super.initState(); + _fetchAgentTypes(); + } + @override void dispose() { _nameController.dispose(); @@ -30,6 +42,22 @@ class _SignupScreenState extends ConsumerState { super.dispose(); } + Future _fetchAgentTypes() async { + setState(() => _loadingAgentTypes = true); + try { + final repo = ref.read(agentsRepositoryProvider); + final types = await repo.getAgentTypes(); + if (mounted) { + setState(() { + _agentTypes = types; + _loadingAgentTypes = false; + }); + } + } catch (_) { + if (mounted) setState(() => _loadingAgentTypes = false); + } + } + String? _validateLocally() { if (_nameController.text.trim().isEmpty) { return 'Please enter your name'; @@ -40,6 +68,9 @@ class _SignupScreenState extends ConsumerState { if (_passwordController.text.isEmpty) { return 'Please enter a password'; } + if (_selectedRole == 'AGENT' && (_selectedAgentTypeId == null || _selectedAgentTypeId!.isEmpty)) { + return 'Please select an agent type'; + } return null; } @@ -60,6 +91,7 @@ class _SignupScreenState extends ConsumerState { email: _emailController.text.trim(), password: _passwordController.text, role: _selectedRole, + agentTypeId: _selectedRole == 'AGENT' ? _selectedAgentTypeId : null, ); } @@ -206,19 +238,10 @@ class _SignupScreenState extends ConsumerState { // Role toggle RoleToggle( selectedRole: _selectedRole, - onChanged: (role) => setState(() => _selectedRole = role), - ), - const SizedBox(height: 20), - - // Subtitle - Text( - 'Enter Your Name to Continue', - style: TextStyle( - fontFamily: 'Fractul', - fontSize: 14, - fontWeight: FontWeight.w300, - color: AppColors.primaryDark.withValues(alpha: 0.7), - ), + onChanged: (role) => setState(() { + _selectedRole = role; + if (role != 'AGENT') _selectedAgentTypeId = null; + }), ), const SizedBox(height: 20), @@ -296,6 +319,76 @@ class _SignupScreenState extends ConsumerState { ), ), ), + + // Agent type selector (only when AGENT role is selected) + if (_selectedRole == 'AGENT') ...[ + const SizedBox(height: 16), + Container( + height: 50, + decoration: BoxDecoration( + color: AppColors.white, + borderRadius: BorderRadius.circular(20), + ), + padding: const EdgeInsets.symmetric(horizontal: 16), + child: _loadingAgentTypes + ? const Center( + child: SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + color: AppColors.accentOrange, + ), + ), + ) + : DropdownButtonHideUnderline( + child: DropdownButton( + value: _selectedAgentTypeId, + hint: Text( + 'Select Agent Type', + style: TextStyle( + fontFamily: 'Fractul', + fontSize: 14, + fontWeight: FontWeight.w300, + color: AppColors.primaryDark.withValues(alpha: 0.5), + ), + ), + isExpanded: true, + icon: const Icon( + Icons.keyboard_arrow_down, + color: AppColors.primaryDark, + size: 22, + ), + style: const TextStyle( + fontFamily: 'Fractul', + fontSize: 14, + fontWeight: FontWeight.w400, + color: AppColors.primaryDark, + ), + items: _agentTypes + .map((type) => DropdownMenuItem( + value: type.id, + child: Text(type.name), + )) + .toList(), + onChanged: (value) => + setState(() => _selectedAgentTypeId = value), + ), + ), + ), + if (authState.getFieldError('agentTypeId') != null) + Padding( + padding: const EdgeInsets.only(top: 6, left: 12), + child: Text( + authState.getFieldError('agentTypeId')!, + style: const TextStyle( + fontFamily: 'Fractul', + fontSize: 12, + color: AppColors.error, + ), + ), + ), + ], const SizedBox(height: 24), // Sign Up button diff --git a/lib/features/home/presentation/widgets/hero_section.dart b/lib/features/home/presentation/widgets/hero_section.dart index bee9376..f955206 100644 --- a/lib/features/home/presentation/widgets/hero_section.dart +++ b/lib/features/home/presentation/widgets/hero_section.dart @@ -50,9 +50,19 @@ class _HeroSectionState extends ConsumerState { if (_selectedLocation != null) params['location'] = Uri.encodeComponent(_selectedLocation!); if (_selectedCategory != null) params['category'] = Uri.encodeComponent(_selectedCategory!); + if (params.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Please select at least one filter to search'), + backgroundColor: AppColors.accentOrange, + ), + ); + return; + } + final queryString = params.entries.map((e) => '${e.key}=${e.value}').join('&'); - context.push('/agents/search${queryString.isNotEmpty ? '?$queryString' : ''}'); + context.push('/agents/search?$queryString'); } Future _showTypePicker() async { diff --git a/lib/features/home/presentation/widgets/home_header.dart b/lib/features/home/presentation/widgets/home_header.dart index 7bdb3ff..3b9e2a3 100644 --- a/lib/features/home/presentation/widgets/home_header.dart +++ b/lib/features/home/presentation/widgets/home_header.dart @@ -341,20 +341,30 @@ class _MenuDrawer extends ConsumerWidget { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, - children: const [ - Icon( - Icons.logout_rounded, - color: AppColors.primaryDark, - size: 20, + children: [ + SizedBox( + height: 20, + width: 20, + child: Center( + child: Icon( + Icons.logout_rounded, + color: AppColors.primaryDark, + size: 18, + ), + ), ), - SizedBox(width: 8), - Text( - 'Log Out', - style: TextStyle( - fontFamily: 'Fractul', - fontSize: 14, - fontWeight: FontWeight.w700, - color: AppColors.primaryDark, + const SizedBox(width: 8), + const Padding( + padding: EdgeInsets.only(top: 1), + child: Text( + 'Log Out', + style: TextStyle( + fontFamily: 'Fractul', + fontSize: 14, + fontWeight: FontWeight.w700, + color: AppColors.primaryDark, + height: 1.0, + ), ), ), ], @@ -366,25 +376,11 @@ class _MenuDrawer extends ConsumerWidget { SizedBox( width: double.infinity, height: 54, - child: ElevatedButton.icon( + child: ElevatedButton( onPressed: () { Navigator.pop(context); context.push('/login'); }, - icon: const Icon( - Icons.login, - color: Colors.white, - size: 20, - ), - label: const Text( - 'Log In', - style: TextStyle( - fontFamily: 'Fractul', - fontSize: 16, - fontWeight: FontWeight.w700, - color: Colors.white, - ), - ), style: ElevatedButton.styleFrom( backgroundColor: AppColors.accentOrange, elevation: 0, @@ -392,6 +388,38 @@ class _MenuDrawer extends ConsumerWidget { borderRadius: BorderRadius.circular(15), ), ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 20, + width: 20, + child: Center( + child: Icon( + Icons.login, + color: Colors.white, + size: 18, + ), + ), + ), + const SizedBox(width: 8), + const Padding( + padding: EdgeInsets.only(top: 1), + child: Text( + 'Log In', + style: TextStyle( + fontFamily: 'Fractul', + fontSize: 16, + fontWeight: FontWeight.w700, + color: Colors.white, + height: 1.0, + ), + ), + ), + ], + ), ), ), const SizedBox(height: 12),