Initial commit: Penyerahan final Source code Tugas Akhir
This commit is contained in:
@ -0,0 +1,377 @@
|
||||
// this screen is only when the profile (name, email, phone number, password) is not complete
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:initial_folder/models/data_diri_model.dart';
|
||||
import 'package:initial_folder/providers/data_diri_provider.dart';
|
||||
import 'package:initial_folder/providers/firebase_authentication_provider.dart';
|
||||
import 'package:initial_folder/providers/incomplete_profile_provider.dart';
|
||||
import 'package:initial_folder/screens/home/home_screen.dart';
|
||||
import 'package:initial_folder/helper/validator.dart';
|
||||
import 'package:initial_folder/screens/login/login_screen.dart';
|
||||
import 'package:initial_folder/screens/login/login_with_email/login_email_screen.dart';
|
||||
import 'package:initial_folder/screens/registrasi/registrasi_screen.dart';
|
||||
import 'package:initial_folder/services/user_info_service.dart';
|
||||
import 'package:initial_folder/size_config.dart';
|
||||
import 'package:initial_folder/theme.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/custom_profile_text_field.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/default_button.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/footer.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/header.dart';
|
||||
import 'package:initial_folder/widgets/login_regist/loading_button.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:initial_folder/helper/user_info.dart';
|
||||
|
||||
class IncompleteProfile extends StatefulWidget {
|
||||
static String routeName = "/uncomplete_profile";
|
||||
IncompleteProfile({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_IncompleteProfileState createState() => _IncompleteProfileState();
|
||||
}
|
||||
|
||||
class _IncompleteProfileState extends State<IncompleteProfile> {
|
||||
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
||||
|
||||
final TextEditingController reEmailController =
|
||||
TextEditingController(text: '');
|
||||
final TextEditingController passwordController =
|
||||
TextEditingController(text: '');
|
||||
final TextEditingController rePasswordController =
|
||||
TextEditingController(text: '');
|
||||
|
||||
bool isLoading = false;
|
||||
bool _isObscure = true;
|
||||
bool _isObscure1 = true;
|
||||
|
||||
bool? isEmailEmpty = false;
|
||||
bool? isPhoneEmpty = false;
|
||||
bool? isNameEmpty = false;
|
||||
|
||||
late String newName = '';
|
||||
late String newEmail = '';
|
||||
late String newPhone = '';
|
||||
late String password = '';
|
||||
late String rePassword = '';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SizeConfig().init(context);
|
||||
|
||||
IncompleteProfileProvider incompleteProfileProvider =
|
||||
Provider.of<IncompleteProfileProvider>(context);
|
||||
|
||||
Future _showMessage(String text) {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
contentPadding: EdgeInsets.fromLTRB(22, 30, 22, 30),
|
||||
content: Text(
|
||||
text,
|
||||
textAlign: TextAlign.center,
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(12), letterSpacing: 1),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
handleProfile(DataDiriProvider state, DataOfDataDiriModel result) async {
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
if (await incompleteProfileProvider.updateIncompleteProfile(
|
||||
fullname: state.newName ? newName : result.fullname ?? '',
|
||||
email: state.newEmail ? newEmail : result.email ?? '',
|
||||
phone: state.newPhone ? newPhone : result.phone ?? '',
|
||||
newPassword: password,
|
||||
newConfirmPassword: rePassword)) {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
HomeScreen.routeName, (Route<dynamic> route) => false);
|
||||
} else {
|
||||
if (incompleteProfileProvider.updateIncompleteProfileModel != null) {
|
||||
dynamic updateIncompleteProfileMessages =
|
||||
incompleteProfileProvider.updateIncompleteProfileModel!.messages;
|
||||
if (updateIncompleteProfileMessages is! String) {
|
||||
// validate name from backend
|
||||
if (updateIncompleteProfileMessages.fullname is String) {
|
||||
setState(() {
|
||||
isNameEmpty = true;
|
||||
});
|
||||
}
|
||||
// validate datebirth from backend
|
||||
if (updateIncompleteProfileMessages.phone is String) {
|
||||
setState(() {
|
||||
isPhoneEmpty = true;
|
||||
});
|
||||
}
|
||||
// validate datebirth from backend
|
||||
if (updateIncompleteProfileMessages.email is String) {
|
||||
setState(() {
|
||||
isEmailEmpty = true;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (incompleteProfileProvider
|
||||
.updateIncompleteProfileModel!.status ==
|
||||
404) {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
LoginEmail.routeName, (Route<dynamic> route) => false);
|
||||
|
||||
_showMessage("Sesi habis silahkan login ulang");
|
||||
} else {
|
||||
_showMessage(updateIncompleteProfileMessages);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
void _validateInputs(DataDiriProvider state, DataOfDataDiriModel result) {
|
||||
if (this._formKey.currentState!.validate()) {
|
||||
handleProfile(state, result);
|
||||
}
|
||||
}
|
||||
|
||||
Widget form(DataDiriProvider state, DataOfDataDiriModel result) {
|
||||
Widget nameInput() {
|
||||
return CustomProfileTextField(
|
||||
pad: getProportionateScreenWidth(16),
|
||||
text: state.newName ? newName : result.fullname ?? '',
|
||||
hinttext: 'Masukan nama lengkap',
|
||||
title: 'Nama Lengkap',
|
||||
validate: validateName,
|
||||
onChanged: (value) {
|
||||
isNameEmpty = false;
|
||||
state.newName = true;
|
||||
newName = value;
|
||||
},
|
||||
isErrorManual: isNameEmpty ?? false,
|
||||
textErrorManual: "Nama lengkap tidak boleh kosong",
|
||||
);
|
||||
}
|
||||
|
||||
Widget emailInput() {
|
||||
return CustomProfileTextField(
|
||||
pad: getProportionateScreenWidth(16),
|
||||
text: state.newEmail ? newEmail : result.email ?? '',
|
||||
hinttext: 'Masukan email',
|
||||
title: 'Email',
|
||||
validate: validateEmail,
|
||||
onChanged: (value) {
|
||||
isEmailEmpty = false;
|
||||
state.newEmail = true;
|
||||
newEmail = value;
|
||||
},
|
||||
isErrorManual: isEmailEmpty ?? false,
|
||||
textErrorManual: "Mohon masukkan email yang valid",
|
||||
);
|
||||
}
|
||||
|
||||
Widget reEmailInput() {
|
||||
return CustomProfileTextField(
|
||||
pad: getProportionateScreenWidth(16),
|
||||
text: '',
|
||||
hinttext: 'Masukan konfirmasi email',
|
||||
title: 'Konfirmasi Email',
|
||||
validate: (String? value) {
|
||||
return validateReEmail(
|
||||
value, state.newEmail ? newEmail : result.email ?? '');
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget phoneNumberInput() {
|
||||
return CustomProfileTextField(
|
||||
pad: getProportionateScreenWidth(16),
|
||||
text: state.newPhone ? newPhone : result.phone ?? '',
|
||||
hinttext: 'Masukan no hp',
|
||||
title: 'No Telepon',
|
||||
validate: validatePhone,
|
||||
onChanged: (value) {
|
||||
isPhoneEmpty = false;
|
||||
state.newPhone = true;
|
||||
newPhone = value;
|
||||
},
|
||||
isErrorManual: isPhoneEmpty ?? false,
|
||||
textErrorManual: "Mohon masukkan nomor telepon yang valid",
|
||||
);
|
||||
}
|
||||
|
||||
Widget passwordInput() {
|
||||
return CustomProfileTextField(
|
||||
pad: getProportionateScreenWidth(16),
|
||||
text: '',
|
||||
hinttext: 'Masukan password',
|
||||
title: 'Password',
|
||||
validate: validatePassword,
|
||||
onChanged: (value) {
|
||||
password = value;
|
||||
},
|
||||
obscuretext: _isObscure,
|
||||
suffix: GestureDetector(
|
||||
onTap: () => setState(() {
|
||||
_isObscure = !_isObscure;
|
||||
}),
|
||||
child: _isObscure
|
||||
? Icon(
|
||||
FeatherIcons.eyeOff,
|
||||
color: secondaryColor,
|
||||
size: 18,
|
||||
)
|
||||
: Icon(
|
||||
FeatherIcons.eye,
|
||||
color: secondaryColor,
|
||||
size: 18,
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
Widget rePasswordInput() {
|
||||
return CustomProfileTextField(
|
||||
pad: getProportionateScreenWidth(16),
|
||||
text: '',
|
||||
hinttext: 'Masukan password',
|
||||
title: 'Konfirmasi Password',
|
||||
validate: (String? value) {
|
||||
return validateRePassword(value, password);
|
||||
},
|
||||
onChanged: (value) {
|
||||
rePassword = value;
|
||||
},
|
||||
obscuretext: _isObscure1,
|
||||
suffix: GestureDetector(
|
||||
onTap: () => setState(() {
|
||||
_isObscure1 = !_isObscure1;
|
||||
}),
|
||||
child: _isObscure1
|
||||
? Icon(
|
||||
FeatherIcons.eyeOff,
|
||||
color: secondaryColor,
|
||||
size: 18,
|
||||
)
|
||||
: Icon(
|
||||
FeatherIcons.eye,
|
||||
color: secondaryColor,
|
||||
size: 18,
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
Widget button() {
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: getProportionateScreenWidth(15),
|
||||
right: getProportionateScreenWidth(15),
|
||||
top: getProportionateScreenHeight(3)),
|
||||
child: isLoading
|
||||
? LoadingButton(
|
||||
backgroundButtonColor: primaryColor,
|
||||
textButtonColor: Color(0xff050505))
|
||||
: DefaultButton(
|
||||
text: 'Simpan',
|
||||
press: () {
|
||||
_validateInputs(state, result);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: [
|
||||
phoneNumberInput(),
|
||||
passwordInput(),
|
||||
rePasswordInput(),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(8),
|
||||
),
|
||||
button(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
body: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
final provider = Provider.of<FirebaseAuthenticationProvider>(
|
||||
context,
|
||||
listen: false);
|
||||
|
||||
await UsersInfo().logout();
|
||||
await provider.logout();
|
||||
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
RegistrationScreen.routeName,
|
||||
(Route<dynamic> route) => false);
|
||||
},
|
||||
icon: Icon(Icons.arrow_back),
|
||||
iconSize: getProportionateScreenWidth(18),
|
||||
padding: EdgeInsets.all(getProportionateScreenWidth(8)),
|
||||
),
|
||||
Container(
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: Header(
|
||||
text: 'Yuk Lengkapi Profile kamu sebelum memulai',
|
||||
style: primaryTextStyle.copyWith(
|
||||
fontSize: getProportionateScreenWidth(14),
|
||||
letterSpacing: 0.5)),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: getProportionateScreenHeight(32),
|
||||
),
|
||||
ChangeNotifierProvider(
|
||||
create: (context) =>
|
||||
DataDiriProvider(userInfoService: UserInfoService()),
|
||||
child:
|
||||
Consumer<DataDiriProvider>(builder: (context, state, _) {
|
||||
if (state.state == ResultStateData.Loading) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator(
|
||||
color: secondaryColor,
|
||||
strokeWidth: 2,
|
||||
),
|
||||
);
|
||||
} else if (state.state == ResultStateData.HasData) {
|
||||
var result = state.result!.data[0];
|
||||
return form(state, result);
|
||||
} else if (state.state == ResultStateData.NoData) {
|
||||
return Center(child: Text(state.message));
|
||||
} else if (state.state == ResultStateData.Error) {
|
||||
return Center(
|
||||
child: TextButton(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text('Server internal Error ${state.message}'),
|
||||
Icon(Icons.refresh)
|
||||
],
|
||||
),
|
||||
onPressed: () {}),
|
||||
);
|
||||
} else {
|
||||
return Center(child: Text('Gagal mengambil data'));
|
||||
}
|
||||
})),
|
||||
SizedBox(height: getProportionateScreenHeight(32)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user