first commit

This commit is contained in:
kicap
2023-11-09 02:42:23 +08:00
commit ba5d6fa38b
54 changed files with 4841 additions and 0 deletions

View File

@ -0,0 +1,191 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import 'package:validatorless/validatorless.dart';
import '../../../../../app/themes/app_colors.dart';
import '../../../../../app/themes/app_text.dart';
import '../../../../widgets/my_textformfield.dart';
import './ganti_password_dialog_view_model.dart';
class GantiPasswordDialogView extends StatelessWidget {
final DialogRequest? request;
final Function(DialogResponse)? completer;
const GantiPasswordDialogView({
Key? key,
this.request,
this.completer,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ViewModelBuilder<GantiPasswordDialogViewModel>.reactive(
viewModelBuilder: () => GantiPasswordDialogViewModel(),
onViewModelReady: (GantiPasswordDialogViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
GantiPasswordDialogViewModel model,
Widget? child,
) {
return Dialog(
child: Container(
padding: const EdgeInsets.all(20),
child: Form(
key: model.globalKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Ganti Password',
style: boldTextStyle.copyWith(fontSize: 18),
),
const SizedBox(height: 20),
MyTextFormField(
labelText: 'Password Lama',
hintText: 'Masukkan password lama',
obscureText: model.isPasswordLamaObscure,
suffixIcon: IconButton(
onPressed: () {
model.isPasswordLamaObscure =
!model.isPasswordLamaObscure;
model.notifyListeners();
},
icon: Icon(
model.isPasswordLamaObscure
? Icons.visibility_off
: Icons.visibility,
),
),
controller: model.passwordLamaController,
validator: Validatorless.multiple(
[
Validatorless.required(
'Password lama tidak boleh kosong'),
Validatorless.min(
8, 'Password lama minimal 8 karakter'),
Validatorless.compare(
// compare with thePasswordLamaController
model.thePasswordLamaController,
'Password lama tidak sama',
)
],
),
),
const SizedBox(height: 10),
MyTextFormField(
labelText: 'Password Baru',
hintText: 'Masukkan password baru',
obscureText: model.isPasswordBaruObscure,
controller: model.passwordBaruController,
suffixIcon: IconButton(
onPressed: () {
model.isPasswordBaruObscure =
!model.isPasswordBaruObscure;
model.notifyListeners();
},
icon: Icon(
model.isPasswordBaruObscure
? Icons.visibility_off
: Icons.visibility,
),
),
validator: Validatorless.multiple(
[
Validatorless.required(
'Password baru tidak boleh kosong'),
Validatorless.min(
8, 'Password baru minimal 8 karakter'),
],
),
),
const SizedBox(height: 10),
MyTextFormField(
labelText: 'Konfirmasi Password Baru',
hintText: 'Masukkan konfirmasi password baru',
obscureText: model.isKonfirmasiPasswordBaruObscure,
controller: model.konfirmasiPasswordBaruController,
suffixIcon: IconButton(
onPressed: () {
model.isKonfirmasiPasswordBaruObscure =
!model.isKonfirmasiPasswordBaruObscure;
model.notifyListeners();
},
icon: Icon(
model.isKonfirmasiPasswordBaruObscure
? Icons.visibility_off
: Icons.visibility,
),
),
validator: Validatorless.multiple(
[
Validatorless.required(
'Konfirmasi password baru tidak boleh kosong'),
Validatorless.min(
8, 'Konfirmasi password baru minimal 8 karakter'),
Validatorless.compare(
model.passwordBaruController,
'Password baru tidak sama',
),
],
),
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
TextButton(
onPressed: () {
if (model.globalKey.currentState!.validate()) {
// remove keyboard
FocusScope.of(context).unfocus();
model.dialogService
.showConfirmationDialog(
title: 'Konfirmasi',
description:
'Apakah anda yakin ingin mengubah password?',
cancelTitle: 'Batal',
confirmationTitle: 'Ya',
)
.then(
(response) async {
if (response!.confirmed) {
// completer!(DialogResponse(confirmed: true));
// model.log.i('Password berhasil diubah');
bool res = await model.gantiPassword();
// model.log.i('res: $res');
if (res) {
completer!(DialogResponse(confirmed: true));
model.log.i('Password berhasil diubah');
}
} else {
model.log.i('Password gagal diubah');
}
},
);
}
},
child: const Text('Simpan'),
),
TextButton(
onPressed: () =>
completer!(DialogResponse(confirmed: false)),
child: const Text(
'Batal',
style: TextStyle(color: dangerColor),
),
),
],
),
],
),
),
),
);
},
);
}
}

View File

@ -0,0 +1,48 @@
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import '../../../../../app/app.logger.dart';
import '../../../../../app/core/custom_base_view_model.dart';
class GantiPasswordDialogViewModel extends CustomBaseViewModel {
final log = getLogger('GantiPasswordDialogViewModel');
// form variable
final globalKey = GlobalKey<FormState>();
TextEditingController passwordLamaController = TextEditingController();
TextEditingController passwordBaruController = TextEditingController();
TextEditingController konfirmasiPasswordBaruController =
TextEditingController();
TextEditingController thePasswordLamaController = TextEditingController();
bool isPasswordLamaObscure = true;
bool isPasswordBaruObscure = true;
bool isKonfirmasiPasswordBaruObscure = true;
Future<void> init() async {
globalVar.backPressed = 'normalBack';
String? passwordLama = await mySharedPrefs.getString('password');
thePasswordLamaController.text = passwordLama!;
}
Future<bool> gantiPassword() async {
setBusy(true);
try {
String? idCaleg = await mySharedPrefs.getString('id');
var formData = FormData.fromMap({
'id_caleg': idCaleg,
'password_lama': passwordLamaController.text,
'password_baru': passwordBaruController.text,
});
await httpService.postWithFormData('login/ganti_pass_caleg', formData);
return true;
} catch (e) {
log.e(e.toString());
return false;
} finally {
setBusy(false);
}
}
}

View File

@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import '../pengaturan_caleg_view.dart';
import './pengaturan_caleg2_view_model.dart';
class PengaturanCaleg2View extends StatelessWidget {
const PengaturanCaleg2View({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<PengaturanCaleg2ViewModel>.nonReactive(
viewModelBuilder: () => PengaturanCaleg2ViewModel(),
onViewModelReady: (PengaturanCaleg2ViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
PengaturanCaleg2ViewModel model,
Widget? child,
) {
return const PengaturanCalegView();
},
);
}
}

View File

@ -0,0 +1,5 @@
import '../../../../../app/core/custom_base_view_model.dart';
class PengaturanCaleg2ViewModel extends CustomBaseViewModel {
Future<void> init() async {}
}

View File

@ -0,0 +1,206 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import '../../../../app/themes/app_colors.dart';
import '../../../../app/themes/app_text.dart';
import '../../../widgets/top_container.dart';
import './pengaturan_caleg_view_model.dart';
class PengaturanCalegView extends StatelessWidget {
const PengaturanCalegView({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<PengaturanCalegViewModel>.reactive(
viewModelBuilder: () => PengaturanCalegViewModel(),
onViewModelReady: (PengaturanCalegViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
PengaturanCalegViewModel model,
Widget? child,
) {
return Scaffold(
body: WillPopScope(
onWillPop: () async {
// model.log.i('backPressed: ${model.globalVar.backPressed}');
if (model.globalVar.backPressed == 'exitApp') {
// model.back();
model.quitApp(context);
}
return false;
},
child: SafeArea(
child: Padding(
padding: const EdgeInsets.all(20),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TopContainer(
title: 'Jumlah Suara',
value: '${model.suaraCounter} Suara',
icon: Icons.people_alt_outlined,
background: warningColor,
),
const SizedBox(height: 10),
TopContainer(
title: 'Area\nTPS',
value: '${model.suaraCounter} TPS',
icon: Icons.location_on_outlined,
background: orangeColor,
),
const SizedBox(height: 10),
TopContainer(
title: 'Jumlah Tim Survei',
value: '${model.timSurverCounter} Orang',
icon: Icons.co_present_outlined,
background: greenColor,
),
const SizedBox(
height: 20,
),
if (model.isBusy)
const Center(child: CircularProgressIndicator()),
if (!model.isBusy && model.status == true)
RichText(
text: TextSpan(
text: 'Selamat Datang, ',
style: regularTextStyle,
children: [
TextSpan(
text: 'Caleg ${model.nama}\n\n',
style: boldTextStyle,
),
const TextSpan(
text: 'Sila tekan menu',
style: regularTextStyle,
),
TextSpan(
text: ' Hasil Suara ',
style: boldTextStyle.copyWith(
color: greenColor,
fontStyle: FontStyle.italic,
),
),
const TextSpan(
text:
'untuk mengetahui jumlah suara.\n\nDan sila tekan menu',
style: regularTextStyle,
),
TextSpan(
text: ' Tim Survei ',
style: boldTextStyle.copyWith(
color: greenColor,
fontStyle: FontStyle.italic,
),
),
const TextSpan(
text:
'untuk mengetahui jumlah tim survei anda.\n\n',
style: regularTextStyle,
),
const TextSpan(
text: 'Dan sila tekan menu',
style: regularTextStyle,
),
TextSpan(
text: ' Area TPS ',
style: boldTextStyle.copyWith(
color: greenColor,
fontStyle: FontStyle.italic,
),
),
const TextSpan(
text: 'untuk mengetahui Area TPS anda.\n\n',
style: regularTextStyle,
),
const TextSpan(
text:
'Jika terjadi kesalahan pada data, silahkan hubungi admin.\n\n',
style: regularTextStyle,
),
const TextSpan(
text: 'Aplikasi dibuat oleh :',
style: italicTextStyle,
),
TextSpan(
text: ' Kicap Karan\n',
style: boldTextStyle.copyWith(
color: mainColor,
),
),
TextSpan(
text: 'http://www.kicap-karan.com\n',
style: boldTextStyle.copyWith(
color: mainColor,
),
),
],
),
),
if (!model.isBusy && model.status == false)
RichText(
text: TextSpan(
text: 'Selamat Datang, ',
style: regularTextStyle,
children: [
TextSpan(
text: '${model.nama}\n',
style: boldTextStyle,
),
const TextSpan(
text: 'Terjadi ',
style: regularTextStyle,
),
TextSpan(
text: 'Error ',
style: boldTextStyle.copyWith(
color: redColor,
fontStyle: FontStyle.italic,
),
),
const TextSpan(
text: 'pada saat mengambil data\n',
style: regularTextStyle,
),
const TextSpan(
text: 'Silahkan coba lagi dengan menekan icon',
style: regularTextStyle,
),
TextSpan(
text: ' Pengaturan\n',
style: boldTextStyle.copyWith(
color: greenColor,
fontStyle: FontStyle.italic,
),
),
const TextSpan(
text: 'di pojok kanan bawah\n',
style: regularTextStyle,
),
],
),
),
],
),
),
),
),
),
// with setting icon
floatingActionButton: FloatingActionButton(
backgroundColor: warningColor,
onPressed: () {
model.gantiPassword();
},
child: const Icon(Icons.settings, color: fontColor),
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
);
},
);
}
}

View File

@ -0,0 +1,52 @@
import '../../../../app/app.dialogs.dart';
import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart';
import '../../../../model/my_response.model.dart';
class PengaturanCalegViewModel extends CustomBaseViewModel {
final log = getLogger('PengaturanCalegViewModel');
int timSurverCounter = 0;
int suaraCounter = 0;
int areaCounter = 0;
bool status = false;
String? nama;
Future<void> init() async {
globalVar.backPressed = 'exitApp';
String? idCaleg = await mySharedPrefs.getString('id');
nama = await mySharedPrefs.getString('nama');
await getData(idCaleg!);
}
getData(String idCaleg) async {
setBusy(true);
try {
var response = await httpService.get('caleg/detail/$idCaleg');
MyResponseModel myResponseModel = MyResponseModel.fromJson(response.data);
timSurverCounter = myResponseModel.data['jumlah_tim_survei'];
suaraCounter = myResponseModel.data['jumlah_suara'];
areaCounter = myResponseModel.data['jumlah_area'];
status = true;
} catch (e) {
log.e(e.toString());
status = false;
} finally {
setBusy(false);
}
}
gantiPassword() async {
var res = await dialogService.showCustomDialog(
variant: DialogType.gantiPasswordDialogView,
title: 'Ganti Password',
mainButtonTitle: 'Simpan',
barrierDismissible: false,
);
if (res!.confirmed) {
snackbarService.showSnackbar(message: 'Password berhasil diubah');
}
}
}