step 8 : get list category, list type from api
This commit is contained in:
@@ -15,11 +15,11 @@ class Constant {
|
|||||||
// static String baseUrl = "https://devregonline.pramita.co.id/one-api/xdoc/";
|
// static String baseUrl = "https://devregonline.pramita.co.id/one-api/xdoc/";
|
||||||
|
|
||||||
// tester devbandungraya
|
// tester devbandungraya
|
||||||
static String baseUrl =
|
static String baseUrlDevone =
|
||||||
"http://devbandungraya.aplikasi.web.id/one-api-doctor/doctor_mitra/";
|
"http://devone.aplikasi.web.id/one-api-pettycash/pettycash/";
|
||||||
|
|
||||||
static String baseUrl_appdoctor =
|
// static String baseUrl_appdoctor =
|
||||||
"http://devbandungraya.aplikasi.web.id/one-api/app_doctor/";
|
// "http://devbandungraya.aplikasi.web.id/one-api/app_doctor/";
|
||||||
|
|
||||||
// * surabaya
|
// * surabaya
|
||||||
// static String baseUrl =
|
// static String baseUrl =
|
||||||
|
|||||||
18
app_petty_cash/lib/model/list_category_model.dart
Normal file
18
app_petty_cash/lib/model/list_category_model.dart
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
class ListCategory {
|
||||||
|
String? categoryid;
|
||||||
|
String? categoryname;
|
||||||
|
|
||||||
|
ListCategory({this.categoryid, this.categoryname});
|
||||||
|
|
||||||
|
ListCategory.fromJson(Map<String, dynamic> json) {
|
||||||
|
categoryid = json['categoryid'];
|
||||||
|
categoryname = json['categoryname'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['categoryid'] = this.categoryid;
|
||||||
|
data['categoryname'] = this.categoryname;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
app_petty_cash/lib/model/list_type_model.dart
Normal file
18
app_petty_cash/lib/model/list_type_model.dart
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
class ListType {
|
||||||
|
String? typeid;
|
||||||
|
String? typename;
|
||||||
|
|
||||||
|
ListType({this.typeid, this.typename});
|
||||||
|
|
||||||
|
ListType.fromJson(Map<String, dynamic> json) {
|
||||||
|
typeid = json['typeid'];
|
||||||
|
typename = json['typename'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['typeid'] = this.typeid;
|
||||||
|
data['typename'] = this.typename;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,8 +19,8 @@ class AuthRepository extends BaseRepository {
|
|||||||
// "doctor_id": "2891",
|
// "doctor_id": "2891",
|
||||||
// "password": "3"
|
// "password": "3"
|
||||||
};
|
};
|
||||||
// final service = "${Constant.baseUrl}xauth/login";
|
// final service = "${Constant.baseUrlDevone}xauth/login";
|
||||||
final service = "${Constant.baseUrl}auth/login";
|
final service = "${Constant.baseUrlDevone}auth/login";
|
||||||
final resp = await post(param: param, service: service);
|
final resp = await post(param: param, service: service);
|
||||||
final result = AuthModel(
|
final result = AuthModel(
|
||||||
token: resp["data"]["token"],
|
token: resp["data"]["token"],
|
||||||
@@ -41,7 +41,7 @@ class AuthRepository extends BaseRepository {
|
|||||||
// "password": "riau123"
|
// "password": "riau123"
|
||||||
};
|
};
|
||||||
|
|
||||||
final service = "${Constant.baseUrl}auth/logout";
|
final service = "${Constant.baseUrlDevone}auth/logout";
|
||||||
final resp = await post(param: param, service: service);
|
final resp = await post(param: param, service: service);
|
||||||
|
|
||||||
if (resp["status"] == "OK") {
|
if (resp["status"] == "OK") {
|
||||||
@@ -72,7 +72,7 @@ class AuthRepository extends BaseRepository {
|
|||||||
// "password": "riau123"
|
// "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 resp = await post(param: param, service: service);
|
||||||
|
|
||||||
// final result = AuthModel(
|
// final result = AuthModel(
|
||||||
|
|||||||
49
app_petty_cash/lib/repository/transaksi_repository.dart
Normal file
49
app_petty_cash/lib/repository/transaksi_repository.dart
Normal file
@@ -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<List<ListType>> getListType() async {
|
||||||
|
final service = "${Constant.baseUrlDevone}transaction/list_type/";
|
||||||
|
final resp = await post(
|
||||||
|
param: {
|
||||||
|
"": "",
|
||||||
|
},
|
||||||
|
service: service,
|
||||||
|
);
|
||||||
|
|
||||||
|
print("url list type : $service");
|
||||||
|
|
||||||
|
final result = List<ListType>.empty(growable: true);
|
||||||
|
resp['data'].forEach((e) {
|
||||||
|
final model = ListType.fromJson(e);
|
||||||
|
result.add(model);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// list category
|
||||||
|
Future<List<ListCategory>> getListCategory() async {
|
||||||
|
final service = "${Constant.baseUrlDevone}transaction/list_category/";
|
||||||
|
final resp = await post(
|
||||||
|
param: {
|
||||||
|
"": "",
|
||||||
|
},
|
||||||
|
service: service,
|
||||||
|
);
|
||||||
|
|
||||||
|
print("url list category : $service");
|
||||||
|
|
||||||
|
final result = List<ListCategory>.empty(growable: true);
|
||||||
|
resp['data'].forEach((e) {
|
||||||
|
final model = ListCategory.fromJson(e);
|
||||||
|
result.add(model);
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<Object?> 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<ListCategory> model;
|
||||||
|
ListCategoryStateDone({
|
||||||
|
required this.model,
|
||||||
|
}) : super(DateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
//notifier
|
||||||
|
class ListCategoryNotifier extends StateNotifier<ListCategoryState> {
|
||||||
|
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<ListCategoryNotifier, ListCategoryState>(
|
||||||
|
(ref) => ListCategoryNotifier(ref: ref),
|
||||||
|
);
|
||||||
64
app_petty_cash/lib/screen/transaksi/list_type_provider.dart
Normal file
64
app_petty_cash/lib/screen/transaksi/list_type_provider.dart
Normal file
@@ -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<Object?> 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<ListType> model;
|
||||||
|
ListTypeStateDone({
|
||||||
|
required this.model,
|
||||||
|
}) : super(DateTime.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
//notifier
|
||||||
|
class ListTypeNotifier extends StateNotifier<ListTypeState> {
|
||||||
|
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<ListTypeNotifier, ListTypeState>(
|
||||||
|
(ref) => ListTypeNotifier(ref: ref),
|
||||||
|
);
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
import 'package:app_petty_cash/app/app_extension.dart';
|
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:dropdown_button2/dropdown_button2.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@@ -7,7 +10,9 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
import '../../app/constant.dart';
|
import '../../app/constant.dart';
|
||||||
|
import '../../model/list_category_model.dart';
|
||||||
import '../../widget/custom_drawer.dart';
|
import '../../widget/custom_drawer.dart';
|
||||||
|
import '../../widget/sankbar_widget.dart';
|
||||||
import '../login/custom_text_field.dart';
|
import '../login/custom_text_field.dart';
|
||||||
|
|
||||||
class DummyDropdownTipe {
|
class DummyDropdownTipe {
|
||||||
@@ -47,51 +52,75 @@ class TransaksiScreen extends HookConsumerWidget {
|
|||||||
final tglAwal = useState<DateTime>(DateTime.now());
|
final tglAwal = useState<DateTime>(DateTime.now());
|
||||||
final tglAwalTmp = useState<String>("");
|
final tglAwalTmp = useState<String>("");
|
||||||
|
|
||||||
final selectedDropdownKategori = useState<DummyDropdownTipe>(
|
final listTypeData = useState<List<ListType>>(List.empty(growable: true));
|
||||||
DummyDropdownTipe(
|
final selectedListTypeData = useState<ListType>(ListType());
|
||||||
"",
|
|
||||||
0,
|
final listTypeLoading = useState(false);
|
||||||
),
|
|
||||||
);
|
// category
|
||||||
final dropdownItemsKategori = useState<List<DummyDropdownTipe>>(
|
final listCategoryLoading = useState(false);
|
||||||
|
final selectedListCategory = useState<ListCategory>(ListCategory());
|
||||||
|
final listCategoryData = useState<List<ListCategory>>(
|
||||||
List.empty(
|
List.empty(
|
||||||
growable: true,
|
growable: true,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
final radioButtonItems =
|
// A. LISTEN PROVIDER
|
||||||
useState<List<DummyRadioTipe>>(List.empty(growable: true));
|
ref.listen(
|
||||||
final selectedRadio = useState<DummyRadioTipe>(DummyRadioTipe("", 0));
|
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(() {
|
useEffect(() {
|
||||||
dropdownItemsKategori.value = [
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
|
||||||
DummyDropdownTipe("Pengantaran Hasil", 1),
|
// list Type Provider
|
||||||
DummyDropdownTipe("Pengambilan Bahan", 2),
|
ref.read(listTypeProvider.notifier).getListType();
|
||||||
DummyDropdownTipe("Lain-lain", 3),
|
|
||||||
];
|
|
||||||
|
|
||||||
// selectedDropdownKategori.value = dropdownItemsKategori.value[input];
|
// list category provider
|
||||||
selectedDropdownKategori.value = dropdownItemsKategori.value[0];
|
ref.read(listCategoryProvider.notifier).getListCategory();
|
||||||
radioButtonItems.value = [
|
});
|
||||||
DummyRadioTipe(
|
|
||||||
"Income",
|
|
||||||
1,
|
|
||||||
),
|
|
||||||
DummyRadioTipe(
|
|
||||||
"Expenses",
|
|
||||||
2,
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
selectedRadio.value = radioButtonItems.value[0];
|
|
||||||
return () {};
|
return () {};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
final isMounted = useIsMounted();
|
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(
|
return Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
@@ -218,7 +247,7 @@ class TransaksiScreen extends HookConsumerWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: Constant.getActualXPhone(context: context, x: 390),
|
width: Constant.getActualXPhone(context: context, x: 390),
|
||||||
child: DropdownButtonHideUnderline(
|
child: DropdownButtonHideUnderline(
|
||||||
child: DropdownButton2<DummyDropdownTipe>(
|
child: DropdownButton2<ListCategory>(
|
||||||
isExpanded: true,
|
isExpanded: true,
|
||||||
hint: Row(
|
hint: Row(
|
||||||
children: [
|
children: [
|
||||||
@@ -234,23 +263,23 @@ class TransaksiScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
items: dropdownItemsKategori.value
|
items: listCategoryData.value
|
||||||
.map((DummyDropdownTipe option) {
|
.map((ListCategory option) {
|
||||||
return DropdownMenuItem<DummyDropdownTipe>(
|
return DropdownMenuItem<ListCategory>(
|
||||||
value: option,
|
value: option,
|
||||||
child: Text(
|
child: Text(
|
||||||
option.options,
|
option.categoryname ?? "",
|
||||||
style: Constant.body1(context: context).copyWith(
|
style: Constant.body1(context: context).copyWith(
|
||||||
color: Constant.textBlack,
|
color: Constant.textBlack,
|
||||||
fontWeight: FontWeight.w600),
|
fontWeight: FontWeight.w600),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
value: selectedDropdownKategori.value,
|
value: selectedListCategory.value,
|
||||||
onChanged: (DummyDropdownTipe? newValue) {
|
onChanged: (ListCategory? newValue) {
|
||||||
// if (newValue) {
|
// if (newValue) {
|
||||||
selectedDropdownKategori.value = newValue!;
|
selectedListCategory.value = newValue!;
|
||||||
print(selectedDropdownKategori.value.id);
|
print(selectedListCategory.value.categoryid);
|
||||||
// }
|
// }
|
||||||
},
|
},
|
||||||
buttonStyleData: ButtonStyleData(
|
buttonStyleData: ButtonStyleData(
|
||||||
@@ -386,30 +415,28 @@ class TransaksiScreen extends HookConsumerWidget {
|
|||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (radioButtonItems.value.isEmpty)
|
if (listTypeData.value.isEmpty)
|
||||||
Text('Radio Button Empty')
|
Text('Radio Button Empty')
|
||||||
else
|
else
|
||||||
for (var i = 0;
|
for (var i = 0; i < listTypeData.value.length; i++)
|
||||||
i < radioButtonItems.value.length;
|
|
||||||
i++)
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(right: 20),
|
padding: const EdgeInsets.only(right: 20),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Radio<DummyRadioTipe>(
|
Radio<ListType>(
|
||||||
activeColor: Constant.confirmed,
|
activeColor: Constant.confirmed,
|
||||||
value: radioButtonItems.value[i],
|
value: listTypeData.value[i],
|
||||||
groupValue: selectedRadio.value,
|
groupValue: selectedListTypeData.value,
|
||||||
onChanged: (DummyRadioTipe? index) {
|
onChanged: (ListType? index) {
|
||||||
if (isMounted()) {
|
if (isMounted()) {
|
||||||
selectedRadio.value = index!;
|
selectedListTypeData.value = index!;
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
radioButtonItems.value[i].text,
|
listTypeData.value[i].typename ?? "",
|
||||||
style: Constant.body1(context: context)
|
style: Constant.body1(context: context)
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: Constant.textBlack,
|
color: Constant.textBlack,
|
||||||
|
|||||||
Reference in New Issue
Block a user