feat: Add app icon generation, update profile navigation, and refine UI styling for profile action buttons and notification tabs.
This commit is contained in:
@@ -751,63 +751,7 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
|
||||
}
|
||||
|
||||
Widget _buildCertifications(List<Map<String, String>> certs) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Certifications',
|
||||
style: TextStyle(
|
||||
fontFamily: 'Fractul',
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.primaryDark,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
...certs.map((cert) => Padding(
|
||||
padding: const EdgeInsets.only(left: 14, bottom: 16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 2),
|
||||
child: Text('\u2022 ',
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: AppColors.primaryDark)),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
cert['name'] ?? '',
|
||||
style: const TextStyle(
|
||||
fontFamily: 'SourceSerif4',
|
||||
fontSize: 14,
|
||||
color: AppColors.primaryDark,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if ((cert['org'] ?? '').isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 20, top: 2),
|
||||
child: Text(
|
||||
cert['org']!.toUpperCase(),
|
||||
style: TextStyle(
|
||||
fontFamily: 'SourceSerif4',
|
||||
fontSize: 14,
|
||||
color: AppColors.primaryDark.withValues(alpha: 0.5),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
const SizedBox(height: 4),
|
||||
],
|
||||
);
|
||||
return _ExpandableCertificationsSection(certs: certs);
|
||||
}
|
||||
|
||||
// ── Info Cards (Availability, Work Env, Best Experience) ──
|
||||
@@ -1096,9 +1040,9 @@ class _ExpandableChipsSectionState extends State<_ExpandableChipsSection> {
|
||||
),
|
||||
),
|
||||
)),
|
||||
if (hasMore && !_expanded)
|
||||
if (hasMore)
|
||||
GestureDetector(
|
||||
onTap: () => setState(() => _expanded = true),
|
||||
onTap: () => setState(() => _expanded = !_expanded),
|
||||
child: IntrinsicWidth(
|
||||
child: Container(
|
||||
height: 28,
|
||||
@@ -1107,17 +1051,34 @@ class _ExpandableChipsSectionState extends State<_ExpandableChipsSection> {
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
border: Border.all(
|
||||
color: AppColors.primaryDark.withValues(alpha: 0.15),
|
||||
color: _expanded
|
||||
? AppColors.accentOrange
|
||||
: AppColors.primaryDark.withValues(alpha: 0.15),
|
||||
width: 1),
|
||||
),
|
||||
child: Text(
|
||||
'+${widget.items.length - widget.initialCount} More',
|
||||
style: const TextStyle(
|
||||
fontFamily: 'SourceSerif4',
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w300,
|
||||
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 : 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),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -1132,6 +1093,133 @@ class _ExpandableChipsSectionState extends State<_ExpandableChipsSection> {
|
||||
}
|
||||
}
|
||||
|
||||
// ── Expandable Certifications Section ──
|
||||
|
||||
class _ExpandableCertificationsSection extends StatefulWidget {
|
||||
final List<Map<String, String>> certs;
|
||||
final int initialCount;
|
||||
|
||||
const _ExpandableCertificationsSection({
|
||||
required this.certs,
|
||||
this.initialCount = 3,
|
||||
});
|
||||
|
||||
@override
|
||||
State<_ExpandableCertificationsSection> createState() =>
|
||||
_ExpandableCertificationsSectionState();
|
||||
}
|
||||
|
||||
class _ExpandableCertificationsSectionState
|
||||
extends State<_ExpandableCertificationsSection> {
|
||||
bool _expanded = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final showCerts = _expanded
|
||||
? widget.certs
|
||||
: widget.certs.take(widget.initialCount).toList();
|
||||
final hasMore = widget.certs.length > widget.initialCount;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Certifications',
|
||||
style: TextStyle(
|
||||
fontFamily: 'Fractul',
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.primaryDark,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
...showCerts.map((cert) => Padding(
|
||||
padding: const EdgeInsets.only(left: 14, bottom: 16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 2),
|
||||
child: Text('\u2022 ',
|
||||
style: TextStyle(
|
||||
fontSize: 14, color: AppColors.primaryDark)),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
cert['name'] ?? '',
|
||||
style: const TextStyle(
|
||||
fontFamily: 'SourceSerif4',
|
||||
fontSize: 14,
|
||||
color: AppColors.primaryDark,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if ((cert['org'] ?? '').isNotEmpty)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 20, top: 2),
|
||||
child: Text(
|
||||
cert['org']!.toUpperCase(),
|
||||
style: TextStyle(
|
||||
fontFamily: 'SourceSerif4',
|
||||
fontSize: 14,
|
||||
color:
|
||||
AppColors.primaryDark.withValues(alpha: 0.5),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)),
|
||||
if (hasMore)
|
||||
Center(
|
||||
child: GestureDetector(
|
||||
onTap: () => setState(() => _expanded = !_expanded),
|
||||
child: Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 14, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
border:
|
||||
Border.all(color: AppColors.accentOrange, width: 1),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
_expanded
|
||||
? 'Show Less'
|
||||
: '+${widget.certs.length - widget.initialCount} More',
|
||||
style: const TextStyle(
|
||||
fontFamily: 'SourceSerif4',
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w700,
|
||||
color: AppColors.accentOrange,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 2),
|
||||
Icon(
|
||||
_expanded
|
||||
? Icons.keyboard_arrow_up
|
||||
: Icons.keyboard_arrow_down,
|
||||
size: 14,
|
||||
color: AppColors.accentOrange,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Specialization Card ──
|
||||
|
||||
class _SpecializationCardWidget extends StatefulWidget {
|
||||
|
||||
@@ -83,7 +83,7 @@ class HomeScreen extends ConsumerWidget {
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'\u00A9 2025 RE-QuestN. All rights reserved.',
|
||||
'\u00A9 2025 RE-Quest. All rights reserved.',
|
||||
style: TextStyle(
|
||||
fontFamily: 'SourceSerif4',
|
||||
fontSize: 12,
|
||||
|
||||
@@ -90,7 +90,7 @@ class _ChangePasswordTabState extends ConsumerState<ChangePasswordTab> {
|
||||
const SizedBox(height: 40),
|
||||
ProfileActionButtons(
|
||||
onSave: _changePassword,
|
||||
onCancel: () => context.pop(),
|
||||
onCancel: () => context.go('/home'),
|
||||
isSaving: _isChangingPassword,
|
||||
saveLabel: 'Update Password',
|
||||
),
|
||||
|
||||
@@ -144,7 +144,7 @@ class _NotificationsTabState extends ConsumerState<NotificationsTab> {
|
||||
const SizedBox(height: 40),
|
||||
ProfileActionButtons(
|
||||
onSave: _saveNotificationSettings,
|
||||
onCancel: () => context.pop(),
|
||||
onCancel: () => context.go('/home'),
|
||||
isSaving: _isSavingNotifications,
|
||||
),
|
||||
],
|
||||
@@ -318,8 +318,8 @@ class _NotificationsTabState extends ConsumerState<NotificationsTab> {
|
||||
child: Center(
|
||||
child: isSelected
|
||||
? Container(
|
||||
height: 22,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 4),
|
||||
height: 24,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 3),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.accentOrange,
|
||||
borderRadius: BorderRadius.circular(15),
|
||||
@@ -328,17 +328,19 @@ class _NotificationsTabState extends ConsumerState<NotificationsTab> {
|
||||
child: Text(labels[i],
|
||||
style: const TextStyle(
|
||||
fontFamily: 'SourceSerif4',
|
||||
fontSize: 14,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: AppColors.primaryDark,
|
||||
height: 1.0,
|
||||
)),
|
||||
)
|
||||
: Text(labels[i],
|
||||
style: const TextStyle(
|
||||
fontFamily: 'SourceSerif4',
|
||||
fontSize: 14,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: AppColors.primaryDark,
|
||||
height: 1.0,
|
||||
)),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -150,7 +150,7 @@ class _PrivacyTabState extends ConsumerState<PrivacyTab> {
|
||||
const SizedBox(height: 20),
|
||||
ProfileActionButtons(
|
||||
onSave: _savePrivacyPreferences,
|
||||
onCancel: () => context.pop(),
|
||||
onCancel: () => context.go('/home'),
|
||||
isSaving: _isSavingPrivacy),
|
||||
const SizedBox(height: 24),
|
||||
ProfileSectionCard(
|
||||
|
||||
@@ -259,7 +259,7 @@ class _ProfileSettingsTabState extends ConsumerState<ProfileSettingsTab> {
|
||||
const SizedBox(height: 30),
|
||||
ProfileActionButtons(
|
||||
onSave: _saveProfileSettings,
|
||||
onCancel: () => context.pop(),
|
||||
onCancel: () => context.go('/home'),
|
||||
isSaving: profileState.isSaving,
|
||||
),
|
||||
],
|
||||
|
||||
@@ -97,56 +97,58 @@ class ProfileActionButtons extends StatelessWidget {
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: onCancel,
|
||||
child: Container(
|
||||
width: 143,
|
||||
height: 31,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
border: Border.all(
|
||||
color: AppColors.primaryDark.withValues(alpha: 0.1),
|
||||
width: 1,
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: onCancel,
|
||||
child: Container(
|
||||
height: 31,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
border: Border.all(
|
||||
color: AppColors.primaryDark.withValues(alpha: 0.1),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: const Text('Cancel',
|
||||
style: TextStyle(
|
||||
fontFamily: 'Fractul',
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: AppColors.primaryDark,
|
||||
)),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: const Text('Cancel',
|
||||
style: TextStyle(
|
||||
fontFamily: 'Fractul',
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: AppColors.primaryDark,
|
||||
)),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
GestureDetector(
|
||||
onTap: isSaving ? null : onSave,
|
||||
child: Container(
|
||||
width: 143,
|
||||
height: 31,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.accentOrange,
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: isSaving ? null : onSave,
|
||||
child: Container(
|
||||
height: 31,
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.accentOrange,
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: isSaving
|
||||
? const SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2, color: AppColors.primaryDark),
|
||||
)
|
||||
: Text(saveLabel,
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Fractul',
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: AppColors.primaryDark,
|
||||
)),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: isSaving
|
||||
? const SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2, color: AppColors.primaryDark),
|
||||
)
|
||||
: Text(saveLabel,
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Fractul',
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: AppColors.primaryDark,
|
||||
)),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user