feat: Limit professional expertise tags to three with a "more" pill and implement save button state management for profile settings based on field changes.
This commit is contained in:
@@ -428,7 +428,7 @@ class _TopProfessionalsSectionState
|
|||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
],
|
],
|
||||||
|
|
||||||
// Expertise tags
|
// Expertise tags (max 3 visible + "more" pill)
|
||||||
if (expertiseTags.isNotEmpty) ...[
|
if (expertiseTags.isNotEmpty) ...[
|
||||||
const Text(
|
const Text(
|
||||||
'Expertise:',
|
'Expertise:',
|
||||||
@@ -444,10 +444,27 @@ class _TopProfessionalsSectionState
|
|||||||
alignment: WrapAlignment.start,
|
alignment: WrapAlignment.start,
|
||||||
spacing: 6,
|
spacing: 6,
|
||||||
runSpacing: 6,
|
runSpacing: 6,
|
||||||
children: expertiseTags
|
children: [
|
||||||
.take(6)
|
...expertiseTags.take(3).map((tag) => _buildTag(tag)),
|
||||||
.map((tag) => _buildTag(tag))
|
if (expertiseTags.length > 3)
|
||||||
.toList(),
|
Container(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(15),
|
||||||
|
color: AppColors.accentOrange.withValues(alpha: 0.1),
|
||||||
|
border: Border.all(color: AppColors.accentOrange, width: 0.7),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
'+${expertiseTags.length - 3} more',
|
||||||
|
style: const TextStyle(
|
||||||
|
fontFamily: 'SourceSerif4',
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: AppColors.accentOrange,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -38,10 +38,23 @@ class _ProfileSettingsTabState extends ConsumerState<ProfileSettingsTab> {
|
|||||||
_emailController = TextEditingController();
|
_emailController = TextEditingController();
|
||||||
_phoneController = TextEditingController();
|
_phoneController = TextEditingController();
|
||||||
_locationController = TextEditingController();
|
_locationController = TextEditingController();
|
||||||
|
// Listen for changes to enable/disable Cancel & Save buttons
|
||||||
|
_fullNameController.addListener(_onFieldChanged);
|
||||||
|
_titleController.addListener(_onFieldChanged);
|
||||||
|
_phoneController.addListener(_onFieldChanged);
|
||||||
|
_locationController.addListener(_onFieldChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onFieldChanged() {
|
||||||
|
setState(() {}); // triggers rebuild so _hasChanges is re-evaluated
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
_fullNameController.removeListener(_onFieldChanged);
|
||||||
|
_titleController.removeListener(_onFieldChanged);
|
||||||
|
_phoneController.removeListener(_onFieldChanged);
|
||||||
|
_locationController.removeListener(_onFieldChanged);
|
||||||
_fullNameController.dispose();
|
_fullNameController.dispose();
|
||||||
_titleController.dispose();
|
_titleController.dispose();
|
||||||
_emailController.dispose();
|
_emailController.dispose();
|
||||||
|
|||||||
@@ -146,8 +146,10 @@ class ProfileActionButtons extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
flex: 3,
|
flex: 3,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: isSaving ? null : onSave,
|
onTap: (isSaving || !hasChanges) ? null : onSave,
|
||||||
child: Container(
|
child: Opacity(
|
||||||
|
opacity: hasChanges ? 1.0 : 0.5,
|
||||||
|
child: Container(
|
||||||
height: 31,
|
height: 31,
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -174,6 +176,7 @@ class ProfileActionButtons extends StatelessWidget {
|
|||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user