Added Sectors of Interest and Save Button to AppBars.
parent
e79bfd5b7e
commit
87beb2dace
|
@ -54,6 +54,7 @@ class Constants {
|
|||
static const String dbFieldUsersCorpCulture = 'corp_culture';
|
||||
static const String dbFieldUsersCommunication = 'communication';
|
||||
static const String dbFieldUsersRiskTolerance = 'risk_tolerance';
|
||||
static const String dbFieldUsersSectors = 'sectors_of_interest';
|
||||
|
||||
static const String dbStoragePathProfiles = 'profile_images';
|
||||
|
||||
|
|
|
@ -252,3 +252,98 @@ enum RiskTolerance {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum SectorOption {
|
||||
agriculture,
|
||||
ai,
|
||||
vr,
|
||||
automotive,
|
||||
bigdata,
|
||||
blockchain,
|
||||
cloud,
|
||||
crypto,
|
||||
cybersecurity,
|
||||
education,
|
||||
energy,
|
||||
fashion,
|
||||
finance,
|
||||
food,
|
||||
gaming,
|
||||
healthcare,
|
||||
home,
|
||||
industry,
|
||||
insurance,
|
||||
iot,
|
||||
legal,
|
||||
ml,
|
||||
media,
|
||||
pharma,
|
||||
retail,
|
||||
robotics,
|
||||
saas,
|
||||
sports,
|
||||
travel;
|
||||
|
||||
String get displayName {
|
||||
switch (this) {
|
||||
case SectorOption.agriculture:
|
||||
return 'Agriculture';
|
||||
case SectorOption.ai:
|
||||
return 'Artificial Intelligence';
|
||||
case SectorOption.vr:
|
||||
return 'Augmented/Virtual Reality';
|
||||
case SectorOption.automotive:
|
||||
return 'Automotive';
|
||||
case SectorOption.bigdata:
|
||||
return 'Big Data';
|
||||
case SectorOption.blockchain:
|
||||
return 'Blockchain';
|
||||
case SectorOption.cloud:
|
||||
return 'Cloud Computing';
|
||||
case SectorOption.crypto:
|
||||
return 'Cryptocurrencies/Digital Assets';
|
||||
case SectorOption.cybersecurity:
|
||||
return 'Cybersecurity';
|
||||
case SectorOption.education:
|
||||
return 'Education';
|
||||
case SectorOption.energy:
|
||||
return 'Energy and Environment';
|
||||
case SectorOption.fashion:
|
||||
return 'Fashion and Lifestyle';
|
||||
case SectorOption.finance:
|
||||
return 'Finance';
|
||||
case SectorOption.food:
|
||||
return 'Food and Beverage';
|
||||
case SectorOption.gaming:
|
||||
return 'Gaming';
|
||||
case SectorOption.healthcare:
|
||||
return 'Healthcare';
|
||||
case SectorOption.home:
|
||||
return 'Home and Garden';
|
||||
case SectorOption.industry:
|
||||
return 'Industry';
|
||||
case SectorOption.insurance:
|
||||
return 'Insurance';
|
||||
case SectorOption.iot:
|
||||
return 'Internet of Things';
|
||||
case SectorOption.legal:
|
||||
return 'Legal and Compliance';
|
||||
case SectorOption.ml:
|
||||
return 'Machine Learning';
|
||||
case SectorOption.media:
|
||||
return 'Media and Entertainment';
|
||||
case SectorOption.pharma:
|
||||
return 'Pharma';
|
||||
case SectorOption.retail:
|
||||
return 'Retail';
|
||||
case SectorOption.robotics:
|
||||
return 'Robotics';
|
||||
case SectorOption.saas:
|
||||
return 'SaaS';
|
||||
case SectorOption.sports:
|
||||
return 'Sports and Fitness';
|
||||
case SectorOption.travel:
|
||||
return 'Travel';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,6 +151,13 @@ class CultureValuesFormPageState extends State<CultureValuesFormPage> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Personal preferences'),
|
||||
actions: [
|
||||
if (widget.isEditMode && !widget.isRegProcess)
|
||||
IconButton(
|
||||
onPressed: handleSubmit,
|
||||
icon: const Icon(Icons.save),
|
||||
)
|
||||
],
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
|
|
|
@ -25,7 +25,7 @@ class ProfileCategoryForm<T> extends StatefulWidget {
|
|||
required this.onSave,
|
||||
required this.preSelectedOptions,
|
||||
this.saveButtonText,
|
||||
this.hideSaveButton = false, // Initialize hideSaveButton parameter
|
||||
this.hideSaveButton = false,
|
||||
});
|
||||
|
||||
@override
|
||||
|
@ -47,6 +47,13 @@ class ProfileCategoryFormState<T> extends State<ProfileCategoryForm<T>> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(widget.title),
|
||||
actions: [
|
||||
if (!widget.hideSaveButton)
|
||||
IconButton(
|
||||
onPressed: _saveButtonClicked,
|
||||
icon: const Icon(Icons.save),
|
||||
)
|
||||
],
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
|
@ -70,9 +77,9 @@ class ProfileCategoryFormState<T> extends State<ProfileCategoryForm<T>> {
|
|||
if (_selectedOptions.length < widget.maxSelections) {
|
||||
_selectedOptions.add(option);
|
||||
} else {
|
||||
// Provide feedback that maximum selections reached
|
||||
_showSnackBar(
|
||||
'Maximum selections reached for ${widget.title}');
|
||||
'Maximum selections reached for ${widget.title}',
|
||||
);
|
||||
}
|
||||
} else {
|
||||
_selectedOptions.remove(option);
|
||||
|
@ -85,13 +92,7 @@ class ProfileCategoryFormState<T> extends State<ProfileCategoryForm<T>> {
|
|||
const SizedBox(height: 16.0),
|
||||
if (!widget.hideSaveButton)
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
if (_selectedOptions.length >= widget.minSelections) {
|
||||
widget.onSave(_selectedOptions);
|
||||
} else {
|
||||
_showSnackBar('No selection made for ${widget.title}');
|
||||
}
|
||||
},
|
||||
onPressed: _saveButtonClicked,
|
||||
child: Text(widget.saveButtonText ?? 'Save'),
|
||||
),
|
||||
],
|
||||
|
@ -100,6 +101,14 @@ class ProfileCategoryFormState<T> extends State<ProfileCategoryForm<T>> {
|
|||
);
|
||||
}
|
||||
|
||||
void _saveButtonClicked() {
|
||||
if (_selectedOptions.length >= widget.minSelections) {
|
||||
widget.onSave(_selectedOptions);
|
||||
} else {
|
||||
_showSnackBar('No selection made for ${widget.title}');
|
||||
}
|
||||
}
|
||||
|
||||
void _showSnackBar(String message) {
|
||||
if (!_isSnackBarVisible) {
|
||||
_isSnackBarVisible = true;
|
||||
|
|
|
@ -129,6 +129,13 @@ class RisksFormPageState extends State<RisksFormPage> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Personal preferences'),
|
||||
actions: [
|
||||
if (widget.isEditMode && !widget.isRegProcess)
|
||||
IconButton(
|
||||
onPressed: handleSubmit,
|
||||
icon: const Icon(Icons.save),
|
||||
)
|
||||
],
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import '../../enumerations.dart';
|
||||
import '../../services/auth/auth_service.dart';
|
||||
import '../../services/user_service.dart';
|
||||
import '../constants.dart';
|
||||
import '../pages/user_vision_page.dart';
|
||||
import 'profile_category_form.dart';
|
||||
|
||||
class SectorsForm extends StatelessWidget {
|
||||
SectorsForm({
|
||||
super.key,
|
||||
required this.isRegProcess,
|
||||
required this.isEditMode,
|
||||
});
|
||||
|
||||
final AuthService _authService = AuthService();
|
||||
|
||||
final bool isRegProcess;
|
||||
final bool isEditMode;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder<List<SectorOption>>(
|
||||
future: UserService.getSectorsFromFirebase(
|
||||
_authService.getCurrentUser()!.uid,
|
||||
),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const CircularProgressIndicator();
|
||||
} else if (snapshot.hasError) {
|
||||
return Text('Error: ${snapshot.error}');
|
||||
} else {
|
||||
List<SectorOption>? userSectors = snapshot.data;
|
||||
int max = 10;
|
||||
return ProfileCategoryForm(
|
||||
title: 'Sectors of interest',
|
||||
header: 'Sectors of interest',
|
||||
description: 'Select up to $max sectors that match your interests.',
|
||||
saveButtonText: isRegProcess ? 'Save and continue' : 'Save',
|
||||
options: SectorOption.values.toList(), // Convert enum to list
|
||||
minSelections: 1,
|
||||
maxSelections: max,
|
||||
preSelectedOptions: userSectors ?? [],
|
||||
onSave: (selectedOptions) async {
|
||||
// Handle saving selected options
|
||||
bool success = await UserService.saveSectorsToFirebase(
|
||||
selectedOptions.cast<SectorOption>(),
|
||||
_authService.getCurrentUser()!.uid,
|
||||
);
|
||||
|
||||
if (context.mounted) {
|
||||
if (success) {
|
||||
if (isRegProcess) {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
// set following registration page HERE
|
||||
builder: (context) => UserVisionPage(
|
||||
isRegProcess: isRegProcess,
|
||||
isEditMode: false,
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
if (isEditMode == true) {
|
||||
// pass selectedOptions data back to caller
|
||||
Navigator.pop(context, {
|
||||
Constants.dbFieldUsersSectors: selectedOptions,
|
||||
});
|
||||
} else {
|
||||
// Navigate back after saving
|
||||
Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Failed to save sectors of interest.'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -3,8 +3,8 @@ import '../../enumerations.dart';
|
|||
import '../../services/auth/auth_service.dart';
|
||||
import '../../services/user_service.dart';
|
||||
import '../constants.dart';
|
||||
import '../pages/user_vision_page.dart';
|
||||
import 'profile_category_form.dart';
|
||||
import 'sectors_form.dart';
|
||||
|
||||
class SkillsForm extends StatelessWidget {
|
||||
SkillsForm({
|
||||
|
@ -14,7 +14,6 @@ class SkillsForm extends StatelessWidget {
|
|||
required this.isEditMode,
|
||||
});
|
||||
|
||||
// get instance of auth
|
||||
final AuthService _authService = AuthService();
|
||||
|
||||
final bool isRegProcess;
|
||||
|
@ -27,7 +26,7 @@ class SkillsForm extends StatelessWidget {
|
|||
future: UserService.getSkillsFromFirebase(
|
||||
skillsSought,
|
||||
_authService.getCurrentUser()!.uid,
|
||||
), // Fetch skills from Firebase
|
||||
),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
// Show loading indicator while fetching data
|
||||
|
@ -58,7 +57,7 @@ class SkillsForm extends StatelessWidget {
|
|||
_authService.getCurrentUser()!.uid,
|
||||
);
|
||||
|
||||
// Then navigate to another screen or perform any other action???
|
||||
// Then navigate to another screen or perform any other action
|
||||
if (context.mounted) {
|
||||
if (success) {
|
||||
if (isRegProcess && skillsSought) {
|
||||
|
@ -66,7 +65,7 @@ class SkillsForm extends StatelessWidget {
|
|||
context,
|
||||
MaterialPageRoute(
|
||||
// set following registration page HERE
|
||||
builder: (context) => UserVisionPage(
|
||||
builder: (context) => SectorsForm(
|
||||
isRegProcess: isRegProcess,
|
||||
isEditMode: false,
|
||||
),
|
||||
|
|
|
@ -160,6 +160,12 @@ class EditProfilePageState extends State<EditProfilePage> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Edit Profile'),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: _saveProfile,
|
||||
icon: const Icon(Icons.save),
|
||||
)
|
||||
],
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
|
|
|
@ -149,6 +149,13 @@ class UserVisionPageState extends State<UserVisionPage> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Personal preferences'),
|
||||
actions: [
|
||||
if (widget.isEditMode && !widget.isRegProcess)
|
||||
IconButton(
|
||||
onPressed: handleSubmit,
|
||||
icon: const Icon(Icons.save),
|
||||
)
|
||||
],
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
|
|
|
@ -10,17 +10,16 @@ class WelcomePage extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Start now'),
|
||||
),
|
||||
body: Padding(
|
||||
appBar: AppBar(title: const Text('Welcome to ${Constants.appTitle}'),),
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const TextBold(
|
||||
text: 'Welcome to ${Constants.appTitle}',
|
||||
text: 'Connect with Potential Co-Founders Here',
|
||||
fontSize: 24,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
@ -80,6 +79,7 @@ class WelcomePage extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -284,4 +284,42 @@ class UserService {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<bool> saveSectorsToFirebase(
|
||||
List<SectorOption> sectors, String userId) async {
|
||||
try {
|
||||
List<String> sectorStrings = sectors.map((x) => x.toString()).toList();
|
||||
await FirebaseFirestore.instance
|
||||
.collection(Constants.dbCollectionUsers)
|
||||
.doc(userId)
|
||||
.update({
|
||||
Constants.dbFieldUsersSectors: sectorStrings,
|
||||
});
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<SectorOption>> getSectorsFromFirebase(
|
||||
String userId) async {
|
||||
try {
|
||||
DocumentSnapshot userDoc = await FirebaseFirestore.instance
|
||||
.collection(Constants.dbCollectionUsers)
|
||||
.doc(userId)
|
||||
.get();
|
||||
if (userDoc.exists && userDoc.data() != null) {
|
||||
var data = userDoc.data() as Map<String, dynamic>;
|
||||
List<dynamic> sectors = data[Constants.dbFieldUsersSectors] ?? [];
|
||||
return sectors
|
||||
.map((x) => SectorOption.values
|
||||
.firstWhere((option) => option.toString() == x))
|
||||
.toList();
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} catch (e) {
|
||||
throw Exception('Error fetching sectors from Firebase: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue