feat: Always display agent experience, specialization, and info card sections on the agent detail screen, showing empty states when data is unavailable.

This commit is contained in:
pradeepkumar
2026-03-14 23:41:50 +05:30
parent 04a57dc137
commit 2198cae027

View File

@@ -111,21 +111,17 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
const SizedBox(height: 16), const SizedBox(height: 16),
_buildProfileInfo(agent, state), _buildProfileInfo(agent, state),
// ── Experience Section ── // ── Experience Section (always show, like web) ──
if (_hasExperience(state)) ...[
const SizedBox(height: 24), const SizedBox(height: 24),
_buildExperienceSection(state), _buildExperienceSection(state),
],
// ── Info Cards (Availability, Work Env, Best Experience) ── // ── Info Cards (Availability, Work Env, Best Experience) ──
const SizedBox(height: 24), const SizedBox(height: 24),
_buildInfoCards(state), _buildInfoCards(state),
// ── Specialization Section ── // ── Specialization Section (always show, like web) ──
if (state.specializationCards.isNotEmpty) ...[
const SizedBox(height: 24), const SizedBox(height: 24),
_buildSpecializationSection(state), _buildSpecializationSection(state),
],
// ── Testimonials Section ── // ── Testimonials Section ──
if (state.testimonials.isNotEmpty) ...[ if (state.testimonials.isNotEmpty) ...[
@@ -707,13 +703,6 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
} }
// ── Experience ── // ── Experience ──
bool _hasExperience(AgentDetailState s) =>
s.yearsInExperience != '-' ||
s.contractsClosed != '-' ||
s.licensingAreas.isNotEmpty ||
s.expertiseYears.isNotEmpty ||
s.certifications.isNotEmpty;
Widget _buildExperienceSection(AgentDetailState state) { Widget _buildExperienceSection(AgentDetailState state) {
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 17), padding: const EdgeInsets.symmetric(horizontal: 17),
@@ -740,15 +729,18 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
_buildExperienceItem('Number of contracts closed', [ _buildExperienceItem('Number of contracts closed', [
state.contractsClosed, state.contractsClosed,
]), ]),
// Licensing Areas // Licensing Areas (always show)
if (state.licensingAreas.isNotEmpty) state.licensingAreas.isNotEmpty
_buildLicensingAreas(state.licensingAreas), ? _buildLicensingAreas(state.licensingAreas)
// Expertise Years : _buildEmptySection('Licensing & Areas', 'No licensed areas added'),
if (state.expertiseYears.isNotEmpty) // Expertise Years (always show)
_buildExpertiseYears(state.expertiseYears), state.expertiseYears.isNotEmpty
// Certifications ? _buildExpertiseYears(state.expertiseYears)
if (state.certifications.isNotEmpty) : _buildEmptySection('Areas in expertise & Years', 'No expertise areas added'),
_buildCertifications(state.certifications), // Certifications (always show)
state.certifications.isNotEmpty
? _buildCertifications(state.certifications)
: _buildEmptySection('Certifications', 'No certifications added'),
], ],
), ),
); );
@@ -811,6 +803,42 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
); );
} }
Widget _buildEmptySection(String title, String emptyText) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: const TextStyle(
fontFamily: 'Fractul',
fontSize: 14,
fontWeight: FontWeight.w700,
color: AppColors.primaryDark,
),
),
const SizedBox(height: 14),
Padding(
padding: const EdgeInsets.only(left: 10),
child: Text(
emptyText,
style: TextStyle(
fontFamily: 'SourceSerif4',
fontSize: 14,
fontWeight: FontWeight.w400,
color: AppColors.primaryDark.withValues(alpha: 0.4),
),
),
),
const SizedBox(height: 16),
Divider(
color: AppColors.primaryDark.withValues(alpha: 0.15),
height: 1,
),
const SizedBox(height: 10),
],
);
}
Widget _buildLicensingAreas(List<String> areas) { Widget _buildLicensingAreas(List<String> areas) {
return _ExpandableChipsSection( return _ExpandableChipsSection(
title: 'Licensing & Areas', title: 'Licensing & Areas',
@@ -859,33 +887,37 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
padding: const EdgeInsets.symmetric(horizontal: 36), padding: const EdgeInsets.symmetric(horizontal: 36),
child: Column( child: Column(
children: [ children: [
// Availability card // Availability card (always show)
if (state.availabilityType.isNotEmpty)
_buildInfoCard( _buildInfoCard(
icon: Icons.access_time_filled, icon: Icons.access_time_filled,
title: 'Availability', title: 'Availability',
subtitle: state.availabilityType, subtitle: state.availabilityType.isNotEmpty
items: state.availabilitySchedule, ? state.availabilityType
: 'Not specified',
items: state.availabilitySchedule.isNotEmpty
? state.availabilitySchedule
: null,
isEmpty: state.availabilityType.isEmpty,
), ),
if (workEnv.isNotEmpty) ...[
const SizedBox(height: 16), const SizedBox(height: 16),
// Work environment (always show)
_buildInfoCard( _buildInfoCard(
icon: Icons.landscape_outlined, icon: Icons.landscape_outlined,
title: '', title: 'Work Environment',
subtitle: '', subtitle: '',
description: workEnv, description: workEnv.isNotEmpty ? workEnv : 'Not specified',
isEmpty: workEnv.isEmpty,
), ),
],
if (bestExp.isNotEmpty) ...[
const SizedBox(height: 16), const SizedBox(height: 16),
// Best experience (always show)
_buildInfoCard( _buildInfoCard(
icon: Icons.star_rounded, icon: Icons.star_rounded,
title: '', title: 'Best Experience',
subtitle: '', subtitle: '',
description: bestExp, description: bestExp.isNotEmpty ? bestExp : 'Not specified',
isEmpty: bestExp.isEmpty,
), ),
], ],
],
), ),
); );
} }
@@ -896,6 +928,7 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
required String subtitle, required String subtitle,
List<String>? items, List<String>? items,
String? description, String? description,
bool isEmpty = false,
}) { }) {
return Container( return Container(
width: double.infinity, width: double.infinity,
@@ -932,11 +965,13 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
const SizedBox(height: 2), const SizedBox(height: 2),
Text( Text(
subtitle, subtitle,
style: const TextStyle( style: TextStyle(
fontFamily: 'SourceSerif4', fontFamily: 'SourceSerif4',
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: AppColors.primaryDark, color: isEmpty
? AppColors.primaryDark.withValues(alpha: 0.4)
: AppColors.primaryDark,
), ),
), ),
], ],
@@ -960,11 +995,13 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
description, description,
style: const TextStyle( style: TextStyle(
fontFamily: 'SourceSerif4', fontFamily: 'SourceSerif4',
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: AppColors.primaryDark, color: isEmpty
? AppColors.primaryDark.withValues(alpha: 0.4)
: AppColors.primaryDark,
), ),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
@@ -1002,11 +1039,22 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
if (state.specializationCards.isNotEmpty)
...state.specializationCards.map( ...state.specializationCards.map(
(card) => Padding( (card) => Padding(
padding: const EdgeInsets.only(bottom: 12), padding: const EdgeInsets.only(bottom: 12),
child: _SpecializationCardWidget(card: card), child: _SpecializationCardWidget(card: card),
), ),
)
else
Text(
'No specialization data added',
style: TextStyle(
fontFamily: 'SourceSerif4',
fontSize: 14,
fontWeight: FontWeight.w400,
color: AppColors.primaryDark.withValues(alpha: 0.4),
),
), ),
], ],
), ),