Extended SkillOptions.

Added MyElevatedButton added to unify Save Buttons.
master
Rafael 2024-06-22 21:56:45 +02:00
parent a13ed0e74b
commit c5a788c67f
13 changed files with 395 additions and 357 deletions

View File

@ -4,6 +4,7 @@ import 'package:geolocator/geolocator.dart';
import 'package:osm_nominatim/osm_nominatim.dart'; import 'package:osm_nominatim/osm_nominatim.dart';
import '../models/location.dart'; import '../models/location.dart';
import '../utils/helper.dart'; import '../utils/helper.dart';
import 'text_with_bold.dart';
class LocationSelector extends StatefulWidget { class LocationSelector extends StatefulWidget {
final Function(MyLocation) onLocationChanged; // Callback function final Function(MyLocation) onLocationChanged; // Callback function
@ -54,8 +55,8 @@ class LocationSelectorState extends State<LocationSelector> {
style: const TextStyle(color: Colors.red), style: const TextStyle(color: Colors.red),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
Text('Country: $_country'), TextWithBold(leadingText: 'Country:', boldText: ' $_country'),
Text('City: $_city'), TextWithBold(leadingText: 'City:', boldText: ' $_city'),
Text('Postal Code: ${_postalCode ?? ''}'), Text('Postal Code: ${_postalCode ?? ''}'),
Text('Street: $_street'), Text('Street: $_street'),
Text('State/Area: ${_administrativeArea ?? ''}'), Text('State/Area: ${_administrativeArea ?? ''}'),

View File

@ -0,0 +1,20 @@
import 'package:flutter/material.dart';
class MyElevatedButton extends StatelessWidget {
final void Function()? onPressed;
final Widget? child;
const MyElevatedButton({super.key, this.onPressed, required this.child});
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onPressed,
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all<Color>(
Theme.of(context).colorScheme.surfaceContainerHigh),
),
child: child,
);
}
}

View File

@ -6,6 +6,9 @@ class Constants {
static const String appVersion = '1.0.1'; static const String appVersion = '1.0.1';
static const String appCompilationDate = '2024-06-20'; static const String appCompilationDate = '2024-06-20';
static const int maxSectors = 10;
static const int maxSkills = 5;
static const String dbCollectionFeedbacks = 'feedbacks'; static const String dbCollectionFeedbacks = 'feedbacks';
static const String dbCollectionUsers = 'Users'; static const String dbCollectionUsers = 'Users';
static const String dbCollectionLanguages = 'languages'; static const String dbCollectionLanguages = 'languages';

View File

@ -33,33 +33,42 @@ enum Gender {
} }
enum SkillOption { enum SkillOption {
product,
finance,
engineering,
design,
marketing,
management, management,
data,
design,
engineering,
finance,
it,
legal,
marketing,
operations, operations,
legal; product,
software;
String get displayName { String get displayName {
switch (this) { switch (this) {
case SkillOption.product: case SkillOption.management:
return 'Product Development'; return 'Business Development';
case SkillOption.data:
return 'Data Analysis and Analytics';
case SkillOption.design: case SkillOption.design:
return 'Design'; return 'Design';
case SkillOption.engineering: case SkillOption.engineering:
return 'Engineering'; return 'Engineering';
case SkillOption.marketing:
return 'Sales and Marketing';
case SkillOption.finance: case SkillOption.finance:
return 'Finance'; return 'Finance and Accounting';
case SkillOption.management: case SkillOption.it:
return 'Management'; return 'Information Technology';
case SkillOption.operations:
return 'Operations';
case SkillOption.legal: case SkillOption.legal:
return 'Legal'; return 'Legal';
case SkillOption.marketing:
return 'Marketing and Sales';
case SkillOption.operations:
return 'Operations Management';
case SkillOption.product:
return 'Product Development';
case SkillOption.software:
return 'Software Development';
} }
} }
} }

View File

@ -1,6 +1,7 @@
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../components/my_elevated_button.dart';
import '../components/text_bold.dart'; import '../components/text_bold.dart';
import '../constants.dart'; import '../constants.dart';
import '../enumerations.dart'; import '../enumerations.dart';
@ -211,7 +212,7 @@ class CultureValuesFormPageState extends State<CultureValuesFormPage> {
); );
}), }),
const SizedBox(height: 20), const SizedBox(height: 20),
ElevatedButton( MyElevatedButton(
onPressed: handleSubmit, onPressed: handleSubmit,
child: Text(widget.isRegProcess ? 'Save and continue' : 'Save'), child: Text(widget.isRegProcess ? 'Save and continue' : 'Save'),
), ),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../components/my_elevated_button.dart';
import '../components/text_bold.dart'; import '../components/text_bold.dart';
import '../utils/helper.dart'; import '../utils/helper.dart';
@ -91,7 +92,7 @@ class ProfileCategoryFormState<T> extends State<ProfileCategoryForm<T>> {
), ),
const SizedBox(height: 16.0), const SizedBox(height: 16.0),
if (!widget.hideSaveButton) if (!widget.hideSaveButton)
ElevatedButton( MyElevatedButton(
onPressed: _saveButtonClicked, onPressed: _saveButtonClicked,
child: Text(widget.saveButtonText ?? 'Save'), child: Text(widget.saveButtonText ?? 'Save'),
), ),

View File

@ -1,6 +1,7 @@
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import '../components/my_elevated_button.dart';
import '../constants.dart'; import '../constants.dart';
import '../enumerations.dart'; import '../enumerations.dart';
import '../pages/registration_complete_page.dart'; import '../pages/registration_complete_page.dart';
@ -180,7 +181,7 @@ class RisksFormPageState extends State<RisksFormPage> {
}), }),
const SizedBox(height: 20), const SizedBox(height: 20),
Center( Center(
child: ElevatedButton( child: MyElevatedButton(
onPressed: handleSubmit, onPressed: handleSubmit,
child: child:
Text(widget.isRegProcess ? 'Save and continue' : 'Save'), Text(widget.isRegProcess ? 'Save and continue' : 'Save'),

View File

@ -31,15 +31,14 @@ class SectorsForm extends StatelessWidget {
return Text('Error: ${snapshot.error}'); return Text('Error: ${snapshot.error}');
} else { } else {
List<SectorOption>? userSectors = snapshot.data; List<SectorOption>? userSectors = snapshot.data;
int max = 10;
return ProfileCategoryForm( return ProfileCategoryForm(
title: 'Sectors of interest', title: 'Sectors of interest',
header: 'Sectors of interest', header: 'Sectors of interest',
description: 'Select up to $max sectors that match your interests.', description: 'Select up to ${Constants.maxSectors} sectors that match your interests.',
saveButtonText: isRegProcess ? 'Save and continue' : 'Save', saveButtonText: isRegProcess ? 'Save and continue' : 'Save',
options: SectorOption.values.toList(), // Convert enum to list options: SectorOption.values.toList(), // Convert enum to list
minSelections: 1, minSelections: 1,
maxSelections: max, maxSelections: Constants.maxSectors,
preSelectedOptions: userSectors ?? [], preSelectedOptions: userSectors ?? [],
onSave: (selectedOptions) async { onSave: (selectedOptions) async {
// Handle saving selected options // Handle saving selected options

View File

@ -41,12 +41,12 @@ class SkillsForm extends StatelessWidget {
? 'Skills you are searching for' ? 'Skills you are searching for'
: 'Your own skills', : 'Your own skills',
description: skillsSought description: skillsSought
? 'Choose up to 3 areas you are looking for in a co-founder' ? 'Choose up to ${Constants.maxSkills} areas you are looking for in a co-founder'
: 'Select up to 3 areas in which you are skilled', : 'Select up to ${Constants.maxSkills} areas in which you are skilled',
saveButtonText: isRegProcess ? 'Save and continue' : 'Save', saveButtonText: isRegProcess ? 'Save and continue' : 'Save',
options: SkillOption.values.toList(), // Convert enum values to list options: SkillOption.values.toList(), // Convert enum values to list
minSelections: 1, minSelections: 1,
maxSelections: 3, maxSelections: Constants.maxSkills,
preSelectedOptions: preSelectedOptions:
userSkills ?? [], // Pass pre-selected skills to the form userSkills ?? [], // Pass pre-selected skills to the form
onSave: (selectedOptions) async { onSave: (selectedOptions) async {

View File

@ -1,11 +1,11 @@
import 'dart:convert'; import 'dart:convert' show json;
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import '../components/location_dialog.dart'; import '../components/location_dialog.dart';
import '../components/my_button.dart'; import '../components/my_elevated_button.dart';
import '../components/text_bold.dart'; import '../components/text_bold.dart';
import '../components/text_with_bold.dart'; import '../components/text_with_bold.dart';
import '../constants.dart'; import '../constants.dart';
@ -554,9 +554,11 @@ class _UserDataPageState extends State<UserDataPage> {
const Divider(), const Divider(),
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: MyButton( child: MyElevatedButton(
text: widget.isRegProcess ? 'Save and continue' : 'Save', child: Text(
onTap: () { widget.isRegProcess ? 'Save and continue' : 'Save',
),
onPressed: () {
_saveButtonClicked(context); _saveButtonClicked(context);
}, },
), ),
@ -588,7 +590,7 @@ class _UserDataPageState extends State<UserDataPage> {
}); });
}, },
child: Text( child: Text(
_isLanguageListExpanded ? 'Show less languages' : 'Show more languages', _isLanguageListExpanded ? 'Show less' : 'Show full list',
), ),
); );
} }

View File

@ -499,14 +499,14 @@ class UserMatchingPageState extends State<UserMatchingPage> {
const TextBold( const TextBold(
text: 'You\'ve viewed all available profiles.', text: 'You\'ve viewed all available profiles.',
textAlign: TextAlign.center, textAlign: TextAlign.center,
fontSize: 24, fontSize: 20,
), ),
const SizedBox(height: 60), const SizedBox(height: 36),
const TextBold( const TextBold(
text: 'Would you like to do another run ' text: 'Would you like to do another run '
'and see the remaining profiles again?', 'and see the remaining profiles again?',
textAlign: TextAlign.center, textAlign: TextAlign.center,
fontSize: 24, fontSize: 20,
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
ElevatedButton( ElevatedButton(
@ -518,6 +518,7 @@ class UserMatchingPageState extends State<UserMatchingPage> {
}, },
child: const Text('Another run'), child: const Text('Another run'),
), ),
const SizedBox(height: 20), // additional space
], ],
), ),
), ),

View File

@ -260,12 +260,12 @@ class _UserProfilePageState extends State<UserProfilePage> {
if (isOwner) if (isOwner)
Divider(color: Theme.of(context).colorScheme.primary), Divider(color: Theme.of(context).colorScheme.primary),
if (isOwner) const SizedBox(height: 16), if (isOwner) const SizedBox(height: 16),
_buildWorkCulture(context), _buildRisks(context),
const SizedBox(height: 16), const SizedBox(height: 16),
if (isOwner) if (isOwner)
Divider(color: Theme.of(context).colorScheme.primary), Divider(color: Theme.of(context).colorScheme.primary),
if (isOwner) const SizedBox(height: 16), if (isOwner) const SizedBox(height: 16),
_buildRisks(context), _buildWorkCulture(context),
const SizedBox(height: 16), const SizedBox(height: 16),
if (isOwner) if (isOwner)
Divider(color: Theme.of(context).colorScheme.primary), Divider(color: Theme.of(context).colorScheme.primary),
@ -277,6 +277,324 @@ class _UserProfilePageState extends State<UserProfilePage> {
); );
} }
Widget _buildAvatar(BuildContext context) {
Widget genderIcon = const Icon(null);
if (myData.gender == Gender.male) {
genderIcon = const Padding(
padding: EdgeInsets.only(left: 4.0),
child: Icon(Icons.male, color: Colors.blue),
);
} else if (myData.gender == Gender.female) {
genderIcon = const Icon(Icons.female, color: Colors.pink);
}
return Column(
children: [
if (isOwner)
_editButton(context, editNameInfo, alignment: Alignment.bottomRight),
CircleAvatar(
radius: 80,
backgroundImage:
((profileImageUrl != null && profileImageUrl!.isNotEmpty))
? NetworkImage(profileImageUrl!)
: null,
child: (profileImageUrl == null || profileImageUrl!.isEmpty)
? const Icon(Icons.person, size: 80)
: null,
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Flexible(
child: Text(
isOwner
? myData.name
: '${myData.name} ${ageInfo(myData.born)}'.trim(),
style: const TextStyle(fontSize: 24),
),
),
genderIcon,
],
),
if (isOwner) Text(myData.email, style: const TextStyle(fontSize: 16)),
const SizedBox(height: 32),
Align(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
isOwner ? 'Short description of yourself' : 'Short description',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
ExpandableText(
linkEllipsis: false,
collapseOnTextTap: true,
expandOnTextTap: true,
myData.bio ?? 'n/a',
expandText: '[Expand]',
collapseText: '[Collapse]',
maxLines: 3,
linkColor: Colors.blue,
style: const TextStyle(fontSize: 16),
),
],
),
),
],
);
}
Widget _buildLocation(BuildContext context) {
int age = calcAge(myData.born);
return Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
myData.locations.length > 1 ? 'Locations' : 'Location',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
if (myData.locations.isEmpty)
const Text('n/a', style: TextStyle(fontSize: 16)),
if (myData.locations
.containsKey(Constants.dbDocMainLocation))
Text(
myData.locations[Constants.dbDocMainLocation]
.toString(),
style: const TextStyle(fontSize: 16),
),
if (myData.locations
.containsKey(Constants.dbDocSecondLocation))
Text(
myData.locations[Constants.dbDocSecondLocation]
.toString(),
style: const TextStyle(fontSize: 16),
),
],
),
if (isOwner)
_editButton(context, editUserDataInfo,
alignment: Alignment.bottomRight),
],
),
if (isOwner) const SizedBox(height: 16),
if (isOwner)
Text(
'Age',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
if (isOwner)
Text(
(age > 0 ? '$age years old, born ${myData.born}' : 'n/a'),
style: const TextStyle(fontSize: 16),
),
if (isOwner) const SizedBox(height: 16),
if (isOwner)
Text(
'Gender',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
if (isOwner)
Text(getDisplayText(myData.gender),
style: const TextStyle(fontSize: 16)),
const SizedBox(height: 16),
Text(
'Spoken languages',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
MyLanguageList(
langList: myData.languages,
textSize: 16,
),
],
),
),
],
);
}
Widget _buildSkills(BuildContext context) {
return Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Skills offered',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
Text(myData.skills.map((x) => x.displayName).join(', '),
style: const TextStyle(fontSize: 16)),
],
),
),
if (isOwner) _editButton(context, editUserSkillsInfo),
],
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Skills sought',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
Text(
myData.skillsSought
.map((x) => x.displayName)
.join(', '),
style: const TextStyle(fontSize: 16)),
],
),
),
if (isOwner) _editButton(context, editUserSkillsSoughtInfo),
],
),
],
),
),
],
);
}
Widget _buildSectors(BuildContext context) {
return Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Sectors of Interest',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
Text(
sortSectorsList(myData.sectors)
.map((x) => x.displayName)
.join('\n'),
style: const TextStyle(fontSize: 16)),
],
),
),
if (isOwner) _editButton(context, editUserSectorsInfo),
],
),
],
),
),
],
);
}
Widget _buildVision(BuildContext context) {
return Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Availability',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
Text(myData.availability.displayName,
style: const TextStyle(fontSize: 16)),
],
),
),
if (isOwner) _editButton(context, editUserVisionInfo),
],
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Vision and Goals',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
Text(
myData.visions
.map((x) => x.displayName)
.join(',\n'),
style: const TextStyle(fontSize: 16)),
],
),
),
],
),
],
),
),
],
);
}
Widget _buildRisks(BuildContext context) { Widget _buildRisks(BuildContext context) {
return Column( return Column(
children: [ children: [
@ -402,325 +720,6 @@ class _UserProfilePageState extends State<UserProfilePage> {
); );
} }
Widget _buildVision(BuildContext context) {
return Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Availability',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
Text(myData.availability.displayName,
style: const TextStyle(fontSize: 16)),
],
),
),
if (isOwner) _editButton(context, editUserVisionInfo),
],
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Vision and Goals',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
Text(
myData.visions
.map((x) => x.displayName)
.join(',\n'),
style: const TextStyle(fontSize: 16)),
],
),
),
],
),
],
),
),
],
);
}
Widget _buildSectors(BuildContext context) {
return Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Sectors of Interest',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
Text(
sortSectorsList(myData.sectors)
.map((x) => x.displayName)
.join('\n'),
style: const TextStyle(fontSize: 16)),
],
),
),
if (isOwner) _editButton(context, editUserSectorsInfo),
],
),
const SizedBox(height: 16),
],
),
),
],
);
}
Widget _buildSkills(BuildContext context) {
return Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Skills offered',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
Text(myData.skills.map((x) => x.displayName).join(', '),
style: const TextStyle(fontSize: 16)),
],
),
),
if (isOwner) _editButton(context, editUserSkillsInfo),
],
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Skills sought',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
Text(
myData.skillsSought
.map((x) => x.displayName)
.join(', '),
style: const TextStyle(fontSize: 16)),
],
),
),
if (isOwner) _editButton(context, editUserSkillsSoughtInfo),
],
),
],
),
),
],
);
}
Widget _buildLocation(BuildContext context) {
int age = calcAge(myData.born);
return Column(
children: [
Align(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
myData.locations.length > 1 ? 'Locations' : 'Location',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
if (myData.locations.isEmpty)
const Text('n/a', style: TextStyle(fontSize: 16)),
if (myData.locations
.containsKey(Constants.dbDocMainLocation))
Text(
myData.locations[Constants.dbDocMainLocation]
.toString(),
style: const TextStyle(fontSize: 16),
),
if (myData.locations
.containsKey(Constants.dbDocSecondLocation))
Text(
myData.locations[Constants.dbDocSecondLocation]
.toString(),
style: const TextStyle(fontSize: 16),
),
],
),
if (isOwner)
_editButton(context, editUserDataInfo,
alignment: Alignment.bottomRight),
],
),
if (isOwner) const SizedBox(height: 16),
if (isOwner)
Text(
'Age',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
if (isOwner)
Text(
(age > 0 ? '$age years old, born ${myData.born}' : 'n/a'),
style: const TextStyle(fontSize: 16),
),
if (isOwner) const SizedBox(height: 16),
if (isOwner)
Text(
'Gender',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
if (isOwner)
Text(getDisplayText(myData.gender),
style: const TextStyle(fontSize: 16)),
const SizedBox(height: 16),
Text(
'Spoken languages',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
MyLanguageList(
langList: myData.languages,
textSize: 16,
),
],
),
),
],
);
}
Widget _buildAvatar(BuildContext context) {
Widget genderIcon = const Icon(null);
if (myData.gender == Gender.male) {
genderIcon = const Padding(
padding: EdgeInsets.only(left: 4.0),
child: Icon(Icons.male, color: Colors.blue),
);
} else if (myData.gender == Gender.female) {
genderIcon = const Icon(Icons.female, color: Colors.pink);
}
return Column(
children: [
if (isOwner)
_editButton(context, editNameInfo, alignment: Alignment.bottomRight),
CircleAvatar(
radius: 80,
backgroundImage:
((profileImageUrl != null && profileImageUrl!.isNotEmpty))
? NetworkImage(profileImageUrl!)
: null,
child: (profileImageUrl == null || profileImageUrl!.isEmpty)
? const Icon(Icons.person, size: 80)
: null,
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Flexible(
child: Text(
isOwner
? myData.name
: '${myData.name} ${ageInfo(myData.born)}'.trim(),
style: const TextStyle(fontSize: 24),
),
),
genderIcon,
],
),
if (isOwner) Text(myData.email, style: const TextStyle(fontSize: 16)),
const SizedBox(height: 32),
Align(
alignment: Alignment.centerLeft,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
isOwner ? 'Short description of yourself' : 'Short description',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
ExpandableText(
linkEllipsis: false,
collapseOnTextTap: true,
expandOnTextTap: true,
myData.bio ?? 'n/a',
expandText: '[Expand]',
collapseText: '[Collapse]',
maxLines: 3,
linkColor: Colors.blue,
style: const TextStyle(fontSize: 16),
),
],
),
),
],
);
}
Widget _editButton(BuildContext context, void Function()? onPressedFunction, Widget _editButton(BuildContext context, void Function()? onPressedFunction,
{Alignment alignment = Alignment.topRight}) { {Alignment alignment = Alignment.topRight}) {
return Align( return Align(

View File

@ -1,6 +1,7 @@
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../components/my_elevated_button.dart';
import '../components/text_bold.dart'; import '../components/text_bold.dart';
import '../constants.dart'; import '../constants.dart';
import '../enumerations.dart'; import '../enumerations.dart';
@ -198,7 +199,7 @@ class UserVisionPageState extends State<UserVisionPage> {
}), }),
const SizedBox(height: 20), const SizedBox(height: 20),
Center( Center(
child: ElevatedButton( child: MyElevatedButton(
onPressed: handleSubmit, onPressed: handleSubmit,
child: child:
Text(widget.isRegProcess ? 'Save and continue' : 'Save'), Text(widget.isRegProcess ? 'Save and continue' : 'Save'),