From 2760c149548032f4e0589422003db7dcbf3f1b43 Mon Sep 17 00:00:00 2001 From: pradeepkumar Date: Thu, 7 May 2026 11:59:21 +0530 Subject: [PATCH] refactor: convert horizontal wrap chips to full-width vertical stack list in agent screens --- .../screens/agent_detail_screen.dart | 245 +++++++++--------- .../screens/agent_home_screen.dart | 150 ++++++----- .../screens/agent_search_screen.dart | 81 +++--- 3 files changed, 256 insertions(+), 220 deletions(-) diff --git a/lib/features/agents/presentation/screens/agent_detail_screen.dart b/lib/features/agents/presentation/screens/agent_detail_screen.dart index bc3b937..437aa2e 100644 --- a/lib/features/agents/presentation/screens/agent_detail_screen.dart +++ b/lib/features/agents/presentation/screens/agent_detail_screen.dart @@ -1297,52 +1297,68 @@ class _ExpandableTagsWrapState extends State<_ExpandableTagsWrap> { _expanded ? widget.tags : widget.tags.take(widget.initialCount).toList(); final hasMore = widget.tags.length > widget.initialCount; + // Each chip fills the row width so all chips share the same left edge. return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Wrap( - alignment: WrapAlignment.center, - spacing: 8, - runSpacing: 8, - children: displayTags - .map((tag) => Container( - padding: - const EdgeInsets.symmetric(horizontal: 12, vertical: 5), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - border: Border.all( - color: AppColors.primaryDark, - width: 0.7, - ), - ), - child: Text( - tag, - style: const TextStyle( - fontFamily: 'SourceSerif4', - fontSize: 14, - fontWeight: FontWeight.w400, - color: AppColors.primaryDark, - ), - ), - )) - .toList(), - ), + for (int i = 0; i < displayTags.length; i++) ...[ + if (i > 0) const SizedBox(height: 8), + Container( + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + border: Border.all( + color: AppColors.primaryDark, + width: 0.7, + ), + ), + child: Text( + displayTags[i], + softWrap: true, + style: const TextStyle( + fontFamily: 'SourceSerif4', + fontSize: 14, + fontWeight: FontWeight.w400, + color: AppColors.primaryDark, + ), + ), + ), + ], if (hasMore) ...[ const SizedBox(height: 10), - GestureDetector( - onTap: () => setState(() => _expanded = !_expanded), - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - border: Border.all(color: AppColors.accentOrange, width: 0.7), - ), - child: Text( - _expanded ? 'Show Less' : 'Show More', - style: const TextStyle( - fontFamily: 'SourceSerif4', - fontSize: 10, - fontWeight: FontWeight.w700, - color: AppColors.accentOrange, + Align( + alignment: Alignment.center, + child: GestureDetector( + onTap: () => setState(() => _expanded = !_expanded), + child: Container( + padding: + const EdgeInsets.symmetric(horizontal: 16, vertical: 6), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + border: + Border.all(color: AppColors.accentOrange, width: 1), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + _expanded ? 'Show Less' : 'Show More', + style: const TextStyle( + fontFamily: 'SourceSerif4', + fontSize: 12, + fontWeight: FontWeight.w700, + color: AppColors.accentOrange, + ), + ), + const SizedBox(width: 4), + Icon( + _expanded + ? Icons.keyboard_arrow_up + : Icons.keyboard_arrow_down, + size: 14, + color: AppColors.accentOrange, + ), + ], ), ), ), @@ -1380,7 +1396,7 @@ class _ExpandableChipsSectionState extends State<_ExpandableChipsSection> { final hasMore = widget.items.length > widget.initialCount; return Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( widget.title, @@ -1392,85 +1408,80 @@ class _ExpandableChipsSectionState extends State<_ExpandableChipsSection> { ), ), const SizedBox(height: 14), - Wrap( - spacing: 10, - runSpacing: 10, - children: [ - ...showItems.map( - (item) => IntrinsicWidth( - child: Container( - height: 28, - padding: const EdgeInsets.symmetric(horizontal: 10), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - border: Border.all( - color: AppColors.primaryDark, - width: 0.7, - ), + // Each chip fills the row so all start at the same left edge. + for (int i = 0; i < showItems.length; i++) ...[ + if (i > 0) const SizedBox(height: 10), + Container( + padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + border: Border.all( + color: AppColors.primaryDark, + width: 0.7, + ), + ), + child: Text( + showItems[i], + softWrap: true, + style: const TextStyle( + fontFamily: 'SourceSerif4', + fontSize: 14, + fontWeight: FontWeight.w500, + color: AppColors.primaryDark, + ), + ), + ), + ], + if (hasMore || _expanded) ...[ + const SizedBox(height: 10), + Align( + alignment: Alignment.center, + child: GestureDetector( + onTap: () => setState(() => _expanded = !_expanded), + child: Container( + padding: + const EdgeInsets.symmetric(horizontal: 16, vertical: 6), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + border: Border.all( + color: _expanded + ? AppColors.accentOrange + : AppColors.primaryDark.withValues(alpha: 0.15), + width: 1, ), - child: Text( - item, - style: const TextStyle( - fontFamily: 'SourceSerif4', - fontSize: 14, - fontWeight: FontWeight.w500, - color: AppColors.primaryDark, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + _expanded + ? 'Show Less' + : '+${widget.items.length - widget.initialCount} More', + style: TextStyle( + fontFamily: 'SourceSerif4', + fontSize: _expanded ? 13 : 13, + fontWeight: FontWeight.w700, + color: _expanded + ? AppColors.accentOrange + : AppColors.primaryDark, + ), ), - ), + const SizedBox(width: 4), + Icon( + _expanded + ? Icons.keyboard_arrow_up + : Icons.keyboard_arrow_down, + size: 14, + color: _expanded + ? AppColors.accentOrange + : AppColors.primaryDark, + ), + ], ), ), ), - if (hasMore || _expanded) - GestureDetector( - onTap: () => setState(() => _expanded = !_expanded), - child: IntrinsicWidth( - child: Container( - height: 28, - padding: const EdgeInsets.symmetric(horizontal: 10), - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - border: Border.all( - color: _expanded - ? AppColors.accentOrange - : AppColors.primaryDark.withValues(alpha: 0.15), - width: 1, - ), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - _expanded - ? 'Show Less' - : '+${widget.items.length - widget.initialCount} More', - style: TextStyle( - fontFamily: 'SourceSerif4', - fontSize: _expanded ? 13 : 15, - fontWeight: _expanded - ? FontWeight.w700 - : FontWeight.w300, - color: _expanded - ? AppColors.accentOrange - : AppColors.primaryDark, - ), - ), - if (_expanded) ...[ - const SizedBox(width: 2), - const Icon( - Icons.keyboard_arrow_up, - size: 14, - color: AppColors.accentOrange, - ), - ], - ], - ), - ), - ), - ), - ], - ), + ), + ], const SizedBox(height: 14), Divider( color: AppColors.primaryDark.withValues(alpha: 0.15), diff --git a/lib/features/agents/presentation/screens/agent_home_screen.dart b/lib/features/agents/presentation/screens/agent_home_screen.dart index a58ecc1..1f22394 100644 --- a/lib/features/agents/presentation/screens/agent_home_screen.dart +++ b/lib/features/agents/presentation/screens/agent_home_screen.dart @@ -969,14 +969,19 @@ class _AgentHomeContentState extends ConsumerState<_AgentHomeContent> { color: AppColors.primaryDark)), ), const SizedBox(height: 8), - _buildTagsWrap( - state.expertiseYears - .map((e) => e['years']!.isNotEmpty - ? '${e['area']} – ${e['years']}' - : e['area']!) - .toList(), - sectionKey: 'expertise', - initialCount: 4, + // Force chips to fill the row so every chip starts at the same + // left edge — prevents short chips from appearing centered. + SizedBox( + width: double.infinity, + child: _buildTagsWrap( + state.expertiseYears + .map((e) => e['years']!.isNotEmpty + ? '${e['area']} – ${e['years']}' + : e['area']!) + .toList(), + sectionKey: 'expertise', + initialCount: 4, + ), ), ], if (state.certifications.isNotEmpty) ...[ @@ -1113,70 +1118,81 @@ class _AgentHomeContentState extends ConsumerState<_AgentHomeContent> { isExpanded ? tags : tags.take(initialCount).toList(); final remaining = tags.length - initialCount; - // Cap each chip's width so long taglines wrap inside the chip instead - // of overflowing the Wrap's row and clipping behind ancestor bounds. - return LayoutBuilder( - builder: (ctx, constraints) { - final maxChipWidth = constraints.maxWidth.isFinite - ? constraints.maxWidth - : MediaQuery.of(ctx).size.width - 32; - return Wrap( - spacing: 8, - runSpacing: 8, - children: [ - ...displayTags.map((tag) => ConstrainedBox( - constraints: BoxConstraints(maxWidth: maxChipWidth), - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 12, vertical: 6), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - border: Border.all( - color: AppColors.primaryDark, width: 0.7), - ), - child: Text( - tag, - softWrap: true, - style: const TextStyle( - fontFamily: 'SourceSerif4', - fontSize: 14, - fontWeight: FontWeight.w500, - color: AppColors.primaryDark), - ), - ), - )), - if (remaining > 0) - GestureDetector( - onTap: () { - setState(() { - if (isExpanded) { - _expandedTagSections.remove(sectionKey); - } else { - _expandedTagSections.add(sectionKey); - } - }); - }, - behavior: HitTestBehavior.opaque, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 12, vertical: 6), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(15), - border: Border.all( - color: AppColors.primaryDark, width: 0.1), - ), - child: Text( + // Each chip fills the full row width so all chips start at the same + // left edge regardless of text length. Long text wraps inside the chip. + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + for (int i = 0; i < displayTags.length; i++) ...[ + if (i > 0) const SizedBox(height: 8), + Container( + padding: const EdgeInsets.symmetric( + horizontal: 14, vertical: 10), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + border: + Border.all(color: AppColors.primaryDark, width: 0.7), + ), + child: Text( + displayTags[i], + softWrap: true, + style: const TextStyle( + fontFamily: 'SourceSerif4', + fontSize: 14, + fontWeight: FontWeight.w500, + color: AppColors.primaryDark), + ), + ), + ], + if (remaining > 0) ...[ + const SizedBox(height: 8), + Align( + alignment: Alignment.center, + child: GestureDetector( + onTap: () { + setState(() { + if (isExpanded) { + _expandedTagSections.remove(sectionKey); + } else { + _expandedTagSections.add(sectionKey); + } + }); + }, + behavior: HitTestBehavior.opaque, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 16, vertical: 6), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(15), + border: Border.all( + color: AppColors.accentOrange, width: 1), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( isExpanded ? 'Show Less' : '+$remaining More', style: const TextStyle( fontFamily: 'SourceSerif4', - fontSize: 15, - fontWeight: FontWeight.w300, - color: AppColors.primaryDark)), + fontSize: 12, + fontWeight: FontWeight.w600, + color: AppColors.accentOrange), + ), + const SizedBox(width: 4), + Icon( + isExpanded + ? Icons.keyboard_arrow_up + : Icons.keyboard_arrow_down, + size: 14, + color: AppColors.accentOrange, + ), + ], ), ), - ], - ); - }, + ), + ), + ], + ], ); } diff --git a/lib/features/agents/presentation/screens/agent_search_screen.dart b/lib/features/agents/presentation/screens/agent_search_screen.dart index 503efee..ce18a40 100644 --- a/lib/features/agents/presentation/screens/agent_search_screen.dart +++ b/lib/features/agents/presentation/screens/agent_search_screen.dart @@ -753,46 +753,55 @@ class _AgentCardState extends State<_AgentCard> { ), const SizedBox(height: 12), - // Expertise tags + // Expertise tags — full-width pills, all start at same left edge if (specializations.isNotEmpty) ...[ - Wrap( - alignment: WrapAlignment.start, - spacing: 6, - runSpacing: 6, - children: [ - ...(_tagsExpanded - ? specializations - : specializations.take(6)) - .map((tag) => _buildTag(tag)), - if (specializations.length > 6) - GestureDetector( - onTap: () => - setState(() => _tagsExpanded = !_tagsExpanded), - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 10, vertical: 5), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - color: AppColors.accentOrange - .withValues(alpha: 0.1), - border: Border.all( - color: AppColors.accentOrange, width: 0.7), - ), - child: Text( - _tagsExpanded - ? 'Show Less' - : '+${specializations.length - 6} more', - style: const TextStyle( - fontFamily: 'SourceSerif4', - fontSize: 13, - fontWeight: FontWeight.w600, - color: AppColors.accentOrange, + Builder(builder: (_) { + final visible = _tagsExpanded + ? specializations + : specializations.take(6).toList(); + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + for (int i = 0; i < visible.length; i++) ...[ + if (i > 0) const SizedBox(height: 6), + _buildTag(visible[i]), + ], + if (specializations.length > 6) ...[ + const SizedBox(height: 8), + Align( + alignment: Alignment.center, + child: GestureDetector( + onTap: () => setState( + () => _tagsExpanded = !_tagsExpanded), + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 5), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: AppColors.accentOrange + .withValues(alpha: 0.1), + border: Border.all( + color: AppColors.accentOrange, + width: 0.7), + ), + child: Text( + _tagsExpanded + ? 'Show Less' + : '+${specializations.length - 6} more', + style: const TextStyle( + fontFamily: 'SourceSerif4', + fontSize: 13, + fontWeight: FontWeight.w600, + color: AppColors.accentOrange, + ), + ), ), ), ), - ), - ], - ), + ], + ], + ); + }), const SizedBox(height: 14), ],