9 Commits

103 changed files with 925 additions and 6374 deletions

2
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,2 @@
{
}

View File

@@ -1,14 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:label="PettyCash"
android:label="app_petty_cash"
android:name="${applicationName}"
android:icon="@mipmap/launcher_icon"
android:usesCleartextTraffic="true"
android:requestLegacyExternalStorage="true"
>
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
@@ -16,9 +11,7 @@
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
android:screenOrientation="portrait"
>
android:windowSoftInputMode="adjustResize">
<!-- 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.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<external-path name="external_storage_directory" path="." />
<external-path name="external_files" path="."/>
</resources>

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,30 +0,0 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="32" height="32" fill="#F5F5F5"/>
<path d="M-2213 -1590C-2213 -1591.1 -2212.1 -1592 -2211 -1592H1326C1327.1 -1592 1328 -1591.1 1328 -1590V2084C1328 2085.1 1327.1 2086 1326 2086H-2211C-2212.1 2086 -2213 2085.1 -2213 2084V-1590Z" fill="#2C2C2D"/>
<path d="M-2211 -1591H1326V-1593H-2211V-1591ZM1327 -1590V2084H1329V-1590H1327ZM1326 2085H-2211V2087H1326V2085ZM-2212 2084V-1590H-2214V2084H-2212ZM-2211 2085C-2211.55 2085 -2212 2084.55 -2212 2084H-2214C-2214 2085.66 -2212.66 2087 -2211 2087V2085ZM1327 2084C1327 2084.55 1326.55 2085 1326 2085V2087C1327.66 2087 1329 2085.66 1329 2084H1327ZM1326 -1591C1326.55 -1591 1327 -1590.55 1327 -1590H1329C1329 -1591.66 1327.66 -1593 1326 -1593V-1591ZM-2211 -1593C-2212.66 -1593 -2214 -1591.66 -2214 -1590H-2212C-2212 -1590.55 -2211.55 -1591 -2211 -1591V-1593Z" fill="black" fill-opacity="0.1"/>
<rect width="390" height="1084" transform="translate(-44 -414)" fill="white"/>
<g filter="url(#filter0_dd_11_141)">
<rect x="-24" y="-28" width="350" height="145" rx="12" fill="white"/>
<rect x="-12" y="-12" width="56" height="56" rx="8" fill="#F15A29" fill-opacity="0.08"/>
<path d="M20 14.6666H20.0133M14.6666 20H14.68M21.3333 21.3333H21.3466M2.66663 21.3333L29.3333 29.3333L21.3333 2.66663C16.8694 3.89048 12.801 6.25514 9.52805 9.52805C6.25514 12.801 3.89048 16.8694 2.66663 21.3333Z" stroke="#F15A29" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M7.61328 22.8133C8.69531 19.2219 10.6497 15.9542 13.3019 13.3019C15.9542 10.6497 19.2219 8.69531 22.8133 7.61328" stroke="#F15A29" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<filter id="filter0_dd_11_141" x="-44" y="-36" width="390" height="185" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feMorphology radius="4" operator="erode" in="SourceAlpha" result="effect1_dropShadow_11_141"/>
<feOffset dy="12"/>
<feGaussianBlur stdDeviation="12"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.568627 0 0 0 0 0.619608 0 0 0 0 0.670588 0 0 0 0.12 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_11_141"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset/>
<feGaussianBlur stdDeviation="1"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0.568627 0 0 0 0 0.619608 0 0 0 0 0.670588 0 0 0 0.2 0"/>
<feBlend mode="normal" in2="effect1_dropShadow_11_141" result="effect2_dropShadow_11_141"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect2_dropShadow_11_141" result="shape"/>
</filter>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -1,5 +0,0 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M28 16V9.33333H6.66667C5.95942 9.33333 5.28115 9.05238 4.78105 8.55229C4.28095 8.05219 4 7.37391 4 6.66667C4 5.95942 4.28095 5.28115 4.78105 4.78105C5.28115 4.28095 5.95942 4 6.66667 4H25.3333V9.33333" stroke="#F15A29" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4 6.66675V25.3334C4 26.0407 4.28095 26.7189 4.78105 27.219C5.28115 27.7191 5.95942 28.0001 6.66667 28.0001H28V21.3334" stroke="#F15A29" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M24 16C23.2928 16 22.6145 16.281 22.1144 16.781C21.6143 17.2811 21.3334 17.9594 21.3334 18.6667C21.3334 19.3739 21.6143 20.0522 22.1144 20.5523C22.6145 21.0524 23.2928 21.3333 24 21.3333H29.3334V16H24Z" stroke="#F15A29" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 904 B

View File

@@ -1,5 +0,0 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20.0001 2.66663H12.0001C11.2637 2.66663 10.6667 3.26358 10.6667 3.99996V6.66663C10.6667 7.40301 11.2637 7.99996 12.0001 7.99996H20.0001C20.7365 7.99996 21.3334 7.40301 21.3334 6.66663V3.99996C21.3334 3.26358 20.7365 2.66663 20.0001 2.66663Z" stroke="#F15A29" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M13.8667 16.8C14.3971 16.2696 15.1166 15.9716 15.8667 15.9716C16.6169 15.9716 17.3363 16.2696 17.8667 16.8C18.3971 17.3304 18.6951 18.0498 18.6951 18.8C18.6951 19.5501 18.3971 20.2696 17.8667 20.8L10.6667 28L5.33337 29.3333L6.66671 24L13.8667 16.8Z" stroke="#F15A29" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M21.3334 5.33325H24C24.7073 5.33325 25.3856 5.6142 25.8857 6.1143C26.3858 6.6144 26.6667 7.29267 26.6667 7.99992V26.6666C26.6667 27.3738 26.3858 28.0521 25.8857 28.5522C25.3856 29.0523 24.7073 29.3333 24 29.3333H16.6667M5.33337 17.9999V7.99992C5.33337 7.29267 5.61433 6.6144 6.11442 6.1143C6.61452 5.6142 7.2928 5.33325 8.00004 5.33325H10.6667" stroke="#F15A29" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 716 B

View File

@@ -1,4 +0,0 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M26.6666 18.6666H5.33329C3.86053 18.6666 2.66663 19.8605 2.66663 21.3333V26.6666C2.66663 28.1394 3.86053 29.3333 5.33329 29.3333H26.6666C28.1394 29.3333 29.3333 28.1394 29.3333 26.6666V21.3333C29.3333 19.8605 28.1394 18.6666 26.6666 18.6666Z" stroke="#F15A29" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M8.01333 24H8M13.3467 24H13.3333M20 13.3333V18.6666M23.7867 9.55997C23.2913 9.0641 22.7031 8.67072 22.0557 8.40232C21.4082 8.13392 20.7142 7.99578 20.0133 7.99578C19.3125 7.99578 18.6184 8.13392 17.971 8.40232C17.3235 8.67072 16.7353 9.0641 16.24 9.55997M27.5467 5.78664C25.5465 3.78776 22.8344 2.66492 20.0067 2.66492C17.1789 2.66492 14.4669 3.78776 12.4667 5.78664" stroke="#F15A29" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 898 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 B

View File

@@ -1,3 +0,0 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M2.66663 29.3333L6.66663 25.3333M9.99996 18L13.3333 14.6667M14 22L17.3333 18.6667M24 4L18.6666 9.33333H26.6666L21.3333 14.6667M8.39996 27.0667C8.69725 27.365 9.05051 27.6017 9.43947 27.7632C9.82844 27.9247 10.2455 28.0079 10.6666 28.0079C11.0878 28.0079 11.5048 27.9247 11.8938 27.7632C12.2827 27.6017 12.636 27.365 12.9333 27.0667L16 24L7.99996 16L4.93329 19.0667C4.63497 19.364 4.39826 19.7172 4.23675 20.1062C4.07524 20.4951 3.9921 20.9122 3.9921 21.3333C3.9921 21.7545 4.07524 22.1715 4.23675 22.5605C4.39826 22.9495 4.63497 23.3027 4.93329 23.6L8.39996 27.0667Z" stroke="#F15A29" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 763 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 880 B

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 762 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -10,21 +10,13 @@ class Constant {
static double designWidthPhone = 390;
static String bearerName = "petty-cash";
// static String version = "1.00";
// NOTE VERSI HARUS SAMA DENGAN PUBSPEC.YAML
static String version = "1.2.0";
static String version = "1.00";
// static String baseUrl = "https://devregonline.pramita.co.id/one-api/xdoc/";
// tester devbandungraya
static String baseUrlDevoneReport = "devone.aplikasi.web.id";
static String baseUrlDevone =
"https://devone.aplikasi.web.id/one-api-pettycash/pettycash/";
// "http://devone.aplikasi.web.id/one-api-pettycash/pettycash/";
static String baseUrlFile =
"https://devone.aplikasi.web.id/pettycash-media/attachment/";
"http://devone.aplikasi.web.id/one-api-pettycash/pettycash/";
// static String baseUrl_appdoctor =
// "http://devbandungraya.aplikasi.web.id/one-api/app_doctor/";
@@ -268,18 +260,6 @@ class Constant {
// background upload file
static Color bgUploadFile = Color.fromRGBO(207, 207, 207, 0.20);
// background icon history
static Color bgIconHistory = Color.fromRGBO(241, 90, 41, 0.16);
// background chip confirmed
static Color bgChipConfirmed = Color(0xffe8f4f5);
static Color bgTextChipConfirmed = Color(0xff32827C);
// delete text
static Color bgTextDelete = Color(0xffFF4842);
static Color bgTextChipDelete = Color.fromRGBO(255, 72, 66, 0.12);
//typoGraphy
static TextStyle titleH1Login({required BuildContext context}) {
return TextStyle(
@@ -288,13 +268,6 @@ 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),
@@ -366,13 +339,6 @@ 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

@@ -1,11 +1,8 @@
import '../screen/change_company/change_company.dart';
import 'package:app_petty_cash/screen/camera/coba_camera.dart';
import 'package:app_petty_cash/screen/camera/example.dart';
import 'package:flutter/material.dart';
import '../screen/change_password/change_password_screen.dart';
import '../screen/home/home_screen.dart';
import '../screen/transaksi/history_transaksi_screen.dart';
import '../screen/transaksi/transaksi_screen.dart';
import '../screen/login/login_screen.dart';
import '../screen/splash/splash_screen.dart';
@@ -20,32 +17,14 @@ const homeRoute = "/homeRoute";
const transaksiRoute = "/transaksiRoute";
const userRoute = "/userRoute";
const reportRoute = "/reportRoute";
const changeCompanyRoute = "/changeCompanyRoute";
const historyTransaksiRoute = "/historyTransaksiRoute";
const cameraExampleRoute = "/cameraExampleRoute";
const cobaCameraRoute = "/cobaCameraRoute";
// test screen
const testFilePickerRoute = "/testFilePickerRoute";
const changePasswordRoute = "/changePasswordRoute";
class AppRoute {
static Route<dynamic> generateRoute(RouteSettings settings) {
// change password
if (settings.name == changePasswordRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0,
padding: EdgeInsets.all(0),
),
child: ChangePasswordScreen(),
);
});
}
// splash screen
if (settings.name == splashScreen) {
return MaterialPageRoute(builder: (context) {
@@ -59,32 +38,6 @@ class AppRoute {
});
}
// change Company
if (settings.name == changeCompanyRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0,
padding: EdgeInsets.all(0),
),
child: ChangeCompanyScreen(),
);
});
}
// history transaksi
if (settings.name == historyTransaksiRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0,
padding: EdgeInsets.all(0),
),
child: HistoryTransaksiScreen(),
);
});
}
// report screen
if (settings.name == reportRoute) {
return MaterialPageRoute(builder: (context) {

View File

@@ -2,15 +2,10 @@ 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
@@ -43,8 +38,8 @@ class MyApp extends StatelessWidget {
},
),
debugShowCheckedModeBanner: false,
// initialRoute: loginRoute,
initialRoute: splashScreen,
initialRoute: loginRoute,
// initialRoute: splashScreen,
// initialRoute: transaksiRoute,
// initialRoute: reportRoute,
// initialRoute: testFilePickerRoute,

View File

@@ -25,8 +25,8 @@ class AuthDoctorModel {
late String M_UserID;
late String M_UserUsername;
late String M_UserEmail;
late String M_CompanyID;
late String M_CompanyName;
// late String M_UserM_DoctorCode;
// late String M_UserM_DoctorID;
// late String M_UserM_StaffID;
// late String M_UserM_MouID;
late String ip;
@@ -39,8 +39,8 @@ class AuthDoctorModel {
required this.M_UserID,
required this.M_UserUsername,
required this.M_UserEmail,
required this.M_CompanyID,
required this.M_CompanyName,
// required this.M_UserM_DoctorCode,
// required this.M_UserM_DoctorID,
// this.M_UserM_StaffID = "",
// this.M_UserM_MouID = "",
this.ip = "",
@@ -51,8 +51,8 @@ class AuthDoctorModel {
M_UserID = json['M_UserID'].toString();
M_UserUsername = json['M_UserUsername'].toString();
M_UserEmail = json['M_UserEmail'].toString();
M_CompanyID = json['M_CompanyID'].toString();
M_CompanyName = json['M_CompanyName'].toString();
// M_UserM_DoctorCode = json['M_UserM_DoctorCode'].toString();
// M_UserM_DoctorID = json['M_UserM_DoctorID'].toString();
// M_UserM_StaffID = json['M_UserM_StaffID'].toString();
// M_UserM_MouID = json['M_UserM_MouID'].toString();
ip = json['ip'].toString();
@@ -64,8 +64,8 @@ class AuthDoctorModel {
data['M_UserID'] = M_UserID;
data['M_UserUsername'] = M_UserUsername;
data['M_UserEmail'] = M_UserEmail;
data['M_CompanyID'] = M_CompanyID;
data['M_CompanyName'] = M_CompanyName;
// data['M_UserM_DoctorCode'] = M_UserM_DoctorCode;
// data['M_UserM_DoctorID'] = M_UserM_DoctorID;
// data['M_UserM_StaffID'] = M_UserM_StaffID;
// data['M_UserM_MouID'] = M_UserM_MouID;
data['ip'] = ip;

View File

@@ -1,21 +0,0 @@
class CompanyModel {
String? companyid;
String? companyname;
String? mUserDefaultCompany;
CompanyModel({this.companyid, this.companyname, this.mUserDefaultCompany});
CompanyModel.fromJson(Map<String, dynamic> json) {
companyid = json['companyid'];
companyname = json['companyname'];
mUserDefaultCompany = json['M_UserDefaultCompany'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['companyid'] = this.companyid;
data['companyname'] = this.companyname;
data['M_UserDefaultCompany'] = this.mUserDefaultCompany;
return data;
}
}

View File

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

View File

@@ -1,69 +0,0 @@
class HistoryTransaksiModel {
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;
String? tanggalcreated;
HistoryTransaksiModel(
{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,
this.tanggalcreated
});
HistoryTransaksiModel.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'];
tanggalcreated = json['tanggalcreated'];
}
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;
data['tanggalcreated'] = this.tanggalcreated;
return data;
}
}

View File

@@ -1,21 +0,0 @@
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

@@ -1,69 +0,0 @@
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;
String? tanggalcreated;
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,
this.tanggalcreated,
});
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'];
tanggalcreated = json['tanggalcreated'];
}
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;
data['tanggalcreated'] = this.tanggalcreated;
return data;
}
}

View File

@@ -1,11 +0,0 @@
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

@@ -1,9 +0,0 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../model/history_total_model.dart';
final currentHistoryTotalProvider = StateProvider<HistoryTotalModel>(
((ref) => HistoryTotalModel(
totalAll: "0",
)),
);

View File

@@ -1,7 +1,3 @@
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import '../app/constant.dart';
import '../model/auth_model.dart';
import 'base_repository.dart';
@@ -23,8 +19,6 @@ class AuthRepository extends BaseRepository {
// "doctor_id": "2891",
// "password": "3"
};
print(param);
// final service = "${Constant.baseUrlDevone}xauth/login";
final service = "${Constant.baseUrlDevone}auth/login";
print('url login $service');
@@ -88,35 +82,7 @@ class AuthRepository extends BaseRepository {
// model: AuthDoctorModel.fromJson(resp["data"]["user"]),
// );
// return result;
if (resp["status"] == "OK") {
return resp['message'];
} else {
return resp['message'];
}
}
Future<String> changePassword({
required String userID,
required String token,
required String tokenx,
required String oldPassword,
required String newPassword,
required String confirmPassword,
}) async {
final param = {
"tokenx": tokenx,
"token": token,
"M_UserID": userID,
"old_password": oldPassword,
"new_password": newPassword,
"confirm_password": confirmPassword
};
final service = "${Constant.baseUrlDevone}auth/change_password";
final resp = await post(param: param, service: service, token: token);
if (resp["status"] == "OK") {
return resp['message'];
} else {

View File

@@ -2,33 +2,11 @@ import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../app/constant.dart';
abstract class BaseRepository {
final Dio dio;
BaseRepository({required this.dio});
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;
}
Future<Map<String, dynamic>> post({
required Map<String, dynamic> param,
required String service,

View File

@@ -1,32 +0,0 @@
import 'dart:convert';
import 'package:app_petty_cash/model/company_model.dart';
import 'package:app_petty_cash/model/list_type_model.dart';
import '../app/constant.dart';
import '../model/history_transaksi_model.dart';
import '../model/list_category_model.dart';
import 'base_repository.dart';
class CompanyRepository extends BaseRepository {
CompanyRepository({required super.dio});
// list company
Future<List<CompanyModel>> getListCompany({required String userID}) async {
// https: //devone.aplikasi.web.id/one-api-pettycash/pettycash/Usercompany/list_company?M_UserID=2
final service =
"${Constant.baseUrlDevone}Usercompany/list_company?M_UserID=${userID}";
final resp = await get(
service: service,
);
print("url list type : $service");
final result = List<CompanyModel>.empty(growable: true);
resp['data'].forEach((e) {
final model = CompanyModel.fromJson(e);
result.add(model);
});
return result;
}
}

View File

@@ -1,61 +0,0 @@
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,10 +1,6 @@
import 'dart:convert';
import 'package:app_petty_cash/model/list_type_model.dart';
import '../app/constant.dart';
import '../model/history_total_model.dart';
import '../model/history_transaksi_model.dart';
import '../model/list_category_model.dart';
import 'base_repository.dart';
@@ -60,69 +56,31 @@ class TransaksiRepository extends BaseRepository {
String catatan,
String userid,
String sender,
String base64file,
String fileName,
String fileSize,
String fileExtension,
String url) async {
// String paramPostInUrl = "";
Map<String, dynamic> prm = {};
String M_CompanyID = await getCompanyID();
if (tipe == "DEBIT") {
String paramPostInUrl = "";
if (tipe == "KREDIT") {
sender = "";
prm = {
'tanggal': tanggal,
'tipe': tipe,
'kategoriid': kategoriid,
'jumlah': jumlah,
'catatan': catatan,
'url': url,
'userid': userid,
'sender': sender,
'companyid': M_CompanyID,
'base64File': base64file,
'fileName': fileName,
'fileSize': fileSize,
'fileEkstension': fileExtension
};
// paramPostInUrl =
// "?tanggal=$tanggal&tipe=$tipe&kategoriid=$kategoriid&jumlah=$jumlah&catatan=$catatan&url=$url&userid=$userid&sender=$sender";
paramPostInUrl =
"?tanggal=$tanggal&tipe=$tipe&kategoriid=$kategoriid&jumlah=$jumlah&catatan=$catatan&url=$url&userid=$userid&sender=$sender";
} else {
if (tipe == "KREDIT") {
if (tipe == "DEBIT") {
kategoriid = "0";
prm = {
'tanggal': tanggal,
'tipe': tipe,
'kategoriid': kategoriid,
'jumlah': jumlah,
'catatan': catatan,
'url': url,
'userid': userid,
'sender': sender,
'companyid': M_CompanyID,
'base64File': base64file,
'fileName': fileName,
'fileSize': fileSize,
'fileEkstension': fileExtension
};
// paramPostInUrl =
// "?tanggal=$tanggal&tipe=$tipe&kategoriid=$kategoriid&jumlah=$jumlah&catatan=$catatan&url=$url&userid=$userid&sender=$sender";
paramPostInUrl =
"?tanggal=$tanggal&tipe=$tipe&kategoriid=$kategoriid&jumlah=$jumlah&catatan=$catatan&url=$url&userid=$userid&sender=$sender";
}
}
// paramPostInUrl += "&companyid=$M_CompanyID";
// /?tanggal=2023-12-29&tipe=KREDIT&kategoriid=3&jumlah=5000&catatan=Lakban%20Besar&url=&userid=1&sender=
final service = "${Constant.baseUrlDevone}transaction/addtransaction";
final resp = await post(
// param: {
// "": "",
// },
service: service,
param: prm);
final service =
"${Constant.baseUrlDevone}transaction/addtransaction/$paramPostInUrl";
final resp = await get(
// param: {
// "": "",
// },
service: service,
);
print("prm insert transaksi : ${jsonEncode(prm)}");
print("url insert transaksi : $service");
// final result = List<ListCategory>.empty(growable: true);
// resp['data'].forEach((e) {
@@ -132,118 +90,4 @@ class TransaksiRepository extends BaseRepository {
return resp['status'];
}
// list history transaksi
Future<List<HistoryTransaksiModel>> getListHistoryTransaksi(
String companyid,
String tglAwal,
String tglAkhir,
String categoryid,
) async {
final service =
"${Constant.baseUrlDevone}/history/list_transaction/?companyid=$companyid&startdate=$tglAwal&enddate=$tglAkhir&kategoriid=$categoryid";
// https://devone.aplikasi.web.id/one-api-pettycash/pettycash/history/list_transaction/?companyid=1&startdate=2023-12-01&enddate=2023-12-30&kategoriid=0
final resp = await get(
// param: {
// "": "",
// },
service: service,
);
print("url list history transaksi : $service");
final result = List<HistoryTransaksiModel>.empty(growable: true);
resp['data'].forEach((e) {
final model = HistoryTransaksiModel.fromJson(e);
result.add(model);
});
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'];
}
// confirm transaksi
Future<String> confirmTransaksi(
String id,
String userid,
) async {
final service =
"${Constant.baseUrlDevone}transaction/confirmtransaction/?id=$id&userid=$userid";
final resp = await get(
// param: {
// "": "",
// },
service: service,
);
print("url confirm 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'];
}
// total by category di history
Future<HistoryTotalModel> getHistoryTotal(
String companyid,
String tglAwal,
String tglAkhir,
String categoryid,
) async {
final service =
"${Constant.baseUrlDevone}history/list_total/?companyid=$companyid&startdate=$tglAwal&enddate=$tglAkhir&kategoriid=$categoryid";
final resp = await get(
// param: {
// "": "",
// },
service: service,
);
print("url total History Transaksi : $service");
HistoryTotalModel result = HistoryTotalModel(
totalAll: "0",
);
// print(resp['data']);
final model = HistoryTotalModel.fromJson(resp['data']);
result = model;
return result;
}
}

View File

@@ -1,209 +0,0 @@
import 'dart:convert';
import 'package:app_petty_cash/model/auth_model.dart';
import 'package:app_petty_cash/model/company_model.dart';
import 'package:app_petty_cash/screen/change_company/list_company_provider.dart';
import 'package:app_petty_cash/widget/sankbar_widget.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 '../../provider/current_user_provider.dart';
import '../../widget/custom_drawer.dart';
class ChangeCompanyScreen extends HookConsumerWidget {
const ChangeCompanyScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final listCompany = useState<List<CompanyModel>>([
CompanyModel(companyid: "1", companyname: "SAS"),
CompanyModel(companyid: "2", companyname: "SIM")
]);
final isLoading = useState(false);
final selectedCompanyID = useState("0");
final selectedCompanyName = useState("");
final auth = ref.watch(currentUserProvider);
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;
}
ref.read(ListCompanyProvider.notifier).getListCompany(userID: userID);
});
return () {};
}, []);
ref.listen(
ListCompanyProvider,
(previous, next) {
if (next is ListCompanyStateLoading) {
isLoading.value = true;
} else if (next is ListCompanyStateError) {
// print(next.message);
isLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
} else if (next is ListCompanyStateDone) {
print(jsonEncode(next.model));
// print(next.model.length);
listCompany.value = next.model;
selectedCompanyID.value = auth?.model.M_CompanyID ?? "0";
isLoading.value = false;
}
},
);
return Padding(
padding: EdgeInsets.only(
top: Constant.getActualYPhone(context: context, y: 30),
),
child: Scaffold(
appBar: AppBar(
// centerTitle: true,
title: Text(
'Change Company',
style: TextStyle(color: Constant.textWhite),
),
backgroundColor: Constant.pcBtnBackgroundColor,
iconTheme: IconThemeData(
color: Constant.textWhite,
),
),
drawer: CustomDrawer(),
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(20),
child: isLoading.value
? Container(
height: MediaQuery.of(context).size.height,
child: Center(
child: CircularProgressIndicator(),
),
)
: Column(
children: listCompany.value
.map((e) => Container(
margin: EdgeInsets.only(bottom: 20),
child: InkWell(
onTap: () async {
selectedCompanyID.value = e.companyid ?? "0";
selectedCompanyName.value =
e.companyname ?? "0";
final shared =
await SharedPreferences.getInstance();
final oldData = jsonDecode(
shared.getString(Constant.bearerName) ??
"");
print(oldData['token']);
final newModel = AuthDoctorModel.fromJson(
oldData['model']);
newModel.M_CompanyID = e.companyid ?? "0";
newModel.M_CompanyName = e.companyname ?? "";
final token = jsonEncode({
"date": oldData['date'],
"model": newModel,
"token": oldData['token']
});
final newAuthData = AuthModel(
token: oldData['token'], model: newModel);
await shared.setString(
Constant.bearerName, token);
ref.read(currentUserProvider.notifier).state =
newAuthData;
Navigator.pushNamed(context, homeRoute);
},
child: Card(
shadowColor:
selectedCompanyID.value == e.companyid
? Constant.bgIconHistory
: Colors.white,
surfaceTintColor:
selectedCompanyID.value == e.companyid
? Constant.bgIconHistory
: Colors.white,
// elevation: selectedCompanyID.value == e.companyid
// ? 0
// : 1,
elevation: 10,
color: selectedCompanyID.value == e.companyid
? Constant.bgIconHistory
: Colors.white,
child: Container(
padding: EdgeInsets.all(20),
width: MediaQuery.of(context).size.width,
child: Row(
children: [
Expanded(
flex: 1,
child: Icon(
Icons.corporate_fare,
color:
selectedCompanyID.value ==
e.companyid
? Constant.textRed
: Colors.black,
size: 30,
)),
SizedBox(
width: 10,
),
Expanded(
flex: 8,
child: Text(e.companyname ?? "",
softWrap: true,
maxLines: 3,
// overflow: ,
style: Constant.body1(
context: context)
.copyWith(
color: selectedCompanyID
.value ==
e.companyid
? Constant.textRed
: Colors.black,
fontSize: 25)),
),
],
)),
),
),
))
.toList()
// [
// Card(
// shadowColor: Colors.white,
// // surfaceTintColor: Colors.white,
// elevation: 0,
// color: Constant.bgIconHistory,
// child: Container(
// padding: EdgeInsets.all(10),
// width: MediaQuery.of(context).size.width,
// child: Row(
// children: [
// Icon(Icons.corporate_fare),
// SizedBox(
// width: 10,
// ),
// Text("Company",
// style: Constant.body1(context: context)
// .copyWith(color: Constant.textRed)),
// ],
// )),
// )
// ],
),
),
),
),
);
}
}

View File

@@ -1,69 +0,0 @@
import 'package:app_petty_cash/model/company_model.dart';
import 'package:app_petty_cash/repository/company_repository.dart';
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 ListCompanyState extends Equatable {
final DateTime date;
const ListCompanyState(this.date);
@override
List<Object?> get props => [date];
}
class ListCompanyStateInit extends ListCompanyState {
ListCompanyStateInit() : super(DateTime.now());
}
class ListCompanyStateLoading extends ListCompanyState {
ListCompanyStateLoading() : super(DateTime.now());
}
class ListCompanyStateError extends ListCompanyState {
final String message;
ListCompanyStateError({
required this.message,
}) : super(DateTime.now());
}
class ListCompanyStateDone extends ListCompanyState {
final List<CompanyModel> model;
ListCompanyStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class ListCompanyNotifier extends StateNotifier<ListCompanyState> {
final Ref ref;
ListCompanyNotifier({
required this.ref,
}) : super(ListCompanyStateInit());
void getListCompany({required String userID}) async {
try {
state = ListCompanyStateLoading();
final dio = ref.read(dioProvider);
final resp =
await CompanyRepository(dio: dio).getListCompany(userID: userID);
state = ListCompanyStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = ListCompanyStateError(message: e.message.toString());
} else {
state = ListCompanyStateError(message: e.toString());
}
}
}
}
//provider
final ListCompanyProvider =
StateNotifierProvider<ListCompanyNotifier, ListCompanyState>(
(ref) => ListCompanyNotifier(ref: ref),
);

View File

@@ -1,83 +0,0 @@
import 'package:app_petty_cash/model/auth_model.dart';
import 'package:app_petty_cash/model/company_model.dart';
import 'package:app_petty_cash/repository/auth_repository.dart';
import 'package:app_petty_cash/repository/company_repository.dart';
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 ChangePasswordState extends Equatable {
final DateTime date;
const ChangePasswordState(this.date);
@override
List<Object?> get props => [date];
}
class ChangePasswordStateInit extends ChangePasswordState {
ChangePasswordStateInit() : super(DateTime.now());
}
class ChangePasswordStateLoading extends ChangePasswordState {
ChangePasswordStateLoading() : super(DateTime.now());
}
class ChangePasswordStateError extends ChangePasswordState {
final String message;
ChangePasswordStateError({
required this.message,
}) : super(DateTime.now());
}
class ChangePasswordStateDone extends ChangePasswordState {
final String model;
ChangePasswordStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class ChangePasswordNotifier extends StateNotifier<ChangePasswordState> {
final Ref ref;
ChangePasswordNotifier({
required this.ref,
}) : super(ChangePasswordStateInit());
void postChangePassword({
required String userID,
required String userToken,
required String userTokenx,
required String oldPassword,
required String newPassword,
required String confirmPassword,
}) async {
try {
state = ChangePasswordStateLoading();
final dio = ref.read(dioProvider);
final resp = await AuthRepository(dio: dio).changePassword(
userID: userID,
tokenx: userTokenx,
token: userToken,
oldPassword: oldPassword,
newPassword: newPassword,
confirmPassword: confirmPassword);
state = ChangePasswordStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = ChangePasswordStateError(message: e.message.toString());
} else {
state = ChangePasswordStateError(message: e.toString());
}
}
}
}
//provider
final ChangePasswordProvider =
StateNotifierProvider<ChangePasswordNotifier, ChangePasswordState>(
(ref) => ChangePasswordNotifier(ref: ref),
);

View File

@@ -1,428 +0,0 @@
import 'package:app_petty_cash/app/constant.dart';
import 'package:app_petty_cash/widget/custom_drawer.dart';
import 'package:app_petty_cash/widget/sankbar_widget.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/route.dart';
import '../../provider/current_user_provider.dart';
import 'change_password_provider.dart';
class ChangePasswordScreen extends HookConsumerWidget {
const ChangePasswordScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedUser = ref.read(currentUserProvider);
//menampung user token jika ada
final userToken = ref.read(currentUserProvider)?.token ?? "";
final userID = ref.read(currentUserProvider)?.model.M_UserID ?? "0";
final tokenx = ref.read(currentUserProvider)?.token ?? "";
final isLoading = useState(false);
final obscureTextOldPassword = useState<bool>(true);
final obscureTextNewPassword = useState<bool>(true);
final obscureTextConfirmPassword = useState<bool>(true);
final ctrlOldPassword = useTextEditingController(text: "");
final ctrlNewPassword = useTextEditingController(text: "");
final ctrlConfirmPassword = useTextEditingController(text: "");
final loading = useState(false);
// inisialisasi agar bisa cek apakah user sudah login sukses apa belum
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 () {};
}, []);
// fungsi logout
Logout() async {
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);
ref.read(currentUserProvider.notifier).state = null;
Navigator.of(context)
.pushNamedAndRemoveUntil(loginRoute, (route) => false);
}
}
// read provider home
ref.listen(
ChangePasswordProvider,
(previous, next) {
if (next is ChangePasswordStateLoading) {
loading.value = true;
} else if (next is ChangePasswordStateError) {
loading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
} else if (next is ChangePasswordStateDone) {
loading.value = false;
SanckbarWidget(
context,
"Ubah Password Berhasil!\nSilahkan Login dengan password baru",
snackbarType.success,
);
Logout();
}
},
);
return Padding(
padding: EdgeInsets.only(
top: Constant.getActualYPhone(context: context, y: 30)),
child: Scaffold(
appBar: AppBar(
// centerTitle: true,
title: Text(
'Change Password',
style: TextStyle(color: Constant.textWhite),
),
backgroundColor: Constant.pcBtnBackgroundColor,
iconTheme: IconThemeData(
color: Constant.textWhite,
),
),
drawer: CustomDrawer(),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(20),
child: Container(
width: Constant.getActualXPhone(context: context, x: 390),
height: Constant.getActualYPhone(context: context, y: 844),
child: Column(
children: [
//Old password
Padding(
padding: EdgeInsets.only(
// top: Constant.getActualYPhone(context: context, y: 63),
left: Constant.getActualXPhone(context: context, x: 20),
right: Constant.getActualXPhone(context: context, x: 20),
),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'Old Password',
style: Constant.body1_400_dibulan(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack),
),
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 4),
),
Padding(
padding: EdgeInsets.only(
top: Constant.getActualYPhone(context: context, y: 5),
left: Constant.getActualXPhone(context: context, x: 20),
right: Constant.getActualXPhone(context: context, x: 20),
),
child: TextField(
obscureText: obscureTextOldPassword.value,
controller: ctrlOldPassword,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(
obscureTextOldPassword.value
? Icons.visibility
: Icons.visibility_off,
color: Constant.textGreyv2,
),
onPressed: () {
obscureTextOldPassword.value = !obscureTextOldPassword.value;
},
),
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: "OldPassword",
hintText: 'Old Password',
),
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 40),
),
//New password
Padding(
padding: EdgeInsets.only(
// top: Constant.getActualYPhone(context: context, y: 63),
left: Constant.getActualXPhone(context: context, x: 20),
right: Constant.getActualXPhone(context: context, x: 20),
),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'New Password',
style: Constant.body1_400_dibulan(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack),
),
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 4),
),
Padding(
padding: EdgeInsets.only(
top: Constant.getActualYPhone(context: context, y: 5),
left: Constant.getActualXPhone(context: context, x: 20),
right: Constant.getActualXPhone(context: context, x: 20),
),
child: TextField(
obscureText: obscureTextNewPassword.value,
controller: ctrlNewPassword,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(
obscureTextNewPassword.value
? Icons.visibility
: Icons.visibility_off,
color: Constant.textGreyv2,
),
onPressed: () {
obscureTextNewPassword.value = !obscureTextNewPassword.value;
},
),
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: "New Password",
hintText: 'New Password',
),
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 40),
),
// Confirm password
Padding(
padding: EdgeInsets.only(
// top: Constant.getActualYPhone(context: context, y: 63),
left: Constant.getActualXPhone(context: context, x: 20),
right: Constant.getActualXPhone(context: context, x: 20),
),
child: Align(
alignment: Alignment.centerLeft,
child: Text(
'Confirm Password',
style: Constant.body1_400_dibulan(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack),
),
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 4),
),
Padding(
padding: EdgeInsets.only(
top: Constant.getActualYPhone(context: context, y: 5),
left: Constant.getActualXPhone(context: context, x: 20),
right: Constant.getActualXPhone(context: context, x: 20),
),
child: TextField(
obscureText: obscureTextConfirmPassword.value,
controller: ctrlConfirmPassword,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(
obscureTextConfirmPassword.value
? Icons.visibility
: Icons.visibility_off,
color: Constant.textGreyv2,
),
onPressed: () {
obscureTextConfirmPassword.value = !obscureTextConfirmPassword.value;
},
),
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: "Confirm Password",
hintText: 'Confirm Password',
),
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 50),
),
//Button Update Password
Padding(
padding: EdgeInsets.only(
left: Constant.getActualXPhone(context: context, x: 20),
right: Constant.getActualXPhone(context: context, x: 20),
),
child: SizedBox(
width: Constant.getActualXPhone(context: context, x: 390),
height: Constant.getActualYPhone(context: context, y: 50),
child: ElevatedButton(
onPressed: (loading.value == true)
? null
: () {
if (ctrlNewPassword.text !=
ctrlConfirmPassword.text) {
SanckbarWidget(
context,
'New Password dan dan confirm password tidak sama!',
snackbarType.warning);
return;
}
if (ctrlOldPassword.text ==
ctrlConfirmPassword.text) {
SanckbarWidget(
context,
'Password lama dan baru tidak boleh sama',
snackbarType.warning);
return;
}
if (ctrlOldPassword.text.isEmpty ||
ctrlNewPassword.text.isEmpty ||
ctrlConfirmPassword.text.isEmpty) {
isLoading.value = true;
SanckbarWidget(context, 'Inputan harus diisi',
snackbarType.warning);
} else {
ref
.read(ChangePasswordProvider.notifier)
.postChangePassword(
userTokenx: tokenx,
userToken: userToken,
userID: userID,
oldPassword: ctrlOldPassword.text,
newPassword: ctrlNewPassword.text,
confirmPassword:
ctrlConfirmPassword.text,
);
}
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => (loading.value == true)
? Constant.textGrey
: Constant.pcBtnBackgroundColor),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: Constant.pcBtnBackgroundColor,
),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Stack(
children: [
(isLoading.value)
? SizedBox(
width: Constant.getActualXPhone(
context: context, x: 24),
height: Constant.getActualYPhone(
context: context, y: 32),
child: Center(
child: CircularProgressIndicator(
color: Colors.white,
),
),
)
: Align(
alignment: Alignment.center,
child: Text(
'Submit',
style: Constant.titleH3_700(
context: context)
.copyWith(
color: Constant.textLoginColor),
),
),
],
),
),
),
),
],
),
),
),
),
),
);
}
}

View File

@@ -1,56 +1,17 @@
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:intl/intl.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";
@@ -62,104 +23,10 @@ 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;
}
},
);
String formatDateString(String inputDate) {
try {
// Parsing tanggal dari string input
DateTime date =
DateFormat('dd-MM-yyyy HH:mm:ss', 'id').parse(inputDate);
// Format tanggal ke '30 Des 2023'
String formattedDate =
DateFormat('dd MMM yyyy HH:mm:ss', '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;
}
}
return Padding(
padding: EdgeInsets.only(
top: Constant.getActualYPhone(context: context, y: 30),
@@ -167,12 +34,8 @@ class HomeScreen extends HookConsumerWidget {
child: Scaffold(
appBar: AppBar(
title: Text(
// 'Home Screen',
M_CompanyName.value,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Constant.textWhite,
),
'Home Screen',
style: TextStyle(color: Constant.textWhite),
),
backgroundColor: Constant.pcBtnBackgroundColor,
iconTheme: IconThemeData(
@@ -181,337 +44,8 @@ class HomeScreen extends HookConsumerWidget {
),
drawer: CustomDrawer(),
body: SafeArea(
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(),
),
SizedBox(
height: Constant.getActualYPhone(
context: context, y: 10),
),
// catatan
Align(
alignment: Alignment.centerLeft,
child: Text(
listTransaksiHome
.value[idx].note
.toString(),
style: Constant.body1(
context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack,
),
),
),
SizedBox(
height: Constant.getActualYPhone(
context: context, y: 10),
),
// Tanggal Created and by align right
Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Text(
'created : ' +
formatDateString(
listTransaksiHome
.value[idx]
.tanggalcreated
.toString(),
),
overflow:
TextOverflow.ellipsis,
style: Constant.body1(
context: context)
.copyWith(
fontWeight:
FontWeight.normal,
fontStyle: FontStyle.italic,
color: Constant.textBlack,
fontSize: 14,
),
),
Expanded(
child: Container(
child: Text(
' by : ' +
listTransaksiHome
.value[idx]
.usertransaksi
.toString(),
overflow:
TextOverflow.ellipsis,
style: Constant.body1(
context: context)
.copyWith(
fontWeight:
FontWeight.normal,
fontStyle:
FontStyle.italic,
color: Constant
.pcBtnBackgroundColor,
fontSize: 14,
),
),
),
),
],
),
],
),
),
),
);
},
),
),
),
],
),
),
),
child: Center(
child: Text('Home Screen Content'),
),
),
),

View File

@@ -1,75 +0,0 @@
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

@@ -1,72 +0,0 @@
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

@@ -114,7 +114,7 @@ class LoginFormScreen extends HookConsumerWidget {
),
Container(
width: Constant.getActualXPhone(context: context, x: 390),
// height: Constant.getActualYPhone(context: context, y: 485),
height: Constant.getActualYPhone(context: context, y: 485),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,

View File

@@ -29,8 +29,7 @@ class LoginScreen extends HookConsumerWidget {
final authModel = AuthModel(
token: xmodel["token"],
model: AuthDoctorModel(
M_CompanyID: xmodel["model"]["M_CompanyID"],
M_CompanyName: xmodel["model"]["M_CompanyName"],
// M_UserM_DoctorID: xmodel["model"]["M_UserM_DoctorID"],
M_UserEmail: xmodel["model"]["M_UserEmail"],
M_UserUsername: xmodel["model"]["M_UserUsername"],
// M_UserM_DoctorCode: xmodel["model"]["M_UserM_DoctorCode"],
@@ -55,22 +54,22 @@ class LoginScreen extends HookConsumerWidget {
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Scaffold(
resizeToAvoidBottomInset: true,
// backgroundColor: Colors.transparent,
backgroundColor: Constant.backgroundColor,
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

@@ -1,7 +1,3 @@
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import '../../widget/sankbar_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
@@ -29,30 +25,6 @@ class ReportScreen extends HookConsumerWidget {
final tglAkhir = useState<DateTime>(DateTime.now());
final tglAkhirTmp = useState<String>("");
String M_CompanyID = "0";
String timeStamp = DateFormat('dd-MM-yyyy').format(
DateTime.now(),
);
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 {
@@ -86,207 +58,226 @@ class ReportScreen extends HookConsumerWidget {
),
drawer: CustomDrawer(),
body: SafeArea(
child: Padding(
padding: EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Tanggal Awal',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textBlack),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 10),
),
// Tanggal Awal
Row(
children: [
Expanded(
child: TextField(
controller: ctrlTglAwal,
decoration: InputDecoration(
hintStyle:
Constant.body2_400(context: context).copyWith(
color: Colors.orange,
),
labelStyle:
Constant.body2_400(context: context).copyWith(
color: Colors.orange,
),
border: OutlineInputBorder(
borderSide: BorderSide(
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Tanggal Awal',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textBlack),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 10),
),
// Tanggal Awal
Row(
children: [
Expanded(
child: TextField(
controller: ctrlTglAwal,
decoration: InputDecoration(
hintStyle:
Constant.body2_400(context: context).copyWith(
color: Colors.orange,
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
labelStyle:
Constant.body2_400(context: context).copyWith(
color: Colors.orange,
width: 1,
),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.orange,
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.orange,
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,
// ),
),
// 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;
}
},
),
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;
}
},
),
),
],
),
],
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
Text(
'Tanggal Akhir',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textBlack),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 10),
),
// Tanggal Akhir
Row(
children: [
Expanded(
child: TextField(
controller: ctrlTglAkhir,
decoration: InputDecoration(
hintStyle:
Constant.body2_400(context: context).copyWith(
color: Colors.orange,
),
labelStyle:
Constant.body2_400(context: context).copyWith(
color: Colors.orange,
),
border: OutlineInputBorder(
borderSide: BorderSide(
Text(
'Tanggal Akhir',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textBlack),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 10),
),
// Tanggal Akhir
Row(
children: [
Expanded(
child: TextField(
controller: ctrlTglAkhir,
decoration: InputDecoration(
hintStyle:
Constant.body2_400(context: context).copyWith(
color: Colors.orange,
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
labelStyle:
Constant.body2_400(context: context).copyWith(
color: Colors.orange,
width: 1,
),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.orange,
width: 1,
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.orange,
width: 1,
),
),
// labelText: "Tanggal Awal",
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,
// ),
),
// labelText: "Tanggal Awal",
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;
}
},
),
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;
}
},
),
),
],
),
Spacer(),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
],
),
],
),
),
),
),
bottomNavigationBar: BottomAppBar(
height: 150,
child: Container(
child: Padding(
padding: EdgeInsets.only(
// right: Constant.getActualXPhone(context: context, x: 27),
// left: Constant.getActualXPhone(context: context, x: 27),
// bottom: Constant.getActualYPhone(context: context, y: 32),
// top: Constant.getActualYPhone(context: context, y: 24),
),
child: Column(
children: [
// Excel
Container(
width: Constant.getActualXPhone(context: context, x: 336),
height: Constant.getActualYPhone(context: context, y: 42),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(states) => Colors.white),
// side: MaterialStateBorderSide.resolveWith(
// (states) => BorderSide(color: Colors.green),
// ),
// backgroundColor: MaterialStateColor.resolveWith(
// (st) => Constant.pcBtnBackgroundColor),
shape:
@@ -318,11 +309,11 @@ class ReportScreen extends HookConsumerWidget {
),
),
SizedBox(
width: Constant.getActualXPhone(
context: context, x: 10),
height: Constant.getActualXPhone(
context: context, x: 8),
),
Text(
'Excel',
'Download Report (xls) ',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Colors.green,
@@ -330,42 +321,19 @@ class ReportScreen extends HookConsumerWidget {
),
],
),
onPressed: () async {
M_CompanyID = await getCompanyID();
if (M_CompanyID == "0") {
SanckbarWidget(
context, 'Invalid Company', snackbarType.error);
return;
}
// Awal
DateTime parsedDateAwal =
DateFormat('dd-MM-yyyy').parse(
ctrlTglAwal.value.text.toString(),
);
String formattedDateAwal =
DateFormat('yyyy-MM-dd').format(parsedDateAwal);
// Akhir
DateTime parsedDateAkhir =
DateFormat('dd-MM-yyyy').parse(
ctrlTglAkhir.value.text.toString(),
);
String formattedDateAkhir =
DateFormat('yyyy-MM-dd').format(parsedDateAkhir);
String url =
"https://${Constant.baseUrlDevoneReport}/birt/run?__report=report/one/pettycash/rpt_r_pt_001.rptdesign&__format=xls&PStartDate=$formattedDateAwal&PEndDate=$formattedDateAkhir&PCompanyID=$M_CompanyID&username=adminsas%20&tm=$timeStamp";
if (!await launchUrl(Uri.parse(url))) {
// throw Exception('Could not launch $url');
SanckbarWidget(context, 'Could not launch $url',
snackbarType.error);
}
// https://devone.aplikasi.web.id/birt/run?__report=report/one/pettycash/rpt_r_pt_001.rptdesign&__format=pdf&PStartDate=2023-11-01&PEndDate=2023-12-30&PCompanyID=0&username=adminsas%20&tm=1701327096267
},
onPressed: () {},
),
),
// PDF
ElevatedButton(
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
// PDF
Container(
width: Constant.getActualXPhone(context: context, x: 336),
height: Constant.getActualYPhone(context: context, y: 42),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.pcBtnBackgroundColor),
@@ -398,11 +366,11 @@ class ReportScreen extends HookConsumerWidget {
),
),
SizedBox(
width: Constant.getActualXPhone(
height: Constant.getActualXPhone(
context: context, x: 8),
),
Text(
'PDF',
'Download Report (PDF)',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.white),
@@ -410,32 +378,7 @@ class ReportScreen extends HookConsumerWidget {
],
),
onPressed: () async {
M_CompanyID = await getCompanyID();
if (M_CompanyID == "0") {
SanckbarWidget(
context, 'Invalid Company', snackbarType.error);
return;
}
// Awal
DateTime parsedDateAwal =
DateFormat('dd-MM-yyyy').parse(
ctrlTglAwal.value.text.toString(),
);
String formattedDateAwal =
DateFormat('yyyy-MM-dd').format(parsedDateAwal);
// Akhir
DateTime parsedDateAkhir =
DateFormat('dd-MM-yyyy').parse(
ctrlTglAkhir.value.text.toString(),
);
String formattedDateAkhir =
DateFormat('yyyy-MM-dd').format(parsedDateAkhir);
String url =
"https://${Constant.baseUrlDevoneReport}/birt/run?__report=report/one/pettycash/rpt_r_pt_001.rptdesign&__format=pdf&PStartDate=$formattedDateAwal&PEndDate=$formattedDateAkhir&PCompanyID=$M_CompanyID&username=adminsas%20&tm=$timeStamp";
print(url);
String url = "https://pub.dev/packages?q=url+launcher";
if (!await launchUrl(Uri.parse(url))) {
// throw Exception('Could not launch $url');
SanckbarWidget(context, 'Could not launch $url',
@@ -443,9 +386,9 @@ class ReportScreen extends HookConsumerWidget {
}
},
),
],
),
],
),
],
),
),
),
),

View File

@@ -1,84 +0,0 @@
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 ConfirmTransaksiState extends Equatable {
final DateTime date;
const ConfirmTransaksiState(this.date);
@override
List<Object?> get props => [date];
}
class ConfirmTransaksiStateInit extends ConfirmTransaksiState {
ConfirmTransaksiStateInit() : super(DateTime.now());
}
class ConfirmTransaksiStateLoading extends ConfirmTransaksiState {
ConfirmTransaksiStateLoading() : super(DateTime.now());
}
class ConfirmTransaksiStateError extends ConfirmTransaksiState {
final String message;
ConfirmTransaksiStateError({
required this.message,
}) : super(DateTime.now());
}
class ConfirmTransaksiStateDone extends ConfirmTransaksiState {
// final List<ListType> model;
final String resp;
ConfirmTransaksiStateDone({
required this.resp,
}) : super(DateTime.now());
}
//notifier
class ConfirmTransaksiNotifier extends StateNotifier<ConfirmTransaksiState> {
final Ref ref;
ConfirmTransaksiNotifier({
required this.ref,
}) : super(ConfirmTransaksiStateInit());
void confirmTransaksi(
String id,
String userid,
String companyid,
String tglAwal,
String tglAkhir,
String categoryid,
) async {
try {
state = ConfirmTransaksiStateLoading();
final dio = ref.read(dioProvider);
final resp = await TransaksiRepository(dio: dio).confirmTransaksi(
id,
userid,
);
state = ConfirmTransaksiStateDone(resp: resp);
// search lagi buat get data
ref.read(searchHistoryTransaksiProvider.notifier).searchHistoryTransaksi(
companyid,
tglAwal,
tglAkhir,
categoryid,
);
} catch (e) {
if (e is BaseRepositoryException) {
state = ConfirmTransaksiStateError(message: e.message.toString());
} else {
state = ConfirmTransaksiStateError(message: e.toString());
}
}
}
}
//provider
final confirmTransaksiProvider =
StateNotifierProvider<ConfirmTransaksiNotifier, ConfirmTransaksiState>(
(ref) => ConfirmTransaksiNotifier(ref: ref),
);

View File

@@ -1,84 +0,0 @@
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,79 +0,0 @@
import 'package:app_petty_cash/model/history_total_model.dart';
import 'package:app_petty_cash/provider/current_info_account_balance_provider.dart';
import 'package:app_petty_cash/repository/home_repository.dart';
import 'package:app_petty_cash/repository/transaksi_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';
abstract class HistoryTotalState extends Equatable {
final DateTime date;
const HistoryTotalState(this.date);
@override
List<Object?> get props => [date];
}
class HistoryTotalStateInit extends HistoryTotalState {
HistoryTotalStateInit() : super(DateTime.now());
}
class HistoryTotalStateLoading extends HistoryTotalState {
HistoryTotalStateLoading() : super(DateTime.now());
}
class HistoryTotalStateError extends HistoryTotalState {
final String message;
HistoryTotalStateError({
required this.message,
}) : super(DateTime.now());
}
class HistoryTotalStateDone extends HistoryTotalState {
final HistoryTotalModel model;
// final String resp;
HistoryTotalStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class HistoryTotalNotifier extends StateNotifier<HistoryTotalState> {
final Ref ref;
HistoryTotalNotifier({
required this.ref,
}) : super(HistoryTotalStateInit());
void historyTotal(
String companyid,
String tglAwal,
String tglAkhir,
String categoryid,
) async {
try {
state = HistoryTotalStateLoading();
final dio = ref.read(dioProvider);
final resp = await TransaksiRepository(dio: dio).getHistoryTotal(
companyid,
tglAwal,
tglAkhir,
categoryid
);
state = HistoryTotalStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = HistoryTotalStateError(message: e.message.toString());
} else {
state = HistoryTotalStateError(message: e.toString());
}
}
}
}
//provider
final historyTotalProvider =
StateNotifierProvider<HistoryTotalNotifier, HistoryTotalState>(
(ref) => HistoryTotalNotifier(ref: ref),
);

View File

@@ -43,18 +43,15 @@ class InsertTransaksiNotifier extends StateNotifier<InsertTransaksiState> {
}) : super(InsertTransaksiStateInit());
void insertTransaksi(
{required String tanggal,
required String tipe,
required String kategoriid,
required String jumlah,
required String catatan,
required String userid,
required String sender,
required String url,
required String base64file,
required String fileName,
required String fileSize,
required String fileExtension}) async {
String tanggal,
String tipe,
String kategoriid,
String jumlah,
String catatan,
String userid,
String sender,
String url,
) async {
try {
state = InsertTransaksiStateLoading();
final dio = ref.read(dioProvider);
@@ -66,10 +63,6 @@ class InsertTransaksiNotifier extends StateNotifier<InsertTransaksiState> {
catatan,
userid,
sender,
base64file,
fileName,
fileSize,
fileExtension,
url,
);
state = InsertTransaksiStateDone(resp: resp);

View File

@@ -1,85 +0,0 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../model/history_transaksi_model.dart';
import '../../repository/transaksi_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import 'history_total_provider.dart';
abstract class SearchHistoryTransaksiState extends Equatable {
final DateTime date;
const SearchHistoryTransaksiState(this.date);
@override
List<Object?> get props => [date];
}
class SearchHistoryTransaksiStateInit extends SearchHistoryTransaksiState {
SearchHistoryTransaksiStateInit() : super(DateTime.now());
}
class SearchHistoryTransaksiStateLoading extends SearchHistoryTransaksiState {
SearchHistoryTransaksiStateLoading() : super(DateTime.now());
}
class SearchHistoryTransaksiStateError extends SearchHistoryTransaksiState {
final String message;
SearchHistoryTransaksiStateError({
required this.message,
}) : super(DateTime.now());
}
class SearchHistoryTransaksiStateDone extends SearchHistoryTransaksiState {
final List<HistoryTransaksiModel> model;
SearchHistoryTransaksiStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class SearchHistoryTransaksiNotifier
extends StateNotifier<SearchHistoryTransaksiState> {
final Ref ref;
SearchHistoryTransaksiNotifier({
required this.ref,
}) : super(SearchHistoryTransaksiStateInit());
void searchHistoryTransaksi(
String companyid,
String tglAwal,
String tglAkhir,
String categoryid,
) async {
try {
state = SearchHistoryTransaksiStateLoading();
final dio = ref.read(dioProvider);
final resp = await TransaksiRepository(dio: dio).getListHistoryTransaksi(
companyid,
tglAwal,
tglAkhir,
categoryid,
);
state = SearchHistoryTransaksiStateDone(model: resp);
// panggil provider total transaksi by category for non all
ref.read(historyTotalProvider.notifier).historyTotal(
companyid,
tglAwal,
tglAkhir,
categoryid,
);
} catch (e) {
if (e is BaseRepositoryException) {
state = SearchHistoryTransaksiStateError(message: e.message.toString());
} else {
state = SearchHistoryTransaksiStateError(message: e.toString());
}
}
}
}
//provider
final searchHistoryTransaksiProvider = StateNotifierProvider<
SearchHistoryTransaksiNotifier, SearchHistoryTransaksiState>(
(ref) => SearchHistoryTransaksiNotifier(ref: ref),
);

View File

@@ -3,17 +3,16 @@ import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class TransaksiPickDateWidget extends StatelessWidget {
const TransaksiPickDateWidget(
{super.key,
required this.ctrlTglAwal,
required this.tglAwal,
required this.tglAwalTmp,
required this.isLoading});
const TransaksiPickDateWidget({
super.key,
required this.ctrlTglAwal,
required this.tglAwal,
required this.tglAwalTmp,
});
final TextEditingController ctrlTglAwal;
final ValueNotifier<DateTime> tglAwal;
final ValueNotifier<String> tglAwalTmp;
final ValueNotifier<bool> isLoading;
@override
Widget build(BuildContext context) {
@@ -64,38 +63,35 @@ class TransaksiPickDateWidget extends StatelessWidget {
// color: Constant.colorIconDate,
// ),
),
onTap: !isLoading.value
? () async {
final selectedDateAwal = await showDatePicker(
keyboardType: TextInputType.none,
// locale: const Locale("en-CA"),
// locale: ,
context: context,
initialEntryMode: DatePickerEntryMode.calendarOnly,
firstDate: DateTime(2000),
lastDate: DateTime(2100),
onTap: () async {
final selectedDateAwal = await showDatePicker(
keyboardType: TextInputType.none,
// 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,
);
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) {
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;
}
}
: null,
if (selectedDateAwal == null) {
print('cancel button');
return;
}
},
),
),
],

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:io' as io;
import 'dart:io';
import 'package:app_petty_cash/app/app_extension.dart';
import 'package:app_petty_cash/app/route.dart';
import 'package:app_petty_cash/model/list_type_model.dart';
import 'package:app_petty_cash/screen/transaksi/insert_transaksi_provider.dart';
@@ -10,6 +11,7 @@ import 'package:app_petty_cash/screen/transaksi/list_type_provider.dart';
import 'package:app_petty_cash/screen/transaksi/transaksi_pick_date_widget.dart';
import 'package:app_petty_cash/screen/transaksi/transaksi_select_kategori_widget.dart';
import 'package:app_petty_cash/screen/transaksi/transaksi_upload_area_widget.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@@ -17,15 +19,14 @@ import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import 'package:mime/mime.dart';
import '../../app/constant.dart';
import '../../model/list_category_model.dart';
import '../../provider/current_menu_provider.dart';
import '../../provider/current_user_provider.dart';
import '../../widget/custom_drawer.dart';
import '../../widget/sankbar_widget.dart';
import 'package:image/image.dart' as img;
import '../login/custom_text_field.dart';
class DummyDropdownTipe {
final String options;
@@ -52,13 +53,10 @@ class TransaksiScreen extends HookConsumerWidget {
final ctrlJumlah = useTextEditingController(text: "");
final ctrlCatatan = useTextEditingController(text: "");
final ctrlNamaPengirim = useTextEditingController(text: "");
final ctrlCompanyName = useTextEditingController(text: "");
final fileData = useState<XFile?>(null);
final fileDataBase64 = useState<String>("");
final isImage = useState(false);
final fileEkstension = useState("");
final fileSize = useState(0);
final fileName = useState("");
String formattedDate = DateFormat('dd-MM-yyyy').format(DateTime.now());
@@ -154,8 +152,6 @@ class TransaksiScreen extends HookConsumerWidget {
'Data Berhasil Disimpan',
snackbarType.success,
);
// diupdate ke menu home jika sukses
ref.read(currentPageProvider.notifier).update((state) => 0);
Navigator.of(context).pop();
Navigator.of(context).pushNamed(homeRoute);
}
@@ -173,9 +169,6 @@ class TransaksiScreen extends HookConsumerWidget {
// Navigator.popAndPushNamed(context, loginRoute);
return;
}
ctrlCompanyName.text =
ref.read(currentUserProvider)?.model.M_CompanyName ?? "";
});
return () {};
}, []);
@@ -199,69 +192,35 @@ class TransaksiScreen extends HookConsumerWidget {
final userIDLogin = ref.read(currentUserProvider)?.model.M_UserID ?? "0";
getBase64_v1() async {
// List<int> imageBytes = await fileData.value?.readAsBytes();
if (fileData.value != null) {
final bytes = io.File(fileData.value!.path).readAsBytesSync();
String base64Image = base64Encode(await fileData.value!.readAsBytes());
fileDataBase64.value = base64Image;
final file = File(fileData.value!.path);
print(file.lengthSync() / 1000000);
print(await fileData.value!.length());
fileSize.value = await fileData.value!.length();
// await getExternalStorageDirectory();
// print(await fileData.value!.saveTo(path));
print(fileDataBase64.value);
}
}
getBase64() async {
// List<int> imageBytes = await fileData.value?.readAsBytes();
if (fileData.value != null) {
final bytes = io.File(fileData.value!.path).readAsBytesSync();
String base64Image = base64Encode(await fileData.value!.readAsBytes());
String base64Image = base64Encode(bytes);
fileDataBase64.value = base64Image;
final file = File(fileData.value!.path);
print(file.lengthSync() / 1000000);
print(await fileData.value!.length());
fileSize.value = await fileData.value!.length();
// await getExternalStorageDirectory();
// print(await fileData.value!.saveTo(path));
print(fileDataBase64.value);
print(base64Image);
}
}
final ImagePicker _picker = ImagePicker();
pickImage() async {
final XFile? pickedFile = await _picker.pickImage(
source: ImageSource.camera,
// maxWidth set untuk width image
maxWidth: 640,
// maxHeight set untuk width image
maxHeight: 480);
source: ImageSource.camera,
);
if (pickedFile != null) {
final tmpFile = FilePickerResult([
PlatformFile(
name: pickedFile.name,
size: await pickedFile.length(),
path: pickedFile.path,
)
]);
if (await pickedFile.length() > 10000000) {
SanckbarWidget(context, "File tidak boleh lebih dari 10 MB",
snackbarType.warning);
} else {
fileData.value = pickedFile;
isImage.value = true;
fileEkstension.value = tmpFile.files.single.extension ?? "";
DateTime now = new DateTime.now();
fileName.value =
"IMG-${now.year}${now.month}${now.day}.${tmpFile.files.single.extension ?? ''}";
}
// final Directory appDocumentsDir =
// await getApplicationDocumentsDirectory();
// print(appDocumentsDir);
@@ -306,14 +265,13 @@ class TransaksiScreen extends HookConsumerWidget {
SanckbarWidget(context, "File tidak boleh lebih dari 10 MB",
snackbarType.warning);
} else {
// File files = File(result.files.single.path!);
File files = File(result.files.single.path!);
print(result.files.single.extension);
XFile fl = XFile(result.files.single.path!);
fileName.value = result.files.single.name;
isImage.value = imgExt.contains(result.files.single.extension);
print(result.files.single.name);
print("ini xfile");
fileData.value = fl;
await getBase64();
fileEkstension.value = result.files.single.extension ?? "";
@@ -323,69 +281,6 @@ class TransaksiScreen extends HookConsumerWidget {
}
}
insertTransaksi() {
if (selectedListTypeData.value.typeid.toString() == "DEBIT") {
ctrlNamaPengirim.text = "";
// validasi form
if (ctrlJumlah.text.isEmpty || ctrlCatatan.text.trim().isEmpty) {
SanckbarWidget(
context, "Jumlah dan catatan harus diisi", snackbarType.warning);
return;
}
} else {
if (selectedListTypeData.value.typeid.toString() == "KREDIT") {
selectedListCategory.value.categoryid = "0";
// validasi form
if (ctrlNamaPengirim.text.trim().isEmpty ||
ctrlJumlah.text.isEmpty ||
ctrlCatatan.text.trim().isEmpty) {
SanckbarWidget(
context,
"Nama pengirim, jumlah dan catatan harus diisi",
snackbarType.warning);
return;
}
}
}
DateTime parsedDate = DateFormat('dd-MM-yyyy').parse(
ctrlTglAwal.value.text.toString(),
);
String formattedDateTransaksi =
DateFormat('yyyy-MM-dd').format(parsedDate);
var param = {
"tgltransaksi": formattedDateTransaksi,
"typeid": selectedListTypeData.value.typeid.toString(),
"categoryid": selectedListCategory.value.categoryid.toString(),
"jumlah": ctrlJumlah.value.text.toString(),
"catatan": ctrlCatatan.value.text.toString(),
// "userid": "1",
"userid": userIDLogin,
"namapengirim": ctrlNamaPengirim.value.text.toString(),
"url": "",
// "base64file": fileDataBase64.value,
"fileName": fileName.value,
"fileExtension": fileEkstension.value,
"fileSize": fileSize.value.toString()
};
print(param);
// return;
ref.read(insertTransaksiProvider.notifier).insertTransaksi(
tanggal: formattedDateTransaksi,
tipe: selectedListTypeData.value.typeid.toString(),
kategoriid: selectedListCategory.value.categoryid.toString(),
jumlah: ctrlJumlah.value.text.toString(),
catatan: ctrlCatatan.value.text.toString(),
// "1",
userid: userIDLogin,
sender: ctrlNamaPengirim.value.text.toString(),
url: "",
base64file: fileDataBase64.value,
fileName: fileData.value?.name ?? "",
fileExtension: fileEkstension.value,
fileSize: fileSize.value.toString());
}
return Padding(
padding: EdgeInsets.only(
top: Constant.getActualYPhone(context: context, y: 30),
@@ -407,76 +302,133 @@ class TransaksiScreen extends HookConsumerWidget {
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(20),
child: Container(
// height: MediaQuery.of(context).size.height - 10,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Company Name
Text(
'Company Name',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 10),
),
TextField(
controller: ctrlCompanyName,
readOnly: true,
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: "Company Name",
hintText: 'Company Name',
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
Text(
'Tanggal Transaksi',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 10),
),
// Tanggal Transaksi
TransaksiPickDateWidget(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Tanggal Transaksi',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textBlack),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 10),
),
// Tanggal Transaksi
TransaksiPickDateWidget(
ctrlTglAwal: ctrlTglAwal,
tglAwal: tglAwal,
tglAwalTmp: tglAwalTmp,
isLoading: transaksiIsLoading,
tglAwalTmp: tglAwalTmp),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
// tipe transaksi
Text(
'Tipe Transaksi',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textBlack),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 10),
),
SizedBox(
width: Constant.getActualXPhone(context: context, x: 340),
height: Constant.getActualYPhone(context: context, y: 36),
child: (listTypeLoading.value)
? SizedBox(
width: Constant.getActualXPhone(
context: context, x: 24),
height: Constant.getActualYPhone(
context: context, y: 32),
child: Center(
child: CircularProgressIndicator(),
),
)
: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (listTypeData.value.isEmpty)
Text('Radio Button Empty')
else
for (var i = 0;
i < listTypeData.value.length;
i++)
Padding(
padding: const EdgeInsets.only(right: 20),
child: Row(
children: [
Radio<ListType>(
activeColor:
Constant.pcBtnBackgroundColor,
value: listTypeData.value[i],
groupValue:
selectedListTypeData.value,
onChanged: (ListType? index) {
if (isMounted()) {
selectedListTypeData.value =
index!;
} else {
return;
}
},
),
Text(
listTypeData.value[i].typename ?? "",
style:
Constant.body1(context: context)
.copyWith(
color: Constant.textBlack,
fontWeight: FontWeight.w400,
),
),
],
),
),
],
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
// Kategori
if (selectedListTypeData.value.typeid == "KREDIT") ...[
Text(
'Kategori',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack,
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 10),
),
// Dropdown kategori
(listCategoryLoading.value)
? SizedBox(
width: Constant.getActualXPhone(
context: context, x: 24),
height: Constant.getActualYPhone(
context: context, y: 32),
child: Center(
child: CircularProgressIndicator(),
),
)
: TransaksiSelectKategoriWidget(
listCategoryData: listCategoryData,
selectedListCategory: selectedListCategory),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
],
// tipe transaksi
// Nama Pengirim
if (selectedListTypeData.value.typeid == "DEBIT") ...[
Text(
'Tipe Transaksi',
'Nama Pengirim',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack),
@@ -484,164 +436,8 @@ class TransaksiScreen extends HookConsumerWidget {
SizedBox(
height: Constant.getActualYPhone(context: context, y: 10),
),
SizedBox(
width: Constant.getActualXPhone(context: context, x: 340),
height: Constant.getActualYPhone(context: context, y: 36),
child: (listTypeLoading.value)
? SizedBox(
width: Constant.getActualXPhone(
context: context, x: 24),
height: Constant.getActualYPhone(
context: context, y: 32),
child: Center(
child: CircularProgressIndicator(),
),
)
: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (listTypeData.value.isEmpty)
Text('Radio Button Empty')
else
for (var i = 0;
i < listTypeData.value.length;
i++)
Padding(
padding: const EdgeInsets.only(right: 20),
child: Row(
children: [
Radio<ListType>(
activeColor:
Constant.pcBtnBackgroundColor,
value: listTypeData.value[i],
groupValue:
selectedListTypeData.value,
onChanged: !transaksiIsLoading.value
? (ListType? index) {
if (isMounted()) {
selectedListTypeData
.value = index!;
} else {
return;
}
}
: null,
),
Text(
listTypeData.value[i].typename ??
"",
style:
Constant.body1(context: context)
.copyWith(
color: Constant.textBlack,
fontWeight: FontWeight.w400,
),
),
],
),
),
],
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
// Kategori
if (selectedListTypeData.value.typeid == "DEBIT") ...[
Text(
'Kategori',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack,
),
),
SizedBox(
height:
Constant.getActualYPhone(context: context, y: 10),
),
// Dropdown kategori
(listCategoryLoading.value)
? SizedBox(
width: Constant.getActualXPhone(
context: context, x: 24),
height: Constant.getActualYPhone(
context: context, y: 32),
child: Center(
child: CircularProgressIndicator(),
),
)
: TransaksiSelectKategoriWidget(
isLoading: transaksiIsLoading,
listCategoryData: listCategoryData,
selectedListCategory: selectedListCategory),
SizedBox(
height:
Constant.getActualYPhone(context: context, y: 20),
),
],
// Nama Pengirim
if (selectedListTypeData.value.typeid == "KREDIT") ...[
Text(
'Nama Pengirim',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack),
),
SizedBox(
height:
Constant.getActualYPhone(context: context, y: 10),
),
TextField(
controller: ctrlNamaPengirim,
readOnly: transaksiIsLoading.value,
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: "Nama Pengirim",
hintText: 'Nama Pengirim',
),
),
],
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
// jumlah
Text(
'Jumlah',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
TextField(
controller: ctrlJumlah,
keyboardType: TextInputType.number,
readOnly: transaksiIsLoading.value,
controller: ctrlNamaPengirim,
decoration: InputDecoration(
hintStyle:
Constant.body2_400(context: context).copyWith(
@@ -663,222 +459,202 @@ class TransaksiScreen extends HookConsumerWidget {
width: 1,
),
),
labelText: "Jumlah",
hintText: 'Jumlah',
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
// catatan
Text(
'Catatan',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
TextField(
readOnly: transaksiIsLoading.value,
controller: ctrlCatatan,
maxLines: 4,
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: "Catatan",
hintText: 'Catatan',
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
// Upload File
TransaksiUploadAreaWidget(
isLoading: transaksiIsLoading,
isImage: isImage,
fileData: fileData,
fileDataBase64: fileDataBase64,
pickFile: pickFile,
pickImage: pickImage),
// Spacer(),
Container(
margin: EdgeInsets.only(
top: Constant.getActualYPhone(
context: context, y: 24)),
width: Constant.getActualXPhone(context: context, x: 390),
height: Constant.getActualY(context: context, y: 64),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.pcBtnBackgroundColor),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: Constant.pcBtnBackgroundColor,
),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Stack(
children: [
(transaksiIsLoading.value)
? SizedBox(
width: Constant.getActualXPhone(
context: context, x: 32),
height: Constant.getActualYPhone(
context: context, y: 32),
child: CircularProgressIndicator(
color: Colors.white,
),
)
: Text(
'Simpan',
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.white),
),
],
),
onPressed: !transaksiIsLoading.value
? () {
// transaksiIsLoading.value = true;
insertTransaksi();
}
: null,
labelText: "Nama Pengirim",
hintText: 'Nama Pengirim',
),
),
],
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
// jumlah
Text(
'Jumlah',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textBlack),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
TextField(
controller: ctrlJumlah,
keyboardType: TextInputType.number,
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: "Jumlah",
hintText: 'Jumlah',
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
// catatan
Text(
'Catatan',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textBlack),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
TextField(
controller: ctrlCatatan,
maxLines: 4,
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: "Catatan",
hintText: 'Catatan',
),
),
SizedBox(
height: Constant.getActualYPhone(context: context, y: 20),
),
// Upload File
TransaksiUploadAreaWidget(
isImage: isImage,
fileData: fileData,
fileDataBase64: fileDataBase64,
pickFile: pickFile,
pickImage: pickImage),
],
),
),
),
),
// bottomNavigationBar: Padding(
// padding: EdgeInsets.only(
// right: Constant.getActualXPhone(context: context, x: 27),
// left: Constant.getActualXPhone(context: context, x: 27),
// bottom: Constant.getActualYPhone(context: context, y: 32),
// top: Constant.getActualYPhone(context: context, y: 10),
// ),
// child: BottomAppBar(
// elevation: 2.0,
// child: Container(
// width: Constant.getActualXPhone(context: context, x: 336),
// height: Constant.getActualYPhone(context: context, y: 42),
// child: ElevatedButton(
// style: ButtonStyle(
// backgroundColor: MaterialStateColor.resolveWith(
// (st) => Constant.pcBtnBackgroundColor),
// shape: MaterialStateProperty.all<RoundedRectangleBorder>(
// RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(8),
// side: BorderSide(
// color: Constant.pcBtnBackgroundColor,
// ),
// ),
// ),
// shadowColor: MaterialStateProperty.all(Color(0xffff48423d)),
// elevation: MaterialStateProperty.all(4.0),
// ),
// child: Stack(
// children: [
// (transaksiIsLoading.value)
// ? SizedBox(
// width: Constant.getActualXPhone(
// context: context, x: 24),
// height: Constant.getActualYPhone(
// context: context, y: 32),
// child: CircularProgressIndicator(
// color: Colors.white,
// ),
// )
// : Text(
// 'Simpan',
// style: Constant.body1(context: context).copyWith(
// fontWeight: FontWeight.w600,
// color: Constant.white),
// ),
// ],
// ),
// onPressed: () {
// if (selectedListTypeData.value.typeid.toString() == "DEBIT") {
// ctrlNamaPengirim.text = "";
// // validasi form
// } else {
// if (selectedListTypeData.value.typeid.toString() ==
// "KREDIT") {
// selectedListCategory.value.categoryid = "0";
// // validasi form
// }
// }
bottomNavigationBar: Padding(
padding: EdgeInsets.only(
right: Constant.getActualXPhone(context: context, x: 27),
left: Constant.getActualXPhone(context: context, x: 27),
bottom: Constant.getActualYPhone(context: context, y: 32),
top: Constant.getActualYPhone(context: context, y: 10),
),
child: BottomAppBar(
elevation: 2.0,
child: Container(
width: Constant.getActualXPhone(context: context, x: 336),
height: Constant.getActualYPhone(context: context, y: 42),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.pcBtnBackgroundColor),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: Constant.pcBtnBackgroundColor,
),
),
),
shadowColor: MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Stack(
children: [
(transaksiIsLoading.value)
? SizedBox(
width: Constant.getActualXPhone(
context: context, x: 24),
height: Constant.getActualYPhone(
context: context, y: 32),
child: CircularProgressIndicator(
color: Colors.white,
),
)
: Text(
'Simpan',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.white),
),
],
),
onPressed: () {
if (selectedListTypeData.value.typeid.toString() ==
"KREDIT") {
ctrlNamaPengirim.text = "";
// validasi form
} else {
if (selectedListTypeData.value.typeid.toString() ==
"DEBIT") {
selectedListCategory.value.categoryid = "0";
// validasi form
}
}
// DateTime parsedDate = DateFormat('dd-MM-yyyy').parse(
// ctrlTglAwal.value.text.toString(),
// );
// String formattedDateTransaksi =
// DateFormat('yyyy-MM-dd').format(parsedDate);
// var param = {
// "tgltransaksi": formattedDateTransaksi,
// "typeid": selectedListTypeData.value.typeid.toString(),
// "categoryid":
// selectedListCategory.value.categoryid.toString(),
// "jumlah": ctrlJumlah.value.text.toString(),
// "catatan": ctrlCatatan.value.text.toString(),
// // "userid": "1",
// "userid": userIDLogin,
// "namapengirim": ctrlNamaPengirim.value.text.toString(),
// "url": "",
// };
// print(param);
// ref.read(insertTransaksiProvider.notifier).insertTransaksi(
// formattedDateTransaksi,
// selectedListTypeData.value.typeid.toString(),
// selectedListCategory.value.categoryid.toString(),
// ctrlJumlah.value.text.toString(),
// ctrlCatatan.value.text.toString(),
// // "1",
// userIDLogin,
// ctrlNamaPengirim.value.text.toString(),
// "",
// );
// },
// ),
// ),
// ),
// ),
DateTime parsedDate = DateFormat('dd-MM-yyyy').parse(
ctrlTglAwal.value.text.toString(),
);
String formattedDateTransaksi =
DateFormat('yyyy-MM-dd').format(parsedDate);
var param = {
"tgltransaksi": formattedDateTransaksi,
"typeid": selectedListTypeData.value.typeid.toString(),
"categoryid":
selectedListCategory.value.categoryid.toString(),
"jumlah": ctrlJumlah.value.text.toString(),
"catatan": ctrlCatatan.value.text.toString(),
// "userid": "1",
"userid": userIDLogin,
"namapengirim": ctrlNamaPengirim.value.text.toString(),
"url": "",
};
print(param);
ref.read(insertTransaksiProvider.notifier).insertTransaksi(
formattedDateTransaksi,
selectedListTypeData.value.typeid.toString(),
selectedListCategory.value.categoryid.toString(),
ctrlJumlah.value.text.toString(),
ctrlCatatan.value.text.toString(),
// "1",
userIDLogin,
ctrlNamaPengirim.value.text.toString(),
"",
);
},
),
),
),
),
),
);
}

View File

@@ -8,12 +8,10 @@ class TransaksiSelectKategoriWidget extends StatelessWidget {
super.key,
required this.listCategoryData,
required this.selectedListCategory,
required this.isLoading,
});
final ValueNotifier<List<ListCategory>> listCategoryData;
final ValueNotifier<ListCategory> selectedListCategory;
final ValueNotifier<bool> isLoading;
@override
Widget build(BuildContext context) {
@@ -39,7 +37,6 @@ class TransaksiSelectKategoriWidget extends StatelessWidget {
value: option,
child: Text(
option.categoryname ?? "",
overflow: TextOverflow.ellipsis,
style: Constant.body1(context: context).copyWith(
color: Constant.textBlack, fontWeight: FontWeight.w400),
),
@@ -48,14 +45,12 @@ class TransaksiSelectKategoriWidget extends StatelessWidget {
style: Constant.body1(context: context)
.copyWith(color: Constant.textBlack, fontWeight: FontWeight.w400),
value: selectedListCategory.value,
onChanged: !isLoading.value
? (ListCategory? newValue) {
// if (newValue) {
selectedListCategory.value = newValue!;
print(selectedListCategory.value.categoryid);
// }
}
: null,
onChanged: (ListCategory? newValue) {
// if (newValue) {
selectedListCategory.value = newValue!;
print(selectedListCategory.value.categoryid);
// }
},
buttonStyleData: ButtonStyleData(
height: Constant.getActualY(context: context, y: 80),
width: Constant.getActualX(context: context, x: 320),

View File

@@ -13,11 +13,9 @@ class TransaksiUploadAreaWidget extends StatelessWidget {
required this.fileDataBase64,
required this.pickFile,
required this.pickImage,
required this.isLoading,
});
final ValueNotifier<bool> isImage;
final ValueNotifier<bool> isLoading;
final ValueNotifier<XFile?> fileData;
final ValueNotifier<String> fileDataBase64;
final Function pickImage;
@@ -26,63 +24,60 @@ class TransaksiUploadAreaWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return InkWell(
onTap: !isLoading.value
? () {
showModalBottomSheet(
context: context,
builder: (context) {
return Container(
height: Constant.getActualY(context: context, y: 200),
padding: EdgeInsets.all(20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
children: [
IconButton(
onPressed: () {
Navigator.pop(context);
pickFile();
},
icon: Icon(
Icons.folder_copy_rounded,
size: 50,
color: Constant.pcBtnBackgroundColor,
)),
Text("Browse a file",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack))
],
),
Column(
children: [
IconButton(
onPressed: () {
Navigator.pop(context);
pickImage();
},
icon: Icon(
Icons.add_a_photo_rounded,
size: 50,
color: Constant.pcBtnBackgroundColor,
)),
Text("Take a picture",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack))
],
),
],
),
);
},
);
}
: null,
onTap: () {
print("tapped");
showModalBottomSheet(
context: context,
builder: (context) {
return Container(
height: Constant.getActualY(context: context, y: 200),
padding: EdgeInsets.all(20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
children: [
IconButton(
onPressed: () {
Navigator.pop(context);
pickFile();
},
icon: Icon(
Icons.folder_copy_rounded,
size: 50,
color: Constant.pcBtnBackgroundColor,
)),
Text("Browse a file",
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack))
],
),
Column(
children: [
IconButton(
onPressed: () {
Navigator.pop(context);
pickImage();
},
icon: Icon(
Icons.add_a_photo_rounded,
size: 50,
color: Constant.pcBtnBackgroundColor,
)),
Text("Take a picture",
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack))
],
),
],
),
);
},
);
},
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
@@ -152,7 +147,7 @@ class TransaksiUploadAreaWidget extends StatelessWidget {
)));
}),
),
if (fileData.value != null && !isLoading.value)
if (fileData.value != null)
IconButton(
onPressed: () {
fileData.value = null;

View File

@@ -1,5 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
@@ -13,11 +12,9 @@ import '../provider/current_user_provider.dart';
import '../screen/login/logout_provider.dart';
class CustomDrawer extends HookConsumerWidget {
// final String userCompany;
const CustomDrawer({
Key? key,
// required this.userCompany,
}) : super(key: key);
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
@@ -25,26 +22,6 @@ 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 {
@@ -57,7 +34,6 @@ class CustomDrawer extends HookConsumerWidget {
// Navigator.popAndPushNamed(context, loginRoute);
return;
}
M_CompanyName.value = await getCompanyName();
});
return () {};
}, []);
@@ -80,6 +56,7 @@ class CustomDrawer extends HookConsumerWidget {
shared.remove(bearerString);
shared.clear();
// Navigator.popAndPushNamed(context, loginRoute);
Navigator.of(context)
.pushNamedAndRemoveUntil(loginRoute, (route) => false);
}
@@ -91,249 +68,136 @@ class CustomDrawer extends HookConsumerWidget {
final currentMenu = ref.read(currentPageProvider);
return Container(
width: Constant.getActualXPhone(context: context, x: 300),
height: Constant.getActualYPhone(context: context, y: 844),
child: Drawer(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(0))),
child: Column(
children: [
Expanded(
child: ListView(
children: [
Container(
child: Image(
image:
AssetImage('images/logo_sismedika_landscape.png')),
),
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),
),
),
// 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.pcBtnBackgroundColor
: Constant.textGreyv2,
),
title: Text(
'Home',
style: TextStyle(
color: (currentMenu == 0)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
),
onTap: () {
// Handle navigation to Home screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 0);
Navigator.pushNamed(context, homeRoute);
},
),
ListTile(
leading: Icon(
Icons.money,
color: (currentMenu == 1)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
title: Text(
'Transaksi',
style: TextStyle(
color: (currentMenu == 1)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
),
onTap: () {
// Handle navigation to Transaksi screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 1);
Navigator.pushNamed(context, transaksiRoute);
},
),
ListTile(
leading: Icon(
Icons.history,
color: (currentMenu == 2)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
title: Text(
'History Transaksi',
style: TextStyle(
color: (currentMenu == 2)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
),
onTap: () {
// Handle navigation to User screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 2);
Navigator.pushNamed(context, historyTransaksiRoute);
},
),
ListTile(
leading: Icon(
Icons.feed,
color: (currentMenu == 3)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
title: Text(
'Report',
style: TextStyle(
color: (currentMenu == 3)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
),
onTap: () {
// Handle navigation to Transaksi screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 3);
Navigator.pushNamed(context, reportRoute);
},
),
ListTile(
leading: Icon(
Icons.account_balance,
color: (currentMenu == 4)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
title: Text(
'Change Company',
style: TextStyle(
color: (currentMenu == 4)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
),
onTap: () {
// Handle navigation to Transaksi screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 4);
Navigator.pushNamed(context, changeCompanyRoute);
},
),
ListTile(
leading: Icon(
Icons.lock_reset,
color: (currentMenu == 5)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
title: Text(
'Change Password',
style: TextStyle(
color: (currentMenu == 5)
? Constant.pcBtnBackgroundColor
: Constant.textGreyv2,
),
),
onTap: () {
// Handle navigation to Transaksi screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 5);
Navigator.pushNamed(context, changePasswordRoute);
},
),
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 ?? "",
);
},
),
],
),
),
// Versi Aplikasi
Padding(
padding: EdgeInsets.only(
right: Constant.getActualXPhone(context: context, x: 20),
bottom: Constant.getActualYPhone(context: context, y: 10),
),
child: Align(
alignment: Alignment.bottomRight,
child: Text(
'Versi ${Constant.version}',
style: Constant.titleH4Login(context: context)
.copyWith(color: Constant.textGrey),
),
),
),
],
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);
// Navigator.pushNamed(context, cameraExampleRoute);
},
),
ListTile(
title: Text(
'Coba Camera',
style: TextStyle(
color: (currentMenu == 10)
? Constant.textWhite
: Constant.textBlack,
),
),
tileColor: (currentMenu == 10)
? Constant.pcBtnBackgroundColor
: Colors.transparent,
onTap: () {
// Handle navigation to Home screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 10);
// Navigator.pushNamed(context, homeRoute);
Navigator.pushNamed(context, cobaCameraRoute);
},
),
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(
'Report',
style: TextStyle(
color: (currentMenu == 2)
? Constant.textWhite
: Constant.textBlack,
),
),
tileColor: (currentMenu == 2)
? Constant.pcBtnBackgroundColor
: Colors.transparent,
onTap: () {
// Handle navigation to Transaksi screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 2);
Navigator.pushNamed(context, reportRoute);
},
),
ListTile(
title: Text(
'User',
style: TextStyle(
color: (currentMenu == 3)
? Constant.textWhite
: Constant.textBlack,
),
),
tileColor: (currentMenu == 3)
? Constant.pcBtnBackgroundColor
: Colors.transparent,
onTap: () {
// Handle navigation to User screen
Navigator.pop(context);
ref.read(currentPageProvider.state).update((state) => 3);
Navigator.pushNamed(context, userRoute);
},
),
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

@@ -1,221 +0,0 @@
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

@@ -1,341 +0,0 @@
import 'dart:async';
import 'dart:convert';
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 CustomDrawerV2 extends HookConsumerWidget {
// final String userCompany;
const CustomDrawerV2({
Key? key,
// required this.userCompany,
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedUser = ref.read(currentUserProvider);
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 {
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;
}
M_CompanyName.value = await getCompanyName();
});
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(
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')),
),
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),
),
),
// 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.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);
},
),
ListTile(
leading: Icon(
Icons.money,
color: (currentMenu == 1)
? 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);
},
),
ListTile(
leading: Icon(
Icons.history,
color: (currentMenu == 2)
? 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);
},
),
ListTile(
leading: Icon(
Icons.feed,
color: (currentMenu == 3)
? 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);
},
),
// 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 ?? "",
);
},
),
Spacer(),
// Versi Aplikasi
ListTile(
title: Text(
'Versi ${Constant.version}',
style: Constant.titleH4Login(context: context)
.copyWith(color: Constant.textGrey),
),
onTap: () {},
),
],
),
),
);
}
}

View File

@@ -1,42 +0,0 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../app/constant.dart';
class FieldRowHistoryTransaksi extends HookConsumerWidget {
final String label;
final String value;
const FieldRowHistoryTransaksi({
Key? key,
required this.label,
required this.value,
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return Row(
children: [
Padding(
padding: EdgeInsets.only(left: 10),
child: SizedBox(
width: Constant.getActualXPhone(context: context, x: 100),
child: Text(label),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Text(':'),
),
Expanded(
child: Padding(
padding: EdgeInsets.only(right: 10),
child: Text(
value,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
),
],
);
}
}

View File

@@ -1,300 +0,0 @@
import 'package:app_petty_cash/widget/sankbar_widget.dart';
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';
class HistoryRowAtasWidget extends HookConsumerWidget {
final String icon_category_id;
final String icon_category_name;
final String amount;
final String tipe;
final String tglTransaksi;
// final ValueNotifier<bool> searchHistoryIsLoading;
const HistoryRowAtasWidget({
Key? key,
required this.icon_category_id,
required this.icon_category_name,
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 {
// 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);
if (response.statusCode == 200) {
return SvgPicture.network(
fileUrl,
semanticsLabel: 'Icon pizza',
);
} else {
return SvgPicture.network(
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg',
semanticsLabel: 'Icon pizza',
);
}
} catch (e) {
return SvgPicture.network(
'https://devone.aplikasi.web.id/pettycash-media/icon/icon_13.svg',
semanticsLabel: 'Icon pizza',
);
}
});
// 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(
children: [
// kiri
Container(
width: Constant.getActualXPhone(context: context, x: 38),
height: Constant.getActualYPhone(context: context, y: 38),
decoration: BoxDecoration(
color: Color.fromRGBO(241, 90, 41, 0.08),
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
),
child: getIconUrl(icon_category_id),
),
// tengah
Expanded(
child: Padding(
padding: EdgeInsets.only(
left: Constant.getActualYPhone(context: context, y: 20),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
icon_category_name,
style: Constant.body2_600(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack,
),
),
SizedBox(
height: Constant.getActualYPhone(
context: context,
y: 8,
),
),
Text(
amount,
style: Constant.body1_600(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.pcBtnBackgroundColor),
),
],
),
),
),
// kanan
Expanded(
child: Padding(
padding: EdgeInsets.only(
right: Constant.getActualYPhone(context: context, y: 8),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
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: Align(
alignment: Alignment.center,
child: Text(
tipe,
style: Constant.body1_600(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.pcBtnBackgroundColor,
fontSize: 14,
),
),
),
),
SizedBox(
height: Constant.getActualYPhone(
context: context,
y: 8,
),
),
Text(
formatDateString(tglTransaksi),
style: Constant.body1_600(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textGreyv2),
),
],
),
),
),
],
);
}
}

View File

@@ -9,10 +9,12 @@ import file_selector_macos
import path_provider_foundation
import shared_preferences_foundation
import url_launcher_macos
import video_player_avfoundation
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
}

View File

@@ -1,68 +1,68 @@
{
"info": {
"version": 1,
"author": "xcode"
"images" : [
{
"size" : "16x16",
"idiom" : "mac",
"filename" : "app_icon_16.png",
"scale" : "1x"
},
"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"
}
]
}
{
"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"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 167 KiB

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 B

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,22 +1,6 @@
# 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:
name: args
sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
url: "https://pub.dev"
source: hosted
version: "2.4.2"
async:
dependency: transitive
description:
@@ -57,22 +41,6 @@ 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:
@@ -85,10 +53,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.17.1"
version: "1.18.0"
convert:
dependency: transitive
description:
@@ -101,10 +69,10 @@ packages:
dependency: transitive
description:
name: cross_file
sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5"
sha256: fedaadfa3a6996f75211d835aaeb8fede285dae94262485698afd832371b9a5e
url: "https://pub.dev"
source: hosted
version: "0.3.3+7"
version: "0.3.3+8"
crypto:
dependency: transitive
description:
@@ -238,14 +206,6 @@ 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:
@@ -278,22 +238,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.4"
flutter_share:
dependency: "direct main"
description:
name: flutter_share
sha256: ae12c1cea13b35926a109824ffac601531e40cb94ad53eeae58625eceb3eaaaa
url: "https://pub.dev"
source: hosted
version: "2.0.0"
flutter_svg:
dependency: "direct main"
description:
name: flutter_svg
sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c
url: "https://pub.dev"
source: hosted
version: "2.0.9"
flutter_test:
dependency: "direct dev"
description: flutter
@@ -324,10 +268,10 @@ packages:
dependency: transitive
description:
name: http
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139
url: "https://pub.dev"
source: hosted
version: "1.1.0"
version: "1.1.2"
http_parser:
dependency: transitive
description:
@@ -336,14 +280,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.2"
image:
dependency: "direct main"
description:
name: image
sha256: "004a2e90ce080f8627b5a04aecb4cdfac87d2c3f3b520aa291260be5a32c033d"
url: "https://pub.dev"
source: hosted
version: "4.1.4"
image_picker:
dependency: "direct main"
description:
@@ -416,22 +352,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.17.0"
js:
dependency: transitive
description:
name: js
sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
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:
@@ -444,26 +364,26 @@ packages:
dependency: transitive
description:
name: matcher
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
version: "0.12.15"
version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
version: "0.2.0"
version: "0.5.0"
meta:
dependency: transitive
description:
name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
mime:
dependency: "direct main"
description:
@@ -488,14 +408,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.8.3"
path_parsing:
dependency: transitive
description:
name: path_parsing
sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
url: "https://pub.dev"
source: hosted
version: "1.0.1"
path_provider:
dependency: "direct main"
description:
@@ -584,14 +496,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.1.3"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
url: "https://pub.dev"
source: hosted
version: "5.4.0"
photo_view:
dependency: "direct main"
description:
@@ -616,14 +520,6 @@ 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:
@@ -697,18 +593,18 @@ packages:
dependency: transitive
description:
name: source_span
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.0"
version: "1.11.1"
state_notifier:
dependency: transitive
description:
@@ -721,10 +617,10 @@ packages:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
string_scanner:
dependency: transitive
description:
@@ -745,10 +641,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.5.1"
version: "0.6.1"
top_snackbar_flutter:
dependency: "direct main"
description:
@@ -829,30 +725,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.1.1"
vector_graphics:
dependency: transitive
description:
name: vector_graphics
sha256: "18f6690295af52d081f6808f2f7c69f0eed6d7e23a71539d75f4aeb8f0062172"
url: "https://pub.dev"
source: hosted
version: "1.1.9+2"
vector_graphics_codec:
dependency: transitive
description:
name: vector_graphics_codec
sha256: "531d20465c10dfac7f5cd90b60bbe4dd9921f1ec4ca54c83ebb176dbacb7bb2d"
url: "https://pub.dev"
source: hosted
version: "1.1.9+2"
vector_graphics_compiler:
dependency: transitive
description:
name: vector_graphics_compiler
sha256: "03012b0a33775c5530576b70240308080e1d5050f0faf000118c20e6463bc0ad"
url: "https://pub.dev"
source: hosted
version: "1.1.9+2"
vector_math:
dependency: transitive
description:
@@ -865,10 +737,10 @@ packages:
dependency: "direct main"
description:
name: video_player
sha256: "74b86e63529cf5885130c639d74cd2f9232e7c8a66cbecbddd1dcb9dbd060d1e"
sha256: fbf28ce8bcfe709ad91b5789166c832cb7a684d14f571a81891858fefb5bb1c2
url: "https://pub.dev"
source: hosted
version: "2.7.2"
version: "2.8.2"
video_player_android:
dependency: transitive
description:
@@ -881,10 +753,10 @@ packages:
dependency: transitive
description:
name: video_player_avfoundation
sha256: bf1a1322bf68bccd349982ba1f5a41314a3880861fb9a93d25d6d0a2345845f0
sha256: "309e3962795e761be010869bae65c0b0e45b5230c5cee1bec72197ca7db040ed"
url: "https://pub.dev"
source: hosted
version: "2.4.11"
version: "2.5.6"
video_player_platform_interface:
dependency: transitive
description:
@@ -897,18 +769,18 @@ packages:
dependency: transitive
description:
name: video_player_web
sha256: "9c34a243785feca23148bfcd772dbb803d63c9304488177ec4f3f4463802fcb7"
sha256: "34beb3a07d4331a24f7e7b2f75b8e2b103289038e07e65529699a671b6a6e2cb"
url: "https://pub.dev"
source: hosted
version: "2.0.17"
whatsapp_share:
dependency: "direct main"
version: "2.1.3"
web:
dependency: transitive
description:
name: whatsapp_share
sha256: d1884f302a52d9f400bc3d7d4274b77aad83424e08f425351cea8d13b4cb8649
name: web
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "2.0.2"
version: "0.3.0"
win32:
dependency: transitive
description:
@@ -925,22 +797,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.4"
xml:
dependency: transitive
description:
name: xml
sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
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"
dart: ">=3.2.0 <4.0.0"
flutter: ">=3.16.0"

View File

@@ -1,5 +1,4 @@
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.
@@ -17,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.2.0
version: 1.0.0+1
environment:
sdk: '>=3.0.6 <4.0.0'
@@ -51,16 +50,11 @@ dependencies:
flutter_multi_formatter: ^2.12.4
top_snackbar_flutter: ^3.1.0
url_launcher: ^6.1.13
flutter_svg: ^2.0.9
flutter_launcher_icons: ^0.13.1
image_picker: ^1.0.7
video_player: ^2.7.2
photo_view: ^0.14.0
mime: ^1.0.4
path_provider: ^2.1.2
flutter_share: ^2.0.0
whatsapp_share: ^2.0.2
image: ^4.1.4
dev_dependencies:
flutter_test:
@@ -76,24 +70,6 @@ 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: 715 B

After

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Some files were not shown because too many files have changed in this diff Show More