added kode otp page, input informasi diri page, and user index tracking page, repair the back button on UserIndexTrackingView

This commit is contained in:
kicap
2023-07-17 04:39:00 +08:00
parent 4c5ec4364d
commit b20b414a21
22 changed files with 1051 additions and 33 deletions

View File

@ -1,10 +1,19 @@
import 'package:flutter/material.dart';
import 'package:reza_app/app/app.router.dart';
import 'package:reza_app/ui/widgets/my_button.dart';
import 'package:reza_app/ui/widgets/my_textformfield.dart';
import 'package:stacked/stacked.dart';
import 'package:validatorless/validatorless.dart';
import '../../../../app/themes/app_colors.dart';
import '../../../../app/themes/app_text.dart';
import './input_informasi_diri_view_model.dart';
class InputInformasiDiriView extends StatelessWidget {
const InputInformasiDiriView({super.key});
final String noHp;
const InputInformasiDiriView({Key? key, required this.noHp})
: super(key: key);
@override
Widget build(BuildContext context) {
@ -18,10 +27,155 @@ class InputInformasiDiriView extends StatelessWidget {
InputInformasiDiriViewModel model,
Widget? child,
) {
return const Scaffold(
body: Center(
child: Text(
'InputInformasiDiriView',
return Scaffold(
appBar: AppBar(
title: const Text('INPUT INFORMASI DIRI',
style: TextStyle(
color: lightColor,
)),
backgroundColor: mainColor,
iconTheme: const IconThemeData(
color:
Colors.white), // Set the color of the back button to white
),
body: WillPopScope(
onWillPop: () async {
if (model.backPressed) {
model.navigationService.navigateToMasukanNoHpView();
}
return false;
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 25),
child: SingleChildScrollView(
child: Form(
key: model.formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
const SizedBox(height: 25),
Center(
child: Image.asset(
'assets/logo.png',
width: 100,
height: 100,
alignment: Alignment.center,
),
),
const SizedBox(height: 15),
const Align(
alignment: Alignment.centerLeft,
child: Text(
' No . HP',
),
),
const SizedBox(height: 5),
MyTextFormField(
initialValue: noHp,
readOnly: true,
),
const SizedBox(height: 15),
const Align(
alignment: Alignment.centerLeft,
child: Text(
' Nama Lengkap',
),
),
const SizedBox(height: 5),
MyTextFormField(
hintText: 'Masukan Nama Lengkap',
controller: model.namaLengkapController,
validator: Validatorless.required(
'Nama Lengkap tidak boleh kosong',
),
),
const SizedBox(height: 15),
const Align(
alignment: Alignment.centerLeft,
child: Text(
' Tanggal Lahir',
),
),
const SizedBox(height: 5),
MyTextFormField(
hintText: 'Pilih Tanggal Lahir',
readOnly: true,
controller: model.tanggalLahirController,
validator: Validatorless.required(
'Tanggal Lahir tidak boleh kosong',
),
onTap: () => model.selectDate(context),
),
const SizedBox(height: 15),
const Align(
alignment: Alignment.centerLeft,
child: Text(
' Jenis Kelamin',
),
),
Container(
width: double.infinity,
height: 60,
padding: const EdgeInsets.symmetric(horizontal: 10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
border: Border.all(
color: mainColor,
),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: model.jenisKelamin,
onChanged: (String? newValue) {
// model.setSelectedJenisKelamin(newValue!);
model.log.i(newValue);
model.jenisKelamin = newValue!;
model.notifyListeners();
},
items: model.jenisKelaminList.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: regularTextStyle.copyWith(
fontSize: 16,
),
),
);
}).toList(),
),
),
),
const SizedBox(height: 15),
const Align(
alignment: Alignment.centerLeft,
child: Text(
' Alamat',
),
),
const SizedBox(height: 5),
MyTextFormField(
hintText: 'Masukan Alamat',
maxLines: 3,
controller: model.alamatController,
validator: Validatorless.required(
'Alamat tidak boleh kosong',
),
),
const SizedBox(height: 15),
MyButton(
text: 'Daftar',
onPressed: () {
if (model.formKey.currentState!.validate()) {
model.goToLogin();
}
},
),
const SizedBox(height: 25),
],
),
),
),
),
),
);

View File

@ -1,5 +1,46 @@
import 'package:reza_app/app/core/custom_base_view_model.dart';
import 'package:flutter/material.dart';
import '../../../../app/app.router.dart';
import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart';
class InputInformasiDiriViewModel extends CustomBaseViewModel {
final log = getLogger('InputInformasiDiriViewModel');
Future<void> init() async {}
List<String> jenisKelaminList = ['Laki-laki', 'Perempuan'];
String jenisKelamin = 'Laki-laki';
TextEditingController namaLengkapController = TextEditingController();
TextEditingController tanggalLahirController = TextEditingController();
TextEditingController alamatController = TextEditingController();
GlobalKey<FormState> formKey = GlobalKey<FormState>();
selectDate(BuildContext context) async {
// get today's date
var datePicked = await showDatePicker(
context: context,
initialDate: DateTime(2013),
firstDate: DateTime(1950),
// last date is today's date
lastDate: DateTime(2013),
);
if (datePicked != null) {
String date = datePicked.toString().split(' ')[0];
tanggalLahirController.text = date;
}
}
goToLogin() async {
backPressed = false;
easyLoading.customLoading("Mendaftarkan Akun Anda");
await Future.delayed(const Duration(seconds: 2));
easyLoading.customLoading("Ke Halaman Login");
await Future.delayed(const Duration(seconds: 2));
easyLoading.dismissLoading();
backPressed = true;
notifyListeners();
await navigationService.navigateToLoginUserView();
}
}

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import '../../../../app/app.router.dart';
import 'package:stacked/stacked.dart';
import 'package:validatorless/validatorless.dart';
@ -35,7 +36,10 @@ class MasukanNoHpView extends StatelessWidget {
),
body: WillPopScope(
onWillPop: () async {
return model.backPressed;
if (model.backPressed) {
model.navigationService.navigateToLoginUserView();
}
return false;
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 25),
@ -78,6 +82,7 @@ class MasukanNoHpView extends StatelessWidget {
if (!model.formKey.currentState!.validate()) {
return;
}
FocusScope.of(context).unfocus();
model.log.i('Selanjutnya button pressed');
model.selanjutnya();
},

View File

@ -1,6 +1,9 @@
import 'package:flutter/material.dart';
import 'package:otp_text_field/otp_text_field.dart';
import 'package:otp_text_field/style.dart';
import 'package:stacked/stacked.dart';
import '../../../../app/themes/app_colors.dart';
import './verifikasi_no_hp_view_model.dart';
class VerifikasiNoHpView extends StatelessWidget {
@ -18,10 +21,128 @@ class VerifikasiNoHpView extends StatelessWidget {
VerifikasiNoHpViewModel model,
Widget? child,
) {
return const Scaffold(
body: Center(
child: Text(
'VerifikasiNoHpView',
return Scaffold(
appBar: AppBar(
title: const Text(
'Verifikasi No. HP',
style: TextStyle(
color: lightColor,
),
),
backgroundColor: mainColor,
iconTheme: const IconThemeData(
color:
Colors.white), // Set the color of the back button to white
),
body: WillPopScope(
onWillPop: () async {
if (model.backPressed) {
model.back();
}
return false;
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 25),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/logo.png',
width: 75,
height: 75,
),
const SizedBox(height: 15),
const Text(
'Masukkan Kode OTP yang telah \ndikirimkan ke nomor HP anda',
textAlign: TextAlign.center,
),
const SizedBox(height: 5),
OTPTextField(
length: 6,
width: MediaQuery.of(context).size.width,
fieldWidth: 50,
style: const TextStyle(fontSize: 17),
textFieldAlignment: MainAxisAlignment.spaceAround,
fieldStyle: FieldStyle.box,
onCompleted: (pin) {
model.log.i('Completed: $pin');
model.noOTP = int.parse(pin);
model.notifyListeners();
},
onChanged: (value) {
model.log.i('onChanged: $value');
model.noOTP = int.parse(value);
model.notifyListeners();
},
),
const SizedBox(height: 5),
RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: 'Kode OTP kadaluarsa dalam ',
style: const TextStyle(color: Colors.black),
children: [
const TextSpan(
text: '00:30\n',
style: TextStyle(color: mainColor),
),
WidgetSpan(
child: GestureDetector(
onTap: () {
// Handle tap
},
child: const Center(
child: Text(
'Kirim ulang kode OTP',
style: TextStyle(
color: mainColor,
fontSize: 14,
height: 1.5,
decoration: TextDecoration.underline,
),
),
),
),
),
],
),
),
const SizedBox(height: 5),
SizedBox(
width: MediaQuery.of(context).size.width * 0.5,
child: ElevatedButton(
onPressed: () {
if (model.noOTP == null) {
model.snackbarService.showSnackbar(
message: 'Kode OTP tidak boleh kosong');
return;
}
// check the length of noOTP
if (model.noOTP.toString().length < 6) {
model.snackbarService.showSnackbar(
message: 'Kode OTP tidak boleh kurang dari 6');
return;
}
// hide the keyboard
FocusScope.of(context).unfocus();
model.log.i('noOTP: ${model.noOTP}');
model.goToInputInformasiDiri();
},
style: ElevatedButton.styleFrom(
backgroundColor: mainColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
child: const Text('Verifikasi'),
),
),
],
),
),
),
),
);

View File

@ -1,5 +1,22 @@
import 'package:reza_app/app/core/custom_base_view_model.dart';
import '../../../../app/app.logger.dart';
import '../../../../app/app.router.dart';
import '../../../../app/core/custom_base_view_model.dart';
class VerifikasiNoHpViewModel extends CustomBaseViewModel {
final log = getLogger('VerifikasiNoHpViewModel');
int? noOTP;
Future<void> init() async {}
goToInputInformasiDiri() async {
backPressed = false;
easyLoading.customLoading("Ke Halaman Input Informasi Diri");
await Future.delayed(const Duration(seconds: 3));
easyLoading.dismissLoading();
backPressed = true;
notifyListeners();
await navigationService.navigateToInputInformasiDiriView(
noHp: "082293246583",
);
}
}