6 Commits

Author SHA1 Message Date
sindhu
987a5a5c3a step 25 : ganti icon apk 2024-01-17 13:54:41 +07:00
sindhu
88ad1d6584 step 24 : fix drawer, login bg color 2024-01-17 12:34:22 +07:00
sindhu
844e4c48f5 step 23 : home screen, repository, provider 2024-01-17 11:40:11 +07:00
sindhu
f3b941772b step 22 : build apk, setting logo 2024-01-17 09:47:34 +07:00
sindhu
be50c48607 step 21 : fix bug history transaksi, logo apk.png 2024-01-17 09:05:11 +07:00
sindhu
f915ed2c10 step 20 : delete transaksi, bug icon svg from server, date convert tgl trans 2024-01-16 22:06:42 +07:00
65 changed files with 2007 additions and 421 deletions

View File

@@ -1,8 +1,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="app_petty_cash"
android:label="PettyCash"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
android:icon="@mipmap/launcher_icon"
android:usesCleartextTraffic="true"
android:requestLegacyExternalStorage="true"
>
<activity
android:name=".MainActivity"
android:exported="true"
@@ -10,7 +14,9 @@
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="adjustResize"
android:screenOrientation="portrait"
>
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,7 @@
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

After

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 B

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 762 B

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -10,7 +10,10 @@ class Constant {
static double designWidthPhone = 390;
static String bearerName = "petty-cash";
static String version = "1.00";
// static String version = "1.00";
// NOTE VERSI HARUS SAMA DENGAN PUBSPEC.YAML
static String version = "1.0.0";
// static String baseUrl = "https://devregonline.pramita.co.id/one-api/xdoc/";
@@ -18,7 +21,7 @@ class Constant {
static String baseUrlDevoneReport = "devone.aplikasi.web.id";
static String baseUrlDevone =
"http://devone.aplikasi.web.id/one-api-pettycash/pettycash/";
"https://devone.aplikasi.web.id/one-api-pettycash/pettycash/";
// static String baseUrl_appdoctor =
// "http://devbandungraya.aplikasi.web.id/one-api/app_doctor/";
@@ -282,6 +285,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 +363,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

@@ -2,10 +2,15 @@ import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'app/route.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
initializeDateFormatting();
await SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarIconBrightness:
Brightness.dark, // this will change the brightness of the icons
@@ -38,8 +43,8 @@ class MyApp extends StatelessWidget {
},
),
debugShowCheckedModeBanner: false,
initialRoute: loginRoute,
// initialRoute: splashScreen,
// initialRoute: loginRoute,
initialRoute: splashScreen,
// initialRoute: transaksiRoute,
// initialRoute: reportRoute,
// initialRoute: testFilePickerRoute,

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

@@ -121,4 +121,34 @@ class TransaksiRepository extends BaseRepository {
});
return result;
}
// delete transaksi
Future<String> deleteTransaksi(
String id,
String userid,
) async {
final service =
"${Constant.baseUrlDevone}transaction/deletetransaction/?id=$id&userid=$userid";
final resp = await get(
// param: {
// "": "",
// },
service: service,
);
print("url delete transaksi : $service");
// final result = List<ListCategory>.empty(growable: true);
// resp['data'].forEach((e) {
// final model = ListCategory.fromJson(e);
// result.add(model);
// });
if(resp['status'] != "OK"){
return resp['message'];
}
return resp['status'];
}
}

View File

@@ -1,17 +1,55 @@
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),
);
final M_CompanyName = useState("-");
// company name
Future<String> getCompanyName() async {
final shared = await SharedPreferences.getInstance();
String M_CompanyName = "-";
if (shared != null) {
final bearerString = shared.get(Constant.bearerName).toString();
final xmodel = jsonDecode(bearerString);
if (xmodel != null) {
M_CompanyName = xmodel["model"]["M_CompanyName"];
}
}
if (M_CompanyName == "0") {
// throw BaseRepositoryException(message: 'Invalid Company ID');
}
return M_CompanyName;
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final userID = ref.read(currentUserProvider)?.model.M_UserID ?? "0";
@@ -23,10 +61,85 @@ class HomeScreen extends HookConsumerWidget {
// Navigator.popAndPushNamed(context, loginRoute);
return;
}
M_CompanyName.value = await getCompanyName();
});
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),
@@ -34,8 +147,12 @@ class HomeScreen extends HookConsumerWidget {
child: Scaffold(
appBar: AppBar(
title: Text(
'Home Screen',
style: TextStyle(color: Constant.textWhite),
// 'Home Screen',
M_CompanyName.value,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Constant.textWhite,
),
),
backgroundColor: Constant.pcBtnBackgroundColor,
iconTheme: IconThemeData(
@@ -44,8 +161,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),
);

View File

@@ -55,22 +55,22 @@ class LoginScreen extends HookConsumerWidget {
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: Constant.backgroundColor,
// backgroundColor: Colors.transparent,
body: SafeArea(
child: Center(
child: Container(
width: Constant.getActualXPhone(context: context, x: 390),
height: Constant.getActualYPhone(context: context, y: 844),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xffdadae6),
Color(0xfff6f7fb),
],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(
// colors: [
// Color(0xffdadae6),
// Color(0xfff6f7fb),
// ],
// begin: Alignment.centerLeft,
// end: Alignment.centerRight,
// ),
// ),
// child: BlockBodyV2(),
child: LoginFormScreen(),
),

View File

@@ -0,0 +1,84 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/transaksi_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import 'search_history_transaksi_provider.dart';
abstract class DeleteTransaksiState extends Equatable {
final DateTime date;
const DeleteTransaksiState(this.date);
@override
List<Object?> get props => [date];
}
class DeleteTransaksiStateInit extends DeleteTransaksiState {
DeleteTransaksiStateInit() : super(DateTime.now());
}
class DeleteTransaksiStateLoading extends DeleteTransaksiState {
DeleteTransaksiStateLoading() : super(DateTime.now());
}
class DeleteTransaksiStateError extends DeleteTransaksiState {
final String message;
DeleteTransaksiStateError({
required this.message,
}) : super(DateTime.now());
}
class DeleteTransaksiStateDone extends DeleteTransaksiState {
// final List<ListType> model;
final String resp;
DeleteTransaksiStateDone({
required this.resp,
}) : super(DateTime.now());
}
//notifier
class DeleteTransaksiNotifier extends StateNotifier<DeleteTransaksiState> {
final Ref ref;
DeleteTransaksiNotifier({
required this.ref,
}) : super(DeleteTransaksiStateInit());
void deleteTransaksi(
String id,
String userid,
String companyid,
String tglAwal,
String tglAkhir,
String categoryid,
) async {
try {
state = DeleteTransaksiStateLoading();
final dio = ref.read(dioProvider);
final resp = await TransaksiRepository(dio: dio).deleteTransaksi(
id,
userid,
);
state = DeleteTransaksiStateDone(resp: resp);
// search lagi buat get data
ref.read(searchHistoryTransaksiProvider.notifier).searchHistoryTransaksi(
companyid,
tglAwal,
tglAkhir,
categoryid,
);
} catch (e) {
if (e is BaseRepositoryException) {
state = DeleteTransaksiStateError(message: e.message.toString());
} else {
state = DeleteTransaksiStateError(message: e.toString());
}
}
}
}
//provider
final deleteTransaksiProvider =
StateNotifierProvider<DeleteTransaksiNotifier, DeleteTransaksiState>(
(ref) => DeleteTransaksiNotifier(ref: ref),
);

View File

@@ -1,5 +1,6 @@
import 'dart:convert';
import 'package:app_petty_cash/screen/transaksi/delete_transaksi_provider.dart';
import 'package:app_petty_cash/screen/transaksi/search_history_transaksi_provider.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
@@ -41,7 +42,8 @@ class HistoryTransaksiScreen extends HookConsumerWidget {
),
);
String M_CompanyID = "0";
// String M_CompanyID = "0";
final M_CompanyID = useState<String>("0");
String formattedDate = DateFormat('dd-MM-yyyy').format(DateTime.now());
final ctrlTglAwal = useTextEditingController(text: formattedDate);
@@ -138,6 +140,27 @@ class HistoryTransaksiScreen extends HookConsumerWidget {
},
);
// delete transaksi
ref.listen(
deleteTransaksiProvider,
(previous, next) {
if (next is DeleteTransaksiStateLoading) {
searchHistoryIsLoading.value = true;
} else if (next is DeleteTransaksiStateError) {
// print(next.message);
searchHistoryIsLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
} else if (next is DeleteTransaksiStateDone) {
// print(jsonEncode(next.model));
// print(next.model.length);
// listSearchHistory.value = next.model;
SanckbarWidget(
context, 'Data Berhasil Dihapus', snackbarType.success);
searchHistoryIsLoading.value = false;
}
},
);
Future<String> getCompanyID() async {
final shared = await SharedPreferences.getInstance();
String M_CompanyID = "0";
@@ -180,7 +203,7 @@ class HistoryTransaksiScreen extends HookConsumerWidget {
// list category provider
ref.read(listCategoryProvider.notifier).getListCategory();
M_CompanyID = await getCompanyID();
M_CompanyID.value = await getCompanyID();
DateTime parsedDate = DateFormat('dd-MM-yyyy').parse(
ctrlTglAwal.value.text.toString(),
@@ -199,11 +222,100 @@ class HistoryTransaksiScreen extends HookConsumerWidget {
ref
.read(searchHistoryTransaksiProvider.notifier)
.searchHistoryTransaksi(
M_CompanyID, formattedDateAwal, formattedDateAkhir, categoryid);
M_CompanyID.value,
formattedDateAwal,
formattedDateAkhir,
categoryid,
);
});
return () {};
}, []);
// delete alert
Future<void> showDeleteConfirmationDialog(
BuildContext context,
String id,
String userid,
String companyid,
String tglAwal,
String tglAkhir,
String categoryid,
) async {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Konfirmasi Hapus'),
content: Text('Apakah anda yakin menghapus data ini?'),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.of(context).pop(); // Tutup dialog
},
child: Text('Batal'),
),
ElevatedButton(
onPressed: () {
print('Deleted id $id , userid $userid');
DateTime parsedDate = DateFormat('dd-MM-yyyy').parse(
ctrlTglAwal.value.text.toString(),
);
String formattedDateAwal =
DateFormat('yyyy-MM-dd').format(parsedDate);
DateTime parsedDateAkhir = DateFormat('dd-MM-yyyy').parse(
ctrlTglAkhir.value.text.toString(),
);
String formattedDateAkhir =
DateFormat('yyyy-MM-dd').format(parsedDateAkhir);
ref.read(deleteTransaksiProvider.notifier).deleteTransaksi(
id,
userid,
companyid,
formattedDateAwal,
formattedDateAkhir,
categoryid,
);
Navigator.of(context).pop();
},
child: Text(
'Hapus Data',
style: Constant.body1_600(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textWhite,
),
),
style: ButtonStyle(
backgroundColor:
MaterialStateColor.resolveWith((st) => Constant.textRed),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: Constant.textRed,
),
),
),
shadowColor: MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
),
],
);
},
);
}
void _closeKeyboard() {
FocusManager.instance.primaryFocus?.unfocus();
}
final FocusNode focusNodetglAwal = useFocusNode();
final tglAwalHasFocus = useState(false);
final FocusNode focusNodetglAkhir = useFocusNode();
final tglAkhirHasFocus = useState(false);
return Padding(
padding: EdgeInsets.only(
top: Constant.getActualYPhone(context: context, y: 30),
@@ -238,80 +350,91 @@ class HistoryTransaksiScreen extends HookConsumerWidget {
children: [
// Tanggal Awal
Expanded(
child: TextField(
controller: ctrlTglAwal,
decoration: InputDecoration(
hintStyle:
Constant.body2_400(context: context).copyWith(
color: Constant.textGreyv2,
),
labelStyle:
Constant.body2_400(context: context).copyWith(
color: Constant.textGreyv2,
),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.orange,
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Constant.textGreyv2,
width: 1,
),
),
labelText: "Tanggal Awal",
hintText: 'Tanggal Awal',
// suffixIcon: isLoadingFilterScope.value
// ? SizedBox(
// width: Constant.getActualXPhone(
// context: context,
// x: 4,
// ),
// height: Constant.getActualYPhone(
// context: context,
// y: 4,
// ),
// child: CircularProgressIndicator(
// color: Constant.textRed,
// ),
// )
// : Icon(
// Icons.calendar_month_sharp,
// color: Constant.colorIconDate,
// ),
),
onTap: () async {
final selectedDateAwal = await showDatePicker(
// locale: const Locale("en-CA"),
// locale: ,
context: context,
initialEntryMode:
DatePickerEntryMode.calendarOnly,
firstDate: DateTime(2000),
lastDate: DateTime(2100),
initialDate: (ctrlTglAwal.text.isEmpty)
? DateTime.now()
: tglAwal.value,
);
if (selectedDateAwal != null) {
String formattedDate = DateFormat('dd-MM-yyyy')
.format(selectedDateAwal);
// ctrlTglAwal.text =
// selectedDateAwal.toString().split(' ')[0];
ctrlTglAwal.text = formattedDate;
tglAwal.value = selectedDateAwal;
tglAwalTmp.value = selectedDateAwal.toString();
}
if (selectedDateAwal == null) {
print('cancel button');
return;
}
child: GestureDetector(
onTap: () {
focusNodetglAwal.unfocus();
// _closeKeyboard();
},
child: TextField(
enableInteractiveSelection: false,
showCursor: (tglAwalHasFocus.value) ? true : false,
controller: ctrlTglAwal,
decoration: InputDecoration(
hintStyle:
Constant.body2_400(context: context).copyWith(
color: Constant.textGreyv2,
),
labelStyle:
Constant.body2_400(context: context).copyWith(
color: Constant.textGreyv2,
),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.orange,
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Constant.textGreyv2,
width: 1,
),
),
labelText: "Tanggal Awal",
hintText: 'Tanggal Awal',
// suffixIcon: isLoadingFilterScope.value
// ? SizedBox(
// width: Constant.getActualXPhone(
// context: context,
// x: 4,
// ),
// height: Constant.getActualYPhone(
// context: context,
// y: 4,
// ),
// child: CircularProgressIndicator(
// color: Constant.textRed,
// ),
// )
// : Icon(
// Icons.calendar_month_sharp,
// color: Constant.colorIconDate,
// ),
),
onTap: () async {
final selectedDateAwal = await showDatePicker(
// locale: const Locale("en-CA"),
// locale: ,
context: context,
initialEntryMode:
DatePickerEntryMode.calendarOnly,
firstDate: DateTime(2000),
lastDate: DateTime(2100),
initialDate: (ctrlTglAwal.text.isEmpty)
? DateTime.now()
: tglAwal.value,
);
if (selectedDateAwal != null) {
String formattedDate = DateFormat('dd-MM-yyyy')
.format(selectedDateAwal);
// ctrlTglAwal.text =
// selectedDateAwal.toString().split(' ')[0];
ctrlTglAwal.text = formattedDate;
tglAwal.value = selectedDateAwal;
tglAwalTmp.value = selectedDateAwal.toString();
}
if (selectedDateAwal == null) {
print('cancel button');
return;
}
// focusNodetglAwal.unfocus();
// _closeKeyboard();
},
),
),
),
@@ -321,80 +444,89 @@ class HistoryTransaksiScreen extends HookConsumerWidget {
),
// Tanggal Akhir
Expanded(
child: TextField(
controller: ctrlTglAkhir,
decoration: InputDecoration(
hintStyle:
Constant.body2_400(context: context).copyWith(
color: Constant.textGreyv2,
),
labelStyle:
Constant.body2_400(context: context).copyWith(
color: Constant.textGreyv2,
),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.orange,
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Constant.textGreyv2,
width: 1,
),
),
labelText: "Tanggal Akhir",
hintText: 'Tanggal Akhir',
// suffixIcon: isLoadingFilterScope.value
// ? SizedBox(
// width: Constant.getActualXPhone(
// context: context,
// x: 4,
// ),
// height: Constant.getActualYPhone(
// context: context,
// y: 4,
// ),
// child: CircularProgressIndicator(
// color: Constant.textRed,
// ),
// )
// : Icon(
// Icons.calendar_month_sharp,
// color: Constant.colorIconDate,
// ),
),
onTap: () async {
final selectedDateAkhir = await showDatePicker(
// locale: const Locale("en-CA"),
// locale: ,
context: context,
initialEntryMode:
DatePickerEntryMode.calendarOnly,
firstDate: DateTime(2000),
lastDate: DateTime(2100),
initialDate: (ctrlTglAkhir.text.isEmpty)
? DateTime.now()
: tglAkhir.value,
);
if (selectedDateAkhir != null) {
String formattedDate = DateFormat('dd-MM-yyyy')
.format(selectedDateAkhir);
// ctrlTglAkhir.text =
// selectedDateAkhir.toString().split(' ')[0];
ctrlTglAkhir.text = formattedDate;
tglAkhir.value = selectedDateAkhir;
tglAkhirTmp.value = selectedDateAkhir.toString();
}
if (selectedDateAkhir == null) {
print('cancel button');
return;
}
child: GestureDetector(
onTap: () {
focusNodetglAkhir.unfocus();
// _closeKeyboard();
},
child: TextField(
enableInteractiveSelection: false,
showCursor: (tglAwalHasFocus.value) ? true : false,
controller: ctrlTglAkhir,
decoration: InputDecoration(
hintStyle:
Constant.body2_400(context: context).copyWith(
color: Constant.textGreyv2,
),
labelStyle:
Constant.body2_400(context: context).copyWith(
color: Constant.textGreyv2,
),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.orange,
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Constant.textGreyv2,
width: 1,
),
),
labelText: "Tanggal Akhir",
hintText: 'Tanggal Akhir',
// suffixIcon: isLoadingFilterScope.value
// ? SizedBox(
// width: Constant.getActualXPhone(
// context: context,
// x: 4,
// ),
// height: Constant.getActualYPhone(
// context: context,
// y: 4,
// ),
// child: CircularProgressIndicator(
// color: Constant.textRed,
// ),
// )
// : Icon(
// Icons.calendar_month_sharp,
// color: Constant.colorIconDate,
// ),
),
onTap: () async {
final selectedDateAkhir = await showDatePicker(
// locale: const Locale("en-CA"),
// locale: ,
context: context,
initialEntryMode:
DatePickerEntryMode.calendarOnly,
firstDate: DateTime(2000),
lastDate: DateTime(2100),
initialDate: (ctrlTglAkhir.text.isEmpty)
? DateTime.now()
: tglAkhir.value,
);
if (selectedDateAkhir != null) {
String formattedDate = DateFormat('dd-MM-yyyy')
.format(selectedDateAkhir);
// ctrlTglAkhir.text =
// selectedDateAkhir.toString().split(' ')[0];
ctrlTglAkhir.text = formattedDate;
tglAkhir.value = selectedDateAkhir;
tglAkhirTmp.value =
selectedDateAkhir.toString();
}
if (selectedDateAkhir == null) {
print('cancel button');
return;
}
},
),
),
),
],
@@ -588,11 +720,11 @@ class HistoryTransaksiScreen extends HookConsumerWidget {
],
),
onPressed: () async {
M_CompanyID = await getCompanyID();
M_CompanyID.value = await getCompanyID();
ref
.read(searchHistoryTransaksiProvider.notifier)
.searchHistoryTransaksi(
M_CompanyID,
M_CompanyID.value,
ctrlTglAwal.text,
ctrlTglAkhir.text,
selectedListCategory.value.categoryid ?? "0",
@@ -754,6 +886,7 @@ class HistoryTransaksiScreen extends HookConsumerWidget {
tipe: listSearchHistory
.value[idx].tipe
.toString(),
// searchHistoryIsLoading.value
),
// bawah
@@ -774,15 +907,15 @@ class HistoryTransaksiScreen extends HookConsumerWidget {
),
shape: RoundedRectangleBorder(
side: BorderSide(
color:
Constant.bgChipConfirmed),
color: Constant
.bgTextChipConfirmed),
borderRadius:
BorderRadius.circular(
50,
),
),
backgroundColor:
Constant.bgChipConfirmed,
backgroundColor: Constant
.bgTextChipConfirmed,
),
],
),
@@ -799,8 +932,28 @@ class HistoryTransaksiScreen extends HookConsumerWidget {
MainAxisAlignment.end,
children: [
InkWell(
onTap: () {
print('Deleted');
onTap: () async {
final userID = ref
.read(
currentUserProvider)
?.model
.M_UserID ??
"0";
// print('Deleted');
showDeleteConfirmationDialog(
context,
listSearchHistory
.value[idx].id
.toString(),
userID,
M_CompanyID.value,
ctrlTglAwal.text.toString(),
ctrlTglAkhir.text
.toString(),
selectedListCategory
.value.categoryid
.toString(),
);
},
child: Chip(
label: Text(
@@ -811,8 +964,8 @@ class HistoryTransaksiScreen extends HookConsumerWidget {
),
shape: RoundedRectangleBorder(
side: BorderSide(
color:
Constant.bgTextChipDelete),
color: Constant
.bgTextChipDelete),
borderRadius:
BorderRadius.circular(
50,

View File

@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
@@ -12,9 +13,11 @@ import '../provider/current_user_provider.dart';
import '../screen/login/logout_provider.dart';
class CustomDrawer extends HookConsumerWidget {
// final String userCompany;
const CustomDrawer({
super.key,
});
Key? key,
// required this.userCompany,
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
@@ -22,6 +25,26 @@ class CustomDrawer extends HookConsumerWidget {
final isLoading = useState(false);
final errorMessage = useState("");
final successMessage = useState("");
final M_CompanyName = useState("-");
Future<String> getCompanyName() async {
final shared = await SharedPreferences.getInstance();
String M_CompanyName = "-";
if (shared != null) {
final bearerString = shared.get(Constant.bearerName).toString();
final xmodel = jsonDecode(bearerString);
if (xmodel != null) {
M_CompanyName = xmodel["model"]["M_CompanyName"];
}
}
if (M_CompanyName == "0") {
// throw BaseRepositoryException(message: 'Invalid Company ID');
}
return M_CompanyName;
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
@@ -34,6 +57,7 @@ class CustomDrawer extends HookConsumerWidget {
// Navigator.popAndPushNamed(context, loginRoute);
return;
}
M_CompanyName.value = await getCompanyName();
});
return () {};
}, []);
@@ -56,7 +80,6 @@ class CustomDrawer extends HookConsumerWidget {
shared.remove(bearerString);
shared.clear();
// Navigator.popAndPushNamed(context, loginRoute);
Navigator.of(context)
.pushNamedAndRemoveUntil(loginRoute, (route) => false);
}
@@ -69,152 +92,249 @@ class CustomDrawer extends HookConsumerWidget {
final currentMenu = ref.read(currentPageProvider);
return Drawer(
child: ListView(
// padding: EdgeInsets.only(
// top: Constant.getActualYPhone(context: context, y: 10),
// ),
children: [
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(0))),
child: Container(
child: ListView(
// padding: EdgeInsets.only(
// top: Constant.getActualYPhone(context: context, y: 10),
// ),
children: [
Container(
// decoration: BoxDecoration(
// border: Border(bottom: BorderSide(color: Colors.transparent)) // <--- use the global theme to change the dividerColor property
// ),
child: Image(
image: AssetImage('images/logo_sismedika_landscape.png')),
),
child: Text(
'Drawer Header',
style: TextStyle(
color: Colors.white,
fontSize: 24,
SizedBox(
height: Constant.getActualYPhone(context: context, y: 8),
),
Padding(
padding: EdgeInsets.only(
top: Constant.getActualYPhone(context: context, y: 10),
bottom: Constant.getActualYPhone(context: context, y: 10),
right: Constant.getActualXPhone(context: context, x: 24),
left: Constant.getActualXPhone(context: context, x: 24),
),
child: Container(
width: Constant.getActualXPhone(context: context, x: 300),
),
),
),
ListTile(
title: Text(
'Home',
style: TextStyle(
// Expanded(
// child: Padding(
// padding: EdgeInsets.only(
// left: Constant.getActualXPhone(context: context, x: 24),
// right: Constant.getActualXPhone(context: context, x: 71),
// ),
// child: Container(
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(6),
// color: Constant.textGrey.withOpacity(0.16),
// ),
// child: Padding(
// padding: EdgeInsets.only(
// left: Constant.getActualXPhone(context: context, x: 8),
// right: Constant.getActualXPhone(context: context, x: 8),
// ),
// child: Text(
// M_CompanyName.value,
// style: Constant.body3(context: context).copyWith(
// fontWeight: FontWeight.w700,
// color: Constant.textGreyv2,
// backgroundColor: Constant.textGrey.withOpacity(0.16),
// ),
// ),
// ),
// ),
// ),
// ),
Chip(
backgroundColor: Constant.textGrey.withOpacity(0.16),
label: Text(
M_CompanyName.value,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Constant.textGreyv2,
),
),
),
ListTile(
leading: Icon(
Icons.home,
color: (currentMenu == 0)
? Constant.textWhite
: Constant.textBlack,
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
title: Text(
'Home',
style: TextStyle(
color: (currentMenu == 0)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
),
// tileColor: (currentMenu == 0)
// ? Constant.pcBtnBackgroundColor
// : Colors.transparent,
onTap: () {
// Handle navigation to Home screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 0);
Navigator.pushNamed(context, homeRoute);
},
),
tileColor: (currentMenu == 0)
? Constant.pcBtnBackgroundColor
: Colors.transparent,
onTap: () {
// Handle navigation to Home screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 0);
Navigator.pushNamed(context, homeRoute);
},
),
ListTile(
title: Text(
'Transaksi',
style: TextStyle(
ListTile(
leading: Icon(
Icons.money,
color: (currentMenu == 1)
? Constant.textWhite
: Constant.textBlack,
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
title: Text(
'Transaksi',
style: TextStyle(
color: (currentMenu == 1)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
),
// tileColor: (currentMenu == 1)
// ? Constant.pcBtnBackgroundColor
// : Colors.transparent,
onTap: () {
// Handle navigation to Transaksi screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 1);
Navigator.pushNamed(context, transaksiRoute);
},
),
tileColor: (currentMenu == 1)
? Constant.pcBtnBackgroundColor
: Colors.transparent,
onTap: () {
// Handle navigation to Transaksi screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 1);
Navigator.pushNamed(context, transaksiRoute);
},
),
ListTile(
title: Text(
'History Transaksi',
style: TextStyle(
ListTile(
leading: Icon(
Icons.history,
color: (currentMenu == 2)
? Constant.textWhite
: Constant.textBlack,
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
title: Text(
'History Transaksi',
style: TextStyle(
color: (currentMenu == 2)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
),
// tileColor: (currentMenu == 2)
// ? Constant.pcBtnBackgroundColor
// : Colors.transparent,
onTap: () {
// Handle navigation to User screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 2);
Navigator.pushNamed(context, historyTransaksiRoute);
},
),
tileColor: (currentMenu == 2)
? Constant.pcBtnBackgroundColor
: Colors.transparent,
onTap: () {
// Handle navigation to User screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 2);
Navigator.pushNamed(context, historyTransaksiRoute);
},
),
ListTile(
title: Text(
'Report',
style: TextStyle(
ListTile(
leading: Icon(
Icons.feed,
color: (currentMenu == 3)
? Constant.textWhite
: Constant.textBlack,
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
title: Text(
'Report',
style: TextStyle(
color: (currentMenu == 3)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
),
// tileColor: (currentMenu == 3)
// ? Constant.pcBtnBackgroundColor
// : Colors.transparent,
onTap: () {
// Handle navigation to Transaksi screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 3);
Navigator.pushNamed(context, reportRoute);
},
),
tileColor: (currentMenu == 3)
? Constant.pcBtnBackgroundColor
: Colors.transparent,
onTap: () {
// Handle navigation to Transaksi screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 3);
Navigator.pushNamed(context, reportRoute);
},
),
// ListTile(
// title: Text(
// 'User',
// style: TextStyle(
// color: (currentMenu == 4)
// ? Constant.textWhite
// : Constant.textBlack,
// ),
// ),
// tileColor: (currentMenu == 4)
// ? Constant.pcBtnBackgroundColor
// : Colors.transparent,
// onTap: () {
// // Handle navigation to User screen
// Navigator.pop(context);
// ref.read(currentPageProvider.state).update((state) => 4);
// Navigator.pushNamed(context, userRoute);
// },
// ),
// ListTile(
// title: Text(
// 'Change Company',
// style: TextStyle(
// color: (currentMenu == 5)
// ? Constant.textWhite
// : Constant.textBlack,
// ),
// ),
// tileColor: (currentMenu == 5)
// ? Constant.pcBtnBackgroundColor
// : Colors.transparent,
// onTap: () {
// // Handle navigation to User screen
// Navigator.pop(context);
// ref.read(currentPageProvider.state).update((state) => 5);
// Navigator.pushNamed(context, changeCompanyRoute);
// },
// ),
ListTile(
title: Text(
'Logout',
// style: TextStyle(color: Constant.textWhite),
// ListTile(
// title: Text(
// 'User',
// style: TextStyle(
// color: (currentMenu == 4)
// ? Constant.textWhite
// : Constant.textBlack,
// ),
// ),
// tileColor: (currentMenu == 4)
// ? Constant.pcBtnBackgroundColor
// : Colors.transparent,
// onTap: () {
// // Handle navigation to User screen
// Navigator.pop(context);
// ref.read(currentPageProvider.state).update((state) => 4);
// Navigator.pushNamed(context, userRoute);
// },
// ),
// ListTile(
// title: Text(
// 'Change Company',
// style: TextStyle(
// color: (currentMenu == 5)
// ? Constant.textWhite
// : Constant.textBlack,
// ),
// ),
// tileColor: (currentMenu == 5)
// ? Constant.pcBtnBackgroundColor
// : Colors.transparent,
// onTap: () {
// // Handle navigation to User screen
// Navigator.pop(context);
// ref.read(currentPageProvider.state).update((state) => 5);
// Navigator.pushNamed(context, changeCompanyRoute);
// },
// ),
ListTile(
leading: Icon(
Icons.logout,
color: Constant.textGreyv2,
),
title: Text(
'Logout',
style: TextStyle(color: Constant.textGreyv2),
),
onTap: () {
// di set ke 0 lagi
ref.read(currentPageProvider.state).update((state) => 0);
ref.read(logoutProvider.notifier).logout(
M_UserID: selectedUser?.model.M_UserID ?? "",
M_UserUsername: selectedUser?.model.M_UserUsername ?? "",
);
},
),
onTap: () {
// di set ke 0 lagi
ref.read(currentPageProvider.state).update((state) => 0);
ref.read(logoutProvider.notifier).logout(
M_UserID: selectedUser?.model.M_UserID ?? "",
M_UserUsername: selectedUser?.model.M_UserUsername ?? "",
);
},
),
],
Spacer(),
// Versi Aplikasi
ListTile(
title: Text(
'Versi ${Constant.version}',
style: Constant.titleH4Login(context: context)
.copyWith(color: Constant.textGrey),
),
onTap: () {},
),
],
),
),
);
}

View File

@@ -0,0 +1,221 @@
import 'dart:async';
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 '../provider/current_menu_provider.dart';
import '../provider/current_user_provider.dart';
import '../screen/login/logout_provider.dart';
class CustomDrawerV1 extends HookConsumerWidget {
const CustomDrawerV1({
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedUser = ref.read(currentUserProvider);
final isLoading = useState(false);
final errorMessage = useState("");
final successMessage = useState("");
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final userID = ref.read(currentUserProvider)?.model.M_UserID ?? "0";
if (userID == "0") {
//not login
Navigator.of(context)
.pushNamedAndRemoveUntil(loginRoute, (route) => true);
// Navigator.popAndPushNamed(context, loginRoute);
return;
}
});
return () {};
}, []);
ref.listen(logoutProvider, (prev, next) async {
if (next is LogoutStateLoading) {
isLoading.value = true;
} else if (next is LogoutStateError) {
isLoading.value = false;
errorMessage.value = next.message;
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is LogoutStateDone) {
isLoading.value = false;
final shared = await SharedPreferences.getInstance();
final bearerString = shared.get(Constant.bearerName).toString();
// print(bearerString);
if (bearerString.isNotEmpty) {
shared.remove(bearerString);
shared.clear();
// Navigator.popAndPushNamed(context, loginRoute);
Navigator.of(context)
.pushNamedAndRemoveUntil(loginRoute, (route) => false);
}
Timer(const Duration(seconds: 3), () async {
successMessage.value = "";
});
}
});
final currentMenu = ref.read(currentPageProvider);
return Drawer(
child: ListView(
// padding: EdgeInsets.only(
// top: Constant.getActualYPhone(context: context, y: 10),
// ),
children: [
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(
'Drawer Header',
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
),
),
ListTile(
title: Text(
'Home',
style: TextStyle(
color: (currentMenu == 0)
? Constant.textWhite
: Constant.textBlack,
),
),
tileColor: (currentMenu == 0)
? Constant.pcBtnBackgroundColor
: Colors.transparent,
onTap: () {
// Handle navigation to Home screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 0);
Navigator.pushNamed(context, homeRoute);
},
),
ListTile(
title: Text(
'Transaksi',
style: TextStyle(
color: (currentMenu == 1)
? Constant.textWhite
: Constant.textBlack,
),
),
tileColor: (currentMenu == 1)
? Constant.pcBtnBackgroundColor
: Colors.transparent,
onTap: () {
// Handle navigation to Transaksi screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 1);
Navigator.pushNamed(context, transaksiRoute);
},
),
ListTile(
title: Text(
'History Transaksi',
style: TextStyle(
color: (currentMenu == 2)
? Constant.textWhite
: Constant.textBlack,
),
),
tileColor: (currentMenu == 2)
? Constant.pcBtnBackgroundColor
: Colors.transparent,
onTap: () {
// Handle navigation to User screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 2);
Navigator.pushNamed(context, historyTransaksiRoute);
},
),
ListTile(
title: Text(
'Report',
style: TextStyle(
color: (currentMenu == 3)
? Constant.textWhite
: Constant.textBlack,
),
),
tileColor: (currentMenu == 3)
? Constant.pcBtnBackgroundColor
: Colors.transparent,
onTap: () {
// Handle navigation to Transaksi screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 3);
Navigator.pushNamed(context, reportRoute);
},
),
// ListTile(
// title: Text(
// 'User',
// style: TextStyle(
// color: (currentMenu == 4)
// ? Constant.textWhite
// : Constant.textBlack,
// ),
// ),
// tileColor: (currentMenu == 4)
// ? Constant.pcBtnBackgroundColor
// : Colors.transparent,
// onTap: () {
// // Handle navigation to User screen
// Navigator.pop(context);
// ref.read(currentPageProvider.state).update((state) => 4);
// Navigator.pushNamed(context, userRoute);
// },
// ),
// ListTile(
// title: Text(
// 'Change Company',
// style: TextStyle(
// color: (currentMenu == 5)
// ? Constant.textWhite
// : Constant.textBlack,
// ),
// ),
// tileColor: (currentMenu == 5)
// ? Constant.pcBtnBackgroundColor
// : Colors.transparent,
// onTap: () {
// // Handle navigation to User screen
// Navigator.pop(context);
// ref.read(currentPageProvider.state).update((state) => 5);
// Navigator.pushNamed(context, changeCompanyRoute);
// },
// ),
ListTile(
title: Text(
'Logout',
// style: TextStyle(color: Constant.textWhite),
),
onTap: () {
// di set ke 0 lagi
ref.read(currentPageProvider.state).update((state) => 0);
ref.read(logoutProvider.notifier).logout(
M_UserID: selectedUser?.model.M_UserID ?? "",
M_UserUsername: selectedUser?.model.M_UserUsername ?? "",
);
},
),
],
),
);
}
}

View File

@@ -3,6 +3,7 @@ import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:intl/intl.dart';
import '../app/constant.dart';
@@ -12,6 +13,7 @@ class HistoryRowAtasWidget extends HookConsumerWidget {
final String amount;
final String tipe;
final String tglTransaksi;
// final ValueNotifier<bool> searchHistoryIsLoading;
const HistoryRowAtasWidget({
Key? key,
@@ -20,13 +22,50 @@ class HistoryRowAtasWidget extends HookConsumerWidget {
required this.amount,
required this.tipe,
required this.tglTransaksi,
// required this.searchHistoryIsLoading,
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
// check file exist
Future<Widget> checkFileExistence(String fileUrl) async {
// Future<Widget> checkFileExistence(String fileUrl) async {
// try {
// final dio = Dio();
// final response = await dio.head(fileUrl);
// if (response.statusCode == 200) {
// return SvgPicture.network(
// fileUrl,
// semanticsLabel: 'Icon pizza',
// // placeholderBuilder: (BuildContext context) => Container(
// // padding: const EdgeInsets.all(30.0),
// // child: const CircularProgressIndicator(),
// // ),
// );
// } else {
// return SvgPicture.network(
// 'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg',
// semanticsLabel: 'Icon pizza',
// // placeholderBuilder: (BuildContext context) => Container(
// // padding: const EdgeInsets.all(30.0),
// // child: const CircularProgressIndicator(),
// // ),
// );
// }
// } catch (e) {
// // print('Error checking file existence: $e');
// return SvgPicture.network(
// 'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg',
// semanticsLabel: 'Icon pizza',
// // placeholderBuilder: (BuildContext context) => Container(
// // padding: const EdgeInsets.all(30.0),
// // child: const CircularProgressIndicator(),
// // ),
// );
// }
// }
final iconProvider =
FutureProvider.family<Widget, String>((ref, fileUrl) async {
try {
final dio = Dio();
final response = await dio.head(fileUrl);
@@ -34,32 +73,130 @@ class HistoryRowAtasWidget extends HookConsumerWidget {
return SvgPicture.network(
fileUrl,
semanticsLabel: 'Icon pizza',
placeholderBuilder: (BuildContext context) => Container(
padding: const EdgeInsets.all(30.0),
child: const CircularProgressIndicator(),
),
);
} else {
return SvgPicture.network(
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg',
semanticsLabel: 'Icon pizza',
placeholderBuilder: (BuildContext context) => Container(
padding: const EdgeInsets.all(30.0),
child: const CircularProgressIndicator(),
),
);
}
} catch (e) {
// print('Error checking file existence: $e');
return SvgPicture.network(
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg',
semanticsLabel: 'Icon pizza',
placeholderBuilder: (BuildContext context) => Container(
padding: const EdgeInsets.all(30.0),
child: const CircularProgressIndicator(),
),
);
}
});
// fungsi tanggal
String formatDateString(String inputDate) {
try {
// Parsing tanggal dari string input
DateTime date = DateFormat('dd-MM-yyyy', 'id').parse(inputDate);
// Format tanggal ke '30 Des 2023'
String formattedDate = DateFormat('dd MMM yyyy', 'id').format(date);
return formattedDate;
} catch (e) {
// Tangkap kesalahan jika format tanggal tidak sesuai
print('Error parsing date: $e');
// return 'Format Tanggal Salah';
return inputDate;
}
}
Widget getIconUrl(String categoryid) {
List<Map<String, String>> iconDataList = [
{
'categoryid': '1',
'url':
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg'
},
{
'categoryid': '2',
'url':
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg'
},
{
'categoryid': '3',
'url':
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_3.svg'
},
{
'categoryid': '4',
'url':
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg'
},
{
'categoryid': '5',
'url':
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_5.svg'
},
{
'categoryid': '6',
'url':
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_6.svg'
},
{
'categoryid': '7',
'url':
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg'
},
{
'categoryid': '8',
'url':
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg'
},
{
'categoryid': '9',
'url':
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg'
},
{
'categoryid': '10',
'url':
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg'
},
{
'categoryid': '11',
'url':
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg'
},
{
'categoryid': '12',
'url':
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_12.svg'
},
{
'categoryid': '13',
'url':
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg'
},
];
String urlFix = "";
for (var i = 0; i < iconDataList.length; i++) {
if (iconDataList[i]['categoryid'] == categoryid) {
// urlFix =
// "https://devone.aplikasi.web.id/pettycash-media/icon/icon_$icon_category_id.svg";
urlFix = iconDataList[i]['url'] ??
"https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg";
}
}
if (urlFix == "") {
urlFix =
"https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg";
}
// return urlFix;
return SvgPicture.network(
urlFix,
semanticsLabel: 'Icon category',
);
}
return Row(
@@ -75,22 +212,71 @@ class HistoryRowAtasWidget extends HookConsumerWidget {
),
),
// child: Text('s'),
child: FutureBuilder<Widget>(
future: checkFileExistence('https://devone.aplikasi.web.id/pettycash-media/icon/icon_$icon_category_id.svg'),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Icon(
Icons.error,
color: Colors.red,
);
} else {
return snapshot.data ??
Container();
}
},
),
// child: FutureBuilder<Widget>(
// future: checkFileExistence(
// 'https://devone.aplikasi.web.id/pettycash-media/icon/icon_$icon_category_id.svg',
// ),
// builder: (context, snapshot) {
// // if (snapshot.connectionState == ConnectionState.waiting) {
// // // return CircularProgressIndicator();
// // return Text('');
// // } else if (snapshot.hasError) {
// // return Icon(
// // Icons.error,
// // color: Colors.red,
// // );
// // } else {
// // return snapshot.data ?? Container();
// // }
// if (snapshot.connectionState == ConnectionState.done) {
// return snapshot.data ?? Container();
// } else if (snapshot.hasError) {
// return Icon(
// Icons.error,
// color: Colors.red,
// );
// } else {
// return Text('');
// }
// },
// ),
// child: Consumer(
// builder: (context, watch, child) {
// String iconUrl =
// 'https://devone.aplikasi.web.id/pettycash-media/icon/icon_$icon_category_id.svg';
// final iconAsyncValue = ref.read(
// iconProvider(
// iconUrl,
// ),
// );
// return iconAsyncValue.when(
// loading: () {
// print('loading iconurl : $iconUrl');
// return CircularProgressIndicator();
// },
// error: (error, stackTrace) {
// print('error iconurl : $iconUrl');
// return Icon(
// Icons.error,
// color: Colors.red,
// );
// },
// data: (iconWidget) {
// print('data iconurl : $iconUrl');
// return iconWidget ?? Container();
// }
// );
// },
// ),
// child: SvgPicture.network(
// 'https://devone.aplikasi.web.id/pettycash-media/icon/icon_$icon_category_id.svg',
// semanticsLabel: 'Icon pizza',
// ),
child: getIconUrl(icon_category_id),
),
// tengah
@@ -138,21 +324,23 @@ class HistoryRowAtasWidget extends HookConsumerWidget {
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
// width: Constant.getActualXPhone(context: context, x: 32),
height: Constant.getActualYPhone(context: context, y: 19),
width: Constant.getActualXPhone(context: context, x: 80),
height: Constant.getActualYPhone(context: context, y: 24),
decoration: BoxDecoration(
color: Constant.bgIconHistory,
borderRadius: BorderRadius.all(
Radius.circular(6.0),
),
),
child: Padding(
padding: EdgeInsets.all(2.0),
child: Align(
alignment: Alignment.center,
child: Text(
tipe,
style: Constant.body1_600(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.pcBtnBackgroundColor),
fontWeight: FontWeight.w600,
color: Constant.pcBtnBackgroundColor,
fontSize: 14,
),
),
),
),
@@ -163,7 +351,7 @@ class HistoryRowAtasWidget extends HookConsumerWidget {
),
),
Text(
tglTransaksi,
formatDateString(tglTransaksi),
style: Constant.body1_600(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textGreyv2),
),

View File

@@ -1,68 +1,68 @@
{
"images" : [
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "app_icon_16.png",
"scale" : "1x"
"info": {
"version": 1,
"author": "xcode"
},
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "app_icon_32.png",
"scale" : "2x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "app_icon_32.png",
"scale" : "1x"
},
{
"size" : "32x32",
"idiom" : "mac",
"filename" : "app_icon_64.png",
"scale" : "2x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "app_icon_128.png",
"scale" : "1x"
},
{
"size" : "128x128",
"idiom" : "mac",
"filename" : "app_icon_256.png",
"scale" : "2x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "app_icon_256.png",
"scale" : "1x"
},
{
"size" : "256x256",
"idiom" : "mac",
"filename" : "app_icon_512.png",
"scale" : "2x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "app_icon_512.png",
"scale" : "1x"
},
{
"size" : "512x512",
"idiom" : "mac",
"filename" : "app_icon_1024.png",
"scale" : "2x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
"images": [
{
"size": "16x16",
"idiom": "mac",
"filename": "app_icon_16.png",
"scale": "1x"
},
{
"size": "16x16",
"idiom": "mac",
"filename": "app_icon_32.png",
"scale": "2x"
},
{
"size": "32x32",
"idiom": "mac",
"filename": "app_icon_32.png",
"scale": "1x"
},
{
"size": "32x32",
"idiom": "mac",
"filename": "app_icon_64.png",
"scale": "2x"
},
{
"size": "128x128",
"idiom": "mac",
"filename": "app_icon_128.png",
"scale": "1x"
},
{
"size": "128x128",
"idiom": "mac",
"filename": "app_icon_256.png",
"scale": "2x"
},
{
"size": "256x256",
"idiom": "mac",
"filename": "app_icon_256.png",
"scale": "1x"
},
{
"size": "256x256",
"idiom": "mac",
"filename": "app_icon_512.png",
"scale": "2x"
},
{
"size": "512x512",
"idiom": "mac",
"filename": "app_icon_512.png",
"scale": "1x"
},
{
"size": "512x512",
"idiom": "mac",
"filename": "app_icon_1024.png",
"scale": "2x"
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 520 B

After

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@@ -1,6 +1,14 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
archive:
dependency: transitive
description:
name: archive
sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d"
url: "https://pub.dev"
source: hosted
version: "3.4.10"
args:
dependency: transitive
description:
@@ -49,6 +57,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
url: "https://pub.dev"
source: hosted
version: "2.0.3"
cli_util:
dependency: transitive
description:
name: cli_util
sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19
url: "https://pub.dev"
source: hosted
version: "0.4.1"
clock:
dependency: transitive
description:
@@ -166,6 +190,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.18.6"
flutter_launcher_icons:
dependency: "direct main"
description:
name: flutter_launcher_icons
sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea"
url: "https://pub.dev"
source: hosted
version: "0.13.1"
flutter_lints:
dependency: "direct dev"
description:
@@ -232,6 +264,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.2"
image:
dependency: transitive
description:
name: image
sha256: "004a2e90ce080f8627b5a04aecb4cdfac87d2c3f3b520aa291260be5a32c033d"
url: "https://pub.dev"
source: hosted
version: "4.1.4"
intl:
dependency: "direct main"
description:
@@ -248,6 +288,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.6.7"
json_annotation:
dependency: transitive
description:
name: json_annotation
sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
url: "https://pub.dev"
source: hosted
version: "4.8.1"
lints:
dependency: transitive
description:
@@ -392,6 +440,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.8"
pointycastle:
dependency: transitive
description:
name: pointycastle
sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29"
url: "https://pub.dev"
source: hosted
version: "3.7.4"
riverpod:
dependency: transitive
description:
@@ -653,6 +709,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.3.0"
yaml:
dependency: transitive
description:
name: yaml
sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.0.6 <4.0.0"
flutter: ">=3.10.0"

View File

@@ -1,4 +1,5 @@
name: app_petty_cash
# name: PettyCash
description: A new Flutter project.
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
@@ -51,6 +52,7 @@ dependencies:
top_snackbar_flutter: ^3.1.0
url_launcher: ^6.1.13
flutter_svg: ^2.0.9
flutter_launcher_icons: ^0.13.1
dev_dependencies:
flutter_test:
@@ -66,6 +68,24 @@ dev_dependencies:
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
flutter_launcher_icons:
android: "launcher_icon"
ios: true
image_path: "images/logo_apk_v2.png"
min_sdk_android: 21 # android min sdk min:16, default 21
web:
generate: true
image_path: "images/logo_apk_v2.png"
background_color: "#00FFFFFF"
theme_color: "#00FFFFFF"
windows:
generate: true
image_path: "images/logo_apk_v2.png"
icon_size: 48 # min:48, max:256, default: 48
macos:
generate: true
image_path: "images/logo_apk_v2.png"
# The following section is specific to Flutter packages.
flutter:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 917 B

After

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 71 KiB

View File

@@ -3,8 +3,8 @@
"short_name": "app_petty_cash",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"background_color": "#00FFFFFF",
"theme_color": "#00FFFFFF",
"description": "A new Flutter project.",
"orientation": "portrait-primary",
"prefer_related_applications": false,
@@ -32,4 +32,4 @@
"purpose": "maskable"
}
]
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB