feat: Add app icon generation, update profile navigation, and refine UI styling for profile action buttons and notification tabs.

This commit is contained in:
pradeepkumar
2026-03-14 17:25:33 +05:30
parent 7b9c19ec67
commit 8411015075
44 changed files with 276 additions and 279 deletions

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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',
),

View File

@@ -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,
)),
),
),

View File

@@ -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(

View File

@@ -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,
),
],

View File

@@ -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,
)),
),
),
],

View File

@@ -23,7 +23,7 @@ class MyApp extends ConsumerWidget {
final router = ref.watch(routerProvider);
return MaterialApp.router(
title: 'RE-QuestN',
title: 'RE-Quest',
theme: AppTheme.light,
routerConfig: router,
debugShowCheckedModeBanner: false,