feat: Add agent profile verification status fields and display corresponding UI banners on the agent home screen.
This commit is contained in:
@@ -17,6 +17,8 @@ class AgentProfile {
|
|||||||
final double? averageRating;
|
final double? averageRating;
|
||||||
final int totalReviews;
|
final int totalReviews;
|
||||||
final bool isVerified;
|
final bool isVerified;
|
||||||
|
final String? verificationStatus;
|
||||||
|
final String? verificationNote;
|
||||||
final bool isFeatured;
|
final bool isFeatured;
|
||||||
final bool isActive;
|
final bool isActive;
|
||||||
final bool isAvailable;
|
final bool isAvailable;
|
||||||
@@ -46,6 +48,8 @@ class AgentProfile {
|
|||||||
this.averageRating,
|
this.averageRating,
|
||||||
this.totalReviews = 0,
|
this.totalReviews = 0,
|
||||||
this.isVerified = false,
|
this.isVerified = false,
|
||||||
|
this.verificationStatus,
|
||||||
|
this.verificationNote,
|
||||||
this.isFeatured = false,
|
this.isFeatured = false,
|
||||||
this.isActive = true,
|
this.isActive = true,
|
||||||
this.isAvailable = false,
|
this.isAvailable = false,
|
||||||
@@ -214,6 +218,8 @@ class AgentProfile {
|
|||||||
averageRating: averageRating,
|
averageRating: averageRating,
|
||||||
totalReviews: totalReviews,
|
totalReviews: totalReviews,
|
||||||
isVerified: isVerified,
|
isVerified: isVerified,
|
||||||
|
verificationStatus: verificationStatus,
|
||||||
|
verificationNote: verificationNote,
|
||||||
isFeatured: isFeatured,
|
isFeatured: isFeatured,
|
||||||
isActive: isActive,
|
isActive: isActive,
|
||||||
isAvailable: isAvailable ?? this.isAvailable,
|
isAvailable: isAvailable ?? this.isAvailable,
|
||||||
@@ -246,6 +252,8 @@ class AgentProfile {
|
|||||||
averageRating: (json['averageRating'] as num?)?.toDouble(),
|
averageRating: (json['averageRating'] as num?)?.toDouble(),
|
||||||
totalReviews: json['totalReviews'] as int? ?? 0,
|
totalReviews: json['totalReviews'] as int? ?? 0,
|
||||||
isVerified: json['isVerified'] as bool? ?? false,
|
isVerified: json['isVerified'] as bool? ?? false,
|
||||||
|
verificationStatus: json['verificationStatus'] as String?,
|
||||||
|
verificationNote: json['verificationNote'] as String?,
|
||||||
isFeatured: json['isFeatured'] as bool? ?? false,
|
isFeatured: json['isFeatured'] as bool? ?? false,
|
||||||
isActive: json['isActive'] as bool? ?? true,
|
isActive: json['isActive'] as bool? ?? true,
|
||||||
isAvailable: json['isAvailable'] as bool? ?? false,
|
isAvailable: json['isAvailable'] as bool? ?? false,
|
||||||
|
|||||||
@@ -257,6 +257,7 @@ class _AgentHomeContentState extends ConsumerState<_AgentHomeContent> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
|
_buildVerificationBanner(agent),
|
||||||
_buildCoverAndAvatar(agent),
|
_buildCoverAndAvatar(agent),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
_buildStatusSection(agent),
|
_buildStatusSection(agent),
|
||||||
@@ -278,6 +279,131 @@ class _AgentHomeContentState extends ConsumerState<_AgentHomeContent> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Verification status banner ──
|
||||||
|
Widget _buildVerificationBanner(AgentProfile agent) {
|
||||||
|
final status = agent.verificationStatus;
|
||||||
|
if (status == null || status == 'APPROVED') return const SizedBox.shrink();
|
||||||
|
|
||||||
|
if (status == 'REJECTED') {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 22, vertical: 0),
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.only(bottom: 12),
|
||||||
|
padding: const EdgeInsets.all(14),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFFEF2F2),
|
||||||
|
border: Border.all(color: const Color(0xFFFECACA)),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.warning_amber_rounded, size: 18, color: Colors.red[700]),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
Text('Profile Verification Rejected',
|
||||||
|
style: TextStyle(fontFamily: 'Fractul', fontSize: 14, fontWeight: FontWeight.w700, color: Colors.red[800])),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
if (agent.verificationNote != null && agent.verificationNote!.isNotEmpty) ...[
|
||||||
|
const SizedBox(height: 6),
|
||||||
|
Text('Reason: ${agent.verificationNote}',
|
||||||
|
style: TextStyle(fontFamily: 'SourceSerif4', fontSize: 13, color: Colors.red[700])),
|
||||||
|
],
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text('Please update your profile and documents, then resubmit.',
|
||||||
|
style: TextStyle(fontFamily: 'SourceSerif4', fontSize: 13, color: Colors.red[600])),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => context.push('/agent/edit-profile'),
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.accentOrange,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: const Text('Update & Resubmit',
|
||||||
|
style: TextStyle(fontFamily: 'SourceSerif4', fontSize: 13, color: Colors.white, fontWeight: FontWeight.w600)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == 'PENDING_REVIEW') {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 22),
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.only(bottom: 12),
|
||||||
|
padding: const EdgeInsets.all(14),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFFEFCE8),
|
||||||
|
border: Border.all(color: const Color(0xFFFDE68A)),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(width: 10, height: 10, decoration: const BoxDecoration(color: Color(0xFFFBBF24), shape: BoxShape.circle)),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
const Expanded(
|
||||||
|
child: Text('Profile verification is under review. You will be notified once approved.',
|
||||||
|
style: TextStyle(fontFamily: 'Fractul', fontSize: 13, fontWeight: FontWeight.w700, color: Color(0xFF854D0E))),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == 'NONE') {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 22),
|
||||||
|
child: Container(
|
||||||
|
margin: const EdgeInsets.only(bottom: 12),
|
||||||
|
padding: const EdgeInsets.all(14),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFEFF6FF),
|
||||||
|
border: Border.all(color: const Color(0xFFBFDBFE)),
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.info_outline, size: 18, color: Colors.blue[700]),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
const Expanded(
|
||||||
|
child: Text('Complete your profile and upload verification documents to get verified.',
|
||||||
|
style: TextStyle(fontFamily: 'Fractul', fontSize: 13, fontWeight: FontWeight.w700, color: Color(0xFF1E40AF))),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => context.push('/agent/edit-profile'),
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: AppColors.accentOrange,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
|
),
|
||||||
|
child: const Text('Complete Profile',
|
||||||
|
style: TextStyle(fontFamily: 'SourceSerif4', fontSize: 13, color: Colors.white, fontWeight: FontWeight.w600)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
// ── Agent profile photo as cover image ──
|
// ── Agent profile photo as cover image ──
|
||||||
Widget _buildCoverAndAvatar(AgentProfile agent) {
|
Widget _buildCoverAndAvatar(AgentProfile agent) {
|
||||||
final screenWidth = MediaQuery.of(context).size.width;
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
|
|||||||
@@ -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+3
|
version: 1.0.0+4
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.10.1
|
sdk: ^3.10.1
|
||||||
|
|||||||
Reference in New Issue
Block a user