step 23 : home screen, repository, provider

This commit is contained in:
sindhu
2024-01-17 11:40:11 +07:00
parent f3b941772b
commit 844e4c48f5
9 changed files with 661 additions and 2 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -282,6 +282,13 @@ class Constant {
);
}
static TextStyle titleH6_700({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualYPhone(context: context, y: 18),
fontWeight: FontWeight.w700,
);
}
static TextStyle titleH3_700({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualYPhone(context: context, y: 24),
@@ -353,6 +360,13 @@ class Constant {
);
}
static TextStyle H4_700V3({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualYPhone(context: context, y: 16),
fontWeight: FontWeight.w700,
);
}
static TextStyle titleH5({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualYPhone(context: context, y: 18),

View File

@@ -0,0 +1,21 @@
class InfoAccountBalanceModel {
String? totalAll;
String? kredit;
String? debit;
InfoAccountBalanceModel({this.totalAll, this.kredit, this.debit});
InfoAccountBalanceModel.fromJson(Map<String, dynamic> json) {
totalAll = json['total_all'];
kredit = json['kredit'];
debit = json['debit'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['total_all'] = this.totalAll;
data['kredit'] = this.kredit;
data['debit'] = this.debit;
return data;
}
}

View File

@@ -0,0 +1,64 @@
class ListTransaksiHomeModel {
String? id;
String? tanggaltransaksi;
String? tipe;
String? kategoriid;
String? kategoriname;
String? note;
String? amount;
String? sender;
String? imgurl;
String? isconfirm;
String? tanggalconfirm;
String? usertransaksi;
String? userconfirm;
ListTransaksiHomeModel(
{this.id,
this.tanggaltransaksi,
this.tipe,
this.kategoriid,
this.kategoriname,
this.note,
this.amount,
this.sender,
this.imgurl,
this.isconfirm,
this.tanggalconfirm,
this.usertransaksi,
this.userconfirm});
ListTransaksiHomeModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
tanggaltransaksi = json['tanggaltransaksi'];
tipe = json['tipe'];
kategoriid = json['kategoriid'];
kategoriname = json['kategoriname'];
note = json['note'];
amount = json['amount'];
sender = json['sender'];
imgurl = json['imgurl'];
isconfirm = json['isconfirm'];
tanggalconfirm = json['tanggalconfirm'];
usertransaksi = json['usertransaksi'];
userconfirm = json['userconfirm'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['tanggaltransaksi'] = this.tanggaltransaksi;
data['tipe'] = this.tipe;
data['kategoriid'] = this.kategoriid;
data['kategoriname'] = this.kategoriname;
data['note'] = this.note;
data['amount'] = this.amount;
data['sender'] = this.sender;
data['imgurl'] = this.imgurl;
data['isconfirm'] = this.isconfirm;
data['tanggalconfirm'] = this.tanggalconfirm;
data['usertransaksi'] = this.usertransaksi;
data['userconfirm'] = this.userconfirm;
return data;
}
}

View File

@@ -0,0 +1,11 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../model/info_account_balance.dart';
final currentInfoAccountBalanceProvider = StateProvider<InfoAccountBalanceModel>(
((ref) => InfoAccountBalanceModel(
debit: "0",
kredit: "0",
totalAll: "0",
)),
);

View File

@@ -0,0 +1,61 @@
import 'package:app_petty_cash/model/list_type_model.dart';
import '../app/constant.dart';
import '../model/info_account_balance.dart';
import '../model/list_transaksi_model.dart';
import 'base_repository.dart';
class HomeRepository extends BaseRepository {
HomeRepository({required super.dio});
// list transaksi home
Future<List<ListTransaksiHomeModel>> getTransaksiListHome(
String companyid,
) async {
final service =
"${Constant.baseUrlDevone}homescreen/list_transaction/?companyid=$companyid";
final resp = await get(
// param: {
// "": "",
// },
service: service,
);
print("url list transaksi home : $service");
final result = List<ListTransaksiHomeModel>.empty(growable: true);
resp['data'].forEach((e) {
final model = ListTransaksiHomeModel.fromJson(e);
result.add(model);
});
return result;
}
// info account balance
Future<InfoAccountBalanceModel> getInfoAccountBalance(
String companyid,
) async {
final service =
"${Constant.baseUrlDevone}homescreen/list_total/?companyid=$companyid";
final resp = await get(
// param: {
// "": "",
// },
service: service,
);
print("url card info account balance home : $service");
InfoAccountBalanceModel result = InfoAccountBalanceModel(
debit: "0",
kredit: "0",
totalAll: "0",
);
print(resp['data']);
final model = InfoAccountBalanceModel.fromJson(resp['data']);
result = model;
return result;
}
}

View File

@@ -1,17 +1,34 @@
import 'dart:convert';
import 'package:app_petty_cash/screen/home/info_account_balance_provider.dart';
import 'package:app_petty_cash/screen/home/list_transaksi_home_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../app/constant.dart';
import '../../app/route.dart';
import '../../model/info_account_balance.dart';
import '../../model/list_transaksi_model.dart';
import '../../provider/current_info_account_balance_provider.dart';
import '../../provider/current_user_provider.dart';
import '../../widget/custom_drawer.dart';
import '../../widget/history_row_atas_widget.dart';
import '../../widget/sankbar_widget.dart';
class HomeScreen extends HookConsumerWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final M_CompanyID = useState<String>("0");
final searchTransaksiHomeLoading = useState<bool>(false);
final infoAccountBalanceHomeLoading = useState<bool>(false);
final listTransaksiHome = useState<List<ListTransaksiHomeModel>>(
List.empty(growable: true),
);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final userID = ref.read(currentUserProvider)?.model.M_UserID ?? "0";
@@ -27,6 +44,80 @@ class HomeScreen extends HookConsumerWidget {
return () {};
}, []);
Future<String> getCompanyID() async {
final shared = await SharedPreferences.getInstance();
String M_CompanyID = "0";
if (shared != null) {
final bearerString = shared.get(Constant.bearerName).toString();
final xmodel = jsonDecode(bearerString);
if (xmodel != null) {
M_CompanyID = xmodel["model"]["M_CompanyID"];
}
}
if (M_CompanyID == "0") {
// throw BaseRepositoryException(message: 'Invalid Company ID');
}
return M_CompanyID;
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
M_CompanyID.value = await getCompanyID();
// info account balance
ref
.read(infoAccountBalanceHomeProvider.notifier)
.infoAccountBalanceHome(M_CompanyID.value);
});
return () {};
}, []);
// read provider home
ref.listen(
listTransaksiHomeProvider,
(previous, next) {
if (next is ListTransaksiHomeStateLoading) {
searchTransaksiHomeLoading.value = true;
} else if (next is ListTransaksiHomeStateError) {
// print(next.message);
searchTransaksiHomeLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
} else if (next is ListTransaksiHomeStateDone) {
// print(jsonEncode(next.model));
// print(next.model.length);
listTransaksiHome.value = next.model;
searchTransaksiHomeLoading.value = false;
}
},
);
// read provider info account balance
ref.listen(
infoAccountBalanceHomeProvider,
(previous, next) {
if (next is InfoAccountBalanceHomeStateLoading) {
infoAccountBalanceHomeLoading.value = true;
} else if (next is InfoAccountBalanceHomeStateError) {
// print(next.message);
infoAccountBalanceHomeLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
} else if (next is InfoAccountBalanceHomeStateDone) {
// print(jsonEncode(next.model));
// print(next.model.length);
// infoAccountBalanceObject.value = next.model;
ref.read(currentInfoAccountBalanceProvider.notifier).state =
InfoAccountBalanceModel(
kredit: next.model.kredit,
debit: next.model.debit,
totalAll: next.model.totalAll,
);
infoAccountBalanceHomeLoading.value = false;
}
},
);
return Padding(
padding: EdgeInsets.only(
top: Constant.getActualYPhone(context: context, y: 30),
@@ -44,8 +135,258 @@ class HomeScreen extends HookConsumerWidget {
),
drawer: CustomDrawer(),
body: SafeArea(
child: Center(
child: Text('Home Screen Content'),
child: Padding(
padding: EdgeInsets.only(
top: Constant.getActualYPhone(context: context, y: 36),
left: Constant.getActualXPhone(context: context, x: 34),
right: Constant.getActualXPhone(context: context, x: 34),
),
child: RefreshIndicator(
onRefresh: () async {
ref
.read(infoAccountBalanceHomeProvider.notifier)
.infoAccountBalanceHome(M_CompanyID.value);
},
child: Container(
width: Constant.getActualXPhone(context: context, x: 390),
height: Constant.getActualYPhone(context: context, y: 844),
child: Column(
children: [
Container(
width: Constant.getActualXPhone(context: context, x: 332),
height:
Constant.getActualYPhone(context: context, y: 173),
decoration: BoxDecoration(
// color: Colors.black12,
borderRadius: BorderRadius.circular(20),
image: DecorationImage(
image: AssetImage('images/background_card.png'),
fit: BoxFit.cover,
),
boxShadow: [
BoxShadow(
color: Color.fromRGBO(145, 158, 171, 0.16),
offset: Offset(0, 24),
blurRadius: 48,
),
],
),
//Isi Card
child: (infoAccountBalanceHomeLoading.value)
? Center(
child: CircularProgressIndicator(),
)
: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Text1 & Text2
Padding(
padding: EdgeInsets.only(
top: Constant.getActualYPhone(
context: context, y: 17),
left: Constant.getActualXPhone(
context: context, x: 81),
right: Constant.getActualXPhone(
context: context, x: 81),
),
child: Column(
children: [
Text(
'Account Balance',
style: Constant.body1(
context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textWhite),
),
Text(
ref
.watch(
currentInfoAccountBalanceProvider)
.totalAll
.toString(),
style: Constant.H4_700V3(
context: context)
.copyWith(
color: Constant.textWhite,
),
),
],
),
),
SizedBox(
height: Constant.getActualYPhone(
context: context, y: 27),
),
//Debit dan Kredit
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
// Spasi di sebelah kiri "Check In"
Expanded(
child: Padding(
padding: EdgeInsets.only(
left: Constant.getActualXPhone(
context: context, x: 20),
),
child: Column(
children: [
Text(
'Debit',
style: Constant.body1(
context: context)
.copyWith(
fontWeight:
FontWeight.w400,
color:
Constant.textWhite),
),
Text(
ref
.watch(
currentInfoAccountBalanceProvider)
.debit
.toString(),
style: Constant.H4_700V3(
context: context)
.copyWith(
color:
Constant.textWhite),
),
],
),
),
),
// SizedBox(
// width: Constant.getActualXPhone(
// context: context, x: 51),
// ),
Expanded(
child: Padding(
padding: EdgeInsets.only(
right: Constant.getActualXPhone(
context: context, x: 28),
),
child: Column(
children: [
Text(
'Credit',
style: Constant.body1(
context: context)
.copyWith(
fontWeight:
FontWeight.w400,
color:
Constant.textWhite),
),
Text(
ref
.watch(
currentInfoAccountBalanceProvider)
.kredit
.toString(),
style: Constant.H4_700V3(
context: context)
.copyWith(
color:
Constant.textWhite),
),
],
),
),
),
],
),
SizedBox(
height: Constant.getActualYPhone(
context: context, y: 17),
),
],
),
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 44),
),
Align(
alignment: Alignment.centerLeft,
child: Text(
'Transaksi Terkini',
style: Constant.titleH5_600(context: context)
.copyWith(color: Constant.textBlack),
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 24),
),
// list transaksi
(searchTransaksiHomeLoading.value)
? Center(
child: CircularProgressIndicator(),
)
: Container(
child: Expanded(
child: ListView.builder(
itemCount: listTransaksiHome.value.length,
itemBuilder: (context, idx) {
return Padding(
padding: EdgeInsets.only(
bottom: Constant.getActualYPhone(
context: context,
y: 10,
),
),
child: Card(
elevation: 2.0,
child: Padding(
padding: EdgeInsets.all(10),
child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.start,
children: [
// atas
HistoryRowAtasWidget(
icon_category_id:
listTransaksiHome
.value[idx].kategoriid
.toString(),
icon_category_name:
listTransaksiHome
.value[idx].kategoriname
.toString(),
amount: listTransaksiHome
.value[idx].amount
.toString(),
tglTransaksi: listTransaksiHome
.value[idx].tanggaltransaksi
.toString(),
tipe: listTransaksiHome
.value[idx].tipe
.toString(),
),
],
),
),
),
);
},
),
),
),
],
),
),
),
),
),
),

View File

@@ -0,0 +1,75 @@
import 'package:app_petty_cash/provider/current_info_account_balance_provider.dart';
import 'package:app_petty_cash/repository/home_repository.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../model/info_account_balance.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import 'list_transaksi_home_provider.dart';
abstract class InfoAccountBalanceHomeState extends Equatable {
final DateTime date;
const InfoAccountBalanceHomeState(this.date);
@override
List<Object?> get props => [date];
}
class InfoAccountBalanceHomeStateInit extends InfoAccountBalanceHomeState {
InfoAccountBalanceHomeStateInit() : super(DateTime.now());
}
class InfoAccountBalanceHomeStateLoading extends InfoAccountBalanceHomeState {
InfoAccountBalanceHomeStateLoading() : super(DateTime.now());
}
class InfoAccountBalanceHomeStateError extends InfoAccountBalanceHomeState {
final String message;
InfoAccountBalanceHomeStateError({
required this.message,
}) : super(DateTime.now());
}
class InfoAccountBalanceHomeStateDone extends InfoAccountBalanceHomeState {
final InfoAccountBalanceModel model;
// final String resp;
InfoAccountBalanceHomeStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class InfoAccountBalanceHomeNotifier
extends StateNotifier<InfoAccountBalanceHomeState> {
final Ref ref;
InfoAccountBalanceHomeNotifier({
required this.ref,
}) : super(InfoAccountBalanceHomeStateInit());
void infoAccountBalanceHome(
String companyid,
) async {
try {
state = InfoAccountBalanceHomeStateLoading();
final dio = ref.read(dioProvider);
final resp = await HomeRepository(dio: dio).getInfoAccountBalance(
companyid,
);
state = InfoAccountBalanceHomeStateDone(model: resp);
// list transaksi home
ref.read(listTransaksiHomeProvider.notifier).listTransaksiHome(companyid);
} catch (e) {
if (e is BaseRepositoryException) {
state = InfoAccountBalanceHomeStateError(message: e.message.toString());
} else {
state = InfoAccountBalanceHomeStateError(message: e.toString());
}
}
}
}
//provider
final infoAccountBalanceHomeProvider = StateNotifierProvider<
InfoAccountBalanceHomeNotifier, InfoAccountBalanceHomeState>(
(ref) => InfoAccountBalanceHomeNotifier(ref: ref),
);

View File

@@ -0,0 +1,72 @@
import 'package:app_petty_cash/repository/home_repository.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../model/list_transaksi_model.dart';
import '../../repository/transaksi_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class ListTransaksiHomeState extends Equatable {
final DateTime date;
const ListTransaksiHomeState(this.date);
@override
List<Object?> get props => [date];
}
class ListTransaksiHomeStateInit extends ListTransaksiHomeState {
ListTransaksiHomeStateInit() : super(DateTime.now());
}
class ListTransaksiHomeStateLoading extends ListTransaksiHomeState {
ListTransaksiHomeStateLoading() : super(DateTime.now());
}
class ListTransaksiHomeStateError extends ListTransaksiHomeState {
final String message;
ListTransaksiHomeStateError({
required this.message,
}) : super(DateTime.now());
}
class ListTransaksiHomeStateDone extends ListTransaksiHomeState {
final List<ListTransaksiHomeModel> model;
// final String resp;
ListTransaksiHomeStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class ListTransaksiHomeNotifier extends StateNotifier<ListTransaksiHomeState> {
final Ref ref;
ListTransaksiHomeNotifier({
required this.ref,
}) : super(ListTransaksiHomeStateInit());
void listTransaksiHome(
String companyid,
) async {
try {
state = ListTransaksiHomeStateLoading();
final dio = ref.read(dioProvider);
final resp = await HomeRepository(dio: dio).getTransaksiListHome(
companyid,
);
state = ListTransaksiHomeStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = ListTransaksiHomeStateError(message: e.message.toString());
} else {
state = ListTransaksiHomeStateError(message: e.toString());
}
}
}
}
//provider
final listTransaksiHomeProvider =
StateNotifierProvider<ListTransaksiHomeNotifier, ListTransaksiHomeState>(
(ref) => ListTransaksiHomeNotifier(ref: ref),
);