first commit

This commit is contained in:
kicap
2023-08-18 01:07:57 +08:00
commit 3b437c4f82
320 changed files with 10503 additions and 0 deletions

View File

@ -0,0 +1,233 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import '../../../../app/themes/app_colors.dart';
import '../../../../app/themes/app_text.dart';
import './custom_currency_view_model.dart';
class CustomCurrencyView extends StatelessWidget {
const CustomCurrencyView({super.key});
@override
Widget build(BuildContext context) {
return ViewModelBuilder<CustomCurrencyViewModel>.reactive(
viewModelBuilder: () => CustomCurrencyViewModel(),
onViewModelReady: (CustomCurrencyViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
CustomCurrencyViewModel model,
Widget? child,
) {
return WillPopScope(
onWillPop: () async {
// model.navigationService.back();
if (model.globalVar.backPressed == 'backNormal') {
model.quitApp(context);
}
return false;
},
child: Scaffold(
body: model.conversionResultModel == null
? const Center(
child: Text(
'Sila Klik Icon Untuk\nKonversi Tukaran Mata Uang',
textAlign: TextAlign.center,
),
)
: const TheDataWidget(),
floatingActionButton: FloatingActionButton(
onPressed: () {
// model.navigationService.back();
model.myDialog();
},
// icon exchange currency
child: const Icon(Icons.swap_horiz),
)),
);
},
);
}
}
class TheDataWidget extends ViewModelWidget<CustomCurrencyViewModel> {
const TheDataWidget({
super.key,
});
@override
Widget build(BuildContext context, CustomCurrencyViewModel viewModel) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
RichText(
text: TextSpan(
text: 'Terakhir diperbarui : ',
style: regularTextStyle,
children: [
TextSpan(
text: viewModel.otherFunction.timeStampConverter(
viewModel.conversionResultModel!.timeLastUpdateUnix!),
style: boldTextStyle.copyWith(
color: greenColor,
),
),
],
),
),
const SizedBox(
height: 10,
),
RichText(
text: TextSpan(
text: 'Update berikutnya : ',
style: regularTextStyle,
children: [
TextSpan(
text: viewModel.otherFunction.timeStampConverter(
viewModel.conversionResultModel!.timeNextUpdateUnix!),
style: boldTextStyle.copyWith(
color: mainColor,
),
),
],
),
),
const SizedBox(
height: 10,
),
Row(
children: [
const Text('Mata Uang : ', style: regularTextStyle),
const SizedBox(
width: 3,
),
Image.asset(
'assets/flags/${viewModel.currencyInfoModel!.alphabeticCode!.toLowerCase()}.png',
width: 30,
height: 30,
),
const SizedBox(
width: 5,
),
Text(
viewModel.currencyInfoModel!.entity!,
style: boldTextStyle.copyWith(
color: redColor,
),
),
const SizedBox(
width: 3,
),
Text(
'( ${viewModel.currencyInfoModel!.alphabeticCode} )',
style: italicTextStyle.copyWith(
color: redColor,
),
),
],
),
const SizedBox(
height: 10,
),
RichText(
text: TextSpan(
text: 'Jumlah Tukaran : ',
style: regularTextStyle,
children: [
TextSpan(
text:
'${viewModel.currencyInfoModel!.alphabeticCode} ${viewModel.otherFunction.commaFormat(int.parse(viewModel.nilaiTukaran!))}',
style: boldTextStyle.copyWith(
color: redColor,
),
),
],
),
),
const SizedBox(
height: 10,
),
RichText(
text: TextSpan(
text: 'Konversi Tukaran : ',
style: regularTextStyle,
children: [
TextSpan(
text: '1 ${viewModel.currencyInfoModel!.alphabeticCode}',
style: boldTextStyle.copyWith(
color: redColor,
),
),
const TextSpan(
text: ' = ',
style: regularTextStyle,
),
TextSpan(
text:
'${viewModel.conversionResultModel!.conversionRate} ${viewModel.konversiInfoModel!.alphabeticCode}',
style: boldTextStyle.copyWith(
color: orangeColor,
),
),
],
),
),
const SizedBox(
height: 10,
),
Row(
children: [
const Text('Uang Konversi: ', style: regularTextStyle),
const SizedBox(
width: 3,
),
Image.asset(
'assets/flags/${viewModel.konversiInfoModel!.alphabeticCode!.toLowerCase()}.png',
width: 30,
height: 30,
),
const SizedBox(
width: 5,
),
Text(
viewModel.konversiInfoModel!.entity!,
style: boldTextStyle.copyWith(
color: orangeColor,
),
),
const SizedBox(
width: 3,
),
Text(
'( ${viewModel.konversiInfoModel!.alphabeticCode} )',
style: italicTextStyle.copyWith(
color: orangeColor,
),
),
],
),
const SizedBox(
height: 10,
),
RichText(
text: TextSpan(
text: 'Nilai Konversi : ',
style: regularTextStyle,
children: [
TextSpan(
text:
'${viewModel.konversiInfoModel!.alphabeticCode} ${viewModel.conversionResultModel!.conversionResult}',
style: boldTextStyle.copyWith(
color: orangeColor,
),
),
],
),
),
],
);
}
}

View File

@ -0,0 +1,61 @@
import '../../../../app/app.dialogs.dart';
import '../../../../app/app.logger.dart';
import '../../../../app/core/custom_base_view_model.dart';
import '../../../../models/all_info_model.dart';
import '../../../../models/conversion_result_model.dart';
class CustomCurrencyViewModel extends CustomBaseViewModel {
final log = getLogger('CustomCurrencyViewModel');
ConversionResultModel? conversionResultModel;
AllInfoModel? currencyInfoModel;
AllInfoModel? konversiInfoModel;
String? nilaiTukaran;
Future<void> init() async {}
myDialog() async {
final res = await dialogService.showCustomDialog(
variant: DialogType.konversiDialogView,
);
if (res!.confirmed) {
setBusy(true);
globalVar.backPressed = 'cantBack';
easyLoading.customLoading('Loading Konversi Tukaran ...');
log.i(res.data);
String currencyCountry = res.data['currencyCountry'];
String nilaiTukaran = res.data['nilaiTukaran'];
String konversiCountry = res.data['konversiCountry'];
this.nilaiTukaran = nilaiTukaran;
String api = '/pair/$currencyCountry/$konversiCountry/$nilaiTukaran';
try {
var response = await httpService.get(api);
log.i(response.data);
for (var item in globalVar.allInfoModel) {
if (item.alphabeticCode == currencyCountry) {
currencyInfoModel = item;
}
if (item.alphabeticCode == konversiCountry) {
konversiInfoModel = item;
}
}
log.i(currencyInfoModel!.entity);
log.i(konversiInfoModel!.entity);
conversionResultModel = ConversionResultModel.fromJson(response.data);
} catch (e) {
snackbarService.showSnackbar(message: e.toString());
log.e(e);
} finally {
setBusy(false);
globalVar.backPressed = 'backNormal';
easyLoading.dismissLoading();
notifyListeners();
}
}
}
}

View File

@ -0,0 +1,101 @@
import 'package:curreny_exchange/app/themes/app_colors.dart';
import 'package:curreny_exchange/ui/widgets/my_textformfield.dart';
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import './konversi_dialog_view_model.dart';
class KonversiDialogView extends StatelessWidget {
// final bool isKonversi;
final DialogRequest? request;
final Function(DialogResponse)? completer;
const KonversiDialogView({
Key? key,
// this.isKonversi = false,
this.request,
this.completer,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ViewModelBuilder<KonversiDialogViewModel>.reactive(
viewModelBuilder: () => KonversiDialogViewModel(),
onViewModelReady: (KonversiDialogViewModel model) async {
await model.init();
},
builder: (
BuildContext context,
KonversiDialogViewModel model,
Widget? child,
) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: model.currencyWidget == null
? const Text('- Pilih Mata Uang -')
: model.currencyWidget!,
),
IconButton(
onPressed: () {
model.pilihNegara(true);
},
icon: const Icon(Icons.edit, color: mainColor),
),
],
),
const SizedBox(height: 10),
MyTextFormField(
hintText: model.hintText ?? 'Pilih Mata Uang Konversi',
keyboardType: TextInputType.number,
controller: model.nilaiTukaranController,
focusNode: model.nilaiTukaranFocusNode,
),
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: model.konversiWidget == null
? const Text('- Pilih Mata Uang -')
: model.konversiWidget!),
IconButton(
onPressed: () {
model.pilihNegara(false);
},
icon: const Icon(Icons.edit, color: mainColor),
),
],
),
const SizedBox(height: 10),
Center(
child: ElevatedButton(
onPressed: () {
model.konversi(completer);
},
child: const Text('Konversi'),
),
),
],
),
),
);
},
);
}
}

View File

@ -0,0 +1,153 @@
import 'package:flutter/material.dart';
import 'package:stacked_services/stacked_services.dart';
import '../../../../../app/app.bottomsheets.dart';
import '../../../../../app/app.logger.dart';
import '../../../../../app/core/custom_base_view_model.dart';
import '../../../../../app/themes/app_colors.dart';
import '../../../../../app/themes/app_text.dart';
import '../../../../../models/all_info_model.dart';
class KonversiDialogViewModel extends CustomBaseViewModel {
final log = getLogger('KonversiDialogViewModel');
String? currencyCountry;
Widget? currencyWidget;
String? hintText;
String? konversiCountry;
Widget? konversiWidget;
TextEditingController nilaiTukaranController = TextEditingController();
FocusNode nilaiTukaranFocusNode = FocusNode();
Future<void> init() async {}
pilihNegara(bool bool) async {
// FocusScope.of(StackedService.navigatorKey!.currentContext!).unfocus();
final res = await bottomSheetService.showCustomSheet(
variant: BottomSheetType.pilihNegaraBottomSheetView,
data: {
'bool': bool,
'currencyCountry': bool == true ? currencyCountry : konversiCountry,
},
);
if (res!.confirmed == true) {
log.i('${res.data} ini res.data');
// if (res.data !=
AllInfoModel? allInfoModel = res.data;
if (bool == true) {
currencyCountry = allInfoModel!.alphabeticCode;
log.i(allInfoModel.entity);
hintText = 'Tukaran ${allInfoModel.alphabeticCode}';
currencyWidget = Row(
children: [
Image.asset(
'assets/flags/${allInfoModel.alphabeticCode!.toLowerCase()}.png',
width: 30,
),
const SizedBox(width: 15),
RichText(
text: TextSpan(
text: allInfoModel.entity,
style: regularTextStyle.copyWith(
color: greenColor,
),
children: [
TextSpan(
text: ' (${allInfoModel.alphabeticCode})',
style: italicTextStyle.copyWith(
color: greenColor,
),
),
],
)),
],
);
} else {
// log.i(allInfoModel!.entity);
konversiCountry = (res.data == 'all'
? 'Semua Mata Uang'
: allInfoModel!.alphabeticCode)!;
// hintText = 'Tukaran ${allInfoModel.alphabeticCode}';
konversiWidget = Row(
children: [
res.data == 'all'
? const Icon(
Icons.all_inclusive,
color: redColor,
)
: Image.asset(
'assets/flags/${allInfoModel!.alphabeticCode!.toLowerCase()}.png',
width: 30,
),
const SizedBox(width: 15),
RichText(
text: TextSpan(
text:
res.data == 'all' ? 'Semua Mata Uang' : allInfoModel!.entity,
style: regularTextStyle.copyWith(
color: redColor,
),
children: [
TextSpan(
text: res.data == 'all'
? '*'
: ' (${allInfoModel!.alphabeticCode})',
style: italicTextStyle.copyWith(
color: redColor,
),
),
],
)),
],
);
}
}
notifyListeners();
}
konversi(Function(DialogResponse p1)? completer) async {
if (currencyCountry == null) {
snackbarService.showSnackbar(
message: 'Pilih Mata Uang',
title: 'Pilih Negara',
);
pilihNegara(true);
return;
}
if (nilaiTukaranController.text == '') {
snackbarService.showSnackbar(
message: 'Masukkan Nilai Tukaran',
title: 'Nilai Tukaran',
);
// focus on textfield
FocusScope.of(StackedService.navigatorKey!.currentContext!)
.requestFocus(nilaiTukaranFocusNode);
return;
}
if (konversiCountry == null) {
snackbarService.showSnackbar(
message: 'Pilih Mata Uang Koversi',
title: 'Pilih Negara',
);
pilihNegara(false);
return;
}
// remove keyboard
FocusScope.of(StackedService.navigatorKey!.currentContext!).unfocus();
completer!(
DialogResponse(confirmed: true, data: {
'currencyCountry': currencyCountry,
'nilaiTukaran': nilaiTukaranController.text,
'konversiCountry': konversiCountry,
}),
);
}
}

View File

@ -0,0 +1,121 @@
import 'package:curreny_exchange/app/themes/app_colors.dart';
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
import '../../../../../../app/themes/app_text.dart';
import './pilih_negara_bottom_sheet_view_model.dart';
// class PilihNegaraData {
// final bool? isKonversi;
// final String? alphabeticCode;
// PilihNegaraData({
// this.isKonversi,
// this.alphabeticCode,
// });
// }
class PilihNegaraBottomSheetView extends StatelessWidget {
final SheetRequest? request;
final Function(SheetResponse)? completer;
const PilihNegaraBottomSheetView({
Key? key,
this.request,
this.completer,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ViewModelBuilder<PilihNegaraBottomSheetViewModel>.reactive(
viewModelBuilder: () => PilihNegaraBottomSheetViewModel(),
onViewModelReady: (PilihNegaraBottomSheetViewModel model) async {
await model.init(request!.data);
},
builder: (
BuildContext context,
PilihNegaraBottomSheetViewModel model,
Widget? child,
) {
return Container(
padding: const EdgeInsets.all(15),
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
topRight: Radius.circular(15),
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Pilih Negara',
style: italicTextStyle.copyWith(
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
Expanded(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
for (var item in model.globalVar.allInfoModel)
Card(
// creata a checkbox at the e
color: request!.data['currencyCountry'] ==
item.alphabeticCode
? mainColor
: Colors.white,
child: ListTile(
onTap: () {
// if (isKonversi) {
completer!(
SheetResponse(confirmed: true, data: item));
// }
},
leading: Image.asset(
'assets/flags/${item.alphabeticCode!.toLowerCase()}.png',
width: 30,
errorBuilder: (context, error, stackTrace) {
return const Icon(Icons.error);
},
),
title: Text(
item.entity!,
style: italicTextStyle.copyWith(
fontSize: 15,
fontWeight: FontWeight.bold,
color: request!.data['currencyCountry'] ==
item.alphabeticCode
? Colors.white
: Colors.black,
),
),
subtitle: Text(
item.currency!,
style: italicTextStyle.copyWith(
fontSize: 15,
// fontWeight: FontWeight.bold,
color: request!.data['currencyCountry'] ==
item.alphabeticCode
? Colors.white
: Colors.black,
),
),
),
)
],
),
),
),
],
),
);
},
);
}
}

View File

@ -0,0 +1,10 @@
import '../../../../../../app/app.logger.dart';
import '../../../../../../app/core/custom_base_view_model.dart';
class PilihNegaraBottomSheetViewModel extends CustomBaseViewModel {
final log = getLogger('PilihNegaraBottomSheetViewModel');
Future<void> init(data) async {
// log.i(globalVar.allInfoModel);
log.i(data['bool']);
}
}