UserDataPage: locations

master
Rafael 2024-05-10 21:25:25 +02:00
parent 76e995acbf
commit e8702c713a
2 changed files with 130 additions and 46 deletions

View File

@ -10,6 +10,9 @@ class Constants {
static const String dbCollectionChatRooms = 'chat_rooms'; static const String dbCollectionChatRooms = 'chat_rooms';
static const String dbCollectionMessages = 'messages'; static const String dbCollectionMessages = 'messages';
static const String dbDocMainLocation = 'main';
static const String dbDocSecondLocation = 'secondary';
static const String dbFieldUsersGender = 'gender'; static const String dbFieldUsersGender = 'gender';
static const String dbFieldUsersYearBorn = 'born'; static const String dbFieldUsersYearBorn = 'born';

View File

@ -1,15 +1,15 @@
import 'dart:convert'; import 'dart:convert';
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:cofounderella/components/my_button.dart'; import '../components/my_button.dart';
import 'package:cofounderella/constants.dart'; import '../constants.dart';
import 'package:cofounderella/models/language.dart'; import '../models/language.dart';
import 'package:cofounderella/models/language_setting.dart'; import '../models/language_setting.dart';
import '../components/location_dialog.dart'; import '../components/location_dialog.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 'package:cofounderella/services/auth/auth_service.dart'; import '../services/auth/auth_service.dart';
import 'package:cofounderella/models/location.dart'; import '../models/location.dart';
class UserDataPage extends StatefulWidget { class UserDataPage extends StatefulWidget {
const UserDataPage({super.key}); const UserDataPage({super.key});
@ -21,7 +21,7 @@ class UserDataPage extends StatefulWidget {
enum Gender { none, male, female, divers } enum Gender { none, male, female, divers }
class _UserDataPageState extends State<UserDataPage> { class _UserDataPageState extends State<UserDataPage> {
MyLocation? _primaryLocation; MyLocation? _mainLocation;
MyLocation? _secondaryLocation; MyLocation? _secondaryLocation;
List<LanguageSetting> languagesList = []; List<LanguageSetting> languagesList = [];
@ -36,6 +36,9 @@ class _UserDataPageState extends State<UserDataPage> {
Gender genderView = Gender.none; Gender genderView = Gender.none;
int _genderFromDb = 0; int _genderFromDb = 0;
List<Language> _languagesFromDb = []; List<Language> _languagesFromDb = [];
MyLocation? _mainLocationFromDb;
MyLocation? _secondaryLocationFromDb;
bool _secondLocationExists = false;
@override @override
void initState() { void initState() {
@ -65,6 +68,33 @@ class _UserDataPageState extends State<UserDataPage> {
? userSnapshot[Constants.dbFieldUsersYearBorn] ? userSnapshot[Constants.dbFieldUsersYearBorn]
: null; : null;
// Fetch locations
QuerySnapshot locationSnapshot = await _firestore
.collection(Constants.dbCollectionUsers)
.doc(currentUserId)
.collection(Constants.dbCollectionLocations)
.get();
MyLocation userLoc;
for (var doc in locationSnapshot.docs) {
userLoc = MyLocation(
street: doc['street'],
country: doc['country'],
administrativeArea: doc['administrativeArea'],
locality: doc['locality'],
subLocality: doc['subLocality'],
postalCode: doc['postalCode'],
latitude: doc['latitude'],
longitude: doc['longitude'],
);
if (doc.id == Constants.dbDocMainLocation) {
_mainLocationFromDb = userLoc;
} else if (doc.id == Constants.dbDocSecondLocation) {
_secondaryLocationFromDb = userLoc;
_secondLocationExists = true;
}
}
// Fetch languages // Fetch languages
QuerySnapshot languagesSnapshot = await _firestore QuerySnapshot languagesSnapshot = await _firestore
.collection(Constants.dbCollectionUsers) .collection(Constants.dbCollectionUsers)
@ -86,6 +116,8 @@ class _UserDataPageState extends State<UserDataPage> {
genderView = Gender.values[_genderFromDb]; genderView = Gender.values[_genderFromDb];
_selectedYear = _yearFromDb; _selectedYear = _yearFromDb;
_languagesFromDb = userLanguages; _languagesFromDb = userLanguages;
_mainLocation = _mainLocationFromDb;
_secondaryLocation = _secondaryLocationFromDb;
}); });
// Load data from JSON file when the widget initializes // Load data from JSON file when the widget initializes
@ -135,6 +167,8 @@ class _UserDataPageState extends State<UserDataPage> {
_firestore.collection(Constants.dbCollectionUsers).doc(currentUserID); _firestore.collection(Constants.dbCollectionUsers).doc(currentUserID);
CollectionReference languagesRef = CollectionReference languagesRef =
userRef.collection(Constants.dbCollectionLanguages); userRef.collection(Constants.dbCollectionLanguages);
CollectionReference locationsRef =
userRef.collection(Constants.dbCollectionLocations);
if (_selectedYear != _yearFromDb) { if (_selectedYear != _yearFromDb) {
await userRef.update( await userRef.update(
@ -157,6 +191,45 @@ class _UserDataPageState extends State<UserDataPage> {
print("gender did NOT change"); print("gender did NOT change");
} }
// Save locations
if (_mainLocation != _mainLocationFromDb) {
if (_mainLocation != null) {
// Update existing user document with new locations
await locationsRef
.doc(Constants.dbDocMainLocation)
.set(_mainLocation!.toMap());
}
} else {
print("main location did NOT change");
}
if (_secondaryLocation != _secondaryLocationFromDb) {
if (_secondaryLocation != null) {
await locationsRef
.doc(Constants.dbDocSecondLocation)
.set(_secondaryLocation!.toMap())
.then((value) => {
print("Document secondary location updated"),
// update local values
_secondaryLocationFromDb = _secondaryLocation,
_secondLocationExists = true
});
} else if (_secondLocationExists) {
// secondLocationExists but is null here -> delete secondary in DB
await locationsRef.doc(Constants.dbDocSecondLocation).delete().then(
(doc) => {
print("Document secondary location deleted"),
// update local values
_secondaryLocationFromDb = null,
_secondLocationExists = false
},
onError: (e) => print("Error updating document $e"),
);
}
} else {
print("secondary location did NOT change");
}
// Save Languages - only if selected values changed // Save Languages - only if selected values changed
if (_selectedLanguages.isEmpty) { if (_selectedLanguages.isEmpty) {
print("no language selected"); print("no language selected");
@ -219,7 +292,7 @@ class _UserDataPageState extends State<UserDataPage> {
onLocationSelected: (location) { onLocationSelected: (location) {
setState(() { setState(() {
if (isPrimary) { if (isPrimary) {
_primaryLocation = location; _mainLocation = location;
} else { } else {
_secondaryLocation = location; _secondaryLocation = location;
} }
@ -254,24 +327,28 @@ class _UserDataPageState extends State<UserDataPage> {
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
// Display selected primary location // Display selected main location
const Text( const Text(
'Primary Location:', 'Main Location:',
style: TextStyle(fontWeight: FontWeight.bold), style: TextStyle(fontWeight: FontWeight.bold),
), ),
if (_primaryLocation != null) ...[ if (_mainLocation != null) ...[
Text(_primaryLocation!.toString()), Text(_mainLocation!.toString()),
const SizedBox(height: 10), const SizedBox(height: 10),
] else ...[ ] else ...[
const Text('n/a'), const Text('n/a'),
const SizedBox(height: 10), const SizedBox(height: 10),
], ],
// Button to set primary location // Button to set main location
ElevatedButton( Center(
onPressed: () { child: ElevatedButton(
_showLocationDialog(true); onPressed: () {
}, _showLocationDialog(true);
child: const Text('Set Primary Location'), },
child: Text(_mainLocation != null
? 'Change Main Location'
: 'Set Main Location'),
),
), ),
const SizedBox(height: 20), const SizedBox(height: 20),
// Display selected secondary location // Display selected secondary location
@ -283,14 +360,14 @@ class _UserDataPageState extends State<UserDataPage> {
Text(_secondaryLocation!.toString()), Text(_secondaryLocation!.toString()),
const SizedBox(height: 10), const SizedBox(height: 10),
], ],
if (_primaryLocation != null) ...[ if (_mainLocation != null) ...[
// Button to set secondary location // Button to set secondary location
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
_showLocationDialog(false); _showLocationDialog(false);
}, },
child: Text(_secondaryLocation != null child: Text(_secondaryLocation != null
? 'Set Secondary Location' ? 'Change Secondary Location'
: 'Add Secondary Location'), : 'Add Secondary Location'),
), ),
], ],
@ -330,38 +407,42 @@ class _UserDataPageState extends State<UserDataPage> {
), ),
], ],
), ),
const SizedBox(height: 20),
Text( Text(
'Gender (${genderView.name} selected)', 'Gender (${genderView.name} selected)',
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
), ),
SegmentedButton<Gender>( Center(
style: SegmentedButton.styleFrom( child: SegmentedButton<Gender>(
selectedBackgroundColor: Colors.blue, style: SegmentedButton.styleFrom(
selectedBackgroundColor: Colors.blue,
),
segments: const <ButtonSegment<Gender>>[
ButtonSegment<Gender>(
value: Gender.none,
label: Text('none'),
),
ButtonSegment<Gender>(
value: Gender.male,
label: Text('male'),
//icon: Icon(Icons.male_sharp),
),
ButtonSegment<Gender>(
value: Gender.female,
label: Text('female'),
//icon: Icon(Icons.female_sharp),
),
ButtonSegment<Gender>(
value: Gender.divers,
label: Text('divers'),
),
],
selected: <Gender>{genderView},
showSelectedIcon: false,
onSelectionChanged: updateSelectedGender,
), ),
segments: const <ButtonSegment<Gender>>[
ButtonSegment<Gender>(
value: Gender.none,
label: Text('none'),
),
ButtonSegment<Gender>(
value: Gender.male,
label: Text('male'),
//icon: Icon(Icons.male_sharp),
),
ButtonSegment<Gender>(
value: Gender.female,
label: Text('female'),
//icon: Icon(Icons.female_sharp),
),
ButtonSegment<Gender>(
value: Gender.divers,
label: Text('divers'),
),
],
selected: <Gender>{genderView},
showSelectedIcon: false,
onSelectionChanged: updateSelectedGender,
), ),
const SizedBox(height: 20),
const Divider(), const Divider(),
Text( Text(
'Language: (${_selectedLanguages.length} selected)', 'Language: (${_selectedLanguages.length} selected)',