Registration: risks

master
Rafael 2024-05-22 02:46:46 +02:00
parent 2a2a82d71d
commit 40581f66da
8 changed files with 315 additions and 103 deletions

View File

@ -22,6 +22,8 @@ class Constants {
static const String dbFieldUsersVisions = 'visions'; static const String dbFieldUsersVisions = 'visions';
static const String dbFieldUsersWorkValues = 'work_values'; static const String dbFieldUsersWorkValues = 'work_values';
static const String dbFieldUsersCorpCulture = 'corp_culture'; static const String dbFieldUsersCorpCulture = 'corp_culture';
static const String dbFieldUsersCommunication = 'communication';
static const String dbFieldUsersRiskTolerance = 'risk_tolerance';
static const String pathLanguagesJson = 'lib/assets/languages.json'; static const String pathLanguagesJson = 'lib/assets/languages.json';
} }

View File

@ -116,3 +116,46 @@ enum CultureOption {
} }
} }
} }
enum CommunicationPreference {
daily,
weekly,
adhoc,
formal;
String get displayName {
switch (this) {
case CommunicationPreference.daily:
return 'Frequent updates and daily meetings';
case CommunicationPreference.weekly:
return 'Weekly summaries and updates';
case CommunicationPreference.adhoc:
return 'Ad-hoc communication as needed';
case CommunicationPreference.formal:
return 'Formal reports and documentation';
}
}
}
enum RiskTolerance {
riskAverse,
cautious,
balanced,
adaptive,
riskTaker;
String get displayName {
switch (this) {
case RiskTolerance.riskAverse:
return 'Prefer avoiding risks whenever possible';
case RiskTolerance.cautious:
return 'Exercising caution to minimize potential losses';
case RiskTolerance.balanced:
return 'Neutral, carefully weighing potential opportunities and hazards';
case RiskTolerance.adaptive:
return 'Flexibly responding to changing risk scenarios';
case RiskTolerance.riskTaker:
return 'Proactively taking risks to maximize rewards';
}
}
}

View File

@ -1,8 +1,9 @@
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../constants.dart'; import '../constants.dart';
import '../enumerations.dart'; import '../enumerations.dart';
import '../pages/registration_complete_page.dart'; import '../forms/risks_form.dart';
import '../services/auth/auth_service.dart'; import '../services/auth/auth_service.dart';
class CultureValuesFormPage extends StatefulWidget { class CultureValuesFormPage extends StatefulWidget {
@ -55,7 +56,7 @@ class CultureValuesFormPageState extends State<CultureValuesFormPage> {
} }
// Load Culture option // Load Culture option
if (data[Constants.dbFieldUsersCorpCulture] != null) { if (data[Constants.dbFieldUsersCorpCulture] != null) {
selectedCultureOption = CultureOption.values.firstWhere( selectedCultureOption = CultureOption.values.firstWhereOrNull(
(e) => e.toString() == data[Constants.dbFieldUsersCorpCulture], (e) => e.toString() == data[Constants.dbFieldUsersCorpCulture],
); );
} }
@ -108,9 +109,9 @@ class CultureValuesFormPageState extends State<CultureValuesFormPage> {
context, context,
MaterialPageRoute( MaterialPageRoute(
// //
// TODO set following registration page HERE // set following registration page HERE
// //
builder: (context) => const RegistrationCompletePage(), builder: (context) => RisksFormPage(isRegProcess: widget.isRegProcess),
), ),
); );
} }

View File

@ -0,0 +1,158 @@
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import '../constants.dart';
import '../enumerations.dart';
import '../pages/registration_complete_page.dart';
import '../services/auth/auth_service.dart';
class RisksFormPage extends StatefulWidget {
const RisksFormPage({super.key, required this.isRegProcess});
final bool isRegProcess;
@override
RisksFormPageState createState() => RisksFormPageState();
}
class RisksFormPageState extends State<RisksFormPage> {
CommunicationPreference? communicationPreference;
RiskTolerance? riskTolerance;
final AuthService _authService = AuthService();
@override
void initState() {
super.initState();
_loadDataFromFirebase();
}
Future<void> _loadDataFromFirebase() async {
final userDoc = FirebaseFirestore.instance
.collection(Constants.dbCollectionUsers)
.doc(_authService.getCurrentUser()!.uid);
final snapshot = await userDoc.get();
if (snapshot.exists) {
final data = snapshot.data();
setState(() {
if (data != null) {
// Load Communication Preference
if (data[Constants.dbFieldUsersCommunication] != null) {
communicationPreference = CommunicationPreference.values
.firstWhereOrNull((x) =>
x.toString() == data[Constants.dbFieldUsersCommunication]);
}
// Load Risk Tolerance
if (data[Constants.dbFieldUsersRiskTolerance] != null) {
riskTolerance = RiskTolerance.values.firstWhereOrNull((x) =>
x.toString() == data[Constants.dbFieldUsersRiskTolerance]);
}
}
});
}
}
Future<void> _saveDataToFirebase() async {
final userDoc = FirebaseFirestore.instance
.collection(Constants.dbCollectionUsers)
.doc(_authService.getCurrentUser()!.uid);
await userDoc.set(
{
Constants.dbFieldUsersCommunication:
communicationPreference?.toString(),
Constants.dbFieldUsersRiskTolerance: riskTolerance?.toString(),
},
SetOptions(merge: true), // avoid overwriting existing data
);
}
void handleSubmit() {
if (communicationPreference == null) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('Please select a communication preference.'),
));
return;
}
if (riskTolerance == null) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('Please select the willingness to take risks.'),
));
return;
}
_saveDataToFirebase();
// Handle the form submission logic here
Navigator.push(
context,
MaterialPageRoute(
//
// TODO set following registration page HERE
//
builder: (context) => const RegistrationCompletePage(),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Personal preferences'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Communication preference',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const Text('How do you prefer to communicate in a team?'),
...CommunicationPreference.values.map((option) {
return RadioListTile(
title: Text(option.displayName),
value: option,
groupValue: communicationPreference,
onChanged: (CommunicationPreference? value) {
setState(() {
communicationPreference = value;
});
},
);
}),
const SizedBox(height: 40),
const Text(
'Risk tolerance',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const Text('How do you deal with uncertainty and risk?'),
...RiskTolerance.values.map((option) {
return RadioListTile(
title: Text(option.displayName),
value: option,
groupValue: riskTolerance,
onChanged: (RiskTolerance? value) {
setState(() {
riskTolerance = value;
});
},
);
}),
const SizedBox(height: 20),
Center(
child: ElevatedButton(
onPressed: handleSubmit,
child:
Text(widget.isRegProcess ? 'Save and continue' : 'Save'),
),
),
],
),
),
),
);
}
}

View File

@ -52,73 +52,78 @@ class LoginPage extends StatelessWidget {
return Scaffold( return Scaffold(
backgroundColor: Theme.of(context).colorScheme.background, backgroundColor: Theme.of(context).colorScheme.background,
body: Center( body: Center(
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [ child: SingleChildScrollView(
// logo child: Column(
Icon(
Icons.people_alt,
size: 60,
color: Theme.of(context).colorScheme.primary,
),
const SizedBox(height: 50),
//welcome back message
Text(
"Welcome back, you've been missed",
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
fontSize: 16,
),
),
const SizedBox(height: 25),
// email textfield
MyTextField(
hintText: "E-Mail",
obscureText: false,
controller: _emailController,
),
//const SizedBox(height: 25),
// password textfield
MyTextField(
hintText: "Password",
obscureText: true,
controller: _passwordController,
),
const SizedBox(height: 25),
// login button
MyButton(
text: "Login",
onTap: () => login(context),
),
const SizedBox(height: 25),
// register now
Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( // logo
"Not a member? ", Icon(
style: TextStyle(color: Theme.of(context).colorScheme.primary), Icons.people_alt,
size: 60,
color: Theme.of(context).colorScheme.primary,
), ),
GestureDetector(
onTap: onTap, const SizedBox(height: 50),
child: const Text(
"Register now", //welcome back message
style: TextStyle( Text(
fontWeight: FontWeight.bold, "Welcome back, you've been missed",
), style: TextStyle(
color: Theme.of(context).colorScheme.primary,
fontSize: 16,
), ),
), ),
const SizedBox(height: 25),
// email textfield
MyTextField(
hintText: "E-Mail",
obscureText: false,
controller: _emailController,
),
// password textfield
MyTextField(
hintText: "Password",
obscureText: true,
controller: _passwordController,
),
const SizedBox(height: 25),
// login button
MyButton(
text: "Login",
onTap: () => login(context),
),
const SizedBox(height: 25),
// register now
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Not a member? ",
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
),
),
GestureDetector(
onTap: onTap,
child: const Text(
"Register now",
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
],
)
], ],
) ),
]), ),
), ),
); );
} }

View File

@ -12,35 +12,37 @@ class RegistrationCompletePage extends StatelessWidget {
title: const Text('Registration Complete'), title: const Text('Registration Complete'),
), ),
body: Center( body: Center(
child: Column( child: SingleChildScrollView(
mainAxisAlignment: MainAxisAlignment.center, child: Column(
children: <Widget>[ mainAxisAlignment: MainAxisAlignment.center,
const Icon( children: <Widget>[
Icons.check_circle, const Icon(
color: Colors.green, Icons.check_circle,
size: 100, color: Colors.green,
), size: 100,
const SizedBox(height: 20), ),
const Text( const SizedBox(height: 20),
'Registration completed!', const Text(
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), 'Registration completed!',
), style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
const SizedBox(height: 80), ),
const Text( const SizedBox(height: 80),
"You can enjoy the app now.", const Text(
style: TextStyle(fontSize: 18), "You can enjoy the app now.",
), style: TextStyle(fontSize: 18),
const SizedBox(height: 20), ),
ElevatedButton( const SizedBox(height: 20),
onPressed: () { ElevatedButton(
Navigator.push( onPressed: () {
context, Navigator.push(
MaterialPageRoute(builder: (context) => HomePage()), context,
); MaterialPageRoute(builder: (context) => HomePage()),
}, );
child: const Text("S T A R T"), },
), child: const Text("S T A R T"),
], ),
],
),
), ),
), ),
); );

View File

@ -182,7 +182,7 @@ class _UserDataPageState extends State<UserDataPage> {
if (_selectedYear != _yearFromDb) { if (_selectedYear != _yearFromDb) {
await userRef.update( await userRef.update(
{'born': _selectedYear}, {Constants.dbFieldUsersYearBorn: _selectedYear},
); );
// update local value // update local value
_yearFromDb = _selectedYear; _yearFromDb = _selectedYear;
@ -191,7 +191,7 @@ class _UserDataPageState extends State<UserDataPage> {
// Update Gender in database - only if value has changed // Update Gender in database - only if value has changed
if (_genderFromDb != genderView.index) { if (_genderFromDb != genderView.index) {
await userRef.update( await userRef.update(
{'gender': genderView.index}, {Constants.dbFieldUsersGender: genderView.index},
); );
// update local value // update local value
_genderFromDb = genderView.index; _genderFromDb = genderView.index;

View File

@ -1,9 +1,10 @@
import "package:cloud_firestore/cloud_firestore.dart"; import 'package:cloud_firestore/cloud_firestore.dart';
import "package:flutter/material.dart"; import 'package:collection/collection.dart';
import "../constants.dart"; import 'package:flutter/material.dart';
import "../enumerations.dart"; import '../constants.dart';
import "../forms/corporate_culture_form.dart"; import '../enumerations.dart';
import "../services/auth/auth_service.dart"; import '../forms/corporate_culture_form.dart';
import '../services/auth/auth_service.dart';
class MatchingForm extends StatefulWidget { class MatchingForm extends StatefulWidget {
const MatchingForm({super.key, required this.isRegProcess}); const MatchingForm({super.key, required this.isRegProcess});
@ -50,7 +51,7 @@ class MatchingFormState extends State<MatchingForm> {
} }
// Load Availability option // Load Availability option
if (data?[Constants.dbFieldUsersAvailability] != null) { if (data?[Constants.dbFieldUsersAvailability] != null) {
availability = AvailabilityOption.values.firstWhere( availability = AvailabilityOption.values.firstWhereOrNull(
(e) => e.toString() == data?[Constants.dbFieldUsersAvailability], (e) => e.toString() == data?[Constants.dbFieldUsersAvailability],
); );
} }