Edit Risks.

master
Rafael 2024-05-31 23:55:33 +02:00
parent cfff83d734
commit 731601e9c0
6 changed files with 215 additions and 32 deletions

View File

@ -75,10 +75,11 @@ class _FeedbackDialogState extends State<FeedbackDialog> {
_firestore.collection(Constants.dbCollectionFeedbacks); _firestore.collection(Constants.dbCollectionFeedbacks);
// Write the server's timestamp and the user's feedback // Write the server's timestamp and the user's feedback
await collection.doc().set({ await collection.add({
'timestamp': FieldValue.serverTimestamp(), 'timestamp': FieldValue.serverTimestamp(),
'feedback': _feedbackController.text, 'feedback': _feedbackController.text,
'user': _authService.getCurrentUser()!.uid, 'user': _authService.getCurrentUser()!.uid,
'email': _authService.getCurrentUser()!.email,
}); });
message = 'Feedback sent successfully. Thank you!'; message = 'Feedback sent successfully. Thank you!';

View File

@ -88,6 +88,18 @@ enum AvailabilityOption {
return 'Full time (40 hours or more)'; return 'Full time (40 hours or more)';
} }
} }
/// @returns [AvailabilityOption.lessThan10Hours] in case [str] is null or empty
static AvailabilityOption fromString(String? str) {
if (str == null || str.isEmpty) {
return AvailabilityOption.lessThan10Hours; // return a default value
}
return AvailabilityOption.values.firstWhere(
(x) => x.toString() == str,
orElse: () =>
throw ArgumentError('Invalid AvailabilityOption enum value: $str'),
);
}
} }
enum WorkValueOption { enum WorkValueOption {
@ -128,6 +140,18 @@ enum CultureOption {
return 'Traditional and structured'; return 'Traditional and structured';
} }
} }
/// @returns [CultureOption.traditional] in case [str] is null or empty
static CultureOption fromString(String? str) {
if (str == null || str.isEmpty) {
return CultureOption.traditional; // return a default value
}
return CultureOption.values.firstWhere(
(x) => x.toString() == str,
orElse: () =>
throw ArgumentError('Invalid CultureOption enum value: $str'),
);
}
} }
enum CommunicationPreference { enum CommunicationPreference {
@ -148,6 +172,18 @@ enum CommunicationPreference {
return 'Formal reports and documentation'; return 'Formal reports and documentation';
} }
} }
/// @returns [CommunicationPreference.daily] in case [str] is null or empty
static CommunicationPreference fromString(String? str) {
if (str == null || str.isEmpty) {
return CommunicationPreference.daily; // return a default value
}
return CommunicationPreference.values.firstWhere(
(x) => x.toString() == str,
orElse: () => throw ArgumentError(
'Invalid CommunicationPreference enum value: $str'),
);
}
} }
enum RiskTolerance { enum RiskTolerance {
@ -171,4 +207,16 @@ enum RiskTolerance {
return 'Proactively taking risks to maximize rewards'; return 'Proactively taking risks to maximize rewards';
} }
} }
/// @returns [RiskTolerance.balanced] in case [str] is null or empty
static RiskTolerance fromString(String? str) {
if (str == null || str.isEmpty) {
return RiskTolerance.balanced; // return a default value != null
}
return RiskTolerance.values.firstWhere(
(x) => x.toString() == str,
orElse: () =>
throw ArgumentError('Invalid RiskTolerance enum value: $str'),
);
}
} }

View File

@ -129,8 +129,10 @@ class CultureValuesFormPageState extends State<CultureValuesFormPage> {
// //
// set following registration page HERE // set following registration page HERE
// //
builder: (context) => builder: (context) => RisksFormPage(
RisksFormPage(isRegProcess: widget.isRegProcess), isRegProcess: widget.isRegProcess,
isEditMode: false,
),
), ),
); );
} else { } else {

View File

@ -7,9 +7,11 @@ import '../pages/registration_complete_page.dart';
import '../services/auth/auth_service.dart'; import '../services/auth/auth_service.dart';
class RisksFormPage extends StatefulWidget { class RisksFormPage extends StatefulWidget {
const RisksFormPage({super.key, required this.isRegProcess}); const RisksFormPage(
{super.key, required this.isRegProcess, required this.isEditMode});
final bool isRegProcess; final bool isRegProcess;
final bool isEditMode;
@override @override
RisksFormPageState createState() => RisksFormPageState(); RisksFormPageState createState() => RisksFormPageState();
@ -17,7 +19,7 @@ class RisksFormPage extends StatefulWidget {
class RisksFormPageState extends State<RisksFormPage> { class RisksFormPageState extends State<RisksFormPage> {
CommunicationPreference? communicationPreference; CommunicationPreference? communicationPreference;
RiskTolerance? riskTolerance; RiskTolerance? riskPreference;
final AuthService _authService = AuthService(); final AuthService _authService = AuthService();
@ -45,7 +47,7 @@ class RisksFormPageState extends State<RisksFormPage> {
} }
// Load Risk Tolerance // Load Risk Tolerance
if (data[Constants.dbFieldUsersRiskTolerance] != null) { if (data[Constants.dbFieldUsersRiskTolerance] != null) {
riskTolerance = RiskTolerance.values.firstWhereOrNull((x) => riskPreference = RiskTolerance.values.firstWhereOrNull((x) =>
x.toString() == data[Constants.dbFieldUsersRiskTolerance]); x.toString() == data[Constants.dbFieldUsersRiskTolerance]);
} }
} }
@ -53,7 +55,8 @@ class RisksFormPageState extends State<RisksFormPage> {
} }
} }
Future<void> _saveDataToFirebase() async { Future<bool> _saveDataToFirebase() async {
try {
final userDoc = FirebaseFirestore.instance final userDoc = FirebaseFirestore.instance
.collection(Constants.dbCollectionUsers) .collection(Constants.dbCollectionUsers)
.doc(_authService.getCurrentUser()!.uid); .doc(_authService.getCurrentUser()!.uid);
@ -62,27 +65,40 @@ class RisksFormPageState extends State<RisksFormPage> {
{ {
Constants.dbFieldUsersCommunication: Constants.dbFieldUsersCommunication:
communicationPreference?.toString(), communicationPreference?.toString(),
Constants.dbFieldUsersRiskTolerance: riskTolerance?.toString(), Constants.dbFieldUsersRiskTolerance: riskPreference?.toString(),
}, },
SetOptions(merge: true), // avoid overwriting existing data SetOptions(merge: true), // avoid overwriting existing data
); );
return true;
} catch (e) {
_showSnackBar(e.toString());
return false;
}
} }
void handleSubmit() { void _showSnackBar(String message) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(message),
));
}
Future<void> handleSubmit() async {
if (communicationPreference == null) { if (communicationPreference == null) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar( ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('Please select a communication preference.'), content: Text('Please select a communication preference.'),
)); ));
return; return;
} }
if (riskTolerance == null) { if (riskPreference == null) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar( ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('Please select the willingness to take risks.'), content: Text('Please select the willingness to take risks.'),
)); ));
return; return;
} }
_saveDataToFirebase();
// Handle the form submission logic here // Handle the form submission logic here
bool success = await _saveDataToFirebase();
if (success) {
if (widget.isRegProcess) {
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(
@ -92,6 +108,24 @@ class RisksFormPageState extends State<RisksFormPage> {
builder: (context) => const RegistrationCompletePage(), builder: (context) => const RegistrationCompletePage(),
), ),
); );
} else {
if (widget.isEditMode == true) {
// pass selectedOptions data back to caller
Navigator.pop(context, {
Constants.dbFieldUsersCommunication: communicationPreference,
Constants.dbFieldUsersRiskTolerance: riskPreference,
});
} else {
Navigator.pop(context);
}
}
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Failed to save data.'),
),
);
}
} }
@override @override
@ -133,10 +167,10 @@ class RisksFormPageState extends State<RisksFormPage> {
return RadioListTile( return RadioListTile(
title: Text(option.displayName), title: Text(option.displayName),
value: option, value: option,
groupValue: riskTolerance, groupValue: riskPreference,
onChanged: (RiskTolerance? value) { onChanged: (RiskTolerance? value) {
setState(() { setState(() {
riskTolerance = value; riskPreference = value;
}); });
}, },
); );

View File

@ -20,6 +20,7 @@ class UserProfile {
RiskTolerance risk; RiskTolerance risk;
AvailabilityOption availability; AvailabilityOption availability;
CultureOption culture; CultureOption culture;
CommunicationPreference communication;
List<SkillOption> skills; List<SkillOption> skills;
List<SkillOption> skillsSought; List<SkillOption> skillsSought;
List<VisionOption> visions; List<VisionOption> visions;
@ -41,6 +42,7 @@ class UserProfile {
required this.risk, required this.risk,
required this.availability, required this.availability,
required this.culture, required this.culture,
required this.communication,
required this.skills, required this.skills,
required this.skillsSought, required this.skillsSought,
required this.visions, required this.visions,
@ -66,6 +68,8 @@ class UserProfile {
AvailabilityOption.fromString(data[Constants.dbFieldUsersAvailability]); AvailabilityOption.fromString(data[Constants.dbFieldUsersAvailability]);
CultureOption culture = CultureOption culture =
CultureOption.fromString(data[Constants.dbFieldUsersCorpCulture]); CultureOption.fromString(data[Constants.dbFieldUsersCorpCulture]);
CommunicationPreference communication = CommunicationPreference.fromString(
data[Constants.dbFieldUsersCommunication]);
return UserProfile( return UserProfile(
id: doc.id, id: doc.id,
@ -80,6 +84,7 @@ class UserProfile {
risk: risk, risk: risk,
availability: availability, availability: availability,
culture: culture, culture: culture,
communication: communication,
workValues: works, workValues: works,
profilePictureUrl: data[Constants.dbFieldUsersProfilePic], profilePictureUrl: data[Constants.dbFieldUsersProfilePic],
bio: data[Constants.dbFieldUsersBio], bio: data[Constants.dbFieldUsersBio],

View File

@ -4,6 +4,7 @@ import 'package:firebase_auth/firebase_auth.dart';
import '../constants.dart'; import '../constants.dart';
import '../enumerations.dart'; import '../enumerations.dart';
import '../forms/corporate_culture_form.dart'; import '../forms/corporate_culture_form.dart';
import '../forms/risks_form.dart';
import '../forms/skills_form.dart'; import '../forms/skills_form.dart';
import '../models/user_profile.dart'; import '../models/user_profile.dart';
import '../services/user_service.dart'; import '../services/user_service.dart';
@ -167,6 +168,27 @@ class _UserProfilePageState extends State<UserProfilePage> {
} }
} }
void editUserCommunicationInfo() async {
final updatedUserData = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const RisksFormPage(
isRegProcess: false,
isEditMode: true,
),
),
);
if (updatedUserData != null) {
setState(() {
// above Type of updatedUserData is dynamic, so convert
myData.risk = updatedUserData[Constants.dbFieldUsersRiskTolerance];
myData.communication =
updatedUserData[Constants.dbFieldUsersCommunication];
});
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -200,6 +222,10 @@ class _UserProfilePageState extends State<UserProfilePage> {
const SizedBox(height: 16), const SizedBox(height: 16),
Divider(color: Theme.of(context).colorScheme.primary), Divider(color: Theme.of(context).colorScheme.primary),
const SizedBox(height: 16), const SizedBox(height: 16),
_buildRisks(context),
const SizedBox(height: 16),
Divider(color: Theme.of(context).colorScheme.primary),
const SizedBox(height: 16),
], ],
), ),
), ),
@ -207,6 +233,73 @@ class _UserProfilePageState extends State<UserProfilePage> {
); );
} }
Widget _buildRisks(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(
'Communication profile',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
Text(myData.communication.displayName,
style: const TextStyle(fontSize: 16)),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: Align(
alignment: Alignment.topRight,
child: OutlinedButton.icon(
label: const Text('Edit'),
icon: const Icon(Icons.edit),
onPressed: editUserCommunicationInfo,
),
),
),
],
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Risk profile',
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
Text(myData.risk.displayName,
style: const TextStyle(fontSize: 16)),
],
),
),
],
),
],
),
),
],
);
}
Widget _buildWorkCulture(BuildContext context) { Widget _buildWorkCulture(BuildContext context) {
return Column( return Column(
children: [ children: [