This commit is contained in:
Juan Felipe Duarte
2023-04-04 09:18:33 -05:00
parent 9656a85090
commit 50737e03dd
7 changed files with 304 additions and 155 deletions
@@ -132,4 +132,15 @@ class AuthenticationRepository extends GetxController {
}
return city;
}
Future<void> updatePhoneNumber(String verificationId, String smsCode) async {
try {
PhoneAuthCredential credential = PhoneAuthProvider.credential(
verificationId: verificationId, smsCode: smsCode);
await FirebaseAuth.instance.currentUser!.updatePhoneNumber(credential);
print("Phone number updated successfully");
} catch (e) {
print("Error updating phone number: $e");
}
}
}
@@ -0,0 +1,13 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:prosappco/src/authentication/authentication_repository.dart';
class NewPhoneController extends GetxController {
static NewPhoneController get instance => Get.find();
final newPhoneNo = TextEditingController();
void phoneAuthentication(String newPhoneNo) {
AuthenticationRepository.instance.phoneAuthentication(newPhoneNo);
}
}
+95 -140
View File
@@ -11,162 +11,90 @@ class CityScreen extends StatefulWidget {
State<CityScreen> createState() => _CityScreenState();
}
List<String> cities = [
"Abrego",
"Aguada",
"Albania",
"Aratoca",
"Arboledas",
"Barbosa",
"Barichara",
"Barrancabermeja",
"Betulia",
"Bochalema",
"Bolivar",
"Bucaramanga",
"Bucarasica",
"Cabrera",
"Cachira",
"Cacota",
"California",
"Capitanejo",
"Carcasi",
"Cepita",
"Cerrito",
"Charala",
"Charta",
"Chima",
"Chinácota",
"Chipata",
"Chitagá",
"Cimitarra",
"Concepcion",
"Confines",
"Contratacion",
"Convención",
"Coromoro",
"Cucutilla",
"Cúcuta",
"Curiti",
"Durania",
"El Carmen",
"El Carmen de Chucuri",
"El Guacamayo",
"El Penon",
"El Playon",
"El Tarra",
"El Zulia",
"Encino",
"Enciso",
"Florian",
"Floridablanca",
"Galán",
"Gambita",
"Giron",
"Gramalote",
"Guaca",
"Guadalupe",
"Guapota",
"Guavata",
"Guepsa",
"Hacarí",
"Hato",
"Herrán",
"Jesús Maria",
"Jordan",
"La Belleza",
"La Esperanza",
"La Paz",
"La Playa",
"Landazuri",
"Labateca",
"Lebrija",
"Los Patios",
"Los Santos",
"Lourdes",
"Macaravita",
"Malaga",
"Matanza",
"Mogotes",
"Molagavita",
"Mutiscua",
"Ocaña",
"Ocamonte",
"Oiba",
"Onzaga",
"Pamplona",
"Pamplonita",
"Palmar",
"Palmas del Socorro",
"Paramo",
"Piedecuesta",
"Pinchote",
"Puente Nacional",
"Puerto Parra",
"Puerto Santander",
"Puerto Wilches",
"Ragonvalia",
"Rionegro",
"Sabana de Torres",
"Salazar",
"San Andres",
"San Benito",
"San Calixto",
"San Cayetano",
"San Gil",
"San Joaquin",
"San Jose de Miranda",
"San Miguel",
"San Vicente de Chucuri",
"Santa Barbara",
"Santa Helena del Opon",
"Santiago",
"Sardinata",
"Silos",
"Simacota",
"Socorro",
"Surata",
"Suaita",
"Sucre",
"Tibú",
"Tona",
"Toledo",
"Valle de San Jose",
"Velez",
"Vetas",
"Villa Caro",
"Villa del Rosario",
"Zapatoca",
"Villanueva",
];
final CollectionReference countriesCollection =
FirebaseFirestore.instance.collection('countries');
class City {
final String name;
City({required this.name});
String? cityName;
String? stateOfCity;
String? countryOfCity;
City({this.cityName, this.stateOfCity, this.countryOfCity});
@override
String toString() {
return "${cityName ?? ""}, ${stateOfCity ?? ""}, ${countryOfCity ?? ""}";
}
}
List<City> citiesList = cities.map((city) => City(name: city)).toList();
Future<List<City>> getCountries() async {
List<City> citys = [];
try {
QuerySnapshot countries = await countriesCollection.get();
for (DocumentSnapshot country in countries.docs) {
String countryName = country.id;
Map<String, dynamic> data = country.data() as Map<String, dynamic>;
Map<String, List<String>> states = {};
for (var entry in data.entries) {
String key = entry.key;
List<String> value = List<String>.from(entry.value);
states[key] = value;
}
for (var state in states.entries) {
var citysState = state.value
.map((cityName) => City(
cityName: cityName,
stateOfCity: state.key,
countryOfCity: countryName))
.toList();
citys.addAll(citysState);
}
}
} catch (e) {
print('xd $e');
}
return citys;
}
class _CityScreenState extends State<CityScreen> {
List<City> filteredCities = citiesList;
List<City>? filteredCities;
TextEditingController searchController = TextEditingController();
final User? user = FirebaseAuth.instance.currentUser;
late final FirebaseAuth _auth;
final uid = AuthenticationRepository.instance.getCurrentUserUid();
List<City>? _cities;
@override
void initState() {
super.initState();
searchController.addListener(() {
setState(() {
filteredCities = citiesList
.where((city) => removeDiacritics(city.name).toLowerCase().contains(
removeDiacritics(searchController.text.toLowerCase())))
.toList();
if (_cities != null) {
if (searchController.text.isEmpty) {
filteredCities = _cities!;
} else {
filteredCities = _cities!
.where((city) => removeDiacritics(city.cityName!)
.toLowerCase()
.contains(
removeDiacritics(searchController.text.toLowerCase())))
.toList();
}
}
});
});
if (_cities == null) {
getCountries().then((List<City> element) => setState(() {
_cities = element;
filteredCities = element;
}));
}
}
Future<void> updateCity(String cityName) async {
@@ -193,6 +121,15 @@ class _CityScreenState extends State<CityScreen> {
@override
Widget build(BuildContext context) {
if (filteredCities == null) {
return const Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.red),
),
);
}
var citys = filteredCities!;
return SafeArea(
child: Scaffold(
appBar: AppBar(
@@ -226,12 +163,30 @@ class _CityScreenState extends State<CityScreen> {
),
Expanded(
child: ListView.builder(
itemCount: filteredCities.length,
itemCount: citys.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text(filteredCities[index].name),
title: RichText(
text: TextSpan(
style: const TextStyle(
fontSize: 18.0,
color: Colors.black,
),
children: <TextSpan>[
TextSpan(
text: '${citys[index].cityName ?? ""}, ',
style: const TextStyle(fontWeight: FontWeight.bold),
),
TextSpan(
text:
"${citys[index].stateOfCity ?? ""}, ${citys[index].countryOfCity ?? ""}",
style: TextStyle(color: Colors.grey[600]),
),
],
),
),
onTap: () {
updateCity(filteredCities[index].name);
updateCity(citys[index].cityName ?? "");
Navigator.pushReplacementNamed(context, '/profile');
},
);
+30 -10
View File
@@ -1,5 +1,8 @@
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intl_phone_field/intl_phone_field.dart';
import 'package:prosappco/src/controllers/phone_auth_controller.dart';
class NewNumberScreen extends StatefulWidget {
const NewNumberScreen({super.key});
@@ -8,7 +11,22 @@ class NewNumberScreen extends StatefulWidget {
State<NewNumberScreen> createState() => _NewNumberScreenState();
}
// Actualizar número de teléfono en Firebase
Future<void> updatePhoneNumber(String verificationId, String smsCode) async {
try {
PhoneAuthCredential credential = PhoneAuthProvider.credential(
verificationId: verificationId, smsCode: smsCode);
await FirebaseAuth.instance.currentUser!.updatePhoneNumber(credential);
print("Phone number updated successfully");
} catch (e) {
print("Error updating phone number: $e");
}
}
class _NewNumberScreenState extends State<NewNumberScreen> {
String completePhoneNumber = '';
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return SafeArea(
@@ -37,15 +55,15 @@ class _NewNumberScreenState extends State<NewNumberScreen> {
style: TextStyle(fontSize: 18.0, color: Color(0xFF65676B))),
)),
Form(
// key: _formKey,
key: _formKey,
child: Padding(
padding: EdgeInsets.only(bottom: 5),
child: IntlPhoneField(
// controller: controller.phoneNo,
initialCountryCode: 'CO',
// onChanged: (phoneNo) {
// completePhoneNumber = phoneNo.completeNumber;
// },
onChanged: (phoneNo) {
completePhoneNumber = phoneNo.completeNumber;
},
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Color(0xFFECECEC)),
@@ -74,12 +92,14 @@ class _NewNumberScreenState extends State<NewNumberScreen> {
child: Center(
child: ElevatedButton(
onPressed: () {
// if (_formKey.currentState!.validate()) {
// PhoneAuthController.instance.phoneAuthentication(
// completePhoneNumber.trim(),
// );
// Get.to(() => const CodeValidationScreen());
// }
// updatePhoneNumber(completePhoneNumber, '123456');
if (_formKey.currentState!.validate()) {
PhoneAuthController.instance.phoneAuthentication(
completePhoneNumber.trim(),
);
Get.to(NewNumberScreen());
}
},
child: Text(
'Enviar código',
+153
View File
@@ -0,0 +1,153 @@
import 'package:flutter/material.dart';
import 'package:flutter_otp_text_field/flutter_otp_text_field.dart';
import 'package:prosappco/src/controllers/otp_controller.dart';
class NewNumberValidationScreen extends StatefulWidget {
const NewNumberValidationScreen({super.key});
@override
State<NewNumberValidationScreen> createState() =>
_NewNumberValidationScreenState();
}
class _NewNumberValidationScreenState extends State<NewNumberValidationScreen> {
var otp;
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Color(0xFFD6F4FF),
body: Stack(
children: [
Container(
margin: const EdgeInsets.only(top: 280),
width: double.infinity,
height: 600,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topRight: Radius.circular(50),
topLeft: Radius.circular(50))),
),
Container(
margin: const EdgeInsets.only(top: 120, left: 70, right: 70),
child: const Image(image: AssetImage('images/logo_prosapp.png')),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 20),
margin: const EdgeInsets.only(top: 280, left: 25),
child: Row(
children: <Widget>[
IconButton(
icon: Icon(
Icons.arrow_back,
size: 30,
),
onPressed: () {
Navigator.pop(context);
},
),
Text(
'Validar código',
style: TextStyle(
color: Color(0xFF262626),
fontSize: 38.0,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.right,
),
],
),
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 20),
margin: const EdgeInsets.only(top: 350, left: 50, right: 50),
child: Column(children: [
const Padding(
padding: EdgeInsets.only(bottom: 5),
child: Align(
alignment: Alignment.topLeft,
child: Text('Numero de celular',
style: TextStyle(
fontSize: 18.0, color: Color(0xFF65676B))),
)),
Padding(
padding: EdgeInsets.only(bottom: 20),
child: Row(
children: [
Expanded(
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: '+57',
suffixIcon: Icon(Icons.edit),
),
),
),
TextButton(
onPressed: () {
// Acción a realizar cuando se hace clic en el texto
},
child: Text('Reenviar código'),
),
],
),
),
Align(
alignment: Alignment.topLeft,
child: Padding(
padding: const EdgeInsets.only(bottom: 5),
child: Text('Codigo',
textAlign: TextAlign.left,
style:
TextStyle(fontSize: 18.0, color: Color(0xFF65676B))),
),
),
Padding(
padding: EdgeInsets.only(bottom: 20),
child: OtpTextField(
numberOfFields: 6,
focusedBorderColor: Colors.blue,
fillColor: Colors.black.withOpacity(0.1),
filled: true,
keyboardType: TextInputType.number,
onSubmit: (code) {
otp = code;
OTPController.instance.verifyOTP(otp);
},
),
),
Padding(
padding: EdgeInsets.only(bottom: 40),
child: Center(
child: ElevatedButton(
onPressed: () {
OTPController.instance.verifyOTP(otp);
},
child: Text(
'Validar código',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
style: ElevatedButton.styleFrom(
primary: Color(0xFF2BA4EC), // Color del botón
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(50), // Bordes redondeados
),
elevation: 0,
minimumSize: Size(230, 60), // Tamaño mínimo del botón
),
)),
),
]),
),
],
),
));
}
}
+1 -3
View File
@@ -414,8 +414,6 @@ class _ProfileScreenState extends State<ProfileScreen> {
margin: EdgeInsets.only(top: 170),
child: ElevatedButton(
onPressed: () {
String newName = _nameController.text;
String newEmail = _emailController.text;
updateInfo();
},
child: Text(
@@ -427,7 +425,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
),
),
style: ElevatedButton.styleFrom(
primary: Color(0xFF2BA4EC),
backgroundColor: Color(0xFF2BA4EC),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
+1 -2
View File
@@ -17,7 +17,6 @@ class _WelcomeScreenState extends State<WelcomeScreen> {
final uid = AuthenticationRepository.instance.getCurrentUserUid();
final _formKey = GlobalKey<FormState>();
final controller = Get.put(NameEmailCityController());
var _nombre = '...';
var _ciudad = '';
@override
@@ -65,7 +64,7 @@ class _WelcomeScreenState extends State<WelcomeScreen> {
style: TextStyle(fontSize: 12),
),
Text(
'${city ?? "a"}',
'${city ?? ""}',
style: TextStyle(fontSize: 12),
),
],