Fakultas Ilmu Komputer UI

Commit da8b0dbb authored by Fakhira Devina's avatar Fakhira Devina
Browse files

Merge branch 'dev-sidiq' into PBI-4-menambahkan_informasi_fasilitas_publik

parents a1ca60b8 bf56b92d
Pipeline #42415 passed with stages
in 48 minutes and 26 seconds
{"_info":"// This is a generated file; do not edit or check into version control.","dependencyGraph":[{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"google_maps_flutter","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"image_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"location","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos"]},{"name":"path_provider_macos","dependencies":[]},{"name":"sqflite","dependencies":[]}]}
\ No newline at end of file
{"_info":"// This is a generated file; do not edit or check into version control.","dependencyGraph":[{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"google_maps_flutter","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"image_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"location","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos"]},{"name":"path_provider_macos","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]}]}
\ No newline at end of file
import 'package:flutter/material.dart';
import 'package:ppl_disabilitas/config/styles.dart';
import 'package:ppl_disabilitas/page/login/login.dart';
import 'package:shared_preferences/shared_preferences.dart';
class BisaGoDrawer extends StatelessWidget {
final List<Map<String, dynamic>> drawerList = [
{'title': 'Beranda', 'icon': Icons.home},
{'title': 'Riwayat Pencarian', 'icon': Icons.history},
{'title': 'Tentang Aplikasi', 'icon': Icons.info},
{'title': 'Log out', 'icon': Icons.keyboard_backspace}
{'title': 'Login', 'icon': Icons.keyboard_backspace}
];
@override
......@@ -24,10 +26,14 @@ class BisaGoDrawer extends StatelessWidget {
),
child: Row(
children: <Widget>[
FloatingActionButton(
backgroundColor: Colors.white,
elevation: 0,
onPressed: () => {},
SizedBox(
width: 40,
child: FloatingActionButton(
heroTag: null,
backgroundColor: Colors.white,
elevation: 0,
onPressed: () => {},
),
),
Padding(
padding: EdgeInsets.all(doubleSpace),
......@@ -52,6 +58,7 @@ class BisaGoDrawer extends StatelessWidget {
menus.forEach((menu) {
drawerItem.add(menu);
});
return Theme(
data: Theme.of(context).copyWith(
canvasColor: greenPrimary,
......@@ -79,7 +86,10 @@ class BisaGoDrawer extends StatelessWidget {
),
),
onTap: () {
Navigator.pop(context);
if(title == 'Login') {
checkLoginStatus(context);
title = 'Logout';
}
},
),
decoration: BoxDecoration(
......@@ -90,4 +100,19 @@ class BisaGoDrawer extends StatelessWidget {
),
);
}
checkLoginStatus(BuildContext context) async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
if(sharedPreferences.getString("token") == null) {
_navigateToLoginPage(context);
}
else {
await sharedPreferences.clear();
await Navigator.pushNamed(context, '/');
}
}
void _navigateToLoginPage(BuildContext context) {
final route = MaterialPageRoute(builder: (_) => Login());
Navigator.of(context).push(route);
}
}
......@@ -5,5 +5,5 @@ import 'flavor/flavor.dart';
void main() {
ApiFlavor.flavor = BuildFlavor.production.toString();
runApp(BisaGo());
}
}
import 'dart:convert';
class User {
bool is_login;
String username;
String name;
String email;
String phone_number;
String token;
User({this.is_login, this.username, this.name, this.email, this.phone_number, this.token});
factory User.fromJson(Map<String, dynamic> map) {
return User(
username: map["username"],
name: map["name"],
email: map["email"],
phone_number: map["phone_number"],);
}
Map<String, dynamic> toJson() {
return {"username": username, "name": name, "email": email, "phone_number": phone_number};
}
@override
String toString() {
return 'User{"username": $username, "name": $name, "email": $email, "phone_number": $phone_number}';
}
}
List<User> userFromJson(String jsonData) {
final data = json.decode(jsonData);
return List<User>.from(data.map((item) => User.fromJson(item)));
}
String userToJson(User data) {
final jsonData = data.toJson();
return json.encode(jsonData);
}
\ No newline at end of file
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:flutter/cupertino.dart';
......@@ -5,13 +6,17 @@ import 'package:flutter/material.dart';
import 'package:ppl_disabilitas/utils/customDeskripsiField.dart';
import 'package:ppl_disabilitas/utils/customButton.dart';
import 'package:ppl_disabilitas/utils/validator.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:smooth_star_rating/smooth_star_rating.dart';
import 'package:image_picker/image_picker.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class AddInformasi extends StatefulWidget{
final String nama;
AddInformasiState createState() => AddInformasiState();
AddInformasi({this.nama});
}
class AddInformasiState extends State<AddInformasi> {
......@@ -106,13 +111,13 @@ class AddInformasiState extends State<AddInformasi> {
GestureDetector(
onTap: _getImage,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0),
decoration: const BoxDecoration(
padding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: const Radius.circular(20.0),
topRight: const Radius.circular(20.0),
bottomLeft: const Radius.circular(20.0),
bottomRight: const Radius.circular(20.0),
topLeft: Radius.circular(20.0),
topRight: Radius.circular(20.0),
bottomLeft: Radius.circular(20.0),
bottomRight: Radius.circular(20.0),
),
color: Colors.black12,
),
......@@ -136,7 +141,7 @@ class AddInformasiState extends State<AddInformasi> {
shrinkWrap: true,
key: Key('Checkbox Fasilitas'),
children: fasilitas.keys.map((String key) {
return new CheckboxListTile(
return CheckboxListTile(
title: Text(key),
value: fasilitas[key],
onChanged: (bool value) {
......@@ -185,7 +190,7 @@ class AddInformasiState extends State<AddInformasi> {
elevation: 0.0,
color: Colors.white70,
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.all(Radius.circular(10)),
borderRadius: BorderRadius.all(Radius.circular(10)),
side: BorderSide(color: Color(0xff3A903A))
),
......@@ -210,7 +215,7 @@ class AddInformasiState extends State<AddInformasi> {
height: 40,
child: submitButton(
'Simpan', Color(0xff3A903A), Colors.white,
Color(0xff3A903A), Colors.white, _validateLoginInput),
Color(0xff3A903A), Colors.white, _validateInformationInput),
),
),
......@@ -233,21 +238,34 @@ class AddInformasiState extends State<AddInformasi> {
}
addInfo(String tag, String deskripsi, String rating) async {
for(MapEntry<String, bool> me in fasilitas.entries)
for(MapEntry<String, bool> me in fasilitas.entries) {
if(me.value == true) tag = tag + tags[me.key] + ' ';
}
Map data = {
'tag': tag,
'deskripsi': deskripsi,
'rating' : rating,
};
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
String namaTempat = widget.nama;
var response = await http.post(
'http://poipole-staging.herokuapp.com/informasi-lokasi/lokasi/detail/*nama_lokasi*', body: data);
if (response.statusCode == 200) {
'http://poipole-staging.herokuapp.com/informasi-fasilitas/lokasi/add-fasilitas/$namaTempat/',
headers: {"Authorization" : "token " + sharedPreferences.getString("token")},
body: data);
Map<String, dynamic> test = jsonDecode(response.body);
String testing = test['response'];
// var response = await http.get('http://poipole-staging.herokuapp.com/informasi-fasilitas/lokasi/list-fasilitas/$namaTempat/');
if (response.statusCode == 201) {
print(response.body);
inputData(context);
}
else {
print(sharedPreferences.getString("token"));
print(namaTempat);
print(response.statusCode);
print(data);
print(testing);
inputData(context);
}
}
......@@ -265,19 +283,20 @@ class AddInformasiState extends State<AddInformasi> {
);
}
void _validateLoginInput() async {
void _validateInformationInput() async {
final FormState form = _formKey.currentState;
if(_formKey.currentState.validate()) {
form.save();
await addInfo(tag, deskripsiController.text.toString(), rating.toStringAsFixed(2));
int ratingInt = rating.toInt();
await addInfo(tag, deskripsiController.text.toString(), ratingInt.toString());
}
}
void _resetInput() async{
deskripsiController.clear();
rating = 0.0;
_clearImage();
_clearCheckBox();
await _clearImage();
await _clearCheckBox();
}
......
......@@ -5,8 +5,11 @@ import 'package:ppl_disabilitas/component/bisago_appbar.dart';
import 'package:ppl_disabilitas/component/bisago_drawer.dart';
import 'package:ppl_disabilitas/config/styles.dart';
import 'package:ppl_disabilitas/network/data/network_model.dart';
import 'package:ppl_disabilitas/page/addInformasi/addInfromasi.dart';
import 'package:ppl_disabilitas/page/filter_fasilitas/komentar.dart';
import 'package:ppl_disabilitas/model/komentar.dart';
import 'package:ppl_disabilitas/page/login/login.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Fasilitas extends StatefulWidget {
......@@ -134,7 +137,7 @@ class _FasilitasState extends State<Fasilitas> {
side: BorderSide(color: Colors.transparent)),
splashColor: Colors.lightGreen,
onPressed: () {
/*...*/
checkLoginStatus();
},
child: Text(
"Tambah Informasi",
......@@ -933,4 +936,19 @@ class _FasilitasState extends State<Fasilitas> {
sortKomentar = -1;
super.dispose();
}
checkLoginStatus() async {
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
if(sharedPreferences.getString("token") == null) {
await Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (BuildContext context) => Login()), (Route<dynamic> route) => false);
}
else {
await Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => AddInformasi(
nama: widget.nama,
)));
}
}
}
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:ppl_disabilitas/config/styles.dart';
import 'package:ppl_disabilitas/page/registrasi/registrasi.dart';
import 'package:ppl_disabilitas/utils/customButton.dart';
import 'package:ppl_disabilitas/utils/customTextField.dart';
import 'package:ppl_disabilitas/utils/validator.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
class Login extends StatefulWidget{
......@@ -12,12 +18,43 @@ class Login extends StatefulWidget{
class LoginState extends State<Login> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
SharedPreferences sharedPreferences;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('bisaGO'),
elevation: 15,
centerTitle: true,
backgroundColor: Color(0xff3A903A),
backgroundColor: greenPrimary,
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(padding: EdgeInsets.all(doubleSpace),
child: Text(
"bisaGo",
style: TextStyle(
fontSize: 25,
fontFamily: 'Comfortaa',
fontWeight: FontWeight.w800),
),
)
],
),
actions: <Widget>[
Padding(
padding: EdgeInsets.all(doubleSpace),
child: InkWell(
child: Text(
'Daftar',
style: TextStyle(fontSize: 15),
),
onTap: () {
_navigateToRegistrasiPage(context);
},
),
)
],
),
body: SingleChildScrollView(
child: Form(
......@@ -41,17 +78,15 @@ class LoginState extends State<Login> {
CustomTextField(
title: 'Nomor Telepon atau Email',
key: Key('Text Field Akun'),
onSaved: (input) {
},
validator: FieldValidator.validateEmail,
controller: emailController,
),
CustomTextField(
title: 'Password',
key: Key('Text Field Password'),
obsecure: true,
onSaved: (input) {
},
validator: FieldValidator.validatePassword,
controller: passwordController,
),
Container(
margin: EdgeInsets.fromLTRB(0, 30, 0, 10),
......@@ -85,6 +120,36 @@ class LoginState extends State<Login> {
final FormState form = _formKey.currentState;
if(_formKey.currentState.validate()) {
form.save();
login(emailController.text, passwordController.text);
}
}
TextEditingController emailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
login(String email, String password) async {
Map data = {
'username' : email,
'password' : password
};
sharedPreferences = await SharedPreferences.getInstance();
var response = await http.post('http://poipole-staging.herokuapp.com/api-token-auth/', body: data);
if(response.statusCode == 200) {
Map<String, dynamic> tokenMap = jsonDecode(response.body);
setState(() {
sharedPreferences.setString("token", tokenMap['token']);
sharedPreferences.setString("email", email);
Navigator.pushNamed(context, '/');
});
}
else {
print(response.body);
}
}
void _navigateToRegistrasiPage(BuildContext context) {
final route = MaterialPageRoute(builder: (_) => Registrasi());
Navigator.of(context).push(route);
}
}
\ No newline at end of file
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:ppl_disabilitas/config/styles.dart';
import 'package:ppl_disabilitas/page/dashboard/dashboard.dart';
import 'package:ppl_disabilitas/utils/customButton.dart';
import 'package:ppl_disabilitas/utils/customTextField.dart';
import 'package:ppl_disabilitas/utils/validator.dart';
import 'package:http/http.dart' as http;
class Registrasi extends StatefulWidget {
RegistrasiState createState() => RegistrasiState();
......@@ -13,9 +17,38 @@ class RegistrasiState extends State<Registrasi> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('bisaGO'),
elevation: 15,
centerTitle: true,
backgroundColor: Color(0xff3A903A),
backgroundColor: greenPrimary,
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(padding: EdgeInsets.all(doubleSpace),
child: Text(
"bisaGo",
style: TextStyle(
fontSize: 25,
fontFamily: 'Comfortaa',
fontWeight: FontWeight.w800),
),
)
],
),
actions: <Widget>[
Padding(
padding: EdgeInsets.all(doubleSpace),
child: InkWell(
child: Text(
'Login',
style: TextStyle(fontSize: 15),
),
onTap: () {
Navigator.pop(context);
},
),
)
],
),
body: SingleChildScrollView(
child: Form(
......@@ -39,28 +72,38 @@ class RegistrasiState extends State<Registrasi> {
CustomTextField(
title: 'Nama Lengkap',
key: Key('Text Field Nama'),
validator: (input) => input.isEmpty ? "*Wajib diisi" : null,
validator: FieldValidator.validateName,
controller: nameController,
),
CustomTextField(
title: 'Nomor Telepon',
key: Key('Text Field Nomor Telepon'),
validator: (input) => input.isEmpty ? "*Wajib diisi" : null,
validator: FieldValidator.validatePhoneNumber,
controller: phoneController,
),
CustomTextField(
title: 'Email (Opsional)',
title: 'Email',
key: Key('Text Field Email'),
controller: emailController,
validator: FieldValidator.validateEmail,
),
CustomTextField(
title: 'Password',
key: Key('Text Field Password'),
obsecure: true,
validator: (input) => input.isEmpty ? "*Wajib diisi" : null,
validator: FieldValidator.validatePassword,
controller: passwordController,
),
CustomTextField(
title: 'Konfirmasi Password',
key: Key('Text Field Konfirmasi Password'),
obsecure: true,
validator: (input) => input.isEmpty ? "*Wajib diisi" : null,
validator: (input) {
if (input != passwordController.text) {
return '*Password tidak sesuai. Coba lagi';
}
return null;
},
),
Container(
margin: EdgeInsets.fromLTRB(0, 30, 0, 10),
......@@ -88,10 +131,61 @@ class RegistrasiState extends State<Registrasi> {
),
);
}
void _validateLoginInput() async {
final FormState form = _formKey.currentState;
if (_formKey.currentState.validate()) {
form.save();
await createUser(nameController.text.toString(), phoneController.text.toString(),
emailController.text.toString(), passwordController.text.toString());
_showDialog();
}
}
}
\ No newline at end of file
TextEditingController nameController = TextEditingController();
TextEditingController phoneController = TextEditingController();
TextEditingController emailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
createUser(String name, String phone_number, String email, String password) async {
Map data = {
'name' : name,
'phone_number' : phone_number,
'email' : email,
'password' : password,
};
final response = await http.post(
"http://poipole-staging.herokuapp.com/api/register/",
// headers: {"Content-Type": "application/json"},
body: data,
);
if (response.statusCode == 200) {
} else {
return false;
}
}
void _showDialog() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Pendaftaran Berhasil"),
content: Text("Silahkan kembali ke halaman utama untuk login"),
actions: <Widget>[
FlatButton(onPressed: () {
_navigateToDashboard(context);
},
child: Text("Dashboard"))
],
);
}
);
}
void _navigateToDashboard(BuildContext context) {
final route = MaterialPageRoute(builder: (_) => Dashboard());
Navigator.of(context).push(route);
}
}
......@@ -11,7 +11,7 @@ Color fillColor, Color textColor, void function()) {
elevation: 0.0,
color: fillColor,
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.all(Radius.circular(10)),
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: Text(
text,
......
......@@ -2,25 +2,51 @@ class FieldValidator {
static String validateEmail(String value) {
Pattern pattern =
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
RegExp regex = new RegExp(pattern);
RegExp regex = RegExp(pattern);
if (value.isEmpty) return '*Wajib diisi';
if (!regex.hasMatch(value))
if (!regex.hasMatch(value)) {
return '*Masukkan email yang valid';
else
} else {
return null;
}
}
static String validatePassword(String value) {