first commit

This commit is contained in:
Sas Andy
2024-10-01 09:37:38 +07:00
commit e3073d9823
268 changed files with 26689 additions and 0 deletions

270
lib/app/constant.dart Normal file
View File

@@ -0,0 +1,270 @@
import 'package:mitra_corporate/app/route.dart';
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:mitra_corporate/model/menu_model.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../model/surat_jalan_model.dart';
import '../widgets/custom_snackbar_widget.dart';
class Constant {
static String baseUrl = "";
static String protocol = "";
static String tokenName = "oneMitraPramita";
static double designHeight = 1024;
static double designWidth = 1440;
static String version = "Versi 1.01";
static String ipAddress = "";
// //color Theme
// static Color textBlack = Color(0xff212B36);
// static Color textGrey = Color(0xff919EAB);
// static Color textBlue = Color(0xff1939B7);
// static Color textWhite = Color(0xffffffff);
// static Color backgroundColor = Color(0xffFCFAFA);
// static Color primaryBlue = Color(0xff1939B7);
// static Color buttonPrimary1 = Color(0xff1E1BD3);
// static Color buttonPrimary2 = Color(0xff5959FF);
//typoGraphy
static TextStyle h1_700({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 36),
fontWeight: FontWeight.w700,
);
}
static TextStyle h2_600({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 28),
fontWeight: FontWeight.w600,
);
}
static TextStyle h3_400({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 24),
fontWeight: FontWeight.w600,
);
}
static TextStyle h4_600({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 18),
fontWeight: FontWeight.w600,
);
}
static TextStyle body1_600({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 16),
fontWeight: FontWeight.w600,
);
}
static TextStyle body2_400({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 16),
fontWeight: FontWeight.w500,
);
}
static TextStyle body2_700({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 16),
fontWeight: FontWeight.w700,
);
}
static TextStyle body3_600({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 14),
fontWeight: FontWeight.w600,
);
}
static TextStyle body3_500({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 14),
fontWeight: FontWeight.w500,
);
}
static TextStyle body3_400({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 14),
fontWeight: FontWeight.w400,
);
}
static TextStyle caption1_600({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 12),
fontWeight: FontWeight.w600,
);
}
static TextStyle caption1_400({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 12),
fontWeight: FontWeight.w400,
);
}
static TextStyle caption2_600({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 10),
fontWeight: FontWeight.w600,
);
}
static TextStyle caption2_400({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 10),
fontWeight: FontWeight.w400,
);
}
static TextStyle button_large({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 15),
fontWeight: FontWeight.w700,
);
}
static TextStyle button_medium({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 14),
fontWeight: FontWeight.w700,
);
}
static TextStyle button_small({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualX(context: context, x: 13),
fontWeight: FontWeight.w700,
);
}
//size convertion
static double getActualX({
required BuildContext context,
required double x,
}) {
return x / designWidth * MediaQuery.of(context).size.width;
}
static double getActualY({
required BuildContext context,
required double y,
}) {
return y / designHeight * MediaQuery.of(context).size.height;
}
static String convertToIdr(dynamic number, int decimalDigit) {
NumberFormat currencyFormatter = NumberFormat.currency(
locale: 'id',
symbol: 'Rp ',
decimalDigits: decimalDigit,
);
return currencyFormatter.format(number);
}
//color Theme
static Color textBlack = Color(0xff212B36);
static Color textGrey = Color(0xff637381);
static Color textBlue = Color(0xff1939B7);
static Color textWhite = Color(0xffffffff);
static Color textYellow = Color(0xffB78103);
static Color textGreen = Color(0xff229A16);
static Color textPurple = Color(0xffBF07FF);
static Color backgroundColor = Color(0xffFCFAFA);
static Color primaryBlue = Color(0xff1939B7);
static Color buttonPrimary1 = Color(0xff1E1BD3);
static Color buttonPrimary2 = Color(0xff5959FF);
static Color grey_200 = Color(0xffF4F6F8);
static Color yellow_016 = Color(0xffFFC107).withOpacity(0.16);
static Color green_016 = Color(0xff54D62C).withOpacity(0.16);
static Color blue_016 = Color(0xff1890FF).withOpacity(0.16);
static Color green = Color(0xff00AB55);
static Color purple_016 = Color(0xffbf07ff).withOpacity(0.16);
static Color selectedMenuBg = Color(0xffFF0000).withOpacity(0.1);
//Pramita color
static Color primaryRed = Color(0xffFF0000);
static List<dateFilterModel> dateFilter = [
dateFilterModel(id: "1", name: "Tanggal Surat Jalan"),
dateFilterModel(id: "2", name: "Tanggal Kedatangan"),
];
static List<MenuModel> menuList = [
MenuModel(
icon: EvaIcons.grid,
subValue: [1],
title: "Dashboard",
index: 1,
mainValue: 1),
MenuModel(
icon: EvaIcons.fileAdd,
subValue: [2],
title: "Registrasi Pasien",
index: 2,
mainValue: 2),
MenuModel(
icon: EvaIcons.clipboard,
subValue: [3, 5],
title: "Kirim Order",
index: 3,
mainValue: 3),
MenuModel(
icon: EvaIcons.shoppingCart,
subValue: [6],
title: "List Order",
index: 4,
mainValue: 6),
// MenuModel(
// icon: EvaIcons.fileText,
// subValue: [4, 7],
// title: "Hasil",
// index: 5,
// mainValue: 4),
];
static List<MenuModel> getMenuModel() {
List<MenuModel> data = menuList;
data.sort(
(a, b) => a.index.compareTo(b.index),
);
return data;
}
static autoLogout({
required BuildContext context,
required String msg,
bool? isSplashScreen,
}) async {
if (msg == "Invalid token") {
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.remove(tokenName);
Navigator.pushNamed(context, loginRoute);
if (isSplashScreen != true) {
SanckbarWidget(
context, "Invalid token, please login again", snackbarType.warning);
}
}
}
static setBaseUrl(String text, String? protocol) {
var prt = protocol;
if (protocol == null) {
prt = "https://";
}
// baseUrl = "$protocol//devbandungraya.aplikasi.web.id/one-api/one_mitra/";
// ipAddress = "devbandungraya.aplikasi.web.id";
// protocol = protocol;
baseUrl = "$protocol//$text/one-api/one_mitra/";
ipAddress = text;
print(baseUrl);
}
}

View File

@@ -0,0 +1,7 @@
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_web/webview_flutter_web.dart';
void registerWebViewWebImplementation() {
// WebView.platform = WebWebViewPlatform();
WebViewPlatform.instance = WebWebViewPlatform();
}

View File

@@ -0,0 +1,3 @@
void registerWebViewWebImplementation() {
//
}

106
lib/app/route.dart Normal file
View File

@@ -0,0 +1,106 @@
import 'package:flutter/material.dart';
import 'package:mitra_corporate/screen/home/home_screen.dart';
import 'package:mitra_corporate/screen/loging/loging.dart';
import 'package:mitra_corporate/screen/splash_screen.dart/splash_screen.dart';
import '../screen/login/login_screen.dart';
const loginRoute = "/LoginScreen";
const registrasiPasienRoute = "/RegistrasiPasienScrenn";
const suratJalanRoute = "/SuratJalanScreen";
const suratJalanDetailRoute = "/SuratJalanDetailScreen";
const homeRoute = "/homeRoute";
const dashboardRoute = "/DashboardScreen";
const splashRoute = "/splashRoute";
const logingRoute = "/logingRoute";
class AppRoute {
static Route<dynamic>? generateRoute(RouteSettings settings) {
if (settings.name == loginRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
padding: const EdgeInsets.all(0),
textScaler: TextScaler.linear(1.0),
),
child: LoginScreen());
});
}
// if (settings.name == dashboardRoute) {
// return MaterialPageRoute(builder: (context) {
// return MediaQuery(
// data: MediaQuery.of(context).copyWith(
// textScaleFactor: 1.0,
// padding: const EdgeInsets.all(0),
// ),
// child: DashboardScreen());
// });
// }
if (settings.name == homeRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
padding: const EdgeInsets.all(0),
textScaler: TextScaler.linear(1.0),
),
child: HomeScreen());
});
}
// if (settings.name == registrasiPasienRoute) {
// return MaterialPageRoute(builder: (context) {
// return MediaQuery(
// data: MediaQuery.of(context).copyWith(
// textScaleFactor: 1.0,
// padding: const EdgeInsets.all(0),
// ),
// child: const RegistrasiPasienScreen());
// });
// }
// if (settings.name == suratJalanRoute) {
// return MaterialPageRoute(builder: (context) {
// return MediaQuery(
// data: MediaQuery.of(context).copyWith(
// textScaleFactor: 1.0,
// padding: const EdgeInsets.all(0),
// ),
// child: const SuratJalanScreen());
// });
// }
// if (settings.name == suratJalanDetailRoute) {
// return MaterialPageRoute(builder: (context) {
// return MediaQuery(
// data: MediaQuery.of(context).copyWith(
// textScaleFactor: 1.0,
// padding: const EdgeInsets.all(0),
// ),
// child: const SuratJalanDetailScreen());
// });
// }
if (settings.name == splashRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
padding: const EdgeInsets.all(0),
textScaler: TextScaler.linear(1.0),
),
child: const SplashScreen());
});
}
if (settings.name == logingRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
padding: const EdgeInsets.all(0),
textScaler: TextScaler.linear(1.0),
),
child: const LogingScreen());
});
}
return null;
}
}

162
lib/main.dart Normal file
View File

@@ -0,0 +1,162 @@
import 'dart:html';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:mitra_corporate/screen/splash_screen.dart/splash_screen.dart';
import 'app/constant.dart';
import 'app/route.dart';
import 'app/register_webview_rtub.dart'
if (dart.library.html) 'app/register_webview.dart';
void main() {
// runApp(const MyApp());
// registerWebViewWebImplementation();
WidgetsFlutterBinding.ensureInitialized();
Constant.setBaseUrl(window.location.host, window.location.protocol);
runApp(ProviderScope(observers: [], child: MyApp()));
// FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
// runApp(ProviderScope(observers: [Logger()], child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
// localizationsDelegates: [
// DefaultMaterialLocalizations.delegate,
// DefaultCupertinoLocalizations.delegate,
// DefaultWidgetsLocalizations.delegate,
// ],
// locale: Locale("id", "ID"),
debugShowCheckedModeBanner: false,
title: 'App Mitra',
localizationsDelegates: [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
// supportedLocales: [
// Locale('en', ''),
// Locale('id', ''), // arabic, no country code
// ],
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.light(
brightness: Brightness.light,
primary: Constant.primaryRed,
surfaceTint: Color(0xff904a46),
onPrimary: Color(0xffffffff),
primaryContainer: Color(0xffffdad7),
onPrimaryContainer: Color(0xff3b0809),
secondary: Color(0xff775654),
onSecondary: Color(0xffffffff),
secondaryContainer: Color(0xffffdad7),
onSecondaryContainer: Color(0xff2c1514),
tertiary: Color(0xff735b2e),
onTertiary: Color(0xffffffff),
tertiaryContainer: Color(0xffffdea7),
onTertiaryContainer: Color(0xff271900),
error: Color(0xffba1a1a),
onError: Color(0xffffffff),
errorContainer: Color(0xffffdad6),
onErrorContainer: Color(0xff410002),
surface: Color(0xfffff8f7),
onSurface: Color(0xff231919),
onSurfaceVariant: Color(0xff534342),
outline: Color(0xff857371),
outlineVariant: Color(0xffd8c2c0),
shadow: Color(0xff000000),
scrim: Color(0xff000000),
inverseSurface: Color(0xff382e2d),
inversePrimary: Color(0xffffb3ae),
primaryFixed: Color(0xffffdad7),
onPrimaryFixed: Color(0xff3b0809),
primaryFixedDim: Color(0xffffb3ae),
onPrimaryFixedVariant: Color(0xff733330),
secondaryFixed: Color(0xffffdad7),
onSecondaryFixed: Color(0xff2c1514),
secondaryFixedDim: Color(0xffe7bdb9),
onSecondaryFixedVariant: Color(0xff5d3f3d),
tertiaryFixed: Color(0xffffdea7),
onTertiaryFixed: Color(0xff271900),
tertiaryFixedDim: Color(0xffe2c28c),
onTertiaryFixedVariant: Color(0xff594319),
surfaceDim: Color(0xffe8d6d4),
surfaceBright: Color(0xfffff8f7),
surfaceContainerLowest: Color(0xffffffff),
surfaceContainerLow: Color(0xfffff0ef),
surfaceContainer: Color(0xfffceae8),
surfaceContainerHigh: Color(0xfff6e4e2),
surfaceContainerHighest: Color(0xfff1dedd),
),
scaffoldBackgroundColor: Constant.backgroundColor,
dialogBackgroundColor: Colors.white,
buttonTheme: ButtonThemeData(
buttonColor: Constant.primaryRed,
),
cardColor: Colors.white,
cardTheme: CardTheme(color: Colors.white),
datePickerTheme: DatePickerThemeData(
locale: Locale("id", 'ID'),
backgroundColor: Colors.white,
headerForegroundColor: Colors.white,
headerBackgroundColor: Constant.primaryRed),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.pressed)) {
return Constant.primaryRed.withOpacity(0.5);
}
return Constant.primaryRed;
}),
shape: WidgetStatePropertyAll(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))))),
fontFamily: "OpenSans",
primaryColor: Constant.primaryRed,
primaryColorLight: Constant.primaryRed,
primarySwatch: MaterialColor(0xffFF0000, {
0: Color(0xffFF0000),
50: Color(0xffFF0000),
100: Color(0xffFF0000),
200: Color(0xffFF0000),
300: Color(0xffFF0000),
400: Color(0xffFF0000),
500: Color(0xffFF0000),
600: Color(0xffFF0000),
700: Color(0xffFF0000),
800: Color(0xffFF0000),
900: Color(0xffFF0000)
}),
// primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity),
initialRoute: splashRoute,
onGenerateRoute: AppRoute.generateRoute,
home: SplashScreen(),
);
}
}
class Logger extends ProviderObserver {
@override
void didUpdateProvider(
ProviderBase<Object?> provider,
Object? previousValue,
Object? newValue,
ProviderContainer container,
) {
// var a = jsonEncode(newValue);
print('''
{
"provider": "${provider.name ?? provider.runtimeType}",
"newValue": "$newValue"
}''');
}
}

52
lib/model/auth_model.dart Normal file
View File

@@ -0,0 +1,52 @@
class AuthModel {
String? mUserID;
String? mUserMCompanyID;
String? mUserMMouID;
String? mUserUsername;
String? companyName;
String? MUserSRegionalID;
String? ip;
String? agent;
String? token;
bool? isRememberMe;
AuthModel(
{this.mUserID,
this.mUserMCompanyID,
this.mUserMMouID,
this.companyName,
this.ip,
this.agent,
this.token,
this.mUserUsername,
this.MUserSRegionalID,
this.isRememberMe});
AuthModel.fromJson(Map<String, dynamic> json) {
mUserID = json['M_UserID'];
mUserMCompanyID = json['M_UserM_CompanyID'];
mUserMMouID = json['M_UserM_MouID'];
companyName = json['company_name'];
mUserUsername = json['M_UserUsername'];
ip = json['ip'];
agent = json['agent'];
token = json['token'];
MUserSRegionalID = json['M_UserS_RegionalID'];
isRememberMe = json['is_remember_me'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['M_UserID'] = mUserID;
data['M_UserM_CompanyID'] = mUserMCompanyID;
data['M_UserM_MouID'] = mUserMMouID;
data['company_name'] = companyName;
data['ip'] = ip;
data['agent'] = agent;
data['M_UserUsername'] = mUserUsername;
data['token'] = token;
data['M_UserS_RegionalID'] = MUserSRegionalID;
data['is_remember_me'] = isRememberMe;
return data;
}
}

View File

@@ -0,0 +1,56 @@
class ChartDataModel {
List<String>? n;
List<String>? y;
List<String>? t;
List<String>? s;
ChartDataModel({this.n, this.y, this.t, this.s});
ChartDataModel.fromJson(Map<String, dynamic> json) {
if (json['N'] != null) {
n = <String>[];
json['N'].forEach((v) {
if (v.isNotEmpty) {
n!.add(v.toString());
}
});
}
if (json['Y'] != null) {
y = <String>[];
json['Y'].forEach((v) {
if (v.isNotEmpty) {
y!.add(v.toString());
}
});
}
if (json['T'] != null) {
t = <String>[];
json['T'].forEach((v) {
if (v.isNotEmpty) {
t!.add(v.toString());
}
});
}
if (json['S'] != null) {
s = <String>[];
json['S'].forEach((v) {
if (v.isNotEmpty) {
s!.add(v.toString());
}
});
}
// n = json['N'].cast<String>();
// p = json['P'].cast<String>();
// d = json['D'].cast<String>();
// s = json['S'].cast<String>();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['N'] = n;
data['Y'] = y;
data['T'] = t;
data['S'] = s;
return data;
}
}

View File

@@ -0,0 +1,101 @@
import 'package:mitra_corporate/model/order_model.dart';
class CreateSuratJalanModel {
Order? order;
List<OrderModel>? orderDetail;
String? token;
CreateSuratJalanModel({this.order, this.orderDetail, this.token});
CreateSuratJalanModel.fromJson(Map<String, dynamic> json) {
order = json['order'] != null ? Order.fromJson(json['order']) : null;
if (json['order_detail'] != null) {
orderDetail = <OrderModel>[];
json['order_detail'].forEach((v) {
orderDetail!.add(OrderModel.fromJson(v));
});
}
token = json['token'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (order != null) {
data['order'] = order!.toJson();
}
if (orderDetail != null) {
data['order_detail'] = orderDetail!.map((v) => v.toJson()).toList();
}
data['token'] = token;
return data;
}
}
class Order {
String? staffId;
String? noRef;
String? date;
String? regionalId;
String? regionalName;
String? destinationId;
String? destinationName;
String? temperature;
String? typeId;
String? typeName;
String? noResi;
String? note;
String? branchCode;
String? companyId;
Order(
{this.staffId,
this.noRef,
this.date,
this.destinationId,
this.temperature,
this.typeId,
this.noResi,
this.typeName,
this.note,
this.regionalId,
this.regionalName,
this.destinationName,
this.branchCode,
this.companyId});
Order.fromJson(Map<String, dynamic> json) {
staffId = json['staff_id'];
noRef = json['no_ref'];
date = json['date'];
destinationId = json['destination_id'];
regionalId = json['regional_id'];
regionalName = json['regional_name'];
destinationName = json['destination_name'];
temperature = json['temperature'];
typeId = json['type_id'];
noResi = json['no_resi'];
note = json['note'];
branchCode = json['branch_code'];
companyId = json['company_id'];
typeName = json['type_name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['staff_id'] = staffId;
data['no_ref'] = noRef;
data['date'] = date;
data['destination_id'] = destinationId;
data['regional_id'] = regionalId;
data['regional_name'] = regionalName;
data['destination_name'] = destinationName;
data['temperature'] = temperature;
data['type_id'] = typeId;
data['no_resi'] = noResi;
data['note'] = note;
data['branch_code'] = branchCode;
data['company_id'] = companyId;
data['type_name'] = typeName;
return data;
}
}

View File

@@ -0,0 +1,21 @@
class DeliveryTypeModel {
String? id;
String? name;
String? isAgent;
DeliveryTypeModel({this.id, this.name, this.isAgent});
DeliveryTypeModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
isAgent = json['isAgent'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
data['isAgent'] = isAgent;
return data;
}
}

View File

@@ -0,0 +1,25 @@
class DestinationModel {
String? branchId;
String? branchCode;
String? branchName;
String? regionalId;
DestinationModel(
{this.branchId, this.branchCode, this.branchName, this.regionalId});
DestinationModel.fromJson(Map<String, dynamic> json) {
branchId = json['branch_id'];
branchCode = json['branch_code'];
branchName = json['branch_name'];
regionalId = json['regional_id'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['branch_id'] = branchId;
data['branch_code'] = branchCode;
data['branch_name'] = branchName;
data['regional_id'] = regionalId;
return data;
}
}

15
lib/model/menu_model.dart Normal file
View File

@@ -0,0 +1,15 @@
import 'package:flutter/material.dart';
class MenuModel {
String title = "";
int mainValue = 0;
List<int> subValue = [];
IconData icon = Icons.abc;
int index = 0;
MenuModel(
{required this.icon,
required this.subValue,
required this.title,
required this.index,
required this.mainValue});
}

190
lib/model/order_model.dart Normal file
View File

@@ -0,0 +1,190 @@
class OrderModel {
String? orderId;
String? orderNumber;
String? patientId;
String? patientName;
String? status;
String? prefix;
String? suffix;
String? dob;
String? NIK;
String? NIP;
String? title;
String? sexID;
String? hp;
String? address;
String? note;
String? diagnosis;
String? statusQr;
String? statusPemeriksaan;
String? jabatan;
String? kedudukan;
String? lokasi;
String? pekerjaan;
String? noRM;
String? isQr;
List<String>? sample;
List<String>? testsID;
List<String>? testDetail;
List<String>? bahan;
List<String>? tests;
List<String>? paket;
List<String>? paketDetail;
OrderModel(
{this.orderId,
this.orderNumber,
this.patientId,
this.patientName,
this.sample,
this.tests,
this.testsID,
this.status,
this.NIK,
this.NIP,
this.address,
this.diagnosis,
this.dob,
this.hp,
this.note,
this.prefix,
this.noRM,
this.sexID,
this.suffix,
this.title,
this.testDetail,
this.paket,
this.paketDetail,
this.statusQr,
this.statusPemeriksaan,
this.jabatan,
this.kedudukan,
this.lokasi,
this.pekerjaan,
this.isQr,
this.bahan});
OrderModel.fromJson(Map<String, dynamic> json) {
orderId = json['order_id'];
orderNumber = json['order_number'];
patientId = json['patient_id'];
patientName = json['patient_name'];
status = json['status'];
prefix = json['prefix'];
suffix = json['suffix'];
dob = json['dob'];
noRM = json['noRM'];
NIK = json['NIK'];
NIP = json['NIP'];
title = json['title'];
sexID = json['sexID'];
hp = json['hp'];
address = json['address'];
note = json['note'];
diagnosis = json['diagnosis'];
statusQr = json['status_qr'];
statusPemeriksaan = json['status_pemeriksaan'];
jabatan = json['jabatan'];
kedudukan = json['kedudukan'];
lokasi = json['lokasi'];
pekerjaan = json['pekerjaan'];
isQr = json['is_qr'];
// sample = json['sample'].cast<String>();
// bahan = json['bahan'].cast<String>();
// tests = json['tests'].cast<String>();
// testsID = json['testsID'].cast<String>();
if (json['sample'] != null) {
sample = <String>[];
json['sample'].forEach((v) {
if (v.isNotEmpty) {
sample!.add(v.toString());
}
});
}
if (json['bahan'] != null) {
bahan = <String>[];
json['bahan'].forEach((v) {
if (v.isNotEmpty) {
bahan!.add(v.toString());
}
});
}
if (json['tests'] != null) {
tests = <String>[];
json['tests'].forEach((v) {
if (v != "") {
tests!.add(v.toString());
}
});
}
if (json['testsID'] != null) {
testsID = <String>[];
json['testsID'].forEach((v) {
if (v.isNotEmpty) {
testsID!.add(v.toString());
}
});
}
if (json['testDetail'] != null) {
testDetail = <String>[];
json['testDetail'].forEach((v) {
if (v.isNotEmpty) {
testDetail!.add(v.toString());
}
});
}
if (json['packet'] != null) {
paket = <String>[];
json['packet'].forEach((v) {
if (v != "") {
paket!.add(v.toString());
}
});
}
if (json['packetDetail'] != null) {
paketDetail = <String>[];
json['packetDetail'].forEach((v) {
if (v.isNotEmpty) {
paketDetail!.add(v.toString());
}
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['order_id'] = orderId;
data['order_number'] = orderNumber;
data['patient_id'] = patientId;
data['patient_name'] = patientName;
data['sample'] = sample;
data['bahan'] = bahan;
data['tests'] = tests;
data['status'] = status;
data['testsID'] = testsID;
data['NIK'] = NIK;
data['nip'] = NIP;
data['address'] = address;
data['diagnosis'] = diagnosis;
data['dob'] = dob;
data['hp'] = hp;
data['note'] = note;
data['prefix'] = prefix;
data['sexID'] = sexID;
data['suffix'] = suffix;
data['title'] = title;
data['testDetail'] = testDetail;
data['packet'] = paket;
data['packetDetail'] = paketDetail;
data['status_qr'] = statusQr;
data['status_pemeriksaan'] = statusPemeriksaan;
data['kedudukan'] = kedudukan;
data['jabatan'] = jabatan;
data['lokasi'] = lokasi;
data['pekerjaan'] = pekerjaan;
data['noRM'] = noRM;
data['is_qr'] = isQr;
return data;
}
}

View File

@@ -0,0 +1,80 @@
class PatientModel {
String? id;
String? prefix;
String? name;
String? suffix;
String? dob;
String? titleId;
String? sexId;
String? hp;
String? nik;
String? nip;
String? noRM;
String? jabatan;
String? kedudukan;
String? lokasi;
String? pekerjaan;
String? address;
String? statusDelete;
PatientModel(
{this.id,
this.prefix,
this.name,
this.suffix,
this.dob,
this.titleId,
this.sexId,
this.hp,
this.nik,
this.nip,
this.noRM,
this.jabatan,
this.kedudukan,
this.lokasi,
this.pekerjaan,
this.statusDelete,
this.address});
PatientModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
prefix = json['prefix'];
name = json['name'];
suffix = json['suffix'];
dob = json['dob'];
titleId = json['title_id'];
sexId = json['sex_id'];
hp = json['hp'];
nik = json['nik'];
nip = json['nip'];
noRM = json['noRM'];
address = json['address'];
jabatan = json['jabatan'];
kedudukan = json['kedudukan'];
lokasi = json['lokasi'];
pekerjaan = json['pekerjaan'];
statusDelete = json['status_delete'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['prefix'] = prefix;
data['name'] = name;
data['suffix'] = suffix;
data['dob'] = dob;
data['title_id'] = titleId;
data['sex_id'] = sexId;
data['hp'] = hp;
data['address'] = address;
data['nik'] = nik;
data['nip'] = nip;
data['noRM'] = noRM;
data['kedudukan'] = kedudukan;
data['jabatan'] = jabatan;
data['lokasi'] = lokasi;
data['pekerjaan'] = pekerjaan;
data['status_delete'] = statusDelete;
return data;
}
}

View File

@@ -0,0 +1,74 @@
import 'package:mitra_corporate/model/destination_model.dart';
import 'package:mitra_corporate/widgets/custom_text_field.dart';
class RegistrationFilterModel {
List<CustomDropDownModel>? titles;
List<CustomDropDownModel>? gender;
List<RegionalModel>? regionals;
RegistrationFilterModel({this.titles, this.gender, this.regionals});
RegistrationFilterModel.fromJson(Map<String, dynamic> json) {
if (json['titles'] != null) {
titles = <CustomDropDownModel>[];
json['titles'].forEach((v) {
titles!.add(CustomDropDownModel.fromJson(v));
});
}
if (json['gender'] != null) {
gender = <CustomDropDownModel>[];
json['gender'].forEach((v) {
gender!.add(CustomDropDownModel.fromJson(v));
});
}
if (json['regional'] != null) {
regionals = <RegionalModel>[];
json['regional'].forEach((v) {
regionals!.add(RegionalModel.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (titles != null) {
data['titles'] = titles!.map((v) => v.toJson()).toList();
}
if (gender != null) {
data['gender'] = gender!.map((v) => v.toJson()).toList();
}
if (regionals != null) {
data['regional'] = regionals!.map((v) => v.toJson()).toList();
}
return data;
}
}
class RegionalModel {
String? regionalId;
String? regionalName;
List<DestinationModel>? branch;
RegionalModel({this.regionalId, this.regionalName, this.branch});
RegionalModel.fromJson(Map<String, dynamic> json) {
regionalId = json['regional_id'];
regionalName = json['regional_name'];
if (json['branch'] != null) {
branch = <DestinationModel>[];
json['branch'].forEach((v) {
branch!.add(DestinationModel.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['regional_id'] = regionalId;
data['regional_name'] = regionalName;
if (branch != null) {
data['branch'] = branch!.map((v) => v.toJson()).toList();
}
return data;
}
}

View File

@@ -0,0 +1,378 @@
import 'package:flutter/material.dart';
class RegistrationModel {
String? patientId;
String? orderID;
List<Paket>? paket;
PatientData? patientData;
List<Tests>? tests;
List<Specimens>? specimens;
List<Bahan>? bahan;
String? total;
String? token;
RegistrationModel(
{this.patientData,
this.tests,
this.specimens,
this.total,
this.bahan,
this.patientId,
this.paket,
this.orderID,
this.token});
RegistrationModel.fromJson(Map<String, dynamic> json) {
patientData = json['patient_data'] != null
? PatientData.fromJson(json['patient_data'])
: null;
if (json['tests'] != null) {
tests = <Tests>[];
json['tests'].forEach((v) {
tests!.add(Tests.fromJson(v));
});
}
if (json['specimens'] != null) {
specimens = <Specimens>[];
json['specimens'].forEach((v) {
specimens!.add(Specimens.fromJson(v));
});
}
if (json['bahan'] != null) {
bahan = <Bahan>[];
json['bahan'].forEach((v) {
bahan!.add(Bahan.fromJson(v));
});
}
if (json['paket'] != null) {
paket = <Paket>[];
json['paket'].forEach((v) {
paket!.add(Paket.fromJson(v));
});
}
total = json['total'];
patientId = json['patient_id'];
token = json['token'];
orderID = json['orderID'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (patientData != null) {
data['patient_data'] = patientData!.toJson();
}
if (tests != null) {
data['tests'] = tests!.map((v) => v.toJson()).toList();
}
if (specimens != null) {
data['specimens'] = specimens!.map((v) => v.toJson()).toList();
}
if (bahan != null) {
data['bahan'] = bahan!.map((v) => v.toJson()).toList();
}
if (paket != null) {
data['paket'] = paket!.map((v) => v.toJson()).toList();
}
data['total'] = total;
data['patient_id'] = patientId;
data['token'] = token;
data['orderID'] = orderID;
return data;
}
}
class PatientData {
String? saluation;
String? prefix;
String? name;
String? suffix;
String? dob;
String? nik;
String? nip;
String? withoutNIK;
String? gender;
String? hp;
String? address;
String? diagnosis;
String? note;
String? noRM;
String? jabatan;
String? kedudukan;
String? lokasi;
String? pekerjaan;
PatientData(
{this.saluation,
this.prefix,
this.name,
this.suffix,
this.dob,
this.nik,
this.nip,
this.withoutNIK,
this.gender,
this.hp,
this.address,
this.diagnosis,
this.noRM,
this.jabatan,
this.kedudukan,
this.lokasi,
this.pekerjaan,
this.note});
PatientData.fromJson(Map<String, dynamic> json) {
saluation = json['saluation'];
prefix = json['prefix'];
name = json['name'];
suffix = json['suffix'];
dob = json['dob'];
nik = json['nik'];
nip = json['nip'];
withoutNIK = json['without_nik'];
gender = json['gender'];
hp = json['hp'];
address = json['address'];
diagnosis = json['diagnosis'];
note = json['note'];
noRM = json['noRM'];
jabatan = json['jabatan'];
kedudukan = json['kedudukan'];
lokasi = json['lokasi'];
pekerjaan = json['pekerjaan'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['saluation'] = saluation;
data['prefix'] = prefix;
data['name'] = name;
data['suffix'] = suffix;
data['dob'] = dob;
data['nik'] = nik;
data['nip'] = nip;
data['without_nik'] = withoutNIK;
data['gender'] = gender;
data['hp'] = hp;
data['address'] = address;
data['diagnosis'] = diagnosis;
data['note'] = note;
data['noRM'] = noRM;
data['kedudukan'] = kedudukan;
data['jabatan'] = jabatan;
data['lokasi'] = lokasi;
data['pekerjaan'] = pekerjaan;
return data;
}
}
class Tests {
String? tab;
String? id;
String? detailID;
String? name;
String? isPaket;
List<Specimens>? specimen;
List<Bahan>? bahan;
String? price;
String? date;
String? sasCode;
bool? dateVal;
Tests(
{this.id,
this.name,
this.specimen,
this.price,
this.date,
this.detailID,
this.tab,
this.isPaket,
this.dateVal,
this.sasCode});
Tests.fromJson(Map<String, dynamic> json) {
id = json['id'].toString();
tab = json['tab'].toString();
name = json['name'].toString();
isPaket = json['is_paket'].toString();
if (json['specimen'] != null) {
specimen = <Specimens>[];
json['specimen'].forEach((v) {
specimen!.add(Specimens.fromJson(v));
});
}
if (json['bahan'] != null) {
bahan = <Bahan>[];
json['bahan'].forEach((v) {
bahan!.add(Bahan.fromJson(v));
});
}
price = json['price'].toString();
detailID = json['detailID'].toString();
date = json['date'].toString();
dateVal = json['dateVal'];
sasCode = json['sasCode'].toString();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['tab'] = tab;
data['name'] = name;
data['is_paket'] = isPaket;
if (specimen != null) {
data['specimen'] = specimen!.map((v) => v.toJson()).toList();
}
if (bahan != null) {
data['bahan'] = bahan!.map((v) => v.toJson()).toList();
}
data['price'] = price;
data['detailID'] = detailID;
data['date'] = date;
data['dateVal'] = dateVal;
data['sasCode'] = sasCode;
return data;
}
}
class Specimens {
String? id;
String? detailID;
String? name;
String? amount;
TextEditingController ctr = TextEditingController(text: "0");
Specimens(
{this.id, this.name, this.amount, this.detailID, required this.ctr});
Specimens.fromJson(Map<String, dynamic> json) {
id = json['id'];
detailID = json['detailID'];
name = json['name'];
amount = json['amount'];
ctr = TextEditingController(text: "0");
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
data['detailID'] = detailID;
data['amount'] = ctr.text;
data["ctr"] = ctr.text;
return data;
}
}
class Bahan {
String? id;
String? detailID;
String? name;
String? amount;
TextEditingController ctr = TextEditingController(text: "0");
Bahan({this.id, this.name, this.amount, this.detailID, required this.ctr});
Bahan.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
amount = json['amount'];
detailID = json['detailID'];
ctr = TextEditingController(text: "0");
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
data['detailID'] = detailID;
data['amount'] = ctr.text;
data["ctr"] = ctr.text;
return data;
}
}
class GetSpecimenModel {
String? id;
String? tab;
List<Specimens>? specimen;
List<Bahan>? bahan;
GetSpecimenModel({this.id, this.tab, this.specimen, this.bahan});
GetSpecimenModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
tab = json['tab'];
if (json['specimen'] != null) {
specimen = <Specimens>[];
json['specimen'].forEach((v) {
specimen!.add(Specimens.fromJson(v));
});
}
if (json['bahan'] != null) {
bahan = <Bahan>[];
json['bahan'].forEach((v) {
bahan!.add(Bahan.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['tab'] = tab;
if (specimen != null) {
data['specimen'] = specimen!.map((v) => v.toJson()).toList();
}
if (bahan != null) {
data['bahan'] = bahan!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Paket {
String? id;
String? detailID;
String? detail;
String? name;
String? price;
String? type;
String? arrTest;
Paket({
this.id,
this.name,
this.detailID,
this.detail,
this.arrTest,
this.price,
this.type,
});
Paket.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
detailID = json['detail_id'];
arrTest = json['arrTest'];
detail = json['detail'];
arrTest = json['price'];
detail = json['type'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
data['detail'] = detail;
data['arrTest'] = arrTest;
data['detail_id'] = detailID;
data['price'] = price;
data['type'] = type;
return data;
}
}

View File

@@ -0,0 +1,30 @@
import 'package:mitra_corporate/model/order_model.dart';
class SearchOrderModel {
List<OrderModel>? orders;
String? total;
int? totalPage;
SearchOrderModel({this.orders, this.total, this.totalPage});
SearchOrderModel.fromJson(Map<String, dynamic> json) {
if (json['data'] != null) {
orders = <OrderModel>[];
json['data'].forEach((v) {
orders!.add(OrderModel.fromJson(v));
});
}
total = json['total'];
totalPage = json['total_page'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (orders != null) {
data['data'] = orders!.map((v) => v.toJson()).toList();
}
data['total'] = total;
data['total_page'] = totalPage;
return data;
}
}

View File

@@ -0,0 +1,30 @@
import 'package:mitra_corporate/model/patient_Model.dart';
class SearchPatientModel {
List<PatientModel>? patients;
String? total;
int? totalPage;
SearchPatientModel({this.patients, this.total, this.totalPage});
SearchPatientModel.fromJson(Map<String, dynamic> json) {
if (json['data'] != null) {
patients = <PatientModel>[];
json['data'].forEach((v) {
patients!.add(PatientModel.fromJson(v));
});
}
total = json['total'];
totalPage = json['total_page'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (patients != null) {
data['data'] = patients!.map((v) => v.toJson()).toList();
}
data['total'] = total;
data['total_page'] = totalPage;
return data;
}
}

View File

@@ -0,0 +1,52 @@
class SuratJalanDetailModel {
String? deliveryId;
String? deliveryNumber;
String? orderNumber;
String? deliveryDetailId;
String? orderId;
String? date;
String? patientName;
String? status;
String? acceptedSample;
String? rejectedSample;
SuratJalanDetailModel(
{this.deliveryId,
this.deliveryNumber,
this.deliveryDetailId,
this.orderId,
this.date,
this.orderNumber,
this.patientName,
this.acceptedSample,
this.rejectedSample,
this.status});
SuratJalanDetailModel.fromJson(Map<String, dynamic> json) {
deliveryId = json['delivery_id'];
deliveryNumber = json['delivery_number'];
deliveryDetailId = json['delivery_detail_id'];
orderId = json['order_id'];
date = json['date'];
orderNumber = json['order_number'];
patientName = json['patient_name'];
acceptedSample = json['accepted_sample'];
rejectedSample = json['rejected_sample'];
status = json['status'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['delivery_id'] = deliveryId;
data['delivery_number'] = deliveryNumber;
data['delivery_detail_id'] = deliveryDetailId;
data['order_id'] = orderId;
data['date'] = date;
data['order_number'] = orderNumber;
data['patient_name'] = patientName;
data['accepted_sample'] = acceptedSample;
data['rejected_sample'] = rejectedSample;
data['status'] = status;
return data;
}
}

View File

@@ -0,0 +1,83 @@
class SuratJalanModel {
String? id;
String? date;
String? orderNumber;
String? pic;
String? type;
String? destination;
String? status;
String? dateSj;
SuratJalanModel(
{this.id,
this.date,
this.orderNumber,
this.pic,
this.type,
this.status,
this.dateSj,
this.destination});
SuratJalanModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
date = json['date'];
orderNumber = json['order_number'];
pic = json['pic'];
type = json['type'];
status = json['status'];
destination = json['destination'];
dateSj = json['date_sj'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['date'] = date;
data['order_number'] = orderNumber;
data['pic'] = pic;
data['type'] = type;
data['status'] = status;
data['destination'] = destination;
data['date_sj'] = dateSj;
return data;
}
}
class SearchSuratJalanModel {
List<SuratJalanModel>? suratJalan;
String? total;
int? totalPage;
SearchSuratJalanModel({this.suratJalan, this.total, this.totalPage});
SearchSuratJalanModel.fromJson(Map<String, dynamic> json) {
if (json['data'] != null) {
suratJalan = <SuratJalanModel>[];
json['data'].forEach((v) {
suratJalan!.add(SuratJalanModel.fromJson(v));
});
}
total = json['total'];
totalPage = json['total_page'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (suratJalan != null) {
data['data'] = suratJalan!.map((v) => v.toJson()).toList();
}
data['total'] = total;
data['total_page'] = totalPage;
return data;
}
}
class dateFilterModel {
String id;
String name;
dateFilterModel({
required this.id,
required this.name,
});
}

76
lib/model/test_model.dart Normal file
View File

@@ -0,0 +1,76 @@
class TestModel {
String? tab;
int? tabId;
String? isPaket;
List<Items>? items;
TestModel({this.tab, this.tabId, this.items, this.isPaket});
TestModel.fromJson(Map<String, dynamic> json) {
tab = json['tab'];
tabId = json['tab_id'];
isPaket = json['is_paket'];
if (json['items'] != null) {
items = <Items>[];
json['items'].forEach((v) {
items!.add(Items.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['tab'] = tab;
data['tab_id'] = tabId;
data['is_paket'] = isPaket;
if (items != null) {
data['items'] = items!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Items {
String? testID;
String? testName;
String? testPrice;
String? sasCode;
String? isPaket;
String? arrTest;
String? type;
bool value = false;
Items(
{this.testID,
this.testName,
this.testPrice,
this.isPaket,
this.arrTest,
this.type,
this.value = false,
this.sasCode});
Items.fromJson(Map<String, dynamic> json) {
testID = json['testID'];
testName = json['testName'];
testPrice = json['testPrice'].toString();
sasCode = json['sasCode'];
isPaket = json['is_paket'];
arrTest = json['arrTest'];
type = json['type'];
value = false;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['testID'] = testID;
data['testName'] = testName;
data['testPrice'] = testPrice;
data['sasCode'] = sasCode;
data['is_paket'] = isPaket;
data['arrTest'] = arrTest;
data['type'] = type;
data['value'] = value;
return data;
}
}

View File

@@ -0,0 +1,6 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../model/auth_model.dart';
//data auth
final authProvider = StateProvider<AuthModel?>((ref) => null);

View File

@@ -0,0 +1,4 @@
import 'package:dio/dio.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final dioProvider = Provider<Dio>((ref) => Dio());

View File

@@ -0,0 +1,5 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
final currentMenuProvider = StateProvider<int>((ref) => 1);
final sideBarExpandProvider = StateProvider<bool>((ref) => true);
final keywordProvider = StateProvider<String>((ref) => "");

View File

@@ -0,0 +1,26 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../model/registration_model.dart';
import '../model/test_model.dart';
final EditStepProvider = StateProvider<int>((ref) => 0);
final editOrderLoadingProvider = StateProvider<bool>((ref) => false);
// mendapatkan perubahan value idTipePeriksa
final tabPeriksaprovider = StateProvider<int>((ref) => 1);
// selected test provider berisi list string "idtab|idtes"
final selectedTestEditProvider =
StateProvider<List<String>>((ref) => List.empty());
final selectedtestData = StateProvider<List<String>>((ref) => List.empty());
//menyimpan data temporary saat registrasi patien selama dialog masih terbuka
final EditDataProvider =
StateProvider<RegistrationModel>((ref) => RegistrationModel());
//temporary test list
final tempTestListEditProvider = StateProvider<List<TestModel>>(
(ref) => List.empty(),
);
final selectedPacketEditProvider =
StateProvider<List<String>>((ref) => List.empty(growable: true));
//Paket yang sudah terpilih di db untuk nantinya perbandingan apakah paket baru ataukah paket dihapus
final currentPacketProvider =
StateProvider<List<String>>((ref) => List.empty(growable: true));

View File

@@ -0,0 +1,28 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/registration_model.dart';
import 'package:mitra_corporate/model/test_model.dart';
// menerima perubahan value dari onTap simpan perubahan
final registrasiProvider = StateProvider<int>((ref) => 0);
final addOrderLoadingProvider = StateProvider<bool>((ref) => false);
// mendapatkan perubahan value idTipePeriksa
final idTipePeriksaStateProvider = StateProvider<int>((ref) => 1);
// selected test provider berisi list string "idtab|idtes"
final selectedTestProvider = StateProvider<List<String>>((ref) => List.empty());
//menyimpan data temporary saat registrasi patien selama dialog masih terbuka
final registrationDataProvider =
StateProvider<RegistrationModel>((ref) => RegistrationModel());
//temporary test list
final tempTestListProvider = StateProvider<List<TestModel>>(
(ref) => List.empty(),
);
final orderNumberProvider = StateProvider<String>((ref) => "");
final dialogOrderActionProvider = StateProvider<String>((ref) => "new");
final selectedPacketProvider =
StateProvider<List<String>>((ref) => List.empty(growable: true));
//edit pasien
final registrationEditPatientProvider =
StateProvider<RegistrationModel>((ref) => RegistrationModel());

View File

@@ -0,0 +1,22 @@
import 'package:mitra_corporate/model/surat_jalan_model.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/create_surat_jalan_model.dart';
import '../app/constant.dart';
// menerima perubahan value dari onTap simpan perubahan
final suratJalanProvider = StateProvider<int>((ref) => 1);
final createSuratJalanProvider =
StateProvider<CreateSuratJalanModel>((ref) => CreateSuratJalanModel());
final suratJalankeywordProvider = StateProvider<String>((ref) => "");
//param untuk detail surat jalan
final suratJalanID = StateProvider<String>((ref) => "");
final suratJalanNumber = StateProvider<String>((ref) => "");
final sjStartDateProvider = StateProvider<DateTime>((ref) => DateTime.now());
final sjEndDateProvider = StateProvider<DateTime>((ref) => DateTime.now());
final sjDateType =
StateProvider<dateFilterModel>((ref) => Constant.dateFilter.first);

View File

@@ -0,0 +1,75 @@
import '../app/constant.dart';
import '../model/auth_model.dart';
import 'base_repository.dart';
class AuthRepository extends BaseRepository {
AuthRepository({required super.dio});
Future<AuthModel> login({
required String username,
required String password,
// required String company_id,
// required String regional_id,
}) async {
final param = {
"username": username,
"password": password,
// "company_id": company_id,
// "regional_id": regional_id
// "username": "alhadad1",
// "doctor_id": "2891",
// "password": "3"
};
final service = "${Constant.baseUrl}auth/login";
final resp = await post(param: param, service: service);
final result = AuthModel.fromJson(resp['data']['user']);
result.token = resp['data']['token'];
return result;
}
Future<String> logout({
required String M_UserID,
required String M_UserUsername,
}) async {
final param = {
"M_UserID": M_UserID,
"username": M_UserUsername
// "username": "alhadad",
// "doctor_id": "3101210841",
// "password": "riau123"
};
final service = "${Constant.baseUrl}auth/logout";
final resp = await post(param: param, service: service);
if (resp["status"] == "OK") {
return resp['status'];
} else {
return resp['message'];
}
}
Future<String> changePassword({
required String token,
required String current_password,
required String new_password,
required String password_confirmation,
}) async {
final param = {
"token": token,
"current_password": current_password,
"new_password": new_password,
"password_confirmation": password_confirmation
};
final service = "${Constant.baseUrl}auth/changepassword";
final resp = await post(param: param, service: service);
if (resp["status"] == "OK") {
return resp['data'];
} else {
return resp['data'];
}
}
}

View File

@@ -0,0 +1,100 @@
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
abstract class BaseRepository {
final Dio dio;
BaseRepository({required this.dio});
Future<Map<String, dynamic>> post({
required Map<String, dynamic> param,
required String service,
String? token,
}) async {
try {
final response = await dio.post(
service,
data: jsonEncode(param),
options: Options(
headers: token != null
? {
HttpHeaders.contentTypeHeader: "application/json",
HttpHeaders.authorizationHeader: "Bearer $token",
}
: {
HttpHeaders.contentTypeHeader: "application/json",
},
contentType: "application/json",
),
);
if (response.statusCode != 200) {
throw BaseRepositoryException(
message: "Invalid Http Response ${response.statusCode}",
);
}
Map<String, dynamic> jsonData = jsonDecode(response.data);
if (jsonData["status"] != "OK") {
throw BaseRepositoryException(
message: jsonData["message"],
);
} else {
return jsonData;
}
} on DioException catch (e) {
throw BaseRepositoryException(message: e.message);
} on SocketException catch (e) {
throw BaseRepositoryException(message: e.message);
} on BaseRepositoryException catch (e) {
throw BaseRepositoryException(message: e.message);
}
}
Future<Map<String, dynamic>> get({
required String service,
String? token,
}) async {
try {
final response = await dio.get(
service,
options: Options(
headers: token != null
? {
HttpHeaders.contentTypeHeader: "application/json",
HttpHeaders.authorizationHeader: "Bearer $token",
}
: {
HttpHeaders.contentTypeHeader: "application/json",
},
contentType: "application/json",
),
);
if (response.statusCode != 200) {
throw BaseRepositoryException(
message: "Invalid Http Response ${response.statusCode}",
);
}
Map<String, dynamic> jsonData = jsonDecode(response.data);
if (jsonData["status"] != "OK") {
throw BaseRepositoryException(
message: jsonData["message"],
);
} else {
return jsonData;
}
} on DioException catch (e) {
throw BaseRepositoryException(message: e.message);
} on SocketException catch (e) {
throw BaseRepositoryException(message: e.message);
} on BaseRepositoryException catch (e) {
throw BaseRepositoryException(message: e.message);
}
}
}
class BaseRepositoryException implements Exception {
final String? message;
BaseRepositoryException({
required this.message,
});
}

View File

@@ -0,0 +1,43 @@
import 'package:mitra_corporate/model/chart_data_model.dart';
import 'package:mitra_corporate/model/surat_jalan_model.dart';
import '../app/constant.dart';
import 'base_repository.dart';
class DashboardRepository extends BaseRepository {
DashboardRepository({required super.dio});
Future<ChartDataModel> getChartData({
required String token,
required String filter,
required String company_id,
}) async {
final param = {"token": token, "filter": filter, "company_id": company_id};
// print(param);
final service = "${Constant.baseUrl}dashboard/chartdata";
final resp = await post(param: param, service: service);
final result = ChartDataModel.fromJson(resp['data']);
return result;
}
Future<List<SuratJalanModel>> getOrder(
{required String token, required String companyID}) async {
final param = {"token": token, "company_id": companyID};
// print(param);
final service = "${Constant.baseUrl}dashboard/getdelivery";
final resp = await post(param: param, service: service);
// print(resp);
List<SuratJalanModel> data = List.empty(growable: true);
if (resp['status'] == 'OK') {
resp['data'].forEach((e) {
final model = SuratJalanModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
}

View File

@@ -0,0 +1,72 @@
import 'package:mitra_corporate/model/search_order_model.dart';
import '../app/constant.dart';
import '../model/registration_model.dart';
import 'base_repository.dart';
class OrderRepository extends BaseRepository {
OrderRepository({required super.dio});
Future<SearchOrderModel> searchOrder(
{required String token,
required String page,
required String keyword,
required String rpp,
required String startDate,
required String endDate,
required String companyID}) async {
final param = {
"token": token,
"keyword": keyword,
"page": page,
"rpp": rpp,
"company_id": companyID,
"start_date": startDate,
"end_date": endDate
};
// print(param);
final service = "${Constant.baseUrl}order/getorder";
final resp = await post(param: param, service: service);
SearchOrderModel data;
// print(resp);
if (resp['status'] == 'OK') {
data = SearchOrderModel.fromJson(resp['data']);
} else {
data = SearchOrderModel();
}
return data;
}
Future<String> editOrder({required RegistrationModel prm}) async {
final url = "${Constant.baseUrl}order/editorder";
final resp = await post(param: prm.toJson(), service: url);
String number;
// print(resp['data']);
if (resp['status'] == 'OK') {
number = resp['data'];
} else {
number = "";
}
return number;
}
Future<String> cancelOrder({
required String token,
required String orderID,
}) async {
var param = {"token": token, "id": orderID};
final url = "${Constant.baseUrl}order/cancel";
final resp = await post(param: param, service: url);
String data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = resp['data'];
} else {
data = "";
}
return data;
}
}

View File

@@ -0,0 +1,66 @@
import 'package:mitra_corporate/model/search_patient_model.dart';
import '../app/constant.dart';
import '../model/registration_model.dart';
import 'base_repository.dart';
class PatientRepository extends BaseRepository {
PatientRepository({required super.dio});
Future<SearchPatientModel> search(
{required String token,
required String page,
required String keyword,
required String rpp,
required String companyID}) async {
final param = {
"token": token,
"keyword": keyword,
"page": page,
"rpp": rpp,
"company_id": companyID
};
// print(param);
final service = "${Constant.baseUrl}patient/search";
final resp = await post(param: param, service: service);
SearchPatientModel data;
// print(resp);
if (resp['status'] == 'OK') {
data = SearchPatientModel.fromJson(resp['data']);
} else {
data = SearchPatientModel();
}
return data;
}
Future<String> editPatient({required RegistrationModel prm}) async {
final url = "${Constant.baseUrl}Patient/editpatient";
final resp = await post(param: prm.toJson(), service: url);
String msg;
// print(resp['data']);
if (resp['status'] == 'OK') {
msg = resp['data'];
} else {
msg = "";
}
return msg;
}
Future<String> deletePatient(
{required String patient_id, required String token}) async {
final prm = {"patient_id": patient_id, "token": token};
final url = "${Constant.baseUrl}Patient/deletePatient";
final resp = await post(param: prm, service: url);
String msg;
// print(resp['data']);
if (resp['status'] == 'OK') {
msg = resp['data'];
} else {
msg = "";
}
return msg;
}
}

View File

@@ -0,0 +1,86 @@
import 'package:mitra_corporate/model/registration_filter_model.dart';
import 'package:mitra_corporate/model/registration_model.dart';
import 'package:mitra_corporate/model/test_model.dart';
import '../app/constant.dart';
import 'base_repository.dart';
class RegistrationRepository extends BaseRepository {
RegistrationRepository({required super.dio});
Future<List<TestModel>> getFPP({
required String mouID,
required String token,
}) async {
var param = {"mou_id": mouID, "token": token};
// print(param);
final url = "${Constant.baseUrl}fpp/load";
final resp = await post(param: param, service: url);
List<TestModel> data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = [];
resp['data'].forEach((e) {
final model = TestModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
Future<RegistrationFilterModel> getFilter({
required String token,
}) async {
var param = {"token": token};
final url = "${Constant.baseUrl}Registration/getfilter";
final resp = await post(param: param, service: url);
RegistrationFilterModel data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = RegistrationFilterModel.fromJson(resp['data']);
} else {
data = RegistrationFilterModel();
}
return data;
}
Future<List<GetSpecimenModel>> getSpecimen({
required String token,
required List<Map<String, String>> arrTest,
}) async {
var param = {"token": token, "arr_test": arrTest};
final url = "${Constant.baseUrl}Registration/getsampletype";
final resp = await post(param: param, service: url);
List<GetSpecimenModel> data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = [];
resp['data'].forEach((e) {
final model = GetSpecimenModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
Future<String> addOrder({required RegistrationModel prm}) async {
final url = "${Constant.baseUrl}Registration/addpatient";
final resp = await post(param: prm.toJson(), service: url);
String number;
// print(resp['data']);
if (resp['status'] == 'OK') {
number = resp['data']['orderNumber'];
} else {
number = "";
}
return number;
}
}

View File

@@ -0,0 +1,222 @@
import 'package:mitra_corporate/model/create_surat_jalan_model.dart';
import 'package:mitra_corporate/model/delivery_type_model.dart';
import 'package:mitra_corporate/model/destination_model.dart';
import 'package:mitra_corporate/model/order_model.dart';
import 'package:mitra_corporate/model/registration_filter_model.dart';
import 'package:mitra_corporate/model/surat_jalan_detail_model.dart';
import '../app/constant.dart';
import '../model/surat_jalan_model.dart';
import 'base_repository.dart';
class SuratJalanRepository extends BaseRepository {
SuratJalanRepository({required super.dio});
Future<List<DeliveryTypeModel>> getDeliveryType({
required String token,
}) async {
var param = {"token": token};
final url = "${Constant.baseUrl}deliveryorder/getdeliverytype";
final resp = await post(param: param, service: url);
List<DeliveryTypeModel> data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = [];
resp['data'].forEach((e) {
final model = DeliveryTypeModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
Future<List<OrderModel>> getOrder({
required String token,
required String company_id,
required String regional_id,
}) async {
var param = {
"token": token,
"company_id": company_id,
"regional_id": regional_id
};
final url = "${Constant.baseUrl}deliveryorder/getorder";
final resp = await post(param: param, service: url);
List<OrderModel> data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = [];
resp['data'].forEach((e) {
final model = OrderModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
Future<String> createSuratJalan({required CreateSuratJalanModel prm}) async {
final url = "${Constant.baseUrl}deliveryorder/addDelivery";
final resp = await post(param: prm.toJson(), service: url);
String number;
// print(resp['data']);
if (resp['status'] == 'OK') {
number = resp['data']['orderNumber'];
} else {
number = "";
}
return number;
}
Future<SearchSuratJalanModel> getSuratJalan({
required String token,
required String company_id,
required String rpp,
required String keyword,
required String page,
required String startDate,
required String endDate,
required String dateType,
}) async {
var param = {
"token": token,
"page": page,
"keyword": keyword,
"rpp": rpp,
"company_id": company_id,
"start_date": startDate,
"end_date": endDate,
"date_type": dateType
};
final url = "${Constant.baseUrl}deliveryorder/getdelivery";
final resp = await post(param: param, service: url);
SearchSuratJalanModel data;
// print(resp);
if (resp['status'] == 'OK') {
data = SearchSuratJalanModel.fromJson(resp['data']);
} else {
data = SearchSuratJalanModel();
}
return data;
}
Future<List<SuratJalanDetailModel>> getSuratJalanSetail({
required String token,
required String deliveryID,
}) async {
var param = {"token": token, "id": deliveryID};
final url = "${Constant.baseUrl}deliveryorder/detaildelivery";
final resp = await post(param: param, service: url);
List<SuratJalanDetailModel> data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = [];
resp['data'].forEach((e) {
final model = SuratJalanDetailModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
Future<String> cancelSuratJalan({
required String token,
required String deliveryID,
}) async {
var param = {"token": token, "id": deliveryID};
final url = "${Constant.baseUrl}deliveryorder/cancel";
final resp = await post(param: param, service: url);
String data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = resp['data'];
} else {
data = "";
}
return data;
}
Future<String> sendSuratJalan({
required String token,
required String deliveryID,
}) async {
var param = {"token": token, "id": deliveryID};
final url = "${Constant.baseUrl}deliveryorder/send";
final resp = await post(param: param, service: url);
String data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = resp['data'];
} else {
data = "";
}
return data;
}
Future<List<DestinationModel>> getDestination({
required String token,
}) async {
var param = {"token": token};
final url = "${Constant.baseUrl}deliveryorder/getdestination";
final resp = await post(param: param, service: url);
List<DestinationModel> data = List.empty(growable: true);
if (resp['status'] == 'OK') {
data = [];
resp['data'].forEach((e) {
final model = DestinationModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
Future<List<RegionalModel>> getRegional({
required String token,
}) async {
var param = {"token": token};
final url = "${Constant.baseUrl}deliveryorder/getregional";
final resp = await post(param: param, service: url);
List<RegionalModel> data = List.empty(growable: true);
if (resp['status'] == 'OK') {
data = [];
resp['data'].forEach((e) {
final model = RegionalModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
Future<String> sendQrCode(
{required String token, required List<String> arrOrderID}) async {
var param = {"token": token, 'arr_order_id': arrOrderID};
final url = "${Constant.baseUrl}deliveryorder/sendqrcode";
final resp = await post(param: param, service: url);
String data = "";
if (resp['status'] == 'OK') {
data = "OK";
} else {
data = "ERROR";
}
return data;
}
}

View File

@@ -0,0 +1,232 @@
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/app/constant.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/screen/dashboard/chart_provider.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../widgets/custom_snackbar_widget.dart';
class ChartScreen extends HookConsumerWidget {
const ChartScreen({super.key, required this.filter});
final ValueNotifier<String> filter;
@override
Widget build(BuildContext context, WidgetRef ref) {
// N = New, S= Send, P= Parsial, D=Done,
final auth = ref.watch(authProvider);
final chartLoading = useState(false);
final total = useState<List<String>>(List.empty());
final dikirim = useState<List<String>>(List.empty());
final dikonfirmasi = useState<List<String>>(List.empty());
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
var fltr = "month";
if (filter.value.toLowerCase() == "bulan") {
fltr = "month";
}
if (filter.value.toLowerCase() == "tahun") {
fltr = "year";
}
ref.read(ChartDataProvider.notifier).ChartData(
token: auth?.token ?? "",
filter: fltr,
company_id: auth?.mUserMCompanyID ?? "");
});
return () {};
}, [filter.value]);
ref.listen(ChartDataProvider, (prev, next) async {
if (next is ChartDataStateLoading) {
chartLoading.value = true;
} else if (next is ChartDataStateError) {
chartLoading.value = false;
SanckbarWidget(context, next.message ?? "", snackbarType.error);
Constant.autoLogout(context: context, msg: next.message ?? "");
} else if (next is ChartDataStateDone) {
total.value = next.model.t ?? [];
dikirim.value = next.model.s ?? [];
dikonfirmasi.value = next.model.y ?? [];
chartLoading.value = false;
}
});
return Scaffold(
body: chartLoading.value
? Center(
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 40))
: Padding(
padding: const EdgeInsets.all(20),
child: LineChart(
LineChartData(
gridData: FlGridData(
show: true,
),
borderData: FlBorderData(
show: true,
border: Border(
top: BorderSide.none,
right: BorderSide.none,
left: BorderSide(color: Colors.grey.shade500),
bottom: BorderSide(color: Colors.grey.shade500))),
backgroundColor: Colors.white,
minX: 0,
minY: 0,
// maxX: 31,
titlesData: FlTitlesData(
rightTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
topTitles: AxisTitles(
sideTitles: SideTitles(showTitles: false)),
leftTitles: AxisTitles(
axisNameSize: 30,
axisNameWidget: Text(
"Total",
style: Constant.caption1_400(context: context),
),
sideTitles: SideTitles(
showTitles: true,
reservedSize: 32,
interval: 10,
getTitlesWidget: (double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: meta.axisSide,
space: 10,
child: Text(
value.toInt().toString(),
style:
Constant.caption1_400(context: context),
),
);
},
)),
bottomTitles: AxisTitles(
axisNameSize: 30,
axisNameWidget: Container(
child: Text(
filter.value == "Bulan" ? "Hari" : "Bulan",
style: Constant.caption1_400(context: context),
),
),
sideTitles: SideTitles(
showTitles: true,
reservedSize: 32,
interval: 1,
getTitlesWidget: (double value, TitleMeta meta) {
return SideTitleWidget(
axisSide: meta.axisSide,
space: 10,
child: Text(
style: Constant.caption1_400(
context: context),
value.toInt().toString(),
));
},
))),
lineBarsData: [
// LineChartBarData(
// isCurved: true,
// curveSmoothness: 0.20,
// color: Colors.red,
// barWidth: 4,
// isStrokeCapRound: true,
// dotData: FlDotData(
// checkToShowDot: (spot, barData) {
// if (pending.value.length == 1) {
// return true;
// } else {
// return false;
// }
// },
// ),
// belowBarData: BarAreaData(show: false),
// spots: pending.value.map((e) {
// var sp = e.split("|");
// return FlSpot(
// double.parse(sp[0]), double.parse(sp[1]));
// }).toList()),
LineChartBarData(
isCurved: true,
curveSmoothness: 0.2,
color: Colors.purple,
barWidth: 4,
isStrokeCapRound: true,
dotData: FlDotData(
checkToShowDot: (spot, barData) {
if (dikirim.value.length == 1) {
return true;
} else {
return false;
}
},
),
belowBarData: BarAreaData(show: false),
spots: dikirim.value.map((e) {
var sp = e.split("|");
return FlSpot(
double.parse(sp[0]), double.parse(sp[1]));
}).toList()),
LineChartBarData(
isCurved: true,
curveSmoothness: 0.1,
color: Colors.blue,
barWidth: 4,
isStrokeCapRound: true,
dotData: FlDotData(
checkToShowDot: (spot, barData) {
if (total.value.length == 1) {
return true;
} else {
return false;
}
},
),
belowBarData: BarAreaData(show: false),
spots: total.value.map((e) {
var sp = e.split("|");
return FlSpot(
double.parse(sp[0]), double.parse(sp[1]));
}).toList()),
LineChartBarData(
isCurved: true,
curveSmoothness: 0.20,
color: Colors.green,
barWidth: 4,
isStrokeCapRound: true,
dotData: FlDotData(
checkToShowDot: (spot, barData) {
if (dikonfirmasi.value.length == 1) {
return true;
} else {
return false;
}
},
),
belowBarData: BarAreaData(show: false),
spots: dikonfirmasi.value.map((e) {
var sp = e.split("|");
return FlSpot(
double.parse(sp[0]), double.parse(sp[1]));
}).toList()),
],
extraLinesData: ExtraLinesData(horizontalLines: [
HorizontalLine(
y: 0,
color: Colors.white,
strokeWidth: 1,
dashArray: [5])
])),
// swapAnimationDuration: Duration(milliseconds: 150),
// swapAnimationCurve: Curves.linear,
),
),
);
}
}

View File

@@ -0,0 +1,69 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/chart_data_model.dart';
import 'package:mitra_corporate/repository/dashboard_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
// 3. state provider
final ChartDataProvider =
StateNotifierProvider<ChartDataNotifier, ChartDataState>(
(ref) => ChartDataNotifier(ref: ref));
// 2. notifier
class ChartDataNotifier extends StateNotifier<ChartDataState> {
final Ref ref;
ChartDataNotifier({required this.ref}) : super(ChartDataStateInit());
void ChartData(
{required String token,
required String filter,
required String company_id,
bool isRememberMe = false}) async {
try {
state = ChartDataStateLoading();
final resp = await DashboardRepository(dio: ref.read(dioProvider))
.getChartData(token: token, filter: filter, company_id: company_id);
state = ChartDataStateDone(model: resp);
// print(shared.getString(Constant.bearerName));
} catch (e) {
if (e is BaseRepositoryException) {
state = ChartDataStateError(message: e.message ?? "");
} else {
state = ChartDataStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class ChartDataState extends Equatable {
final DateTime date;
const ChartDataState(this.date);
@override
List<Object?> get props => [date];
}
class ChartDataStateInit extends ChartDataState {
ChartDataStateInit() : super(DateTime.now());
}
class ChartDataStateLoading extends ChartDataState {
ChartDataStateLoading() : super(DateTime.now());
}
class ChartDataStateError extends ChartDataState {
final String? message;
ChartDataStateError({
required this.message,
}) : super(DateTime.now());
}
class ChartDataStateDone extends ChartDataState {
final ChartDataModel model;
ChartDataStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,72 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/surat_jalan_model.dart';
import 'package:mitra_corporate/repository/dashboard_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
// 3. state provider
final DashboardDeliveryProvider =
StateNotifierProvider<DashboardDeliveryNotifier, DashboardDeliveryState>(
(ref) => DashboardDeliveryNotifier(ref: ref));
// 2. notifier
class DashboardDeliveryNotifier extends StateNotifier<DashboardDeliveryState> {
final Ref ref;
DashboardDeliveryNotifier({required this.ref})
: super(DashboardDeliveryStateInit());
void DashboardDelivery(
{required String token,
required String company_id,
bool isRememberMe = false}) async {
try {
state = DashboardDeliveryStateLoading();
final resp = await DashboardRepository(dio: ref.read(dioProvider))
.getOrder(token: token, companyID: company_id);
state = DashboardDeliveryStateDone(model: resp);
// print(shared.getString(Constant.bearerName));
} catch (e) {
if (e is BaseRepositoryException) {
state = DashboardDeliveryStateError(message: e.message ?? "");
} else {
state = DashboardDeliveryStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class DashboardDeliveryState extends Equatable {
final DateTime date;
const DashboardDeliveryState(this.date);
@override
List<Object?> get props => [date];
}
class DashboardDeliveryStateInit extends DashboardDeliveryState {
DashboardDeliveryStateInit() : super(DateTime.now());
}
class DashboardDeliveryStateLoading extends DashboardDeliveryState {
DashboardDeliveryStateLoading() : super(DateTime.now());
}
class DashboardDeliveryStateError extends DashboardDeliveryState {
final String? message;
DashboardDeliveryStateError({
required this.message,
}) : super(DateTime.now());
}
class DashboardDeliveryStateDone extends DashboardDeliveryState {
final List<SuratJalanModel> model;
DashboardDeliveryStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,213 @@
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/screen/dashboard/chart.dart';
// import 'package:syncfusion_flutter_charts/charts.dart';
import '../../app/constant.dart';
import '../../provider/menu_provider.dart';
import '../../widgets/header.dart';
class DashboardScreen extends HookConsumerWidget {
const DashboardScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final isExpand = ref.watch(sideBarExpandProvider);
List<String> chartType = <String>['Tahun', 'Bulan'];
final selectedChartType = useState("Tahun");
return Scaffold(
body: Column(
children: [
Header(),
Padding(
padding: EdgeInsets.all(32.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
// color: Colors.red,
alignment: Alignment.centerLeft,
child: Text('Dashboard',
style: Constant.h3_400(context: context)
.copyWith(color: Constant.textBlack)),
),
SizedBox(
height: Constant.getActualY(context: context, y: 40),
),
//Statistik
Material(
// elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
color: Colors.white,
child: Container(
padding: EdgeInsets.all(20),
// width: Constant.getActualX(context: context, x: 1080),
height: Constant.getActualY(context: context, y: 720),
child: Column(
children: [
Row(
children: [
Text(
"Statistik",
style: Constant.h4_600(context: context),
),
const Spacer(),
// Text(
// "Bulan",
// style: Constant.caption1_400(context: context),
// ),
// Icon(EvaIcons.arrowIosDownward, size: 12),
DropdownButton<String>(
value: selectedChartType.value,
icon: Icon(EvaIcons.arrowIosDownward, size: 12),
elevation: 16,
style: Constant.caption1_400(context: context)
.copyWith(color: Colors.black),
underline: Container(
height: 0,
),
focusColor: Colors.white,
onChanged: (value) {
// This is called when the user selects an item.
selectedChartType.value = value!;
},
items: chartType.map<DropdownMenuItem<String>>(
(String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
)
],
),
SizedBox(
height:
Constant.getActualX(context: context, x: 4)),
// Row(
// children: [
// Text(
// "Last Update 1 Juli",
// style: Constant.caption1_400(context: context),
// ),
// ],
// ),
// Image.asset(
// 'images/grafik.png',
// width: Constant.getActualX(context: context, x: 1039),
// height: Constant.getActualY(context: context, y: 241),
// ),
SizedBox(
// width:
// Constant.getActualX(context: context, x: 1039),
height:
Constant.getActualY(context: context, y: 550),
child: Row(
children: [
Expanded(
flex: 9,
child: ChartScreen(
filter: selectedChartType,
)),
Expanded(flex: 1, child: Container()),
Expanded(
flex: 2,
child: Container(
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Row(
children: [
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius:
BorderRadius.circular(
5)),
margin:
EdgeInsets.only(right: 10),
),
Text(
"Total Order",
style: Constant.caption1_400(
context: context),
)
],
),
SizedBox(
height: Constant.getActualY(
context: context, y: 16),
),
Row(
children: [
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: Colors.purple,
borderRadius:
BorderRadius.circular(
5)),
margin:
EdgeInsets.only(right: 10),
),
Text(
"Dikirim",
style: Constant.caption1_400(
context: context),
)
],
),
SizedBox(
height: Constant.getActualY(
context: context, y: 16),
),
Row(
children: [
Container(
width: 20,
height: 20,
decoration: BoxDecoration(
color: Colors.green,
borderRadius:
BorderRadius.circular(
5)),
margin:
EdgeInsets.only(right: 10),
),
Text(
"Dikonfirmasi",
style: Constant.caption1_400(
context: context),
)
],
),
],
),
)),
],
),
)
],
)),
),
// SizedBox(
// height: Constant.getActualY(context: context, y: 40),
// ),
// //Pengiriman terbaru
// DashboardTabel()
],
),
),
],
),
);
}
}

View File

@@ -0,0 +1,283 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/model/surat_jalan_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../provider/menu_provider.dart';
import '../../widgets/custom_snackbar_widget.dart';
import 'dashboard_delivery_provider.dart';
class DashboardTabel extends HookConsumerWidget {
const DashboardTabel({
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final auth = ref.read(authProvider);
final dataList = useState<List<SuratJalanModel>>(List.empty());
final loading = useState(false);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
ref.read(DashboardDeliveryProvider.notifier).DashboardDelivery(
token: auth?.token ?? "", company_id: auth?.mUserMCompanyID ?? "");
});
return () {};
}, []);
ref.listen(DashboardDeliveryProvider, (prev, next) async {
if (next is DashboardDeliveryStateLoading) {
loading.value = true;
} else if (next is DashboardDeliveryStateError) {
loading.value = false;
SanckbarWidget(context, next.message ?? "", snackbarType.error);
Constant.autoLogout(context: context, msg: next.message ?? "");
} else if (next is DashboardDeliveryStateDone) {
dataList.value = next.model;
loading.value = false;
}
});
return Material(
elevation: 5,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
color: Colors.white,
child: SizedBox(
height: Constant.getActualY(context: context, y: 370),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Text('Pengiriman Terbaru',
style: Constant.h4_600(context: context)
.copyWith(color: Constant.textBlack)),
),
Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 8)),
child: Column(
children: [
Container(
decoration: BoxDecoration(
color: Constant.grey_200,
borderRadius: BorderRadius.circular(8)),
height: Constant.getActualY(context: context, y: 56),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Text(
"Tanggal",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Text(
"Nomor Surat Jalan",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Text(
"Staff PIC",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Text(
"Tipe Pengiriman",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Text(
"Tujuan",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Text(
"Status",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
],
),
)
],
),
),
Container(
height: Constant.getActualY(context: context, y: 160),
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 8)),
child: loading.value
? Center(
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 40))
: ListView(
children: dataList.value
.map((e) => Container(
margin: EdgeInsets.symmetric(
vertical: Constant.getActualY(
context: context, y: 10)),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: SelectableText(e.date ?? "",
style: Constant.body3_600(
context: context)),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: SelectableText(
e.orderNumber ?? "",
style: Constant.body3_600(
context: context)),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: SelectableText(e.pic ?? "",
style: Constant.body3_600(
context: context)),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: SelectableText(e.type ?? "",
style: Constant.body3_600(
context: context)),
)),
Expanded(
flex: 2,
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: SelectableText(
e.destination ?? "",
style: Constant.body3_600(
context: context)),
)),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.bottomLeft,
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 12)),
child: Chip(
backgroundColor:
Constant.yellow_016,
label: SelectableText(
"Proses",
style: Constant.caption1_600(
context: context)
.copyWith(
color: Constant
.textYellow),
),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(8)),
)
// Text("Status",
// style: Constant.body3_600(context: context)),
)),
],
),
))
.toList(),
),
),
Divider(),
Container(
padding: EdgeInsets.only(right: 10),
height: Constant.getActualY(context: context, y: 60),
child: Row(
children: [
Spacer(),
TextButton(
onPressed: () {
ref.read(currentMenuProvider.notifier).state = 3;
},
child: Row(
children: [
Text(
"View All",
style: Constant.body3_600(context: context)
.copyWith(color: Colors.black),
),
Icon(
Icons.arrow_forward_ios_rounded,
color: Colors.black,
size: 17,
)
],
))
],
),
)
],
),
),
);
}
}

View File

@@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/screen/dashboard/dashboard_screen.dart';
import 'package:mitra_corporate/screen/registrasi/registrasi_pasien_screen.dart';
import 'package:mitra_corporate/screen/result/detail_result_screen.dart';
import 'package:mitra_corporate/screen/result/result_screen.dart';
import 'package:mitra_corporate/screen/surat_jalan/surat_jalan_detail_screen.dart';
import 'package:mitra_corporate/screen/surat_jalan/surat_jalan_screen.dart';
import 'package:mitra_corporate/widgets/side_menu.dart';
import '../../provider/menu_provider.dart';
import '../order/order_screen.dart';
class HomeScreen extends HookConsumerWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final currentMenu = ref.watch(currentMenuProvider);
// getPref() async {
// final SharedPreferences prefs = await SharedPreferences.getInstance();
// final String? getData = prefs.getString(Constant.tokenName);
// // print(getData);
// if (getData == null) {
// Timer(Duration(seconds: 1), () {
// Navigator.pushNamed(context, loginRoute);
// });
// }
// }
// useEffect(() {
// WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
// getPref();
// });
// return () {};
// }, []);
return Scaffold(
body: Container(
child: Row(
children: [
SideMenu(),
if (currentMenu == 1) Expanded(child: DashboardScreen()),
if (currentMenu == 2) Expanded(child: RegistrasiPasienScreen()),
if (currentMenu == 3) Expanded(child: SuratJalanScreen()),
if (currentMenu == 4) Expanded(child: ResultScreen()),
if (currentMenu == 5) Expanded(child: SuratJalanDetailScreen()),
if (currentMenu == 6) Expanded(child: OrderScreen()),
if (currentMenu == 7) Expanded(child: DetailResultScreen()),
// Container(
// child: Text("a"),
// )
],
),
),
);
}
}

View File

@@ -0,0 +1,72 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../provider/dio_provider.dart';
import '../../repository/auth_repository.dart';
import '../../repository/base_repository.dart';
// 3. state provider
final ChangePasswordProvider =
StateNotifierProvider<ChangePasswordNotifier, ChangePasswordState>(
(ref) => ChangePasswordNotifier(ref: ref));
// 2. notifier
class ChangePasswordNotifier extends StateNotifier<ChangePasswordState> {
final Ref ref;
ChangePasswordNotifier({required this.ref})
: super(ChangePasswordStateInit());
void ChangePassword({
required String token,
required String current_password,
required String new_password,
required String password_confirmation,
}) async {
try {
state = ChangePasswordStateLoading();
final resp = await AuthRepository(dio: ref.read(dioProvider))
.changePassword(
token: token,
current_password: current_password,
new_password: new_password,
password_confirmation: password_confirmation);
// print(resp);
state = ChangePasswordStateDone(message: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = ChangePasswordStateError(message: e.message ?? "");
} else {
state = ChangePasswordStateError(message: e.toString());
}
}
}
}
// 1. state
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 message;
ChangePasswordStateDone({
required this.message,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,301 @@
import 'dart:convert';
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/app/route.dart';
import 'package:mitra_corporate/model/auth_model.dart';
import 'package:mitra_corporate/screen/login/login_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../model/registration_filter_model.dart';
import '../../provider/auth_provider.dart';
import '../../widgets/custom_snackbar_widget.dart';
import '../../widgets/custom_text_field.dart';
import '../surat_jalan/get_regional_provider.dart';
class LoginBox extends HookConsumerWidget {
const LoginBox({super.key});
// bool? _value = false;
// bool? remember = false;
@override
Widget build(BuildContext context, WidgetRef ref) {
final remember = useState(false);
final obsecureText = useState(true);
// final companyIdCtr = useTextEditingController();
final usernameCtr = useTextEditingController();
final passwordCtr = useTextEditingController();
final regionalList = useState<List<RegionalModel>>(List.empty());
// final selectedRegional = useState(RegionalModel());
final regionalKey = useState(1);
final regionalLoading = useState(false);
final isLoading = useState(false);
final errorMsg = useState("");
getPref() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final String? getData = prefs.getString(Constant.tokenName);
print(getData);
if (getData != null) {
ref.read(authProvider.notifier).state =
AuthModel.fromJson(jsonDecode(getData));
Navigator.pushNamed(context, homeRoute);
}
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
// ref.read(GetRegionalProvider.notifier).getRegional(token: "");
getPref();
});
return () {};
}, []);
login() {
if (
// companyIdCtr.text.isEmpty ||
usernameCtr.text.isEmpty || passwordCtr.text.isEmpty
// selectedRegional.value.regionalId == null
) {
SanckbarWidget(
context, "Username dan Password harus diisi", snackbarType.warning);
// toastification.show(
// context: context,
// title: 'Hello, world!',
// autoCloseDuration: const Duration(seconds: 5),
// );
} else {
ref.read(loginProvider.notifier).login(
username: usernameCtr.text,
password: passwordCtr.text,
// company_id: companyIdCtr.text,
// regional_id: selectedRegional.value.regionalId ?? "",
isRememberMe: remember.value);
}
}
// aksi login
ref.listen(loginProvider, (prev, next) async {
if (next is LoginStateLoading) {
isLoading.value = true;
} else if (next is LoginStateError) {
isLoading.value = false;
errorMsg.value = next.message ?? "";
SanckbarWidget(context, errorMsg.value, snackbarType.error);
} else if (next is LoginStateDone) {
isLoading.value = false;
if (next.model.token != null) {
Navigator.pushNamed(context, homeRoute);
} else {
SanckbarWidget(context, "Login Gagal", snackbarType.error);
}
}
});
ref.listen(
GetRegionalProvider,
(previous, next) {
if (next is GetRegionalStateInit) {
regionalLoading.value = true;
} else if (next is GetRegionalStateLoading) {
regionalLoading.value = true;
} else if (next is GetRegionalStateError) {
SanckbarWidget(context, next.message, snackbarType.error);
regionalLoading.value = false;
} else if (next is GetRegionalStateDone) {
// print(jsonEncode(next.model));
regionalList.value = next.model;
regionalKey.value = regionalKey.value + 1;
regionalLoading.value = false;
}
},
);
return Column(children: [
//Selamat datang
SizedBox(
width: Constant.getActualX(context: context, x: 320),
// height: Constant.getActualY(context: context, y: 52),
// color: Colors.blueAccent,
child: Text("Selamat Datang",
style: Constant.h1_700(context: context)
.copyWith(color: Constant.textBlack)),
),
SizedBox(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 28),
// color: Colors.blueAccent,
child: Text("Silahkan login untuk masuk",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.textGrey)),
),
SizedBox(
height: Constant.getActualY(context: context, y: 48),
),
// SizedBox(
// width: Constant.getActualX(context: context, x: 320),
// // height: Constant.getActualY(context: context, y: 56),
// child: DropdownMenu<RegionalModel>(
// enableFilter: true,
// enableSearch: true,
// key: ValueKey(regionalKey.value),
// menuHeight: Constant.getActualY(context: context, y: 300),
// initialSelection: selectedRegional.value,
// trailingIcon: regionalLoading.value
// ? LoadingAnimationWidget.discreteCircle(
// color: Constant.primaryRed, size: 20)
// : null,
// width: Constant.getActualX(context: context, x: 320),
// hintText: "Regional",
// textStyle: Constant.body2_400(context: context),
// inputDecorationTheme: InputDecorationTheme(
// border: OutlineInputBorder(
// borderSide: BorderSide(color: Constant.primaryRed),
// borderRadius: BorderRadius.circular(8),
// )),
// label: const Text(
// "Regional",
// maxLines: 1,
// overflow: TextOverflow.ellipsis,
// ),
// onSelected: (value) {
// // onSelectSaluation(value!);
// if (value!.regionalId != selectedRegional.value.regionalId) {
// print("change");
// selectedRegional.value = value;
// }
// },
// dropdownMenuEntries: regionalList.value
// .map<DropdownMenuEntry<RegionalModel>>((e) => DropdownMenuEntry(
// value: e,
// label: e.regionalName ?? "",
// ))
// .toList()),
// ),
// SizedBox(
// height: Constant.getActualY(context: context, y: 20),
// ),
//Username
// SizedBox(
// width: Constant.getActualX(context: context, x: 320),
// // height: Constant.getActualY(context: context, y: 56),
// child: CustomTextField(
// controller: companyIdCtr,
// hintText: "Company ID",
// labelText: "Company ID",
// ),
// ),
// SizedBox(
// height: Constant.getActualY(context: context, y: 20),
// ),
//Username
SizedBox(
width: Constant.getActualX(context: context, x: 320),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
controller: usernameCtr,
hintText: "Username",
labelText: "Username",
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
//Password
SizedBox(
width: Constant.getActualX(context: context, x: 320),
// height: Constant.getActualY(context: context, y: 56),
child: CustomPasswordField(
controller: passwordCtr,
isPassword: obsecureText,
hintText: "Password",
labelText: "Password",
suffixIcon: Icon(EvaIcons.eyeOffOutline),
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
SizedBox(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 24),
child: Row(
children: [
Center(
child: Transform.scale(
scale: 0.8,
child: Checkbox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4)),
value: remember.value,
onChanged: (value) {
remember.value = value!;
}),
),
),
Text('Remember Me',
style: Constant.body3_400(context: context)
.copyWith(color: Constant.textBlack)),
Spacer(),
// SizedBox(
// child: Text("Forgot Password?",
// style: Constant.body3_400(context: context)
// .copyWith(color: Constant.textBlue)),
// )
],
),
),
SizedBox(height: Constant.getActualY(context: context, y: 56)),
SizedBox(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 56),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(8),
// gradient: LinearGradient(
// colors: [Constant.buttonPrimary1, Constant.buttonPrimary2])),
child: ElevatedButton(
onPressed: () {
isLoading.value ? null : login();
},
style: ElevatedButton.styleFrom(
backgroundColor: Constant.primaryRed,
// shadowColor: Colors.transparent
),
child: isLoading.value
? Center(
child: LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white, size: 30),
)
: Text('Login',
style: Constant.button_large(context: context)
.copyWith(color: Constant.textWhite)),
),
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Text(Constant.version,
style: Constant.body3_600(context: context).copyWith(
color: Constant.textGrey,
))
// SizedBox(
// width: Constant.getActualX(context: context, x: 320),
// // height: Constant.getActualY(context: context, y: 24),
// child: Align(
// alignment: Alignment.center,
// child: Text(
// 'Problem Login ? ',
// style: Constant.caption1_400(context: context)
// .copyWith(color: Constant.textBlue),
// ),
// ),
// )
]);
}
}

View File

@@ -0,0 +1,96 @@
import 'dart:convert';
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../app/constant.dart';
import '../../model/auth_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/auth_repository.dart';
import '../../repository/base_repository.dart';
// 3. state provider
final loginProvider = StateNotifierProvider<LoginNotifier, LoginState>(
(ref) => LoginNotifier(ref: ref));
// 2. notifier
class LoginNotifier extends StateNotifier<LoginState> {
final Ref ref;
LoginNotifier({required this.ref}) : super(LoginStateInit());
void login(
{required String username,
required String password,
// required String company_id,
// required String regional_id,
bool isRememberMe = false}) async {
try {
state = LoginStateLoading();
final resp = await AuthRepository(dio: ref.read(dioProvider)).login(
username: username,
password: password,
// company_id: company_id,
// regional_id: regional_id
);
state = LoginStateDone(model: resp);
//Simpan ke token jk remember me
if (isRememberMe == true) {
final shared = await SharedPreferences.getInstance();
resp.isRememberMe = isRememberMe;
final tokenEncode = jsonEncode(resp);
await shared.setString(Constant.tokenName, tokenEncode);
} else {
// share pref di remove karena remember me tidak di centang
final shared = await SharedPreferences.getInstance();
await shared.remove("usernameX");
await shared.remove("passwordX");
await shared.remove("isRememberMeX");
await shared.remove(Constant.tokenName);
}
resp.isRememberMe = isRememberMe;
ref.read(authProvider.notifier).state = resp;
// print(shared.getString(Constant.bearerName));
} catch (e) {
if (e is BaseRepositoryException) {
state = LoginStateError(message: e.message ?? "");
} else {
state = LoginStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class LoginState extends Equatable {
final DateTime date;
const LoginState(this.date);
@override
List<Object?> get props => [date];
}
class LoginStateInit extends LoginState {
LoginStateInit() : super(DateTime.now());
}
class LoginStateLoading extends LoginState {
LoginStateLoading() : super(DateTime.now());
}
class LoginStateError extends LoginState {
final String? message;
LoginStateError({
required this.message,
}) : super(DateTime.now());
}
class LoginStateDone extends LoginState {
final AuthModel model;
LoginStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'package:mitra_corporate/screen/login/login_box.dart';
import '../../app/constant.dart';
class LoginScreen extends StatelessWidget {
const LoginScreen({super.key});
@override
Widget build(BuildContext context) {
return Material(
child: Stack(
children: [
//image
Image.asset(
"images/pramita_login.png",
fit: BoxFit.fill,
width: Constant.getActualX(context: context, x: 1440),
height: Constant.getActualY(context: context, y: 1024),
),
//login
Positioned(
top: Constant.getActualY(context: context, y: 200),
left: Constant.getActualX(context: context, x: 963),
width: Constant.getActualX(context: context, x: 320),
// height: Constant.getActualY(context: context, y: 533),
child: LoginBox(),
)
],
),
);
}
}

View File

@@ -0,0 +1,64 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../provider/dio_provider.dart';
import '../../repository/auth_repository.dart';
import '../../repository/base_repository.dart';
// 3. state provider
final logoutProvider = StateNotifierProvider<LogoutNotifier, LogoutState>(
(ref) => LogoutNotifier(ref: ref));
// 2. notifier
class LogoutNotifier extends StateNotifier<LogoutState> {
final Ref ref;
LogoutNotifier({required this.ref}) : super(LogoutStateInit());
void logout({
required String M_UserID,
required String M_UserUsername,
}) async {
try {
state = LogoutStateLoading();
final resp = await AuthRepository(dio: ref.read(dioProvider))
.logout(M_UserID: M_UserID, M_UserUsername: M_UserUsername);
// print(resp);
state = LogoutStateDone(message: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = LogoutStateError(message: e.message ?? "");
} else {
state = LogoutStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class LogoutState extends Equatable {
final DateTime date;
const LogoutState(this.date);
@override
List<Object?> get props => [date];
}
class LogoutStateInit extends LogoutState {
LogoutStateInit() : super(DateTime.now());
}
class LogoutStateLoading extends LogoutState {
LogoutStateLoading() : super(DateTime.now());
}
class LogoutStateError extends LogoutState {
final String message;
LogoutStateError({
required this.message,
}) : super(DateTime.now());
}
class LogoutStateDone extends LogoutState {
final String message;
LogoutStateDone({
required this.message,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,23 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
class LogingScreen extends HookConsumerWidget {
const LogingScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final auth = ref.watch(authProvider);
return Material(
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(20),
child: ListView(
children: [Text("a"), Text("AUTH"), Text(jsonEncode(auth))],
),
),
);
}
}

View File

@@ -0,0 +1,65 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/repository/order_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class CancelOrderState extends Equatable {
final DateTime date;
const CancelOrderState(this.date);
@override
List<Object?> get props => [date];
}
class CancelOrderStateInit extends CancelOrderState {
CancelOrderStateInit() : super(DateTime.now());
}
class CancelOrderStateLoading extends CancelOrderState {
CancelOrderStateLoading() : super(DateTime.now());
}
class CancelOrderStateError extends CancelOrderState {
final String message;
CancelOrderStateError({
required this.message,
}) : super(DateTime.now());
}
class CancelOrderStateDone extends CancelOrderState {
final String number;
CancelOrderStateDone({
required this.number,
}) : super(DateTime.now());
}
//notifier
class CancelOrderNotifier extends StateNotifier<CancelOrderState> {
final Ref ref;
CancelOrderNotifier({
required this.ref,
}) : super(CancelOrderStateInit());
void cancel({required String token, required String orderID}) async {
try {
state = CancelOrderStateLoading();
final dio = ref.read(dioProvider);
final resp = await OrderRepository(dio: dio)
.cancelOrder(token: token, orderID: orderID);
state = CancelOrderStateDone(number: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = CancelOrderStateError(message: e.message.toString());
} else {
state = CancelOrderStateError(message: e.toString());
}
}
}
}
//provider
final CancelOrderProvider =
StateNotifierProvider<CancelOrderNotifier, CancelOrderState>(
(ref) => CancelOrderNotifier(ref: ref));

View File

@@ -0,0 +1,154 @@
import 'package:flutter/material.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
class DialogCancelOrder extends StatelessWidget {
const DialogCancelOrder(
{super.key,
required this.orderNumber,
required this.cancel,
required this.orderID,
required this.loading,
required this.name});
final String name;
final String orderNumber;
final Function cancel;
final String orderID;
final bool loading;
@override
Widget build(BuildContext context) {
return AlertDialog(
titlePadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 24)),
actionsPadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 24)),
contentPadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 24)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8))),
title: Text(
'Konfirmasi Pembatalan',
style: Constant.h4_600(context: context),
),
content: Container(
constraints: BoxConstraints(
minHeight: Constant.getActualY(context: context, y: 100),
maxHeight: Constant.getActualY(context: context, y: 362),
),
height: Constant.getActualY(context: context, y: 240),
child: Column(
children: [
Text(
'Anda yakin membatalkan order berikut ?',
style: Constant.body1_600(context: context),
),
SizedBox(
height: Constant.getActualY(context: context, y: 24),
),
SizedBox(
width: Constant.getActualX(context: context, x: 416),
child: Card(
color: Colors.white,
elevation: 1,
shape: RoundedRectangleBorder(
side: BorderSide(color: Constant.grey_200),
borderRadius: BorderRadius.circular(12)),
child: Container(
padding: EdgeInsets.symmetric(
horizontal:
Constant.getActualX(context: context, x: 24),
vertical:
Constant.getActualY(context: context, y: 24)),
child: Column(
children: [
Row(
children: [
Expanded(
flex: 5,
child: Text(
"Nomor Reg",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
),
Expanded(
flex: 7,
child: Text(
orderNumber,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack),
),
)
],
),
SizedBox(
height:
Constant.getActualY(context: context, y: 12),
),
Row(
children: [
Expanded(
flex: 5,
child: Text(
"Nama",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
),
Expanded(
flex: 7,
child: Text(
name,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack),
),
)
],
),
],
)),
),
)
],
)),
actions: <Widget>[
OutlinedButton(
style: OutlinedButton.styleFrom(
surfaceTintColor: Constant.primaryBlue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: !loading ? () => Navigator.pop(context, 'Batal') : null,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: loading
? LoadingAnimationWidget.staggeredDotsWave(
color: Constant.primaryBlue, size: 20)
: Text('Batal',
style: Constant.button_medium(context: context)
.copyWith(color: Constant.textBlack)),
),
),
ElevatedButton(
onPressed: !loading ? () => cancel(orderID) : null,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: loading
? LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white, size: 20)
: Text(
'Yakin',
style: Constant.button_medium(context: context)
.copyWith(color: Colors.white),
),
),
),
],
);
}
}

View File

@@ -0,0 +1,141 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/app/constant.dart';
import 'package:mitra_corporate/provider/order_provider.dart';
import 'package:mitra_corporate/screen/order/edit_pemeriksaan.dart';
import 'package:mitra_corporate/screen/order/form_detail_edit.dart';
import 'package:mitra_corporate/screen/registrasi/registrasi_sukses.dart';
import 'package:mitra_corporate/widgets/stepper_edit.dart';
import 'form_edit_data_pasien.dart';
class DialogEdit extends HookConsumerWidget {
const DialogEdit({super.key});
// const DialogDataPasien({
// Key? key,
// }) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final editStep = ref.watch(EditStepProvider);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: SimpleDialog(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12))),
contentPadding: const EdgeInsets.all(40.0),
children: [
Column(children: [
(editStep == 3)
? Text('')
: SizedBox(
width: Constant.getActualX(context: context, x: 1080),
height: Constant.getActualY(context: context, y: 62),
child: Text('Edit Order',
style: Constant.h2_600(context: context)
.copyWith(color: Constant.textBlack)),
),
SizedBox(height: Constant.getActualY(context: context, y: 40)),
//Stepper
(editStep == 3)
? Text('')
: SizedBox(
width: Constant.getActualX(context: context, x: 1080),
height: Constant.getActualY(context: context, y: 100),
child: StepperEdit()),
SizedBox(
height: Constant.getActualY(context: context, y: 40),
),
// membaca perubahan value dari registrasi_provider.dart
(editStep == 0)
? FormEditDatapasien()
: (editStep == 1)
? FormEditPemeriksaan()
: (editStep == 2)
? DetailEdit()
: (editStep == 3)
? RegistrasiSukses()
: Text('Tidak ada view'),
// if(editStep == 1){
// FormDataPasien()
// } else{
// if(editStep == 2){
// Text('2')
// }else{
// Text('3')
// }
// }
//
// SizedBox(height: Constant.getActualY(context: context, y: 24)),
// Container(
// // height: Constant.getActualY(context: context, y: 100),
// // color: Colors.red,
// padding: const EdgeInsets.only(left: 32, right: 32),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.end,
// children: [
// (editStep == 4)
// ? Text('')
// : OutlinedButton(
// style: OutlinedButton.styleFrom(
// backgroundColor: Colors.white,
// side: BorderSide(
// color: Constant.primaryBlue, width: 2),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(8))),
// onPressed: () {
// ref
// .read(registrasiProvider.state)
// .update((state) => state - 1);
// },
// child: SizedBox(
// height: Constant.getActualY(context: context, y: 56),
// child: Center(
// child: Text('Batal',
// style: Constant.body3_600(context: context)
// .copyWith(color: Constant.textBlue)),
// ),
// )),
// SizedBox(width: Constant.getActualX(context: context, x: 24)),
// (editStep == 4)
// ? Text('')
// : ElevatedButton(
// style: ElevatedButton.styleFrom(
// backgroundColor: Constant.primaryBlue,
// side:
// BorderSide(color: Constant.primaryBlue, width: 2),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(8),
// ),
// ),
// // onPressed: () {
// // showDialog(
// // context: context,
// // builder: ((context) => DialogPemeriksaan()));
// // },
// onPressed: () {
// ref
// .read(registrasiProvider.state)
// .update((state) => state + 1);
// },
// child: SizedBox(
// height: Constant.getActualY(context: context, y: 56),
// child: Center(
// child: Text('Simpan Perubahan',
// style: Constant.body3_600(context: context)
// .copyWith(color: Constant.textWhite)),
// ),
// )),
// ],
// ),
// )
])
]),
);
}
}

View File

@@ -0,0 +1,64 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/registration_model.dart';
import 'package:mitra_corporate/repository/order_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class EditOrderState extends Equatable {
final DateTime date;
const EditOrderState(this.date);
@override
List<Object?> get props => [date];
}
class EditOrderStateInit extends EditOrderState {
EditOrderStateInit() : super(DateTime.now());
}
class EditOrderStateLoading extends EditOrderState {
EditOrderStateLoading() : super(DateTime.now());
}
class EditOrderStateError extends EditOrderState {
final String message;
EditOrderStateError({
required this.message,
}) : super(DateTime.now());
}
class EditOrderStateDone extends EditOrderState {
final String number;
EditOrderStateDone({
required this.number,
}) : super(DateTime.now());
}
//notifier
class EditOrderNotifier extends StateNotifier<EditOrderState> {
final Ref ref;
EditOrderNotifier({
required this.ref,
}) : super(EditOrderStateInit());
void editOrder({required RegistrationModel prm}) async {
try {
state = EditOrderStateLoading();
final dio = ref.read(dioProvider);
final resp = await OrderRepository(dio: dio).editOrder(prm: prm);
state = EditOrderStateDone(number: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = EditOrderStateError(message: e.message.toString());
} else {
state = EditOrderStateError(message: e.toString());
}
}
}
}
//provider
final EditOrderProvider =
StateNotifierProvider<EditOrderNotifier, EditOrderState>(
(ref) => EditOrderNotifier(ref: ref));

View File

@@ -0,0 +1,655 @@
import 'dart:convert';
import 'dart:ui';
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/model/auth_model.dart';
import 'package:mitra_corporate/model/registration_model.dart';
import 'package:mitra_corporate/model/test_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/provider/order_provider.dart';
import 'package:mitra_corporate/screen/registrasi/registrasi_prvider.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import '../../app/constant.dart';
import '../../provider/registrasi_provider.dart';
import '../../widgets/custom_snackbar_widget.dart';
import '../../widgets/custom_text_field.dart';
// ubah stateless jadi HookConsumerWidget
class FormEditPemeriksaan extends HookConsumerWidget {
const FormEditPemeriksaan({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final tempRegistrationData = ref.watch(EditDataProvider);
final selectedtest = ref.watch(selectedTestEditProvider);
final selectedPacket = ref.watch(selectedPacketEditProvider);
final selectedPacketOld = ref.watch(currentPacketProvider);
// inisialisasi baca provider idTipePeriksaStateProvider
final selectedTab = ref.watch(idTipePeriksaStateProvider);
final AuthModel auth = ref.watch(authProvider) ?? AuthModel();
final listTest = useState<List<TestModel>>(List.empty());
final testLoading = useState(false);
final searchCtr = useTextEditingController(text: "");
final scrollCtr = useScrollController();
final ctr = useState(AutoScrollController());
//get pemeriksaan from api
getPemeriksaan() {
ref
.read(GetFPPProvider.notifier)
.getData(mouID: auth.mUserMMouID ?? "0", token: auth.token ?? "0");
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
getPemeriksaan();
});
return () {};
}, []);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
int index = listTest.value
.indexWhere((element) => element.tabId == selectedTab);
if (searchCtr.text.isNotEmpty) {
ctr.value.scrollToIndex(index);
}
// scrollCtr.animateTo(double.parse(index.toString()),
// curve: Curves.linear, duration: Duration(milliseconds: 100));
// // scrollCtr.jumpTo(double.parse(index.toString()));
});
return () {};
}, [selectedTab]);
ref.listen(
GetFPPProvider,
(pref, next) {
if (next is GetFPPStateInit) {
testLoading.value = true;
} else if (next is GetFPPStateLoading) {
testLoading.value = true;
} else if (next is GetFPPStateError) {
testLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is GetFPPStateDone) {
listTest.value = next.model;
ref.read(tempTestListProvider.notifier).state = next.model;
// tabController.length
testLoading.value = false;
}
},
);
// searchCtr.addListener(() {
// listTest.value.firstWhere((element) => element.items)
// },);
return Material(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 500),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
suffixIcon: const Icon(EvaIcons.search),
controller: searchCtr,
isPassword: false,
hintText: "Cari Pemeriksaan",
labelText: "Cari Pemeriksaan",
),
),
SizedBox(height: Constant.getActualY(context: context, y: 12)),
// Tab
testLoading.value
? LoadingAnimationWidget.discreteCircle(
color: Colors.blue, size: 20)
: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: Constant.getActualX(context: context, x: 1080)),
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: Constant.getActualY(context: context, y: 70),
child: ScrollConfiguration(
behavior:
ScrollConfiguration.of(context).copyWith(dragDevices: {
PointerDeviceKind.mouse,
PointerDeviceKind.touch,
PointerDeviceKind.trackpad,
PointerDeviceKind.stylus,
PointerDeviceKind.unknown
}),
child: ListView(
controller: ctr.value,
scrollDirection: Axis.horizontal,
children: listTest.value
.asMap()
.entries
.map((e) => AutoScrollTag(
key: ValueKey(e.key),
index: e.key,
controller: ctr.value,
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: selectedTab == e.value.tabId
? BorderSide(
width: 2,
color: Constant.primaryRed)
: const BorderSide(
color: Colors.transparent),
),
),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shadowColor: Constant.primaryRed
.withOpacity(0.5),
backgroundColor: Colors.transparent,
elevation: 0),
onPressed: () {
ref
.read(idTipePeriksaStateProvider
.state)
.update((state) => e.value.tabId!);
},
child: Text(
e.value.tab!,
style:
Constant.body3_500(context: context)
.copyWith(color: Colors.black),
)),
),
))
.toList(),
),
),
),
),
SizedBox(height: Constant.getActualY(context: context, y: 14)),
// widget checkbox semua biar rapi
listCheckboxWidget(
search: searchCtr,
listTest: listTest,
loading: testLoading,
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
SizedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
OutlinedButton(
style: OutlinedButton.styleFrom(
backgroundColor: Colors.white,
side: BorderSide(color: Colors.grey.shade400, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: () {
// Navigator.pop(context);
ref
.read(EditStepProvider.state)
.update((state) => state - 1);
},
child: SizedBox(
height: Constant.getActualY(context: context, y: 56),
child: Center(
child: Text('Sebelumnya',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack)),
),
)),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Constant.green,
side: BorderSide(color: Constant.green, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
onPressed: () {
if (selectedtest.isEmpty && selectedPacket.isEmpty) {
SanckbarWidget(context, "Belum memilih Pemeriksaan",
snackbarType.warning);
return;
}
List<Tests> ts = List.empty(growable: true);
double total = 0;
for (var i = 0; i < selectedtest.length; i++) {
var splitted = selectedtest[i].split("|");
var tabid = splitted[0];
var testid = splitted[1];
for (var j = 0; j < listTest.value.length; j++) {
if (listTest.value[j].tabId == int.parse(tabid)) {
var tests = listTest.value[j].items;
for (var k = 0; k < tests!.length; k++) {
if (tests[k].testID == testid) {
ts.add(Tests(
date: DateTime.now().toString(),
id: tests[k].testID,
name: tests[k].testName,
price: tests[k].testPrice,
sasCode: tests[k].sasCode,
// specimen: "",
tab: tabid,
));
total = total +
double.parse(tests[k].testPrice ?? "0");
}
}
}
}
}
List<Paket> pkt = List.empty(growable: true);
for (var i = 0; i < selectedPacket.length; i++) {
var paket = listTest.value
.firstWhere((element) => element.isPaket == "Y");
paket.items?.forEach((element) {
if (element.testID == selectedPacket[i]) {
if (selectedPacketOld.isNotEmpty) {
for (var i in selectedPacketOld) {
var splitted = i.split('|');
if (splitted[1] == element.testID) {
pkt.add(Paket(
detailID: splitted[0],
id: element.testID,
arrTest: element.arrTest,
detail: element.sasCode,
name: element.testName));
total = total +
double.parse(element.testPrice ?? "0");
} else {
pkt.add(Paket(
detailID: "new",
id: element.testID,
price: element.testPrice,
type: element.type,
arrTest: element.arrTest,
detail: element.sasCode,
name: element.testName));
total = total +
double.parse(element.testPrice ?? "0");
}
}
} else {
pkt.add(Paket(
detailID: "new",
id: element.testID,
arrTest: element.arrTest,
detail: element.sasCode,
price: element.testPrice,
type: element.type,
name: element.testName));
total =
total + double.parse(element.testPrice ?? "0");
}
}
});
}
bool paketValidation = false;
bool testValidation = false;
for (var e in pkt) {
var test = e.arrTest?.split(",");
test?.forEach((f) {
for (var g in pkt) {
if (e.id?.trim() != g.id?.trim()) {
var testCek = g.arrTest!.split(",");
var cek = testCek.firstWhere(
(h) => h.trim() == f.trim(),
orElse: () => "-1",
);
if (cek != "-1") {
paketValidation = true;
}
}
}
});
}
for (var e in pkt) {
var test = e.arrTest?.split(",");
test?.forEach((f) {
for (var g in ts) {
if (f.trim() == g.id?.trim()) {
testValidation = true;
}
}
});
}
if (paketValidation) {
SanckbarWidget(
context,
"Paket pilihan memiliki pemeriksaan yang sama ",
snackbarType.warning);
return;
}
if (testValidation) {
SanckbarWidget(
context,
"Paket pilihan memiliki pemeriksaan yang sama dengan test pilihan",
snackbarType.warning);
return;
}
ref.read(EditDataProvider.notifier).state =
RegistrationModel(
orderID: tempRegistrationData.orderID,
patientId: tempRegistrationData.patientId,
token: auth.token,
patientData: tempRegistrationData.patientData,
specimens: tempRegistrationData.specimens,
bahan: tempRegistrationData.bahan,
paket: pkt,
tests: ts,
total: total.toString());
print("Specimen awal");
print(jsonEncode(tempRegistrationData.specimens));
print("Bahan awal");
print(jsonEncode(tempRegistrationData.bahan));
ref.read(EditStepProvider.state).update((state) => 2);
},
child: SizedBox(
height: Constant.getActualY(context: context, y: 56),
child: Center(
child: Text('Berikutnya',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textWhite)),
),
)),
],
),
)
],
));
}
}
class listCheckboxWidget extends HookConsumerWidget {
const listCheckboxWidget(
{super.key,
required this.listTest,
required this.loading,
required this.search});
final ValueNotifier<List<TestModel>> listTest;
final ValueNotifier<bool> loading;
final TextEditingController search;
@override
Widget build(BuildContext context, WidgetRef ref) {
bool? isChecked = false;
final tests = useState<List<Items>>(List.empty());
final isPaket = useState(false);
// inisialisasi state provider buat baca idTipePeriksa yang di klik
final selectedTab = ref.watch(idTipePeriksaStateProvider);
final selectedTest = ref.watch(selectedTestEditProvider);
final selectedPacket = ref.watch(selectedPacketEditProvider);
final scrollCtr = useScrollController();
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
if (loading.value == false && listTest.value.isNotEmpty) {
// TestModel temp = listTest.value[0];
var selected = listTest.value
.firstWhere((element) => element.tabId == selectedTab);
if (selected.isPaket == 'Y') {
isPaket.value = true;
} else {
isPaket.value = false;
}
if (search.text.isNotEmpty) {
List<Items> filter = selected.items!
.where((element) =>
element.testName!.toLowerCase().contains(search.text))
.toList();
tests.value = filter;
} else {
tests.value = selected.items ?? [];
}
}
});
return () {};
}, [selectedTab, loading.value]);
search.addListener(
() {
if (loading.value == false && listTest.value.isNotEmpty) {
for (var i = 0; i < listTest.value.length; i++) {
List<Items> flt = listTest.value[i].items!
.where((element) =>
element.testName!.toLowerCase().contains(search.text))
.toList();
if (flt.isNotEmpty) {
ref.read(idTipePeriksaStateProvider.notifier).state =
listTest.value[i].tabId!;
break;
}
}
var selected = listTest.value
.firstWhere((element) => element.tabId == selectedTab);
if (search.text.isNotEmpty) {
List<Items> filter = selected.items!
.where((element) =>
element.testName!.toLowerCase().contains(search.text))
.toList();
tests.value = filter;
} else {
tests.value = selected.items ?? [];
}
}
},
);
selectedItem(int idTab, String idTest) {
List<String> temp = selectedTest.toSet().toList(growable: true);
var data = "$idTab|$idTest";
var cek = temp.firstWhere(
(element) => element == data,
orElse: () => "-1",
);
if (cek == "-1") {
temp.add(data);
} else {
temp.remove(cek);
}
ref.read(selectedTestEditProvider.notifier).state = temp.toSet().toList();
}
valueCek<Bool>(int idTab, String idTest) {
var data = "$idTab|$idTest";
var cek = selectedTest.firstWhere(
(element) => element == data,
orElse: () => "-1",
);
if (cek == "-1") {
return false;
} else {
return true;
}
}
selectPacket(String idTest) {
List<String> temp = selectedPacket.toSet().toList(growable: true);
var cek = temp.firstWhere(
(element) => element == idTest,
orElse: () => "-1",
);
if (cek == "-1") {
temp.add(idTest);
} else {
temp.remove(cek);
}
ref.read(selectedPacketEditProvider.notifier).state =
temp.toSet().toList();
}
valueCekPacket<Bool>(String idTest) {
var cek = selectedPacket.firstWhere(
(element) => element == idTest,
orElse: () => "-1",
);
if (cek == "-1") {
return false;
} else {
return true;
}
}
// buat data2 dari List Periksa
return Row(children: [
SizedBox(
width: Constant.getActualX(context: context, x: 1080),
height: Constant.getActualY(context: context, y: 230),
child: loading.value
? Center(
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 30),
)
: Scrollbar(
controller: scrollCtr,
thumbVisibility: true,
trackVisibility: true,
child: ScrollConfiguration(
behavior:
ScrollConfiguration.of(context).copyWith(dragDevices: {
PointerDeviceKind.mouse,
PointerDeviceKind.touch,
PointerDeviceKind.trackpad,
PointerDeviceKind.stylus,
PointerDeviceKind.unknown
}),
child: isPaket.value
? ListView(
controller: scrollCtr,
children: tests.value
.map(
(e) => Container(
margin: EdgeInsets.symmetric(vertical: 5),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
children: [
Checkbox(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(4)),
// value: valueCek(
// selectedTab, e.testID!),
value: valueCekPacket(e.testID!),
onChanged: (value) {
print(value);
selectPacket(e.testID!);
// selectedItem(
// selectedTab, e.testID!);
}),
SizedBox(
// constraints: BoxConstraints(
// maxWidth:
// ),
// color: Colors.red,
width: Constant.getActualX(
context: context, x: 380),
child: Text('${e.testName}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Constant.body3_400(
context: context)
.copyWith(
color: Constant
.textBlack)),
),
],
),
Padding(
padding: EdgeInsets.only(left: 30),
child: Text(
e.sasCode ?? "",
style: Constant.caption2_400(
context: context)
.copyWith(
color: Constant.textGrey),
),
)
],
),
),
)
.toList(),
)
: GridView.count(
controller: scrollCtr,
shrinkWrap: true,
crossAxisCount: 2,
childAspectRatio: 15,
children: tests.value
.map(
(e) => Container(
// color: Colors.primaries[
// Random().nextInt(Colors.primaries.length)],
child: Row(
children: [
Checkbox(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(4)),
// value: valueCek(selectedTab, e.testID!),
value:
valueCek(selectedTab, e.testID!),
onChanged: (value) {
print(value);
selectedItem(
selectedTab, e.testID!);
}),
SizedBox(
// constraints: BoxConstraints(
// maxWidth:
// ),
// color: Colors.red,
width: Constant.getActualX(
context: context, x: 380),
child: Text('${e.testName}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Constant.body3_400(
context: context)
.copyWith(
color: Constant.textBlack)),
),
// Container(
// // constraints: BoxConstraints(
// // maxWidth:
// // ),
// // color: Colors.red,
// // width:
// // Constant.getActualX(context: context, x: 350),
// child: Text(
// Constant.convertToIdr(
// int.parse(e.testPrice ?? "0"), 0),
// style: Constant.body3_500(
// context: context)
// .copyWith(color: Constant.textBlack)),
// ),
],
),
),
)
.toList(),
),
),
),
),
]);
}
}

View File

@@ -0,0 +1,663 @@
import 'dart:convert';
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:mitra_corporate/model/registration_model.dart';
import 'package:mitra_corporate/model/test_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/provider/order_provider.dart';
import 'package:mitra_corporate/provider/registrasi_provider.dart';
import 'package:mitra_corporate/screen/order/edit_order_provider.dart';
import 'package:mitra_corporate/screen/registrasi/get_specimen_provider.dart';
import 'package:mitra_corporate/widgets/tests_tabel_edit_widget.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../widgets/custom_snackbar_widget.dart';
class DetailEdit extends HookConsumerWidget {
const DetailEdit({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final auth = ref.watch(authProvider);
final tempRegistrationData = ref.watch(EditDataProvider);
final selectedtestDataOld = ref.watch(selectedtestData);
final selectedPacketOld = ref.watch(currentPacketProvider);
final testListAll = ref.read(tempTestListProvider);
final selectedTest = ref.read(selectedTestEditProvider);
final dialogAction = ref.watch(dialogOrderActionProvider);
final testList = useState<List<Items>>(List.empty());
final testScrollCtr = useScrollController();
final specimenLoading = useState(false);
final addOrderLoading = ref.watch(editOrderLoadingProvider);
final tabctr = useTabController(initialLength: 2);
final selectedTab = useState(0);
//get specimen & bahan from list of tests
getSpecimen() {
List<Map<String, String>> test = List.empty(growable: true);
tempRegistrationData.tests?.forEach((element) {
test.add({
"id": element.id ?? "0",
"tab": element.tab ?? "0",
"sasCode": element.sasCode ?? "-"
});
});
// print(jsonEncode(test));
ref
.read(GetSpecimenProvider.notifier)
.getData(arrTest: test, token: auth?.token ?? "0");
}
ref.listen(
GetSpecimenProvider,
(pref, next) {
if (next is GetSpecimenStateInit) {
specimenLoading.value = true;
} else if (next is GetSpecimenStateLoading) {
specimenLoading.value = true;
} else if (next is GetSpecimenStateError) {
specimenLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is GetSpecimenStateDone) {
var tests = tempRegistrationData.tests;
//assign specimn & bahan
List<GetSpecimenModel> nw = next.model;
List<Specimens> sp = List.empty(growable: true);
List<Bahan> bhn = List.empty(growable: true);
for (var i = 0; i < tests!.length; i++) {
var tes = tests[i];
var cek = "${tes.tab}|${tes.id}";
for (var j = 0; j < nw.length; j++) {
var cek2 = "${nw[j].tab}|${nw[j].id}";
if (cek == cek2) {
tests[i].specimen = nw[j].specimen?.toSet().toList();
tests[i].bahan = nw[j].bahan?.toSet().toList();
tests[i].detailID = 'new';
nw[j].specimen?.forEach((element) {
var a = sp.firstWhere(
(dt) => dt.id == element.id,
orElse: () =>
Specimens(ctr: TextEditingController(), id: "new"),
);
if (a.id == "new") {
element.detailID = "new";
sp.add(element);
}
});
nw[j].bahan?.forEach((element) {
var a = bhn.firstWhere(
(dt) => dt.id == element.id,
orElse: () =>
Bahan(ctr: TextEditingController(), id: "new"),
);
if (a.id == "new") {
element.detailID = "new";
bhn.add(element);
}
});
}
}
}
print("SPECIMEN");
print(jsonEncode(sp));
print("BAHAN");
print(jsonEncode(bhn));
for (var e in sp) {
tempRegistrationData.specimens?.forEach((i) {
if (e.id == i.id) {
e.detailID = i.detailID;
e.ctr.text = i.amount ?? "0";
e.amount = i.amount ?? "0";
}
});
}
for (var e in bhn) {
tempRegistrationData.bahan?.forEach((i) {
if (e.id == i.id) {
e.detailID = i.detailID;
e.ctr.text = i.amount ?? "0";
e.amount = i.amount ?? "0";
}
});
}
print("SPECIMEN2");
print(jsonEncode(sp));
print("BAHAN2");
print(jsonEncode(bhn));
for (var e in tests) {
for (var i in selectedtestDataOld) {
//detailid|idtest|testdate
// 68|205|2023-10-18 14:32:19
var splitted = i.split('|');
if (e.id == splitted[1]) {
e.detailID = splitted[0];
///assign date
// e.date = splitted[2];
e.date = DateFormat('dd-MM-yyyy HH:mm')
.format(DateTime.parse(splitted[2]))
.toString();
}
}
}
ref.read(EditDataProvider.notifier).state = RegistrationModel(
orderID: tempRegistrationData.orderID,
patientId: tempRegistrationData.patientId,
token: auth?.token,
patientData: tempRegistrationData.patientData,
paket: tempRegistrationData.paket,
tests: tests,
specimens: sp.toSet().toList(),
bahan: bhn.toSet().toList(),
total: tempRegistrationData.total);
specimenLoading.value = false;
}
},
);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
List<Items> temp = List.empty(growable: true);
for (var element in testListAll) {
// "$idTab|$idTest"
for (var i in element.items!) {
String cek = "${element.tabId}|${i.testID}";
String ck = selectedTest.firstWhere(
(j) => j == cek,
orElse: () => "-1",
);
if (ck != "-1") {
temp.add(i);
}
}
}
testList.value = temp;
getSpecimen();
});
return () {};
}, []);
//delete tests & auto cek & delete specimen/bahan
delete(String idTest, String idtab) {
List<Tests> temp = tempRegistrationData.tests ?? [];
List<String> selectedTest = ref.watch(selectedTestEditProvider);
String cek = "$idtab|$idTest";
double total = double.parse(tempRegistrationData.total!);
List<Specimens> oldSp = tempRegistrationData.specimens ?? [];
List<Bahan> oldBhn = tempRegistrationData.bahan ?? [];
Tests removed = tempRegistrationData.tests!.firstWhere(
(element) => element.id == idTest && element.tab == idtab);
temp.removeWhere(
(element) => element.id == idTest && element.tab == idtab);
selectedTest.removeWhere((element) => element == cek);
total = total - double.parse(removed.price!);
// var tests = tempRegistrationData.tests;
// List<GetSpecimenModel> nw = next.model;
List<Specimens> newSp = List.empty(growable: true);
List<Bahan> newBhn = List.empty(growable: true);
for (var j = 0; j < temp.length; j++) {
temp[j].specimen?.forEach((element) {
var a = newSp.firstWhere(
(dt) => dt.id == element.id,
orElse: () => Specimens(ctr: TextEditingController(), id: "new"),
);
if (a.id == "new") {
newSp.add(element);
}
});
temp[j].bahan?.forEach((element) {
var a = newBhn.firstWhere(
(dt) => dt.id == element.id,
orElse: () => Bahan(ctr: TextEditingController(), id: "new"),
);
if (a.id == "new") {
newBhn.add(element);
}
});
}
// print("old sp");
// print(jsonEncode(oldSp));
// print("new sp");
// print(jsonEncode(newSp));
//compare old dp and new sp to get deleted specimen
List<Specimens> deletedSp = List.empty(growable: true);
for (var i = 0; i < oldSp.length; i++) {
Specimens sp = newSp.firstWhere((element) => element.id == oldSp[i].id,
orElse: () =>
Specimens(ctr: TextEditingController(), id: "deleted"));
if (sp.id == "deleted") {
deletedSp.add(oldSp[i]);
}
}
List<Specimens> tempSp = tempRegistrationData.specimens ?? [];
for (var e in deletedSp) {
tempSp.removeWhere((element) => element.id == e.id);
}
// print("deleted sp");
// print(jsonEncode(deletedSp));
// print("old bhn");
// print(jsonEncode(oldBhn));
// print("new bhn");
// print(jsonEncode(newBhn));
//compare old bhn and new bhn to get deleted bahan
List<Bahan> deletedBhn = List.empty(growable: true);
for (var i = 0; i < oldBhn.length; i++) {
Bahan sp = newBhn.firstWhere((element) => element.id == oldBhn[i].id,
orElse: () => Bahan(ctr: TextEditingController(), id: "deleted"));
if (sp.id == "deleted") {
deletedBhn.add(oldBhn[i]);
}
}
List<Bahan> tempBhn = tempRegistrationData.bahan ?? [];
for (var e in deletedBhn) {
tempBhn.removeWhere((element) => element.id == e.id);
}
// print("deleted bahan");
// print(jsonEncode(deletedBhn));
ref.read(EditDataProvider.notifier).state = RegistrationModel(
orderID: tempRegistrationData.orderID,
patientId: tempRegistrationData.patientId,
token: auth?.token,
patientData: tempRegistrationData.patientData,
specimens: tempSp,
paket: tempRegistrationData.paket,
bahan: tempBhn,
tests: temp,
total: total.toString());
ref.read(selectedTestEditProvider.notifier).state = selectedTest;
if (selectedTest.isEmpty) {
ref.read(EditStepProvider.state).update((state) => state - 1);
}
}
deletePaket(String idPaket) {
List<Paket> temp = tempRegistrationData.paket ?? [];
List<String> selectedPaket = ref.watch(selectedPacketEditProvider);
selectedPaket.removeWhere((element) => element == idPaket);
temp.removeWhere((element) => element.id == idPaket);
ref.read(selectedPacketEditProvider.notifier).state = selectedPaket;
ref.read(EditDataProvider.notifier).state = RegistrationModel(
orderID: tempRegistrationData.orderID,
patientId: tempRegistrationData.patientId,
token: auth?.token,
patientData: tempRegistrationData.patientData,
specimens: tempRegistrationData.specimens,
paket: temp,
bahan: tempRegistrationData.bahan,
tests: tempRegistrationData.tests,
total: tempRegistrationData.total);
}
Future<DateTime?> pickDate(DateTime initialdate) => showDatePicker(
// locale: Locale("id", "ID"),
context: context,
initialEntryMode: DatePickerEntryMode.calendarOnly,
cancelText: "Batal",
confirmText: "Simpan",
helpText: "Pilih Tanggal",
initialDate: initialdate,
firstDate: DateTime(1800),
lastDate: DateTime(2100));
Future<TimeOfDay?> pickTime(TimeOfDay initialTime) => showTimePicker(
context: context,
initialTime: initialTime,
cancelText: "Batal",
confirmText: "Simpan",
helpText: "Masukkan Jam dan Menit",
hourLabelText: "Jam",
minuteLabelText: "Menit",
builder: (context, childWidget) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
// Using 24-Hour format
alwaysUse24HourFormat: true),
// If you want 12-Hour format, just change alwaysUse24HourFormat to false or remove all the builder argument
child: childWidget!);
},
initialEntryMode: TimePickerEntryMode.input);
Future pickDateTime(String idtab, String idtest, String dt) async {
// DateTime selectedDate = DateTime.parse(dt);
// DateTime? date = await pickDate(selectedDate);
// if (date == null) return;
// TimeOfDay? time = await pickTime(
// TimeOfDay(hour: selectedDate.hour, minute: selectedDate.minute));
// if (time == null) return;
// var test = tempRegistrationData.tests ?? [];
// for (var i = 0; i < test.length; i++) {
// if (test[i].id == idtest && test[i].tab == idtab) {
// test[i].date =
// DateTime(date.year, date.month, date.day, time.hour, time.minute)
// .toString();
// }
// }
var test = tempRegistrationData.tests ?? [];
for (var i = 0; i < test.length; i++) {
if (test[i].id == idtest && test[i].tab == idtab) {
test[i].date = dt;
}
}
ref.read(EditDataProvider.notifier).state = RegistrationModel(
orderID: tempRegistrationData.orderID,
patientData: tempRegistrationData.patientData,
specimens: tempRegistrationData.specimens,
tests: test,
token: auth?.token,
patientId: tempRegistrationData.patientId,
bahan: tempRegistrationData.bahan,
total: tempRegistrationData.total);
}
bool validateDate(String? value) {
if (value == null || value.isEmpty) {
SanckbarWidget(context, "Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
final splitted = value.split(" ");
if (splitted.length == 2) {
final date = splitted[0];
final time = splitted[1];
final splittedDate = date.split("-");
final splittedTime = time.split(":");
if (splittedDate.length == 3) {
final day = int.tryParse(splittedDate[0]);
final month = int.tryParse(splittedDate[1]);
final year = int.tryParse(splittedDate[2]);
if (day != null) {
if (day > 31) {
SanckbarWidget(
context,
"Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
}
if (month != null) {
if (month > 12) {
SanckbarWidget(
context,
"Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
}
// if (year == null) {
// return "Format salah";
// }
} else {
SanckbarWidget(context, "Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
if (splittedTime.length == 2) {
var hour = int.tryParse(splittedTime[0]);
var sec = int.tryParse(splittedTime[1]);
if (hour != null) {
if (hour > 24) {
SanckbarWidget(
context,
"Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
}
if (sec != null) {
if (sec > 60) {
SanckbarWidget(
context,
"Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
}
} else {
SanckbarWidget(context, "Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
} else {
SanckbarWidget(context, "Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
return false;
}
editOrder() {
print(jsonEncode(tempRegistrationData));
// tempRegistrationData.tests!.forEach((element) {
// if (element.date == null || element.date!.isEmpty) {
// SanckbarWidget(
// context,
// "Waktu pengambilan sample ${element.name} Tidak boleh kosong",
// snackbarType.warning);
// return;
// }
// if (validateDate(element.date)) {
// return;
// }
// var coba = Jiffy.parse(element.date!, pattern: 'dd-MM-yyyy HH:mm')
// .format(pattern: 'yyyy-MM-dd HH:mm');
// });
// print(jsonEncode(tempRegistrationData));
// return;
ref.read(EditOrderProvider.notifier).editOrder(prm: tempRegistrationData);
}
ref.listen(
EditOrderProvider,
(pref, next) {
if (next is EditOrderStateInit) {
ref.read(editOrderLoadingProvider.notifier).state = true;
} else if (next is EditOrderStateLoading) {
ref.read(editOrderLoadingProvider.notifier).state = true;
} else if (next is EditOrderStateError) {
ref.read(editOrderLoadingProvider.notifier).state = false;
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is EditOrderStateDone) {
ref.read(orderNumberProvider.notifier).state = next.number;
print(next.number);
SanckbarWidget(context, "Edit Order Berhasil ", snackbarType.success);
ref.read(editOrderLoadingProvider.notifier).state = false;
Navigator.pop(context);
ref.read(EditStepProvider.notifier).state = 0;
ref.read(tabPeriksaprovider.notifier).state = 1;
ref.read(EditDataProvider.notifier).state = RegistrationModel();
ref.read(selectedtestData.notifier).state =
List.empty(growable: true);
ref.read(tempTestListProvider.notifier).state =
List.empty(growable: true);
ref.read(currentPacketProvider.notifier).state =
List.empty(growable: true);
ref.read(selectedPacketEditProvider.notifier).state = List.empty();
}
},
);
return Material(
child: Container(
width: Constant.getActualX(context: context, x: 1160),
// height: MediaQuery.of(context).size.height,
color: Colors.white,
child: Column(
children: [
Row(
children: [
SizedBox(
// color: Colors.red,
width: Constant.getActualX(context: context, x: 1160),
child: TestsTableEditWidget(
paketDelete: deletePaket,
specimenLoading: specimenLoading,
testScrollCtr: testScrollCtr,
tempRegistrationData: tempRegistrationData,
addOrderLoading: addOrderLoading,
delete: delete,
pickDateTime: pickDateTime)
// TestsTableWEditWidget(
// specimenLoading: specimenLoading,
// testScrollCtr: testScrollCtr,
// tempRegistrationData: tempRegistrationData,
// addOrderLoading: addOrderLoading,
// delete: delete,
// pickDateTime: pickDateTime),
),
// Container(
// width:
// Constant.getActualX(context: context, x: 1160) * 0.05,
// ),
// Container(
// // color: Colors.red,
// width:
// Constant.getActualX(context: context, x: 1160) * 0.24,
// child: Column(
// children: [
// Container(
// width:
// Constant.getActualX(context: context, x: 1160) *
// 0.24,
// child: TabBar(
// controller: tabctr,
// labelColor: Colors.black,
// labelStyle: Constant.body3_500(context: context)
// .copyWith(color: Colors.black),
// indicatorColor: Constant.primaryRed,
// onTap: (value) => selectedTab.value = value,
// tabs: [
// Tab(
// text: "Specimen",
// ),
// Tab(
// text: "Bahan",
// )
// ]),
// ),
// SizedBox(
// height:
// Constant.getActualY(context: context, y: 20),
// ),
// if (selectedTab.value == 0)
// SpecimenTableWidget(
// specimenLoading: specimenLoading,
// tempRegistrationData: tempRegistrationData,
// addOrderLoading: addOrderLoading),
// if (selectedTab.value == 1)
// BahanTableWidget(
// specimenLoading: specimenLoading,
// tempRegistrationData: tempRegistrationData,
// addOrderLoading: addOrderLoading)
// // SizedBox(
// // height:
// // Constant.getActualY(context: context, y: 20),
// // ),
// // BahanTableWidget(
// // specimenLoading: specimenLoading,
// // tempRegistrationData: tempRegistrationData,
// // addOrderLoading: addOrderLoading),
// ],
// ),
// ),
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
OutlinedButton(
style: OutlinedButton.styleFrom(
backgroundColor: Colors.white,
side: BorderSide(
color: Colors.grey.shade400, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: addOrderLoading == false
? () {
// Navigator.pop(context);
ref
.read(EditStepProvider.state)
.update((state) => state - 1);
}
: null,
child: SizedBox(
height:
Constant.getActualY(context: context, y: 56),
child: Center(
child: addOrderLoading
? LoadingAnimationWidget.staggeredDotsWave(
color: Constant.primaryRed, size: 30)
: Text('Sebelumnya',
style: Constant.body3_600(
context: context)
.copyWith(color: Constant.textBlack)),
),
)),
SizedBox(
width: Constant.getActualX(context: context, x: 24)),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Constant.green,
side: BorderSide(color: Constant.green, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
// onPressed: () {
// showDialog(
// context: context,
// builder: ((context) => DialogPemeriksaan()));
// },
onPressed: addOrderLoading == false
? () {
editOrder();
}
: null,
child: SizedBox(
height:
Constant.getActualY(context: context, y: 56),
child: Center(
child: addOrderLoading
? LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white, size: 30)
: Text('Simpan',
style: Constant.body3_600(
context: context)
.copyWith(color: Constant.textWhite)),
),
)),
],
),
)
],
)));
}
}

View File

@@ -0,0 +1,896 @@
import 'package:age_calculator/age_calculator.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:jiffy/jiffy.dart';
import 'package:mitra_corporate/app/constant.dart';
import 'package:mitra_corporate/model/registration_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/provider/order_provider.dart';
import 'package:mitra_corporate/screen/registrasi/get_filter_provider.dart';
import 'package:mitra_corporate/widgets/custom_snackbar_widget.dart';
import 'package:mitra_corporate/widgets/custom_text_field.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
class FormEditDatapasien extends HookConsumerWidget {
const FormEditDatapasien({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final tempPatient = ref.watch(EditDataProvider);
final auth = ref.watch(authProvider);
//withoutnik apabila tanpa nik maka true
final withoutNIK = useState(false);
final getFilterLoading = useState(false);
final sapaanKey = useState(1);
final genderKey = useState(1000);
final prefixCtr = useTextEditingController(text: "");
final nameCtr = useTextEditingController(text: "");
final suffixCtr = useTextEditingController(text: "");
final nikCtr = useTextEditingController(text: "");
final nipCtr = useTextEditingController(text: "");
final hpCtr = useTextEditingController(text: "");
final noRmCtr = useTextEditingController(text: "");
final addressCtr = useTextEditingController(text: "");
final diagnosisCtr = useTextEditingController(text: "");
final noteCtr = useTextEditingController(text: "");
final jabatanCtr = useTextEditingController(text: "");
final kedudukanCtr = useTextEditingController(text: "");
final lokasiCtr = useTextEditingController(text: "");
final pekerjaanCtr = useTextEditingController(text: "");
final sapaan = useState<List<CustomDropDownModel>>(List.empty());
final selectedSaluation = useState(CustomDropDownModel());
final gender = useState<List<CustomDropDownModel>>(List.empty());
final selectedGender = useState(CustomDropDownModel());
//select salah satu sapaan
onSelectSaluation(CustomDropDownModel value) {
selectedSaluation.value = value;
selectedGender.value =
gender.value.firstWhere((element) => element.id == value.type);
genderKey.value = genderKey.value + 1;
// sapaanKey.value = sapaanKey.value + 1;
}
//update gender saat sapaan dipilih
selectedSaluation.addListener(() {
selectedGender.value = gender.value
.firstWhere((element) => element.id == selectedSaluation.value.type);
genderKey.value = genderKey.value + 1;
});
//select gender
onSelectGender(CustomDropDownModel value) {
selectedGender.value = value;
}
final dobRb = useState('date');
final dobCtr = useTextEditingController(
text: DateFormat('dd-MM-yyyy').format(DateTime.now()));
final dobState = useState(DateTime.now());
final yearCtr = useTextEditingController(text: "0");
final monthCtr = useTextEditingController(text: "0");
final dayCtr = useTextEditingController(text: "0");
//perhitungan umur dari tanggal ke angka
DateDuration calculateAge(DateTime birthDate) {
DateTime currentDate = DateTime.now();
var age = AgeCalculator.age(birthDate, today: currentDate);
return age;
}
dobState.addListener(
() {
// print(calculateAge(dobState.value));
if (dobRb.value == "date") {
var age = calculateAge(dobState.value);
yearCtr.text = age.years.toString();
monthCtr.text = age.months.toString();
dayCtr.text = age.days.toString();
}
},
);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
nameCtr.text = tempPatient.patientData?.name ?? "";
prefixCtr.text = tempPatient.patientData?.prefix ?? "";
suffixCtr.text = tempPatient.patientData?.suffix ?? "";
nikCtr.text = tempPatient.patientData?.nik ?? "";
nipCtr.text = tempPatient.patientData?.nip ?? "";
withoutNIK.value =
tempPatient.patientData?.withoutNIK == 'Y' ? true : false;
hpCtr.text = tempPatient.patientData?.hp ?? "";
addressCtr.text = tempPatient.patientData?.address ?? "";
diagnosisCtr.text = tempPatient.patientData?.diagnosis ?? "";
noteCtr.text = tempPatient.patientData?.note ?? "";
noRmCtr.text = tempPatient.patientData?.noRM ?? "";
jabatanCtr.text = tempPatient.patientData?.jabatan ?? "";
kedudukanCtr.text = tempPatient.patientData?.kedudukan ?? "";
lokasiCtr.text = tempPatient.patientData?.lokasi ?? "";
pekerjaanCtr.text = tempPatient.patientData?.pekerjaan ?? "";
// DateFormat('dd-MM-yyyy').format(DateTime.now())
dobCtr.text = DateFormat('dd-MM-yyyy').format(DateTime.parse(
tempPatient.patientData?.dob ?? DateTime.now().toString()));
dobState.value = DateTime.parse(
tempPatient.patientData?.dob ?? DateTime.now().toString());
ref
.read(GetFilterRegistrationProvider.notifier)
.getData(token: auth!.token ?? "");
});
return () {};
}, []);
ref.listen(
GetFilterRegistrationProvider,
(previous, next) {
if (next is GetFilterRegistrationStateInit) {
getFilterLoading.value = true;
} else if (next is GetFilterRegistrationStateLoading) {
getFilterLoading.value = true;
} else if (next is GetFilterRegistrationStateError) {
SanckbarWidget(context, next.message, snackbarType.error);
getFilterLoading.value = false;
Constant.autoLogout(context: context, msg: next.message);
} else if (next is GetFilterRegistrationStateDone) {
// print(jsonEncode(next.model));
sapaan.value = next.model.titles!;
gender.value = next.model.gender!;
// selectedGender.value = next.model.gender![0];
if (tempPatient.patientData?.saluation != null) {
var sp = next.model.titles!.firstWhere(
(element) => element.id == tempPatient.patientData?.saluation);
selectedSaluation.value = sp;
}
if (tempPatient.patientData?.gender != null) {
var gd = next.model.gender!.firstWhere(
(element) => element.id == tempPatient.patientData?.gender);
selectedGender.value = gd;
}
sapaanKey.value = sapaanKey.value + 1;
genderKey.value = genderKey.value + 1;
getFilterLoading.value = false;
}
},
);
//Function ke step selanjutny(pilih pemeriksaan)
nextStep() {
if (withoutNIK.value == false) {
if (nikCtr.text.isEmpty) {
SanckbarWidget(context, "NIK Harus diisi", snackbarType.warning);
return;
}
if (nikCtr.text.length < 16 || nikCtr.text.length > 16) {
SanckbarWidget(
context, "NIK berjumlah 16 digit", snackbarType.warning);
return;
}
}
if (nameCtr.text.isEmpty || selectedGender.value.id == null) {
// print(nameCtr.text);
// print(selectedGender.value.name);
SanckbarWidget(
context,
"Nama, Tanggal Lahir, dan Jenis Kelamin Haruus Diisi !",
snackbarType.warning);
} else {
var temp = ref.watch(EditDataProvider);
PatientData data = PatientData(
noRM: noRmCtr.text,
saluation: selectedSaluation.value.id,
name: nameCtr.text,
prefix: prefixCtr.text,
suffix: suffixCtr.text,
dob: dobState.value.toString(),
nik: nikCtr.text,
nip: nipCtr.text,
withoutNIK: withoutNIK.value ? "Y" : "N",
gender: selectedGender.value.id.toString(),
address: addressCtr.text,
diagnosis: diagnosisCtr.text,
hp: hpCtr.text,
note: noteCtr.text);
ref.read(EditDataProvider.notifier).state = RegistrationModel(
orderID: temp.orderID,
token: auth?.token ?? "",
patientId: temp.patientId ?? "new",
patientData: data,
specimens: temp.specimens,
bahan: temp.bahan,
tests: temp.tests,
total: temp.total);
ref.read(EditStepProvider.state).update((state) => 1);
}
}
return Padding(
padding: const EdgeInsets.only(top: 20, bottom: 20, left: 24, right: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 120),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
DropdownMenu<CustomDropDownModel>(
enabled: false,
menuHeight:
Constant.getActualY(context: context, y: 300),
key: ValueKey(sapaanKey.value),
initialSelection: selectedSaluation.value,
trailingIcon: getFilterLoading.value
? LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)
: null,
width: Constant.getActualX(context: context, x: 120),
hintText: "Sapaan",
textStyle: Constant.body2_400(context: context),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
)),
label: const Text(
"Sapaan",
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
onSelected: (value) {
onSelectSaluation(value!);
selectedSaluation.value = value;
},
dropdownMenuEntries: sapaan.value
.map<DropdownMenuEntry<CustomDropDownModel>>(
(e) => DropdownMenuEntry(
value: e, label: e.name ?? ""))
.toList()),
],
)),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 160),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
disable: false,
hintText: 'Prefix',
labelText: "Prefix",
controller: prefixCtr,
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 520),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
disable: false,
hintText: 'Name',
labelText: "Nama",
controller: nameCtr,
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 160),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
disable: false,
hintText: 'Suffix',
labelText: "suffix",
controller: suffixCtr,
),
),
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Row(
children: [
Radio<String>(
value: "date",
groupValue: dobRb.value,
onChanged: (value) {
dobRb.value = value!;
},
),
SizedBox(width: Constant.getActualX(context: context, x: 20)),
SizedBox(
width: Constant.getActualX(context: context, x: 252),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
TextField(
enabled: false,
controller: dobCtr,
style: Constant.body2_400(context: context),
decoration: InputDecoration(
suffixIcon: Icon(Icons.calendar_today),
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
),
labelText: "Tanggal Lahir" //label text of field
),
readOnly: true,
onTap: () async {
DateTime? pickedDate = await showDatePicker(
// locale: Locale("id"),
context: context,
initialDate: dobState.value,
firstDate: DateTime(1800),
initialEntryMode: DatePickerEntryMode.calendarOnly,
//DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2100));
if (pickedDate != null) {
print(
pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000
String formattedDate =
DateFormat('dd-MM-yyyy').format(pickedDate);
print(
formattedDate); //formatted date output using intl package => 2021-03-16
dobCtr.text =
formattedDate; //set output date to TextField value.
dobState.value = pickedDate;
} else {}
},
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
Radio<String>(
value: "age",
groupValue: dobRb.value,
onChanged: (value) {
dobRb.value = value!;
},
),
SizedBox(width: Constant.getActualX(context: context, x: 20)),
Stack(
clipBehavior: Clip.none,
// alignment: AlignmentDirectional.bottomCenter,
children: [
Container(
padding: EdgeInsets.symmetric(
horizontal:
Constant.getActualX(context: context, x: 16),
vertical: Constant.getActualY(context: context, y: 12)),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey)),
child: Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 90),
height: Constant.getActualY(context: context, y: 40),
child: CustomTextField(
onChange: (value) {
if (dobRb.value == "age") {
DateTime coba = Jiffy.now()
.subtract(
months: int.parse(monthCtr.text),
years: int.parse(yearCtr.text),
days: int.parse(dayCtr.text))
.dateTime;
// print(coba);
dobState.value = coba;
dobCtr.text = DateFormat('dd-MM-yyyy')
.format(dobState.value);
}
},
disable: dobRb.value != "date",
hintText: 'Tahun',
labelText: "",
isDense: true,
suffixIcon: SizedBox(
child: Container(
padding: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 8),
bottom: Constant.getActualY(
context: context, y: 8),
right: Constant.getActualX(
context: context, x: 5),
),
child: Text(
'Tahun',
style: Constant.body3_400(context: context)
.copyWith(color: Colors.grey),
),
),
),
style: Constant.body3_400(context: context),
hintStyle: Constant.body3_400(context: context),
labelStyle: Constant.body3_400(context: context),
controller: yearCtr,
inputType: TextInputType.number,
),
),
SizedBox(
width:
Constant.getActualX(context: context, x: 16)),
SizedBox(
width: Constant.getActualX(context: context, x: 90),
height: Constant.getActualY(context: context, y: 40),
child: CustomTextField(
onChange: (value) {
if (dobRb.value == "age") {
DateTime currentDate = DateTime.now();
DateTime coba = Jiffy.now()
.subtract(
months: int.parse(monthCtr.text),
years: int.parse(yearCtr.text),
days: int.parse(dayCtr.text))
.dateTime;
// print(coba);
dobState.value = coba;
dobCtr.text = DateFormat('dd-MM-yyyy')
.format(dobState.value);
}
},
disable: dobRb.value != "date",
hintText: 'Bulan',
labelText: "",
controller: monthCtr,
inputType: TextInputType.number,
isDense: true,
suffixIcon: Container(
child: Container(
padding: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 8),
bottom: Constant.getActualY(
context: context, y: 8),
right: Constant.getActualX(
context: context, x: 5),
),
child: Text(
'Bulan',
style: Constant.body3_400(context: context)
.copyWith(color: Colors.grey),
),
),
),
style: Constant.body3_400(context: context),
hintStyle: Constant.body3_400(context: context),
labelStyle: Constant.body3_400(context: context),
),
),
SizedBox(
width:
Constant.getActualX(context: context, x: 16)),
SizedBox(
width: Constant.getActualX(context: context, x: 90),
height: Constant.getActualY(context: context, y: 40),
child: CustomTextField(
disable: dobRb.value != "date",
onChange: (value) {
if (dobRb.value == "age") {
if (int.parse(dayCtr.text) <= 31) {
DateTime currentDate = DateTime.now();
DateTime coba = Jiffy.now()
.subtract(
months: int.parse(monthCtr.text),
years: int.parse(yearCtr.text),
days: int.parse(dayCtr.text))
.dateTime;
// print(coba);
dobState.value = coba;
dobCtr.text = DateFormat('dd-MM-yyyy')
.format(dobState.value);
} else {
dayCtr.text = "31";
SanckbarWidget(
context,
"hari tidak lebih dari 31",
snackbarType.warning);
}
}
},
hintText: 'Hari',
labelText: "",
controller: dayCtr,
inputType: TextInputType.number,
isDense: true,
suffixIcon: Container(
child: Container(
padding: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 8),
bottom: Constant.getActualY(
context: context, y: 8),
right: Constant.getActualX(
context: context, x: 5),
),
child: Text(
'Hari',
style: Constant.body3_400(context: context)
.copyWith(color: Colors.grey),
),
),
),
style: Constant.body3_400(context: context),
hintStyle: Constant.body3_400(context: context),
labelStyle: Constant.body3_400(context: context),
),
),
],
),
),
Positioned(
top: -8,
left: 10,
child: Container(
color: Colors.white,
child: const Text(
"Umur",
style: TextStyle(color: Colors.grey),
)))
],
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 300),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
disable: false,
hintText: 'No RM',
labelText: "No RM",
controller: noRmCtr,
),
)
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 240),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
disable: false,
inputType: TextInputType.number,
controller: nikCtr,
hintText: withoutNIK.value
? "Pasien Tanpa NIK Data Historis Tidak Terkonsolidasi"
: 'NIK',
labelText: withoutNIK.value
? "Pasien Tanpa NIK Data Historis Tidak Terkonsolidasi"
: "NIK"),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 20)),
Center(
child: Transform.scale(
scale: 0.8,
child: Checkbox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4)),
value: withoutNIK.value,
onChanged: (value) {
withoutNIK.value = value!;
if (value == true) {}
}),
),
),
Text('Tanpa NIK',
style: Constant.body2_400(context: context)
.copyWith(color: Constant.textBlack)),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 24),
),
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 304),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
DropdownMenu<CustomDropDownModel>(
enabled: false,
key: ValueKey(genderKey.value),
initialSelection: selectedGender.value,
trailingIcon: getFilterLoading.value
? LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)
: null,
width: Constant.getActualX(context: context, x: 304),
hintText: "Jenis Kelamin",
textStyle: Constant.body2_400(context: context),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
)),
label: const Text("jenis Kelamin"),
onSelected: (value) {
onSelectGender(value!);
selectedGender.value = value;
},
dropdownMenuEntries: gender.value
.map<DropdownMenuEntry<CustomDropDownModel>>(
(e) => DropdownMenuEntry(
value: e, label: e.name ?? ""))
.toList()),
],
)),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
disable: false,
hintText: 'No Hp',
labelText: "No Hp",
controller: hpCtr,
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
child: CustomTextField(
disable: false,
hintText: "NIP",
labelText: "NIP",
controller: nipCtr,
),
),
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 304),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
disable: false,
hintText: 'Jabatan',
labelText: "Jabatan",
controller: jabatanCtr,
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
disable: false,
hintText: 'Kedudukan',
labelText: "Kedudukan",
controller: kedudukanCtr,
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
disable: false,
hintText: 'Lokasi',
labelText: "Lokasi",
controller: lokasiCtr,
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
disable: false,
hintText: 'Pekerjaan',
labelText: "Pekerjaan",
controller: pekerjaanCtr,
),
],
),
)
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 1032),
// height: Constant.getActualY(context: context, y: 120),
child: CustomTextField(
disable: false,
controller: addressCtr,
hintText: 'Alamat',
labelText: "Alamat",
maxLines: 4,
minLines: 1),
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 1032),
// height: Constant.getActualY(context: context, y: 120),
child: CustomTextField(
controller: diagnosisCtr,
hintText: 'Diagnosis',
labelText: "Diagnosis",
maxLines: 4,
minLines: 1),
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 1032),
// height: Constant.getActualY(context: context, y: 120),
child: CustomTextField(
controller: noteCtr,
hintText: 'Catatan FO',
labelText: "Catatan FO",
maxLines: 4,
minLines: 1),
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
SizedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
OutlinedButton(
style: OutlinedButton.styleFrom(
backgroundColor: Colors.white,
side: BorderSide(color: Colors.grey.shade400, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: () {
ref.read(EditDataProvider.notifier).state =
RegistrationModel();
ref.read(selectedTestEditProvider.notifier).state =
List.empty(growable: true);
ref.read(currentPacketProvider.notifier).state =
List.empty(growable: true);
ref.read(selectedPacketEditProvider.notifier).state =
List.empty();
Navigator.pop(context);
},
child: SizedBox(
height: Constant.getActualY(context: context, y: 56),
child: Center(
child: Text('Batal',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack)),
),
)),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Constant.green,
side: BorderSide(color: Constant.green, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
onPressed: () {
nextStep();
},
child: SizedBox(
height: Constant.getActualY(context: context, y: 56),
child: Center(
child: Text('Berikutnya',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textWhite)),
),
)),
],
),
)
],
),
);
}
}

View File

@@ -0,0 +1,214 @@
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:intl/intl.dart';
import '../../app/constant.dart';
import '../../provider/auth_provider.dart';
import '../../widgets/custom_dialog_builder.dart';
class OrderFilter extends HookConsumerWidget {
const OrderFilter({
super.key,
required this.startDateCtr,
required this.startDateState,
required this.endDateCtr,
required this.endDateState,
required this.keywordCtr,
});
final TextEditingController startDateCtr;
final ValueNotifier<DateTime> startDateState;
final TextEditingController endDateCtr;
final ValueNotifier<DateTime> endDateState;
final TextEditingController keywordCtr;
@override
Widget build(BuildContext context, WidgetRef ref) {
final auth = ref.watch(authProvider);
final username = auth?.mUserUsername ?? "-";
showDialogBuilder() {
var endDateParam =
DateFormat('yyyy-MM-dd').format(endDateState.value).toString();
var startDateParam =
DateFormat('yyyy-MM-dd').format(startDateState.value).toString();
var companyID = auth?.mUserMCompanyID ?? "";
print("endDateParam : $endDateParam");
print("startDateParam : $startDateParam");
CustomDialogBuilder.dialogBuilderWebPDF(
context,
// startDateCtr.text.toString(),
// endDateCtr.text.toString(),
startDateParam,
endDateParam,
keywordCtr.text.toString(),
username,
companyID);
// launchUrlString("http://10.9.8.249/birt/run?__report=report/one/rekap/rpt_sales_001.rptdesign&__format=xls&PStartDate=2023-01-01&PEndDate=2023-01-31&username=adminsas&tm=1681262919125");
}
return Padding(
padding: const EdgeInsets.all(0),
child: Row(
children: [
Expanded(
flex: 3,
child: TextField(
style: Constant.body1_600(context: context),
controller: startDateCtr,
decoration: InputDecoration(
suffixIcon: Icon(EvaIcons.calendar),
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
),
labelStyle: Constant.body1_600(context: context),
labelText: "Tanggal Awal" //label text of field
),
readOnly: true,
onTap: () async {
DateTime? pickedDate = await showDatePicker(
// locale: Locale("id"),
confirmText: "OK",
cancelText: "Batal",
context: context,
initialDate: startDateState.value,
firstDate: DateTime(1800),
initialEntryMode: DatePickerEntryMode.calendarOnly,
//DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2100));
if (pickedDate != null) {
print(
pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000
String formattedDate =
DateFormat('dd-MM-yyyy').format(pickedDate);
print(
formattedDate); //formatted date output using intl package => 2021-03-16
startDateCtr.text =
formattedDate; //set output date to TextField value.
startDateState.value = pickedDate;
} else {}
},
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
Expanded(
flex: 3,
child: TextField(
style: Constant.body1_600(context: context),
controller: endDateCtr,
decoration: InputDecoration(
suffixIcon: Icon(EvaIcons.calendar),
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
),
labelStyle: Constant.body1_600(context: context),
labelText: "Tanggal Akhir" //label text of field
),
readOnly: true,
onTap: () async {
DateTime? pickedDate = await showDatePicker(
// locale: Locale("id"),
confirmText: "OK",
cancelText: "Batal",
context: context,
initialDate: endDateState.value,
firstDate: DateTime(1800),
initialEntryMode: DatePickerEntryMode.calendarOnly,
//DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2100));
if (pickedDate != null) {
print(
pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000
String formattedDate =
DateFormat('dd-MM-yyyy').format(pickedDate);
print(
formattedDate); //formatted date output using intl package => 2021-03-16
endDateCtr.text =
formattedDate; //set output date to TextField value.
endDateState.value = pickedDate;
} else {}
},
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
Expanded(
flex: 6,
child: TextField(
style: Constant.body1_600(context: context),
controller: keywordCtr,
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
),
hintText: "No Reg / Nama",
hintStyle: Constant.body1_600(context: context),
labelStyle: Constant.body1_600(context: context),
labelText: "No Reg / Nama" //label text of field
)),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
// button report pdf
Expanded(
flex: 1,
child: SizedBox(
width: Constant.getActualX(
context: context,
x: 171,
),
height: Constant.getActualY(context: context, y: 56),
child: ElevatedButton(
onPressed: () {
showDialogBuilder();
},
style: ButtonStyle(
backgroundColor: WidgetStateColor.resolveWith(
(st) => Constant.primaryRed,
),
shape: WidgetStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: Colors.transparent,
),
),
),
// shadowColor: MaterialStateProperty.all(
// Color(0xffff48423d)),
elevation: WidgetStateProperty.all(1.0),
),
// child: Align(
// alignment: Alignment.center,
// child: Text(
// 'Cetak',
// style: Constant.body3_600(context: context).copyWith(
// color: Constant.textWhite,
// ),
// ),
// ),
child: Icon(
color: Colors.white,
EvaIcons.printerOutline,
),
),
),
),
],
),
);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,79 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/search_order_model.dart';
import 'package:mitra_corporate/repository/order_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class SearchOrderState extends Equatable {
final DateTime date;
const SearchOrderState(this.date);
@override
List<Object?> get props => [date];
}
class SearchOrderStateInit extends SearchOrderState {
SearchOrderStateInit() : super(DateTime.now());
}
class SearchOrderStateLoading extends SearchOrderState {
SearchOrderStateLoading() : super(DateTime.now());
}
class SearchOrderStateError extends SearchOrderState {
final String message;
SearchOrderStateError({
required this.message,
}) : super(DateTime.now());
}
class SearchOrderStateDone extends SearchOrderState {
final SearchOrderModel model;
SearchOrderStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class SearchOrderNotifier extends StateNotifier<SearchOrderState> {
final Ref ref;
SearchOrderNotifier({
required this.ref,
}) : super(SearchOrderStateInit());
void getData({
required String token,
required String companyID,
required String rpp,
required String keyword,
required String page,
required String startDate,
required String endDate,
}) async {
try {
state = SearchOrderStateLoading();
final dio = ref.read(dioProvider);
final resp = await OrderRepository(dio: dio).searchOrder(
endDate: endDate,
startDate: startDate,
token: token,
companyID: companyID,
rpp: rpp,
keyword: keyword,
page: page);
state = SearchOrderStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = SearchOrderStateError(message: e.message.toString());
} else {
state = SearchOrderStateError(message: e.toString());
}
}
}
}
//provider
final SearchOrderProvider =
StateNotifierProvider<SearchOrderNotifier, SearchOrderState>(
(ref) => SearchOrderNotifier(ref: ref));

View File

@@ -0,0 +1,65 @@
import 'package:mitra_corporate/repository/patient_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 DeletePatientProviderState extends Equatable {
final DateTime date;
const DeletePatientProviderState(this.date);
@override
List<Object?> get props => [date];
}
class DeletePatientProviderStateInit extends DeletePatientProviderState {
DeletePatientProviderStateInit() : super(DateTime.now());
}
class DeletePatientProviderStateLoading extends DeletePatientProviderState {
DeletePatientProviderStateLoading() : super(DateTime.now());
}
class DeletePatientProviderStateError extends DeletePatientProviderState {
final String message;
DeletePatientProviderStateError({
required this.message,
}) : super(DateTime.now());
}
class DeletePatientProviderStateDone extends DeletePatientProviderState {
final String msg;
DeletePatientProviderStateDone({
required this.msg,
}) : super(DateTime.now());
}
//notifier
class DeletePatientProviderNotifier
extends StateNotifier<DeletePatientProviderState> {
final Ref ref;
DeletePatientProviderNotifier({
required this.ref,
}) : super(DeletePatientProviderStateInit());
void DeletePatent({required String patient_id, required String token}) async {
try {
state = DeletePatientProviderStateLoading();
final dio = ref.read(dioProvider);
final resp = await PatientRepository(dio: dio)
.deletePatient(patient_id: patient_id, token: token);
state = DeletePatientProviderStateDone(msg: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = DeletePatientProviderStateError(message: e.message.toString());
} else {
state = DeletePatientProviderStateError(message: e.toString());
}
}
}
}
//provider
final DeletePatientProvider = StateNotifierProvider<
DeletePatientProviderNotifier, DeletePatientProviderState>(
(ref) => DeletePatientProviderNotifier(ref: ref));

View File

@@ -0,0 +1,156 @@
import 'package:flutter/material.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
class DialogDeletePatient extends StatelessWidget {
const DialogDeletePatient(
{super.key,
required this.NIK,
required this.delete,
required this.patientID,
required this.loading,
required this.name});
final String name;
final String NIK;
final Function delete;
final String patientID;
final bool loading;
@override
Widget build(BuildContext context) {
return AlertDialog(
titlePadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 24)),
actionsPadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 24)),
contentPadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 24)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8))),
title: Text(
'Konfirmasi hapus',
style: Constant.h4_600(context: context),
),
content: Container(
constraints: BoxConstraints(
minHeight: Constant.getActualY(context: context, y: 100),
maxHeight: Constant.getActualY(context: context, y: 362),
),
height: Constant.getActualY(context: context, y: 240),
child: Column(
children: [
Text(
'Anda yakin menghapus pasien berikut ?',
style: Constant.body1_600(context: context),
),
SizedBox(
height: Constant.getActualY(context: context, y: 24),
),
SizedBox(
width: Constant.getActualX(context: context, x: 416),
child: Card(
elevation: 1,
shape: RoundedRectangleBorder(
side: BorderSide(color: Constant.grey_200),
borderRadius: BorderRadius.circular(12)),
child: Container(
padding: EdgeInsets.symmetric(
horizontal:
Constant.getActualX(context: context, x: 24),
vertical:
Constant.getActualY(context: context, y: 24)),
child: Column(
children: [
Row(
children: [
Expanded(
flex: 5,
child: Text(
"NIK",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
),
Expanded(
flex: 7,
child: Text(
NIK,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack),
),
)
],
),
SizedBox(
height:
Constant.getActualY(context: context, y: 12),
),
Row(
children: [
Expanded(
flex: 5,
child: Text(
"Nama",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
),
Expanded(
flex: 7,
child: Text(
name,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack),
),
)
],
),
],
)),
),
)
],
)),
actions: <Widget>[
OutlinedButton(
style: OutlinedButton.styleFrom(
surfaceTintColor: Constant.primaryBlue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: !loading ? () => Navigator.pop(context, 'Batal') : null,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: loading
? LoadingAnimationWidget.staggeredDotsWave(
color: Constant.primaryBlue, size: 20)
: Text('Batal',
style: Constant.button_medium(context: context)
.copyWith(color: Constant.textBlack)),
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: !loading ? () => delete(patientID) : null,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: loading
? LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white, size: 20)
: Text(
'Yakin',
style: Constant.button_medium(context: context),
),
),
),
],
);
}
}

View File

@@ -0,0 +1,951 @@
import 'dart:convert';
import 'package:mitra_corporate/provider/registrasi_provider.dart';
import 'package:mitra_corporate/screen/registrasi/edit_patient_provider.dart';
import 'package:age_calculator/age_calculator.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:jiffy/jiffy.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../model/registration_model.dart';
import '../../provider/auth_provider.dart';
import '../../widgets/custom_snackbar_widget.dart';
import '../../widgets/custom_text_field.dart';
import 'get_filter_provider.dart';
class DialogEditPatient extends HookConsumerWidget {
const DialogEditPatient({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final tempPatient = ref.watch(registrationEditPatientProvider);
final auth = ref.watch(authProvider);
//withoutnik apabila tanpa nik maka true
final withoutNIK = useState(false);
final getFilterLoading = useState(false);
final sapaanKey = useState(1);
final genderKey = useState(1000);
final prefixCtr = useTextEditingController(text: "");
final nameCtr = useTextEditingController(text: "");
final suffixCtr = useTextEditingController(text: "");
final nikCtr = useTextEditingController(text: "");
final nipCtr = useTextEditingController(text: "");
final hpCtr = useTextEditingController(text: "");
final noRmCtr = useTextEditingController(text: "");
final addressCtr = useTextEditingController(text: "");
final diagnosisCtr = useTextEditingController(text: "");
final noteCtr = useTextEditingController(text: "");
final jabatanCtr = useTextEditingController(text: "");
final kedudukanCtr = useTextEditingController(text: "");
final lokasiCtr = useTextEditingController(text: "");
final pekerjaanCtr = useTextEditingController(text: "");
final sapaan = useState<List<CustomDropDownModel>>(List.empty());
final selectedSaluation = useState(CustomDropDownModel());
final gender = useState<List<CustomDropDownModel>>(List.empty());
final selectedGender = useState(CustomDropDownModel());
final editLoading = useState(false);
//select salah satu sapaan
onSelectSaluation(CustomDropDownModel value) {
selectedSaluation.value = value;
selectedGender.value =
gender.value.firstWhere((element) => element.id == value.type);
genderKey.value = genderKey.value + 1;
// sapaanKey.value = sapaanKey.value + 1;
}
//update gender saat sapaan dipilih
selectedSaluation.addListener(() {
selectedGender.value = gender.value
.firstWhere((element) => element.id == selectedSaluation.value.type);
genderKey.value = genderKey.value + 1;
});
//select gender
onSelectGender(CustomDropDownModel value) {
selectedGender.value = value;
}
final dobRb = useState('date');
final dobCtr = useTextEditingController(
text: DateFormat('dd-MM-yyyy').format(DateTime.now()));
final dobState = useState(DateTime.now());
final yearCtr = useTextEditingController(text: "0");
final monthCtr = useTextEditingController(text: "0");
final dayCtr = useTextEditingController(text: "0");
//perhitungan umur dari tanggal ke angka
DateDuration calculateAge(DateTime birthDate) {
DateTime currentDate = DateTime.now();
var age = AgeCalculator.age(birthDate, today: currentDate);
return age;
}
dobState.addListener(
() {
// print(calculateAge(dobState.value));
if (dobRb.value == "date") {
var age = calculateAge(dobState.value);
yearCtr.text = age.years.toString();
monthCtr.text = age.months.toString();
dayCtr.text = age.days.toString();
}
},
);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
nameCtr.text = tempPatient.patientData?.name ?? "";
prefixCtr.text = tempPatient.patientData?.prefix ?? "";
suffixCtr.text = tempPatient.patientData?.suffix ?? "";
nikCtr.text = tempPatient.patientData?.nik ?? "";
nipCtr.text = tempPatient.patientData?.nip ?? "";
withoutNIK.value =
tempPatient.patientData?.withoutNIK == 'Y' ? true : false;
hpCtr.text = tempPatient.patientData?.hp ?? "";
addressCtr.text = tempPatient.patientData?.address ?? "";
diagnosisCtr.text = tempPatient.patientData?.diagnosis ?? "";
noteCtr.text = tempPatient.patientData?.note ?? "";
noRmCtr.text = tempPatient.patientData?.noRM ?? "";
jabatanCtr.text = tempPatient.patientData?.jabatan ?? "";
kedudukanCtr.text = tempPatient.patientData?.kedudukan ?? "";
lokasiCtr.text = tempPatient.patientData?.lokasi ?? "";
pekerjaanCtr.text = tempPatient.patientData?.pekerjaan ?? "";
// DateFormat('dd-MM-yyyy').format(DateTime.now())
dobCtr.text = DateFormat('dd-MM-yyyy').format(DateTime.parse(
tempPatient.patientData?.dob ?? DateTime.now().toString()));
dobState.value = DateTime.parse(
tempPatient.patientData?.dob ?? DateTime.now().toString());
ref
.read(GetFilterRegistrationProvider.notifier)
.getData(token: auth!.token ?? "");
});
return () {};
}, []);
ref.listen(
GetFilterRegistrationProvider,
(previous, next) {
if (next is GetFilterRegistrationStateInit) {
getFilterLoading.value = true;
} else if (next is GetFilterRegistrationStateLoading) {
getFilterLoading.value = true;
} else if (next is GetFilterRegistrationStateError) {
SanckbarWidget(context, next.message, snackbarType.error);
getFilterLoading.value = false;
Constant.autoLogout(context: context, msg: next.message);
} else if (next is GetFilterRegistrationStateDone) {
// print(jsonEncode(next.model));
sapaan.value = next.model.titles!;
gender.value = next.model.gender!;
// selectedGender.value = next.model.gender![0];
if (tempPatient.patientData?.saluation != null) {
var sp = next.model.titles!.firstWhere(
(element) => element.id == tempPatient.patientData?.saluation);
selectedSaluation.value = sp;
}
if (tempPatient.patientData?.gender != null) {
var gd = next.model.gender!.firstWhere(
(element) => element.id == tempPatient.patientData?.gender);
selectedGender.value = gd;
}
sapaanKey.value = sapaanKey.value + 1;
genderKey.value = genderKey.value + 1;
getFilterLoading.value = false;
}
},
);
saveEdit() {
if (withoutNIK.value == false) {
if (nikCtr.text.isEmpty) {
SanckbarWidget(context, "NIK Harus diisi", snackbarType.warning);
return;
}
if (nikCtr.text.length < 16 || nikCtr.text.length > 16) {
SanckbarWidget(
context, "NIK berjumlah 16 digit", snackbarType.warning);
return;
}
}
if (nameCtr.text.isEmpty ||
selectedGender.value.id == null ||
selectedSaluation.value.id == null ||
jabatanCtr.text.isEmpty ||
kedudukanCtr.text.isEmpty ||
lokasiCtr.text.isEmpty ||
pekerjaanCtr.text.isEmpty) {
// print(nameCtr.text);
// print(selectedGender.value.name);
SanckbarWidget(
context,
"Sapaan, Nama, Tanggal Lahir, Jenis Kelamin, jabatan, kedudukan, lokasi, dan pekerjaan Harus Diisi !",
snackbarType.warning);
} else {
PatientData data = PatientData(
noRM: noRmCtr.text,
saluation: selectedSaluation.value.id,
name: nameCtr.text,
prefix: prefixCtr.text,
suffix: suffixCtr.text,
dob: dobState.value.toString(),
nik: nikCtr.text,
nip: nipCtr.text,
withoutNIK: withoutNIK.value ? "Y" : "N",
gender: selectedGender.value.id.toString(),
address: addressCtr.text,
diagnosis: diagnosisCtr.text,
hp: hpCtr.text,
jabatan: jabatanCtr.text,
kedudukan: kedudukanCtr.text,
lokasi: lokasiCtr.text,
pekerjaan: pekerjaanCtr.text,
note: noteCtr.text);
ref.read(registrationEditPatientProvider.notifier).state =
RegistrationModel(
token: auth?.token ?? "",
patientId: tempPatient.patientId,
patientData: data,
);
print(jsonEncode(RegistrationModel(
token: auth?.token ?? "",
patientId: tempPatient.patientId,
patientData: data,
)));
ref.read(EditPatientProviderProvider.notifier).editPatent(
prm: RegistrationModel(
token: auth?.token ?? "",
patientId: tempPatient.patientId,
patientData: data,
));
}
}
ref.listen(
EditPatientProviderProvider,
(previous, next) {
if (next is EditPatientProviderStateInit) {
editLoading.value = true;
} else if (next is EditPatientProviderStateLoading) {
editLoading.value = true;
} else if (next is EditPatientProviderStateError) {
SanckbarWidget(context, next.message, snackbarType.error);
editLoading.value = false;
Constant.autoLogout(context: context, msg: next.message);
} else if (next is EditPatientProviderStateDone) {
SanckbarWidget(
context, "Berhasil Mengubah Data patient", snackbarType.success);
editLoading.value = false;
Navigator.pop(context, "done");
}
},
);
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 1032),
height: Constant.getActualY(context: context, y: 62),
child: Text('Edit Pasien',
style: Constant.h2_600(context: context)
.copyWith(color: Constant.textBlack)),
),
SizedBox(height: Constant.getActualY(context: context, y: 40)),
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 120),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
DropdownMenu<CustomDropDownModel>(
menuHeight:
Constant.getActualY(context: context, y: 300),
key: ValueKey(sapaanKey.value),
initialSelection: selectedSaluation.value,
trailingIcon: getFilterLoading.value
? LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)
: null,
width: Constant.getActualX(context: context, x: 120),
hintText: "Sapaan",
textStyle: Constant.body2_400(context: context),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
)),
label: const Text(
"Sapaan",
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
onSelected: (value) {
onSelectSaluation(value!);
selectedSaluation.value = value;
},
dropdownMenuEntries: sapaan.value
.map<DropdownMenuEntry<CustomDropDownModel>>(
(e) => DropdownMenuEntry(
value: e, label: e.name ?? ""))
.toList()),
],
)),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 160),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
hintText: 'Prefix',
labelText: "Prefix",
controller: prefixCtr,
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 520),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
hintText: 'Name',
labelText: "Nama",
controller: nameCtr,
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 160),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
hintText: 'Suffix',
labelText: "suffix",
controller: suffixCtr,
),
),
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Row(
children: [
Radio<String>(
value: "date",
groupValue: dobRb.value,
onChanged: (value) {
dobRb.value = value!;
},
),
SizedBox(width: Constant.getActualX(context: context, x: 20)),
SizedBox(
width: Constant.getActualX(context: context, x: 252),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
TextField(
enabled: dobRb.value != "age",
controller: dobCtr,
style: Constant.body2_400(context: context),
decoration: InputDecoration(
suffixIcon: Icon(Icons.calendar_today),
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
),
labelText: "Tanggal Lahir" //label text of field
),
readOnly: true,
onTap: () async {
DateTime? pickedDate = await showDatePicker(
// locale: Locale("id"),
context: context,
initialDate: dobState.value,
firstDate: DateTime(1800),
initialEntryMode: DatePickerEntryMode.calendarOnly,
//DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2100));
if (pickedDate != null) {
print(
pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000
String formattedDate =
DateFormat('dd-MM-yyyy').format(pickedDate);
print(
formattedDate); //formatted date output using intl package => 2021-03-16
dobCtr.text =
formattedDate; //set output date to TextField value.
dobState.value = pickedDate;
} else {}
},
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
Radio<String>(
value: "age",
groupValue: dobRb.value,
onChanged: (value) {
dobRb.value = value!;
},
),
SizedBox(width: Constant.getActualX(context: context, x: 20)),
Stack(
clipBehavior: Clip.none,
// alignment: AlignmentDirectional.bottomCenter,
children: [
Container(
padding: EdgeInsets.symmetric(
horizontal:
Constant.getActualX(context: context, x: 16),
vertical: Constant.getActualY(context: context, y: 12)),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey)),
child: Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 90),
height: Constant.getActualY(context: context, y: 40),
child: CustomTextField(
onChange: (value) {
if (dobRb.value == "age") {
DateTime coba = Jiffy.now()
.subtract(
months: int.parse(monthCtr.text),
years: int.parse(yearCtr.text),
days: int.parse(dayCtr.text))
.dateTime;
// print(coba);
dobState.value = coba;
dobCtr.text = DateFormat('dd-MM-yyyy')
.format(dobState.value);
}
},
disable: dobRb.value != "date",
hintText: 'Tahun',
labelText: "",
isDense: true,
suffixIcon: SizedBox(
child: Container(
padding: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 8),
bottom: Constant.getActualY(
context: context, y: 8),
right: Constant.getActualX(
context: context, x: 5),
),
child: Text(
'Tahun',
style: Constant.body3_400(context: context)
.copyWith(color: Colors.grey),
),
),
),
style: Constant.body3_400(context: context),
hintStyle: Constant.body3_400(context: context),
labelStyle: Constant.body3_400(context: context),
controller: yearCtr,
inputType: TextInputType.number,
),
),
SizedBox(
width:
Constant.getActualX(context: context, x: 16)),
SizedBox(
width: Constant.getActualX(context: context, x: 90),
height: Constant.getActualY(context: context, y: 40),
child: CustomTextField(
onChange: (value) {
if (dobRb.value == "age") {
DateTime currentDate = DateTime.now();
DateTime coba = Jiffy.now()
.subtract(
months: int.parse(monthCtr.text),
years: int.parse(yearCtr.text),
days: int.parse(dayCtr.text))
.dateTime;
// print(coba);
dobState.value = coba;
dobCtr.text = DateFormat('dd-MM-yyyy')
.format(dobState.value);
}
},
disable: dobRb.value != "date",
hintText: 'Bulan',
labelText: "",
controller: monthCtr,
inputType: TextInputType.number,
isDense: true,
suffixIcon: Container(
child: Container(
padding: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 8),
bottom: Constant.getActualY(
context: context, y: 8),
right: Constant.getActualX(
context: context, x: 5),
),
child: Text(
'Bulan',
style: Constant.body3_400(context: context)
.copyWith(color: Colors.grey),
),
),
),
style: Constant.body3_400(context: context),
hintStyle: Constant.body3_400(context: context),
labelStyle: Constant.body3_400(context: context),
),
),
SizedBox(
width:
Constant.getActualX(context: context, x: 16)),
SizedBox(
width: Constant.getActualX(context: context, x: 90),
height: Constant.getActualY(context: context, y: 40),
child: CustomTextField(
disable: dobRb.value != "date",
onChange: (value) {
if (dobRb.value == "age") {
if (int.parse(dayCtr.text) <= 31) {
DateTime currentDate = DateTime.now();
DateTime coba = Jiffy.now()
.subtract(
months: int.parse(monthCtr.text),
years: int.parse(yearCtr.text),
days: int.parse(dayCtr.text))
.dateTime;
// print(coba);
dobState.value = coba;
dobCtr.text = DateFormat('dd-MM-yyyy')
.format(dobState.value);
} else {
dayCtr.text = "31";
SanckbarWidget(
context,
"hari tidak lebih dari 31",
snackbarType.warning);
}
}
},
hintText: 'Hari',
labelText: "",
controller: dayCtr,
inputType: TextInputType.number,
isDense: true,
suffixIcon: Container(
child: Container(
padding: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 8),
bottom: Constant.getActualY(
context: context, y: 8),
right: Constant.getActualX(
context: context, x: 5),
),
child: Text(
'Hari',
style: Constant.body3_400(context: context)
.copyWith(color: Colors.grey),
),
),
),
style: Constant.body3_400(context: context),
hintStyle: Constant.body3_400(context: context),
labelStyle: Constant.body3_400(context: context),
),
),
],
),
),
Positioned(
top: -8,
left: 10,
child: Container(
color: Colors.white,
child: const Text(
"Umur",
style: TextStyle(color: Colors.grey),
)))
],
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 300),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
hintText: 'No RM',
labelText: "No RM",
controller: noRmCtr,
),
)
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 240),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
inputType: TextInputType.number,
controller: nikCtr,
hintText: withoutNIK.value
? "Pasien Tanpa NIK Data Historis Tidak Terkonsolidasi"
: 'NIK',
labelText: withoutNIK.value
? "Pasien Tanpa NIK Data Historis Tidak Terkonsolidasi"
: "NIK"),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 20)),
Center(
child: Transform.scale(
scale: 0.8,
child: Checkbox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4)),
value: withoutNIK.value,
onChanged: (value) {
withoutNIK.value = value!;
if (value == true) {}
}),
),
),
Text('Tanpa NIK',
style: Constant.body2_400(context: context)
.copyWith(color: Constant.textBlack)),
// SizedBox(width: Constant.getActualX(context: context, x: 24)),
// SizedBox(
// width: Constant.getActualX(context: context, x: 250),
// child: DropdownMenu<CustomDropDownModel>(
// key: ValueKey(genderKey.value),
// initialSelection: selectedGender.value,
// trailingIcon: getFilterLoading.value
// ? LoadingAnimationWidget.discreteCircle(
// color: Constant.primaryBlue, size: 20)
// : null,
// width: Constant.getActualX(context: context, x: 250),
// hintText: "Jenis Kelamin",
// textStyle: Constant.body2_400(context: context),
// inputDecorationTheme: InputDecorationTheme(
// border: OutlineInputBorder(
// borderSide: BorderSide(color: Constant.primaryBlue),
// borderRadius: BorderRadius.circular(8),
// )),
// label: const Text("jenis Kelamin"),
// onSelected: (value) {
// onSelectGender(value!);
// selectedGender.value = value;
// },
// dropdownMenuEntries: gender.value
// .map<DropdownMenuEntry<CustomDropDownModel>>((e) =>
// DropdownMenuEntry(value: e, label: e.name ?? ""))
// .toList())),
// SizedBox(width: Constant.getActualX(context: context, x: 24)),
// SizedBox(
// width: Constant.getActualX(context: context, x: 365),
// // height: Constant.getActualY(context: context, y: 56),
// child: CustomTextField(
// hintText: 'No Hp',
// labelText: "No Hp",
// controller: hpCtr,
// ),
// ),
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 304),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
DropdownMenu<CustomDropDownModel>(
key: ValueKey(genderKey.value),
initialSelection: selectedGender.value,
trailingIcon: getFilterLoading.value
? LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)
: null,
width: Constant.getActualX(context: context, x: 304),
hintText: "Jenis Kelamin",
textStyle: Constant.body2_400(context: context),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
)),
label: const Text("jenis Kelamin"),
onSelected: (value) {
onSelectGender(value!);
selectedGender.value = value;
},
dropdownMenuEntries: gender.value
.map<DropdownMenuEntry<CustomDropDownModel>>(
(e) => DropdownMenuEntry(
value: e, label: e.name ?? ""))
.toList()),
],
)),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
inputType: TextInputType.number,
hintText: 'No Hp',
labelText: "No Hp",
controller: hpCtr,
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
child: CustomTextField(
hintText: "NIP",
labelText: "NIP",
controller: nipCtr,
),
),
],
),
// SizedBox(height: Constant.getActualY(context: context, y: 24)),
// Row(
// children: [],
// ),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 304),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
hintText: 'Jabatan',
labelText: "Jabatan",
controller: jabatanCtr,
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
hintText: 'Kedudukan',
labelText: "Kedudukan",
controller: kedudukanCtr,
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
hintText: 'Lokasi',
labelText: "Lokasi",
controller: lokasiCtr,
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
hintText: 'Pekerjaan',
labelText: "Pekerjaan",
controller: pekerjaanCtr,
),
],
),
)
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 1032),
// height: Constant.getActualY(context: context, y: 120),
child: CustomTextField(
controller: addressCtr,
hintText: 'Alamat',
labelText: "Alamat",
maxLines: 4,
minLines: 1),
),
SizedBox(height: Constant.getActualY(context: context, y: 30)),
SizedBox(
width: Constant.getActualX(context: context, x: 1032),
// height: Constant.getActualY(context: context, y: 120),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
OutlinedButton(
style: OutlinedButton.styleFrom(
backgroundColor: Colors.white,
side: BorderSide(color: Colors.grey.shade400, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: !editLoading.value
? () {
ref
.read(registrationEditPatientProvider.notifier)
.state = RegistrationModel();
Navigator.pop(context);
}
: null,
child: SizedBox(
height: Constant.getActualY(context: context, y: 56),
child: Center(
child: Text('Batal',
style: Constant.button_medium(context: context)
.copyWith(color: Constant.textBlack)),
),
)),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Constant.green,
side: BorderSide(color: Constant.green, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
onPressed: !editLoading.value
? () {
saveEdit();
}
: null,
child: SizedBox(
height: Constant.getActualY(context: context, y: 56),
child: Center(
child: editLoading.value
? LoadingAnimationWidget.discreteCircle(
color: Constant.primaryRed, size: 20)
: Text('Simpan',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textWhite)),
),
)),
],
),
),
],
),
);
}
}

View File

@@ -0,0 +1,141 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/app/constant.dart';
import 'package:mitra_corporate/screen/registrasi/form_data_pasien.dart';
import 'package:mitra_corporate/screen/registrasi/form_detail_order.dart';
import 'package:mitra_corporate/screen/registrasi/form_pemeriksaan.dart';
import 'package:mitra_corporate/screen/registrasi/registrasi_sukses.dart';
import 'package:mitra_corporate/widgets/stepper_registrasi.dart';
import '../../provider/registrasi_provider.dart';
class DialogPendaftaranPasien extends HookConsumerWidget {
const DialogPendaftaranPasien({super.key});
// const DialogDataPasien({
// Key? key,
// }) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
final bacaRegistrasiProvider = ref.watch(registrasiProvider);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: SimpleDialog(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12))),
contentPadding: const EdgeInsets.all(40.0),
children: [
Column(children: [
(bacaRegistrasiProvider == 3)
? Text('')
: SizedBox(
width: Constant.getActualX(context: context, x: 1080),
height: Constant.getActualY(context: context, y: 62),
child: Text('Pendaftaran Pasien Baru',
style: Constant.h2_600(context: context)
.copyWith(color: Constant.textBlack)),
),
SizedBox(height: Constant.getActualY(context: context, y: 40)),
//Stepper
(bacaRegistrasiProvider == 3)
? Text('')
: SizedBox(
width: Constant.getActualX(context: context, x: 1080),
height: Constant.getActualY(context: context, y: 100),
child: StepperRegistrasi()),
SizedBox(
height: Constant.getActualY(context: context, y: 40),
),
// membaca perubahan value dari registrasi_provider.dart
(bacaRegistrasiProvider == 0)
? FormDataPasien()
: (bacaRegistrasiProvider == 1)
? FormPemeriksaan()
: (bacaRegistrasiProvider == 2)
? DetailOrder()
: (bacaRegistrasiProvider == 3)
? RegistrasiSukses()
: Text('Tidak ada view'),
// if(bacaRegistrasiProvider == 1){
// FormDataPasien()
// } else{
// if(bacaRegistrasiProvider == 2){
// Text('2')
// }else{
// Text('3')
// }
// }
//
// SizedBox(height: Constant.getActualY(context: context, y: 24)),
// Container(
// // height: Constant.getActualY(context: context, y: 100),
// // color: Colors.red,
// padding: const EdgeInsets.only(left: 32, right: 32),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.end,
// children: [
// (bacaRegistrasiProvider == 4)
// ? Text('')
// : OutlinedButton(
// style: OutlinedButton.styleFrom(
// backgroundColor: Colors.white,
// side: BorderSide(
// color: Constant.primaryBlue, width: 2),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(8))),
// onPressed: () {
// ref
// .read(registrasiProvider.state)
// .update((state) => state - 1);
// },
// child: SizedBox(
// height: Constant.getActualY(context: context, y: 56),
// child: Center(
// child: Text('Batal',
// style: Constant.body3_600(context: context)
// .copyWith(color: Constant.textBlue)),
// ),
// )),
// SizedBox(width: Constant.getActualX(context: context, x: 24)),
// (bacaRegistrasiProvider == 4)
// ? Text('')
// : ElevatedButton(
// style: ElevatedButton.styleFrom(
// backgroundColor: Constant.primaryBlue,
// side:
// BorderSide(color: Constant.primaryBlue, width: 2),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(8),
// ),
// ),
// // onPressed: () {
// // showDialog(
// // context: context,
// // builder: ((context) => DialogPemeriksaan()));
// // },
// onPressed: () {
// ref
// .read(registrasiProvider.state)
// .update((state) => state + 1);
// },
// child: SizedBox(
// height: Constant.getActualY(context: context, y: 56),
// child: Center(
// child: Text('Simpan Perubahan',
// style: Constant.body3_600(context: context)
// .copyWith(color: Constant.textWhite)),
// ),
// )),
// ],
// ),
// )
])
]),
);
}
}

View File

@@ -0,0 +1,65 @@
import 'package:mitra_corporate/repository/patient_repository.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/registration_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class EditPatientProviderState extends Equatable {
final DateTime date;
const EditPatientProviderState(this.date);
@override
List<Object?> get props => [date];
}
class EditPatientProviderStateInit extends EditPatientProviderState {
EditPatientProviderStateInit() : super(DateTime.now());
}
class EditPatientProviderStateLoading extends EditPatientProviderState {
EditPatientProviderStateLoading() : super(DateTime.now());
}
class EditPatientProviderStateError extends EditPatientProviderState {
final String message;
EditPatientProviderStateError({
required this.message,
}) : super(DateTime.now());
}
class EditPatientProviderStateDone extends EditPatientProviderState {
final String msg;
EditPatientProviderStateDone({
required this.msg,
}) : super(DateTime.now());
}
//notifier
class EditPatientProviderNotifier
extends StateNotifier<EditPatientProviderState> {
final Ref ref;
EditPatientProviderNotifier({
required this.ref,
}) : super(EditPatientProviderStateInit());
void editPatent({required RegistrationModel prm}) async {
try {
state = EditPatientProviderStateLoading();
final dio = ref.read(dioProvider);
final resp = await PatientRepository(dio: dio).editPatient(prm: prm);
state = EditPatientProviderStateDone(msg: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = EditPatientProviderStateError(message: e.message.toString());
} else {
state = EditPatientProviderStateError(message: e.toString());
}
}
}
}
//provider
final EditPatientProviderProvider = StateNotifierProvider<
EditPatientProviderNotifier,
EditPatientProviderState>((ref) => EditPatientProviderNotifier(ref: ref));

View File

@@ -0,0 +1,931 @@
import 'package:age_calculator/age_calculator.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:jiffy/jiffy.dart';
import 'package:mitra_corporate/app/constant.dart';
import 'package:mitra_corporate/model/registration_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/screen/registrasi/get_filter_provider.dart';
import 'package:mitra_corporate/widgets/custom_snackbar_widget.dart';
import 'package:mitra_corporate/widgets/custom_text_field.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../provider/registrasi_provider.dart';
class FormDataPasien extends HookConsumerWidget {
const FormDataPasien({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final tempPatient = ref.watch(registrationDataProvider);
final auth = ref.watch(authProvider);
//withoutnik apabila tanpa nik maka true
final withoutNIK = useState(false);
final getFilterLoading = useState(false);
final sapaanKey = useState(1);
final genderKey = useState(1000);
final prefixCtr = useTextEditingController(text: "");
final nameCtr = useTextEditingController(text: "");
final suffixCtr = useTextEditingController(text: "");
final nikCtr = useTextEditingController(text: "");
final nipCtr = useTextEditingController(text: "");
final hpCtr = useTextEditingController(text: "");
final noRmCtr = useTextEditingController(text: "");
final addressCtr = useTextEditingController(text: "");
final diagnosisCtr = useTextEditingController(text: "");
final noteCtr = useTextEditingController(text: "");
final jabatanCtr = useTextEditingController(text: "");
final kedudukanCtr = useTextEditingController(text: "");
final lokasiCtr = useTextEditingController(text: "");
final pekerjaanCtr = useTextEditingController(text: "");
final sapaan = useState<List<CustomDropDownModel>>(List.empty());
final selectedSaluation = useState(CustomDropDownModel());
final gender = useState<List<CustomDropDownModel>>(List.empty());
final selectedGender = useState(CustomDropDownModel());
//select salah satu sapaan
onSelectSaluation(CustomDropDownModel value) {
selectedSaluation.value = value;
selectedGender.value =
gender.value.firstWhere((element) => element.id == value.type);
genderKey.value = genderKey.value + 1;
// sapaanKey.value = sapaanKey.value + 1;
}
//update gender saat sapaan dipilih
selectedSaluation.addListener(() {
selectedGender.value = gender.value
.firstWhere((element) => element.id == selectedSaluation.value.type);
genderKey.value = genderKey.value + 1;
});
//select gender
onSelectGender(CustomDropDownModel value) {
selectedGender.value = value;
}
final dobRb = useState('date');
final dobCtr = useTextEditingController(
text: DateFormat('dd-MM-yyyy').format(DateTime.now()));
final dobState = useState(DateTime.now());
final yearCtr = useTextEditingController(text: "0");
final monthCtr = useTextEditingController(text: "0");
final dayCtr = useTextEditingController(text: "0");
//perhitungan umur dari tanggal ke angka
DateDuration calculateAge(DateTime birthDate) {
DateTime currentDate = DateTime.now();
var age = AgeCalculator.age(birthDate, today: currentDate);
return age;
}
dobState.addListener(
() {
// print(calculateAge(dobState.value));
if (dobRb.value == "date") {
var age = calculateAge(dobState.value);
yearCtr.text = age.years.toString();
monthCtr.text = age.months.toString();
dayCtr.text = age.days.toString();
}
},
);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
nameCtr.text = tempPatient.patientData?.name ?? "";
prefixCtr.text = tempPatient.patientData?.prefix ?? "";
suffixCtr.text = tempPatient.patientData?.suffix ?? "";
nikCtr.text = tempPatient.patientData?.nik ?? "";
nipCtr.text = tempPatient.patientData?.nip ?? "";
withoutNIK.value =
tempPatient.patientData?.withoutNIK == 'Y' ? true : false;
hpCtr.text = tempPatient.patientData?.hp ?? "";
addressCtr.text = tempPatient.patientData?.address ?? "";
diagnosisCtr.text = tempPatient.patientData?.diagnosis ?? "";
noteCtr.text = tempPatient.patientData?.note ?? "";
noRmCtr.text = tempPatient.patientData?.noRM ?? "";
jabatanCtr.text = tempPatient.patientData?.jabatan ?? "";
kedudukanCtr.text = tempPatient.patientData?.kedudukan ?? "";
lokasiCtr.text = tempPatient.patientData?.lokasi ?? "";
pekerjaanCtr.text = tempPatient.patientData?.pekerjaan ?? "";
// DateFormat('dd-MM-yyyy').format(DateTime.now())
dobCtr.text = DateFormat('dd-MM-yyyy').format(DateTime.parse(
tempPatient.patientData?.dob ?? DateTime.now().toString()));
dobState.value = DateTime.parse(
tempPatient.patientData?.dob ?? DateTime.now().toString());
ref
.read(GetFilterRegistrationProvider.notifier)
.getData(token: auth!.token ?? "");
});
return () {};
}, []);
ref.listen(
GetFilterRegistrationProvider,
(previous, next) {
if (next is GetFilterRegistrationStateInit) {
getFilterLoading.value = true;
} else if (next is GetFilterRegistrationStateLoading) {
getFilterLoading.value = true;
} else if (next is GetFilterRegistrationStateError) {
SanckbarWidget(context, next.message, snackbarType.error);
getFilterLoading.value = false;
Constant.autoLogout(context: context, msg: next.message);
} else if (next is GetFilterRegistrationStateDone) {
// print(jsonEncode(next.model));
sapaan.value = next.model.titles!;
gender.value = next.model.gender!;
// selectedGender.value = next.model.gender![0];
if (tempPatient.patientData?.saluation != null) {
var sp = next.model.titles!.firstWhere(
(element) => element.id == tempPatient.patientData?.saluation);
selectedSaluation.value = sp;
}
if (tempPatient.patientData?.gender != null) {
var gd = next.model.gender!.firstWhere(
(element) => element.id == tempPatient.patientData?.gender);
selectedGender.value = gd;
}
sapaanKey.value = sapaanKey.value + 1;
genderKey.value = genderKey.value + 1;
getFilterLoading.value = false;
}
},
);
//Function ke step selanjutny(pilih pemeriksaan)
nextStep() {
if (withoutNIK.value == false) {
if (nikCtr.text.isEmpty) {
SanckbarWidget(context, "NIK Harus diisi", snackbarType.warning);
return;
}
if (nikCtr.text.length < 16 || nikCtr.text.length > 16) {
SanckbarWidget(
context, "NIK berjumlah 16 digit", snackbarType.warning);
return;
}
}
if (nameCtr.text.isEmpty ||
selectedGender.value.id == null ||
selectedSaluation.value.id == null ||
jabatanCtr.text.isEmpty ||
kedudukanCtr.text.isEmpty ||
lokasiCtr.text.isEmpty ||
pekerjaanCtr.text.isEmpty) {
// print(nameCtr.text);
// print(selectedGender.value.name);
SanckbarWidget(
context,
"Sapaan, Nama, Tanggal Lahir, Jenis Kelamin, jabatan, kedudukan, lokasi, dan pekerjaan Harus Diisi !",
snackbarType.warning);
} else {
var temp = ref.watch(registrationDataProvider);
PatientData data = PatientData(
noRM: noRmCtr.text,
saluation: selectedSaluation.value.id,
name: nameCtr.text,
prefix: prefixCtr.text,
suffix: suffixCtr.text,
dob: dobState.value.toString(),
nik: nikCtr.text,
nip: nipCtr.text,
withoutNIK: withoutNIK.value ? "Y" : "N",
gender: selectedGender.value.id.toString(),
address: addressCtr.text,
diagnosis: diagnosisCtr.text,
hp: hpCtr.text,
jabatan: jabatanCtr.text,
kedudukan: kedudukanCtr.text,
lokasi: lokasiCtr.text,
pekerjaan: pekerjaanCtr.text,
note: noteCtr.text);
ref.read(registrationDataProvider.notifier).state = RegistrationModel(
orderID: temp.orderID,
token: auth?.token ?? "",
patientId: temp.patientId ?? "new",
patientData: data,
specimens: temp.specimens,
paket: temp.paket,
bahan: temp.bahan,
tests: temp.tests,
total: temp.total);
ref.read(registrasiProvider.state).update((state) => 1);
}
}
return Padding(
padding: const EdgeInsets.only(top: 20, bottom: 20, left: 24, right: 24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 120),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
DropdownMenu<CustomDropDownModel>(
menuHeight:
Constant.getActualY(context: context, y: 300),
key: ValueKey(sapaanKey.value),
initialSelection: selectedSaluation.value,
trailingIcon: getFilterLoading.value
? LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)
: null,
width: Constant.getActualX(context: context, x: 120),
hintText: "Sapaan",
textStyle: Constant.body2_400(context: context),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
)),
label: const Text(
"Sapaan",
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
onSelected: (value) {
onSelectSaluation(value!);
selectedSaluation.value = value;
},
dropdownMenuEntries: sapaan.value
.map<DropdownMenuEntry<CustomDropDownModel>>(
(e) => DropdownMenuEntry(
value: e, label: e.name ?? ""))
.toList()),
],
)),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 160),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
hintText: 'Prefix',
labelText: "Prefix",
controller: prefixCtr,
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 520),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
hintText: 'Name',
labelText: "Nama",
controller: nameCtr,
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 160),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
hintText: 'Suffix',
labelText: "suffix",
controller: suffixCtr,
),
),
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Row(
children: [
Radio<String>(
value: "date",
groupValue: dobRb.value,
onChanged: (value) {
dobRb.value = value!;
},
),
SizedBox(width: Constant.getActualX(context: context, x: 20)),
SizedBox(
width: Constant.getActualX(context: context, x: 252),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
TextField(
enabled: dobRb.value != "age",
controller: dobCtr,
style: Constant.body2_400(context: context),
decoration: InputDecoration(
suffixIcon: Icon(Icons.calendar_today),
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
),
labelText: "Tanggal Lahir" //label text of field
),
readOnly: true,
onTap: () async {
DateTime? pickedDate = await showDatePicker(
// locale: Locale("id"),
context: context,
initialDate: dobState.value,
firstDate: DateTime(1800),
initialEntryMode: DatePickerEntryMode.calendarOnly,
//DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2100));
if (pickedDate != null) {
print(
pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000
String formattedDate =
DateFormat('dd-MM-yyyy').format(pickedDate);
print(
formattedDate); //formatted date output using intl package => 2021-03-16
dobCtr.text =
formattedDate; //set output date to TextField value.
dobState.value = pickedDate;
} else {}
},
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
Radio<String>(
value: "age",
groupValue: dobRb.value,
onChanged: (value) {
dobRb.value = value!;
},
),
SizedBox(width: Constant.getActualX(context: context, x: 20)),
Stack(
clipBehavior: Clip.none,
// alignment: AlignmentDirectional.bottomCenter,
children: [
Container(
padding: EdgeInsets.symmetric(
horizontal:
Constant.getActualX(context: context, x: 16),
vertical: Constant.getActualY(context: context, y: 12)),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey)),
child: Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 90),
height: Constant.getActualY(context: context, y: 40),
child: CustomTextField(
onChange: (value) {
if (dobRb.value == "age") {
DateTime coba = Jiffy.now()
.subtract(
months: int.parse(monthCtr.text),
years: int.parse(yearCtr.text),
days: int.parse(dayCtr.text))
.dateTime;
// print(coba);
dobState.value = coba;
dobCtr.text = DateFormat('dd-MM-yyyy')
.format(dobState.value);
}
},
disable: dobRb.value != "date",
hintText: 'Tahun',
labelText: "",
isDense: true,
suffixIcon: SizedBox(
child: Container(
padding: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 8),
bottom: Constant.getActualY(
context: context, y: 8),
right: Constant.getActualX(
context: context, x: 5),
),
child: Text(
'Tahun',
style: Constant.body3_400(context: context)
.copyWith(color: Colors.grey),
),
),
),
style: Constant.body3_400(context: context),
hintStyle: Constant.body3_400(context: context),
labelStyle: Constant.body3_400(context: context),
controller: yearCtr,
inputType: TextInputType.number,
),
),
SizedBox(
width:
Constant.getActualX(context: context, x: 16)),
SizedBox(
width: Constant.getActualX(context: context, x: 90),
height: Constant.getActualY(context: context, y: 40),
child: CustomTextField(
onChange: (value) {
if (dobRb.value == "age") {
DateTime currentDate = DateTime.now();
DateTime coba = Jiffy.now()
.subtract(
months: int.parse(monthCtr.text),
years: int.parse(yearCtr.text),
days: int.parse(dayCtr.text))
.dateTime;
// print(coba);
dobState.value = coba;
dobCtr.text = DateFormat('dd-MM-yyyy')
.format(dobState.value);
}
},
disable: dobRb.value != "date",
hintText: 'Bulan',
labelText: "",
controller: monthCtr,
inputType: TextInputType.number,
isDense: true,
suffixIcon: Container(
child: Container(
padding: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 8),
bottom: Constant.getActualY(
context: context, y: 8),
right: Constant.getActualX(
context: context, x: 5),
),
child: Text(
'Bulan',
style: Constant.body3_400(context: context)
.copyWith(color: Colors.grey),
),
),
),
style: Constant.body3_400(context: context),
hintStyle: Constant.body3_400(context: context),
labelStyle: Constant.body3_400(context: context),
),
),
SizedBox(
width:
Constant.getActualX(context: context, x: 16)),
SizedBox(
width: Constant.getActualX(context: context, x: 90),
height: Constant.getActualY(context: context, y: 40),
child: CustomTextField(
disable: dobRb.value != "date",
onChange: (value) {
if (dobRb.value == "age") {
if (int.parse(dayCtr.text) <= 31) {
DateTime currentDate = DateTime.now();
DateTime coba = Jiffy.now()
.subtract(
months: int.parse(monthCtr.text),
years: int.parse(yearCtr.text),
days: int.parse(dayCtr.text))
.dateTime;
// print(coba);
dobState.value = coba;
dobCtr.text = DateFormat('dd-MM-yyyy')
.format(dobState.value);
} else {
dayCtr.text = "31";
SanckbarWidget(
context,
"hari tidak lebih dari 31",
snackbarType.warning);
}
}
},
hintText: 'Hari',
labelText: "",
controller: dayCtr,
inputType: TextInputType.number,
isDense: true,
suffixIcon: Container(
child: Container(
padding: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 8),
bottom: Constant.getActualY(
context: context, y: 8),
right: Constant.getActualX(
context: context, x: 5),
),
child: Text(
'Hari',
style: Constant.body3_400(context: context)
.copyWith(color: Colors.grey),
),
),
),
style: Constant.body3_400(context: context),
hintStyle: Constant.body3_400(context: context),
labelStyle: Constant.body3_400(context: context),
),
),
],
),
),
Positioned(
top: -8,
left: 10,
child: Container(
color: Colors.white,
child: const Text(
"Umur",
style: TextStyle(color: Colors.grey),
)))
],
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 300),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
hintText: 'No RM',
labelText: "No RM",
controller: noRmCtr,
),
)
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 240),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
inputType: TextInputType.number,
controller: nikCtr,
hintText: withoutNIK.value
? "Pasien Tanpa NIK Data Historis Tidak Terkonsolidasi"
: 'NIK',
labelText: withoutNIK.value
? "Pasien Tanpa NIK Data Historis Tidak Terkonsolidasi"
: "NIK"),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 20)),
Center(
child: Transform.scale(
scale: 0.8,
child: Checkbox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4)),
value: withoutNIK.value,
onChanged: (value) {
withoutNIK.value = value!;
if (value == true) {}
}),
),
),
Text('Tanpa NIK',
style: Constant.body2_400(context: context)
.copyWith(color: Constant.textBlack)),
// SizedBox(width: Constant.getActualX(context: context, x: 24)),
// SizedBox(
// width: Constant.getActualX(context: context, x: 250),
// child: DropdownMenu<CustomDropDownModel>(
// key: ValueKey(genderKey.value),
// initialSelection: selectedGender.value,
// trailingIcon: getFilterLoading.value
// ? LoadingAnimationWidget.discreteCircle(
// color: Constant.primaryBlue, size: 20)
// : null,
// width: Constant.getActualX(context: context, x: 250),
// hintText: "Jenis Kelamin",
// textStyle: Constant.body2_400(context: context),
// inputDecorationTheme: InputDecorationTheme(
// border: OutlineInputBorder(
// borderSide: BorderSide(color: Constant.primaryBlue),
// borderRadius: BorderRadius.circular(8),
// )),
// label: const Text("jenis Kelamin"),
// onSelected: (value) {
// onSelectGender(value!);
// selectedGender.value = value;
// },
// dropdownMenuEntries: gender.value
// .map<DropdownMenuEntry<CustomDropDownModel>>((e) =>
// DropdownMenuEntry(value: e, label: e.name ?? ""))
// .toList())),
// SizedBox(width: Constant.getActualX(context: context, x: 24)),
// SizedBox(
// width: Constant.getActualX(context: context, x: 365),
// // height: Constant.getActualY(context: context, y: 56),
// child: CustomTextField(
// hintText: 'No Hp',
// labelText: "No Hp",
// controller: hpCtr,
// ),
// ),
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 304),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
DropdownMenu<CustomDropDownModel>(
key: ValueKey(genderKey.value),
initialSelection: selectedGender.value,
trailingIcon: getFilterLoading.value
? LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)
: null,
width: Constant.getActualX(context: context, x: 304),
hintText: "Jenis Kelamin",
textStyle: Constant.body2_400(context: context),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
)),
label: const Text("jenis Kelamin"),
onSelected: (value) {
onSelectGender(value!);
selectedGender.value = value;
},
dropdownMenuEntries: gender.value
.map<DropdownMenuEntry<CustomDropDownModel>>(
(e) => DropdownMenuEntry(
value: e, label: e.name ?? ""))
.toList()),
],
)),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
inputType: TextInputType.number,
hintText: 'No Hp',
labelText: "No Hp",
controller: hpCtr,
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
child: CustomTextField(
hintText: "NIP",
labelText: "NIP",
controller: nipCtr,
),
),
],
),
// SizedBox(height: Constant.getActualY(context: context, y: 24)),
// Row(
// children: [],
// ),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 304),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
hintText: 'Jabatan',
labelText: "Jabatan",
controller: jabatanCtr,
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
hintText: 'Kedudukan',
labelText: "Kedudukan",
controller: kedudukanCtr,
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
hintText: 'Lokasi',
labelText: "Lokasi",
controller: lokasiCtr,
),
],
),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 218),
// height: Constant.getActualY(context: context, y: 56),
child: Stack(
alignment: AlignmentDirectional.topEnd,
children: [
Padding(
padding: const EdgeInsets.all(5),
child: Text(
"*",
style: Constant.body2_400(context: context)
.copyWith(color: Constant.primaryRed),
),
),
CustomTextField(
hintText: 'Pekerjaan',
labelText: "Pekerjaan",
controller: pekerjaanCtr,
),
],
),
)
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 1032),
// height: Constant.getActualY(context: context, y: 120),
child: CustomTextField(
controller: addressCtr,
hintText: 'Alamat',
labelText: "Alamat",
maxLines: 4,
minLines: 1),
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 1032),
// height: Constant.getActualY(context: context, y: 120),
child: CustomTextField(
controller: diagnosisCtr,
hintText: 'Diagnosis',
labelText: "Diagnosis",
maxLines: 4,
minLines: 1),
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
SizedBox(
width: Constant.getActualX(context: context, x: 1032),
// height: Constant.getActualY(context: context, y: 120),
child: CustomTextField(
controller: noteCtr,
hintText: 'Catatan FO',
labelText: "Catatan FO",
maxLines: 4,
minLines: 1),
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
SizedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
OutlinedButton(
style: OutlinedButton.styleFrom(
backgroundColor: Colors.white,
side: BorderSide(color: Colors.grey.shade400, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: () {
ref.read(registrationDataProvider.notifier).state =
RegistrationModel();
ref.read(selectedTestProvider.notifier).state =
List.empty(growable: true);
ref.read(selectedPacketProvider.notifier).state =
List.empty(growable: true);
Navigator.pop(context);
},
child: SizedBox(
height: Constant.getActualY(context: context, y: 56),
child: Center(
child: Text('Batal',
style: Constant.button_medium(context: context)
.copyWith(color: Constant.textBlack)),
),
)),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Constant.green,
side: BorderSide(color: Constant.green, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
onPressed: () {
nextStep();
},
child: SizedBox(
height: Constant.getActualY(context: context, y: 56),
child: Center(
child: Text('Berikutnya',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textWhite)),
),
)),
],
),
)
],
),
);
}
}

View File

@@ -0,0 +1,631 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:jiffy/jiffy.dart';
import 'package:mitra_corporate/model/registration_model.dart';
import 'package:mitra_corporate/model/test_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/provider/registrasi_provider.dart';
import 'package:mitra_corporate/screen/registrasi/get_specimen_provider.dart';
import 'package:mitra_corporate/screen/registrasi/new_order_provider.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../widgets/custom_snackbar_widget.dart';
import '../../widgets/tests_tabel_widget.dart';
class DetailOrder extends HookConsumerWidget {
const DetailOrder({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final auth = ref.watch(authProvider);
final tempRegistrationData = ref.watch(registrationDataProvider);
final testListAll = ref.read(tempTestListProvider);
final selectedTest = ref.read(selectedTestProvider);
final dialogAction = ref.watch(dialogOrderActionProvider);
final testList = useState<List<Items>>(List.empty());
final testScrollCtr = useScrollController();
final specimenLoading = useState(false);
final addOrderLoading = ref.watch(addOrderLoadingProvider);
final tabctr = useTabController(initialLength: 2);
final selectedTab = useState(0);
final dateValidation = useState(false);
dateVal(bool value) {
dateValidation.value = value;
}
//get specimen & bahan from list of tests
getSpecimen() {
List<Map<String, String>> test = List.empty(growable: true);
tempRegistrationData.tests?.forEach((element) {
test.add({
"id": element.id ?? "0",
"tab": element.tab ?? "0",
"sasCode": element.sasCode ?? "-"
});
});
// print(jsonEncode(test));
ref
.read(GetSpecimenProvider.notifier)
.getData(arrTest: test, token: auth?.token ?? "0");
}
ref.listen(
GetSpecimenProvider,
(pref, next) {
if (next is GetSpecimenStateInit) {
specimenLoading.value = true;
} else if (next is GetSpecimenStateLoading) {
specimenLoading.value = true;
} else if (next is GetSpecimenStateError) {
specimenLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is GetSpecimenStateDone) {
var tests = tempRegistrationData.tests;
//assign specimn & bahan
List<GetSpecimenModel> nw = next.model;
List<Specimens> sp = List.empty(growable: true);
List<Bahan> bhn = List.empty(growable: true);
for (var i = 0; i < tests!.length; i++) {
var tes = tests[i];
var cek = "${tes.tab}|${tes.id}";
for (var j = 0; j < nw.length; j++) {
var cek2 = "${nw[j].tab}|${nw[j].id}";
if (cek == cek2) {
tests[i].specimen = nw[j].specimen?.toSet().toList();
tests[i].bahan = nw[j].bahan?.toSet().toList();
nw[j].specimen?.forEach((element) {
var a = sp.firstWhere(
(dt) => dt.id == element.id,
orElse: () =>
Specimens(ctr: TextEditingController(), id: "new"),
);
if (a.id == "new") {
sp.add(element);
}
});
nw[j].bahan?.forEach((element) {
var a = bhn.firstWhere(
(dt) => dt.id == element.id,
orElse: () =>
Bahan(ctr: TextEditingController(), id: "new"),
);
if (a.id == "new") {
bhn.add(element);
}
});
}
}
}
ref.read(registrationDataProvider.notifier).state = RegistrationModel(
orderID: tempRegistrationData.orderID,
patientId: tempRegistrationData.patientId,
token: auth?.token,
patientData: tempRegistrationData.patientData,
paket: tempRegistrationData.paket,
tests: tests,
specimens: sp.toSet().toList(),
bahan: bhn.toSet().toList(),
total: tempRegistrationData.total);
specimenLoading.value = false;
}
},
);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
List<Items> temp = List.empty(growable: true);
for (var element in testListAll) {
// "$idTab|$idTest"
for (var i in element.items!) {
String cek = "${element.tabId}|${i.testID}";
String ck = selectedTest.firstWhere(
(j) => j == cek,
orElse: () => "-1",
);
if (ck != "-1") {
temp.add(i);
}
}
}
testList.value = temp;
getSpecimen();
});
return () {};
}, []);
//delete tests & auto cek & delete specimen/bahan
delete(String idTest, String idtab) {
List<Tests> temp = tempRegistrationData.tests ?? [];
List<String> selectedTest = ref.watch(selectedTestProvider);
String cek = "$idtab|$idTest";
double total = double.parse(tempRegistrationData.total!);
List<Specimens> oldSp = tempRegistrationData.specimens ?? [];
List<Bahan> oldBhn = tempRegistrationData.bahan ?? [];
Tests removed = tempRegistrationData.tests!.firstWhere(
(element) => element.id == idTest && element.tab == idtab);
temp.removeWhere(
(element) => element.id == idTest && element.tab == idtab);
selectedTest.removeWhere((element) => element == cek);
total = total - double.parse(removed.price!);
// var tests = tempRegistrationData.tests;
// List<GetSpecimenModel> nw = next.model;
List<Specimens> newSp = List.empty(growable: true);
List<Bahan> newBhn = List.empty(growable: true);
for (var j = 0; j < temp.length; j++) {
temp[j].specimen?.forEach((element) {
var a = newSp.firstWhere(
(dt) => dt.id == element.id,
orElse: () => Specimens(ctr: TextEditingController(), id: "new"),
);
if (a.id == "new") {
newSp.add(element);
}
});
temp[j].bahan?.forEach((element) {
var a = newBhn.firstWhere(
(dt) => dt.id == element.id,
orElse: () => Bahan(ctr: TextEditingController(), id: "new"),
);
if (a.id == "new") {
newBhn.add(element);
}
});
}
// print("old sp");
// print(jsonEncode(oldSp));
// print("new sp");
// print(jsonEncode(newSp));
//compare old dp and new sp to get deleted specimen
List<Specimens> deletedSp = List.empty(growable: true);
for (var i = 0; i < oldSp.length; i++) {
Specimens sp = newSp.firstWhere((element) => element.id == oldSp[i].id,
orElse: () =>
Specimens(ctr: TextEditingController(), id: "deleted"));
if (sp.id == "deleted") {
deletedSp.add(oldSp[i]);
}
}
List<Specimens> tempSp = tempRegistrationData.specimens ?? [];
for (var e in deletedSp) {
tempSp.removeWhere((element) => element.id == e.id);
}
// print("deleted sp");
// print(jsonEncode(deletedSp));
// print("old bhn");
// print(jsonEncode(oldBhn));
// print("new bhn");
// print(jsonEncode(newBhn));
//compare old bhn and new bhn to get deleted bahan
List<Bahan> deletedBhn = List.empty(growable: true);
for (var i = 0; i < oldBhn.length; i++) {
Bahan sp = newBhn.firstWhere((element) => element.id == oldBhn[i].id,
orElse: () => Bahan(ctr: TextEditingController(), id: "deleted"));
if (sp.id == "deleted") {
deletedBhn.add(oldBhn[i]);
}
}
List<Bahan> tempBhn = tempRegistrationData.bahan ?? [];
for (var e in deletedBhn) {
tempBhn.removeWhere((element) => element.id == e.id);
}
// print("deleted bahan");
// print(jsonEncode(deletedBhn));
ref.read(registrationDataProvider.notifier).state = RegistrationModel(
orderID: tempRegistrationData.orderID,
patientId: tempRegistrationData.patientId,
token: auth?.token,
patientData: tempRegistrationData.patientData,
specimens: tempSp,
paket: tempRegistrationData.paket,
bahan: tempBhn,
tests: temp,
total: total.toString());
ref.read(selectedTestProvider.notifier).state = selectedTest;
if (selectedTest.isEmpty) {
ref.read(registrasiProvider.state).update((state) => state - 1);
}
}
deletePaket(String idPaket) {
List<Paket> temp = tempRegistrationData.paket ?? [];
List<String> selectedPaket = ref.watch(selectedPacketProvider);
selectedPaket.removeWhere((element) => element == idPaket);
temp.removeWhere((element) => element.id == idPaket);
ref.read(selectedPacketProvider.notifier).state = selectedPaket;
ref.read(registrationDataProvider.notifier).state = RegistrationModel(
orderID: tempRegistrationData.orderID,
patientId: tempRegistrationData.patientId,
token: auth?.token,
patientData: tempRegistrationData.patientData,
specimens: tempRegistrationData.specimens,
paket: temp,
bahan: tempRegistrationData.bahan,
tests: tempRegistrationData.tests,
total: tempRegistrationData.total);
}
Future<DateTime?> pickDate(DateTime initialdate) => showDatePicker(
// locale: Locale("id", "ID"),
context: context,
initialEntryMode: DatePickerEntryMode.calendarOnly,
cancelText: "Batal",
confirmText: "Simpan",
helpText: "Pilih Tanggal",
initialDate: initialdate,
firstDate: DateTime(1800),
lastDate: DateTime(2100));
Future<TimeOfDay?> pickTime(TimeOfDay initialTime) => showTimePicker(
context: context,
initialTime: initialTime,
cancelText: "Batal",
confirmText: "Simpan",
helpText: "Masukkan Jam dan Menit",
hourLabelText: "Jam",
minuteLabelText: "Menit",
builder: (context, childWidget) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
// Using 24-Hour format
alwaysUse24HourFormat: true),
// If you want 12-Hour format, just change alwaysUse24HourFormat to false or remove all the builder argument
child: childWidget!);
},
initialEntryMode: TimePickerEntryMode.input);
Future pickDateTime(String idtab, String idtest, String dt) async {
print(dt);
// DateTime selectedDate = DateTime.parse(dt);
// DateTime? date = await pickDate(selectedDate);
// if (date == null) return;
// TimeOfDay? time = await pickTime(
// TimeOfDay(hour: selectedDate.hour, minute: selectedDate.minute));
// if (time == null) return;
var test = tempRegistrationData.tests ?? [];
for (var i = 0; i < test.length; i++) {
if (test[i].id == idtest && test[i].tab == idtab) {
test[i].date = dt;
}
}
ref.read(registrationDataProvider.notifier).state = RegistrationModel(
orderID: tempRegistrationData.orderID,
patientData: tempRegistrationData.patientData,
specimens: tempRegistrationData.specimens,
tests: test,
token: auth?.token,
patientId: tempRegistrationData.patientId,
bahan: tempRegistrationData.bahan,
total: tempRegistrationData.total);
}
Future dateValidationFunc(
String idtab, String idtest, bool validate) async {
// DateTime selectedDate = DateTime.parse(dt);
// DateTime? date = await pickDate(selectedDate);
// if (date == null) return;
// TimeOfDay? time = await pickTime(
// TimeOfDay(hour: selectedDate.hour, minute: selectedDate.minute));
// if (time == null) return;
var test = tempRegistrationData.tests ?? [];
for (var i = 0; i < test.length; i++) {
if (test[i].id == idtest && test[i].tab == idtab) {
test[i].dateVal = validate;
}
}
ref.read(registrationDataProvider.notifier).state = RegistrationModel(
orderID: tempRegistrationData.orderID,
patientData: tempRegistrationData.patientData,
specimens: tempRegistrationData.specimens,
tests: test,
token: auth?.token,
patientId: tempRegistrationData.patientId,
bahan: tempRegistrationData.bahan,
total: tempRegistrationData.total);
}
bool validateDate(String? value) {
if (value == null || value.isEmpty) {
SanckbarWidget(context, "Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
final splitted = value.split(" ");
if (splitted.length == 2) {
final date = splitted[0];
final time = splitted[1];
final splittedDate = date.split("-");
final splittedTime = time.split(":");
if (splittedDate.length == 3) {
final day = int.tryParse(splittedDate[0]);
final month = int.tryParse(splittedDate[1]);
final year = int.tryParse(splittedDate[2]);
if (day != null) {
if (day > 31) {
SanckbarWidget(
context,
"Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
}
if (month != null) {
if (month > 12) {
SanckbarWidget(
context,
"Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
}
// if (year == null) {
// return "Format salah";
// }
} else {
SanckbarWidget(context, "Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
if (splittedTime.length == 2) {
var hour = int.tryParse(splittedTime[0]);
var sec = int.tryParse(splittedTime[1]);
if (hour != null) {
if (hour > 24) {
SanckbarWidget(
context,
"Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
}
if (sec != null) {
if (sec > 60) {
SanckbarWidget(
context,
"Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
}
} else {
SanckbarWidget(context, "Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
} else {
SanckbarWidget(context, "Format Waktu Pengambilan Sample Salah !",
snackbarType.warning);
return true;
}
return false;
}
addOrder() {
print(jsonEncode(tempRegistrationData));
for (var element in tempRegistrationData.tests!) {
if (element.date == null || element.date!.isEmpty) {
SanckbarWidget(
context,
"Waktu pengambilan sample ${element.name} Tidak boleh kosong",
snackbarType.warning);
continue;
}
if (validateDate(element.date)) {
continue;
}
var coba = Jiffy.parse(element.date!, pattern: 'dd-MM-yyyy HH:mm')
.format(pattern: 'yyyy-MM-dd HH:mm');
print(coba);
}
// print(jsonEncode(tempRegistrationData));
// return;
ref
.read(NewOrderProviderProvider.notifier)
.addOrder(prm: tempRegistrationData);
}
ref.listen(
NewOrderProviderProvider,
(pref, next) {
if (next is NewOrderProviderStateInit) {
ref.read(addOrderLoadingProvider.notifier).state = true;
} else if (next is NewOrderProviderStateLoading) {
ref.read(addOrderLoadingProvider.notifier).state = true;
} else if (next is NewOrderProviderStateError) {
ref.read(addOrderLoadingProvider.notifier).state = false;
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is NewOrderProviderStateDone) {
ref.read(orderNumberProvider.notifier).state = next.number;
print(next.number);
SanckbarWidget(
context,
"Registrasi Berhasil. Order Number ${next.number}",
snackbarType.success);
ref.read(addOrderLoadingProvider.notifier).state = false;
ref.read(registrasiProvider.state).update((state) => 3);
print(jsonEncode(tempRegistrationData));
}
},
);
return Material(
child: Container(
width: Constant.getActualX(context: context, x: 1160),
// height: MediaQuery.of(context).size.height,
color: Colors.white,
child: Column(
children: [
Row(
children: [
SizedBox(
// color: Colors.red,
width: Constant.getActualX(context: context, x: 1160),
// Constant.getActualX(context: context, x: 1160) * 0.71,
child: TestsTableWidget(
specimenLoading: specimenLoading,
testScrollCtr: testScrollCtr,
tempRegistrationData: tempRegistrationData,
addOrderLoading: addOrderLoading,
delete: delete,
deletePaket: deletePaket,
pickDateTime: pickDateTime),
),
// Container(
// width:
// Constant.getActualX(context: context, x: 1160) * 0.05,
// ),
// Container(
// // color: Colors.red,
// width:
// Constant.getActualX(context: context, x: 1160) * 0.24,
// child: Column(
// children: [
// Container(
// width:
// Constant.getActualX(context: context, x: 1160) *
// 0.24,
// child: TabBar(
// controller: tabctr,
// labelColor: Colors.black,
// labelStyle: Constant.body3_500(context: context)
// .copyWith(color: Colors.black),
// indicatorColor: Constant.primaryBlue,
// onTap: (value) => selectedTab.value = value,
// tabs: [
// Tab(
// text: "Specimen",
// ),
// Tab(
// text: "Bahan",
// )
// ]),
// ),
// SizedBox(
// height:
// Constant.getActualY(context: context, y: 20),
// ),
// if (selectedTab.value == 0)
// SpecimenTableWidget(
// specimenLoading: specimenLoading,
// tempRegistrationData: tempRegistrationData,
// addOrderLoading: addOrderLoading),
// if (selectedTab.value == 1)
// BahanTableWidget(
// specimenLoading: specimenLoading,
// tempRegistrationData: tempRegistrationData,
// addOrderLoading: addOrderLoading)
// // SizedBox(
// // height:
// // Constant.getActualY(context: context, y: 20),
// // ),
// // BahanTableWidget(
// // specimenLoading: specimenLoading,
// // tempRegistrationData: tempRegistrationData,
// // addOrderLoading: addOrderLoading),
// ],
// ),
// ),
],
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
OutlinedButton(
style: OutlinedButton.styleFrom(
backgroundColor: Colors.white,
side: BorderSide(
color: Colors.grey.shade400, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: addOrderLoading == false
? () {
// Navigator.pop(context);
ref
.read(registrasiProvider.state)
.update((state) => state - 1);
}
: null,
child: SizedBox(
height:
Constant.getActualY(context: context, y: 56),
child: Center(
child: addOrderLoading
? LoadingAnimationWidget.staggeredDotsWave(
color: Constant.green, size: 30)
: Text('Sebelumnya',
style: Constant.body3_600(
context: context)
.copyWith(color: Constant.textBlack)),
),
)),
SizedBox(
width: Constant.getActualX(context: context, x: 24)),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Constant.green,
side: BorderSide(color: Constant.green, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
// onPressed: () {
// showDialog(
// context: context,
// builder: ((context) => DialogPemeriksaan()));
// },
onPressed: addOrderLoading == false
? () {
addOrder();
}
: null,
child: SizedBox(
height:
Constant.getActualY(context: context, y: 56),
child: Center(
child: addOrderLoading
? LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white, size: 30)
: Text('Simpan',
style: Constant.body3_600(
context: context)
.copyWith(color: Constant.textWhite)),
),
)),
],
),
)
],
)));
}
}

View File

@@ -0,0 +1,658 @@
import 'dart:ui';
import 'package:eva_icons_flutter/eva_icons_flutter.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:mitra_corporate/model/auth_model.dart';
import 'package:mitra_corporate/model/registration_model.dart';
import 'package:mitra_corporate/model/test_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/screen/registrasi/registrasi_prvider.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:scroll_to_index/scroll_to_index.dart';
import '../../app/constant.dart';
import '../../provider/registrasi_provider.dart';
import '../../widgets/custom_snackbar_widget.dart';
import '../../widgets/custom_text_field.dart';
// buat model tipu2 sebagai penampung list dari data-data
// DummyListPeriksa = idListPeriksa, idTipePeriksa, namaPeriksa
// DummyTipePeriksa = idTipePeriksa, tipePeriksa
class DummyListPeriksa {
late int idListPeriksa;
late int idTipePeriksa;
late String namaPeriksa;
DummyListPeriksa(
{required this.idListPeriksa,
required this.idTipePeriksa,
required this.namaPeriksa});
}
class DummyTipePeriksa {
late int idTipePeriksa;
late String tipePeriksa;
DummyTipePeriksa({required this.idTipePeriksa, required this.tipePeriksa});
}
// ubah stateless jadi HookConsumerWidget
class FormPemeriksaan extends HookConsumerWidget {
const FormPemeriksaan({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final tempRegistrationData = ref.watch(registrationDataProvider);
final selectedtest = ref.watch(selectedTestProvider);
final selectedPacket = ref.watch(selectedPacketProvider);
// inisialisasi baca provider idTipePeriksaStateProvider
final selectedTab = ref.watch(idTipePeriksaStateProvider);
final AuthModel auth = ref.watch(authProvider) ?? AuthModel();
final listTest = useState<List<TestModel>>(List.empty());
final testLoading = useState(false);
final searchCtr = useTextEditingController(text: "");
final scrollCtr = useScrollController();
final ctr = useState(AutoScrollController());
//get pemeriksaan from api
getPemeriksaan() {
ref
.read(GetFPPProvider.notifier)
.getData(mouID: auth.mUserMMouID ?? "0", token: auth.token ?? "0");
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
getPemeriksaan();
});
return () {};
}, []);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
int index = listTest.value
.indexWhere((element) => element.tabId == selectedTab);
print(index);
// scrollCtr.animateTo(double.parse(index.toString()),
// curve: Curves.linear, duration: Duration(milliseconds: 100));
// scrollCtr.jumpTo(double.parse(index.toString()));
if (searchCtr.text.isNotEmpty) {
ctr.value.scrollToIndex(index);
}
});
return () {};
}, [selectedTab]);
// ref.watch(idTipePeriksaStateProvider.notifier).addListener((state) {
// int index =
// listTest.value.indexWhere((element) => element.tabId == selectedTab);
// print(index);
// if (index != -1) {
// // scrollCtr.animateTo(double.parse(index.toString()),
// // curve: Curves.linear, duration: Duration(milliseconds: 100));
// // scrollCtr.jumpTo(double.parse(index.toString()));
// }
// });
ref.listen(
GetFPPProvider,
(pref, next) {
if (next is GetFPPStateInit) {
testLoading.value = true;
} else if (next is GetFPPStateLoading) {
testLoading.value = true;
} else if (next is GetFPPStateError) {
testLoading.value = false;
print(next.message);
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is GetFPPStateDone) {
listTest.value = next.model;
ref.read(tempTestListProvider.notifier).state = next.model;
// tabController.length
testLoading.value = false;
}
},
);
// searchCtr.addListener(() {
// listTest.value.firstWhere((element) => element.items)
// },);
return Material(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 500),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
suffixIcon: const Icon(EvaIcons.search),
controller: searchCtr,
isPassword: false,
hintText: "Cari Pemeriksaan",
labelText: "Cari Pemeriksaan",
),
),
SizedBox(height: Constant.getActualY(context: context, y: 12)),
// Tab
testLoading.value
? LoadingAnimationWidget.discreteCircle(
color: Colors.blue, size: 20)
: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: Constant.getActualX(context: context, x: 1080)),
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: Constant.getActualY(context: context, y: 70),
child: ScrollConfiguration(
behavior:
ScrollConfiguration.of(context).copyWith(dragDevices: {
PointerDeviceKind.mouse,
PointerDeviceKind.touch,
PointerDeviceKind.trackpad,
PointerDeviceKind.stylus,
PointerDeviceKind.unknown
}),
child: ListView(
controller: ctr.value,
scrollDirection: Axis.horizontal,
children: listTest.value
.asMap()
.entries
.map((e) => AutoScrollTag(
key: ValueKey(e.key),
index: e.key,
controller: ctr.value,
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: selectedTab == e.value.tabId
? BorderSide(
width: 2,
color: Constant.primaryRed)
: const BorderSide(
color: Colors.transparent),
),
),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shadowColor: Constant.primaryRed
.withOpacity(0.5),
backgroundColor: Colors.transparent,
elevation: 0),
onPressed: () {
ref
.read(idTipePeriksaStateProvider
.state)
.update((state) => e.value.tabId!);
},
child: Text(
e.value.tab!,
style:
Constant.body3_500(context: context)
.copyWith(color: Colors.black),
)),
),
))
.toList(),
),
),
),
),
SizedBox(height: Constant.getActualY(context: context, y: 14)),
// widget checkbox semua biar rapi
listCheckboxWidget(
search: searchCtr,
listTest: listTest,
loading: testLoading,
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
SizedBox(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
OutlinedButton(
style: OutlinedButton.styleFrom(
backgroundColor: Colors.white,
side: BorderSide(color: Colors.grey.shade400, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: () {
// Navigator.pop(context);
ref
.read(registrasiProvider.state)
.update((state) => state - 1);
},
child: SizedBox(
height: Constant.getActualY(context: context, y: 56),
child: Center(
child: Text('Sebelumnya',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack)),
),
)),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Constant.green,
side: BorderSide(color: Constant.green, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
onPressed: () {
if (selectedtest.isEmpty && selectedPacket.isEmpty) {
SanckbarWidget(
context,
"Belum memilih Pemeriksaan atau paket",
snackbarType.warning);
return;
}
List<Tests> ts = List.empty(growable: true);
double total = 0;
for (var i = 0; i < selectedtest.length; i++) {
var splitted = selectedtest[i].split("|");
var tabid = splitted[0];
var testid = splitted[1];
for (var j = 0; j < listTest.value.length; j++) {
if (listTest.value[j].tabId == int.parse(tabid)) {
var tests = listTest.value[j].items;
for (var k = 0; k < tests!.length; k++) {
if (tests[k].testID == testid) {
ts.add(Tests(
date: DateFormat('dd-MM-yyyy HH:mm')
.format(DateTime.now())
.toString(),
id: tests[k].testID,
name: tests[k].testName,
price: tests[k].testPrice,
sasCode: tests[k].sasCode,
// specimen: "",
tab: tabid,
));
total = total +
double.parse(tests[k].testPrice ?? "0");
}
}
}
}
}
List<Paket> pkt = List.empty(growable: true);
for (var i = 0; i < selectedPacket.length; i++) {
var paket = listTest.value
.firstWhere((element) => element.isPaket == "Y");
paket.items?.forEach((element) {
if (element.testID == selectedPacket[i]) {
pkt.add(Paket(
id: element.testID,
arrTest: element.arrTest,
detail: element.sasCode,
price: element.testPrice,
type: element.type,
name: element.testName));
total =
total + double.parse(element.testPrice ?? "0");
}
});
}
bool paketValidation = false;
bool testValidation = false;
for (var e in pkt) {
var test = e.arrTest?.split(",");
test?.forEach((f) {
for (var g in pkt) {
if (e.id?.trim() != g.id?.trim()) {
var testCek = g.arrTest!.split(",");
var cek = testCek.firstWhere(
(h) => h.trim() == f.trim(),
orElse: () => "-1",
);
if (cek != "-1") {
paketValidation = true;
}
}
}
});
}
for (var e in pkt) {
var test = e.arrTest?.split(",");
test?.forEach((f) {
for (var g in ts) {
if (f.trim() == g.id?.trim()) {
testValidation = true;
}
}
});
}
if (paketValidation) {
SanckbarWidget(
context,
"Paket Pilihan memiliki pemeriksaan yang sama ",
snackbarType.warning);
return;
}
if (testValidation) {
SanckbarWidget(
context,
"Paket Pilihan memiliki pemeriksaan yang sama dengan test pilihan",
snackbarType.warning);
return;
}
ref.read(registrationDataProvider.notifier).state =
RegistrationModel(
orderID: tempRegistrationData.orderID,
patientId: tempRegistrationData.patientId,
token: auth.token,
patientData: tempRegistrationData.patientData,
specimens: tempRegistrationData.specimens,
bahan: tempRegistrationData.bahan,
tests: ts,
paket: pkt,
total: total.toString());
ref.read(registrasiProvider.state).update((state) => 2);
},
child: SizedBox(
height: Constant.getActualY(context: context, y: 56),
child: Center(
child: Text('Berikutnya',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textWhite)),
),
)),
],
),
)
],
));
}
}
class listCheckboxWidget extends HookConsumerWidget {
const listCheckboxWidget(
{super.key,
required this.listTest,
required this.loading,
required this.search});
final ValueNotifier<List<TestModel>> listTest;
final ValueNotifier<bool> loading;
final TextEditingController search;
@override
Widget build(BuildContext context, WidgetRef ref) {
bool? isChecked = false;
final tests = useState<List<Items>>(List.empty());
final isPaket = useState(false);
// inisialisasi state provider buat baca idTipePeriksa yang di klik
final selectedTab = ref.watch(idTipePeriksaStateProvider);
final selectedTest = ref.watch(selectedTestProvider);
final selectedPacket = ref.watch(selectedPacketProvider);
final scrollCtr = useScrollController();
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
if (loading.value == false && listTest.value.isNotEmpty) {
// TestModel temp = listTest.value[0];
var selected = listTest.value
.firstWhere((element) => element.tabId == selectedTab);
if (selected.isPaket == 'Y') {
isPaket.value = true;
} else {
isPaket.value = false;
}
if (search.text.isNotEmpty) {
List<Items> filter = selected.items!
.where((element) =>
element.testName!.toLowerCase().contains(search.text))
.toList();
tests.value = filter;
} else {
tests.value = selected.items ?? [];
}
}
});
return () {};
}, [selectedTab, loading.value]);
search.addListener(
() {
if (loading.value == false && listTest.value.isNotEmpty) {
for (var i = 0; i < listTest.value.length; i++) {
List<Items> flt = listTest.value[i].items!
.where((element) => element.testName!
.toLowerCase()
.contains(search.text.toLowerCase()))
.toList();
if (flt.isNotEmpty) {
ref.read(idTipePeriksaStateProvider.notifier).state =
listTest.value[i].tabId!;
break;
}
}
var selected = listTest.value
.firstWhere((element) => element.tabId == selectedTab);
if (search.text.isNotEmpty) {
List<Items> filter = selected.items!
.where((element) => element.testName!
.toLowerCase()
.contains(search.text.toLowerCase()))
.toList();
tests.value = filter;
} else {
tests.value = selected.items ?? [];
}
}
},
);
selectedItem(int idTab, String idTest) {
List<String> temp = selectedTest.toSet().toList(growable: true);
var data = "$idTab|$idTest";
var cek = temp.firstWhere(
(element) => element == data,
orElse: () => "-1",
);
if (cek == "-1") {
temp.add(data);
} else {
temp.remove(cek);
}
ref.read(selectedTestProvider.notifier).state = temp.toSet().toList();
}
valueCek<Bool>(int idTab, String idTest) {
var data = "$idTab|$idTest";
var cek = selectedTest.firstWhere(
(element) => element == data,
orElse: () => "-1",
);
if (cek == "-1") {
return false;
} else {
return true;
}
}
selectPacket(String idTest) {
List<String> temp = selectedPacket.toSet().toList(growable: true);
var cek = temp.firstWhere(
(element) => element == idTest,
orElse: () => "-1",
);
if (cek == "-1") {
temp.add(idTest);
} else {
temp.remove(cek);
}
ref.read(selectedPacketProvider.notifier).state = temp.toSet().toList();
}
valueCekPacket<Bool>(String idTest) {
var cek = selectedPacket.firstWhere(
(element) => element == idTest,
orElse: () => "-1",
);
if (cek == "-1") {
return false;
} else {
return true;
}
}
// buat data2 dari List Periksa
return Row(children: [
SizedBox(
width: Constant.getActualX(context: context, x: 1080),
height: Constant.getActualY(context: context, y: 230),
child: loading.value
? Center(
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 30),
)
: Scrollbar(
controller: scrollCtr,
thumbVisibility: true,
trackVisibility: true,
child: ScrollConfiguration(
behavior:
ScrollConfiguration.of(context).copyWith(dragDevices: {
PointerDeviceKind.mouse,
PointerDeviceKind.touch,
PointerDeviceKind.trackpad,
PointerDeviceKind.stylus,
PointerDeviceKind.unknown
}),
child: isPaket.value
? ListView(
controller: scrollCtr,
children: tests.value
.map(
(e) => Container(
margin: EdgeInsets.symmetric(vertical: 5),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
children: [
Checkbox(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(4)),
// value: valueCek(
// selectedTab, e.testID!),
value: valueCekPacket(e.testID!),
onChanged: (value) {
print(value);
selectPacket(e.testID!);
// selectedItem(
// selectedTab, e.testID!);
}),
SizedBox(
// constraints: BoxConstraints(
// maxWidth:
// ),
// color: Colors.red,
width: Constant.getActualX(
context: context, x: 380),
child: Text('${e.testName}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Constant.body3_400(
context: context)
.copyWith(
color: Constant
.textBlack)),
),
],
),
Padding(
padding: EdgeInsets.only(left: 30),
child: Text(
e.sasCode ?? "",
style: Constant.caption2_400(
context: context)
.copyWith(
color: Constant.textGrey),
),
)
],
),
),
)
.toList(),
)
: GridView.count(
controller: scrollCtr,
shrinkWrap: true,
crossAxisCount: 2,
childAspectRatio: 15,
children: tests.value
.map(
(e) => Container(
child: Row(
children: [
Checkbox(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(4)),
// value: valueCek(selectedTab, e.testID!),
value:
valueCek(selectedTab, e.testID!),
onChanged: (value) {
print(value);
selectedItem(
selectedTab, e.testID!);
}),
SizedBox(
// constraints: BoxConstraints(
// maxWidth:
// ),
// color: Colors.red,
width: Constant.getActualX(
context: context, x: 380),
child: Text('${e.testName}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Constant.body3_400(
context: context)
.copyWith(
color: Constant.textBlack)),
),
// Container(
// // constraints: BoxConstraints(
// // maxWidth:
// // ),
// // color: Colors.red,
// // width:
// // Constant.getActualX(context: context, x: 350),
// child: Text(
// Constant.convertToIdr(
// int.parse(e.testPrice ?? "0"), 0),
// style: Constant.body3_500(
// context: context)
// .copyWith(color: Constant.textBlack)),
// ),
],
),
),
)
.toList(),
),
),
),
),
]);
}
}

View File

@@ -0,0 +1,66 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/registration_filter_model.dart';
import 'package:mitra_corporate/repository/registration_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class GetFilterRegistrationState extends Equatable {
final DateTime date;
const GetFilterRegistrationState(this.date);
@override
List<Object?> get props => [date];
}
class GetFilterRegistrationStateInit extends GetFilterRegistrationState {
GetFilterRegistrationStateInit() : super(DateTime.now());
}
class GetFilterRegistrationStateLoading extends GetFilterRegistrationState {
GetFilterRegistrationStateLoading() : super(DateTime.now());
}
class GetFilterRegistrationStateError extends GetFilterRegistrationState {
final String message;
GetFilterRegistrationStateError({
required this.message,
}) : super(DateTime.now());
}
class GetFilterRegistrationStateDone extends GetFilterRegistrationState {
final RegistrationFilterModel model;
GetFilterRegistrationStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class GetFilterRegistrationNotifier
extends StateNotifier<GetFilterRegistrationState> {
final Ref ref;
GetFilterRegistrationNotifier({
required this.ref,
}) : super(GetFilterRegistrationStateInit());
void getData({required String token}) async {
try {
state = GetFilterRegistrationStateLoading();
final dio = ref.read(dioProvider);
final resp =
await RegistrationRepository(dio: dio).getFilter(token: token);
state = GetFilterRegistrationStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = GetFilterRegistrationStateError(message: e.message.toString());
} else {
state = GetFilterRegistrationStateError(message: e.toString());
}
}
}
}
//provider
final GetFilterRegistrationProvider = StateNotifierProvider<
GetFilterRegistrationNotifier, GetFilterRegistrationState>(
(ref) => GetFilterRegistrationNotifier(ref: ref));

View File

@@ -0,0 +1,67 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/registration_model.dart';
import 'package:mitra_corporate/repository/registration_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class GetSpecimenState extends Equatable {
final DateTime date;
const GetSpecimenState(this.date);
@override
List<Object?> get props => [date];
}
class GetSpecimenStateInit extends GetSpecimenState {
GetSpecimenStateInit() : super(DateTime.now());
}
class GetSpecimenStateLoading extends GetSpecimenState {
GetSpecimenStateLoading() : super(DateTime.now());
}
class GetSpecimenStateError extends GetSpecimenState {
final String message;
GetSpecimenStateError({
required this.message,
}) : super(DateTime.now());
}
class GetSpecimenStateDone extends GetSpecimenState {
final List<GetSpecimenModel> model;
GetSpecimenStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class GetSpecimenNotifier extends StateNotifier<GetSpecimenState> {
final Ref ref;
GetSpecimenNotifier({
required this.ref,
}) : super(GetSpecimenStateInit());
void getData(
{required List<Map<String, String>> arrTest,
required String token}) async {
try {
state = GetSpecimenStateLoading();
final dio = ref.read(dioProvider);
final resp = await RegistrationRepository(dio: dio)
.getSpecimen(arrTest: arrTest, token: token);
state = GetSpecimenStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = GetSpecimenStateError(message: e.message.toString());
} else {
state = GetSpecimenStateError(message: e.toString());
}
}
}
}
//provider
final GetSpecimenProvider =
StateNotifierProvider<GetSpecimenNotifier, GetSpecimenState>(
(ref) => GetSpecimenNotifier(ref: ref));

View File

@@ -0,0 +1,64 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/registration_model.dart';
import 'package:mitra_corporate/repository/registration_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class NewOrderProviderState extends Equatable {
final DateTime date;
const NewOrderProviderState(this.date);
@override
List<Object?> get props => [date];
}
class NewOrderProviderStateInit extends NewOrderProviderState {
NewOrderProviderStateInit() : super(DateTime.now());
}
class NewOrderProviderStateLoading extends NewOrderProviderState {
NewOrderProviderStateLoading() : super(DateTime.now());
}
class NewOrderProviderStateError extends NewOrderProviderState {
final String message;
NewOrderProviderStateError({
required this.message,
}) : super(DateTime.now());
}
class NewOrderProviderStateDone extends NewOrderProviderState {
final String number;
NewOrderProviderStateDone({
required this.number,
}) : super(DateTime.now());
}
//notifier
class NewOrderProviderNotifier extends StateNotifier<NewOrderProviderState> {
final Ref ref;
NewOrderProviderNotifier({
required this.ref,
}) : super(NewOrderProviderStateInit());
void addOrder({required RegistrationModel prm}) async {
try {
state = NewOrderProviderStateLoading();
final dio = ref.read(dioProvider);
final resp = await RegistrationRepository(dio: dio).addOrder(prm: prm);
state = NewOrderProviderStateDone(number: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = NewOrderProviderStateError(message: e.message.toString());
} else {
state = NewOrderProviderStateError(message: e.toString());
}
}
}
}
//provider
final NewOrderProviderProvider =
StateNotifierProvider<NewOrderProviderNotifier, NewOrderProviderState>(
(ref) => NewOrderProviderNotifier(ref: ref));

View File

@@ -0,0 +1,116 @@
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/provider/menu_provider.dart';
import 'package:mitra_corporate/screen/registrasi/dialog_pendaftaran_pasien.dart';
import 'package:mitra_corporate/screen/registrasi/table_pasien.dart';
import 'package:mitra_corporate/widgets/header.dart';
import '../../app/constant.dart';
import '../../provider/registrasi_provider.dart';
import '../../widgets/custom_text_field.dart';
class RegistrasiPasienScreen extends HookConsumerWidget {
const RegistrasiPasienScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final isExpand = ref.watch(sideBarExpandProvider);
final keywordCtr =
useTextEditingController(text: ref.read(keywordProvider));
return Scaffold(
// backgroundColor: Constant.grey_200,
// backgroundColor: Color(0xffF9FAFB),
body: Column(
children: [
Header(),
Padding(
// padding: const EdgeInsets.all(0),
padding: const EdgeInsets.all(32.0),
child: Column(
children: [
Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 1079),
// height: Constant.getActualY(context: context, y: 40),
child: Text('Registrasi Pasien',
style: Constant.h3_400(context: context)
.copyWith(color: Constant.textBlack)),
),
SizedBox(
height: Constant.getActualY(context: context, y: 40),
),
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12)),
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 32),
),
child: Column(
children: [
Row(
children: [
Expanded(
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
controller: keywordCtr,
onChange: (value) {
ref.read(keywordProvider.notifier).state =
value;
},
isPassword: false,
hintText: "Cari Nama, NIK, dan Nomor HP",
labelText: "Cari Nama, NIK, dan Nomor HP",
suffixIcon: Icon(EvaIcons.search),
),
),
SizedBox(
width:
Constant.getActualX(context: context, x: 24)),
SizedBox(
width:
Constant.getActualX(context: context, x: 171),
height:
Constant.getActualY(context: context, y: 56),
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(8),
// color: Constant.primaryRed),
child: ElevatedButton.icon(
label: Text('Pasien Baru',
style: Constant.button_large(context: context)
.copyWith(color: Constant.textWhite)),
icon: Icon(EvaIcons.plus,
color: Colors.white, size: 20.0),
onPressed: () {
ref
.read(dialogOrderActionProvider.notifier)
.state = 'new';
showDialog(
context: context,
barrierDismissible: false,
builder: ((context) =>
DialogPendaftaranPasien()));
},
),
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 24)),
TablePasien()
],
),
),
],
),
)
],
),
);
}
}

View File

@@ -0,0 +1,64 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/test_model.dart';
import 'package:mitra_corporate/repository/registration_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class GetFPPState extends Equatable {
final DateTime date;
const GetFPPState(this.date);
@override
List<Object?> get props => [date];
}
class GetFPPStateInit extends GetFPPState {
GetFPPStateInit() : super(DateTime.now());
}
class GetFPPStateLoading extends GetFPPState {
GetFPPStateLoading() : super(DateTime.now());
}
class GetFPPStateError extends GetFPPState {
final String message;
GetFPPStateError({
required this.message,
}) : super(DateTime.now());
}
class GetFPPStateDone extends GetFPPState {
final List<TestModel> model;
GetFPPStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class GetFPPNotifier extends StateNotifier<GetFPPState> {
final Ref ref;
GetFPPNotifier({
required this.ref,
}) : super(GetFPPStateInit());
void getData({required String mouID, required String token}) async {
try {
state = GetFPPStateLoading();
final dio = ref.read(dioProvider);
final resp = await RegistrationRepository(dio: dio)
.getFPP(mouID: mouID, token: token);
state = GetFPPStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = GetFPPStateError(message: e.message.toString());
} else {
state = GetFPPStateError(message: e.toString());
}
}
}
}
//provider
final GetFPPProvider = StateNotifierProvider<GetFPPNotifier, GetFPPState>(
(ref) => GetFPPNotifier(ref: ref));

View File

@@ -0,0 +1,70 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/model/registration_model.dart';
import 'package:mitra_corporate/provider/registrasi_provider.dart';
import '../../app/constant.dart';
class RegistrasiSukses extends HookConsumerWidget {
const RegistrasiSukses({
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final orderNumber = ref.watch(orderNumberProvider);
return Column(
children: [
SizedBox(
// color: Colors.green,
width: Constant.getActualX(context: context, x: 500),
height: Constant.getActualY(context: context, y: 500),
child: Image.asset(
'images/order_success.png',
fit: BoxFit.contain,
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
Text('Registrastion Success',
style: Constant.h3_400(context: context)
.copyWith(color: Constant.textBlack)),
SizedBox(
height: Constant.getActualY(context: context, y: 48),
),
SelectableText('Order Number : $orderNumber',
style: Constant.h3_400(context: context)
.copyWith(color: Constant.textBlack)),
SizedBox(
height: Constant.getActualY(context: context, y: 48),
),
SizedBox(
height: Constant.getActualY(context: context, y: 48),
child: OutlinedButton(
style: OutlinedButton.styleFrom(
backgroundColor: Colors.white,
side: BorderSide(color: Constant.primaryRed, width: 1),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: () {
Navigator.pop(context);
ref.read(registrasiProvider.notifier).state = 0;
ref.read(idTipePeriksaStateProvider.notifier).state = 1;
ref.read(registrationDataProvider.notifier).state =
RegistrationModel();
ref.read(selectedTestProvider.notifier).state =
List.empty(growable: true);
ref.read(tempTestListProvider.notifier).state =
List.empty(growable: true);
ref.read(selectedPacketProvider.notifier).state =
List.empty(growable: true);
},
child: Text('Kembali ke Dashboard',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.primaryRed))),
),
],
);
}
}

View File

@@ -0,0 +1,74 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/search_patient_model.dart';
import 'package:mitra_corporate/repository/patient_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class SearchPatientState extends Equatable {
final DateTime date;
const SearchPatientState(this.date);
@override
List<Object?> get props => [date];
}
class SearchPatientStateInit extends SearchPatientState {
SearchPatientStateInit() : super(DateTime.now());
}
class SearchPatientStateLoading extends SearchPatientState {
SearchPatientStateLoading() : super(DateTime.now());
}
class SearchPatientStateError extends SearchPatientState {
final String message;
SearchPatientStateError({
required this.message,
}) : super(DateTime.now());
}
class SearchPatientStateDone extends SearchPatientState {
final SearchPatientModel model;
SearchPatientStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class SearchPatientNotifier extends StateNotifier<SearchPatientState> {
final Ref ref;
SearchPatientNotifier({
required this.ref,
}) : super(SearchPatientStateInit());
void getData(
{required String token,
required String page,
required String keyword,
required String rpp,
required String companyID}) async {
try {
state = SearchPatientStateLoading();
final dio = ref.read(dioProvider);
final resp = await PatientRepository(dio: dio).search(
companyID: companyID,
keyword: keyword,
page: page,
rpp: rpp,
token: token);
state = SearchPatientStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = SearchPatientStateError(message: e.message.toString());
} else {
state = SearchPatientStateError(message: e.toString());
}
}
}
}
//provider
final SearchPatientProvider =
StateNotifierProvider<SearchPatientNotifier, SearchPatientState>(
(ref) => SearchPatientNotifier(ref: ref));

View File

@@ -0,0 +1,488 @@
import 'dart:async';
import 'package:mitra_corporate/screen/registrasi/delete_patient_provider%20copy.dart';
import 'package:mitra_corporate/screen/registrasi/dialog_delete_patient.dart';
import 'package:mitra_corporate/screen/registrasi/dialog_edit_patient.dart';
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:data_table_2/data_table_2.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:intl/intl.dart';
import 'package:mitra_corporate/model/patient_Model.dart';
import 'package:mitra_corporate/model/registration_model.dart';
import 'package:mitra_corporate/model/search_patient_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/provider/registrasi_provider.dart';
import 'package:mitra_corporate/screen/registrasi/search_patient_provider.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../provider/menu_provider.dart';
import '../../widgets/custom_snackbar_widget.dart';
import 'dialog_pendaftaran_pasien.dart';
class TablePasien extends HookConsumerWidget {
const TablePasien({
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final isExpand = ref.watch(sideBarExpandProvider);
final auth = ref.watch(authProvider);
final rowsPerPage = useState(10);
final searchLoading = useState(false);
final deleteLoading = useState(false);
final dataStart = useState(1);
final dataEnd = useState(1);
final currPage = useState(1);
final patientList = useState<SearchPatientModel>(
SearchPatientModel(patients: [], total: "0", totalPage: 0));
final keyword = ref.watch(keywordProvider);
final registrasiTabID = ref.watch(registrasiProvider);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final debouncer = Debouncer(milliseconds: 100);
debouncer.run(() {
ref.read(SearchPatientProvider.notifier).getData(
token: auth?.token ?? "",
page: currPage.value.toString(),
keyword: keyword,
rpp: rowsPerPage.value.toString(),
companyID: auth?.mUserMCompanyID ?? "");
});
});
return () {};
}, [currPage.value, registrasiTabID]);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final debouncer = Debouncer(milliseconds: 100);
currPage.value = 1;
debouncer.run(() {
ref.read(SearchPatientProvider.notifier).getData(
token: auth?.token ?? "",
page: "1",
keyword: keyword,
rpp: rowsPerPage.value.toString(),
companyID: auth?.mUserMCompanyID ?? "");
});
});
return () {};
}, [
keyword,
rowsPerPage.value,
]);
ref.listen(
SearchPatientProvider,
(pref, next) {
if (next is SearchPatientStateInit) {
searchLoading.value = true;
} else if (next is SearchPatientStateLoading) {
searchLoading.value = true;
} else if (next is SearchPatientStateError) {
searchLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is SearchPatientStateDone) {
patientList.value = next.model;
// print(jsonEncode(next.model));
dataStart.value =
(currPage.value * rowsPerPage.value) - rowsPerPage.value + 1;
dataEnd.value = currPage.value == next.model.totalPage
? int.parse(next.model.total ?? "0")
: dataStart.value + rowsPerPage.value - 1;
searchLoading.value = false;
}
},
);
openDialog(PatientModel e) {
ref.read(registrationDataProvider.notifier).state = RegistrationModel(
patientId: e.id,
patientData: PatientData(
noRM: e.noRM,
address: e.address,
dob: e.dob,
gender: e.sexId,
hp: e.hp,
name: e.name,
nik: e.nik,
nip: e.nip,
prefix: e.prefix,
kedudukan: e.kedudukan,
jabatan: e.jabatan,
lokasi: e.lokasi,
pekerjaan: e.pekerjaan,
saluation: e.titleId,
suffix: e.suffix),
);
ref.read(dialogOrderActionProvider.notifier).state = 'new';
showDialog(
context: context,
barrierDismissible: false,
builder: ((context) => DialogPendaftaranPasien()));
}
openDialogEdit(PatientModel e) {
ref.read(registrationEditPatientProvider.notifier).state =
RegistrationModel(
patientId: e.id,
patientData: PatientData(
noRM: e.noRM,
address: e.address,
dob: e.dob,
gender: e.sexId,
hp: e.hp,
name: e.name,
nik: e.nik,
nip: e.nip,
prefix: e.prefix,
kedudukan: e.kedudukan,
jabatan: e.jabatan,
lokasi: e.lokasi,
pekerjaan: e.pekerjaan,
saluation: e.titleId,
suffix: e.suffix),
);
// showDialog<String>(
// context: context,
// barrierDismissible: false,
// builder: (BuildContext context) => DialogSendQr(
// arrOrderID: ["1", "2"],
// orderNumber: "abc",
// ),
// );
showDialog(
context: context,
barrierDismissible: false,
builder: ((context) => SimpleDialog(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12))),
contentPadding: const EdgeInsets.all(40.0),
children: [DialogEditPatient()],
))).then((value) {
print(value);
if (value == "done") {
ref.read(SearchPatientProvider.notifier).getData(
token: auth?.token ?? "",
page: currPage.value.toString(),
keyword: keyword,
rpp: rowsPerPage.value.toString(),
companyID: auth?.mUserMCompanyID ?? "");
}
});
}
openDialogDelete(PatientModel e) {
showDialog(
context: context,
builder: (context) {
return DialogDeletePatient(
NIK: e.nik ?? "",
delete: (patientID) {
print(patientID);
ref.read(DeletePatientProvider.notifier).DeletePatent(
patient_id: patientID, token: auth?.token ?? '');
},
patientID: e.id ?? "",
loading: deleteLoading.value,
name: e.name ?? "");
},
);
}
ref.listen(
DeletePatientProvider,
(pref, next) {
if (next is DeletePatientProviderStateInit) {
deleteLoading.value = true;
} else if (next is DeletePatientProviderStateLoading) {
deleteLoading.value = true;
} else if (next is DeletePatientProviderStateError) {
deleteLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is DeletePatientProviderStateDone) {
SanckbarWidget(
context, "Berhasil mengapus data", snackbarType.success);
Navigator.pop(context);
ref.read(SearchPatientProvider.notifier).getData(
token: auth?.token ?? "",
page: currPage.value.toString(),
keyword: keyword,
rpp: rowsPerPage.value.toString(),
companyID: auth?.mUserMCompanyID ?? "");
deleteLoading.value = false;
}
},
);
return Material(
// elevation: 8,
borderRadius: BorderRadius.circular(8),
child: Container(
// width: Constant.getActualX(context: context, x: 1079),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
// color: Colors.red,
),
height: Constant.getActualY(context: context, y: 586),
child: Column(
children: [
Container(
color: Colors.white,
height: Constant.getActualY(context: context, y: 516),
// height: Constant.getActualY(context: context, y: 300),
child: DataTable2(
dividerThickness: 1,
headingRowColor: WidgetStatePropertyAll(Constant.grey_200),
columnSpacing: 12,
horizontalMargin: 15,
minWidth: 600,
empty: Text("Data tidak ditemukan"),
columns: [
DataColumn2(
label: Text('Nama Pasien',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
size: ColumnSize.M,
),
DataColumn2(
label: Text('Alamat',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
size: ColumnSize.L),
DataColumn(
label: Text('NIK',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
DataColumn(
label: Text('DOB',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
DataColumn(
label: Text('Nomor HP',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
DataColumn2(
fixedWidth:
Constant.getActualX(context: context, x: 120),
label: Text('Aksi',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
// size: ColumnSize.S,
),
],
rows: searchLoading.value
? [
DataRow(cells: [
DataCell(LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)),
DataCell(LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)),
DataCell(LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)),
DataCell(LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)),
DataCell(LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)),
DataCell(LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)),
])
]
: patientList.value.patients!
.map((e) => DataRow(
onLongPress: () {
// openDialog(e);
},
cells: [
DataCell(SelectableText(e.name ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color: Constant.textBlack))),
DataCell(SelectableText(e.address ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color: Constant.textBlack))),
DataCell(SelectableText(e.nik ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color: Constant.textBlack))),
DataCell(SelectableText(
DateFormat('dd-MM-yyyy')
.format(DateTime.parse(e.dob!)),
style: Constant.body3_600(
context: context)
.copyWith(
color: Constant.textBlack))),
DataCell(SelectableText(e.hp ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color: Constant.textBlack))),
DataCell(Row(
children: [
Tooltip(
message: "Tambah order ${e.name}",
child: IconButton(
onPressed: () {
openDialog(e);
},
icon: Icon(
EvaIcons.plusSquare,
color: Colors.grey,
),
),
),
Tooltip(
message: "Edit Patient ${e.name}",
child: IconButton(
onPressed: () {
openDialogEdit(e);
},
icon: Icon(
EvaIcons.edit2,
color: Colors.grey,
),
),
),
if (e.statusDelete == "Y")
Tooltip(
message:
"Delete Patient ${e.name}",
child: IconButton(
onPressed: () {
openDialogDelete(e);
},
icon: Icon(
EvaIcons.closeCircle,
color: Colors.grey,
),
),
),
],
)),
]))
.toList()),
),
Material(
borderRadius: BorderRadius.circular(8),
color: Colors.white,
child: SizedBox(
// decoration: BoxDecoration(
// color: Colors.white,
// shape: BoxShape.rectangle,
// borderRadius: BorderRadius.circular(8)),
height: Constant.getActualY(context: context, y: 70),
child: Row(
children: [
Spacer(),
Text(
"Rows per page :",
style: Constant.body3_400(context: context),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
DropdownButton<int>(
value: rowsPerPage.value,
dropdownColor: Colors.white,
elevation: 0,
style: Constant.body3_400(context: context)
.copyWith(color: Colors.black),
underline: Container(),
icon: Icon(Icons.keyboard_arrow_down_rounded),
focusColor: Colors.white,
items: [
DropdownMenuItem(
value: 10,
child: Text("10"),
),
DropdownMenuItem(
value: 15,
child: Text("15"),
),
DropdownMenuItem(
value: 20,
child: Text("20"),
),
DropdownMenuItem(
value: 30,
child: Text("30"),
),
DropdownMenuItem(
value: 40,
child: Text("40"),
),
DropdownMenuItem(
value: 50,
child: Text("50"),
),
],
onChanged: (value) {
rowsPerPage.value = value!;
}),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
Text(
"${dataStart.value} - ${dataEnd.value} of ${patientList.value.total}",
style: Constant.body3_400(context: context),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
IconButton(
iconSize: 20,
onPressed: currPage.value > 1
? () {
currPage.value = currPage.value - 1;
}
: null,
icon: Icon(Icons.arrow_back_ios_new_rounded)),
SizedBox(
width: Constant.getActualX(context: context, x: 10),
),
IconButton(
iconSize: 20,
onPressed: currPage.value <
patientList.value.totalPage!.toInt()
? () {
currPage.value = currPage.value + 1;
}
: null,
icon: Icon(Icons.arrow_forward_ios_outlined)),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
)
],
),
),
)
],
)),
);
}
}
class Debouncer {
Debouncer({required this.milliseconds});
final int milliseconds;
Timer? _timer;
void run(VoidCallback action) {
if (_timer?.isActive ?? false) {
_timer?.cancel();
}
_timer = Timer(Duration(milliseconds: milliseconds), action);
}
}

View File

@@ -0,0 +1,436 @@
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../model/surat_jalan_detail_model.dart';
import '../../provider/auth_provider.dart';
import '../../provider/menu_provider.dart';
import '../../provider/surat_jalan_provider.dart';
import '../../widgets/custom_snackbar_widget.dart';
import '../../widgets/header.dart';
import '../../widgets/dialog_print.dart';
import '../surat_jalan/get_surat_jalan_detail_provider.dart';
class DetailResultScreen extends HookConsumerWidget {
const DetailResultScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final sjNumber = ref.watch(suratJalanNumber);
final id = ref.watch(suratJalanID);
final auth = ref.watch(authProvider);
final loading = useState(false);
final data = useState<List<SuratJalanDetailModel>>(List.empty());
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
ref
.read(GetSuratJalanDetailProvider.notifier)
.getData(token: auth?.token ?? "", deliveryID: id);
});
return () {};
}, [id]);
ref.listen(
GetSuratJalanDetailProvider,
(pref, next) {
if (next is GetSuratJalanDetailStateInit) {
loading.value = true;
} else if (next is GetSuratJalanDetailStateLoading) {
loading.value = true;
} else if (next is GetSuratJalanDetailStateError) {
loading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is GetSuratJalanDetailStateDone) {
// print(jsonEncode(next.model));
data.value = next.model;
loading.value = false;
}
},
);
return Material(
child: Column(
children: [
Header(),
Container(
child: Padding(
padding: const EdgeInsets.all(32.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
IconButton(
onPressed: () {
ref.read(currentMenuProvider.notifier).state = 4;
},
icon: Icon(EvaIcons.arrowBackOutline)),
Text(sjNumber,
style: Constant.h4_600(context: context)
.copyWith(color: Constant.textBlack)),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 24)),
// SizedBox(
// height: Constant.getActualY(context: context, y: 24)),
Material(
elevation: 10,
borderRadius: BorderRadius.all(Radius.circular(8)),
child: Column(
children: [
Container(
height: Constant.getActualY(context: context, y: 64),
decoration: BoxDecoration(
color: Constant.grey_200,
),
child: Row(
children: [
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 100),
height: Constant.getActualY(
context: context, y: 64),
color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: Text('Tanggal',
style:
Constant.body3_600(context: context)
.copyWith(
color: Constant.textGrey)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 115),
height: Constant.getActualY(
context: context, y: 64),
color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: Text('No Lab',
style:
Constant.body3_600(context: context)
.copyWith(
color: Constant.textGrey)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 196),
height: Constant.getActualY(
context: context, y: 64),
color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: Text('Nama Pasien',
style:
Constant.body3_600(context: context)
.copyWith(
color: Constant.textGrey)),
),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 100),
height: Constant.getActualY(
context: context, y: 64),
color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: Text('Receive',
overflow: TextOverflow.ellipsis,
style:
Constant.body3_600(context: context)
.copyWith(
color: Constant.textGrey)),
),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 100),
height: Constant.getActualY(
context: context, y: 64),
color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: Text('Proses',
overflow: TextOverflow.ellipsis,
style:
Constant.body3_600(context: context)
.copyWith(
color: Constant.textGrey)),
),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 80),
height: Constant.getActualY(
context: context, y: 64),
color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: Text('Done',
overflow: TextOverflow.ellipsis,
style:
Constant.body3_600(context: context)
.copyWith(
color: Constant.textGrey)),
),
),
),
],
),
),
Container(
color: Colors.white,
height: Constant.getActualY(context: context, y: 700),
child: loading.value
? Center(
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 40),
)
: ListView(
children: data.value
.map(
(e) => Row(
children: [
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 100),
height: Constant.getActualY(
context: context, y: 64),
child: Padding(
padding:
const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: Text(e.date ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color: Constant
.textBlack)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
width: Constant.getActualX(
context: context, x: 115),
height: Constant.getActualY(
context: context, y: 64),
child: Padding(
padding:
const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: Text(
e.orderNumber ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color: Constant
.textBlack)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
width: Constant.getActualX(
context: context, x: 196),
height: Constant.getActualY(
context: context, y: 64),
child: Padding(
padding:
const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: Text(
e.patientName ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color: Constant
.textBlack)),
),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
width: Constant.getActualX(
context: context, x: 100),
height: Constant.getActualY(
context: context, y: 64),
child: Padding(
padding:
const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: e.status == "R" ||
e.status == "T" ||
e.status == "P" ||
e.status == "Q" ||
e.status == "D"
? Icon(
EvaIcons
.checkmarkCircle2,
size: 24,
color:
Constant.green,
)
: null),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
width: Constant.getActualX(
context: context, x: 100),
height: Constant.getActualY(
context: context, y: 64),
child: Padding(
padding:
const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: e.status == "P" ||
e.status == "Q" ||
e.status == "D"
? Icon(
EvaIcons
.checkmarkCircle2,
size: 24,
color:
Constant.green,
)
: null),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
width: Constant.getActualX(
context: context, x: 80),
height: Constant.getActualY(
context: context, y: 64),
child: Padding(
padding:
const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: e.status == "D"
? InkWell(
onTap: () {
showDialog(
context:
context,
// barrierDismissible: false,
builder:
((context) =>
Container(
child:
DialogPrint(url: "http://devone.aplikasi.web.id/birt/run?__report=report/one/lab/rpt_fo_001.rptdesign&__format=pdf&username=ADMIN&PID=131868?t=1696927533769"),
)));
},
child: Tooltip(
message:
"Cetak laporan",
child: Icon(
EvaIcons
.printer,
size: 24,
color: Constant
.primaryBlue,
),
),
)
: null),
),
),
],
),
)
.toList(),
),
),
],
),
)
],
),
),
),
],
),
);
}
}

View File

@@ -0,0 +1,532 @@
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/provider/menu_provider.dart';
import 'package:mitra_corporate/screen/result/search_result_provider.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../model/surat_jalan_model.dart';
import '../../provider/auth_provider.dart';
import '../../provider/surat_jalan_provider.dart';
import '../../widgets/custom_snackbar_widget.dart';
import '../../widgets/custom_text_field.dart';
import '../../widgets/header.dart';
import '../registrasi/table_pasien.dart';
class ResultScreen extends HookConsumerWidget {
const ResultScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final keyword = useState("");
final keywordCtr = useTextEditingController(text: "");
final auth = ref.watch(authProvider);
final suratJalanTab = ref.watch(suratJalanProvider);
final rowsPerPage = useState(10);
final searchLoading = useState(false);
final dataStart = useState(1);
final dataEnd = useState(1);
final currPage = useState(1);
final sjList = useState<SearchSuratJalanModel>(
SearchSuratJalanModel(suratJalan: [], total: "0", totalPage: 0));
onRefresh() {
ref.read(SearchResultProvider.notifier).getData(
ed: "",
sd: "",
token: auth?.token ?? "",
page: currPage.value.toString(),
keyword: keyword.value,
rpp: rowsPerPage.value.toString(),
company_id: auth?.mUserMCompanyID ?? "");
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final debouncer = Debouncer(milliseconds: 100);
debouncer.run(() {
onRefresh();
});
});
return () {};
}, [currPage.value, suratJalanTab]);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final debouncer = Debouncer(milliseconds: 100);
currPage.value = 1;
debouncer.run(() {
ref.read(SearchResultProvider.notifier).getData(
ed: "",
sd: "",
token: auth?.token ?? "",
page: "1",
keyword: keyword.value,
rpp: rowsPerPage.value.toString(),
company_id: auth?.mUserMCompanyID ?? "");
});
});
return () {};
}, [
keyword.value,
rowsPerPage.value,
]);
ref.listen(
SearchResultProvider,
(pref, next) {
if (next is SearchResultStateInit) {
searchLoading.value = true;
} else if (next is SearchResultStateLoading) {
searchLoading.value = true;
} else if (next is SearchResultStateError) {
searchLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is SearchResultStateDone) {
sjList.value = next.model;
// print(jsonEncode(next.model));
dataStart.value =
(currPage.value * rowsPerPage.value) - rowsPerPage.value + 1;
dataEnd.value = currPage.value == next.model.totalPage
? int.parse(next.model.total ?? "0")
: dataStart.value + rowsPerPage.value - 1;
searchLoading.value = false;
}
},
);
return Material(
child: Column(children: [
Header(),
Padding(
padding: const EdgeInsets.all(32.0),
child:
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 1079),
height: Constant.getActualY(context: context, y: 40),
child: Text('Hasil',
style: Constant.h3_400(context: context)
.copyWith(color: Constant.textBlack)),
),
SizedBox(height: Constant.getActualY(context: context, y: 42)),
Container(
alignment: Alignment.centerLeft,
width: Constant.getActualX(context: context, x: 409),
child: CustomTextField(
onChange: (value) {
keyword.value = value;
},
// controller: searchCtr,
isPassword: false,
hintText: "Cari Nomor Surat Jalan",
labelText: "Cari",
suffixIcon: Icon(EvaIcons.search),
),
),
SizedBox(height: Constant.getActualY(context: context, y: 24)),
Material(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
child: Column(children: [
Row(
children: [
Expanded(
flex: 2,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
height:
Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 24, right: 24),
child: Text('Tanggal',
overflow: TextOverflow.ellipsis,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
)),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 24, right: 24),
child: Text('Nomor Surat Jalan',
overflow: TextOverflow.ellipsis,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
Expanded(
flex: 3,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 24, right: 24),
child: Text('Staff PIC',
overflow: TextOverflow.ellipsis,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 24, right: 24),
child: Text('New',
overflow: TextOverflow.ellipsis,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 24, right: 24),
child: Text('Send',
overflow: TextOverflow.ellipsis,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 24, right: 24),
child: Text('Receive',
overflow: TextOverflow.ellipsis,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
],
),
Container(
color: Colors.white,
height: Constant.getActualY(context: context, y: 500),
child: searchLoading.value
? Center(
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 40))
: ListView(
children: sjList.value.suratJalan!
.map(
(e) => TextButton(
onPressed: () {
ref.read(suratJalanID.notifier).state =
e.id ?? "";
ref
.read(suratJalanNumber.notifier)
.state = e.orderNumber ?? "";
ref
.read(currentMenuProvider.notifier)
.state = 7;
},
style: TextButton.styleFrom(
foregroundColor: Constant.primaryBlue),
child: Row(
children: [
Expanded(
flex: 2,
child: Padding(
padding:
const EdgeInsets.all(8.0),
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
// height: Constant.getActualY(
// context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding:
const EdgeInsets.only(
top: 12,
bottom: 12,
left: 24,
right: 24),
child: Text(e.date ?? "",
overflow:
TextOverflow.ellipsis,
style: Constant.body3_600(
context: context)
.copyWith(
color: Colors
.black)),
),
),
)),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
// height: Constant.getActualY(
// context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 24,
right: 24),
child: Text(e.orderNumber ?? "",
overflow:
TextOverflow.ellipsis,
style: Constant.body3_600(
context: context)
.copyWith(
color: Colors.black)),
),
),
),
Expanded(
flex: 3,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
// height: Constant.getActualY(
// context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 24,
right: 24),
child: Text(e.pic ?? "",
overflow:
TextOverflow.ellipsis,
style: Constant.body3_600(
context: context)
.copyWith(
color: Colors.black)),
),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
// height: Constant.getActualY(
// context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 24,
right: 24),
child: e.status == "N" ||
e.status == "S" ||
e.status == "D"
? Icon(
EvaIcons.checkmarkCircle2,
size: 24,
color: Constant.green,
)
: null,
),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
// height: Constant.getActualY(
// context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 24,
right: 24),
child: Row(
children: [
if (e.status == "S" ||
e.status == "D")
Icon(
EvaIcons.checkmarkCircle2,
size: 24,
color: Constant.green,
),
if (e.status == "X")
Icon(
EvaIcons.closeCircle,
size: 24,
color: Colors.red,
),
],
),
),
),
),
Expanded(
flex: 1,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
// height: Constant.getActualY(
// context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 24,
right: 24),
child: e.status == "D"
? Icon(
EvaIcons.checkmarkCircle2,
size: 24,
color: Constant.green,
)
: null,
),
),
),
],
),
),
)
.toList(),
),
),
Divider(),
SizedBox(
// color: Colors.white,
height: Constant.getActualY(context: context, y: 60),
child: Row(
children: [
Spacer(),
Text(
"Rows per page :",
style: Constant.body3_400(context: context),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
DropdownButton<int>(
value: rowsPerPage.value,
dropdownColor: Colors.white,
elevation: 0,
style: Constant.body3_400(context: context)
.copyWith(color: Colors.black),
underline: Container(),
icon: Icon(Icons.keyboard_arrow_down_rounded),
focusColor: Colors.white,
items: [
DropdownMenuItem(
value: 10,
child: Text("10"),
),
DropdownMenuItem(
value: 15,
child: Text("15"),
),
DropdownMenuItem(
value: 20,
child: Text("20"),
),
DropdownMenuItem(
value: 30,
child: Text("30"),
),
DropdownMenuItem(
value: 40,
child: Text("40"),
),
DropdownMenuItem(
value: 50,
child: Text("50"),
),
],
onChanged: (value) {
rowsPerPage.value = value!;
}),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
Text(
"${dataStart.value} - ${dataEnd.value} of ${sjList.value.total}",
style: Constant.body3_400(context: context),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
IconButton(
iconSize: 20,
onPressed: currPage.value > 1
? () {
currPage.value = currPage.value - 1;
}
: null,
icon: Icon(Icons.arrow_back_ios_new_rounded)),
SizedBox(
width: Constant.getActualX(context: context, x: 10),
),
IconButton(
iconSize: 20,
onPressed:
currPage.value < sjList.value.totalPage!.toInt()
? () {
currPage.value = currPage.value + 1;
}
: null,
icon: Icon(Icons.arrow_forward_ios_outlined)),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
)
],
),
)
]))
]))
]));
}
}

View File

@@ -0,0 +1,80 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/surat_jalan_model.dart';
import 'package:mitra_corporate/repository/surat_jalan_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class SearchResultState extends Equatable {
final DateTime date;
const SearchResultState(this.date);
@override
List<Object?> get props => [date];
}
class SearchResultStateInit extends SearchResultState {
SearchResultStateInit() : super(DateTime.now());
}
class SearchResultStateLoading extends SearchResultState {
SearchResultStateLoading() : super(DateTime.now());
}
class SearchResultStateError extends SearchResultState {
final String message;
SearchResultStateError({
required this.message,
}) : super(DateTime.now());
}
class SearchResultStateDone extends SearchResultState {
final SearchSuratJalanModel model;
SearchResultStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class SearchResultNotifier extends StateNotifier<SearchResultState> {
final Ref ref;
SearchResultNotifier({
required this.ref,
}) : super(SearchResultStateInit());
void getData({
required String token,
required String company_id,
required String rpp,
required String keyword,
required String page,
required String sd,
required String ed,
}) async {
try {
state = SearchResultStateLoading();
final dio = ref.read(dioProvider);
final resp = await SuratJalanRepository(dio: dio).getSuratJalan(
dateType: "1",
token: token,
company_id: company_id,
rpp: rpp,
keyword: keyword,
endDate: ed,
startDate: sd,
page: page);
state = SearchResultStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = SearchResultStateError(message: e.message.toString());
} else {
state = SearchResultStateError(message: e.toString());
}
}
}
}
//provider
final SearchResultProvider =
StateNotifierProvider<SearchResultNotifier, SearchResultState>(
(ref) => SearchResultNotifier(ref: ref));

View File

@@ -0,0 +1,53 @@
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:mitra_corporate/app/constant.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../app/route.dart';
import '../../model/auth_model.dart';
import '../../provider/auth_provider.dart';
class SplashScreen extends HookConsumerWidget {
const SplashScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
getPref() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final String? getData = prefs.getString(Constant.tokenName);
// print(getData);
if (getData != null) {
Timer(Duration(seconds: 1), () {
ref.read(authProvider.notifier).state =
AuthModel.fromJson(jsonDecode(getData));
Navigator.pushNamed(context, homeRoute);
});
} else {
Timer(Duration(seconds: 1), () {
Navigator.pushNamed(context, loginRoute);
});
}
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
// FlutterNativeSplash.remove();
getPref();
});
return () {};
}, []);
return Container(
color: Colors.white,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Center(
child: LoadingAnimationWidget.staggeredDotsWave(
color: Constant.primaryRed, size: 80),
),
);
}
}

View File

@@ -0,0 +1,65 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/repository/surat_jalan_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class CancelSuratJalanState extends Equatable {
final DateTime date;
const CancelSuratJalanState(this.date);
@override
List<Object?> get props => [date];
}
class CancelSuratJalanStateInit extends CancelSuratJalanState {
CancelSuratJalanStateInit() : super(DateTime.now());
}
class CancelSuratJalanStateLoading extends CancelSuratJalanState {
CancelSuratJalanStateLoading() : super(DateTime.now());
}
class CancelSuratJalanStateError extends CancelSuratJalanState {
final String message;
CancelSuratJalanStateError({
required this.message,
}) : super(DateTime.now());
}
class CancelSuratJalanStateDone extends CancelSuratJalanState {
final String number;
CancelSuratJalanStateDone({
required this.number,
}) : super(DateTime.now());
}
//notifier
class CancelSuratJalanNotifier extends StateNotifier<CancelSuratJalanState> {
final Ref ref;
CancelSuratJalanNotifier({
required this.ref,
}) : super(CancelSuratJalanStateInit());
void cancel({required String token, required String deliveryID}) async {
try {
state = CancelSuratJalanStateLoading();
final dio = ref.read(dioProvider);
final resp = await SuratJalanRepository(dio: dio)
.cancelSuratJalan(token: token, deliveryID: deliveryID);
state = CancelSuratJalanStateDone(number: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = CancelSuratJalanStateError(message: e.message.toString());
} else {
state = CancelSuratJalanStateError(message: e.toString());
}
}
}
}
//provider
final CancelSuratJalanProvider =
StateNotifierProvider<CancelSuratJalanNotifier, CancelSuratJalanState>(
(ref) => CancelSuratJalanNotifier(ref: ref));

View File

@@ -0,0 +1,65 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/create_surat_jalan_model.dart';
import 'package:mitra_corporate/repository/surat_jalan_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class CreateSuratJalanState extends Equatable {
final DateTime date;
const CreateSuratJalanState(this.date);
@override
List<Object?> get props => [date];
}
class CreateSuratJalanStateInit extends CreateSuratJalanState {
CreateSuratJalanStateInit() : super(DateTime.now());
}
class CreateSuratJalanStateLoading extends CreateSuratJalanState {
CreateSuratJalanStateLoading() : super(DateTime.now());
}
class CreateSuratJalanStateError extends CreateSuratJalanState {
final String message;
CreateSuratJalanStateError({
required this.message,
}) : super(DateTime.now());
}
class CreateSuratJalanStateDone extends CreateSuratJalanState {
final String number;
CreateSuratJalanStateDone({
required this.number,
}) : super(DateTime.now());
}
//notifier
class CreateSuratJalanNotifier extends StateNotifier<CreateSuratJalanState> {
final Ref ref;
CreateSuratJalanNotifier({
required this.ref,
}) : super(CreateSuratJalanStateInit());
void addOrder({required CreateSuratJalanModel prm}) async {
try {
state = CreateSuratJalanStateLoading();
final dio = ref.read(dioProvider);
final resp =
await SuratJalanRepository(dio: dio).createSuratJalan(prm: prm);
state = CreateSuratJalanStateDone(number: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = CreateSuratJalanStateError(message: e.message.toString());
} else {
state = CreateSuratJalanStateError(message: e.toString());
}
}
}
}
//provider
final CreateSuratJalanProvider =
StateNotifierProvider<CreateSuratJalanNotifier, CreateSuratJalanState>(
(ref) => CreateSuratJalanNotifier(ref: ref));

View File

@@ -0,0 +1,182 @@
import 'package:flutter/material.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
class DialogCancelSuratJalan extends StatelessWidget {
const DialogCancelSuratJalan(
{super.key,
required this.date,
required this.deliveryNumber,
required this.cancel,
required this.deliveryID,
required this.loading,
required this.pic});
final String date;
final String pic;
final String deliveryNumber;
final Function cancel;
final String deliveryID;
final bool loading;
@override
Widget build(BuildContext context) {
return AlertDialog(
titlePadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 24)),
actionsPadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 24)),
contentPadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 24)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8))),
title: Text(
'Konfirmasi Pembatalan',
style: Constant.h4_600(context: context),
),
content: Container(
constraints: BoxConstraints(
minHeight: Constant.getActualY(context: context, y: 100),
maxHeight: Constant.getActualY(context: context, y: 362),
),
height: Constant.getActualY(context: context, y: 240),
child: Column(
children: [
Text(
'Anda yakin membatalkan surat jalan berikut ?',
style: Constant.body1_600(context: context),
),
SizedBox(
height: Constant.getActualY(context: context, y: 24),
),
SizedBox(
width: Constant.getActualX(context: context, x: 416),
child: Card(
elevation: 1,
shape: RoundedRectangleBorder(
side: BorderSide(color: Constant.grey_200),
borderRadius: BorderRadius.circular(12)),
child: Container(
padding: EdgeInsets.symmetric(
horizontal:
Constant.getActualX(context: context, x: 24),
vertical:
Constant.getActualY(context: context, y: 24)),
child: Column(
children: [
Row(
children: [
Expanded(
flex: 5,
child: Text(
"Tanggal",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
),
Expanded(
flex: 7,
child: Text(
date,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack),
),
)
],
),
SizedBox(
height:
Constant.getActualY(context: context, y: 12),
),
Row(
children: [
Expanded(
flex: 5,
child: Text(
"Nomor Surat Jalan",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
),
Expanded(
flex: 7,
child: Text(
deliveryNumber,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack),
),
)
],
),
SizedBox(
height:
Constant.getActualY(context: context, y: 12),
),
Row(
children: [
Expanded(
flex: 5,
child: Text(
"Staff PIC",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
),
Expanded(
flex: 7,
child: Text(
pic,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack),
),
)
],
),
],
)),
),
)
],
)),
actions: <Widget>[
OutlinedButton(
style: OutlinedButton.styleFrom(
surfaceTintColor: Constant.primaryBlue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: !loading ? () => Navigator.pop(context, 'Batal') : null,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: loading
? LoadingAnimationWidget.staggeredDotsWave(
color: Constant.primaryBlue, size: 20)
: Text('Batal',
style: Constant.button_medium(context: context)
.copyWith(color: Constant.textBlack)),
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: !loading ? () => cancel(deliveryID) : null,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: loading
? LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white, size: 20)
: Text(
'Yakin',
style: Constant.button_medium(context: context)
.copyWith(color: Colors.white),
),
),
),
],
);
}
}

View File

@@ -0,0 +1,182 @@
import 'package:flutter/material.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
class DialogConfirmSuratJalan extends StatelessWidget {
const DialogConfirmSuratJalan(
{super.key,
required this.date,
required this.deliveryNumber,
required this.sendFunction,
required this.deliveryID,
required this.loading,
required this.pic});
final String date;
final String pic;
final String deliveryNumber;
final Function sendFunction;
final String deliveryID;
final bool loading;
@override
Widget build(BuildContext context) {
return AlertDialog(
titlePadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 24)),
actionsPadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 24)),
contentPadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 24)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8))),
title: Text(
'Konfirmasi Surat Jalan',
style: Constant.h4_600(context: context),
),
content: Container(
constraints: BoxConstraints(
minHeight: Constant.getActualY(context: context, y: 100),
maxHeight: Constant.getActualY(context: context, y: 362),
),
height: Constant.getActualY(context: context, y: 240),
child: Column(
children: [
Text(
'Anda yakin mengirimkan surat jalan berikut ?',
style: Constant.body1_600(context: context),
),
SizedBox(
height: Constant.getActualY(context: context, y: 24),
),
SizedBox(
width: Constant.getActualX(context: context, x: 416),
child: Card(
elevation: 1,
shape: RoundedRectangleBorder(
side: BorderSide(color: Constant.grey_200),
borderRadius: BorderRadius.circular(12)),
child: Container(
padding: EdgeInsets.symmetric(
horizontal:
Constant.getActualX(context: context, x: 24),
vertical:
Constant.getActualY(context: context, y: 24)),
child: Column(
children: [
Row(
children: [
Expanded(
flex: 5,
child: Text(
"Tanggal",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
),
Expanded(
flex: 7,
child: Text(
date,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack),
),
)
],
),
SizedBox(
height:
Constant.getActualY(context: context, y: 12),
),
Row(
children: [
Expanded(
flex: 5,
child: Text(
"Nomor Surat Jalan",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
),
Expanded(
flex: 7,
child: Text(
deliveryNumber,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack),
),
)
],
),
SizedBox(
height:
Constant.getActualY(context: context, y: 12),
),
Row(
children: [
Expanded(
flex: 5,
child: Text(
"Staff PIC",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
),
Expanded(
flex: 7,
child: Text(
pic,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack),
),
)
],
),
],
)),
),
)
],
)),
actions: <Widget>[
OutlinedButton(
style: OutlinedButton.styleFrom(
surfaceTintColor: Constant.primaryBlue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: !loading ? () => Navigator.pop(context, 'Batal') : null,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: loading
? LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white, size: 20)
: Text('Batal',
style: Constant.button_medium(context: context)
.copyWith(color: Constant.textBlack)),
),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Constant.green,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: !loading ? () => sendFunction(deliveryID) : null,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: loading
? LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white, size: 20)
: Text(
'Yakin',
style: Constant.button_medium(context: context)
.copyWith(color: Colors.white),
),
),
),
],
);
}
}

View File

@@ -0,0 +1,209 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/screen/surat_jalan/send_qr_code_provider.dart';
import '../../app/constant.dart';
import '../../widgets/custom_snackbar_widget.dart';
class DialogSendQr extends HookConsumerWidget {
const DialogSendQr(
{super.key, required this.arrOrderID, required this.orderNumber});
final List<String> arrOrderID;
final String orderNumber;
@override
Widget build(BuildContext context, WidgetRef ref) {
final auth = ref.watch(authProvider);
final rb = useState("Y");
sendQrCode() {
ref
.read(SendQrCodeProvider.notifier)
.senQrCode(token: auth?.token ?? "", arrOrderID: arrOrderID);
}
ref.listen(
SendQrCodeProvider,
(pref, next) {
if (next is SendQrCodeStateInit) {
} else if (next is SendQrCodeStateLoading) {
} else if (next is SendQrCodeStateError) {
SanckbarWidget(
context,
"Gagal Menyimpan Data${jsonEncode(next.message)}",
snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is SendQrCodeStateDone) {
Navigator.pop(context);
// print(jsonEncode(next.model));
if (next.model != 'OK') {
SanckbarWidget(context, "Gagal Menyimpan Data", snackbarType.error);
} else {
SanckbarWidget(
context,
"Berhasil Menyimpan Data, Qr Code Akan Dikirimkan",
snackbarType.success);
}
}
},
);
return AlertDialog(
contentPadding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 24)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12))),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Kirim QR Code',
textAlign: TextAlign.center,
style: Constant.h4_600(context: context)
.copyWith(fontWeight: FontWeight.w700),
),
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: Icon(Icons.close_rounded))
],
),
content: Container(
constraints: BoxConstraints(
minHeight: Constant.getActualY(context: context, y: 100),
maxHeight: Constant.getActualY(context: context, y: 362),
),
height: Constant.getActualY(context: context, y: 320),
child: Column(
// crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: Constant.getActualY(context: context, y: 30),
),
Text(
"Surat Jalan Berhasil Dibuat",
style: Constant.body1_600(context: context)
.copyWith(fontWeight: FontWeight.w600),
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
Container(
width: Constant.getActualX(context: context, x: 263),
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 12)),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
border: Border.all(color: Colors.grey.shade300)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Nomor Surat Jalan",
style: Constant.body3_500(context: context)
.copyWith(color: Constant.textGrey),
),
Text(
orderNumber,
style: Constant.body3_500(context: context)
.copyWith(fontWeight: FontWeight.w600),
)
],
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
// width: Constant.getActualX(context: context, x: 48),
child: RadioMenuButton<String>(
style: ButtonStyle(
backgroundColor: WidgetStateColor.resolveWith(
(states) => Colors.white,
),
shadowColor: WidgetStateColor.resolveWith(
(states) => Colors.white),
overlayColor: WidgetStateColor.resolveWith(
(states) => Colors.white)),
value: 'Y',
groupValue: rb.value,
onChanged: (value) {
if (rb.value == value) {
rb.value = 'N';
} else {
rb.value = value!;
}
},
child: Text(
"Kirim Whatsapp QR Code",
style: Constant.body3_400(context: context),
)),
),
// Text(
// "Kirim Whatsapp QR Code",
// style: Constant.body3_400(context: context),
// )
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 37),
),
ElevatedButton(
onPressed: rb.value == 'Y'
? () {
sendQrCode();
}
: null,
style: ElevatedButton.styleFrom(
minimumSize: Size(
Constant.getActualX(context: context, x: 328),
Constant.getActualY(context: context, y: 64)),
elevation: 5,
backgroundColor: Constant.primaryRed,
shadowColor: Constant.primaryRed,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
child: Container(
margin: EdgeInsets.symmetric(
vertical: Constant.getActualY(context: context, y: 11)),
child: Text(
"Kirim QR Code",
style: Constant.button_large(context: context)
.copyWith(color: Colors.white),
),
)),
// SizedBox(
// height: Constant.getActualY(context: context, y: 12),
// ),
// Row(
// children: [
// Text(
// "Belum menerima QR Code ?",
// style: Constant.caption1_600(context: context)
// .copyWith(color: Constant.textGrey),
// ),
// TextButton(
// onPressed: rb.value == 'Y' ? () {} : null,
// child: Text("Kirim Ulang",
// style: Constant.caption1_600(context: context)
// .copyWith()))
// ],
// )
],
)),
);
}
}

View File

@@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/provider/surat_jalan_provider.dart';
import 'package:mitra_corporate/screen/surat_jalan/form_surat_jalan.dart';
import 'package:mitra_corporate/screen/surat_jalan/surat_jalan_confirmation.dart';
import '../../app/constant.dart';
class DialogSuratJalan extends HookConsumerWidget {
const DialogSuratJalan({super.key});
// const DialogSuratJalan({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final bacaSuratJalanProvider = ref.watch(suratJalanProvider);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 40),
child: SimpleDialog(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12))),
children: [
Padding(
padding: EdgeInsets.fromLTRB(40, 20, 40, 20),
child: Column(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 1332),
height: Constant.getActualY(context: context, y: 62),
child: Text(
bacaSuratJalanProvider == 1
? 'Pengiriman Order Baru'
: "Konfirmasi",
style: Constant.h2_600(context: context)
.copyWith(color: Constant.textBlack)),
),
SizedBox(
height: Constant.getActualY(context: context, y: 10)),
///
if (bacaSuratJalanProvider == 1) FormSuratJalan(),
if (bacaSuratJalanProvider == 2) SuratJalanConfirmation(),
///
],
),
),
]),
);
}
}

View File

@@ -0,0 +1,529 @@
import 'dart:convert';
import 'package:eva_icons_flutter/eva_icons_flutter.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:mitra_corporate/model/create_surat_jalan_model.dart';
import 'package:mitra_corporate/model/delivery_type_model.dart';
import 'package:mitra_corporate/model/destination_model.dart';
import 'package:mitra_corporate/model/order_model.dart';
import 'package:mitra_corporate/model/registration_filter_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/screen/surat_jalan/get_order_list_provider.dart';
import 'package:mitra_corporate/screen/surat_jalan/get_regional_provider.dart';
import 'package:mitra_corporate/screen/surat_jalan/list_pasien_terpilih.dart';
import 'package:mitra_corporate/screen/surat_jalan/table_list_pasien.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../provider/surat_jalan_provider.dart';
import '../../widgets/custom_snackbar_widget.dart';
import '../../widgets/custom_text_field.dart';
class FormSuratJalan extends HookConsumerWidget {
const FormSuratJalan({
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final tempSuratJalan = ref.watch(createSuratJalanProvider);
final auth = ref.watch(authProvider);
final picCtr = useTextEditingController(text: auth?.mUserUsername ?? "");
final noRefCtr =
useTextEditingController(text: tempSuratJalan.order?.noRef);
final suhuBoxCtr =
useTextEditingController(text: tempSuratJalan.order?.temperature);
final noResiCtr =
useTextEditingController(text: tempSuratJalan.order?.noResi);
final noteCtr = useTextEditingController(text: tempSuratJalan.order?.note);
final searchPatient = useTextEditingController(text: "");
final deliveryTypeLoading = useState(false);
final selectedDeliveryType =
useState<DeliveryTypeModel>(DeliveryTypeModel());
final deliveryTypeList = useState<List<DeliveryTypeModel>>(List.empty());
final deliveryTypeKey = useState(1);
final deliveryDate = useTextEditingController(
text: DateFormat('dd-MM-yyyy').format(DateTime.parse(
tempSuratJalan.order?.date ?? DateTime.now().toString())));
final deliveryState = useState(DateTime.parse(
tempSuratJalan.order?.date ?? DateTime.now().toString()));
final getOrderLoading = useState(false);
final orderList = useState<List<OrderModel>>(List.empty());
final fullOrderList = useState<List<OrderModel>>(List.empty());
final selectedOrder = useState<List<OrderModel>>(List.empty());
final destinationList = useState<List<DestinationModel>>(List.empty());
final selectedDestination = useState<DestinationModel>(DestinationModel());
final regionalList = useState<List<RegionalModel>>(List.empty());
final selectedRegional = useState(RegionalModel());
final destinationLoading = useState(false);
final regionalLoading = useState(false);
final destinationKey = useState(1000);
final regionalKey = useState(5000);
final branchKey = useState(10000);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
// deliveryState.value = DateTime.parse(tempSuratJalan.order?.date ?? '');
// ref
// .read(GetDeliveryTypeProvider.notifier)
// .getData(token: auth?.token ?? "");
ref.read(GetOrderListProvider.notifier).getData(
token: auth?.token ?? "",
company_id: auth?.mUserMCompanyID ?? "",
regional_id: auth?.MUserSRegionalID ?? "0");
ref
.read(GetRegionalProvider.notifier)
.getRegional(token: auth?.token ?? "");
});
return () {};
}, []);
// ref.listen(
// GetDeliveryTypeProvider,
// (previous, next) {
// if (next is GetDeliveryTypeStateInit) {
// deliveryTypeLoading.value = true;
// } else if (next is GetDeliveryTypeStateLoading) {
// deliveryTypeLoading.value = true;
// } else if (next is GetDeliveryTypeStateError) {
// SanckbarWidget(context, next.message, snackbarType.error);
// deliveryTypeLoading.value = false;
// } else if (next is GetDeliveryTypeStateDone) {
// // print(jsonEncode(next.model));
// deliveryTypeList.value = next.model;
// next.model.forEach((element) {
// if (element.id == tempSuratJalan.order?.typeId) {
// selectedDeliveryType.value = element;
// }
// });
// deliveryTypeKey.value = deliveryTypeKey.value + 1;
// deliveryTypeLoading.value = false;
// }
// },
// );
ref.listen(
GetOrderListProvider,
(previous, next) {
if (next is GetOrderListStateInit) {
getOrderLoading.value = true;
} else if (next is GetOrderListStateLoading) {
getOrderLoading.value = true;
} else if (next is GetOrderListStateError) {
SanckbarWidget(context, next.message, snackbarType.error);
getOrderLoading.value = false;
Constant.autoLogout(context: context, msg: next.message);
} else if (next is GetOrderListStateDone) {
// print(jsonEncode(next.model));
var a = next.model;
selectedOrder.value = tempSuratJalan.orderDetail ?? [];
for (var element in selectedOrder.value) {
a.removeWhere((i) => element.orderId == i.orderId);
}
orderList.value = a;
fullOrderList.value = a;
getOrderLoading.value = false;
}
},
);
ref.listen(
GetRegionalProvider,
(previous, next) {
if (next is GetRegionalStateInit) {
regionalLoading.value = true;
} else if (next is GetRegionalStateLoading) {
regionalLoading.value = true;
} else if (next is GetRegionalStateError) {
SanckbarWidget(context, next.message, snackbarType.error);
regionalLoading.value = false;
Constant.autoLogout(context: context, msg: next.message);
} else if (next is GetRegionalStateDone) {
// print(jsonEncode(next.model));
regionalList.value = next.model;
for (var element in next.model) {
if (element.regionalId == tempSuratJalan.order?.regionalId) {
selectedRegional.value = element;
destinationList.value = element.branch ?? [];
element.branch?.forEach((i) {
if (i.branchId == tempSuratJalan.order?.destinationId) {
selectedDestination.value = i;
}
});
}
}
regionalKey.value = regionalKey.value + 1;
branchKey.value = branchKey.value + 1;
destinationKey.value = destinationKey.value + 1;
regionalLoading.value = false;
}
},
);
selectOrder(OrderModel e) {
List<OrderModel> temp = orderList.value;
List<OrderModel> fullTemp = fullOrderList.value;
List<OrderModel> tempSlct = selectedOrder.value.toList(growable: true);
temp.removeWhere((element) => element.orderId == e.orderId);
fullTemp.removeWhere((element) => element.orderId == e.orderId);
tempSlct.add(e);
orderList.value = temp;
fullOrderList.value = fullTemp;
selectedOrder.value = tempSlct;
}
unSelectOrder(OrderModel e) {
List<OrderModel> temp = orderList.value.toList(growable: true);
List<OrderModel> tempSlct = selectedOrder.value.toList(growable: true);
List<OrderModel> fullTemp = fullOrderList.value;
tempSlct.removeWhere((element) => element.orderId == e.orderId);
temp.add(e);
fullTemp.add(e);
orderList.value = temp;
fullOrderList.value = fullTemp;
selectedOrder.value = tempSlct;
}
return Column(
children: [
Row(
children: [
// Container(
// width: Constant.getActualX(context: context, x: 382),
// // height: Constant.getActualY(context: context, y: 56),
// child: DropdownMenu<RegionalModel>(
// menuHeight: Constant.getActualY(context: context, y: 300),
// key: ValueKey(regionalKey.value),
// initialSelection: selectedRegional.value,
// trailingIcon: regionalLoading.value
// ? LoadingAnimationWidget.discreteCircle(
// color: Constant.primaryRed, size: 20)
// : null,
// width: Constant.getActualX(context: context, x: 382),
// hintText: "Regional",
// textStyle: Constant.body2_400(context: context),
// inputDecorationTheme: InputDecorationTheme(
// border: OutlineInputBorder(
// borderSide: BorderSide(color: Constant.primaryRed),
// borderRadius: BorderRadius.circular(8),
// )),
// label: const Text(
// "Regional",
// maxLines: 1,
// overflow: TextOverflow.ellipsis,
// ),
// onSelected: (value) {
// // onSelectSaluation(value!);
// if (value!.regionalId !=
// selectedRegional.value.regionalId) {
// print("change");
// selectedRegional.value = value;
// selectedDestination.value = DestinationModel();
// destinationList.value = value.branch ?? [];
// }
// branchKey.value = branchKey.value + 1;
// },
// dropdownMenuEntries: regionalList.value
// .map<DropdownMenuEntry<RegionalModel>>((e) =>
// DropdownMenuEntry(
// value: e, label: e.regionalName ?? ""))
// .toList()),
// ),
// SizedBox(
// width: Constant.getActualX(context: context, x: 24),
// ),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 24),
),
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 318),
// height: Constant.getActualY(context: context, y: 56),
child: DropdownMenu<DestinationModel>(
menuHeight: Constant.getActualY(context: context, y: 300),
key: ValueKey(branchKey.value),
initialSelection: selectedDestination.value,
trailingIcon: regionalLoading.value
? LoadingAnimationWidget.discreteCircle(
color: Constant.primaryRed, size: 20)
: null,
width: Constant.getActualX(context: context, x: 318),
hintText: "Cabang",
textStyle: Constant.body2_400(context: context),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryRed),
borderRadius: BorderRadius.circular(8),
)),
label: const Text(
"Cabang",
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
onSelected: (value) {
// onSelectSaluation(value!);
selectedDestination.value = value!;
},
dropdownMenuEntries: destinationList.value
.map<DropdownMenuEntry<DestinationModel>>((e) =>
DropdownMenuEntry(
value: e, label: e.branchName ?? ""))
.toList()),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
SizedBox(
width: Constant.getActualX(context: context, x: 318),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
controller: picCtr,
hintText: 'Staf PIC',
labelText: "Staf PIC",
disable: false,
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
SizedBox(
width: Constant.getActualX(context: context, x: 318),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
controller: noRefCtr,
hintText: 'Nomor Referensi Surat',
labelText: "Nomor Referensi Surat"),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
SizedBox(
width: Constant.getActualX(context: context, x: 165),
// height: Constant.getActualY(context: context, y: 56),
child: TextField(
controller: deliveryDate,
style: Constant.body2_400(context: context),
decoration: InputDecoration(
suffixIcon: Icon(EvaIcons.calendarOutline),
border: OutlineInputBorder(
borderSide: BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
),
labelText: "Tanggal Kedatangan" //label text of field
),
readOnly: true,
onTap: () async {
DateTime? pickedDate = await showDatePicker(
// locale: Locale("ID"),
cancelText: "Batal",
confirmText: "Simpan",
context: context,
initialDate: deliveryState.value,
firstDate: DateTime(1800),
initialEntryMode: DatePickerEntryMode.calendarOnly,
//DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2100));
if (pickedDate != null) {
print(
pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000
String formattedDate =
DateFormat('dd-MM-yyyy').format(pickedDate);
print(
formattedDate); //formatted date output using intl package => 2021-03-16
deliveryDate.text =
formattedDate; //set output date to TextField value.
deliveryState.value = pickedDate;
} else {}
},
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 24),
),
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 1194),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
controller: noteCtr,
hintText: 'Catatan',
labelText: 'Catatan'),
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 24),
),
Row(
children: [
SizedBox(
width: Constant.getActualX(context: context, x: 585),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
onChange: (value) {
List<OrderModel> temp = fullOrderList.value.toSet().toList();
// List<OrderModel> fullOrderList = orderList.value.toSet().toList();
var searched = temp.where((element) =>
element.patientName!
.toLowerCase()
.contains(value.toString().toLowerCase()) ||
element.orderNumber!
.toLowerCase()
.contains(value.toString().toLowerCase()));
if (value.isNotEmpty) {
orderList.value = searched.toList();
} else {
orderList.value = temp;
}
// jsonEncode(searched.toString());
},
controller: searchPatient,
hintText: 'Nama Pasien, Nomor Registrasi',
labelText: 'Nama Pasien, Nomor Registrasi',
suffixIcon: Icon(EvaIcons.search),
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
Container(
width: Constant.getActualX(context: context, x: 585),
// height: Constant.getActualY(context: context, y: 56),
alignment: Alignment.centerLeft,
child: Text('List Pasien Terpilih',
style: Constant.h4_600(context: context)
.copyWith(color: Constant.textBlack)),
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
Row(
children: [
TableListPasien(
orders: orderList.value,
loading: getOrderLoading.value,
selected: selectOrder,
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
ListPasienTerpilih(
orders: selectedOrder.value,
loading: getOrderLoading.value,
unselect: unSelectOrder,
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
height: Constant.getActualY(context: context, y: 45),
child: OutlinedButton(
style: OutlinedButton.styleFrom(
backgroundColor: Colors.white,
side: BorderSide(color: Colors.grey, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: () {
ref.read(createSuratJalanProvider.notifier).state =
CreateSuratJalanModel();
Navigator.pop(context);
},
child: Text('Batal',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack))),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
Container(
height: Constant.getActualY(context: context, y: 45),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Constant.green),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Constant.green,
side: BorderSide(color: Constant.green, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
onPressed: () {
if (selectedOrder.value.isEmpty) {
SanckbarWidget(context, "Pilih salah satu order",
snackbarType.warning);
return;
}
if (selectedDestination.value.branchId == null) {
SanckbarWidget(context, "Pilih salah satu tujuan",
snackbarType.warning);
return;
}
if (selectedRegional.value.regionalId == null) {
SanckbarWidget(context, "Pilih salah satu regional",
snackbarType.warning);
return;
}
ref.read(createSuratJalanProvider.notifier).state =
CreateSuratJalanModel(
order: Order(
branchCode:
selectedDestination.value.branchCode,
companyId: auth?.mUserMCompanyID,
date: deliveryState.value.toString(),
regionalId: selectedRegional.value.regionalId,
regionalName:
selectedRegional.value.regionalName,
destinationName:
selectedDestination.value.branchName,
destinationId:
selectedDestination.value.branchId,
noRef: noRefCtr.text,
noResi: noResiCtr.text,
note: noteCtr.text,
staffId: auth?.mUserID,
typeName: selectedDeliveryType.value.name,
temperature: suhuBoxCtr.text,
typeId: selectedDeliveryType.value.id),
orderDetail: selectedOrder.value,
token: auth?.token);
ref.read(suratJalanProvider.state).update((state) => 2);
print(jsonEncode(tempSuratJalan));
// kamu liat ntar value nya jadi berapa
// print();
},
child: Text('Selanjutnya',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textWhite))),
),
],
)
],
);
}
}

View File

@@ -0,0 +1,65 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/delivery_type_model.dart';
import 'package:mitra_corporate/repository/surat_jalan_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class GetDeliveryTypeState extends Equatable {
final DateTime date;
const GetDeliveryTypeState(this.date);
@override
List<Object?> get props => [date];
}
class GetDeliveryTypeStateInit extends GetDeliveryTypeState {
GetDeliveryTypeStateInit() : super(DateTime.now());
}
class GetDeliveryTypeStateLoading extends GetDeliveryTypeState {
GetDeliveryTypeStateLoading() : super(DateTime.now());
}
class GetDeliveryTypeStateError extends GetDeliveryTypeState {
final String message;
GetDeliveryTypeStateError({
required this.message,
}) : super(DateTime.now());
}
class GetDeliveryTypeStateDone extends GetDeliveryTypeState {
final List<DeliveryTypeModel> model;
GetDeliveryTypeStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class GetDeliveryTypeNotifier extends StateNotifier<GetDeliveryTypeState> {
final Ref ref;
GetDeliveryTypeNotifier({
required this.ref,
}) : super(GetDeliveryTypeStateInit());
void getData({required String token}) async {
try {
state = GetDeliveryTypeStateLoading();
final dio = ref.read(dioProvider);
final resp =
await SuratJalanRepository(dio: dio).getDeliveryType(token: token);
state = GetDeliveryTypeStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = GetDeliveryTypeStateError(message: e.message.toString());
} else {
state = GetDeliveryTypeStateError(message: e.toString());
}
}
}
}
//provider
final GetDeliveryTypeProvider =
StateNotifierProvider<GetDeliveryTypeNotifier, GetDeliveryTypeState>(
(ref) => GetDeliveryTypeNotifier(ref: ref));

View File

@@ -0,0 +1,65 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/repository/surat_jalan_repository.dart';
import '../../model/destination_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class GetDestinationState extends Equatable {
final DateTime date;
const GetDestinationState(this.date);
@override
List<Object?> get props => [date];
}
class GetDestinationStateInit extends GetDestinationState {
GetDestinationStateInit() : super(DateTime.now());
}
class GetDestinationStateLoading extends GetDestinationState {
GetDestinationStateLoading() : super(DateTime.now());
}
class GetDestinationStateError extends GetDestinationState {
final String message;
GetDestinationStateError({
required this.message,
}) : super(DateTime.now());
}
class GetDestinationStateDone extends GetDestinationState {
final List<DestinationModel> model;
GetDestinationStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class GetDestinationNotifier extends StateNotifier<GetDestinationState> {
final Ref ref;
GetDestinationNotifier({
required this.ref,
}) : super(GetDestinationStateInit());
void getData({required String token}) async {
try {
state = GetDestinationStateLoading();
final dio = ref.read(dioProvider);
final resp =
await SuratJalanRepository(dio: dio).getDestination(token: token);
state = GetDestinationStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = GetDestinationStateError(message: e.message.toString());
} else {
state = GetDestinationStateError(message: e.toString());
}
}
}
}
//provider
final GetDestinationProvider =
StateNotifierProvider<GetDestinationNotifier, GetDestinationState>(
(ref) => GetDestinationNotifier(ref: ref));

View File

@@ -0,0 +1,68 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/order_model.dart';
import 'package:mitra_corporate/repository/surat_jalan_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class GetOrderListState extends Equatable {
final DateTime date;
const GetOrderListState(this.date);
@override
List<Object?> get props => [date];
}
class GetOrderListStateInit extends GetOrderListState {
GetOrderListStateInit() : super(DateTime.now());
}
class GetOrderListStateLoading extends GetOrderListState {
GetOrderListStateLoading() : super(DateTime.now());
}
class GetOrderListStateError extends GetOrderListState {
final String message;
GetOrderListStateError({
required this.message,
}) : super(DateTime.now());
}
class GetOrderListStateDone extends GetOrderListState {
final List<OrderModel> model;
GetOrderListStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class GetOrderListNotifier extends StateNotifier<GetOrderListState> {
final Ref ref;
GetOrderListNotifier({
required this.ref,
}) : super(GetOrderListStateInit());
void getData(
{required String token,
required String company_id,
required String regional_id}) async {
try {
state = GetOrderListStateLoading();
final dio = ref.read(dioProvider);
final resp = await SuratJalanRepository(dio: dio).getOrder(
token: token, company_id: company_id, regional_id: regional_id);
state = GetOrderListStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = GetOrderListStateError(message: e.message.toString());
} else {
state = GetOrderListStateError(message: e.toString());
}
}
}
}
//provider
final GetOrderListProvider =
StateNotifierProvider<GetOrderListNotifier, GetOrderListState>(
(ref) => GetOrderListNotifier(ref: ref));

View File

@@ -0,0 +1,66 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/registration_filter_model.dart';
import 'package:mitra_corporate/repository/surat_jalan_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class GetRegionalState extends Equatable {
final DateTime date;
const GetRegionalState(this.date);
@override
List<Object?> get props => [date];
}
class GetRegionalStateInit extends GetRegionalState {
GetRegionalStateInit() : super(DateTime.now());
}
class GetRegionalStateLoading extends GetRegionalState {
GetRegionalStateLoading() : super(DateTime.now());
}
class GetRegionalStateError extends GetRegionalState {
final String message;
GetRegionalStateError({
required this.message,
}) : super(DateTime.now());
}
class GetRegionalStateDone extends GetRegionalState {
final List<RegionalModel> model;
GetRegionalStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class GetRegionalNotifier extends StateNotifier<GetRegionalState> {
final Ref ref;
GetRegionalNotifier({
required this.ref,
}) : super(GetRegionalStateInit());
void getRegional({required String token}) async {
try {
state = GetRegionalStateLoading();
final dio = ref.read(dioProvider);
final resp =
await SuratJalanRepository(dio: dio).getRegional(token: token);
state = GetRegionalStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = GetRegionalStateError(message: e.message.toString());
} else {
state = GetRegionalStateError(message: e.toString());
}
}
}
}
//provider
final GetRegionalProvider =
StateNotifierProvider<GetRegionalNotifier, GetRegionalState>(
(ref) => GetRegionalNotifier(ref: ref));

View File

@@ -0,0 +1,66 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/surat_jalan_detail_model.dart';
import 'package:mitra_corporate/repository/surat_jalan_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class GetSuratJalanDetailState extends Equatable {
final DateTime date;
const GetSuratJalanDetailState(this.date);
@override
List<Object?> get props => [date];
}
class GetSuratJalanDetailStateInit extends GetSuratJalanDetailState {
GetSuratJalanDetailStateInit() : super(DateTime.now());
}
class GetSuratJalanDetailStateLoading extends GetSuratJalanDetailState {
GetSuratJalanDetailStateLoading() : super(DateTime.now());
}
class GetSuratJalanDetailStateError extends GetSuratJalanDetailState {
final String message;
GetSuratJalanDetailStateError({
required this.message,
}) : super(DateTime.now());
}
class GetSuratJalanDetailStateDone extends GetSuratJalanDetailState {
final List<SuratJalanDetailModel> model;
GetSuratJalanDetailStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class GetSuratJalanDetailNotifier
extends StateNotifier<GetSuratJalanDetailState> {
final Ref ref;
GetSuratJalanDetailNotifier({
required this.ref,
}) : super(GetSuratJalanDetailStateInit());
void getData({required String token, required String deliveryID}) async {
try {
state = GetSuratJalanDetailStateLoading();
final dio = ref.read(dioProvider);
final resp = await SuratJalanRepository(dio: dio)
.getSuratJalanSetail(token: token, deliveryID: deliveryID);
state = GetSuratJalanDetailStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = GetSuratJalanDetailStateError(message: e.message.toString());
} else {
state = GetSuratJalanDetailStateError(message: e.toString());
}
}
}
}
//provider
final GetSuratJalanDetailProvider = StateNotifierProvider<
GetSuratJalanDetailNotifier,
GetSuratJalanDetailState>((ref) => GetSuratJalanDetailNotifier(ref: ref));

View File

@@ -0,0 +1,81 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/model/surat_jalan_model.dart';
import 'package:mitra_corporate/repository/surat_jalan_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class GetSuratJalanListState extends Equatable {
final DateTime date;
const GetSuratJalanListState(this.date);
@override
List<Object?> get props => [date];
}
class GetSuratJalanListStateInit extends GetSuratJalanListState {
GetSuratJalanListStateInit() : super(DateTime.now());
}
class GetSuratJalanListStateLoading extends GetSuratJalanListState {
GetSuratJalanListStateLoading() : super(DateTime.now());
}
class GetSuratJalanListStateError extends GetSuratJalanListState {
final String message;
GetSuratJalanListStateError({
required this.message,
}) : super(DateTime.now());
}
class GetSuratJalanListStateDone extends GetSuratJalanListState {
final SearchSuratJalanModel model;
GetSuratJalanListStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class GetSuratJalanListNotifier extends StateNotifier<GetSuratJalanListState> {
final Ref ref;
GetSuratJalanListNotifier({
required this.ref,
}) : super(GetSuratJalanListStateInit());
void getData({
required String token,
required String company_id,
required String rpp,
required String keyword,
required String page,
required String sd,
required String ed,
required String dateType,
}) async {
try {
state = GetSuratJalanListStateLoading();
final dio = ref.read(dioProvider);
final resp = await SuratJalanRepository(dio: dio).getSuratJalan(
token: token,
company_id: company_id,
endDate: ed,
startDate: sd,
rpp: rpp,
keyword: keyword,
dateType: dateType,
page: page);
state = GetSuratJalanListStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = GetSuratJalanListStateError(message: e.message.toString());
} else {
state = GetSuratJalanListStateError(message: e.toString());
}
}
}
}
//provider
final GetSuratJalanListProvider =
StateNotifierProvider<GetSuratJalanListNotifier, GetSuratJalanListState>(
(ref) => GetSuratJalanListNotifier(ref: ref));

View File

@@ -0,0 +1,247 @@
import 'dart:ui';
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/model/order_model.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
class ListPasienTerpilih extends HookConsumerWidget {
const ListPasienTerpilih(
{super.key,
required this.orders,
required this.loading,
required this.unselect});
final List<OrderModel> orders;
final bool loading;
final Function unselect;
@override
Widget build(BuildContext context, WidgetRef ref) {
final scrollCtr = useScrollController();
return Material(
child: Container(
width: Constant.getActualX(context: context, x: 585),
height: Constant.getActualY(context: context, y: 410),
color: Colors.white,
child: Column(
children: [
Row(
children: [
Container(
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 12)),
alignment: Alignment.centerLeft,
width: Constant.getActualX(context: context, x: 180),
height: Constant.getActualY(context: context, y: 64),
color: Constant.grey_200,
child: Text('No Registrasi / Nama',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
Container(
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 12)),
alignment: Alignment.centerLeft,
width: Constant.getActualX(context: context, x: 325),
height: Constant.getActualY(context: context, y: 64),
color: Constant.grey_200,
child: Text('Pemeriksaan',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
// Container(
// padding: EdgeInsets.only(
// left: Constant.getActualX(context: context, x: 12)),
// alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 200),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
// child: Text('Jenis Specimen',
// style: Constant.body3_600(context: context)
// .copyWith(color: Constant.textGrey)),
// ),
Container(
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 12)),
alignment: Alignment.centerLeft,
width: Constant.getActualX(context: context, x: 80),
height: Constant.getActualY(context: context, y: 64),
color: Constant.grey_200,
child: Text('Aksi',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 340),
// color: Colors.red,
child: loading
? Center(
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 40),
)
: Scrollbar(
thickness: 5,
interactive: true,
thumbVisibility: true,
trackVisibility: true,
scrollbarOrientation: ScrollbarOrientation.right,
controller: scrollCtr,
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(context)
.copyWith(dragDevices: {
PointerDeviceKind.mouse,
PointerDeviceKind.touch,
PointerDeviceKind.trackpad,
PointerDeviceKind.stylus,
PointerDeviceKind.unknown
}),
child: ListView(
controller: scrollCtr,
scrollDirection: Axis.vertical,
children: orders
.asMap()
.entries
.map(
(e) => Container(
padding: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 10),
bottom: Constant.getActualY(
context: context, y: 10)),
color: e.key.isOdd
? Constant.primaryBlue
.withOpacity(0.05)
: Colors.white,
margin: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 5),
bottom: Constant.getActualY(
context: context, y: 5)),
child: Row(
children: [
Container(
padding: EdgeInsets.only(
left: Constant.getActualX(
context: context, x: 12)),
alignment: Alignment.centerLeft,
width: Constant.getActualX(
context: context, x: 180),
height: Constant.getActualY(
context: context, y: 64),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(e.value.orderNumber ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color: Constant
.textBlack)),
Text(e.value.patientName ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color: Constant
.textBlack))
],
),
),
// Container(
// padding: EdgeInsets.only(
// left: Constant.getActualX(
// context: context, x: 12)),
// alignment: Alignment.centerLeft,
// width: Constant.getActualX(
// context: context, x: 195),
// height: Constant.getActualY(
// context: context, y: 64),
// color: Colors.white,
// child: Text(e.patientName ?? "",
// style: Constant.body3_600(
// context: context)
// .copyWith(
// color: Constant
// .textBlack)),
// ),
SizedBox(
width: Constant.getActualX(
context: context, x: 325),
child: Wrap(
alignment: WrapAlignment.start,
spacing: 10,
children: [
if (e.value.tests!.isNotEmpty)
...e.value.tests!
.map((k) => Container(
margin: EdgeInsets.only(
bottom: Constant
.getActualX(
context:
context,
x: 10)),
child: Chip(
shape:
RoundedRectangleBorder(
borderRadius: BorderRadius
.all(Radius
.circular(
6)),
),
// backgroundColor:
// Constant
// .blue_016,
label: Text(
'$k '.replaceAll(
' ',
'\u00A0'),
overflow:
TextOverflow
.ellipsis,
style: Constant.caption2_600(
context:
context)
.copyWith(
color:
Constant.textBlack)),
),
))
],
),
),
Container(
alignment: Alignment.centerLeft,
width: Constant.getActualX(
context: context, x: 80),
child: IconButton(
onPressed: () {
// print(e.orderNumber);
unselect(e.value);
},
icon: Icon(
EvaIcons.arrowCircleLeft,
size: 24,
color:
Constant.primaryRed)),
)
],
),
),
)
.toList(),
),
),
),
),
],
)
//
));
}
}

View File

@@ -0,0 +1,65 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/repository/surat_jalan_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class SendQrCodeState extends Equatable {
final DateTime date;
const SendQrCodeState(this.date);
@override
List<Object?> get props => [date];
}
class SendQrCodeStateInit extends SendQrCodeState {
SendQrCodeStateInit() : super(DateTime.now());
}
class SendQrCodeStateLoading extends SendQrCodeState {
SendQrCodeStateLoading() : super(DateTime.now());
}
class SendQrCodeStateError extends SendQrCodeState {
final String message;
SendQrCodeStateError({
required this.message,
}) : super(DateTime.now());
}
class SendQrCodeStateDone extends SendQrCodeState {
final String model;
SendQrCodeStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class SendQrCodeNotifier extends StateNotifier<SendQrCodeState> {
final Ref ref;
SendQrCodeNotifier({
required this.ref,
}) : super(SendQrCodeStateInit());
void senQrCode(
{required String token, required List<String> arrOrderID}) async {
try {
state = SendQrCodeStateLoading();
final dio = ref.read(dioProvider);
final resp = await SuratJalanRepository(dio: dio)
.sendQrCode(token: token, arrOrderID: arrOrderID);
state = SendQrCodeStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = SendQrCodeStateError(message: e.message.toString());
} else {
state = SendQrCodeStateError(message: e.toString());
}
}
}
}
//provider
final SendQrCodeProvider =
StateNotifierProvider<SendQrCodeNotifier, SendQrCodeState>(
(ref) => SendQrCodeNotifier(ref: ref));

View File

@@ -0,0 +1,65 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mitra_corporate/repository/surat_jalan_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class SendSuratJalanState extends Equatable {
final DateTime date;
const SendSuratJalanState(this.date);
@override
List<Object?> get props => [date];
}
class SendSuratJalanStateInit extends SendSuratJalanState {
SendSuratJalanStateInit() : super(DateTime.now());
}
class SendSuratJalanStateLoading extends SendSuratJalanState {
SendSuratJalanStateLoading() : super(DateTime.now());
}
class SendSuratJalanStateError extends SendSuratJalanState {
final String message;
SendSuratJalanStateError({
required this.message,
}) : super(DateTime.now());
}
class SendSuratJalanStateDone extends SendSuratJalanState {
final String number;
SendSuratJalanStateDone({
required this.number,
}) : super(DateTime.now());
}
//notifier
class SendSuratJalanNotifier extends StateNotifier<SendSuratJalanState> {
final Ref ref;
SendSuratJalanNotifier({
required this.ref,
}) : super(SendSuratJalanStateInit());
void Send({required String token, required String deliveryID}) async {
try {
state = SendSuratJalanStateLoading();
final dio = ref.read(dioProvider);
final resp = await SuratJalanRepository(dio: dio)
.sendSuratJalan(token: token, deliveryID: deliveryID);
state = SendSuratJalanStateDone(number: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = SendSuratJalanStateError(message: e.message.toString());
} else {
state = SendSuratJalanStateError(message: e.toString());
}
}
}
}
//provider
final SendSuratJalanProvider =
StateNotifierProvider<SendSuratJalanNotifier, SendSuratJalanState>(
(ref) => SendSuratJalanNotifier(ref: ref));

View File

@@ -0,0 +1,421 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';
import 'package:mitra_corporate/app/constant.dart';
import 'package:mitra_corporate/model/create_surat_jalan_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/provider/surat_jalan_provider.dart';
import 'package:mitra_corporate/screen/surat_jalan/create_surat_jalan_provider.dart';
import 'package:mitra_corporate/screen/surat_jalan/dialog_send_qr.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../widgets/custom_snackbar_widget.dart';
class SuratJalanConfirmation extends HookConsumerWidget {
const SuratJalanConfirmation({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final tempSuratjalan = ref.watch(createSuratJalanProvider);
final auth = ref.watch(authProvider);
final date = useState("");
final loading = useState(false);
final number = useState("");
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
DateTime now = DateTime.parse(tempSuratjalan.order!.date!);
// DateTime now = DateTime.now();
initializeDateFormatting('id', '').then((_) {
date.value = DateFormat('EEEE, d MMMM yyyy', "id").format(now);
print(DateFormat('EEEE, d MMMM yyyy', "id").format(now));
});
});
return () {};
}, []);
addOrder() {
// print(jsonEncode(tempSuratjalan));
// return;
ref.read(CreateSuratJalanProvider.notifier).addOrder(prm: tempSuratjalan);
}
ref.listen(
CreateSuratJalanProvider,
(previous, next) {
if (next is CreateSuratJalanStateInit) {
loading.value = true;
} else if (next is CreateSuratJalanStateLoading) {
loading.value = true;
} else if (next is CreateSuratJalanStateError) {
SanckbarWidget(context, next.message, snackbarType.error);
loading.value = false;
Constant.autoLogout(context: context, msg: next.message);
} else if (next is CreateSuratJalanStateDone) {
// print(jsonEncode(next.model));
number.value = next.number;
SanckbarWidget(
context,
"Pengiriman order berhasil di buat ${next.number}",
snackbarType.success);
List<String> arrOrderID = List.empty(growable: true);
for (var element in tempSuratjalan.orderDetail!) {
arrOrderID.add(element.orderId!);
}
Navigator.pop(context);
ref.read(createSuratJalanProvider.notifier).state =
CreateSuratJalanModel();
ref.read(suratJalanProvider.state).update((state) => 1);
showDialog<String>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) => DialogSendQr(
arrOrderID: arrOrderID,
orderNumber: next.number,
),
);
loading.value = false;
}
},
);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Anda yakin dengan pengiriman order berikut ?",
style: Constant.h4_600(context: context),
),
SizedBox(
height: Constant.getActualY(context: context, y: 28),
),
Row(
children: [
Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 24)),
child: Text(
"Regional",
style: Constant.body1_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 9,
child: Text(
tempSuratjalan.order?.regionalName ?? "",
style: Constant.body1_600(context: context),
))
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
Row(
children: [
Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 24)),
child: Text(
"Cabang",
style: Constant.body1_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 9,
child: Text(
tempSuratjalan.order?.destinationName ?? "",
style: Constant.body1_600(context: context),
))
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
Row(
children: [
Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 24)),
child: Text(
"Staff PIC",
style: Constant.body1_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 9,
child: Text(
auth?.mUserUsername ?? "",
style: Constant.body1_600(context: context),
))
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
Row(
children: [
Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 24)),
child: Text(
"Nomor Referensi",
style: Constant.body1_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 9,
child: Text(
tempSuratjalan.order?.noRef ?? "",
style: Constant.body1_600(context: context),
))
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
Row(
children: [
Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 24)),
child: Text(
"Tanggal Kirim Order",
style: Constant.body1_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 9,
child: Text(
date.value,
style: Constant.body1_600(context: context),
))
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
Row(
children: [
Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 24)),
child: Text(
"Catatan",
style: Constant.body1_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 9,
child: Text(
tempSuratjalan.order?.note ?? "",
style: Constant.body1_600(context: context),
))
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 28),
),
SizedBox(
height: Constant.getActualY(context: context, y: 64),
child: Text(
"List Pasien Terpilih",
style: Constant.h4_600(context: context),
),
),
Container(
height: Constant.getActualY(context: context, y: 64),
decoration: BoxDecoration(
color: Constant.grey_200, borderRadius: BorderRadius.circular(8)),
child: Row(
children: [
Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 24)),
child: Text(
"Nomor Registrasi",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 24)),
child: Text(
"Nama Pasien",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
Expanded(
flex: 6,
child: Container(
margin: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 24)),
child: Text(
"Pemeriksaan",
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey),
),
)),
],
),
),
...tempSuratjalan.orderDetail!.map((e) => Container(
constraints: BoxConstraints(
minHeight: Constant.getActualX(context: context, x: 64)),
margin: EdgeInsets.only(
bottom: Constant.getActualX(context: context, x: 10)),
child: Row(
children: [
Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 24)),
child: Text(
e.orderNumber ?? "",
style: Constant.body3_600(context: context),
),
)),
Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 24)),
child: Text(
e.patientName ?? "",
style: Constant.body3_600(context: context),
),
)),
Expanded(
flex: 6,
child: Container(
margin: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 24)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Wrap(
children: [
...e.tests!.map((i) => Container(
margin: EdgeInsets.only(
top: Constant.getActualX(
context: context, x: 10),
right: Constant.getActualX(
context: context, x: 10),
bottom: Constant.getActualX(
context: context, x: 10)),
child: Chip(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(6)),
),
// backgroundColor:
// Constant.grey_200,
label: Text(
'$i '.replaceAll(' ', '\u00A0'),
overflow: TextOverflow.ellipsis,
style: Constant.caption1_600(
context: context)
.copyWith(
color: Constant.textBlack)),
),
)),
],
),
],
),
)),
],
),
)),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
height: Constant.getActualY(context: context, y: 45),
child: OutlinedButton(
style: OutlinedButton.styleFrom(
backgroundColor: Colors.white,
side: BorderSide(color: Colors.grey, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8))),
onPressed: !loading.value
? () {
// ref.read(createSuratJalanProvider.notifier).state =
// CreateSuratJalanModel();
ref
.read(suratJalanProvider.state)
.update((state) => 1);
// Navigator.pop(context);
}
: null,
child: loading.value
? LoadingAnimationWidget.staggeredDotsWave(
color: Constant.green, size: 20)
: Text('Batal',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textBlack))),
),
SizedBox(width: Constant.getActualX(context: context, x: 24)),
Container(
height: Constant.getActualY(context: context, y: 45),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Constant.green),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Constant.green,
side: BorderSide(color: Constant.green, width: 2),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
onPressed: !loading.value
? () {
addOrder();
}
: null,
child: loading.value
? LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white, size: 20)
: Text('Simpan',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textWhite))),
),
],
)
],
);
}
}

View File

@@ -0,0 +1,83 @@
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/provider/menu_provider.dart';
import 'package:mitra_corporate/screen/surat_jalan/table_detail_surat_jalan.dart';
import 'package:mitra_corporate/widgets/header.dart';
import '../../app/constant.dart';
import '../../provider/surat_jalan_provider.dart';
class SuratJalanDetailScreen extends HookConsumerWidget {
const SuratJalanDetailScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final sjNumber = ref.watch(suratJalanNumber);
return Material(
child: Column(
children: [
Header(),
Container(
child: Padding(
padding: const EdgeInsets.all(32.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
IconButton(
onPressed: () {
ref.read(currentMenuProvider.notifier).state = 3;
},
icon: Icon(EvaIcons.arrowBackOutline)),
Text('Detail Surat Jalan',
style: Constant.h4_600(context: context)
.copyWith(color: Constant.textBlack)),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 40),
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: Colors.white,
),
padding: EdgeInsets.symmetric(
horizontal:
Constant.getActualY(context: context, y: 24),
vertical: Constant.getActualY(context: context, y: 24)),
child: Column(
children: [
Row(children: [
Text('Nomor Surat Jalan',
style: Constant.body1_600(context: context)
.copyWith(color: Constant.textBlack)),
SizedBox(
width:
Constant.getActualX(context: context, x: 8)),
Text(sjNumber,
style: Constant.body1_600(context: context)
.copyWith(color: Constant.primaryRed)),
]),
SizedBox(
height:
Constant.getActualY(context: context, y: 24)),
// SizedBox(
// height: Constant.getActualY(context: context, y: 24)),
TableDetailSuratJalan()
],
),
),
],
),
),
)
],
),
);
}
}

View File

@@ -0,0 +1,280 @@
import 'package:mitra_corporate/model/surat_jalan_model.dart';
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/model/create_surat_jalan_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/provider/surat_jalan_provider.dart';
import 'package:mitra_corporate/screen/surat_jalan/dialog_surat_jalan.dart';
import 'package:mitra_corporate/screen/surat_jalan/table_surat_jalan.dart';
import 'package:mitra_corporate/widgets/header.dart';
import 'package:intl/intl.dart';
import '../../app/constant.dart';
import '../../provider/menu_provider.dart';
import '../../widgets/custom_text_field.dart';
class SuratJalanScreen extends HookConsumerWidget {
const SuratJalanScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final auth = ref.watch(authProvider);
final selectedDateType = ref.watch(sjDateType);
final isExpand = ref.watch(sideBarExpandProvider);
final searchCtr = useTextEditingController(text: "");
final startDateCtr = useTextEditingController(
text: DateFormat('dd-MM-yyyy').format(ref.watch(sjStartDateProvider)));
final startDateState = useState(ref.watch(sjStartDateProvider));
final endDateCtr = useTextEditingController(
text: DateFormat('dd-MM-yyyy').format(ref.watch(sjEndDateProvider)));
final endDateState = useState(ref.watch(sjEndDateProvider));
final dateFilterKey = useState(1);
final selectedDateFilter = useState(selectedDateType);
useEffect(() {
// ref.read(sjDateType.notifier).state = dateFilter.first;
selectedDateFilter.value = selectedDateType;
dateFilterKey.value = dateFilterKey.value + 1;
return null;
}, [isExpand]);
// useEffect(() {
// selectedDateFilter.value = selectedDateType;
// print(selectedDateType.name);
// }, [selectedDateType]);
return Material(
child: Column(
children: [
Header(),
Padding(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 32),
vertical: Constant.getActualY(context: context, y: 32)),
child: Column(
children: [
Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 1079),
height: Constant.getActualY(context: context, y: 40),
child: Text('Kirim Order',
style: Constant.h3_400(context: context)
.copyWith(color: Constant.textBlack)),
),
SizedBox(height: Constant.getActualY(context: context, y: 42)),
Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 24),
vertical: Constant.getActualY(context: context, y: 32)),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color: Colors.white),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(child: LayoutBuilder(builder:
(BuildContext context,
BoxConstraints constraints) {
return DropdownMenu<dateFilterModel>(
key: ValueKey(dateFilterKey.value),
hintText: "Tipe Tanggal",
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(
borderSide: BorderSide(
color: Constant.primaryRed),
borderRadius: BorderRadius.circular(8))),
menuHeight:
Constant.getActualY(context: context, y: 300),
// width: Constant.getActualX(context: context, x: 150),
width: constraints.maxWidth,
textStyle: Constant.body2_400(context: context),
label: const Text(
"Tipe Tanggal",
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
initialSelection: selectedDateFilter.value,
onSelected: (dateFilterModel? value) {
// This is called when the user selects an item.
// print(value!.name);
ref.read(sjDateType.notifier).state = value!;
selectedDateFilter.value = value;
},
dropdownMenuEntries: Constant.dateFilter
.map<DropdownMenuEntry<dateFilterModel>>(
(dateFilterModel value) {
return DropdownMenuEntry<dateFilterModel>(
value: value, label: value.name);
}).toList(),
);
})),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
Expanded(
child: TextField(
style: Constant.body1_600(context: context),
controller: startDateCtr,
decoration: InputDecoration(
suffixIcon: Icon(EvaIcons.calendar),
border: OutlineInputBorder(
borderSide:
BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
),
labelStyle:
Constant.body1_600(context: context),
labelText: "Tanggal Awal" //label text of field
),
readOnly: true,
onTap: () async {
DateTime? pickedDate = await showDatePicker(
// locale: Locale("id"),
confirmText: "OK",
cancelText: "Batal",
context: context,
initialDate: startDateState.value,
firstDate: DateTime(1800),
initialEntryMode:
DatePickerEntryMode.calendarOnly,
//DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2100));
if (pickedDate != null) {
print(
pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000
String formattedDate =
DateFormat('dd-MM-yyyy').format(pickedDate);
print(
formattedDate); //formatted date output using intl package => 2021-03-16
startDateCtr.text =
formattedDate; //set output date to TextField value.
startDateState.value = pickedDate;
ref.read(sjStartDateProvider.notifier).state =
pickedDate;
} else {}
},
)),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
Expanded(
child: TextField(
style: Constant.body1_600(context: context),
controller: endDateCtr,
decoration: InputDecoration(
suffixIcon: Icon(EvaIcons.calendar),
border: OutlineInputBorder(
borderSide:
BorderSide(color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
),
labelStyle:
Constant.body1_600(context: context),
labelText: "Tanggal Akhir" //label text of field
),
readOnly: true,
onTap: () async {
DateTime? pickedDate = await showDatePicker(
// locale: Locale("id"),
confirmText: "OK",
cancelText: "Batal",
context: context,
initialDate: endDateState.value,
firstDate: DateTime(1800),
initialEntryMode:
DatePickerEntryMode.calendarOnly,
//DateTime.now() - not to allow to choose before today.
lastDate: DateTime(2100));
if (pickedDate != null) {
print(
pickedDate); //pickedDate output format => 2021-03-10 00:00:00.000
String formattedDate =
DateFormat('dd-MM-yyyy').format(pickedDate);
print(
formattedDate); //formatted date output using intl package => 2021-03-16
endDateCtr.text =
formattedDate; //set output date to TextField value.
endDateState.value = pickedDate;
ref.read(sjEndDateProvider.notifier).state =
pickedDate;
} else {}
},
)),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
Expanded(
// width: Constant.getActualX(context: context, x: 408),
// height: Constant.getActualY(context: context, y: 56),
child: CustomTextField(
onChange: (value) {
ref
.read(suratJalankeywordProvider.notifier)
.state = value;
},
controller: searchCtr,
isPassword: false,
hintText: "Cari No/Tujuan/Staff PIC",
labelText: "Cari No/Tujuan/Staff PIC",
suffixIcon: Icon(EvaIcons.search),
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
Container(
// width: Constant.getActualX(context: context, x: 171),
height:
Constant.getActualY(context: context, y: 56),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Constant.primaryRed),
child: ElevatedButton.icon(
label: Text('Kirim order Baru',
style: Constant.button_large(context: context)
.copyWith(color: Constant.textWhite)),
icon: Icon(EvaIcons.plus,
color: Colors.white, size: 20.0),
onPressed: () {
ref
.read(createSuratJalanProvider.notifier)
.state =
CreateSuratJalanModel(
order: Order(
regionalId:
auth?.MUserSRegionalID ?? ""));
showDialog(
context: context,
barrierDismissible: false,
builder: ((context) => DialogSuratJalan()));
},
style: ElevatedButton.styleFrom(
shadowColor: Colors.transparent),
),
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 24)),
TableSuratJalan()
],
),
),
],
),
)
],
),
);
}
}

View File

@@ -0,0 +1,587 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/model/surat_jalan_detail_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/screen/surat_jalan/get_surat_jalan_detail_provider.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../provider/surat_jalan_provider.dart';
import '../../widgets/custom_snackbar_widget.dart';
class TableDetailSuratJalan extends HookConsumerWidget {
const TableDetailSuratJalan({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final id = ref.watch(suratJalanID);
final auth = ref.watch(authProvider);
final loading = useState(false);
final data = useState<List<SuratJalanDetailModel>>(List.empty());
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
ref
.read(GetSuratJalanDetailProvider.notifier)
.getData(token: auth?.token ?? "", deliveryID: id);
});
return () {};
}, [id]);
ref.listen(
GetSuratJalanDetailProvider,
(pref, next) {
if (next is GetSuratJalanDetailStateInit) {
loading.value = true;
} else if (next is GetSuratJalanDetailStateLoading) {
loading.value = true;
} else if (next is GetSuratJalanDetailStateError) {
loading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is GetSuratJalanDetailStateDone) {
// print(jsonEncode(next.model));
data.value = next.model;
loading.value = false;
}
},
);
return Material(
child: Column(
children: [
Container(
height: Constant.getActualY(context: context, y: 64),
decoration: BoxDecoration(
color: Constant.grey_200,
border: Border(bottom: BorderSide(color: Colors.grey))),
child: Row(
children: [
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 100),
height: Constant.getActualY(context: context, y: 64),
color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 20, right: 20),
child: Text('Tanggal',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 115),
height: Constant.getActualY(context: context, y: 64),
color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 20, right: 20),
child: Text('No Lab',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 196),
height: Constant.getActualY(context: context, y: 64),
color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 20, right: 20),
child: Text('Nama Pasien',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
// Expanded(
// flex: 1,
// child: Container(
// alignment: Alignment.centerLeft,
// // width: Constant.getActualX(context: context, x: 100),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
// child: Padding(
// padding: const EdgeInsets.only(
// top: 12, bottom: 12, left: 20, right: 20),
// child: Text('Dikirim',
// overflow: TextOverflow.ellipsis,
// style: Constant.body3_600(context: context)
// .copyWith(color: Constant.textGrey)),
// ),
// ),
// ),
// Expanded(
// flex: 1,
// child: Container(
// alignment: Alignment.centerLeft,
// // width: Constant.getActualX(context: context, x: 100),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
// child: Padding(
// padding: const EdgeInsets.only(
// top: 12, bottom: 12, left: 20, right: 20),
// child: Text('Diterima',
// overflow: TextOverflow.ellipsis,
// style: Constant.body3_600(context: context)
// .copyWith(color: Constant.textGrey)),
// ),
// ),
// ),
// Expanded(
// flex: 1,
// child: Container(
// alignment: Alignment.centerLeft,
// // width: Constant.getActualX(context: context, x: 100),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
// child: Padding(
// padding: const EdgeInsets.only(
// top: 12, bottom: 12, left: 20, right: 20),
// child: Text('Ditolak',
// overflow: TextOverflow.ellipsis,
// style: Constant.body3_600(context: context)
// .copyWith(color: Constant.textGrey)),
// ),
// ),
// ),
// Expanded(
// flex: 1,
// child: Container(
// alignment: Alignment.centerLeft,
// // width: Constant.getActualX(context: context, x: 100),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
// child: Padding(
// padding: const EdgeInsets.only(
// top: 12, bottom: 12, left: 20, right: 20),
// child: Text('Proses',
// overflow: TextOverflow.ellipsis,
// style: Constant.body3_600(context: context)
// .copyWith(color: Constant.textGrey)),
// ),
// ),
// ),
// Expanded(
// flex: 1,
// child: Container(
// alignment: Alignment.centerLeft,
// // width: Constant.getActualX(context: context, x: 100),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
// child: Padding(
// padding: const EdgeInsets.only(
// top: 12, bottom: 12, left: 20, right: 20),
// child: Text('Selesai',
// overflow: TextOverflow.ellipsis,
// style: Constant.body3_600(context: context)
// .copyWith(color: Constant.textGrey)),
// ),
// ),
// ),
// Expanded(
// flex: 1,
// child: Container(
// alignment: Alignment.centerLeft,
// // width: Constant.getActualX(context: context, x: 80),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
// child: Padding(
// padding: const EdgeInsets.only(
// top: 12, bottom: 12, left: 20, right: 20),
// child: Text('Aksi',
// overflow: TextOverflow.ellipsis,
// style: Constant.body3_600(context: context)
// .copyWith(color: Constant.textGrey)),
// ),
// ),
// ),
],
),
),
Container(
height: Constant.getActualY(context: context, y: 580),
color: Colors.white,
child: loading.value
? Center(
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 40),
)
: ListView(
children: data.value
.map(
(e) => Row(
children: [
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 100),
height: Constant.getActualY(
context: context, y: 64),
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: Text(e.date ?? "",
style:
Constant.body3_600(context: context)
.copyWith(
color: Constant.textBlack)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
width: Constant.getActualX(
context: context, x: 115),
height: Constant.getActualY(
context: context, y: 64),
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: Text(e.orderNumber ?? "",
style:
Constant.body3_600(context: context)
.copyWith(
color: Constant.textBlack)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
width: Constant.getActualX(
context: context, x: 196),
height: Constant.getActualY(
context: context, y: 64),
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 20,
right: 20),
child: Text(e.patientName ?? "",
style:
Constant.body3_600(context: context)
.copyWith(
color: Constant.textBlack)),
),
),
),
// Expanded(
// flex: 1,
// child: Container(
// alignment: Alignment.centerLeft,
// width: Constant.getActualX(
// context: context, x: 100),
// height: Constant.getActualY(
// context: context, y: 64),
// child: Padding(
// padding: const EdgeInsets.only(
// top: 12,
// bottom: 12,
// left: 20,
// right: 20),
// child: e.status == "S" ||
// e.status == "R" ||
// e.status == "T" ||
// e.status == "X" ||
// e.status == "P" ||
// e.status == "Q" ||
// e.status == "D"
// ? Icon(
// EvaIcons.checkmarkCircle2,
// size: 24,
// color: Constant.green,
// )
// : null),
// ),
// ),
// Expanded(
// flex: 1,
// child: Container(
// alignment: Alignment.centerLeft,
// width: Constant.getActualX(
// context: context, x: 100),
// height: Constant.getActualY(
// context: context, y: 64),
// child: Padding(
// padding: const EdgeInsets.only(
// top: 12,
// bottom: 12,
// left: 20,
// right: 20),
// child: e.status == "R" ||
// e.status == "T" ||
// e.status == "P" ||
// e.status == "Q" ||
// e.status == "D"
// ? JustTheTooltip(
// preferredDirection:
// AxisDirection.up,
// backgroundColor:
// Constant.textGrey,
// elevation: 10,
// content: Padding(
// padding: EdgeInsets.all(10),
// child:
// Builder(builder: (context) {
// List<Map<String, String>>
// accepted = List.empty(
// growable: true);
// if (e.acceptedSample !=
// null) {
// var splt = e.acceptedSample
// ?.split('|');
// if (splt!.length > 0) {
// splt.forEach((element) {
// var splitted =
// element.split('@');
// accepted.add({
// "name": splitted[0],
// "type": splitted[1]
// });
// });
// }
// }
// return Wrap(
// spacing: 10,
// runSpacing: 10,
// children: accepted
// .map((e) => Chip(
// backgroundColor: e[
// 'type'] ==
// "S"
// ? Constant
// .yellow_016
// : Constant
// .blue_016,
// label: Text(
// e['name'] ?? "",
// style: Constant
// .caption2_600(
// context:
// context)
// .copyWith(
// color: e['type'] ==
// "S"
// ? Constant
// .textYellow
// : Constant
// .textBlue),
// )))
// .toList(),
// );
// }),
// ),
// child: Icon(
// EvaIcons.checkmarkCircle2,
// size: 24,
// color: Constant.green,
// ),
// )
// : null),
// ),
// ),
// Expanded(
// flex: 1,
// child: Container(
// alignment: Alignment.centerLeft,
// width: Constant.getActualX(
// context: context, x: 100),
// height: Constant.getActualY(
// context: context, y: 64),
// child: Padding(
// padding: const EdgeInsets.only(
// top: 12,
// bottom: 12,
// left: 20,
// right: 20),
// child: e.status == "T" || e.status == "X"
// ? JustTheTooltip(
// preferredDirection:
// AxisDirection.up,
// backgroundColor: Constant.textGrey,
// elevation: 10,
// content: Padding(
// padding: EdgeInsets.all(10),
// child:
// Builder(builder: (context) {
// List<Map<String, String>>
// rejected =
// List.empty(growable: true);
// if (e.rejectedSample != null) {
// var splt = e.rejectedSample
// ?.split('|');
// if (splt!.length > 0) {
// splt.forEach((element) {
// var splitted =
// element.split('@');
// rejected.add({
// "name": splitted[0],
// "type": splitted[1]
// });
// });
// }
// }
// return Wrap(
// spacing: 10,
// runSpacing: 10,
// children: rejected
// .map((e) => Chip(
// backgroundColor: e[
// 'type'] ==
// "S"
// ? Constant
// .yellow_016
// : Constant
// .blue_016,
// label: Text(
// e['name'] ?? "",
// style: Constant
// .caption2_600(
// context:
// context)
// .copyWith(
// color: e[
// 'type'] ==
// "S"
// ? Constant
// .textYellow
// : Constant
// .textBlue),
// )))
// .toList(),
// );
// }),
// ),
// child: Icon(
// EvaIcons.checkmarkCircle2,
// size: 24,
// color: Constant.green,
// ),
// )
// : null,
// ),
// ),
// ),
// Expanded(
// flex: 1,
// child: Container(
// alignment: Alignment.centerLeft,
// width: Constant.getActualX(
// context: context, x: 100),
// height: Constant.getActualY(
// context: context, y: 64),
// child: Padding(
// padding: const EdgeInsets.only(
// top: 12,
// bottom: 12,
// left: 20,
// right: 20),
// child: e.status == "Q" ||
// e.status == "P" ||
// e.status == "D"
// ? Icon(
// EvaIcons.checkmarkCircle2,
// size: 24,
// color: Constant.green,
// )
// : null),
// ),
// ),
// Expanded(
// flex: 1,
// child: Container(
// alignment: Alignment.centerLeft,
// width: Constant.getActualX(
// context: context, x: 100),
// height: Constant.getActualY(
// context: context, y: 64),
// child: Padding(
// padding: const EdgeInsets.only(
// top: 12,
// bottom: 12,
// left: 20,
// right: 20),
// child: e.status == "D"
// ? Icon(
// EvaIcons.checkmarkCircle2,
// size: 24,
// color: Constant.green,
// )
// : null),
// ),
// ),
// Expanded(
// flex: 1,
// child: Container(
// alignment: Alignment.centerLeft,
// width: Constant.getActualX(
// context: context, x: 80),
// height: Constant.getActualY(
// context: context, y: 64),
// child: Padding(
// padding: const EdgeInsets.only(
// top: 12,
// bottom: 12,
// left: 20,
// right: 20),
// child: InkWell(
// onTap: e.status == "D"
// ? () {
// showDialog(
// context: context,
// // barrierDismissible: false,
// builder: ((context) =>
// Container(
// child: DialogPrint(
// url:
// "http://devone.aplikasi.web.id/birt/run?__report=report/one/lab/rpt_fo_001.rptdesign&__format=pdf&username=ADMIN&PID=131868?t=1696927533769"),
// )));
// }
// : null,
// child: Tooltip(
// message: "Cetak laporan",
// child: Icon(
// EvaIcons.printer,
// size: 24,
// color: e.status == "D"
// ? Constant.primaryBlue
// : Colors.grey,
// ),
// ),
// )),
// ),
// ),
],
),
)
.toList(),
),
),
],
),
);
}
}

View File

@@ -0,0 +1,246 @@
import 'dart:ui';
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/model/order_model.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
class TableListPasien extends HookConsumerWidget {
const TableListPasien(
{super.key,
required this.orders,
required this.loading,
required this.selected});
final List<OrderModel> orders;
final bool loading;
final Function selected;
@override
Widget build(BuildContext context, WidgetRef ref) {
final scrollCtr = useScrollController();
return Material(
child: Container(
width: Constant.getActualX(context: context, x: 585),
height: Constant.getActualY(context: context, y: 410),
color: Colors.white,
child: Column(
children: [
Row(
children: [
Container(
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 12)),
alignment: Alignment.centerLeft,
width: Constant.getActualX(context: context, x: 180),
height: Constant.getActualY(context: context, y: 64),
color: Constant.grey_200,
child: Text('No Registrasi / Nama',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
Container(
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 12)),
alignment: Alignment.centerLeft,
width: Constant.getActualX(context: context, x: 325),
height: Constant.getActualY(context: context, y: 64),
color: Constant.grey_200,
child: Text('Pemeriksaan',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
// Container(
// padding: EdgeInsets.only(
// left: Constant.getActualX(context: context, x: 12)),
// alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 200),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
// child: Text('Jenis Specimen',
// style: Constant.body3_600(context: context)
// .copyWith(color: Constant.textGrey)),
// ),
Container(
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 12)),
alignment: Alignment.centerLeft,
width: Constant.getActualX(context: context, x: 80),
height: Constant.getActualY(context: context, y: 64),
color: Constant.grey_200,
child: Text('Aksi',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 340),
// color: Colors.red,
child: loading
? Center(
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 40),
)
: Scrollbar(
thickness: 5,
interactive: true,
thumbVisibility: true,
trackVisibility: true,
scrollbarOrientation: ScrollbarOrientation.right,
controller: scrollCtr,
child: ScrollConfiguration(
behavior: ScrollConfiguration.of(context)
.copyWith(dragDevices: {
PointerDeviceKind.mouse,
PointerDeviceKind.touch,
PointerDeviceKind.trackpad,
PointerDeviceKind.stylus,
PointerDeviceKind.unknown
}),
child: ListView(
controller: scrollCtr,
scrollDirection: Axis.vertical,
children: orders
.asMap()
.entries
.map(
(e) => Container(
padding: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 10),
bottom: Constant.getActualY(
context: context, y: 10)),
color: e.key.isOdd
? Constant.primaryBlue
.withOpacity(0.05)
: Colors.white,
margin: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 5),
bottom: Constant.getActualY(
context: context, y: 5)),
child: Row(
children: [
Container(
padding: EdgeInsets.only(
left: Constant.getActualX(
context: context, x: 12)),
alignment: Alignment.centerLeft,
width: Constant.getActualX(
context: context, x: 180),
height: Constant.getActualY(
context: context, y: 64),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(e.value.orderNumber ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color: Constant
.textBlack)),
Text(e.value.patientName ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color: Constant
.textBlack))
],
),
),
// Container(
// padding: EdgeInsets.only(
// left: Constant.getActualX(
// context: context, x: 12)),
// alignment: Alignment.centerLeft,
// width: Constant.getActualX(
// context: context, x: 195),
// height: Constant.getActualY(
// context: context, y: 64),
// color: Colors.white,
// child: Text(e.patientName ?? "",
// style: Constant.body3_600(
// context: context)
// .copyWith(
// color: Constant.textBlack)),
// ),
SizedBox(
// color: Colors.red,
width: Constant.getActualX(
context: context, x: 325),
child: Wrap(
alignment: WrapAlignment.start,
spacing: 10,
children: [
if (e.value.tests!.isNotEmpty)
...e.value.tests!
.map((k) => Container(
margin: EdgeInsets.only(
bottom: Constant
.getActualX(
context:
context,
x: 10)),
child: Chip(
shape:
RoundedRectangleBorder(
borderRadius: BorderRadius
.all(Radius
.circular(
6)),
),
// backgroundColor:
// Constant
// .blue_016,
label: Text(
'$k '.replaceAll(
' ',
'\u00A0'),
overflow:
TextOverflow
.ellipsis,
style: Constant.caption2_600(
context:
context)
.copyWith(
color:
Constant.textBlack)),
),
))
],
),
),
Container(
alignment: Alignment.centerLeft,
width: Constant.getActualX(
context: context, x: 80),
child: IconButton(
onPressed: () {
// print(e.orderNumber);
selected(e.value);
},
icon: Icon(
EvaIcons.arrowCircleRight,
size: 24,
color: Constant.green)),
)
],
),
),
)
.toList(),
),
),
),
),
],
)
//
));
}
}

View File

@@ -0,0 +1,669 @@
import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mitra_corporate/model/surat_jalan_model.dart';
import 'package:mitra_corporate/provider/auth_provider.dart';
import 'package:mitra_corporate/provider/surat_jalan_provider.dart';
import 'package:mitra_corporate/screen/surat_jalan/cancel_surat_jalan_provider.dart';
import 'package:mitra_corporate/screen/surat_jalan/get_surat_jalan_list_provider.dart';
import 'package:mitra_corporate/screen/surat_jalan/send_surat_jalan_provider.dart';
import 'package:intl/intl.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../provider/menu_provider.dart';
import '../../widgets/custom_snackbar_widget.dart';
import '../registrasi/table_pasien.dart';
import 'dialog_cancel.dart';
import 'dialog_send.dart';
class TableSuratJalan extends HookConsumerWidget {
const TableSuratJalan({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
// final isExpand = ref.watch(sideBarExpandProvider);
final keyword = ref.watch(suratJalankeywordProvider);
final startDate = ref.watch(sjStartDateProvider);
final endDate = ref.watch(sjEndDateProvider);
final sjdateType = ref.watch(sjDateType);
final auth = ref.watch(authProvider);
final suratJalanTab = ref.watch(suratJalanProvider);
final rowsPerPage = useState(10);
final searchLoading = useState(false);
final dataStart = useState(1);
final dataEnd = useState(1);
final currPage = useState(1);
final sjList = useState<SearchSuratJalanModel>(
SearchSuratJalanModel(suratJalan: [], total: "0", totalPage: 0));
final cancelLoading = useState(false);
final sendLoading = useState(false);
onRefresh() {
var ed = DateFormat('yyyy-MM-dd').format(endDate).toString();
var sd = DateFormat('yyyy-MM-dd').format(startDate).toString();
ref.read(GetSuratJalanListProvider.notifier).getData(
ed: ed,
sd: sd,
token: auth?.token ?? "",
page: currPage.value.toString(),
keyword: keyword,
rpp: rowsPerPage.value.toString(),
dateType: sjdateType.id,
company_id: auth?.mUserMCompanyID ?? "");
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final debouncer = Debouncer(milliseconds: 100);
debouncer.run(() {
onRefresh();
});
});
return () {};
}, [currPage.value, suratJalanTab]);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final debouncer = Debouncer(milliseconds: 100);
currPage.value = 1;
debouncer.run(() {
var ed = DateFormat('yyyy-MM-dd').format(endDate).toString();
var sd = DateFormat('yyyy-MM-dd').format(startDate).toString();
ref.read(GetSuratJalanListProvider.notifier).getData(
ed: ed,
sd: sd,
token: auth?.token ?? "",
page: "1",
keyword: keyword,
dateType: sjdateType.id,
rpp: rowsPerPage.value.toString(),
company_id: auth?.mUserMCompanyID ?? "");
});
});
return () {};
}, [
keyword,
startDate,
endDate,
sjdateType,
rowsPerPage.value,
]);
ref.listen(
GetSuratJalanListProvider,
(pref, next) {
if (next is GetSuratJalanListStateInit) {
searchLoading.value = true;
} else if (next is GetSuratJalanListStateLoading) {
searchLoading.value = true;
} else if (next is GetSuratJalanListStateError) {
searchLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is GetSuratJalanListStateDone) {
sjList.value = next.model;
// print(jsonEncode(next.model));
dataStart.value =
(currPage.value * rowsPerPage.value) - rowsPerPage.value + 1;
dataEnd.value = currPage.value == next.model.totalPage
? int.parse(next.model.total ?? "0")
: dataStart.value + rowsPerPage.value - 1;
searchLoading.value = false;
}
},
);
cancelSuratJalan(String deliveryID) {
ref
.read(CancelSuratJalanProvider.notifier)
.cancel(token: auth?.token ?? "", deliveryID: deliveryID);
}
ref.listen(
CancelSuratJalanProvider,
(pref, next) {
if (next is CancelSuratJalanStateInit) {
cancelLoading.value = true;
} else if (next is CancelSuratJalanStateLoading) {
cancelLoading.value = true;
} else if (next is CancelSuratJalanStateError) {
cancelLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is CancelSuratJalanStateDone) {
var ed = DateFormat('yyyy-MM-dd').format(endDate).toString();
var sd = DateFormat('yyyy-MM-dd').format(startDate).toString();
ref.read(GetSuratJalanListProvider.notifier).getData(
dateType: sjdateType.id,
ed: ed,
sd: sd,
token: auth?.token ?? "",
page: currPage.value.toString(),
keyword: keyword,
rpp: rowsPerPage.value.toString(),
company_id: auth?.mUserMCompanyID ?? "");
Navigator.pop(context);
// print(jsonEncode(next.model));
SanckbarWidget(context, "Berhasil Membatalkan pengiriman order",
snackbarType.success);
cancelLoading.value = false;
}
},
);
sendSuratJalan(String deliveryID) {
ref
.read(SendSuratJalanProvider.notifier)
.Send(token: auth?.token ?? "", deliveryID: deliveryID);
}
ref.listen(
SendSuratJalanProvider,
(pref, next) {
if (next is SendSuratJalanStateInit) {
sendLoading.value = true;
} else if (next is SendSuratJalanStateLoading) {
sendLoading.value = true;
} else if (next is SendSuratJalanStateError) {
sendLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
Constant.autoLogout(context: context, msg: next.message);
} else if (next is SendSuratJalanStateDone) {
var ed = DateFormat('yyyy-MM-dd').format(endDate).toString();
var sd = DateFormat('yyyy-MM-dd').format(startDate).toString();
ref.read(GetSuratJalanListProvider.notifier).getData(
dateType: sjdateType.id,
ed: ed,
sd: sd,
token: auth?.token ?? "",
page: currPage.value.toString(),
keyword: keyword,
rpp: rowsPerPage.value.toString(),
company_id: auth?.mUserMCompanyID ?? "");
Navigator.pop(context);
// print(jsonEncode(next.model));
SanckbarWidget(context, "Berhasil", snackbarType.success);
sendLoading.value = false;
}
},
);
return Material(
borderRadius: BorderRadius.all(Radius.circular(8)),
child: Column(
children: [
Container(
// height: Constant.getActualY(context: context, y: 64),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8)),
color: Constant.grey_200,
),
child: Row(
children: [
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 115),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 24, right: 6),
child: Text('Tanggal Surat Jalan',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 115),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 6, right: 6),
child: Text('Tanggal Kedatangan',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 24, right: 24),
child: Text('Nomor Pengiriman',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 337),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 24, right: 24),
child: Text('Staf PIC',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 175),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 24, right: 24),
child: Text('Tujuan',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 106),
// height: Constant.getActualY(context: context, y: 64),
// color: Constant.grey_200,
child: Padding(
padding: const EdgeInsets.only(
top: 12, bottom: 12, left: 24, right: 24),
child: Text('Aksi',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
),
),
],
),
),
Container(
// width: Constant.getActualX(context: context, x: 1080),
color: Colors.white,
height: Constant.getActualY(context: context, y: 466),
child: searchLoading.value
? Center(
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 40))
: ListView(
children: sjList.value.suratJalan!
.map((e) => Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
flex: 2,
child: Container(
// width: Constant.getActualX(context: context, x: 115),
height: Constant.getActualY(
context: context, y: 64),
color: Colors.white,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 24,
right: 6),
child: Text(e.dateSj ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color:
Constant.textBlack)),
),
),
),
Expanded(
flex: 2,
child: Container(
// width: Constant.getActualX(context: context, x: 115),
height: Constant.getActualY(
context: context, y: 64),
color: Colors.white,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 6,
right: 6),
child: Text(e.date ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color:
Constant.textBlack)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 171),
height: Constant.getActualY(
context: context, y: 64),
color: Colors.white,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 24,
right: 24),
child: Text(e.orderNumber ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color:
Constant.textBlack)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 337),
height: Constant.getActualY(
context: context, y: 64),
color: Colors.white,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 24,
right: 24),
child: Text(e.pic ?? "",
style: Constant.body3_600(
context: context)
.copyWith(
color:
Constant.textBlack)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 175),
height: Constant.getActualY(
context: context, y: 64),
color: Colors.white,
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 24,
right: 24),
child: Text(e.destination ?? '',
style: Constant.body3_600(
context: context)
.copyWith(
color:
Constant.textBlack)),
),
),
),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.centerLeft,
// width: Constant.getActualX(context: context, x: 105),
height: Constant.getActualY(
context: context, y: 64),
child: Padding(
padding: const EdgeInsets.only(
top: 12,
bottom: 12,
left: 24,
right: 0),
child: Wrap(
children: [
InkWell(
onTap: () {
ref
.read(
suratJalanID.notifier)
.state = e.id.toString();
ref
.read(suratJalanNumber
.notifier)
.state =
e.orderNumber.toString();
ref
.read(currentMenuProvider
.notifier)
.state = 5;
},
child: Tooltip(
message: "Detail Pengiriman",
child: Icon(EvaIcons.maximize,
size: 24,
color: Constant.green),
),
),
SizedBox(
width: Constant.getActualX(
context: context, x: 10)),
// InkWell(
// onTap: () {
// // html.window.open(
// // 'http://devone.aplikasi.web.id/birt/run?__report=report/one/lab/rpt_fo_001.rptdesign&__format=pdf&username=ADMIN&PID=131868?t=1696927533769',
// // "_blank");
// showDialog(
// context: context,
// // barrierDismissible: false,
// builder: ((context) =>
// Container(
// child: DialogPrint(
// url:
// "http://devkedungdororaya.aplikasi.web.id/birt/run?__report=report/one/regional/rpt_mt_001.rptdesign&PID=${e.id}&username=${auth?.mUserUsername}&__format=pdf"),
// )));
// },
// child: Tooltip(
// message: "Cetak Surat Jalan ",
// child: Icon(EvaIcons.printer,
// size: 24,
// color: Constant.green),
// ),
// ),
// SizedBox(
// width: Constant.getActualX(
// context: context, x: 10)),
if (e.status == 'N')
InkWell(
onTap: () {
showDialog<String>(
context: context,
barrierDismissible:
!sendLoading.value,
builder: (BuildContext
context) =>
DialogConfirmSuratJalan(
sendFunction:
sendSuratJalan,
deliveryID:
e.id ?? "0",
loading:
cancelLoading
.value,
date:
e.date ?? "",
deliveryNumber:
e.orderNumber ??
"",
pic: e.pic ?? ""),
);
},
child: Tooltip(
message: "Kirim",
child: Icon(
Icons.task_rounded,
size: 24,
color: Constant.green),
),
),
SizedBox(
width: Constant.getActualX(
context: context, x: 10)),
if (e.status == 'N')
InkWell(
onTap: () {
showDialog<String>(
context: context,
barrierDismissible:
!cancelLoading.value,
builder: (BuildContext
context) =>
DialogCancelSuratJalan(
cancel:
cancelSuratJalan,
deliveryID:
e.id ?? "0",
loading:
cancelLoading
.value,
date:
e.date ?? "",
deliveryNumber:
e.orderNumber ??
"",
pic: e.pic ?? ""),
).whenComplete(() {
onRefresh();
});
},
child: Tooltip(
message: "Batalkan",
child: Icon(
EvaIcons.closeCircle,
size: 24,
color: Constant.green),
),
),
],
),
),
),
)
],
))
.toList(),
)),
Divider(),
Container(
color: Colors.white,
height: Constant.getActualY(context: context, y: 52),
child: Row(
children: [
Spacer(),
Text(
"Rows per page :",
style: Constant.body3_400(context: context),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
DropdownButton<int>(
value: rowsPerPage.value,
dropdownColor: Colors.white,
elevation: 0,
style: Constant.body3_400(context: context)
.copyWith(color: Colors.black),
underline: Container(),
icon: Icon(Icons.keyboard_arrow_down_rounded),
focusColor: Colors.white,
items: [
DropdownMenuItem(
value: 10,
child: Text("10"),
),
DropdownMenuItem(
value: 15,
child: Text("15"),
),
DropdownMenuItem(
value: 20,
child: Text("20"),
),
DropdownMenuItem(
value: 30,
child: Text("30"),
),
DropdownMenuItem(
value: 40,
child: Text("40"),
),
DropdownMenuItem(
value: 50,
child: Text("50"),
),
],
onChanged: (value) {
rowsPerPage.value = value!;
}),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
Text(
"${dataStart.value} - ${dataEnd.value} of ${sjList.value.total}",
style: Constant.body3_400(context: context),
),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
),
IconButton(
iconSize: 20,
onPressed: currPage.value > 1
? () {
currPage.value = currPage.value - 1;
}
: null,
icon: Icon(Icons.arrow_back_ios_new_rounded)),
SizedBox(
width: Constant.getActualX(context: context, x: 10),
),
IconButton(
iconSize: 20,
onPressed:
currPage.value < sjList.value.totalPage!.toInt()
? () {
currPage.value = currPage.value + 1;
}
: null,
icon: Icon(Icons.arrow_forward_ios_outlined)),
SizedBox(
width: Constant.getActualX(context: context, x: 24),
)
],
),
)
],
));
}
}

View File

@@ -0,0 +1,111 @@
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../app/constant.dart';
import '../model/registration_model.dart';
class BahanTableWidget extends HookConsumerWidget {
const BahanTableWidget({
super.key,
required this.specimenLoading,
required this.tempRegistrationData,
required this.addOrderLoading,
});
final ValueNotifier<bool> specimenLoading;
final RegistrationModel tempRegistrationData;
final bool addOrderLoading;
@override
Widget build(BuildContext context, WidgetRef ref) {
return Column(
children: [
Row(
children: [
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 20)),
width: Constant.getActualX(context: context, x: 1160) * 0.13,
height: Constant.getActualY(context: context, y: 64),
color: Constant.grey_200,
child: Text('Bahan',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 20)),
width: Constant.getActualX(context: context, x: 1160) * 0.11,
height: Constant.getActualY(context: context, y: 64),
color: Constant.grey_200,
child: Text('Jumlah',
style: Constant.body3_600(context: context)
.copyWith(color: Constant.textGrey)),
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 300),
child: specimenLoading.value
? Center(
child: LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 30),
)
: ListView(children: [
...?tempRegistrationData.bahan?.map((e) => SizedBox(
height: Constant.getActualY(context: context, y: 64),
child: Row(
children: [
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 20)),
width: Constant.getActualX(
context: context, x: 1160) *
0.13,
color: Colors.white,
child: Chip(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(6)),
),
backgroundColor: Constant.blue_016,
label: Text(
'${e.name}'.replaceAll(' ', '\u00A0'),
style: Constant.caption1_600(
context: context)
.copyWith(color: Constant.textBlue)),
)),
Container(
height: Constant.getActualY(
context: context, y: 52),
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 20)),
width: Constant.getActualX(
context: context, x: 1160) *
0.11,
child: TextField(
enabled: !addOrderLoading,
controller: e.ctr,
onChanged: (value) {
print(value);
},
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8)))),
))
],
),
)),
]),
),
],
);
}
}

View File

View File

@@ -0,0 +1,409 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../app/constant.dart';
import 'iframe_view.dart';
class CustomDialogBuilder {
// // pdf mobile
// static reportPdf(
// BuildContext context,
// String typeReportParam,
// String startDateParam,
// String endDateParam,
// String usernameParam,
// String filterRegionalID,
// String tatReportCategoryCode,
// ) {
// String urlParam = "";
// String tatReportCategoryCodeLowerCase = tatReportCategoryCode.toLowerCase();
// if (typeReportParam == "type_report_pendapatan") {
// // pendapatan
// // urlParam =
// // "https://${Constant.ipAddress}/birt/run?__report=report/one/rekap/rpt_sales_001.rptdesign&__format=xlsx&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&tm=${DateTime.now()}";
// // urlParam =
// // "https://devone.aplikasi.web.id/birt/frameset?__report=report/one/lab/rpt_test.rptdesign&__format=xls&username=ADMIN&PID=131878&tm=1697596972372";
// if (filterRegionalID == "0") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_sales_nasional_001.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=pdf ";
// } else {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_sales_001.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=pdf";
// }
// } else {
// // piutang
// if (typeReportParam == "type_report_piutang") {
// // urlParam =
// // "https://${Constant.ipAddress}/birt/run?__report=report/one/rekap/rpt_sales_001.rptdesign&__format=xlsx&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&tm=${DateTime.now()}";
// // urlParam =
// // "https://${Constant.ipAddress}/birt/frameset?__report=report/one/lab/rpt_test.rptdesign&__format=xls&username=ADMIN&PID=131878&tm=1697596972372";
// if (filterRegionalID == "0") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_piutang_nasional_001.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=pdf ";
// } else {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_piutang_001.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=pdf";
// }
// } else {
// // tat
// if (filterRegionalID == "0") {
// // global
// if (tatReportCategoryCodeLowerCase == "global") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=pdf ";
// print("global nasional tat : $urlParam");
// } else {
// // fo
// if (tatReportCategoryCodeLowerCase == "fo") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=pdf ";
// print("fo nasional tat : $urlParam");
// } else {
// // proses
// if (tatReportCategoryCodeLowerCase == "proses") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=pdf ";
// print("proses nasional tat : $urlParam");
// } else {
// // sampling
// if (tatReportCategoryCodeLowerCase == "sampling") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=pdf ";
// print("sampling nasional tat : $urlParam");
// } else {
// // pengolahan
// if (tatReportCategoryCodeLowerCase == "pengolahan") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=pdf ";
// print("sampling nasional tat : $urlParam");
// } else {
// // validasi
// if (tatReportCategoryCodeLowerCase == "validasi") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=pdf ";
// print("sampling nasional tat : $urlParam");
// }
// }
// }
// }
// }
// }
// } else {
// // global
// if (tatReportCategoryCodeLowerCase == "global") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001i_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=pdf";
// print("global regional tat : $urlParam");
// } else {
// // fo
// if (tatReportCategoryCodeLowerCase == "fo") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001i_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=pdf";
// print("fo regional tat : $urlParam");
// } else {
// // proses
// if (tatReportCategoryCodeLowerCase == "proses") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001i_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=pdf";
// print("proses regional tat : $urlParam");
// } else {
// // sampling
// if (tatReportCategoryCodeLowerCase == "sampling") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001i_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=pdf";
// print("sampling regional tat : $urlParam");
// } else {
// // pengolahan
// if (tatReportCategoryCodeLowerCase == "pengolahan") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001i_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=pdf";
// print("sampling regional tat : $urlParam");
// } else {
// // validasi
// if (tatReportCategoryCodeLowerCase == "validasi") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001i_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=pdf";
// print("sampling regional tat : $urlParam");
// }
// }
// }
// }
// }
// }
// }
// }
// }
// // launchUrlString(urlParam, mode: LaunchMode.externalNonBrowserApplication);
// launchUrlString(urlParam);
// }
// // excel web or mobile
// static reportExcel(
// String typeReportParam,
// String startDateParam,
// String endDateParam,
// String usernameParam,
// String filterRegionalID,
// String tatReportCategoryCode,
// ) {
// String urlParam = "";
// String tatReportCategoryCodeLowerCase = tatReportCategoryCode.toLowerCase();
// if (typeReportParam == "type_report_pendapatan") {
// // pendapatan
// // urlParam =
// // "https://${Constant.ipAddress}/birt/run?__report=report/one/rekap/rpt_sales_001.rptdesign&__format=xlsx&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&tm=${DateTime.now()}";
// // urlParam =
// // "https://devone.aplikasi.web.id/birt/frameset?__report=report/one/lab/rpt_test.rptdesign&__format=xls&username=ADMIN&PID=131878&tm=1697596972372";
// if (filterRegionalID == "0") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_sales_nasional_001.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=xls ";
// } else {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_sales_001.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=xls";
// }
// } else {
// if (typeReportParam == "type_report_piutang") {
// // piutang
// // urlParam =
// // "https://${Constant.ipAddress}/birt/run?__report=report/one/rekap/rpt_sales_001.rptdesign&__format=xlsx&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&tm=${DateTime.now()}";
// // urlParam =
// // "https://${Constant.ipAddress}/birt/frameset?__report=report/one/lab/rpt_test.rptdesign&__format=xls&username=ADMIN&PID=131878&tm=1697596972372";
// if (filterRegionalID == "0") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_piutang_nasional_001.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=xls ";
// } else {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_piutang_001.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=xls";
// }
// } else {
// // tat
// // if (filterRegionalID == "0") {
// // urlParam =
// // "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=xls ";
// // } else {
// // urlParam =
// // "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001i.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=xls";
// // }
// // tat
// if (filterRegionalID == "0") {
// // global
// if (tatReportCategoryCodeLowerCase == "global") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=xls ";
// print("global nasional tat : $urlParam");
// } else {
// // fo
// if (tatReportCategoryCodeLowerCase == "fo") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=xls ";
// print("fo nasional tat : $urlParam");
// } else {
// // proses
// if (tatReportCategoryCodeLowerCase == "proses") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=xls ";
// print("proses nasional tat : $urlParam");
// } else {
// // sampling
// if (tatReportCategoryCodeLowerCase == "sampling") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=xls ";
// print("sampling nasional tat : $urlParam");
// } else {
// // pengolahan
// if (tatReportCategoryCodeLowerCase == "pengolahan") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=xls ";
// print("sampling nasional tat : $urlParam");
// } else {
// // validasi
// if (tatReportCategoryCodeLowerCase == "validasi") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&__format=xls ";
// print("sampling nasional tat : $urlParam");
// }
// }
// }
// }
// }
// }
// } else {
// // global
// if (tatReportCategoryCodeLowerCase == "global") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001i_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=xls";
// print("global regional tat : $urlParam");
// } else {
// // fo
// if (tatReportCategoryCodeLowerCase == "fo") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001i_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=xls";
// print("fo regional tat : $urlParam");
// } else {
// // proses
// if (tatReportCategoryCodeLowerCase == "proses") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001i_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=xls";
// print("proses regional tat : $urlParam");
// } else {
// // sampling
// if (tatReportCategoryCodeLowerCase == "sampling") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001i_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=xls";
// print("sampling regional tat : $urlParam");
// } else {
// // pengolahan
// if (tatReportCategoryCodeLowerCase == "pengolahan") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001i_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=xls";
// print("sampling regional tat : $urlParam");
// } else {
// // validasi
// if (tatReportCategoryCodeLowerCase == "validasi") {
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_tat_nasional_001i_$tatReportCategoryCodeLowerCase.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&PregionalID=${filterRegionalID}&username=${usernameParam}&__format=xls";
// print("sampling regional tat : $urlParam");
// }
// }
// }
// }
// }
// }
// }
// }
// }
// launchUrlString(urlParam);
// }
// pdf web
static dialogBuilderWebPDF(
BuildContext context,
String startDateParam,
String endDateParam,
String noRegNamaParam,
String username,
String companyID) {
String urlParam = "";
String titleParam = "";
// pendapatan
var param = {
"CompanyID": companyID,
"startDateParam": startDateParam,
"endDateParam": endDateParam,
"noRegNamaParam": noRegNamaParam
};
print(param);
// Parsing tanggal dan waktu
DateTime dateTime = DateTime.now();
// Mengonversi ke timestamp
int timestamp = dateTime.millisecondsSinceEpoch;
titleParam = "Report Order";
urlParam =
"${Constant.protocol}//${Constant.ipAddress}/birt/run?__report=report/one/regional/mitra/rpt_list_order.rptdesign&__format=pdf&PStartDate=$startDateParam&PEndDate=$endDateParam&PSearch=$noRegNamaParam&username=$username&CompanyID=$companyID&tm=$timestamp";
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/rekap/rpt_sales_001.rptdesign&__format=pdf&PStartDate=$startDateParam&PEndDate=$endDateParam&username=${usernameParam}&tm=${DateTime.now()}";
// urlParam =
// "https://${Constant.ipAddress}/birt/run?__report=report/one/one_dash/rpt_sales_nasional_001.rptdesign&PStartDate=$startDateParam&PEndDate=$endDateParam&noreg=${noRegNamaParam}&__format=pdf ";
// urlParam =
// "https://devone.aplikasi.web.id/birt/frameset?__report=report/one/lab/rpt_test.rptdesign&__format=pdf&username=ADMIN&PID=131878&tm=1697596972372";
return showDialog<void>(
context: context,
builder: (BuildContext context) {
return HookConsumer(builder: (context, ref, widget) {
final isLoading = useState(true);
useEffect(() {
Timer(Duration(seconds: 3), () {
isLoading.value = false;
});
return null;
}, []);
return AlertDialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
title: Text(titleParam),
content: Padding(
padding: const EdgeInsets.all(10),
child: SizedBox(
width: Constant.getActualX(context: context, x: 1440),
child: Column(
children: [
// Text('${startDateParam}'),
// Text('${endDateParam}'),
// Text('${noRegNamaParam}'),
Expanded(
child: Stack(
alignment: Alignment.center,
children: [
IframeView(
key: UniqueKey(),
source: urlParam,
onCreated: (idx) {
// print('Oncreated print ${idx}');
isLoading.value = false;
},
),
// loading
if (isLoading.value == true)
const Center(
child: SizedBox(
width: 32,
height: 32,
child: CircularProgressIndicator(),
),
),
],
),
),
],
),
),
),
actions: <Widget>[
ElevatedButton(
style: ElevatedButton.styleFrom(
textStyle: Constant.body3_600(context: context),
),
onPressed: (isLoading.value)
? null
: () {
isLoading.value = false;
Navigator.of(context).pop();
},
child: Padding(
padding: const EdgeInsets.all(10),
child: Text(
'Tutup',
style: TextStyle(color: Colors.white),
),
),
),
],
);
});
},
);
}
}

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