Skip to content

Instantly share code, notes, and snippets.

@rodolfofranco
Created July 16, 2019 03:34
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save rodolfofranco/39bc5d4cefd80531c3a3a317409851c9 to your computer and use it in GitHub Desktop.
Profile Page
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pray_flutter/screens/home.dart';
import 'package:validators/validators.dart';
import 'package:http/http.dart' as http;
import 'package:async/async.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
class Country {
final String name;
Country({this.name});
factory Country.fromJson(Map<String, dynamic> json) {
return Country(
name: json['name'],
);
}
}
class User {
final String photo;
String firstName;
String lastName;
String country;
String association;
String dateBirth;
String email;
String phone;
User({this.phone, this.firstName, this.lastName, this.country, this.association, this.dateBirth, this.email, this.photo});
factory User.fromJson(Map<String, dynamic> json) {
return User(
photo: json['photo'],
firstName: json['firstName'],
lastName: json['lastName'],
country: json['country'],
association: json['association'],
dateBirth: json['dateBirth'],
email: json['email'],
phone: json['phone']
);
}
}
class ProfilePage extends StatefulWidget{
@override
_ProfilePageState createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> {
String dropdownValue;
String birthdate;
User user;
String apiUrl = 'https://restcountries.eu/rest/v2/all';
Iterable<Country> countries;
final AsyncMemoizer _memoizer = AsyncMemoizer();
static final GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
TextEditingController birthController;
TextEditingController firstController;
TextEditingController lastController;
TextEditingController emailController;
TextEditingController phoneController;
TextEditingController associationController;
TextEditingController countryController;
@override
void initState() {
super.initState();
birthController = TextEditingController();
firstController = TextEditingController();
lastController = TextEditingController();
emailController = TextEditingController();
phoneController = TextEditingController();
associationController = TextEditingController();
countryController = TextEditingController();
}
Future<void> _changePassword() async {
var user = await FirebaseAuth.instance.currentUser();
var email = user.email;
try {
await FirebaseAuth.instance.sendPasswordResetEmail(email: email);
} catch (error) {
print(error);
}
}
get _fetchData async {
return this._memoizer.runOnce(() async {
await Future.delayed(Duration(seconds: 2));
var response = await http.get(apiUrl);
FirebaseUser fireUser= await FirebaseAuth.instance.currentUser();
var uid = fireUser.uid;
var userInfo = await Firestore.instance
.collection('users')
.document(uid)
.get();
if (response.statusCode == 200 && userInfo.exists) {
print(userInfo.data);
var obj = json.decode(response.body);
// print(obj);
var list = (obj as List).map((p) => Country.fromJson(p));
var finalUser = User.fromJson(userInfo.data);
// setState(() {
countries = list;
user = finalUser;
firstController.text = user.firstName;
lastController.text = user.lastName;
emailController.text = user.email;
phoneController.text = user.phone;
associationController.text = user.association;
countryController.text = user.country;
birthController.text = user.dateBirth;
// });
return 'success';
} else {
throw Exception('Failed to load news');
}
});
}
_saveData(data, BuildContext ctx) async {
FirebaseUser fireUser= await FirebaseAuth.instance.currentUser();
var uid = fireUser.uid;
await Firestore.instance.collection('users').document(uid).updateData(data).then((val) {
final snackBar = SnackBar(
content: Text('Your profile has been updated.'),
elevation: 10,
);
Scaffold.of(ctx).showSnackBar(snackBar);
return Navigator.pop(context);
})
.catchError((err) {
final snackBar = SnackBar(
content: Text('There have been an error updating your profile' + err.toString()),
elevation: 10,
);
Scaffold.of(ctx).showSnackBar(snackBar);
});
}
get _fetch => _fetchData;
_showList(BuildContext globalContext) {
print('passed context');
print(globalContext);
return Form(
key: _formKey,
child: ListView(
children: <Widget>[
Container(
alignment: Alignment.center,
margin: const EdgeInsets.only(top:30.0),
width:100.0,
height:100.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: NetworkImage(
user.photo
)
)
),
),
Container(
padding: EdgeInsets.only(left:10.0, right:10.0),
child:
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: TextFormField(
controller: firstController,
decoration: InputDecoration(
labelText: 'First Name',
icon: Icon(Icons.person)
),
),
),
Padding(
padding: EdgeInsets.only(left:5.0, right:5.0)
),
Expanded(
child: TextFormField(
controller: lastController,
decoration: InputDecoration(
labelText: 'Last Name',
icon: Icon(Icons.person)
),
),
),
],
)
),
Container(
padding: EdgeInsets.only(left:10.0, right:10.0),
child: FormField(
builder: (FormFieldState state) {
return InputDecorator(
decoration: InputDecoration(
icon: Icon(Icons.place),
labelText: 'Country',
),
isEmpty: user.country == '',
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: countryController.text,
isDense: true,
isExpanded: true,
onChanged: (String newValue) {
dropdownValue = newValue;
countryController.text = newValue;
user.country = newValue;
state.didChange(newValue);
},
items: countries.map<DropdownMenuItem<String>>((Country value) {
return DropdownMenuItem<String>(
value: value.name,
child: Text(value.name),
);
}).toList()
)
)
);
}
)
),
Container(
padding: EdgeInsets.only(left:10.0, right:10.0),
alignment: Alignment.center,
child: TextFormField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email',
icon: Icon(Icons.email)
),
)
),
Container(
padding: EdgeInsets.only(left:10.0, right:10.0),
alignment: Alignment.center,
child: TextFormField(
controller: phoneController,
keyboardType: TextInputType.phone,
decoration: InputDecoration(
labelText: 'Phone',
icon: Icon(Icons.phone),
prefix: Text('+65 ')
),
)
),
Container(
padding: EdgeInsets.only(left:10.0, right:10.0),
alignment: Alignment.center,
child: InkWell(
onTap: () {
DatePicker.showDatePicker(context,
showTitleActions: true,
minTime: DateTime(1930, 3, 5),
maxTime: DateTime.now(), onChanged: (date) {
},
onConfirm: (date) {
birthdate = date.toString().substring(0,10);
birthController.text = birthdate;
user.dateBirth = birthdate;
}, currentTime: DateTime.now(), locale: LocaleType.en);
},
child: IgnorePointer(
child: TextFormField(
controller: birthController,
decoration: InputDecoration(
labelText: 'Birthdate',
icon: Icon(Icons.date_range),
),
)
)
)
),
Container(
padding: EdgeInsets.only(left:10.0, right:10.0),
child: TextFormField(
controller: associationController,
onFieldSubmitted: (val) {
setState(() {
user.association = val;
});
},
decoration: InputDecoration(
labelText: 'Association',
icon: Icon(Icons.people)
),
)
),
Container(
padding: EdgeInsets.only(left:10.0, right: 10.0),
child: Builder(
builder: (BuildContext ctx) {
return ButtonTheme(
minWidth: double.infinity,
buttonColor: Colors.pink,
shape: new RoundedRectangleBorder(borderRadius: new BorderRadius.circular(20)),
child: RaisedButton.icon(
icon: Icon(Icons.save),
textColor: Colors.white,
elevation: 10,
onPressed: () {
Map<String, dynamic> data = Map<String, dynamic>();
data['firstName'] = firstController.text;
data['lastName'] = lastController.text;
data['phone'] = phoneController.text;
data['country'] = countryController.text;
data['email'] = emailController.text;
data['association'] = associationController.text;
data['photo'] = user.photo;
data['dateBirth'] = birthController.text;
_saveData(data, ctx);
},
label: Text('Save')
)
);
}
)
),
Container(
padding: EdgeInsets.only(left:10.0, right: 10.0),
child: Builder(
builder: (BuildContext newContext) {
return ButtonTheme(
minWidth: double.infinity,
buttonColor: Colors.pink[50],
shape: new RoundedRectangleBorder(borderRadius: new BorderRadius.circular(20)),
child: RaisedButton.icon(
icon: Icon(Icons.vpn_key),
textColor: Colors.pink,
elevation: 10,
onPressed: () {
_changePassword().then((va) {
final snackBar = SnackBar(
content: Text('An email has been sent with instruction to reset your password.'),
elevation: 10,
);
Scaffold.of(newContext).showSnackBar(snackBar);
});
},
label: Text('Change Password')
)
);
}
)
)
],
)
);
}
@override
Widget build(BuildContext globalContext) {
return Scaffold(
appBar: AppBar(title: Text('Profile')),
body: Center(
child: FutureBuilder(
future: _fetch,
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.connectionState == ConnectionState.done) {
return _showList(globalContext);
} else if (snapshot.hasError) {
print(snapshot.error);
return new Container(width: 0.0, height: 0.0);
} else {
return Center(child: CircularProgressIndicator());
}
},
)
)
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment