diff --git a/app_petty_cash/lib/app/constant.dart b/app_petty_cash/lib/app/constant.dart index 4dd813f..dd5a6f1 100644 --- a/app_petty_cash/lib/app/constant.dart +++ b/app_petty_cash/lib/app/constant.dart @@ -15,11 +15,11 @@ class Constant { // static String baseUrl = "https://devregonline.pramita.co.id/one-api/xdoc/"; // tester devbandungraya - static String baseUrl = - "http://devbandungraya.aplikasi.web.id/one-api-doctor/doctor_mitra/"; + static String baseUrlDevone = + "http://devone.aplikasi.web.id/one-api-pettycash/pettycash/"; - static String baseUrl_appdoctor = - "http://devbandungraya.aplikasi.web.id/one-api/app_doctor/"; + // static String baseUrl_appdoctor = + // "http://devbandungraya.aplikasi.web.id/one-api/app_doctor/"; // * surabaya // static String baseUrl = diff --git a/app_petty_cash/lib/model/list_category_model.dart b/app_petty_cash/lib/model/list_category_model.dart new file mode 100644 index 0000000..b0e8bc3 --- /dev/null +++ b/app_petty_cash/lib/model/list_category_model.dart @@ -0,0 +1,18 @@ +class ListCategory { + String? categoryid; + String? categoryname; + + ListCategory({this.categoryid, this.categoryname}); + + ListCategory.fromJson(Map json) { + categoryid = json['categoryid']; + categoryname = json['categoryname']; + } + + Map toJson() { + final Map data = new Map(); + data['categoryid'] = this.categoryid; + data['categoryname'] = this.categoryname; + return data; + } +} \ No newline at end of file diff --git a/app_petty_cash/lib/model/list_type_model.dart b/app_petty_cash/lib/model/list_type_model.dart new file mode 100644 index 0000000..6f3bbbf --- /dev/null +++ b/app_petty_cash/lib/model/list_type_model.dart @@ -0,0 +1,18 @@ +class ListType { + String? typeid; + String? typename; + + ListType({this.typeid, this.typename}); + + ListType.fromJson(Map json) { + typeid = json['typeid']; + typename = json['typename']; + } + + Map toJson() { + final Map data = new Map(); + data['typeid'] = this.typeid; + data['typename'] = this.typename; + return data; + } +} \ No newline at end of file diff --git a/app_petty_cash/lib/repository/auth_repository.dart b/app_petty_cash/lib/repository/auth_repository.dart index 4154225..9974c96 100644 --- a/app_petty_cash/lib/repository/auth_repository.dart +++ b/app_petty_cash/lib/repository/auth_repository.dart @@ -19,8 +19,8 @@ class AuthRepository extends BaseRepository { // "doctor_id": "2891", // "password": "3" }; - // final service = "${Constant.baseUrl}xauth/login"; - final service = "${Constant.baseUrl}auth/login"; + // final service = "${Constant.baseUrlDevone}xauth/login"; + final service = "${Constant.baseUrlDevone}auth/login"; final resp = await post(param: param, service: service); final result = AuthModel( token: resp["data"]["token"], @@ -41,7 +41,7 @@ class AuthRepository extends BaseRepository { // "password": "riau123" }; - final service = "${Constant.baseUrl}auth/logout"; + final service = "${Constant.baseUrlDevone}auth/logout"; final resp = await post(param: param, service: service); if (resp["status"] == "OK") { @@ -72,7 +72,7 @@ class AuthRepository extends BaseRepository { // "password": "riau123" }; - final service = "${Constant.baseUrl}auth/change_password"; + final service = "${Constant.baseUrlDevone}auth/change_password"; final resp = await post(param: param, service: service); // final result = AuthModel( diff --git a/app_petty_cash/lib/repository/transaksi_repository.dart b/app_petty_cash/lib/repository/transaksi_repository.dart new file mode 100644 index 0000000..b5c2723 --- /dev/null +++ b/app_petty_cash/lib/repository/transaksi_repository.dart @@ -0,0 +1,49 @@ +import 'package:app_petty_cash/model/list_type_model.dart'; + +import '../app/constant.dart'; +import '../model/list_category_model.dart'; +import 'base_repository.dart'; + +class TransaksiRepository extends BaseRepository { + TransaksiRepository({required super.dio}); + + // list type + Future> getListType() async { + final service = "${Constant.baseUrlDevone}transaction/list_type/"; + final resp = await post( + param: { + "": "", + }, + service: service, + ); + + print("url list type : $service"); + + final result = List.empty(growable: true); + resp['data'].forEach((e) { + final model = ListType.fromJson(e); + result.add(model); + }); + return result; + } + + // list category + Future> getListCategory() async { + final service = "${Constant.baseUrlDevone}transaction/list_category/"; + final resp = await post( + param: { + "": "", + }, + service: service, + ); + + print("url list category : $service"); + + final result = List.empty(growable: true); + resp['data'].forEach((e) { + final model = ListCategory.fromJson(e); + result.add(model); + }); + return result; + } +} diff --git a/app_petty_cash/lib/screen/transaksi/list_category_provider.dart b/app_petty_cash/lib/screen/transaksi/list_category_provider.dart new file mode 100644 index 0000000..ff0f572 --- /dev/null +++ b/app_petty_cash/lib/screen/transaksi/list_category_provider.dart @@ -0,0 +1,64 @@ +import '../../model/list_category_model.dart'; +import '../../repository/transaksi_repository.dart'; +import 'package:equatable/equatable.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import '../../provider/dio_provider.dart'; +import '../../repository/base_repository.dart'; + +abstract class ListCategoryState extends Equatable { + final DateTime date; + const ListCategoryState(this.date); + @override + List get props => [date]; +} + +class ListCategoryStateInit extends ListCategoryState { + ListCategoryStateInit() : super(DateTime.now()); +} + +class ListCategoryStateLoading extends ListCategoryState { + ListCategoryStateLoading() : super(DateTime.now()); +} + +class ListCategoryStateError extends ListCategoryState { + final String message; + ListCategoryStateError({ + required this.message, + }) : super(DateTime.now()); +} + +class ListCategoryStateDone extends ListCategoryState { + final List model; + ListCategoryStateDone({ + required this.model, + }) : super(DateTime.now()); +} + +//notifier +class ListCategoryNotifier extends StateNotifier { + final Ref ref; + ListCategoryNotifier({ + required this.ref, + }) : super(ListCategoryStateInit()); + + void getListCategory() async { + try { + state = ListCategoryStateLoading(); + final dio = ref.read(dioProvider); + final resp = await TransaksiRepository(dio: dio).getListCategory(); + state = ListCategoryStateDone(model: resp); + } catch (e) { + if (e is BaseRepositoryException) { + state = ListCategoryStateError(message: e.message.toString()); + } else { + state = ListCategoryStateError(message: e.toString()); + } + } + } +} + +//provider +final listCategoryProvider = StateNotifierProvider( + (ref) => ListCategoryNotifier(ref: ref), +); diff --git a/app_petty_cash/lib/screen/transaksi/list_type_provider.dart b/app_petty_cash/lib/screen/transaksi/list_type_provider.dart new file mode 100644 index 0000000..f2288b6 --- /dev/null +++ b/app_petty_cash/lib/screen/transaksi/list_type_provider.dart @@ -0,0 +1,64 @@ +import 'package:app_petty_cash/repository/transaksi_repository.dart'; +import 'package:equatable/equatable.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import '../../model/list_type_model.dart'; +import '../../provider/dio_provider.dart'; +import '../../repository/base_repository.dart'; + +abstract class ListTypeState extends Equatable { + final DateTime date; + const ListTypeState(this.date); + @override + List get props => [date]; +} + +class ListTypeStateInit extends ListTypeState { + ListTypeStateInit() : super(DateTime.now()); +} + +class ListTypeStateLoading extends ListTypeState { + ListTypeStateLoading() : super(DateTime.now()); +} + +class ListTypeStateError extends ListTypeState { + final String message; + ListTypeStateError({ + required this.message, + }) : super(DateTime.now()); +} + +class ListTypeStateDone extends ListTypeState { + final List model; + ListTypeStateDone({ + required this.model, + }) : super(DateTime.now()); +} + +//notifier +class ListTypeNotifier extends StateNotifier { + final Ref ref; + ListTypeNotifier({ + required this.ref, + }) : super(ListTypeStateInit()); + + void getListType() async { + try { + state = ListTypeStateLoading(); + final dio = ref.read(dioProvider); + final resp = await TransaksiRepository(dio: dio).getListType(); + state = ListTypeStateDone(model: resp); + } catch (e) { + if (e is BaseRepositoryException) { + state = ListTypeStateError(message: e.message.toString()); + } else { + state = ListTypeStateError(message: e.toString()); + } + } + } +} + +//provider +final listTypeProvider = StateNotifierProvider( + (ref) => ListTypeNotifier(ref: ref), +); diff --git a/app_petty_cash/lib/screen/transaksi/transaksi_screen.dart b/app_petty_cash/lib/screen/transaksi/transaksi_screen.dart index bcb61a3..978c005 100644 --- a/app_petty_cash/lib/screen/transaksi/transaksi_screen.dart +++ b/app_petty_cash/lib/screen/transaksi/transaksi_screen.dart @@ -1,4 +1,7 @@ import 'package:app_petty_cash/app/app_extension.dart'; +import 'package:app_petty_cash/model/list_type_model.dart'; +import 'package:app_petty_cash/screen/transaksi/list_category_provider.dart'; +import 'package:app_petty_cash/screen/transaksi/list_type_provider.dart'; import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -7,7 +10,9 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:intl/intl.dart'; import '../../app/constant.dart'; +import '../../model/list_category_model.dart'; import '../../widget/custom_drawer.dart'; +import '../../widget/sankbar_widget.dart'; import '../login/custom_text_field.dart'; class DummyDropdownTipe { @@ -47,51 +52,75 @@ class TransaksiScreen extends HookConsumerWidget { final tglAwal = useState(DateTime.now()); final tglAwalTmp = useState(""); - final selectedDropdownKategori = useState( - DummyDropdownTipe( - "", - 0, - ), - ); - final dropdownItemsKategori = useState>( + final listTypeData = useState>(List.empty(growable: true)); + final selectedListTypeData = useState(ListType()); + + final listTypeLoading = useState(false); + + // category + final listCategoryLoading = useState(false); + final selectedListCategory = useState(ListCategory()); + final listCategoryData = useState>( List.empty( growable: true, ), ); - final radioButtonItems = - useState>(List.empty(growable: true)); - final selectedRadio = useState(DummyRadioTipe("", 0)); + // A. LISTEN PROVIDER + ref.listen( + listTypeProvider, + (previous, next) { + if (next is ListTypeStateLoading) { + listTypeLoading.value = true; + } else if (next is ListTypeStateError) { + print(next.message); + listTypeLoading.value = false; + SanckbarWidget(context, next.message, snackbarType.error); + } else if (next is ListTypeStateDone) { + // print(jsonEncode(next.model)); + // print(next.model.length); + listTypeData.value = next.model; + listTypeLoading.value = false; + selectedListTypeData.value = listTypeData.value[0]; + } + }, + ); + + ref.listen( + listCategoryProvider, + (previous, next) { + if (next is ListCategoryStateLoading) { + listCategoryLoading.value = true; + } else if (next is ListCategoryStateError) { + print(next.message); + listCategoryLoading.value = false; + SanckbarWidget(context, next.message, snackbarType.error); + } else if (next is ListCategoryStateDone) { + // print(jsonEncode(next.model)); + // print(next.model.length); + listCategoryData.value = next.model; + listCategoryLoading.value = false; + selectedListCategory.value = listCategoryData.value[0]; + } + }, + ); useEffect(() { - dropdownItemsKategori.value = [ - DummyDropdownTipe("Pengantaran Hasil", 1), - DummyDropdownTipe("Pengambilan Bahan", 2), - DummyDropdownTipe("Lain-lain", 3), - ]; + WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { + // list Type Provider + ref.read(listTypeProvider.notifier).getListType(); - // selectedDropdownKategori.value = dropdownItemsKategori.value[input]; - selectedDropdownKategori.value = dropdownItemsKategori.value[0]; - radioButtonItems.value = [ - DummyRadioTipe( - "Income", - 1, - ), - DummyRadioTipe( - "Expenses", - 2, - ), - ]; - - selectedRadio.value = radioButtonItems.value[0]; + // list category provider + ref.read(listCategoryProvider.notifier).getListCategory(); + }); return () {}; }, []); final isMounted = useIsMounted(); - var sbHeight = MediaQuery.of(context).padding.top; + // var sbHeight = MediaQuery.of(context).padding.top; - print('Height : ${sbHeight}'); + // print('Height : ${sbHeight}'); return Padding( padding: EdgeInsets.only( @@ -218,7 +247,7 @@ class TransaksiScreen extends HookConsumerWidget { SizedBox( width: Constant.getActualXPhone(context: context, x: 390), child: DropdownButtonHideUnderline( - child: DropdownButton2( + child: DropdownButton2( isExpanded: true, hint: Row( children: [ @@ -234,23 +263,23 @@ class TransaksiScreen extends HookConsumerWidget { ), ], ), - items: dropdownItemsKategori.value - .map((DummyDropdownTipe option) { - return DropdownMenuItem( + items: listCategoryData.value + .map((ListCategory option) { + return DropdownMenuItem( value: option, child: Text( - option.options, + option.categoryname ?? "", style: Constant.body1(context: context).copyWith( color: Constant.textBlack, fontWeight: FontWeight.w600), ), ); }).toList(), - value: selectedDropdownKategori.value, - onChanged: (DummyDropdownTipe? newValue) { + value: selectedListCategory.value, + onChanged: (ListCategory? newValue) { // if (newValue) { - selectedDropdownKategori.value = newValue!; - print(selectedDropdownKategori.value.id); + selectedListCategory.value = newValue!; + print(selectedListCategory.value.categoryid); // } }, buttonStyleData: ButtonStyleData( @@ -386,30 +415,28 @@ class TransaksiScreen extends HookConsumerWidget { child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ - if (radioButtonItems.value.isEmpty) + if (listTypeData.value.isEmpty) Text('Radio Button Empty') else - for (var i = 0; - i < radioButtonItems.value.length; - i++) + for (var i = 0; i < listTypeData.value.length; i++) Padding( padding: const EdgeInsets.only(right: 20), child: Row( children: [ - Radio( + Radio( activeColor: Constant.confirmed, - value: radioButtonItems.value[i], - groupValue: selectedRadio.value, - onChanged: (DummyRadioTipe? index) { + value: listTypeData.value[i], + groupValue: selectedListTypeData.value, + onChanged: (ListType? index) { if (isMounted()) { - selectedRadio.value = index!; + selectedListTypeData.value = index!; } else { return; } }, ), Text( - radioButtonItems.value[i].text, + listTypeData.value[i].typename ?? "", style: Constant.body1(context: context) .copyWith( color: Constant.textBlack,