step 3 : hapus ai_barcode_scanner, ai barcode, update permission_handler, flutter_map,latlong2

This commit is contained in:
sindhu
2025-04-11 13:39:17 +07:00
parent aa05bb5d51
commit 25fdce45f9
141 changed files with 19594 additions and 165 deletions

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

@@ -0,0 +1,122 @@
import 'package:flutter/material.dart';
class Constant {
static String tokenName = "kdr-kurir";
// static String baseUrl = "http://devkedungdororaya.aplikasi.web.id/one-api/";
static String baseUrl = "http://kd-kurir.aplikasi.web.id/one-api/";
static String baseBirtUrl = "http://kd-kurir.aplikasi.web.id/";
static double designHeight = 844;
static double designWidth = 390;
static String version = "1.01";
//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;
}
//color identity
static Color backgroundWhite = const Color(0xffFFFFFF);
static Color textBlack = const Color(0xFF070708);
static Color textGrey = const Color(0xFF919EAB);
static Color primaryBlue = const Color(0xFF005AA9);
static Color backgroundBlue = const Color(0xFF1890FF).withOpacity(0.25);
static Color iconBlue = const Color(0xFF3366FF);
static Color primaryGreen = const Color(0xFF229A16);
static Color backgroundGreen = const Color(0xFF54D62C).withOpacity(0.25);
static Color primaryOrange = const Color(0xFFB78103);
static Color backgroundOrange = const Color(0xFFFFC107).withOpacity(0.25);
static Color primaryRed = const Color(0xFFB72136);
static Color primaryYellow = const Color(0xFFFFC107);
static Color primaryPurple = const Color(0xFFBF07FF);
static Color backgroundPurple = const Color(0xFFBF07FF).withOpacity(0.25);
static Color textSecondary = const Color(0xFF637381);
// sindhu
static Color textPrimary = const Color(0xff212B36);
static Color primaryMain = const Color(0xff3366FF);
static Color errorDark = const Color(0xffB72136);
// static Color dropdownTextColor = const Color(0xff005AA9);
static Color blueButton = const Color(0xff005AA9);
static Color primaryDark = const Color(0xff005AA9);
static Color buttonIsNotActive = const Color(0xffDFE3E8);
static Color historyCardColor = const Color(0xff54D62C).withOpacity(0.08);
static Color historyCardColorPending =
const Color(0xffFF0D05).withOpacity(0.08);
// typography
static TextStyle heading2({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualY(context: context, y: 28),
height: 1.5,
);
}
static TextStyle body1({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualY(context: context, y: 16),
height: 1.5,
);
}
static TextStyle caption1({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualY(context: context, y: 12),
height: 1.5,
);
}
static TextStyle buttonLarge({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualY(context: context, y: 15),
height: 1.5,
);
}
static TextStyle heading4({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualY(context: context, y: 18),
height: 1.5,
);
}
static TextStyle body3({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualY(context: context, y: 14),
height: 1.5,
);
}
static TextStyle caption2({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualY(context: context, y: 10),
height: 1.5,
);
}
static TextStyle heading3({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualY(context: context, y: 20),
height: 1.5,
);
}
static TextStyle body2({required BuildContext context}) {
return TextStyle(
fontSize: Constant.getActualY(context: context, y: 14),
height: 1.5,
);
}
}

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

@@ -0,0 +1,285 @@
import 'package:flutter/material.dart';
import '../screen/change_password_screen/change_password_screen.dart';
import '../screen/input_pekerjaan/input_pekerjaan_lain_lain.dart';
import '../screen/input_pekerjaan/input_pekerjaan_pengambilan_bahan.dart';
import '../screen/personal_information_screen/personal_information_screen.dart';
import '../screen/test/test_home_screen.dart';
import '../screen/work_process_screen/work_process_screen.dart';
import '../screen/input_pekerjaan/input_lain_lain_screen.dart';
import '../screen/input_pekerjaan/input_pekerjaan_pengantaran_hasil.dart';
import '../screen/input_pekerjaan/input_pekerjaan_screen.dart';
import '../screen/input_pekerjaan/input_pengambilan_bahan_screen.dart';
import '../screen/input_pekerjaan/input_pengantaran_hasil_dokter_screen.dart';
import '../screen/input_pekerjaan/input_pengantaran_hasil_instansi_screen.dart';
import '../screen/input_pekerjaan/input_pengantaran_hasil_pasien_screen.dart';
import '../screen/input_pekerjaan/input_scan_screen.dart';
import '../screen/konfirmasi/konfirmasi_screen.dart';
import '../screen/login/login_screen.dart';
import '../screen/problemlogin/problem_login_screen.dart';
import '../screen/splash_screen/splash_screen.dart';
import '../screen/menu_screen/menu_screen.dart';
// import '../screen/splash_screen.dart';
const splashRoute = "/splashRoute";
const loginRoute = "/loginRoute";
const problemLoginRoute = "/problemLoginRoute";
const testHomeRoute = "/testHomeRoute";
const inputPekerjaan = "/inputPekerjaan";
const inputScanRoute = "/inputScanRoute";
const konfirmasiRoute = "/konfirmasiRoute";
const inputPengantaranHasilPasien = "/inputPengantaranHasilPasien";
const inputPengantaranHasilInstansi = "/inputPengantaranHasilInstansi";
const inputPengantaranHasilDokter = "/inputPengantaranHasilDokter";
const inputPengambilanBahan = "/inputPengambilanBahan";
const inputLainLain = "/inputLainLain";
const personalInformationRoute = "/personalInformation";
const changePasswordRoute = "/changPassword";
const workProcessRoute = "/workProcessRoute";
const menuRoute = "/menuRoute";
const inputPekerjaanPengantaranHasil = "/inputPekerjaanPengantaranHasil";
const inputPekerjaanPengambilanBahan = "/inputPekerjaanPengambilanBahan";
const inputPekerjaanLainLain = "/inputPekerjaanLainLain";
class inputPekerjaanProp {
final int input;
final int tipe;
inputPekerjaanProp(this.input, this.tipe);
}
class InputScanPekerjaanProp {
final int input;
final int tipe;
InputScanPekerjaanProp(this.input, this.tipe);
}
class AppRoute {
static Route<dynamic> generateRoute(RouteSettings settings) {
// splash screen
if (settings.name == splashRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: const SplashScreen());
});
}
// login
if (settings.name == loginRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: const LoginScreen());
});
}
// problem login
if (settings.name == problemLoginRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: const ProblemLoginScreen());
});
}
// test home screen
if (settings.name == testHomeRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: const TestHomeScreen());
});
}
// test Menu screen
if (settings.name == menuRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: const MenuScreen());
});
}
// input pekerjaan
if (settings.name == inputPekerjaan) {
final inputPekerjaanProp args = settings.arguments as inputPekerjaanProp;
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: InputPekerjaan(
input: args.input,
tipe: args.tipe,
));
});
}
// input pekerjaan pengantaran hasil
if (settings.name == inputPekerjaanPengantaranHasil) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: const InputPekerjaanPengantaranHasil());
});
}
// input pekerjaan pengambilan bahan
if (settings.name == inputPekerjaanPengambilanBahan) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: const InputPekerjaanPengambilanBahan());
});
}
// input pekerjaan lain lain
if (settings.name == inputPekerjaanLainLain) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: const InputPekerjaanPekerjaanLainLain());
});
}
// input pengantaran hasil pasien
if (settings.name == inputPengantaranHasilPasien) {
final args = settings.arguments as Map<String, dynamic>;
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: InputPengantaranHasilPasienScreen(
data: args,
));
});
}
// input pengantaran hasil instansi
if (settings.name == inputPengantaranHasilInstansi) {
final args = settings.arguments as Map<String, dynamic>;
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context)
.copyWith(textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: InputPengantaranHasilInstansiScreen(
data: args,
),
);
});
}
// input pengantaran hasil dokter
if (settings.name == inputPengantaranHasilDokter) {
final args = settings.arguments as Map<String, dynamic>;
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context)
.copyWith(textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: InputPengantaranHasilDokterScreen(
data: args,
),
);
});
}
// input pengambilan bahan
if (settings.name == inputPengambilanBahan) {
final args = settings.arguments as Map<String, dynamic>;
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context)
.copyWith(textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: InputPengambilanBahanScreen(
data: args,
),
);
});
}
// input lain lain
if (settings.name == inputLainLain) {
final args = settings.arguments as Map<String, dynamic>;
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context)
.copyWith(textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: InputLainLain(
data: args,
),
);
});
}
// input scan
if (settings.name == inputScanRoute) {
// final args = settings.arguments as Map<String, dynamic>;
final InputScanPekerjaanProp args =
settings.arguments as InputScanPekerjaanProp;
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context)
.copyWith(textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: InputScanScreen(
data: args,
),
);
});
}
// konfirmasi
if (settings.name == konfirmasiRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: const KonfirmasiScreen());
});
}
// Informasi Pribadi
if (settings.name == personalInformationRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: const PersonalInformationScreen());
});
}
if (settings.name == changePasswordRoute) {
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: const ChangePasswordScreen());
});
}
if (settings.name == workProcessRoute) {
final args = settings.arguments as DetailWorkProp;
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: WorkProcessScreen(
data: args,
));
});
}
return MaterialPageRoute(builder: (context) {
return MediaQuery(
data: MediaQuery.of(context)
.copyWith(textScaleFactor: 1.0, padding: const EdgeInsets.all(0)),
child: const SplashScreen());
});
}
}

BIN
lib/images/bg_login.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

BIN
lib/images/icon_home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 B

BIN
lib/images/logo_kdr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@@ -1,7 +1,18 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter/services.dart';
import 'package:intl/date_symbol_data_file.dart';
import 'app/constant.dart';
import 'app/route.dart';
void main() {
runApp(const MyApp());
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitUp,
]).then((value) => runApp(const ProviderScope(child: MyApp())));
// runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
@@ -11,112 +22,34 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
title: 'Aplikasi Kurir Kedungdoro',
theme: ThemeData(
// This is the theme of your application.
//
// TRY THIS: Try running your application with "flutter run". You'll see
// the application has a purple toolbar. Then, without quitting the app,
// try changing the seedColor in the colorScheme below to Colors.green
// and then invoke "hot reload" (save your changes or press the "hot
// reload" button in a Flutter-supported IDE, or press "r" if you used
// the command line to start the app).
//
// Notice that the counter didn't reset back to zero; the application
// state is not lost during the reload. To reset the state, use hot
// restart instead.
//
// This works for code too, not just values: Most code changes can be
// tested with just a hot reload.
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
primarySwatch: createMaterialColor(const Color(0xFF005AA9)),
fontFamily: 'OpenSans'),
debugShowCheckedModeBanner: false,
// initialRoute: loginRoute,
initialRoute: splashRoute,
onGenerateRoute: AppRoute.generateRoute,
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
MaterialColor createMaterialColor(Color color) {
List strengths = <double>[.05];
Map<int, Color> swatch = {};
final int r = color.red, g = color.green, b = color.blue;
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
for (int i = 1; i < 10; i++) {
strengths.add(0.1 * i);
}
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// TRY THIS: Try changing the color here to a specific color (to
// Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
// change color while the other colors stay the same.
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
// Column is also a layout widget. It takes a list of children and
// arranges them vertically. By default, it sizes itself to fit its
// children horizontally, and tries to be as tall as its parent.
//
// Column has various properties to control how it sizes itself and
// how it positions its children. Here we use mainAxisAlignment to
// center the children vertically; the main axis here is the vertical
// axis because Columns are vertical (the cross axis would be
// horizontal).
//
// TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
// action in the IDE, or press "p" in the console), to see the
// wireframe for each widget.
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text('You have pushed the button this many times:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
for (var strength in strengths) {
final double ds = 0.5 - strength;
swatch[(strength * 1000).round()] = Color.fromRGBO(
r + ((ds < 0 ? r : (255 - r)) * ds).round(),
g + ((ds < 0 ? g : (255 - g)) * ds).round(),
b + ((ds < 0 ? b : (255 - b)) * ds).round(),
1,
);
}
return MaterialColor(color.value, swatch);
}

View File

@@ -0,0 +1,71 @@
class AuthModel {
final String token;
final AuthKurirModel model;
AuthModel({
required this.token,
required this.model,
});
}
class AuthKurirModel {
User? user;
String? token;
AuthKurirModel({this.user, this.token});
AuthKurirModel.fromJson(Map<String, dynamic> json) {
user = json['user'] != null ? User.fromJson(json['user']) : null;
token = json['token'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
if (user != null) {
data['user'] = user!.toJson();
}
data['token'] = token;
return data;
}
}
class User {
String? mUserID;
String? mUserUsername;
String? mStaffName;
String? ip;
String? agent;
String? mUserPassword = "";
String? mCourierID;
User(
{this.mUserID,
this.mUserUsername,
this.mStaffName,
this.ip,
this.agent,
this.mUserPassword,
this.mCourierID});
User.fromJson(Map<String, dynamic> json) {
mUserID = json['M_UserID'];
mUserUsername = json['M_UserUsername'];
mStaffName = json['Nat_StaffName'];
ip = json['ip'];
agent = json['agent'];
mCourierID = json['M_CourierID'];
mUserPassword = "";
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['M_UserID'] = mUserID;
data['M_UserUsername'] = mUserUsername;
data['Nat_StaffName'] = mStaffName;
data['ip'] = ip;
data['agent'] = agent;
data['M_CourierID'] = mCourierID;
data['M_UserPassword'] = mUserPassword;
return data;
}
}

View File

@@ -0,0 +1,32 @@
class CompanyModel {
String? mCompanyID;
String? mCompanyName;
String? mCompanyNumber;
String? detail;
String? mCompanyAddress;
CompanyModel(
{this.mCompanyID,
this.mCompanyName,
this.mCompanyNumber,
this.detail,
this.mCompanyAddress});
CompanyModel.fromJson(Map<String, dynamic> json) {
mCompanyID = json['M_CompanyID'];
mCompanyName = json['M_CompanyName'];
mCompanyNumber = json['M_CompanyNumber'];
detail = json['detail'];
mCompanyAddress = json['M_CompanyAddress'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['M_CompanyID'] = this.mCompanyID;
data['M_CompanyName'] = this.mCompanyName;
data['M_CompanyNumber'] = this.mCompanyNumber;
data['detail'] = this.detail;
data['M_CompanyAddress'] = this.mCompanyAddress;
return data;
}
}

View File

@@ -0,0 +1,149 @@
import 'dart:convert';
import '../models/patient_model.dart';
// "note_penyerahan": "lengkap",
// "alamat_pengantaran": "Jl Sampangan no 231 ABA Barusari, Semarang Selatan, Semarang",
// "penerima": "Nicolas Saputra",
// "note_penerima": "oke lengkap",
class DetailHistoryModel {
String? id;
String? tipeid;
String? tipe;
String? noSuratJalan;
String? nama;
String? distance;
String? cdate;
String? alamatPengambilan;
String? petugasPenyerahan;
String? alamatPengantaran;
String? penerima;
String? lokasiPengambilanAwal;
String? latPengambilanAwal;
String? lngPengambilanAwal;
String? lokasiPengambilanAkhir;
String? latPengambilanAkhir;
String? lngPengambilanAkhir;
String? lokasiPengantaranAwal;
String? latPengantaranAwal;
String? lngPengantaranAwal;
String? lokasiPengantaranAkhir;
String? latPengantaranAkhir;
String? lngPengantaranAkhir;
String? notePenyerahan;
String? notePenerimaan;
List<PatientModel>? patients;
String? foNote;
String? adminNote;
DetailHistoryModel(
{this.id,
this.tipeid,
this.tipe,
this.noSuratJalan,
this.nama,
this.distance,
this.cdate,
this.alamatPengambilan,
this.petugasPenyerahan,
this.alamatPengantaran,
this.penerima,
this.lokasiPengambilanAwal,
this.latPengambilanAwal,
this.lngPengambilanAwal,
this.lokasiPengambilanAkhir,
this.latPengambilanAkhir,
this.lngPengambilanAkhir,
this.lokasiPengantaranAwal,
this.latPengantaranAwal,
this.lngPengantaranAwal,
this.lokasiPengantaranAkhir,
this.latPengantaranAkhir,
this.lngPengantaranAkhir,
this.notePenerimaan,
this.notePenyerahan,
this.foNote,
this.adminNote,
this.patients});
DetailHistoryModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
tipeid = json['tipeid'];
tipe = json['tipe'];
noSuratJalan = json['no_surat_jalan'];
nama = json['nama'];
distance = json['distance'];
cdate = json['cdate'];
alamatPengambilan = json['alamat_pengambilan'];
petugasPenyerahan = json['petugas_penyerahan'];
alamatPengantaran = json['alamat_pengantaran'];
penerima = json['penerima'];
lokasiPengambilanAwal = json['lokasi_pengambilan_awal'];
latPengambilanAwal = json['lat_pengambilan_awal'];
lngPengambilanAwal = json['lng_pengambilan_awal'];
lokasiPengambilanAkhir = json['lokasi_pengambilan_akhir'];
latPengambilanAkhir = json['lat_pengambilan_akhir'];
lngPengambilanAkhir = json['lng_pengambilan_akhir'];
lokasiPengantaranAwal = json['lokasi_pengantaran_awal'];
latPengantaranAwal = json['lat_pengantaran_awal'];
lngPengantaranAwal = json['lng_pengantaran_awal'];
lokasiPengantaranAkhir = json['lokasi_pengantaran_akhir'];
latPengantaranAkhir = json['lat_pengantaran_akhir'];
lngPengantaranAkhir = json['lng_pengantaran_akhir'];
notePenerimaan = json['note_penerima'];
notePenyerahan = json['note_penyerahan'];
foNote = json['fo_note'];
adminNote = json['admin_note'];
// patients = json['patients'];
if (json['patients'].toString().isNotEmpty) {
var data = <PatientModel>[];
// print("hasil json decode");
// print(jsonDecode(json['patients']));
// print("end");
try {
jsonDecode(json['patients']).forEach((v) {
data.add(PatientModel.fromJson(v));
});
} catch (e) {
print(e);
}
patients = data;
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['tipeid'] = this.tipeid;
data['tipe'] = this.tipe;
data['no_surat_jalan'] = this.noSuratJalan;
data['nama'] = this.nama;
data['distance'] = this.distance;
data['cdate'] = this.cdate;
data['alamat_pengambilan'] = this.alamatPengambilan;
data['petugas_penyerahan'] = this.petugasPenyerahan;
data['alamat_pengantaran'] = this.alamatPengantaran;
data['penerima'] = this.penerima;
data['lokasi_pengambilan_awal'] = this.lokasiPengambilanAwal;
data['lat_pengambilan_awal'] = this.latPengambilanAwal;
data['lng_pengambilan_awal'] = this.lngPengambilanAwal;
data['lokasi_pengambilan_akhir'] = this.lokasiPengambilanAkhir;
data['lat_pengambilan_akhir'] = this.latPengambilanAkhir;
data['lng_pengambilan_akhir'] = this.lngPengambilanAkhir;
data['lokasi_pengantaran_awal'] = this.lokasiPengantaranAwal;
data['lat_pengantaran_awal'] = this.latPengantaranAwal;
data['lng_pengantaran_awal'] = this.lngPengantaranAwal;
data['lokasi_pengantaran_akhir'] = this.lokasiPengantaranAkhir;
data['lat_pengantaran_akhir'] = this.latPengantaranAkhir;
data['lng_pengantaran_akhir'] = this.lngPengantaranAkhir;
data['note_penyerahan'] = this.notePenyerahan;
data['note_penerima'] = this.notePenerimaan;
data['fo_note'] = this.foNote;
data['admin_note'] = this.adminNote;
// data['patients'] = this.patients;
if (this.patients != null || this.patients != "") {
data['patients'] = this.patients!.map((v) => v.toJson()).toList();
}
return data;
}
}

View File

@@ -0,0 +1,195 @@
import 'dart:convert';
import '../models/patient_model.dart';
class DetailWorkModel {
String? id;
String? tipeid;
String? tipe;
String? noSuratJalan;
String? nama;
String? distance;
String? cdate;
String? alamatPengambilan;
String? petugasPenyerahan;
String? alamatPengantaran;
String? penerima;
String? lokasiPengambilanAwal;
String? latPengambilanAwal;
String? lngPengambilanAwal;
String? lokasiPengambilanAkhir;
String? latPengambilanAkhir;
String? lngPengambilanAkhir;
String? lokasiPengantaranAwal;
String? latPengantaranAwal;
String? lngPengantaranAwal;
String? lokasiPengantaranAkhir;
String? latPengantaranAkhir;
String? lngPengantaranAkhir;
String? notePenyerahan;
String? notePenerimaan;
List<PatientModel>? patients;
// TAMBAHAN INPUTAN INFO
String? suhuBox;
String? suhuSample;
String? totalPasien;
String? totalEdta;
String? totalCitras;
String? totalSerum;
String? totalUrine;
String? totalPleura;
String? otherSample;
String? totalOther;
String? foNote;
String? adminNote;
String? branchID;
DetailWorkModel(
{this.id,
this.tipeid,
this.tipe,
this.noSuratJalan,
this.nama,
this.distance,
this.cdate,
this.alamatPengambilan,
this.petugasPenyerahan,
this.alamatPengantaran,
this.penerima,
this.lokasiPengambilanAwal,
this.latPengambilanAwal,
this.lngPengambilanAwal,
this.lokasiPengambilanAkhir,
this.latPengambilanAkhir,
this.lngPengambilanAkhir,
this.lokasiPengantaranAwal,
this.latPengantaranAwal,
this.lngPengantaranAwal,
this.lokasiPengantaranAkhir,
this.latPengantaranAkhir,
this.lngPengantaranAkhir,
this.notePenerimaan,
this.notePenyerahan,
this.patients,
// TAMBAHAN INPUTAN INFO
this.suhuBox,
this.suhuSample,
this.totalPasien,
this.totalEdta,
this.totalCitras,
this.totalSerum,
this.totalUrine,
this.totalPleura,
this.otherSample,
this.totalOther,
this.foNote,
this.adminNote,
this.branchID});
DetailWorkModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
tipeid = json['tipeid'];
tipe = json['tipe'];
noSuratJalan = json['no_surat_jalan'];
nama = json['nama'];
distance = json['distance'];
cdate = json['cdate'];
alamatPengambilan = json['alamat_pengambilan'];
petugasPenyerahan = json['petugas_penyerahan'];
alamatPengantaran = json['alamat_pengantaran'];
penerima = json['penerima'];
lokasiPengambilanAwal = json['lokasi_pengambilan_awal'];
latPengambilanAwal = json['lat_pengambilan_awal'];
lngPengambilanAwal = json['lng_pengambilan_awal'];
lokasiPengambilanAkhir = json['lokasi_pengambilan_akhir'];
latPengambilanAkhir = json['lat_pengambilan_akhir'];
lngPengambilanAkhir = json['lng_pengambilan_akhir'];
lokasiPengantaranAwal = json['lokasi_pengantaran_awal'];
latPengantaranAwal = json['lat_pengantaran_awal'];
lngPengantaranAwal = json['lng_pengantaran_awal'];
lokasiPengantaranAkhir = json['lokasi_pengantaran_akhir'];
latPengantaranAkhir = json['lat_pengantaran_akhir'];
lngPengantaranAkhir = json['lng_pengantaran_akhir'];
notePenerimaan = json['note_penerima'];
notePenyerahan = json['note_penyerahan'];
// patients = json['patients'];
if (json['patients'].toString().isNotEmpty) {
var data = <PatientModel>[];
// print("hasil json decode");
// print(jsonDecode(json['patients']));
// print("end");
try {
jsonDecode(json['patients']).forEach((v) {
data.add(PatientModel.fromJson(v));
});
} catch (e) {
print(e);
}
patients = data;
}
// TAMBAHAN INPUTAN INFO
suhuBox = json['suhu_box'];
suhuSample = json['suhu_sample'];
totalPasien = json['total_pasien'];
totalEdta = json['total_edta'];
totalCitras = json['total_citras'];
totalSerum = json['total_serum'];
totalUrine = json['total_urine'];
totalPleura = json['total_pleura'];
otherSample = json['other_sample'];
totalOther = json['total_other'];
foNote = json['fo_note'];
adminNote = json['admin_note'];
branchID = json['branchid'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['tipeid'] = this.tipeid;
data['tipe'] = this.tipe;
data['no_surat_jalan'] = this.noSuratJalan;
data['nama'] = this.nama;
data['distance'] = this.distance;
data['cdate'] = this.cdate;
data['alamat_pengambilan'] = this.alamatPengambilan;
data['petugas_penyerahan'] = this.petugasPenyerahan;
data['alamat_pengantaran'] = this.alamatPengantaran;
data['penerima'] = this.penerima;
data['lokasi_pengambilan_awal'] = this.lokasiPengambilanAwal;
data['lat_pengambilan_awal'] = this.latPengambilanAwal;
data['lng_pengambilan_awal'] = this.lngPengambilanAwal;
data['lokasi_pengambilan_akhir'] = this.lokasiPengambilanAkhir;
data['lat_pengambilan_akhir'] = this.latPengambilanAkhir;
data['lng_pengambilan_akhir'] = this.lngPengambilanAkhir;
data['lokasi_pengantaran_awal'] = this.lokasiPengantaranAwal;
data['lat_pengantaran_awal'] = this.latPengantaranAwal;
data['lng_pengantaran_awal'] = this.lngPengantaranAwal;
data['lokasi_pengantaran_akhir'] = this.lokasiPengantaranAkhir;
data['lat_pengantaran_akhir'] = this.latPengantaranAkhir;
data['lng_pengantaran_akhir'] = this.lngPengantaranAkhir;
data['note_penyerahan'] = this.notePenyerahan;
data['note_penerima'] = this.notePenerimaan;
// data['patients'] = this.patients;
if (this.patients != null || this.patients != "") {
data['patients'] = this.patients!.map((v) => v.toJson()).toList();
}
// TAMBAHAN INPUTAN INFO
data['suhu_box'] = this.suhuBox;
data['suhu_sample'] = this.suhuSample;
data['total_pasien'] = this.totalPasien;
data['total_edta'] = this.totalEdta;
data['total_citras'] = this.totalCitras;
data['total_serum'] = this.totalSerum;
data['total_urine'] = this.totalUrine;
data['total_pleura'] = this.totalPleura;
data['other_sample'] = this.otherSample;
data['total_other'] = this.totalOther;
data['fo_note'] = this.foNote;
data['admin_note'] = this.adminNote;
data['branchid'] = this.branchID;
return data;
}
}

View File

@@ -0,0 +1,44 @@
class HistoryModel {
String? id;
int? tipeid;
String? tipe;
String? noSuratJalan;
String? nama;
String? distance;
String? cdate;
String? ispending;
HistoryModel(
{this.id,
this.tipeid,
this.tipe,
this.noSuratJalan,
this.nama,
this.distance,
this.cdate,
this.ispending});
HistoryModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
tipeid = int.parse(json['tipeid']);
tipe = json['tipe'];
noSuratJalan = json['no_surat_jalan'];
nama = json['nama'];
distance = json['distance'];
cdate = json['cdate'];
ispending = json['ispending'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['tipeid'] = this.tipeid;
data['tipe'] = this.tipe;
data['no_surat_jalan'] = this.noSuratJalan;
data['nama'] = this.nama;
data['distance'] = this.distance;
data['cdate'] = this.cdate;
data['ispending'] = this.ispending;
return data;
}
}

View File

@@ -0,0 +1,23 @@
import 'package:equatable/equatable.dart';
class HistoryTypeModel extends Equatable {
String? tipeid;
String? tipename;
HistoryTypeModel({this.tipeid, this.tipename});
HistoryTypeModel.fromJson(Map<String, dynamic> json) {
tipeid = json['tipeid'];
tipename = json['tipename'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['tipeid'] = this.tipeid;
data['tipename'] = this.tipename;
return data;
}
@override
List<Object?> get props => [tipeid];
}

View File

@@ -0,0 +1,32 @@
class PatientModel {
String? tOrderDeliveryID;
String? tOrderHeaderID;
String? tOrderHeaderLabNumber;
String? pasien;
String? courierConfirmNote;
PatientModel(
{this.tOrderDeliveryID,
this.tOrderHeaderID,
this.tOrderHeaderLabNumber,
this.pasien,
this.courierConfirmNote});
PatientModel.fromJson(Map<String, dynamic> json) {
tOrderDeliveryID = json['T_OrderDeliveryID'];
tOrderHeaderID = json['T_OrderHeaderID'];
tOrderHeaderLabNumber = json['T_OrderHeaderLabNumber'];
pasien = json['pasien'];
courierConfirmNote = json['courier_confirmNote'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['T_OrderDeliveryID'] = this.tOrderDeliveryID;
data['T_OrderHeaderID'] = this.tOrderHeaderID;
data['T_OrderHeaderLabNumber'] = this.tOrderHeaderLabNumber;
data['pasien'] = this.pasien;
data['courier_confirmNote'] = this.courierConfirmNote;
return data;
}
}

View File

@@ -0,0 +1,92 @@
import 'dart:convert';
import '../models/patient_model.dart';
class PendingWorkModel {
int? id;
int? tipeid;
String? tipe;
String? noSuratJalan;
String? nama;
String? noLab;
String? alamat;
String? statusTransaksi;
String? branchid;
String? branchcode;
String? branchname;
String? branchaddress;
String? supervisor;
List<PatientModel>? patients;
String? note;
PendingWorkModel(
{this.id,
this.tipeid,
this.tipe,
this.noSuratJalan,
this.nama,
this.noLab,
this.alamat,
this.statusTransaksi,
this.branchid,
this.branchcode,
this.branchname,
this.branchaddress,
this.patients,
this.note});
PendingWorkModel.fromJson(Map<String, dynamic> json) {
id = int.parse(json['id']);
tipeid = int.parse(json['tipeid']);
tipe = json['tipe'];
noSuratJalan = json['no_surat_jalan'];
nama = json['nama'];
noLab = json['no_lab'];
alamat = json['alamat'];
statusTransaksi = json['status_transaksi'];
branchid = json['branchid'];
branchcode = json['branchcode'];
branchname = json['branchname'];
branchaddress = json['branchaddress'];
note = json['note'];
supervisor = json['supervisor'];
// print("patient :" + json['patients']);
if (json['patients'].toString().isNotEmpty) {
var data = <PatientModel>[];
// print("hasil json decode");
// print(jsonDecode(json['patients']));
// print("end");
try {
jsonDecode(json['patients']).forEach((v) {
data.add(PatientModel.fromJson(v));
});
} catch (e) {
print(e);
}
patients = data;
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['tipeid'] = this.tipeid;
data['tipe'] = this.tipe;
data['no_surat_jalan'] = this.noSuratJalan;
data['nama'] = this.nama;
data['no_lab'] = this.noLab;
data['alamat'] = this.alamat;
data['status_transaksi'] = this.statusTransaksi;
data['branchid'] = this.branchid;
data['branchcode'] = this.branchcode;
data['branchname'] = this.branchname;
data['branchaddress'] = this.branchaddress;
data['patients'] = this.patients;
if (this.patients != null || this.patients != "") {
data['patients'] = this.patients!.map((v) => v.toJson()).toList();
}
data['note'] = this.note;
data['supervisor'] = this.supervisor;
return data;
}
}

View File

@@ -0,0 +1,36 @@
class PersonalInformationModel {
String? mUserID;
String? mUserUsername;
String? mUserPassword;
String? natStaffName;
String? natStaffNIK;
String? mCourierID;
PersonalInformationModel(
{this.mUserID,
this.mUserUsername,
this.mUserPassword,
this.natStaffName,
this.natStaffNIK,
this.mCourierID});
PersonalInformationModel.fromJson(Map<String, dynamic> json) {
mUserID = json['M_UserID'];
mUserUsername = json['M_UserUsername'];
mUserPassword = json['M_UserPassword'];
natStaffName = json['Nat_StaffName'];
natStaffNIK = json['Nat_StaffNIK'];
mCourierID = json['M_CourierID'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['M_UserID'] = this.mUserID;
data['M_UserUsername'] = this.mUserUsername;
data['M_UserPassword'] = this.mUserPassword;
data['Nat_StaffName'] = this.natStaffName;
data['Nat_StaffNIK'] = this.natStaffNIK;
data['M_CourierID'] = this.mCourierID;
return data;
}
}

View File

@@ -0,0 +1,25 @@
class ResponseListBranchModel {
String? branchid;
String? branchcode;
String? branchname;
String? branchaddress;
ResponseListBranchModel(
{this.branchid, this.branchcode, this.branchname, this.branchaddress});
ResponseListBranchModel.fromJson(Map<String, dynamic> json) {
branchid = json['branchid'];
branchcode = json['branchcode'];
branchname = json['branchname'];
branchaddress = json['branchaddress'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['branchid'] = branchid;
data['branchcode'] = branchcode;
data['branchname'] = branchname;
data['branchaddress'] = branchaddress;
return data;
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,86 @@
import 'dart:convert';
import 'patient_model.dart';
class ResponseSearchPengantaranHasilModel {
String? deliveryid;
String? tipeid;
String? tipe;
String? sourceId;
String? nama;
String? nomor;
String? detail;
String? alamat;
String? branchid;
String? branchcode;
String? branchname;
String? branchaddress;
List<PatientModel>? patients;
ResponseSearchPengantaranHasilModel(
{this.deliveryid,
this.tipeid,
this.tipe,
this.sourceId,
this.nama,
this.nomor,
this.detail,
this.alamat,
this.branchid,
this.branchcode,
this.branchname,
this.branchaddress,
this.patients});
ResponseSearchPengantaranHasilModel.fromJson(Map<String, dynamic> json) {
deliveryid = json['id'];
tipeid = json['tipeid'];
tipe = json['tipe'];
sourceId = json['source_id'];
nama = json['nama'];
nomor = json['nomor'];
detail = json['detail'];
alamat = json['alamat'];
branchid = json['branchid'];
branchcode = json['branchcode'];
branchname = json['branchname'];
branchaddress = json['branchaddress'];
// patients = json['patients'];
if (json['patients'].toString().isNotEmpty) {
var data = <PatientModel>[];
// print("hasil json decode");
// print(jsonDecode(json['patients']));
// print("end");
try {
jsonDecode(json['patients']).forEach((v) {
data.add(PatientModel.fromJson(v));
});
} catch (e) {
print(e);
}
patients = data;
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = deliveryid;
data['tipeid'] = tipeid;
data['tipe'] = tipe;
data['source_id'] = sourceId;
data['nama'] = nama;
data['nomor'] = nomor;
data['detail'] = detail;
data['alamat'] = alamat;
data['branchid'] = branchid;
data['branchcode'] = branchcode;
data['branchname'] = branchname;
data['branchaddress'] = branchaddress;
// data['patients'] = patients;
if (patients != null || patients != "") {
data['patients'] = patients!.map((v) => v.toJson()).toList();
}
return data;
}
}

View File

@@ -0,0 +1,92 @@
import 'dart:convert';
import '../models/patient_model.dart';
class WorkListModel {
int? id;
int? tipeid;
String? tipe;
String? noSuratJalan;
String? nama;
String? noLab;
String? alamat;
String? statusTransaksi;
String? branchid;
String? branchcode;
String? branchname;
String? branchaddress;
String? supervisor;
List<PatientModel>? patients;
String? note;
WorkListModel(
{this.id,
this.tipeid,
this.tipe,
this.noSuratJalan,
this.nama,
this.noLab,
this.alamat,
this.statusTransaksi,
this.branchid,
this.branchcode,
this.branchname,
this.branchaddress,
this.patients,
this.note});
WorkListModel.fromJson(Map<String, dynamic> json) {
id = int.parse(json['id']);
tipeid = int.parse(json['tipeid']);
tipe = json['tipe'];
noSuratJalan = json['no_surat_jalan'];
nama = json['nama'];
noLab = json['no_lab'];
alamat = json['alamat'];
statusTransaksi = json['status_transaksi'];
branchid = json['branchid'];
branchcode = json['branchcode'];
branchname = json['branchname'];
branchaddress = json['branchaddress'];
note = json['note'];
supervisor = json['supervisor'];
// print("patient :" + json['patients']);
if (json['patients'].toString().isNotEmpty) {
var data = <PatientModel>[];
// print("hasil json decode");
// print(jsonDecode(json['patients']));
// print("end");
try {
jsonDecode(json['patients']).forEach((v) {
data.add(PatientModel.fromJson(v));
});
} catch (e) {
print(e);
}
patients = data;
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['tipeid'] = this.tipeid;
data['tipe'] = this.tipe;
data['no_surat_jalan'] = this.noSuratJalan;
data['nama'] = this.nama;
data['no_lab'] = this.noLab;
data['alamat'] = this.alamat;
data['status_transaksi'] = this.statusTransaksi;
data['branchid'] = this.branchid;
data['branchcode'] = this.branchcode;
data['branchname'] = this.branchname;
data['branchaddress'] = this.branchaddress;
data['patients'] = this.patients;
if (this.patients != null || this.patients != "") {
data['patients'] = this.patients!.map((v) => v.toJson()).toList();
}
data['note'] = this.note;
data['supervisor'] = this.supervisor;
return data;
}
}

View File

@@ -0,0 +1,18 @@
class WorkStatusModel {
String? statusid;
String? statusname;
WorkStatusModel({this.statusid, this.statusname});
WorkStatusModel.fromJson(Map<String, dynamic> json) {
statusid = json['statusid'];
statusname = json['statusname'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['statusid'] = this.statusid;
data['statusname'] = this.statusname;
return data;
}
}

View File

@@ -0,0 +1,18 @@
class WorkSupervisorModel {
String? supervisorid;
String? supervisorname;
WorkSupervisorModel({this.supervisorid, this.supervisorname});
WorkSupervisorModel.fromJson(Map<String, dynamic> json) {
supervisorid = json['supervisorid'];
supervisorname = json['supervisorname'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['supervisorid'] = this.supervisorid;
data['supervisorname'] = this.supervisorname;
return data;
}
}

View File

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

View File

@@ -0,0 +1,32 @@
class WorkTypeModel {
int? id;
String? name;
WorkTypeModel({this.id, this.name});
WorkTypeModel.fromJson(Map<String, dynamic> json) {
id = int.parse(json['tipeid']);
name = json['tipename'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['tipeid'] = this.id;
data['tipename'] = this.name;
return data;
}
}
// 1 Pengantaran Hasil Pasien
// 2 Pengantaran Hasil Instansi
// 3 Pengantaran Hasil Dokter
// 4 Lain-lain
// 5 Pengambilan Sampel
// List<WorkTypeModel> WorkTypeData = [
// WorkTypeModel(id: 1, name: "Pengantaran Hasil Pasien"),
// WorkTypeModel(id: 2, name: "Pengantaran Hasil Instansi"),
// WorkTypeModel(id: 3, name: "Pengantaran Hasil Dokter"),
// WorkTypeModel(id: 4, name: "Lain-lain"),
// WorkTypeModel(id: 5, name: "Pengambilan Sampel"),
// ];

View File

@@ -0,0 +1,4 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
final barcodeScanResult = StateProvider<String>((ref) => "");
final isFromScanScreen = StateProvider<bool?>((ref) => false);

View File

@@ -0,0 +1,5 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../models/auth_model.dart';
final currentUserProvider = StateProvider<AuthModel?>((ref) => null);

View File

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

View File

@@ -0,0 +1,8 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
import '../models/history_type_model.dart';
final selectedTypeProvider = StateProvider<HistoryTypeModel>(
(ref) => HistoryTypeModel(tipeid: "0", tipename: "Semua"));
final dateFilterProvider = StateProvider<DateTime>((ref) => DateTime.now());

View File

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

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 DioError 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 DioError 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,29 @@
import 'dart:convert';
import '../models/personal_information_model.dart';
import '../app/constant.dart';
import '../models/response_save_change_password_model.dart';
import 'base_repository.dart';
class ChangePasswordRepository extends BaseRepository {
ChangePasswordRepository({required super.dio});
Future<ResponseSaveChangePasswordModel> ubahPassword(
{required String userID,
required String oldPassword,
required String newPassword}) async {
final param = {
"userid": userID,
"old": oldPassword,
"new": newPassword,
};
print(param);
final url =
"${Constant.baseUrl}/v1/courier/login/change_password/?userid=$userID&old=$oldPassword&new=$newPassword";
final resp = await post(param: param, service: url);
return ResponseSaveChangePasswordModel.fromJson(resp);
}
}

View File

@@ -0,0 +1,35 @@
import '../models/company_model.dart';
import '../models/work_status_model.dart';
import '../models/work_supervisor_model.dart';
import '../app/constant.dart';
import '../models/work_type_model.dart';
import 'base_repository.dart';
class CompanyRepository extends BaseRepository {
CompanyRepository({required super.dio});
Future<List<CompanyModel>> search({required String keyword}) async {
// http: //10.9.9.3/one-api/v1/courier/mobile/inputcourier/search_company_all/?search=sas
final url = Constant.baseUrl +
"/v1/courier/mobile/inputcourier/search_company_all/?search=$keyword";
final resp = await get(service: url);
List<CompanyModel> data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = [];
if (resp['data'] != null) {
resp['data']['records'].forEach((e) {
final model = CompanyModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
} else {
data = [];
}
return data;
}
}

View File

@@ -0,0 +1,65 @@
import '../models/work_status_model.dart';
import '../models/work_supervisor_model.dart';
import '../app/constant.dart';
import '../models/work_type_model.dart';
import 'base_repository.dart';
class FilterRepository extends BaseRepository {
FilterRepository({required super.dio});
Future<List<WorkTypeModel>> getType() async {
final url = Constant.baseUrl + "/v1/courier/mobile/homescreen/list_tipe";
final resp = await get(service: url);
List<WorkTypeModel> data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = [];
resp['data'].forEach((e) {
final model = WorkTypeModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
Future<List<WorkStatusModel>> getStatus() async {
final url = Constant.baseUrl + "v1/courier/mobile/homescreen/list_status";
final resp = await get(service: url);
List<WorkStatusModel> data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = [];
resp['data'].forEach((e) {
final model = WorkStatusModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
Future<List<WorkSupervisorModel>> getSupervisor() async {
final url =
Constant.baseUrl + "v1/courier/mobile/homescreen/list_supervisor";
final resp = await get(service: url);
List<WorkSupervisorModel> data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = [];
resp['data'].forEach((e) {
final model = WorkSupervisorModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
}

View File

@@ -0,0 +1,59 @@
import '../app/constant.dart';
import 'base_repository.dart';
class GetOtherRepository extends BaseRepository {
GetOtherRepository({required super.dio});
Future<bool> setLocation(
{required String id,
required String step,
required String lat,
required String long,
required String address,
required String branchID}) async {
final url =
"${Constant.baseUrl}/v1/courier/mobile/process/add_other/?id=$id&locid=$step&lat=$lat&long=$long&address=$address&branchid=$branchID";
final resp = await get(service: url);
bool data = false;
if (resp['status'] == "OK") {
data = true;
}
return data;
}
Future<bool> setDeliveryPerson({
required String id,
required String name,
required String note,
}) async {
final url =
"${Constant.baseUrl}/v1/courier/mobile/process/update_deliver_other/?id=$id&name=$name&note=$note";
final resp = await get(service: url);
bool data = false;
if (resp['status'] == "OK") {
data = true;
}
return data;
}
Future<bool> setReceivePerson({
required String id,
required String name,
required String note,
}) async {
final url =
"${Constant.baseUrl}/v1/courier/mobile/process/update_receive_other/?id=$id&name=$name&note=$note";
final resp = await get(service: url);
bool data = false;
if (resp['status'] == "OK") {
data = true;
}
return data;
}
}

View File

@@ -0,0 +1,72 @@
import '../app/constant.dart';
import 'base_repository.dart';
class GetSampleRepository extends BaseRepository {
GetSampleRepository({required super.dio});
Future<bool> setLocation(
{required String id,
required String step,
required String lat,
required String long,
required String address,
required String branchID}) async {
final url =
"${Constant.baseUrl}/v1/courier/mobile/process/add_sample/?id=$id&locid=$step&lat=$lat&long=$long&address=$address&branchid=$branchID";
final resp = await get(service: url);
bool data = false;
if (resp['status'] == "OK") {
data = true;
}
return data;
}
Future<bool> setDeliveryPerson({
required String id,
required String name,
required String note,
// Inputan INFO
required String jumlahPasien,
required String edtaRutin,
required String darahCitras,
required String serum,
required String urine,
required String pleura,
required String otherTextBahan,
required String totalOther,
}) async {
// final url =
// "${Constant.baseUrl}/v1/courier/mobile/process/update_deliver_sample/?id=$id&name=$name&note=$note";
final url =
"${Constant.baseUrl}/v1/courier/mobile/process/update_deliver_sample/?id=$id&name=$name&note=$note&t_patient=$jumlahPasien&t_edta=$edtaRutin&t_citras=$darahCitras&t_serum=$serum&t_urine=$urine&t_pleura=$pleura&t_other=$totalOther&other=$otherTextBahan";
final resp = await get(service: url);
bool data = false;
if (resp['status'] == "OK") {
data = true;
}
return data;
}
Future<bool> setReceivePerson({
required String id,
required String name,
required String note,
required String suhuSample,
}) async {
final url =
"${Constant.baseUrl}/v1/courier/mobile/process/update_receive_sample/?id=$id&name=$name&note=$note&suhu=$suhuSample";
final resp = await get(service: url);
bool data = false;
if (resp['status'] == "OK") {
data = true;
}
return data;
}
}

View File

@@ -0,0 +1,78 @@
import 'dart:convert';
import '../models/detail_history_model.dart';
import '../models/history_model.dart';
import '../models/history_type_model.dart';
import '../models/work_status_model.dart';
import '../models/work_supervisor_model.dart';
import '../app/constant.dart';
import '../models/work_type_model.dart';
import 'base_repository.dart';
class HistoryRepository extends BaseRepository {
HistoryRepository({required super.dio});
Future<List<HistoryModel>> getData(
{required String id, required String date, required String type}) async {
// http: //10.9.9.3/one-api/v1/courier/mobile/history/list_all/?id=40&startdate=11-09-2023&tipeid=3
final url = Constant.baseUrl +
"/v1/courier/mobile/history/list_all/?id=$id&startdate=$date&tipeid=$type";
final resp = await get(service: url);
List<HistoryModel> data = [];
print(resp['data']);
if (resp['status'] == 'OK') {
data = [];
resp['data'].forEach((e) {
final model = HistoryModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
Future<DetailHistoryModel> getDetail(
{required String id,
required String tipeId,
required String deliveryId}) async {
final url =
"${Constant.baseUrl}/v1/courier/mobile/history/list_by_id/?id=$id&tipeid=$tipeId&deliveryid=$deliveryId";
final resp = await get(service: url);
// DetailHistoryModel data;
// print(resp['data']);
DetailHistoryModel data = DetailHistoryModel.fromJson(resp['data'][0]);
// resp['data'].forEach((e) {
// final model = HistoryModel.fromJson(e);
// data.add(model);
// });
// }
// print(data.alamatPengambilan);
return data;
}
Future<List<HistoryTypeModel>> getHistoryType() async {
// http: //10.9.9.3/one-api/v1/courier/mobile/homescreen/list_tipe_history
final url =
"${Constant.baseUrl}/v1/courier/mobile/homescreen/list_tipe_history";
final resp = await get(service: url);
// DetailHistoryModel data;
// print(resp['data']);
List<HistoryTypeModel> data = List.empty(growable: true);
resp['data'].forEach((e) {
final model = HistoryTypeModel.fromJson(e);
data.add(model);
});
// print(data.alamatPengambilan);
return data;
}
}

View File

@@ -0,0 +1,42 @@
import 'dart:convert';
import '../app/constant.dart';
import '../models/pending_work_model.dart';
import '../models/work_total_model.dart';
import 'base_repository.dart';
class HomeScreenRepository extends BaseRepository {
HomeScreenRepository({required super.dio});
Future<WorkTotalModel> getTotalWork({required String id}) async {
final url =
Constant.baseUrl + "v1/courier/mobile/homescreen/list_total/?id=$id";
final resp = await get(service: url);
WorkTotalModel data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = WorkTotalModel.fromJson(resp['data']);
} else {
data = {} as WorkTotalModel;
}
return data;
}
Future<List<PendingWorkModel>> getPendingWork({required String id}) async {
final url =
Constant.baseUrl + "/v1/courier/mobile/homescreen/list_order/?id=$id";
final resp = await get(service: url);
List<PendingWorkModel> data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = [];
resp['data'].forEach((e) {
final model = PendingWorkModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
}

View File

@@ -0,0 +1,76 @@
import '../app/constant.dart';
import '../models/auth_model.dart';
import '../models/response_list_branch_model.dart';
import '../models/response_save_pengantaran_hasil_model.dart';
import '../models/response_search_pengantaran_hasil_model.dart';
import 'base_repository.dart';
class DummyNoLabDokter {
final String noLab;
final int idLab;
final String nama;
final String alamatPengantaran;
DummyNoLabDokter(
this.noLab,
this.idLab,
this.nama,
this.alamatPengantaran
);
}
class InputLainLainRepository extends BaseRepository {
InputLainLainRepository({required super.dio});
List<DummyNoLabDokter> result = [
DummyNoLabDokter("110378", 1, "Agas", "Jl wora wari"),
DummyNoLabDokter("110390", 2, "Indy Ratna", "Jl moestopo"),
DummyNoLabDokter("140390", 3, "Jarot", "Jl pahlawan no 1"),
DummyNoLabDokter("190390", 4, "Deny", "Jl Ir Soekarno"),
DummyNoLabDokter("119090", 5, "Said Hasan", "Jl mawar no 04"),
DummyNoLabDokter("110391", 1, "Jarot P", "Jl nawangsih no 07"),
DummyNoLabDokter("110399", 2, "Joko S", "Jl Pegangsaan no 04"),
];
Future<List<ResponseListBranchModel>> loadListCabangInputLainLain() async {
final service =
"${Constant.baseUrl}v1/courier/mobile/homescreen/list_branch";
final resp = await get(service: service);
final result = List<ResponseListBranchModel>.empty(growable: true);
if (resp['data'] != null) {
resp['data'].forEach((e) {
final model = ResponseListBranchModel.fromJson(e);
result.add(model);
});
}
return result;
}
Future<ResponseSavePengantaranHasilModel> inputLainLainSave({
required String courierID,
required String tipeID,
required String branchID,
required String branchCode,
required String pickup,
required String destination,
required String note
}) async {
final param = {
"id": courierID,
"tipeid": tipeID,
"branchid": branchID,
"branchcode": branchCode,
"pickup": pickup,
"destination":destination,
"note": note
};
print("param : $param");
final service = "${Constant.baseUrl}v1/courier/mobile/inputcourier/add/?id=$courierID&tipeid=$tipeID&branchid=$branchID&branchcode=$branchCode&pickup=$pickup&destination=$destination&note=$note";
final resp = await post(param: param, service: service);
return ResponseSavePengantaranHasilModel.fromJson(resp);
}
}

View File

@@ -0,0 +1,28 @@
import 'dart:convert';
import '../app/constant.dart';
import '../app/constant.dart';
import 'base_repository.dart';
class KurirTolakRepository extends BaseRepository {
KurirTolakRepository({required super.dio});
Future<bool> getKurirTolak(
{required String id,
required String tipeId,
required String deliveryId,
required String note}) async {
final url =
"${Constant.baseUrl}/v1/courier/mobile/worklist/cancel/?id=$id&tipeid=$tipeId&deliveryid=$deliveryId&note=$note";
final resp = await get(service: url);
bool data = false;
// print(resp['data']);
if (resp["status"] == "OK") {
data = true;
}
return data;
}
}

View File

@@ -0,0 +1,74 @@
import '../app/constant.dart';
import '../models/auth_model.dart';
import '../models/response_list_branch_model.dart';
import '../models/response_save_pengantaran_hasil_model.dart';
import '../models/response_search_pengantaran_hasil_model.dart';
import 'base_repository.dart';
class DummyNoLabDokter {
final String noLab;
final int idLab;
final String nama;
final String alamatPengantaran;
DummyNoLabDokter(
this.noLab,
this.idLab,
this.nama,
this.alamatPengantaran
);
}
class PengambilanBahanRepository extends BaseRepository {
PengambilanBahanRepository({required super.dio});
List<DummyNoLabDokter> result = [
DummyNoLabDokter("110378", 1, "Agas", "Jl wora wari"),
DummyNoLabDokter("110390", 2, "Indy Ratna", "Jl moestopo"),
DummyNoLabDokter("140390", 3, "Jarot", "Jl pahlawan no 1"),
DummyNoLabDokter("190390", 4, "Deny", "Jl Ir Soekarno"),
DummyNoLabDokter("119090", 5, "Said Hasan", "Jl mawar no 04"),
DummyNoLabDokter("110391", 1, "Jarot P", "Jl nawangsih no 07"),
DummyNoLabDokter("110399", 2, "Joko S", "Jl Pegangsaan no 04"),
];
Future<List<ResponseListBranchModel>> loadListCabangPengambilanBahan() async {
final service =
"${Constant.baseUrl}v1/courier/mobile/homescreen/list_branch";
final resp = await get(service: service);
final result = List<ResponseListBranchModel>.empty(growable: true);
if (resp['data'] != null) {
resp['data'].forEach((e) {
final model = ResponseListBranchModel.fromJson(e);
result.add(model);
});
}
return result;
}
Future<ResponseSavePengantaranHasilModel> pengambilanBahanSave({
required String courierID,
required String tipeID,
required String branchID,
required String branchCode,
required String name,
required String destination
}) async {
final param = {
"id": courierID,
"tipeid": tipeID,
"branchid": branchID,
"branchcode": branchCode,
"name": name,
"destination":destination
};
print("param : $param");
final service = "${Constant.baseUrl}v1/courier/mobile/inputcourier/add/?id=$courierID&tipeid=$tipeID&branchid=$branchID&branchcode=$branchCode&name=$name&destination=$destination";
final resp = await post(param: param, service: service);
return ResponseSavePengantaranHasilModel.fromJson(resp);
}
}

View File

@@ -0,0 +1,72 @@
import '../app/constant.dart';
import '../models/auth_model.dart';
import '../models/response_save_pengantaran_hasil_model.dart';
import '../models/response_search_pengantaran_hasil_model.dart';
import 'base_repository.dart';
class DummyNoLabDokter {
final String noLab;
final int idLab;
final String nama;
final String alamatPengantaran;
DummyNoLabDokter(
this.noLab,
this.idLab,
this.nama,
this.alamatPengantaran
);
}
class PengantaranHasilDokterRepository extends BaseRepository {
PengantaranHasilDokterRepository({required super.dio});
List<DummyNoLabDokter> result = [
DummyNoLabDokter("110378", 1, "Agas", "Jl wora wari"),
DummyNoLabDokter("110390", 2, "Indy Ratna", "Jl moestopo"),
DummyNoLabDokter("140390", 3, "Jarot", "Jl pahlawan no 1"),
DummyNoLabDokter("190390", 4, "Deny", "Jl Ir Soekarno"),
DummyNoLabDokter("119090", 5, "Said Hasan", "Jl mawar no 04"),
DummyNoLabDokter("110391", 1, "Jarot P", "Jl nawangsih no 07"),
DummyNoLabDokter("110399", 2, "Joko S", "Jl Pegangsaan no 04"),
];
Future<List<ResponseSearchPengantaranHasilModel>> loadListNoDokterPengantaranHasilDokter({
required String search,
}) async {
final param = {
"search": search,
};
final service =
"${Constant.baseUrl}v1/courier/mobile/inputcourier/search_doctor/?search=$search";
final resp = await post(param: param, service: service);
final result = List<ResponseSearchPengantaranHasilModel>.empty(growable: true);
if (resp['data'] != null) {
resp['data']['records'].forEach((e) {
final model = ResponseSearchPengantaranHasilModel.fromJson(e);
result.add(model);
});
}
return result;
}
Future<ResponseSavePengantaranHasilModel> pengantaranHasilDokterSave({
required String courierID,
required String tipeID,
required String deliveryID,
}) async {
final param = {
"id": courierID,
"tipeid": tipeID,
"deliveryid": deliveryID
};
print("param : $param");
final service = "${Constant.baseUrl}v1/courier/mobile/inputcourier/add/?id=$courierID&tipeid=$tipeID&deliveryid=$deliveryID";
final resp = await post(param: param, service: service);
return ResponseSavePengantaranHasilModel.fromJson(resp);
}
}

View File

@@ -0,0 +1,71 @@
import '../app/constant.dart';
import '../models/auth_model.dart';
import '../models/response_save_pengantaran_hasil_model.dart';
import '../models/response_search_pengantaran_hasil_model.dart';
import 'base_repository.dart';
class DummyNoSuratJalan {
final String noSuratJalan;
final int idSuratJalan;
final String nama;
final String alamatPengantaran;
DummyNoSuratJalan(
this.noSuratJalan,
this.idSuratJalan,
this.nama,
this.alamatPengantaran
);
}
class PengantaranHasilInstansiRepository extends BaseRepository {
PengantaranHasilInstansiRepository({required super.dio});
List<DummyNoSuratJalan> result = [
DummyNoSuratJalan("110378", 1, "Agas", "Jl wora wari"),
DummyNoSuratJalan("110390", 2, "Indy Ratna", "Jl moestopo"),
DummyNoSuratJalan("140390", 3, "Jarot", "Jl pahlawan no 1"),
DummyNoSuratJalan("190390", 4, "Deny", "Jl Ir Soekarno"),
DummyNoSuratJalan("119090", 5, "Said Hasan", "Jl mawar no 04"),
DummyNoSuratJalan("110391", 1, "Jarot P", "Jl nawangsih no 07"),
DummyNoSuratJalan("110399", 2, "Joko S", "Jl Pegangsaan no 04"),
];
Future<List<ResponseSearchPengantaranHasilModel>> loadListNoSuratJalanPengantaranHasilInstansi({
required String search,
}) async {
final param = {
"search": search,
};
final service =
"${Constant.baseUrl}v1/courier/mobile/inputcourier/search_company/?search=$search";
final resp = await post(param: param, service: service);
final result = List<ResponseSearchPengantaranHasilModel>.empty(growable: true);
if (resp['data'] != null) {
resp['data']['records'].forEach((e) {
final model = ResponseSearchPengantaranHasilModel.fromJson(e);
result.add(model);
});
}
return result;
}
Future<ResponseSavePengantaranHasilModel> pengantaranHasilInstansiSave({
required String courierID,
required String tipeID,
required String deliveryID,
}) async {
final param = {
"id": courierID,
"tipeid": tipeID,
"deliveryid": deliveryID
};
print("param : $param");
final service = "${Constant.baseUrl}v1/courier/mobile/inputcourier/add/?id=$courierID&tipeid=$tipeID&deliveryid=$deliveryID";
final resp = await post(param: param, service: service);
return ResponseSavePengantaranHasilModel.fromJson(resp);
}
}

View File

@@ -0,0 +1,48 @@
import '../app/constant.dart';
import '../models/response_save_pengantaran_hasil_model.dart';
import '../models/response_search_pengantaran_hasil_model.dart';
import 'base_repository.dart';
class PengantaranHasilPasienRepository extends BaseRepository {
PengantaranHasilPasienRepository({required super.dio});
// search no lab pasien
Future<List<ResponseSearchPengantaranHasilModel>>
loadListNoLabPengantaranHasilPasien({
required String search,
}) async {
final param = {
"search": search,
};
final service =
"${Constant.baseUrl}v1/courier/mobile/inputcourier/search_patient/?search=$search";
final resp = await post(param: param, service: service);
final result = List<ResponseSearchPengantaranHasilModel>.empty(growable: true);
if (resp['data'] != null) {
resp['data']['records'].forEach((e) {
final model = ResponseSearchPengantaranHasilModel.fromJson(e);
result.add(model);
});
}
return result;
}
// simpan input pengantaran hasil pasien
Future<ResponseSavePengantaranHasilModel> pengantaranHasilPasienSave({
required String courierID,
required String tipeID,
required String deliveryID,
}) async {
final param = {
"id": courierID,
"tipeid": tipeID,
"deliveryid": deliveryID
};
final service = "${Constant.baseUrl}v1/courier/mobile/inputcourier/add/?id=$courierID&tipeid=$tipeID&deliveryid=$deliveryID";
final resp = await post(param: param, service: service);
return ResponseSavePengantaranHasilModel.fromJson(resp);
}
}

View File

@@ -0,0 +1,34 @@
import 'dart:convert';
import '../models/personal_information_model.dart';
import '../app/constant.dart';
import 'base_repository.dart';
class PersonalInformationRepository extends BaseRepository {
PersonalInformationRepository({required super.dio});
Future<List<PersonalInformationModel>> getPersonalInformation(
{required String mCourierID}) async {
final param = {
"id": mCourierID
};
final url =
"${Constant.baseUrl}/v1/courier/mobile/profile/info/?id=$mCourierID";
final resp = await get(service: url);
// print("url :" + url);
List<PersonalInformationModel> data;
// print(resp['data']);
if (resp['status'] == 'OK' && resp['status'] != null) {
data = [];
resp['data'].forEach((e) {
final model = PersonalInformationModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
}

View File

@@ -0,0 +1,59 @@
import '../app/constant.dart';
import 'base_repository.dart';
class ResultDeliveryRepository extends BaseRepository {
ResultDeliveryRepository({required super.dio});
Future<bool> setLocation(
{required String id,
required String step,
required String lat,
required String long,
required String address,
required String branchID}) async {
final url =
"${Constant.baseUrl}/v1/courier/mobile/process/add_delivery/?id=$id&locid=$step&lat=$lat&long=$long&address=$address&branchid=$branchID";
final resp = await get(service: url);
bool data = false;
if (resp['status'] == "OK") {
data = true;
}
return data;
}
Future<bool> setDeliveryPerson({
required String id,
required String name,
required String note,
}) async {
final url =
"${Constant.baseUrl}/v1/courier/mobile/process/update_deliver/?id=$id&name=$name&note=$note";
final resp = await get(service: url);
bool data = false;
if (resp['status'] == "OK") {
data = true;
}
return data;
}
Future<bool> setReceivePerson({
required String id,
required String name,
required String note,
}) async {
final url =
"${Constant.baseUrl}/v1/courier/mobile/process/update_receive/?id=$id&name=$name&note=$note";
final resp = await get(service: url);
bool data = false;
if (resp['status'] == "OK") {
data = true;
}
return data;
}
}

View File

@@ -0,0 +1,28 @@
import '../app/constant.dart';
import '../models/response_save_work_suhu_model.dart';
import 'base_repository.dart';
class WorkInputSuhuRepository extends BaseRepository {
WorkInputSuhuRepository({required super.dio});
Future<ResponseSaveWorkSuhuModel> inputWorkSuhu({
required String deliveryId,
required String suhu
}) async {
final param = {
"id": deliveryId,
"suhu": suhu
};
print("param : $param");
// Pengantaran Hasil => tipeID 1
// Lain-lain => tipeID 4
// Pengambilan Bahan => tipeID 5
final service = "${Constant.baseUrl}v1/courier/mobile/process/update_temperatur_box/?id=$deliveryId&suhu=$suhu";
final resp = await post(param: param, service: service);
return ResponseSaveWorkSuhuModel.fromJson(resp);
}
}

View File

@@ -0,0 +1,58 @@
import 'dart:convert';
import '../models/work_list_model.dart';
import '../app/constant.dart';
import '../models/detail_work_model.dart';
import '../models/pending_work_model.dart';
import '../models/work_total_model.dart';
import 'base_repository.dart';
class WorkListRepository extends BaseRepository {
WorkListRepository({required super.dio});
Future<List<WorkListModel>> getListWork(
{required String id,
required String tipeId,
required String supervisor,
required String status}) async {
final url =
"${Constant.baseUrl}/v1/courier/mobile/worklist/listbycourierv2/?id=$id&tipeid=$tipeId&status='$status'&supervisor='$supervisor'";
final resp = await get(service: url);
// print("url :" + url);
List<WorkListModel> data;
// print(resp['data']);
if (resp['status'] == 'OK' && resp['status'] != null) {
data = [];
resp['data'].forEach((e) {
final model = WorkListModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
return data;
}
Future<DetailWorkModel> getDetail(
{required String id,
required String tipeId,
required String deliveryId}) async {
final url =
"${Constant.baseUrl}/v1/courier/mobile/worklist/list_by_id/?id=$id&tipeid=$tipeId&deliveryid=$deliveryId";
final resp = await get(service: url);
// DetailWorkModel data;
// print(resp['data']);
DetailWorkModel data = DetailWorkModel.fromJson(resp['data'][0]);
// resp['data'].forEach((e) {
// final model = HistoryModel.fromJson(e);
// data.add(model);
// });
// }
// print(data.alamatPengambilan);
return data;
}
}

View File

@@ -0,0 +1,32 @@
import '../app/constant.dart';
import '../models/response_save_work_tunda_model.dart';
import 'base_repository.dart';
class WorkTundaRepository extends BaseRepository {
WorkTundaRepository({required super.dio});
Future<ResponseSaveWorkTundaModel> inputWorkTunda({
required String courierID,
required String tipeID,
required String deliveryID,
required String note
}) async {
final param = {
"id": courierID,
"tipeid": tipeID,
"deliveryid": deliveryID,
"note": note
};
print("param : $param");
// Pengantaran Hasil => tipeID 1
// Lain-lain => tipeID 4
// Pengambilan Bahan => tipeID 5
final service = "${Constant.baseUrl}v1/courier/mobile/pending/add/?id=$courierID&tipeid=$tipeID&deliveryid=$deliveryID&note=$note";
final resp = await post(param: param, service: service);
return ResponseSaveWorkTundaModel.fromJson(resp);
}
}

View File

@@ -0,0 +1,78 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../models/personal_information_model.dart';
import '../../repository/change_password_repository.dart';
import '../../repository/personal_information_repository.dart';
import '../../repository/work_list_repository.dart';
import '../../models/pending_work_model.dart';
import '../../models/response_save_change_password_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/home_screen_repository.dart';
abstract class ChangePasswordState extends Equatable {
final DateTime date;
const ChangePasswordState(this.date);
@override
List<Object?> get props => [date];
}
class ChangePasswordStateInit extends ChangePasswordState {
ChangePasswordStateInit() : super(DateTime.now());
}
class ChangePasswordStateLoading extends ChangePasswordState {
ChangePasswordStateLoading() : super(DateTime.now());
}
class ChangePasswordStateError extends ChangePasswordState {
final String message;
ChangePasswordStateError({
required this.message,
}) : super(DateTime.now());
}
class ChangePasswordStateDone extends ChangePasswordState {
final ResponseSaveChangePasswordModel model;
ChangePasswordStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class ChangePasswordNotifier extends StateNotifier<ChangePasswordState> {
final Ref ref;
ChangePasswordNotifier({
required this.ref,
}) : super(ChangePasswordStateInit());
void ubahPassword({
required String userID,
required String oldPassword,
required String newPassword,
}) async {
try {
state = ChangePasswordStateLoading();
final dio = ref.read(dioProvider);
final resp = await ChangePasswordRepository(dio: dio)
.ubahPassword(
userID: userID,
oldPassword: oldPassword,
newPassword: newPassword
);
state = ChangePasswordStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = ChangePasswordStateError(message: e.message.toString());
} else {
state = ChangePasswordStateError(message: e.toString());
}
}
}
}
//provider
final ChangePasswordProvider =
StateNotifierProvider<ChangePasswordNotifier, ChangePasswordState>(
(ref) => ChangePasswordNotifier(ref: ref));

View File

@@ -0,0 +1,268 @@
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter/src/widgets/placeholder.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../app/route.dart';
import '../change_password_screen/change_password_provider.dart';
import '/widget/snackbar_widget.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../app/constant.dart';
import '../../provider/current_user_provider.dart';
class ChangePasswordScreen extends HookConsumerWidget {
const ChangePasswordScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final currentPassword = useTextEditingController(text: "");
final passwordNow = useTextEditingController(text: "");
final confirmPassword = useTextEditingController(text: "");
final hideCurrentPassword = useState(true);
final hidePasswordNow = useState(true);
final hideConfirmPassword = useState(true);
final isLoading = useState<bool>(false);
final userID = ref.watch(currentUserProvider)?.model.user?.mUserID ?? "0";
ref.listen(ChangePasswordProvider, (previous, next) async {
if (next is ChangePasswordStateLoading) {
isLoading.value = true;
} else if (next is ChangePasswordStateError) {
isLoading.value = false;
// print(next.message);
SanckbarWidget(
context, next.message, snackbarType.error);
} else if (next is ChangePasswordStateDone) {
isLoading.value = false;
isLoading.value = false;
if (next.model.status != "OK") {
SanckbarWidget(context, "${next.model.message}", snackbarType.error);
} else {
final shared = await SharedPreferences.getInstance();
final passwordSharePref = shared.getString("passwordX");
if (passwordSharePref != null) {
await shared.setString("passwordX", confirmPassword.text);
}
SanckbarWidget(
context,
"Berhasil Mengubah Password",
snackbarType.success);
Navigator.of(context).pushNamedAndRemoveUntil(
menuRoute,
(route) => false,
);
}
}
});
disabledBtn<bool>() {
if (currentPassword.text.isNotEmpty &&
passwordNow.text.isNotEmpty &&
confirmPassword.text.isNotEmpty &&
(passwordNow.text == confirmPassword.text)) {
return true;
} else {
return false;
}
}
return Scaffold(
bottomNavigationBar: Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 35),
vertical: Constant.getActualY(context: context, y: 40)),
child: ElevatedButton(
onPressed: () {
// showDialog(
// context: context,
// builder: (context) {
// return ErrorDialog(
// title: "Something Went Wrong",
// message: "404 Not Found",
// showImage: true,
// showButton: true,
// buttonText: "Close",
// buttonFunction: () {
// print("a");
// });
// },
// );
if (currentPassword.text.isNotEmpty &&
passwordNow.text.isNotEmpty &&
confirmPassword.text.isNotEmpty &&
(passwordNow.text == confirmPassword.text)) {
// print("a");
ref.read(ChangePasswordProvider.notifier).ubahPassword(
userID: userID,
oldPassword: currentPassword.text,
newPassword: passwordNow.text);
} else {
// null;
if (currentPassword.text.isEmpty) {
SanckbarWidget(
context,
"Password Saat ini tidak boleh kosong",
snackbarType.warning);
} else {
if ((passwordNow.text.isEmpty ||
confirmPassword.text.isEmpty)) {
SanckbarWidget(
context,
"Password Saat ini atau Konformasi Password tidak boleh kosong",
snackbarType.warning);
} else {
if ((passwordNow.text != confirmPassword.text)) {
SanckbarWidget(
context,
"Konfirmasi Password & Password Baru harus sama",
snackbarType.warning);
}
}
}
}
},
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
side: const BorderSide(width: 0.1, color: Colors.grey),
borderRadius: BorderRadius.circular(8),
),
),
child: Container(
height: Constant.getActualY(context: context, y: 46),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
"Simpan",
style: TextStyle(fontWeight: FontWeight.bold),
)
],
),
)),
),
body: ListView(
children: [
Container(
height: Constant.getActualY(context: context, y: 56),
),
Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 10)),
height: Constant.getActualY(context: context, y: 48),
child: Row(
children: [
IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: Icon(Icons.arrow_back_ios_rounded),
),
Text(
"Ubah Password",
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textPrimary),
),
],
),
),
Container(
height: Constant.getActualY(context: context, y: 31),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 34)),
child: TextFormField(
controller: currentPassword,
obscureText: hideCurrentPassword.value,
enableSuggestions: false,
autocorrect: false,
decoration: InputDecoration(
suffixIcon: InkWell(
onTap: () {
hideCurrentPassword.value = !hideCurrentPassword.value;
},
child: Icon(!hideCurrentPassword.value
? Icons.remove_red_eye
: Icons.remove_red_eye_outlined)),
labelText: "Password Saat Ini",
hintText: "Password Saat Ini",
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
),
),
),
Container(
height: Constant.getActualY(context: context, y: 24),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 34)),
child: TextFormField(
controller: passwordNow,
obscureText: hidePasswordNow.value,
enableSuggestions: false,
autocorrect: false,
decoration: InputDecoration(
suffixIcon: InkWell(
onTap: () {
hidePasswordNow.value = !hidePasswordNow.value;
},
child: Icon(!hidePasswordNow.value
? Icons.remove_red_eye
: Icons.remove_red_eye_outlined)),
labelText: "Password Baru",
hintText: "Password Baru",
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
),
),
),
Container(
height: Constant.getActualY(context: context, y: 24),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 34)),
child: TextFormField(
controller: confirmPassword,
obscureText: hideConfirmPassword.value,
enableSuggestions: false,
autocorrect: false,
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: (value) {
if (value != passwordNow.text) {
return "Konfirmasi password berbeda";
}
},
onEditingComplete: () {
FocusScope.of(context).unfocus();
},
// onChanged: (e) {
// if (e != passwordNow.text) {
// print("diff");
// }
// },
decoration: InputDecoration(
suffixIcon: InkWell(
onTap: () {
hideConfirmPassword.value = !hideConfirmPassword.value;
},
child: Icon(!hideConfirmPassword.value
? Icons.remove_red_eye
: Icons.remove_red_eye_outlined)),
labelText: "konfirmasi Password Baru",
hintText: "konfirmasi Password Baru",
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
),
),
),
],
),
);
}
}

View File

@@ -0,0 +1,72 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '/models/detail_history_model.dart';
import '/models/history_model.dart';
import '/../repository/history_screen_repository.dart';
import '/screen/history_screen/history_screen.dart';
import '../../models/pending_work_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/home_screen_repository.dart';
abstract class DetailHistoryState extends Equatable {
final DateTime date;
const DetailHistoryState(this.date);
@override
List<Object?> get props => [date];
}
class DetailHistoryStateInit extends DetailHistoryState {
DetailHistoryStateInit() : super(DateTime.now());
}
class DetailHistoryStateLoading extends DetailHistoryState {
DetailHistoryStateLoading() : super(DateTime.now());
}
class DetailHistoryStateError extends DetailHistoryState {
final String message;
DetailHistoryStateError({
required this.message,
}) : super(DateTime.now());
}
class DetailHistoryStateDone extends DetailHistoryState {
final DetailHistoryModel model;
DetailHistoryStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class DetailHistoryNotifier extends StateNotifier<DetailHistoryState> {
final Ref ref;
DetailHistoryNotifier({
required this.ref,
}) : super(DetailHistoryStateInit());
void getData(
{required String id,
required String tipeId,
required String deliveryId}) async {
try {
state = DetailHistoryStateLoading();
final dio = ref.read(dioProvider);
final resp = await HistoryRepository(dio: dio)
.getDetail(id: id, tipeId: tipeId, deliveryId: deliveryId);
state = DetailHistoryStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = DetailHistoryStateError(message: e.message.toString());
} else {
state = DetailHistoryStateError(message: e.toString());
}
}
}
}
//provider
final DetailHistoryProvider =
StateNotifierProvider<DetailHistoryNotifier, DetailHistoryState>(
(ref) => DetailHistoryNotifier(ref: ref));

View File

@@ -0,0 +1,792 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter/src/widgets/placeholder.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:geolocator/geolocator.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:intl/intl.dart';
import '/models/detail_history_model.dart';
import '/screen/detail_history_screen/detail_history_provider.dart';
import '/widget/chip_type.dart';
import '/widget/patient_card.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:maps_launcher/maps_launcher.dart';
import '../../app/constant.dart';
import '../../widget/snackbar_widget.dart';
class DetailHistoryProp {
final String tipeId;
final String kurirId;
final String deliveryId;
DetailHistoryProp(this.tipeId, this.kurirId, this.deliveryId);
}
class DetailHistoryScreen extends HookConsumerWidget {
const DetailHistoryScreen(
{super.key, required this.data, required this.prop});
final Map<String, dynamic> data;
final DetailHistoryProp prop;
@override
Widget build(BuildContext context, WidgetRef ref) {
final detailLoading = useState(false);
final detailData = useState<DetailHistoryModel>(DetailHistoryModel());
var formattedDate = useState('');
final pengambilanAwalLoc = useState<Map<String, String>>(
{"long": "110.7104622", "lat": "-7.5031631"});
final pengambilanAkhirLoc = useState<Map<String, String>>(
{"long": "110.7104622", "lat": "-7.5031631"});
final pengantaranAwalLoc = useState<Map<String, String>>(
{"long": "110.7104622", "lat": "-7.5031631"});
final pengantaranAkhirLoc = useState<Map<String, String>>(
{"long": "110.7104622", "lat": "-7.5031631"});
final petugasPengambilan = useState("Liliana Ruby");
final petugasPengantaran = useState("Liliana Ruby");
final catatanPengambilan = useState("Lengkap");
final catatanPengantaran = useState("Lengkap");
List<Map<String, String>> listPasien = [
{"id": "1", "name": "Sabrina Dewi", "no_lab": "112035"},
{"id": "2", "name": "Lisa Andriani", "no_lab": "113040"},
{"id": "3", "name": "Leo Rolly", "no_lab": "112987"},
];
fetchData() {
ref.read(DetailHistoryProvider.notifier).getData(
id: prop.kurirId, tipeId: prop.tipeId, deliveryId: prop.deliveryId);
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
fetchData();
});
return () {};
}, []);
ref.listen(
DetailHistoryProvider,
(previous, next) {
if (next is DetailHistoryStateLoading) {
detailLoading.value = true;
} else if (next is DetailHistoryStateError) {
// print(next.message);
detailLoading.value = false;
SanckbarWidget(
context, next.message.substring(0, 30), snackbarType.error);
} else if (next is DetailHistoryStateDone) {
// print(next.model);
detailData.value = next.model;
String originalDateString = next.model.cdate.toString();
DateTime originalDate =
DateFormat('dd-MM-yyyy HH:mm:ss').parse(originalDateString);
// String formattedDate = DateFormat.yMMMMd('id').format(originalDate);
formattedDate.value = DateFormat('d MMM HH:mm').format(originalDate);
// print("data from json");
// print(next.model.tipeid);
pengambilanAwalLoc.value = {
"long": next.model.lngPengambilanAwal ?? "0",
"lat": next.model.latPengambilanAwal ?? "0"
};
pengambilanAkhirLoc.value = {
"long": next.model.lngPengambilanAkhir ?? "0",
"lat": next.model.latPengambilanAkhir ?? "0"
};
pengantaranAwalLoc.value = {
"long": next.model.lngPengantaranAwal ?? "0",
"lat": next.model.latPengantaranAwal ?? "0"
};
pengantaranAkhirLoc.value = {
"long": next.model.lngPengantaranAkhir ?? "0",
"lat": next.model.latPengantaranAkhir ?? "0"
};
petugasPengambilan.value = next.model.petugasPenyerahan ?? " ";
petugasPengantaran.value = next.model.penerima ?? " ";
catatanPengantaran.value = next.model.notePenerimaan ?? " ";
catatanPengambilan.value = next.model.notePenyerahan ?? " ";
detailLoading.value = false;
}
},
);
return detailLoading.value
? SizedBox(
height: Constant.designHeight * 0.9,
child: Center(
child: LoadingAnimationWidget.fourRotatingDots(
color: Constant.primaryBlue, size: 50),
),
)
: SingleChildScrollView(
child: Column(children: [
SizedBox(
height: Constant.getActualY(context: context, y: 24),
),
Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 20)),
height: Constant.getActualY(context: context, y: 40),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.asset(
"assets/icon_detail_riwayat_motor.png",
width: Constant.getActualX(context: context, x: 64),
height: Constant.getActualX(context: context, x: 64),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
formattedDate.value,
style: Constant.body1(context: context)
.copyWith(fontWeight: FontWeight.w500),
),
ChipType(
name: detailData.value.tipe.toString(),
tipe: int.parse(prop.tipeId),
isDetailHistory: true,
)
],
)
],
),
),
Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 35)),
// color: Colors.red,
height: Constant.getActualY(context: context, y: 737),
child: SingleChildScrollView(
// reverse: MediaQuery.of(context).viewInsets.bottom != 0
// ? true
// : false,
child: Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
child: Column(
// shrinkWrap: true,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
displayDetailText(context, "No. Surat Jalan",
detailData.value.noSuratJalan.toString()),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
displayDetailText(
context, "Nama", detailData.value.nama.toString()),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
if (int.parse(prop.tipeId) == 1)
Container(
margin: EdgeInsets.only(
bottom:
Constant.getActualY(context: context, y: 12),
),
child: displayDetailText(context, "Catatan FO",
detailData.value.foNote ?? ""),
),
if (int.parse(prop.tipeId) == 1 ||
int.parse(prop.tipeId) == 2 ||
int.parse(prop.tipeId) == 3 ||
int.parse(prop.tipeId) == 4 ||
int.parse(prop.tipeId) == 5)
displayDetailText(context, "Catatan Admin",
detailData.value.adminNote ?? ""),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
if (int.parse(prop.tipeId) == 1 ||
int.parse(prop.tipeId) == 2 ||
int.parse(prop.tipeId) == 3)
Text(
"Pengambilan Hasil",
// maxLines: 5,
overflow: TextOverflow.visible,
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textPrimary),
),
if (int.parse(prop.tipeId) == 5)
Text(
"Pengambilan Bahan",
// maxLines: 5,
overflow: TextOverflow.visible,
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textPrimary),
),
if (int.parse(prop.tipeId) == 4)
Text(
"Pengirim",
// maxLines: 5,
overflow: TextOverflow.visible,
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textPrimary),
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Alamat Pengambilan",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
": ${detailData.value.alamatPengambilan}",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
if (pengambilanAwalLoc.value["lat"] == "" ||
pengambilanAwalLoc.value['long'] == "")
Icon(Icons.location_on,
color: Constant.primaryBlue),
if (pengambilanAwalLoc.value["lat"] == "" ||
pengambilanAwalLoc.value['long'] == "")
SizedBox(
width: Constant.getActualX(
context: context, x: 4),
),
Text(
"Lokasi Awal",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
)
],
),
if (pengambilanAwalLoc.value["lat"] != "" ||
pengambilanAwalLoc.value['long'] != "")
InkWell(
onTap: () {
MapsLauncher.launchCoordinates(
double.parse(
pengambilanAwalLoc.value["lat"]!),
double.parse(
pengambilanAwalLoc.value["long"]!));
},
child: Row(
children: [
Text(
"Sudah ditandai",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.primaryBlue),
),
SizedBox(
width: Constant.getActualX(
context: context, x: 4),
),
Icon(
Icons.map_outlined,
color: Constant.primaryBlue,
),
],
),
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
if (pengambilanAkhirLoc.value["lat"] == "" ||
pengambilanAkhirLoc.value['long'] == "")
Icon(
Icons.location_on,
color: Constant.primaryBlue,
),
if (pengambilanAkhirLoc.value["lat"] == "" ||
pengambilanAkhirLoc.value['long'] == "")
SizedBox(
width: Constant.getActualX(
context: context, x: 4),
),
Text(
"Lokasi Akhir",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
)
],
),
if (pengambilanAkhirLoc.value["lat"] != "" ||
pengambilanAkhirLoc.value['long'] != "")
InkWell(
onTap: () {
MapsLauncher.launchCoordinates(
double.parse(
pengambilanAkhirLoc.value["lat"]!),
double.parse(
pengambilanAkhirLoc.value["long"]!));
},
child: Row(
children: [
Text(
"Sudah ditandai",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.primaryBlue),
),
SizedBox(
width: Constant.getActualX(
context: context, x: 4),
),
Icon(
Icons.map_outlined,
color: Constant.primaryBlue,
),
],
),
),
],
),
if (petugasPengambilan.value.isNotEmpty ||
catatanPengambilan.value.isNotEmpty)
SizedBox(
height:
Constant.getActualY(context: context, y: 12),
),
if (petugasPengambilan.value.isNotEmpty ||
catatanPengambilan.value.isNotEmpty)
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Petugas Penyerahan",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
" : ${petugasPengambilan.value}",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
if (petugasPengambilan.value.isNotEmpty ||
catatanPengambilan.value.isNotEmpty)
SizedBox(
height:
Constant.getActualY(context: context, y: 12),
),
if (petugasPengambilan.value.isNotEmpty ||
catatanPengambilan.value.isNotEmpty)
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Catatan",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
" : ${catatanPengambilan.value} ",
overflow: TextOverflow.visible,
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
if (int.parse(prop.tipeId) == 1 ||
int.parse(prop.tipeId) == 2 ||
int.parse(prop.tipeId) == 3)
Text(
"Pengantaran Hasil",
// maxLines: 5,
overflow: TextOverflow.visible,
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textPrimary),
),
if (int.parse(prop.tipeId) == 5)
Text(
"Pengantaran Bahan",
// maxLines: 5,
overflow: TextOverflow.visible,
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textPrimary),
),
if (int.parse(prop.tipeId) == 4)
Text(
"Penerima",
// maxLines: 5,
overflow: TextOverflow.visible,
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.textPrimary),
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Alamat Pengantaran",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
": ${detailData.value.alamatPengantaran}",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
if (pengantaranAwalLoc.value["lat"] == "" ||
pengantaranAwalLoc.value['long'] == "")
Icon(
Icons.location_on,
color: Constant.primaryBlue,
),
if (pengantaranAwalLoc.value["lat"] == "" ||
pengantaranAwalLoc.value['long'] == "")
SizedBox(
width: Constant.getActualX(
context: context, x: 4),
),
Text(
"Lokasi Awal",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
)
],
),
if (pengantaranAwalLoc.value["lat"] != "" ||
pengantaranAwalLoc.value['long'] != "")
InkWell(
onTap: () {
MapsLauncher.launchCoordinates(
double.parse(
pengantaranAwalLoc.value["lat"]!),
double.parse(
pengantaranAwalLoc.value["long"]!));
},
child: Row(
children: [
Text(
"Sudah ditandai",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.primaryBlue),
),
SizedBox(
width: Constant.getActualX(
context: context, x: 4),
),
Icon(
Icons.map_outlined,
color: Constant.primaryBlue,
),
],
),
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 12),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
if (pengantaranAkhirLoc.value["lat"] == "" ||
pengantaranAkhirLoc.value['long'] == "")
Icon(
Icons.location_on,
color: Constant.primaryBlue,
),
if (pengantaranAkhirLoc.value["lat"] == "" ||
pengantaranAkhirLoc.value['long'] == "")
SizedBox(
width: Constant.getActualX(
context: context, x: 4),
),
Text(
"Lokasi Akhir",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
)
],
),
if (pengantaranAkhirLoc.value["lat"] != "" ||
pengantaranAkhirLoc.value['long'] != "")
InkWell(
onTap: () {
MapsLauncher.launchCoordinates(
double.parse(
pengantaranAkhirLoc.value["lat"]!),
double.parse(
pengantaranAkhirLoc.value["long"]!));
},
child: Row(
children: [
Text(
"Sudah ditandai",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.primaryBlue),
),
SizedBox(
width: Constant.getActualX(
context: context, x: 4),
),
Icon(
Icons.map_outlined,
color: Constant.primaryBlue,
),
],
),
),
],
),
if (petugasPengantaran.value.isNotEmpty ||
catatanPengantaran.value.isNotEmpty)
SizedBox(
height:
Constant.getActualY(context: context, y: 12),
),
if (petugasPengantaran.value.isNotEmpty ||
catatanPengantaran.value.isNotEmpty)
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Penerima",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
" : ${petugasPengantaran.value}",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
if (petugasPengantaran.value.isNotEmpty ||
catatanPengantaran.value.isNotEmpty)
SizedBox(
height:
Constant.getActualY(context: context, y: 12),
),
if (petugasPengantaran.value.isNotEmpty ||
catatanPengantaran.value.isNotEmpty)
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Catatan",
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
" : ${catatanPengantaran.value} ",
overflow: TextOverflow.visible,
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 14),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Total Jarak",
style: Constant.heading4(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.textPrimary),
),
Text(
" ${detailData.value.distance ?? ''} KM",
overflow: TextOverflow.visible,
style: Constant.heading3(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.textPrimary),
)
],
),
if (detailData.value.patients != null)
ExpansionTile(
tilePadding: EdgeInsets.symmetric(horizontal: 0),
title: Text(
"List (${detailData.value.patients?.length} pasien)",
style: Constant.body1(context: context)
.copyWith(fontWeight: FontWeight.w400),
),
children: detailData.value.patients!
.map((e) => PatientCard(
name: e.pasien.toString(),
noLab: e.tOrderHeaderLabNumber.toString(),
note: e.courierConfirmNote ?? "",
))
.toList(),
),
],
),
),
),
)
]),
);
}
Widget displayDetailText(BuildContext context, String teks, String value) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
teks,
style: Constant.heading4(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textPrimary),
),
),
Expanded(
child: Text(
" : ${value}",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.heading4(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textPrimary),
),
)
],
);
}
Widget headerCard(
BuildContext context, Color bgColor, String teks, Color textColor) {
return Container(
height: Constant.getActualY(context: context, y: 44),
decoration:
BoxDecoration(color: bgColor, borderRadius: BorderRadius.circular(8)),
child: Align(
child: Text(
"${teks}",
style: Constant.heading4(context: context)
.copyWith(fontWeight: FontWeight.w600, color: textColor),
),
),
);
}
}

View File

@@ -0,0 +1,207 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/models/history_model.dart';
import '/screen/detail_history_screen/detail_history_screen.dart';
import '/widget/chip_type.dart';
import 'package:intl/intl.dart';
import '../../app/constant.dart';
import '../../provider/current_user_provider.dart';
class HistoryListCard extends HookConsumerWidget {
const HistoryListCard({
super.key,
required this.ListRiwayat,
});
final List<HistoryModel> ListRiwayat;
@override
Widget build(BuildContext context, WidgetRef ref) {
final mCourirID =
ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0";
return ListView.builder(
itemCount: ListRiwayat.length,
itemBuilder: (context, index) {
var data = ListRiwayat[index];
String originalDateString = data.cdate.toString();
DateTime originalDate =
DateFormat('dd-MM-yyyy HH:mm:ss').parse(originalDateString);
// String formattedDate = DateFormat.yMMMMd('id').format(originalDate);
String formattedDate = DateFormat('d MMM HH:mm').format(originalDate);
// Output: 30 Mei 2023
return Container(
margin: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 24)),
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 31)),
child: ElevatedButton(
onPressed: () {
showModalBottomSheet(
enableDrag: true,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16)),
),
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
context: context,
builder: (context) {
return DraggableScrollableSheet(
initialChildSize: 0.9,
maxChildSize: 0.95,
minChildSize: 0.5,
expand: false,
builder: (_, scrollController) => Stack(
children: [
Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 125)),
child: Divider(
thickness: 3,
color: Constant.textPrimary,
),
),
SingleChildScrollView(
controller: scrollController,
child: DetailHistoryScreen(
data: {
"id": "1",
"alamat": "Cabang Kertajaya",
"jarak": "1,2 KM",
"tanggal": "02 Desember 14:50",
"tipe": "Pengantaran hasil Instansi",
"tipe_id": 4
},
prop: DetailHistoryProp(
data.tipeid.toString(),
mCourirID,
data.id.toString()),
)),
],
));
},
);
},
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.all(10),
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(16))),
backgroundColor: data.ispending == 'N'
? Constant.historyCardColor
: Constant.historyCardColorPending,
foregroundColor: Colors.grey),
child: Column(
children: [
SizedBox(
height: Constant.getActualY(context: context, y: 14),
),
Row(
children: [
Image.asset(
"assets/icon_riwayat_motor.png",
width: Constant.getActualX(context: context, x: 64),
height: Constant.getActualX(context: context, x: 64),
),
SizedBox(
width: Constant.getActualX(context: context, x: 12),
),
Container(
height: Constant.getActualX(context: context, x: 70),
width: Constant.getActualX(context: context, x: 232),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
constraints: BoxConstraints(
maxWidth: Constant.getActualX(
context: context, x: 130)),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
data.noSuratJalan.toString(),
textAlign: TextAlign.start,
style: Constant.caption1(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.primaryBlue),
),
Text(
data.nama.toString(),
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.caption2(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack),
),
],
),
),
Container(
constraints: BoxConstraints(
maxWidth: Constant.getActualX(
context: context, x: 100)),
child: Text(
"${data.distance ?? '0'} Km",
style: Constant.heading3(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.textBlack),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Text(
formattedDate,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.caption1(context: context)
.copyWith(
fontWeight: FontWeight.w500,
color: Constant.textBlack),
),
),
Container(
constraints: BoxConstraints(
maxWidth: Constant.getActualX(
context: context, x: 150)),
child: ChipType(
name: data.tipe.toString(),
tipe: data.tipeid!,
isDetailHistory: false,
),
)
],
)
],
),
),
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 14),
),
],
),
),
);
},
);
}
}

View File

@@ -0,0 +1,69 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '/models/history_model.dart';
import '../../repository/history_screen_repository.dart';
import '/screen/history_screen/history_screen.dart';
import '../../models/pending_work_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/home_screen_repository.dart';
abstract class HistoryListState extends Equatable {
final DateTime date;
const HistoryListState(this.date);
@override
List<Object?> get props => [date];
}
class HistoryListStateInit extends HistoryListState {
HistoryListStateInit() : super(DateTime.now());
}
class HistoryListStateLoading extends HistoryListState {
HistoryListStateLoading() : super(DateTime.now());
}
class HistoryListStateError extends HistoryListState {
final String message;
HistoryListStateError({
required this.message,
}) : super(DateTime.now());
}
class HistoryListStateDone extends HistoryListState {
final List<HistoryModel> model;
HistoryListStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class HistoryListNotifier extends StateNotifier<HistoryListState> {
final Ref ref;
HistoryListNotifier({
required this.ref,
}) : super(HistoryListStateInit());
void getData(
{required String id, required String date, required String type}) async {
try {
state = HistoryListStateLoading();
final dio = ref.read(dioProvider);
final resp = await HistoryRepository(dio: dio)
.getData(date: date, id: id, type: type);
state = HistoryListStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = HistoryListStateError(message: e.message.toString());
} else {
state = HistoryListStateError(message: e.toString());
}
}
}
}
//provider
final HistoryListProvider =
StateNotifierProvider<HistoryListNotifier, HistoryListState>(
(ref) => HistoryListNotifier(ref: ref));

View File

@@ -0,0 +1,466 @@
import 'dart:async';
import 'dart:convert';
import 'package:dropdown_button2/dropdown_button2.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 '/models/history_model.dart';
import '/models/history_type_model.dart';
import '/provider/history_filter_provider.dart';
import '/screen/history_screen/history_list_card.dart';
import '/screen/history_screen/history_list_provider.dart';
import '/screen/history_screen/history_type_provider.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
// import 'package:eva_icons_flutter/eva_icons_flutter.dart';
import '../../app/constant.dart';
import '../../provider/current_user_provider.dart';
import '../../widget/header_widget.dart';
import '../../widget/snackbar_widget.dart';
class HistoryScreen extends HookConsumerWidget {
const HistoryScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final historyListData = useState<List<HistoryModel>>([]);
final historyListLoading = useState(false);
final isMounted = useIsMounted();
final mCourirID =
ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0";
final dateFilter =
DateFormat('d MMM y').format(ref.watch(dateFilterProvider));
final SelectedTypeFilter = ref.watch(selectedTypeProvider);
fetchData() {
ref.read(HistoryListProvider.notifier).getData(
id: mCourirID,
date: DateFormat('dd-MM-yyyy').format(ref.watch(dateFilterProvider)),
type: SelectedTypeFilter.tipeid.toString());
}
final dateInput = useTextEditingController(
text: DateFormat('yyyy-MM-dd').format(DateTime.now()));
// ref.watch(dateFilterProvider);
ref.listen<HistoryListState>(
HistoryListProvider,
(previous, next) {
if (next is HistoryListStateLoading) {
historyListLoading.value = true;
} else if (next is HistoryListStateError) {
print(next.message);
historyListLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
} else if (next is HistoryListStateDone) {
print(next.model);
historyListData.value = next.model;
historyListLoading.value = false;
}
},
);
useEffect(() {
// final cancellationSource = CancellationSource();
if (isMounted.call()) {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
fetchData();
});
}
return () {};
}, []);
return RefreshIndicator(
onRefresh: () async {
fetchData();
},
child: Container(
// color: const Color(0XFFF4F6F8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
color: Colors.white,
height: Constant.getActualY(context: context, y: 56),
),
HeaderWidget(teks: "Riwayat"),
SizedBox(
height: Constant.getActualY(context: context, y: 24),
),
Container(
width: double.infinity,
margin: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 31),
right: Constant.getActualX(context: context, x: 31)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Text(
SelectedTypeFilter.tipename.toString(),
style: Constant.body1(context: context)
.copyWith(fontWeight: FontWeight.w600),
),
SizedBox(
width: Constant.getActualX(context: context, x: 5),
),
Icon(
Icons.fiber_manual_record_rounded,
size: 9,
),
SizedBox(
width: Constant.getActualX(context: context, x: 5),
),
Chip(
label: Text(
dateFilter,
style: Constant.body3(context: context).copyWith(
fontWeight: FontWeight.w700,
color: Colors.grey.shade600),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6))),
)
],
),
InkWell(
onTap: () {
showModalBottomSheet<void>(
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
return HookConsumer(
builder: (BuildContext context, WidgetRef ref, a) {
final typeLoading = useState(false);
final typeData =
useState<List<HistoryTypeModel>>(List.empty());
final dateCtr = useTextEditingController(
// d MMMM y'
text: DateFormat('yyyy-MM-dd')
.format(ref.read(dateFilterProvider)));
final selectedType = useState<HistoryTypeModel>(
ref.watch(selectedTypeProvider));
getData() {
ref
.read(HistoryTypeListProvider.notifier)
.getHistoryType();
}
useEffect(() {
WidgetsBinding.instance
.addPostFrameCallback((timeStamp) async {
getData();
});
return () {};
}, []);
ref.listen(HistoryTypeListProvider, (previous, next) {
if (next is HistoryTypeListStateInit) {
typeLoading.value = true;
} else if (next is HistoryTypeListStateLoading) {
typeLoading.value = true;
} else if (next is HistoryTypeListStateError) {
typeLoading.value = false;
} else if (next is HistoryTypeListStateDone) {
print(jsonEncode(next.model));
typeData.value = next.model;
typeLoading.value = false;
}
});
return Container(
margin: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 31)),
height:
Constant.getActualY(context: context, y: 370),
child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: Constant.getActualY(
context: context, y: 20),
),
SizedBox(
width: Constant.getActualX(
context: context, x: 100),
child: Divider(
color: Colors.grey,
height: 2,
thickness: 2,
)),
SizedBox(
height: Constant.getActualY(
context: context, y: 20),
),
Text(
"Filter",
style: Constant.heading3(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.primaryBlue),
),
SizedBox(
height: Constant.getActualY(
context: context, y: 20),
),
TextField(
controller: dateCtr,
decoration: InputDecoration(
suffixIcon: Icon(Icons.today_rounded),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8))),
labelText:
"Tanggal (yyyy-mm-dd)" //label text of field
),
readOnly: true,
onTap: () async {
DateTime? pickedDate = await showDatePicker(
context: context,
initialDate:
DateTime.parse(dateCtr.text),
// initialDate:
// DateTime.parse(dateCtr.text),
firstDate: DateTime(1950),
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('yyyy-MM-dd')
.format(pickedDate);
print(
formattedDate); //formatted date output using intl package => 2021-03-16
dateCtr.text =
formattedDate; //set output date to TextField value.
// ref
// .read(dateFilterProvider.notifier)
// .state = pickedDate;
} else {}
},
),
SizedBox(
height: Constant.getActualY(
context: context, y: 20),
),
Container(
// width: Constant.getActualX(
// context: context, x: 320),
// height: Constant.getActualY(
// context: context, y: 56),
child: DropdownButtonHideUnderline(
child: DropdownButton2<HistoryTypeModel>(
isExpanded: true,
hint: Row(
children: [
Expanded(
child: Text(
'Select Item',
style: Constant.body1(
context: context)
.copyWith(
fontWeight:
FontWeight.w600,
color:
Constant.primaryDark),
overflow: TextOverflow.ellipsis,
),
),
],
),
items: typeData.value
.map((HistoryTypeModel option) {
return DropdownMenuItem<
HistoryTypeModel>(
value: option,
child: Text(
option.tipename.toString(),
style: Constant.body1(
context: context)
.copyWith(
color: Constant.textBlack,
fontWeight:
FontWeight.w600),
),
);
}).toList(),
value: selectedType.value,
onChanged: (HistoryTypeModel? newValue) {
selectedType.value = newValue!;
// if (newValue) {
// ref
// .read(selectedTypeProvider.notifier)
// .state = newValue!;
print(
"Branch ID Selected : ${selectedType.value.tipename}");
print(
"Branch Code Selected : ${selectedType.value.tipename}");
// }
},
buttonStyleData: ButtonStyleData(
padding: EdgeInsets.only(
left: Constant.getActualX(
context: context, x: 10),
right: Constant.getActualX(
context: context, x: 10),
),
decoration: BoxDecoration(
// color: Colors.white,
border: Border.all(
color: Colors.grey.shade400),
borderRadius:
BorderRadius.circular(8),
),
// elevation: 2,
),
iconStyleData: IconStyleData(
icon: typeLoading.value
? LoadingAnimationWidget
.discreteCircle(
color: Constant.primaryBlue,
size: 20)
: Icon(
Icons
.keyboard_arrow_down_outlined,
),
iconSize: 24,
iconEnabledColor: Constant.textBlack,
iconDisabledColor: Colors.grey,
),
dropdownStyleData: DropdownStyleData(
maxHeight: Constant.getActualY(
context: context, y: 120),
width: Constant.getActualX(
context: context, x: 320),
padding: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 10),
left: Constant.getActualX(
context: context, x: 10),
right: Constant.getActualX(
context: context, x: 10),
bottom: Constant.getActualY(
context: context, y: 10),
),
decoration: BoxDecoration(
// color: Constant.backgroundWhite,
borderRadius:
BorderRadius.circular(8),
),
// elevation: 8,
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(40),
thickness:
MaterialStateProperty.all<double>(
6),
thumbVisibility:
MaterialStateProperty.all<bool>(
true),
),
),
menuItemStyleData: MenuItemStyleData(
height: Constant.getActualY(
context: context, y: 56),
padding: EdgeInsets.only(
top: Constant.getActualY(
context: context, y: 10),
left: Constant.getActualX(
context: context, x: 10),
right: Constant.getActualX(
context: context, x: 10),
),
),
),
),
),
SizedBox(
height: Constant.getActualY(
context: context, y: 40),
),
Container(
width: double.infinity,
height: Constant.getActualY(
context: context, y: 48),
child: ElevatedButton(
onPressed: () {
ref
.read(selectedTypeProvider.notifier)
.state = selectedType.value;
ref
.read(dateFilterProvider.notifier)
.state = DateTime.parse(dateCtr.text);
ref
.read(HistoryListProvider.notifier)
.getData(
id: mCourirID,
date: DateFormat('dd-MM-yyyy')
.format(ref.watch(
dateFilterProvider)),
type: ref
.watch(selectedTypeProvider)
.tipeid!);
Navigator.pop(context);
},
child: Text(
"Cari",
style: Constant.heading3(context: context)
.copyWith(
fontWeight: FontWeight.w700),
),
style: ButtonStyle(
backgroundColor:
MaterialStateColor.resolveWith(
(st) => Constant.primaryBlue),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(8),
// side: BorderSide(color: Colors.red),
),
),
shadowColor: MaterialStateProperty.all(
const Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
),
)
],
),
);
});
},
);
},
child: Icon(
Icons.filter_alt_outlined,
size: 25,
),
)
],
),
),
Container(
// color: Colors.red,
height: Constant.getActualY(context: context, y: 588),
child: historyListLoading.value
? Center(
child: LoadingAnimationWidget.fourRotatingDots(
color: Constant.primaryBlue, size: 50),
)
: HistoryListCard(ListRiwayat: historyListData.value),
),
],
)),
);
}
}

View File

@@ -0,0 +1,68 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '/models/history_model.dart';
import '../../repository/history_screen_repository.dart';
import '/screen/history_screen/history_screen.dart';
import '../../models/history_type_model.dart';
import '../../models/pending_work_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/home_screen_repository.dart';
abstract class HistoryTypeListState extends Equatable {
final DateTime date;
const HistoryTypeListState(this.date);
@override
List<Object?> get props => [date];
}
class HistoryTypeListStateInit extends HistoryTypeListState {
HistoryTypeListStateInit() : super(DateTime.now());
}
class HistoryTypeListStateLoading extends HistoryTypeListState {
HistoryTypeListStateLoading() : super(DateTime.now());
}
class HistoryTypeListStateError extends HistoryTypeListState {
final String message;
HistoryTypeListStateError({
required this.message,
}) : super(DateTime.now());
}
class HistoryTypeListStateDone extends HistoryTypeListState {
final List<HistoryTypeModel> model;
HistoryTypeListStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class HistoryTypeListNotifier extends StateNotifier<HistoryTypeListState> {
final Ref ref;
HistoryTypeListNotifier({
required this.ref,
}) : super(HistoryTypeListStateInit());
void getHistoryType() async {
try {
state = HistoryTypeListStateLoading();
final dio = ref.read(dioProvider);
final resp = await HistoryRepository(dio: dio).getHistoryType();
state = HistoryTypeListStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = HistoryTypeListStateError(message: e.message.toString());
} else {
state = HistoryTypeListStateError(message: e.toString());
}
}
}
}
//provider
final HistoryTypeListProvider =
StateNotifierProvider<HistoryTypeListNotifier, HistoryTypeListState>(
(ref) => HistoryTypeListNotifier(ref: ref));

View File

@@ -0,0 +1,434 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/app/route.dart';
import '/screen/home_screen/pending_work_provider.dart';
import '/screen/home_screen/total_work_provider.dart';
import '/widget/information_rpt_card.dart';
import '/widget/pending_card.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../models/pending_work_model.dart';
import '../../models/work_total_model.dart';
import '../../provider/current_user_provider.dart';
import '../../widget/information_card.dart';
import '../../widget/snackbar_widget.dart';
import '../../widget/work_card.dart';
class HomeScreen extends HookConsumerWidget {
const HomeScreen({
super.key,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final totalWork = useState<WorkTotalModel>(WorkTotalModel());
final totalWorkLoading = useState(false);
final pendingWork = useState<List<PendingWorkModel>>([]);
final pendingWorkLoading = useState(false);
final mUsername =
ref.watch(currentUserProvider)?.model.user?.mStaffName ?? "0";
final mCourirID =
ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0";
fetchData() {
// ref.read(TotalWorkProvider.notifier).getData(
// id: ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0");
ref.read(PendingWorkProvider.notifier).getData(
id: ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0");
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
fetchData();
});
return () {};
}, [mCourirID]);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
fetchData();
});
return () {};
}, []);
ref.listen(
TotalWorkProvider,
(previous, next) {
if (next is TotalWorkStateLoading) {
totalWorkLoading.value = true;
} else if (next is TotalWorkStateError) {
print(next.message);
totalWorkLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
} else if (next is TotalWorkStateDone) {
print(next.model);
totalWork.value = next.model;
totalWorkLoading.value = false;
}
},
);
ref.listen(
PendingWorkProvider,
(previous, next) {
if (next is PendingWorkStateLoading) {
pendingWorkLoading.value = true;
} else if (next is PendingWorkStateError) {
print(next.message);
pendingWorkLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
} else if (next is PendingWorkStateDone) {
// print(jsonEncode(next.model));
// print(next.model.length);
pendingWork.value = next.model;
pendingWorkLoading.value = false;
}
},
);
return RefreshIndicator(
onRefresh: () async {
fetchData();
},
triggerMode: RefreshIndicatorTriggerMode.onEdge,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Container(
// color: Colors.red,
padding: EdgeInsets.fromLTRB(
Constant.getActualX(context: context, x: 40),
Constant.getActualY(context: context, y: 68),
Constant.getActualX(context: context, x: 40),
0),
child: Column(
children: [
SizedBox(
height: Constant.getActualY(context: context, y: 48),
child: Row(
children: [
Expanded(
flex: 10,
child: SizedBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Hi $mUsername",
overflow: TextOverflow.ellipsis,
style: Constant.heading4(context: context)
.copyWith(
color: Constant.primaryBlue,
fontWeight: FontWeight.w600),
),
Text(
"Silahkan lakukan pengantaran",
overflow: TextOverflow.ellipsis,
style: Constant.caption1(context: context)
.copyWith(fontWeight: FontWeight.w500),
)
],
),
)),
Expanded(
flex: 2,
child: Container(
alignment: Alignment.topRight,
// color: Colors.red,
child: Image.asset(
"assets/icon_home_bell_blue.png",
width: Constant.getActualY(context: context, y: 24),
height:
Constant.getActualY(context: context, y: 24),
),
))
],
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
// InformationCard(
// data: totalWork.value,
// loading: totalWorkLoading.value,
// bgColor: Color(0XFFF3F7FB),
// elevation: false,
// ),
InformationRptCard(mCourirID),
SizedBox(
height: Constant.getActualY(context: context, y: 25),
),
SizedBox(
// color: Colors.blue,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Ambil Pekerjaan Baru",
style: Constant.heading4(context: context).copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
// InkWell(
// onTap: () {},
// child: Row(
// children: [
// Text(
// "Detail",
// style: Constant.caption1(context: context)
// .copyWith(
// color: Constant.textPrimary,
// fontWeight: FontWeight.w500),
// ),
// SizedBox(
// width: Constant.getActualX(
// context: context, x: 5),
// ),
// const Icon(
// Icons.arrow_forward_ios_outlined,
// size: 15,
// )
// ],
// ))
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
// color: Colors.red,
height: Constant.getActualY(context: context, y: 80),
width: Constant.getActualX(context: context, x: 86),
decoration: BoxDecoration(
// color: Colors.red,
boxShadow: [
BoxShadow(
color: Color(0XFF919EAB).withOpacity(0.12),
offset: Offset(0.0, 12), //(x,y)
blurRadius: 24,
spreadRadius: -4),
BoxShadow(
color: Color(0XFF919EAB).withOpacity(0.2),
offset: Offset(0.0, 0), //(x,y)
blurRadius: 2,
),
],
borderRadius: BorderRadius.circular(12)),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0.2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
surfaceTintColor: Colors.grey,
foregroundColor: Colors.grey,
backgroundColor: Colors.white),
onPressed: () {
Navigator.of(context).pushNamed(inputPekerjaan,
arguments: inputPekerjaanProp(0, 0));
},
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
Image.asset(
width: Constant.getActualX(
context: context, x: 24),
height: Constant.getActualX(
context: context, x: 24),
"assets/icon_home_hasil_blue.png"),
Text(
"Hasil",
style: Constant.body3(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.textSecondary),
)
],
)),
),
Container(
// color: Colors.red,
height: Constant.getActualY(context: context, y: 80),
width: Constant.getActualX(context: context, x: 86),
decoration: BoxDecoration(
// color: Colors.red,
boxShadow: [
BoxShadow(
color: Color(0XFF919EAB).withOpacity(0.12),
offset: Offset(0.0, 12), //(x,y)
blurRadius: 24,
spreadRadius: -4),
BoxShadow(
color: Color(0XFF919EAB).withOpacity(0.2),
offset: Offset(0.0, 0), //(x,y)
blurRadius: 2,
),
],
borderRadius: BorderRadius.circular(12)),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0.2,
shape: RoundedRectangleBorder(
side: const BorderSide(
width: 0.1, color: Colors.grey),
borderRadius: BorderRadius.circular(12),
),
surfaceTintColor: Colors.grey,
foregroundColor: Colors.grey,
backgroundColor: Colors.white),
onPressed: () {
Navigator.of(context).pushNamed(inputPekerjaan,
arguments: inputPekerjaanProp(1, 0));
},
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
Image.asset(
width: Constant.getActualX(
context: context, x: 24),
height: Constant.getActualX(
context: context, x: 24),
"assets/icon_home_sample_blue.png"),
Text(
"Sample",
style: Constant.body3(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.textSecondary),
)
],
)),
),
Container(
// color: Colors.red,
height: Constant.getActualY(context: context, y: 80),
width: Constant.getActualX(context: context, x: 86),
decoration: BoxDecoration(
// color: Colors.red,
boxShadow: [
BoxShadow(
color: Color(0XFF919EAB).withOpacity(0.12),
offset: Offset(0.0, 12), //(x,y)
blurRadius: 24,
spreadRadius: -4),
BoxShadow(
color: Color(0XFF919EAB).withOpacity(0.2),
offset: Offset(0.0, 0), //(x,y)
blurRadius: 2,
),
],
borderRadius: BorderRadius.circular(12)),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0.2,
shape: RoundedRectangleBorder(
side: const BorderSide(
width: 0.1, color: Colors.grey),
borderRadius: BorderRadius.circular(12),
),
surfaceTintColor: Colors.grey,
foregroundColor: Colors.grey,
backgroundColor: Colors.white),
onPressed: () {
Navigator.of(context).pushNamed(inputPekerjaan,
arguments: inputPekerjaanProp(2, 0));
},
child: Column(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
Image.asset(
width: Constant.getActualX(
context: context, x: 24),
height: Constant.getActualX(
context: context, x: 24),
"assets/icon_home_lainnya_blue.png"),
Text(
"Lainya",
style: Constant.body3(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.textSecondary),
)
],
)),
),
],
)
],
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 30),
),
SizedBox(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Pending List Pekerjaan",
overflow: TextOverflow.ellipsis,
style: Constant.heading4(context: context).copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
// InkWell(
// onTap: () {},
// child: Row(
// children: [
// Text(
// "Detail",
// style: Constant.caption1(context: context)
// .copyWith(
// color: Constant.textPrimary,
// fontWeight: FontWeight.w500),
// ),
// SizedBox(
// width: Constant.getActualX(
// context: context, x: 5),
// ),
// const Icon(
// Icons.arrow_forward_ios_outlined,
// size: 15,
// )
// ],
// ))
],
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
Container(
// color: Colors.red,
padding:
EdgeInsets.symmetric(horizontal: 0.9, vertical: 0.5),
height: Constant.getActualY(context: context, y: 235),
child: pendingWorkLoading.value
? LoadingAnimationWidget.fourRotatingDots(
color: Constant.primaryBlue, size: 50)
: ListView.builder(
itemCount: pendingWork.value.length,
itemBuilder: (context, index) {
return PendingCardWidget(
data: pendingWork.value[index]);
},
),
)
],
),
)
],
),
),
),
);
}
}

View File

@@ -0,0 +1,64 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../models/pending_work_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/home_screen_repository.dart';
abstract class PendingWorkState extends Equatable {
final DateTime date;
const PendingWorkState(this.date);
@override
List<Object?> get props => [date];
}
class PendingWorkStateInit extends PendingWorkState {
PendingWorkStateInit() : super(DateTime.now());
}
class PendingWorkStateLoading extends PendingWorkState {
PendingWorkStateLoading() : super(DateTime.now());
}
class PendingWorkStateError extends PendingWorkState {
final String message;
PendingWorkStateError({
required this.message,
}) : super(DateTime.now());
}
class PendingWorkStateDone extends PendingWorkState {
final List<PendingWorkModel> model;
PendingWorkStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class PendingWorkNotifier extends StateNotifier<PendingWorkState> {
final Ref ref;
PendingWorkNotifier({
required this.ref,
}) : super(PendingWorkStateInit());
void getData({required String id}) async {
try {
state = PendingWorkStateLoading();
final dio = ref.read(dioProvider);
final resp = await HomeScreenRepository(dio: dio).getPendingWork(id: id);
state = PendingWorkStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = PendingWorkStateError(message: e.message.toString());
} else {
state = PendingWorkStateError(message: e.toString());
}
}
}
}
//provider
final PendingWorkProvider =
StateNotifierProvider<PendingWorkNotifier, PendingWorkState>(
(ref) => PendingWorkNotifier(ref: ref));

View File

@@ -0,0 +1,64 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../models/work_total_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/home_screen_repository.dart';
abstract class TotalWorkState extends Equatable {
final DateTime date;
const TotalWorkState(this.date);
@override
List<Object?> get props => [date];
}
class TotalWorkStateInit extends TotalWorkState {
TotalWorkStateInit() : super(DateTime.now());
}
class TotalWorkStateLoading extends TotalWorkState {
TotalWorkStateLoading() : super(DateTime.now());
}
class TotalWorkStateError extends TotalWorkState {
final String message;
TotalWorkStateError({
required this.message,
}) : super(DateTime.now());
}
class TotalWorkStateDone extends TotalWorkState {
final WorkTotalModel model;
TotalWorkStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class TotalWorkNotifier extends StateNotifier<TotalWorkState> {
final Ref ref;
TotalWorkNotifier({
required this.ref,
}) : super(TotalWorkStateInit());
void getData({required String id}) async {
try {
state = TotalWorkStateLoading();
final dio = ref.read(dioProvider);
final resp = await HomeScreenRepository(dio: dio).getTotalWork(id: id);
state = TotalWorkStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = TotalWorkStateError(message: e.message.toString());
} else {
state = TotalWorkStateError(message: e.toString());
}
}
}
}
//provider
final TotalWorkProvider =
StateNotifierProvider<TotalWorkNotifier, TotalWorkState>(
(ref) => TotalWorkNotifier(ref: ref));

View File

@@ -0,0 +1,61 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '/models/response_list_branch_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/input_lain_lain_repository.dart';
// 3. state provider
final inputLainLainCabang = StateNotifierProvider<InputLainLainNotifier, InputLainLainState>(
(ref) => InputLainLainNotifier(ref: ref));
// 2. notifier
class InputLainLainNotifier extends StateNotifier<InputLainLainState> {
final Ref ref;
InputLainLainNotifier({required this.ref}) : super(InputLainLainStateInit());
void loadListCabangInputLainLain() async {
try {
state = InputLainLainStateLoading();
final resp = await InputLainLainRepository(dio: ref.read(dioProvider))
.loadListCabangInputLainLain();
state = InputLainLainStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = InputLainLainStateError(message: e.message ?? "");
} else {
state = InputLainLainStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class InputLainLainState extends Equatable {
final DateTime date;
const InputLainLainState(this.date);
@override
List<Object?> get props => [date];
}
class InputLainLainStateInit extends InputLainLainState {
InputLainLainStateInit() : super(DateTime.now());
}
class InputLainLainStateLoading extends InputLainLainState {
InputLainLainStateLoading() : super(DateTime.now());
}
class InputLainLainStateError extends InputLainLainState {
final String? message;
InputLainLainStateError({
required this.message,
}) : super(DateTime.now());
}
class InputLainLainStateDone extends InputLainLainState {
final List<ResponseListBranchModel> model;
InputLainLainStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,81 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/input_lain_lain_repository.dart';
import '../../models/response_save_pengantaran_hasil_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/pengambilan_bahan_repository.dart';
import '../../repository/pengantaran_hasil_dokter_repository.dart';
// 3. state provider
final inputLainLainSave = StateNotifierProvider<InputLainLainSaveNotifier,
InputLainLainSaveState>((ref) => InputLainLainSaveNotifier(ref: ref));
// 2. notifier
class InputLainLainSaveNotifier
extends StateNotifier<InputLainLainSaveState> {
final Ref ref;
InputLainLainSaveNotifier({required this.ref})
: super(InputLainLainSaveStateInit());
void inputLainLainSave({
required String courierID,
required String tipeID,
required String branchID,
required String branchCode,
required String pickup,
required String destination,
required String note
}) async {
try {
state = InputLainLainSaveStateLoading();
final resp = await InputLainLainRepository(dio: ref.read(dioProvider))
.inputLainLainSave(
courierID: courierID,
tipeID: tipeID,
branchID: branchID,
branchCode: branchCode,
pickup: pickup,
destination: destination,
note: note
);
state = InputLainLainSaveStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = InputLainLainSaveStateError(message: e.message ?? "");
} else {
state = InputLainLainSaveStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class InputLainLainSaveState extends Equatable {
final DateTime date;
const InputLainLainSaveState(this.date);
@override
List<Object?> get props => [date];
}
class InputLainLainSaveStateInit extends InputLainLainSaveState {
InputLainLainSaveStateInit() : super(DateTime.now());
}
class InputLainLainSaveStateLoading extends InputLainLainSaveState {
InputLainLainSaveStateLoading() : super(DateTime.now());
}
class InputLainLainSaveStateError extends InputLainLainSaveState {
final String? message;
InputLainLainSaveStateError({
required this.message,
}) : super(DateTime.now());
}
class InputLainLainSaveStateDone extends InputLainLainSaveState {
final ResponseSavePengantaranHasilModel model;
InputLainLainSaveStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,432 @@
import 'dart:async';
import 'package:dropdown_button2/dropdown_button2.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 '../../app/route.dart';
import '../../models/response_list_branch_model.dart';
import '../../provider/current_user_provider.dart';
import '../../widget/custom_textfield.dart';
import '../../widget/sas_textfield.dart';
import '../../widget/snackbar_widget.dart';
import 'input_lain_lain_loadcabang_provider.dart';
import 'input_lain_lain_save_provider.dart';
class InputLainLain extends HookConsumerWidget {
// const InputLainLain({super.key});
const InputLainLain({super.key, required this.data});
final Map<String, dynamic> data;
@override
Widget build(BuildContext context, WidgetRef ref) {
print(data);
final mCourirID =
ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0";
final tipePekerjaanIDSave = data['tipePekerjaan'];
final focusNodeCatatan = useFocusNode();
final catatanhasFocus = useState(false);
final focusNodeAlamatPengambilan = useFocusNode();
final alamatPengambilanhasFocus = useState(false);
final focusNodeAlamatPengantaran = useFocusNode();
final alamatPengantaranhasFocus = useState(false);
final ctrlCatatan = useTextEditingController(text: "");
final ctrlAlamatPengambilan = useTextEditingController(text: "");
final ctrlAlamatPengantaran = useTextEditingController(text: "");
// cabang
final selectedDropdownCabang = useState<ResponseListBranchModel>(
ResponseListBranchModel(
branchid: "", branchaddress: "", branchcode: "", branchname: ""));
final dropdownItemsCabang =
useState<List<ResponseListBranchModel>>(List.empty(growable: true));
final isLoading = useState(false);
final errorMessage = useState("");
focusNodeCatatan.addListener(() {
if (focusNodeCatatan.hasFocus) {
catatanhasFocus.value = true;
} else {
catatanhasFocus.value = false;
}
});
focusNodeAlamatPengambilan.addListener(() {
if (focusNodeAlamatPengambilan.hasFocus) {
alamatPengambilanhasFocus.value = true;
} else {
alamatPengambilanhasFocus.value = false;
}
});
focusNodeAlamatPengantaran.addListener(() {
if (focusNodeAlamatPengantaran.hasFocus) {
alamatPengantaranhasFocus.value = true;
} else {
alamatPengantaranhasFocus.value = false;
}
});
// populate list cabang
ref.listen(inputLainLainCabang, (prev, next) {
if (next is InputLainLainStateLoading) {
isLoading.value = true;
} else if (next is InputLainLainStateError) {
isLoading.value = false;
errorMessage.value = next.message ?? "";
SanckbarWidget(context, "${next.message}", snackbarType.error);
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is InputLainLainStateDone) {
if (next.model.isNotEmpty) {
dropdownItemsCabang.value = next.model;
selectedDropdownCabang.value = next.model[0];
} else {
dropdownItemsCabang.value = [
ResponseListBranchModel(
branchid: "0",
branchcode: "",
branchname: "Cabang Belum Ada",
branchaddress: ""),
];
selectedDropdownCabang.value = dropdownItemsCabang.value[0];
SanckbarWidget(context, "Data Cabang Belum Ada", snackbarType.error);
return;
}
isLoading.value = false;
}
});
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
ref.read(inputLainLainCabang.notifier).loadListCabangInputLainLain();
});
return () {};
}, []);
// save pengambilan bahan
ref.listen(inputLainLainSave, (prev, next) {
if (next is InputLainLainSaveStateLoading) {
isLoading.value = true;
} else if (next is InputLainLainSaveStateError) {
isLoading.value = false;
errorMessage.value = next.message ?? "";
SanckbarWidget(context, "${next.message}", snackbarType.error);
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is InputLainLainSaveStateDone) {
if (next.model.status != "OK") {
SanckbarWidget(context, "${next.model.message}", snackbarType.error);
} else {
Navigator.of(context).pushNamedAndRemoveUntil(
konfirmasiRoute,
(route) => false,
);
}
isLoading.value = false;
}
});
return Column(
children: [
// dropdown cabang
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 56),
child: DropdownButtonHideUnderline(
child: DropdownButton2<ResponseListBranchModel>(
isExpanded: true,
hint: Row(
children: [
Expanded(
child: Text(
'Select Item',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.primaryDark),
overflow: TextOverflow.ellipsis,
),
),
],
),
items: dropdownItemsCabang.value
.map((ResponseListBranchModel option) {
return DropdownMenuItem<ResponseListBranchModel>(
value: option,
child: Text(
option.branchname.toString(),
style: Constant.body1(context: context).copyWith(
color: Constant.primaryBlue,
fontWeight: FontWeight.w600),
),
);
}).toList(),
value: selectedDropdownCabang.value,
onChanged: (ResponseListBranchModel? newValue) {
// if (newValue) {
selectedDropdownCabang.value = newValue!;
print(
"Branch ID Selected : ${selectedDropdownCabang.value.branchid}");
print(
"Branch Code Selected : ${selectedDropdownCabang.value.branchcode}");
// }
},
buttonStyleData: ButtonStyleData(
height: Constant.getActualY(context: context, y: 56),
width: Constant.getActualX(context: context, x: 320),
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
),
decoration: BoxDecoration(
color: Constant.backgroundWhite,
border: Border.all(color: Constant.textBlack, width: 1),
borderRadius: BorderRadius.circular(8),
),
elevation: 2,
),
iconStyleData: IconStyleData(
icon: isLoading.value
? LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)
: Icon(
Icons.keyboard_arrow_down_outlined,
),
iconSize: 24,
iconEnabledColor: Constant.textBlack,
iconDisabledColor: Colors.grey,
),
dropdownStyleData: DropdownStyleData(
maxHeight: Constant.getActualY(context: context, y: 200),
width: Constant.getActualX(context: context, x: 320),
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 10),
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
bottom: Constant.getActualY(context: context, y: 10),
),
decoration: BoxDecoration(
color: Constant.backgroundWhite,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 20.0,
spreadRadius: 2.0,
offset: Offset(0.0, 0.0),
),
],
),
elevation: 8,
offset: const Offset(0, -10),
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(40),
thickness: MaterialStateProperty.all<double>(6),
thumbVisibility: MaterialStateProperty.all<bool>(true),
),
),
menuItemStyleData: MenuItemStyleData(
height: Constant.getActualY(context: context, y: 56),
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 10),
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
),
),
),
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 28),
),
// catatan
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 120),
// color: Colors.green,
child: SasTextFieldArea(
controller: ctrlCatatan,
hintText: "Catatan",
labelText: "Catatan",
hasFocus: catatanhasFocus.value,
focusNode: focusNodeCatatan,
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 28),
),
// alamat pengambilan
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 120),
// color: Colors.green,
child: SasTextFieldArea(
controller: ctrlAlamatPengambilan,
hintText: "Alamat Pengambilan",
labelText: "Alamat Pengambilan",
hasFocus: alamatPengambilanhasFocus.value,
focusNode: focusNodeAlamatPengambilan,
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 28),
),
// alamat pengantaran
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 120),
// color: Colors.green,
child: SasTextFieldArea(
controller: ctrlAlamatPengantaran,
hintText: "Alamat Pengantaran",
labelText: "Alamat Pengantaran",
hasFocus: alamatPengantaranhasFocus.value,
focusNode: focusNodeAlamatPengantaran,
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 30),
),
// loading
// if (isLoading.value) ...[
// // Center(
// // child: SizedBox(
// // width: Constant.getActualX(context: context, x: 20),
// // height: Constant.getActualY(context: context, y: 20),
// // child: CircularProgressIndicator(),
// // ),
// // ),
// const Center(
// child: CircularProgressIndicator(),
// ),
// ],
// SizedBox(
// height: Constant.getActualY(context: context, y: 60),
// ),
// button batal & simpan
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: Constant.getActualX(context: context, x: 317),
height: Constant.getActualY(context: context, y: 36),
// color: Colors.pink,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// batal
ElevatedButton(
onPressed: isLoading.value
? null
: () {
Navigator.pop(context);
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.backgroundWhite),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(color: Constant.blueButton),
),
),
shadowColor: MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Batal',
style: Constant.body3(context: context).copyWith(
color: Constant.blueButton,
fontWeight: FontWeight.w700,
),
),
),
),
// simpan
ElevatedButton(
onPressed: (isLoading.value)
? null
: () {
if (ctrlCatatan.text == "" ||
ctrlAlamatPengambilan.text == "" ||
ctrlAlamatPengantaran.text == "") {
SanckbarWidget(
context,
"Catatan atau Alamat Pengambilan atau Alamat Pengantaran Silahkan Diisi",
snackbarType.warning);
} else {
print(selectedDropdownCabang.value.branchid);
if (selectedDropdownCabang.value.branchid == "") {
SanckbarWidget(context, "Data Cabang Belum Ada",
snackbarType.warning);
} else {
ref
.read(inputLainLainSave.notifier)
.inputLainLainSave(
courierID: mCourirID,
tipeID: tipePekerjaanIDSave,
branchID: selectedDropdownCabang
.value.branchid
.toString(),
branchCode: selectedDropdownCabang
.value.branchcode
.toString(),
pickup: ctrlAlamatPengambilan.text,
destination: ctrlAlamatPengantaran.text,
note: ctrlCatatan.text);
}
}
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.blueButton),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
// side: BorderSide(color: Constant.blueButton),
),
),
shadowColor: MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: isLoading.value
? LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white, size: 30)
: Text(
'Simpan',
style: Constant.body3(context: context).copyWith(
color: Constant.backgroundWhite,
fontWeight: FontWeight.w700,
),
),
),
),
],
),
),
),
],
);
}
}

View File

@@ -0,0 +1,241 @@
import 'dart:async';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/screen/input_pekerjaan/input_lain_lain_screen.dart';
import '../../app/constant.dart';
import 'input_pengambilan_bahan_screen.dart';
import 'input_pengantaran_hasil_dokter_screen.dart';
import 'input_pengantaran_hasil_instansi_screen.dart';
import 'input_pengantaran_hasil_pasien_screen.dart';
class DummyDropdownTipe {
final String options;
final int id;
DummyDropdownTipe(this.options, this.id);
}
class DummyRadioTipe {
final String text;
final int id;
DummyRadioTipe(this.text, this.id);
}
class InputPekerjaanPekerjaanLainLain extends HookConsumerWidget {
const InputPekerjaanPekerjaanLainLain({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedDropdown =
useState<DummyDropdownTipe>(DummyDropdownTipe("", 0));
final dropdownItems =
useState<List<DummyDropdownTipe>>(List.empty(growable: true));
final radioButtonItems =
useState<List<DummyRadioTipe>>(List.empty(growable: true));
final selectedRadio = useState<DummyRadioTipe>(DummyRadioTipe("", 0));
useEffect(() {
dropdownItems.value = [
DummyDropdownTipe("Pengantaran Hasil", 1),
DummyDropdownTipe("Pengambilan Bahan", 2),
DummyDropdownTipe("Lain-lain", 3),
];
selectedDropdown.value = dropdownItems.value[2];
// selectedDropdown.value = dropdownItems.value[1];
}, []);
final isLoading = useState(false);
final isMounted = useIsMounted();
return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Scaffold(
backgroundColor: Constant.backgroundWhite,
appBar: AppBar(
toolbarHeight: Constant.getActualY(context: context, y: 110),
backgroundColor: Constant.backgroundWhite,
elevation: 0,
titleSpacing: 0,
centerTitle: false,
title: Text(
'Kembali',
style: Constant.body1(context: context).copyWith(
color: Constant.textBlack,
fontWeight: FontWeight.w600,
),
),
leading: GestureDetector(
child: Icon(
Icons.arrow_back_ios,
color: Constant.textBlack,
size: Constant.getActualY(context: context, y: 16),
),
onTap: () {
Navigator.pop(context);
},
),
automaticallyImplyLeading: true,
),
body: SingleChildScrollView(
child: SizedBox(
width: Constant.getActualX(context: context, x: 390),
height: Constant.getActualY(context: context, y: 760),
child: Padding(
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 35),
right: Constant.getActualX(context: context, x: 35),
// bottom: Constant.getActualY(context: context, y: 40)
),
child: Column(
children: [
// dropdown
if (dropdownItems.value.isEmpty) ...[
Text('Dropdown No Data')
] else ...[
DropdownButtonHideUnderline(
child: DropdownButton2<DummyDropdownTipe>(
isExpanded: true,
hint: Row(
children: [
Expanded(
child: Text(
'Select Item',
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.primaryDark),
overflow: TextOverflow.ellipsis,
),
),
],
),
items:
dropdownItems.value.map((DummyDropdownTipe option) {
return DropdownMenuItem<DummyDropdownTipe>(
value: option,
child: Text(
option.options,
style: Constant.body1(context: context).copyWith(
color: Constant.primaryBlue,
fontWeight: FontWeight.w600),
),
);
}).toList(),
value: selectedDropdown.value,
// onChanged: (DummyDropdownTipe? newValue) {
// // if (newValue) {
// selectedDropdown.value = newValue!;
// print(selectedDropdown.value.id);
// // }
// },
onChanged: null,
buttonStyleData: ButtonStyleData(
height: Constant.getActualY(context: context, y: 56),
width: Constant.getActualX(context: context, x: 320),
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
),
decoration: BoxDecoration(
color: Constant.backgroundWhite,
border:
Border.all(color: Constant.textBlack, width: 1),
borderRadius: BorderRadius.circular(8),
),
elevation: 2,
),
iconStyleData: IconStyleData(
icon: Icon(
Icons.keyboard_arrow_down_outlined,
),
iconSize: 24,
iconEnabledColor: Constant.textBlack,
iconDisabledColor: Colors.grey,
),
dropdownStyleData: DropdownStyleData(
maxHeight:
Constant.getActualY(context: context, y: 200),
width: Constant.getActualX(context: context, x: 320),
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 10),
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
bottom:
Constant.getActualY(context: context, y: 10),
),
decoration: BoxDecoration(
color: Constant.backgroundWhite,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 20.0,
spreadRadius: 2.0,
offset: Offset(0.0, 0.0),
),
],
),
elevation: 8,
offset: const Offset(0, -10),
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(40),
thickness: MaterialStateProperty.all<double>(6),
thumbVisibility:
MaterialStateProperty.all<bool>(true),
),
),
menuItemStyleData: MenuItemStyleData(
height: Constant.getActualY(context: context, y: 56),
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 10),
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
),
),
),
),
],
SizedBox(
height: Constant.getActualY(context: context, y: 32),
),
// form
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 612),
// color: Colors.green,
child: Column(
children: [
if (selectedDropdown.value.id == 3) ...[
const InputLainLain(
data: {
"tipePekerjaan": "4",
"tipePengantaranHasil": ""
},
)
]
],
),
),
// spacing
SizedBox(
height: Constant.getActualY(context: context, y: 32),
),
],
),
),
),
),
),
);
}
}

View File

@@ -0,0 +1,249 @@
import 'dart:async';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/screen/input_pekerjaan/input_lain_lain_screen.dart';
import '../../app/constant.dart';
import 'input_pengambilan_bahan_screen.dart';
import 'input_pengantaran_hasil_dokter_screen.dart';
import 'input_pengantaran_hasil_instansi_screen.dart';
import 'input_pengantaran_hasil_pasien_screen.dart';
class DummyDropdownTipe {
final String options;
final int id;
DummyDropdownTipe(this.options, this.id);
}
class DummyRadioTipe {
final String text;
final int id;
DummyRadioTipe(this.text, this.id);
}
class InputPekerjaanPengambilanBahan extends HookConsumerWidget {
const InputPekerjaanPengambilanBahan({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedDropdown =
useState<DummyDropdownTipe>(DummyDropdownTipe("", 0));
final dropdownItems =
useState<List<DummyDropdownTipe>>(List.empty(growable: true));
final radioButtonItems =
useState<List<DummyRadioTipe>>(List.empty(growable: true));
final selectedRadio = useState<DummyRadioTipe>(DummyRadioTipe("", 0));
useEffect(() {
dropdownItems.value = [
DummyDropdownTipe("Pengantaran Hasil", 1),
DummyDropdownTipe("Pengambilan Bahan", 2),
DummyDropdownTipe("Lain-lain", 3),
];
selectedDropdown.value = dropdownItems.value[1];
// selectedDropdown.value = dropdownItems.value[1];
}, []);
final isLoading = useState(false);
final isMounted = useIsMounted();
return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Scaffold(
backgroundColor: Constant.backgroundWhite,
appBar: AppBar(
toolbarHeight: Constant.getActualY(context: context, y: 110),
backgroundColor: Constant.backgroundWhite,
elevation: 0,
titleSpacing: 0,
centerTitle: false,
title: Text(
'Kembali',
style: Constant.body1(context: context).copyWith(
color: Constant.textBlack,
fontWeight: FontWeight.w600,
),
),
leading: GestureDetector(
child: Icon(
Icons.arrow_back_ios,
color: Constant.textBlack,
size: Constant.getActualY(context: context, y: 16),
),
onTap: () {
Navigator.pop(context);
},
),
automaticallyImplyLeading: true,
),
body: SingleChildScrollView(
child: SizedBox(
width: Constant.getActualX(context: context, x: 390),
height: Constant.getActualY(context: context, y: 760),
child: Padding(
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 35),
right: Constant.getActualX(context: context, x: 35),
// bottom: Constant.getActualY(context: context, y: 40)
),
child: Column(
children: [
// dropdown
if (dropdownItems.value.isEmpty) ...[
Text('Dropdown No Data')
] else ...[
DropdownButtonHideUnderline(
child: DropdownButton2<DummyDropdownTipe>(
isExpanded: true,
hint: Row(
children: [
Expanded(
child: Text(
'Select Item',
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.primaryDark),
overflow: TextOverflow.ellipsis,
),
),
],
),
items:
dropdownItems.value.map((DummyDropdownTipe option) {
return DropdownMenuItem<DummyDropdownTipe>(
value: option,
child: Text(
option.options,
style: Constant.body1(context: context).copyWith(
color: Constant.primaryBlue,
fontWeight: FontWeight.w600),
),
);
}).toList(),
value: selectedDropdown.value,
// onChanged: (DummyDropdownTipe? newValue) {
// // if (newValue) {
// selectedDropdown.value = newValue!;
// print(selectedDropdown.value.id);
// // }
// },
onChanged: null,
buttonStyleData: ButtonStyleData(
height: Constant.getActualY(context: context, y: 56),
width: Constant.getActualX(context: context, x: 320),
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
),
decoration: BoxDecoration(
color: Constant.backgroundWhite,
border:
Border.all(color: Constant.textBlack, width: 1),
borderRadius: BorderRadius.circular(8),
),
elevation: 2,
),
iconStyleData: IconStyleData(
icon: Icon(
Icons.keyboard_arrow_down_outlined,
),
iconSize: 24,
iconEnabledColor: Constant.textBlack,
iconDisabledColor: Colors.grey,
),
dropdownStyleData: DropdownStyleData(
maxHeight:
Constant.getActualY(context: context, y: 200),
width: Constant.getActualX(context: context, x: 320),
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 10),
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
bottom:
Constant.getActualY(context: context, y: 10),
),
decoration: BoxDecoration(
color: Constant.backgroundWhite,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 20.0,
spreadRadius: 2.0,
offset: Offset(0.0, 0.0),
),
],
),
elevation: 8,
offset: const Offset(0, -10),
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(40),
thickness: MaterialStateProperty.all<double>(6),
thumbVisibility:
MaterialStateProperty.all<bool>(true),
),
),
menuItemStyleData: MenuItemStyleData(
height: Constant.getActualY(context: context, y: 56),
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 10),
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
),
),
),
),
],
SizedBox(
height: Constant.getActualY(context: context, y: 32),
),
// form
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 612),
// color: Colors.green,
child: Column(
children: [
if (selectedDropdown.value.id == 2) ...[
// Text('Antar Bahan')
Container(
width:
Constant.getActualX(context: context, x: 320),
height:
Constant.getActualY(context: context, y: 612),
// color: Colors.amber,
child: const InputPengambilanBahanScreen(
data: {
"tipePekerjaan": "5",
"tipePengantaranHasil": ""
},
),
),
],
],
),
),
// spacing
SizedBox(
height: Constant.getActualY(context: context, y: 32),
),
],
),
),
),
),
),
);
}
}

View File

@@ -0,0 +1,338 @@
import 'dart:async';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/screen/input_pekerjaan/input_lain_lain_screen.dart';
import '../../app/constant.dart';
import 'input_pengambilan_bahan_screen.dart';
import 'input_pengantaran_hasil_dokter_screen.dart';
import 'input_pengantaran_hasil_instansi_screen.dart';
import 'input_pengantaran_hasil_pasien_screen.dart';
class DummyDropdownTipe {
final String options;
final int id;
DummyDropdownTipe(this.options, this.id);
}
class DummyRadioTipe {
final String text;
final int id;
DummyRadioTipe(this.text, this.id);
}
class InputPekerjaanPengantaranHasil extends HookConsumerWidget {
const InputPekerjaanPengantaranHasil({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedDropdown =
useState<DummyDropdownTipe>(DummyDropdownTipe("", 0));
final dropdownItems =
useState<List<DummyDropdownTipe>>(List.empty(growable: true));
final radioButtonItems =
useState<List<DummyRadioTipe>>(List.empty(growable: true));
final selectedRadio = useState<DummyRadioTipe>(DummyRadioTipe("", 0));
useEffect(() {
dropdownItems.value = [
DummyDropdownTipe("Pengantaran Hasil", 1),
DummyDropdownTipe("Pengambilan Bahan", 2),
DummyDropdownTipe("Lain-lain", 3),
];
selectedDropdown.value = dropdownItems.value[0];
// selectedDropdown.value = dropdownItems.value[1];
radioButtonItems.value = [
DummyRadioTipe("Pasien", 1),
DummyRadioTipe("Instansi", 2),
DummyRadioTipe("Dokter", 3),
];
selectedRadio.value = radioButtonItems.value[0];
}, []);
final isLoading = useState(false);
final isMounted = useIsMounted();
return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Scaffold(
backgroundColor: Constant.backgroundWhite,
resizeToAvoidBottomInset: false,
appBar: AppBar(
toolbarHeight: Constant.getActualY(context: context, y: 110),
backgroundColor: Constant.backgroundWhite,
elevation: 0,
titleSpacing: 0,
centerTitle: false,
title: Text(
'Kembali',
style: Constant.body1(context: context).copyWith(
color: Constant.textBlack,
fontWeight: FontWeight.w600,
),
),
leading: GestureDetector(
child: Icon(
Icons.arrow_back_ios,
color: Constant.textBlack,
size: Constant.getActualY(context: context, y: 16),
),
onTap: () {
Navigator.pop(context);
},
),
automaticallyImplyLeading: true,
),
body: SizedBox(
width: Constant.getActualX(context: context, x: 390),
height: Constant.getActualY(context: context, y: 760),
child: Padding(
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 35),
right: Constant.getActualX(context: context, x: 35),
// bottom: Constant.getActualY(context: context, y: 40)
),
child: Column(
children: [
// dropdown
if (dropdownItems.value.isEmpty) ...[
Text('Dropdown No Data')
] else ...[
DropdownButtonHideUnderline(
child: DropdownButton2<DummyDropdownTipe>(
isExpanded: true,
hint: Row(
children: [
Expanded(
child: Text(
'Select Item',
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.primaryDark),
overflow: TextOverflow.ellipsis,
),
),
],
),
items:
dropdownItems.value.map((DummyDropdownTipe option) {
return DropdownMenuItem<DummyDropdownTipe>(
value: option,
child: Text(
option.options,
style: Constant.body1(context: context).copyWith(
color: Constant.primaryBlue,
fontWeight: FontWeight.w600),
),
);
}).toList(),
value: selectedDropdown.value,
// onChanged: (DummyDropdownTipe? newValue) {
// // if (newValue) {
// selectedDropdown.value = newValue!;
// print(selectedDropdown.value.id);
// // }
// },
onChanged: null,
buttonStyleData: ButtonStyleData(
height: Constant.getActualY(context: context, y: 56),
width: Constant.getActualX(context: context, x: 320),
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
),
decoration: BoxDecoration(
color: Constant.backgroundWhite,
border:
Border.all(color: Constant.textBlack, width: 1),
borderRadius: BorderRadius.circular(8),
),
elevation: 2,
),
iconStyleData: IconStyleData(
icon: Icon(
Icons.keyboard_arrow_down_outlined,
),
iconSize: 24,
iconEnabledColor: Constant.textBlack,
iconDisabledColor: Colors.grey,
),
dropdownStyleData: DropdownStyleData(
maxHeight:
Constant.getActualY(context: context, y: 200),
width: Constant.getActualX(context: context, x: 320),
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 10),
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
bottom:
Constant.getActualY(context: context, y: 10),
),
decoration: BoxDecoration(
color: Constant.backgroundWhite,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 20.0,
spreadRadius: 2.0,
offset: Offset(0.0, 0.0),
),
],
),
elevation: 8,
offset: const Offset(0, -10),
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(40),
thickness: MaterialStateProperty.all<double>(6),
thumbVisibility:
MaterialStateProperty.all<bool>(true),
),
),
menuItemStyleData: MenuItemStyleData(
height: Constant.getActualY(context: context, y: 56),
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 10),
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
),
),
),
),
],
SizedBox(
height: Constant.getActualY(context: context, y: 32),
),
// form
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 612),
// color: Colors.green,
child: Column(
children: [
if (selectedDropdown.value.id == 1) ...[
// radio button
SizedBox(
width:
Constant.getActualX(context: context, x: 320),
height:
Constant.getActualY(context: context, y: 36),
// color: Colors.green,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
if (radioButtonItems.value.isEmpty) ...[
Text('Radio Button Empty')
] else ...[
for (var i = 0;
i < radioButtonItems.value.length;
i++) ...[
Expanded(
flex: 1,
child: Row(
children: [
Radio<DummyRadioTipe>(
activeColor: Constant.primaryMain,
value: radioButtonItems.value[i],
groupValue: selectedRadio.value,
onChanged: (DummyRadioTipe? index) {
if (isMounted()) {
selectedRadio.value = index!;
} else {
return;
}
},
),
Expanded(
child: Text(
radioButtonItems.value[i].text,
style: Constant.body3(
context: context)
.copyWith(
color:
Constant.textPrimary,
fontWeight:
FontWeight.w400),
),
)
],
),
),
]
]
],
),
),
SizedBox(
height:
Constant.getActualY(context: context, y: 32),
),
// form scan dan inputan
Container(
width:
Constant.getActualX(context: context, x: 320),
height:
Constant.getActualY(context: context, y: 544),
// color: Colors.amber,
child: Column(
children: [
if (selectedRadio.value.id == 1) ...[
// InputPengantaranHasilPasienScreen(data: {
// "tipePekerjaan": selectedDropdown.value.id.toString(),
// "tipePengantaranHasil": selectedRadio.value.id.toString()
// }),
const InputPengantaranHasilPasienScreen(
data: {
"tipePekerjaan": "1",
"tipePengantaranHasil": ""
}),
],
if (selectedRadio.value.id == 2) ...[
const InputPengantaranHasilInstansiScreen(
data: {
"tipePekerjaan": "2",
"tipePengantaranHasil": ""
})
],
if (selectedRadio.value.id == 3) ...[
const InputPengantaranHasilDokterScreen(
data: {
"tipePekerjaan": "3",
"tipePengantaranHasil": ""
},
)
]
],
),
),
]
],
),
),
// spacing
SizedBox(
height: Constant.getActualY(context: context, y: 32),
),
],
),
),
),
),
);
}
}

View File

@@ -0,0 +1,376 @@
import 'dart:async';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/screen/input_pekerjaan/input_lain_lain_screen.dart';
import '../../app/constant.dart';
import '../../provider/current_scan_provider.dart';
import 'input_pengambilan_bahan_screen.dart';
import 'input_pengantaran_hasil_dokter_screen.dart';
import 'input_pengantaran_hasil_instansi_screen.dart';
import 'input_pengantaran_hasil_pasien_screen.dart';
class DummyDropdownTipe {
final String options;
final int id;
DummyDropdownTipe(this.options, this.id);
}
class DummyRadioTipe {
final String text;
final int id;
DummyRadioTipe(this.text, this.id);
}
class InputPekerjaan extends HookConsumerWidget {
const InputPekerjaan({super.key, required this.input, required this.tipe});
final int input;
final int tipe;
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedDropdown =
useState<DummyDropdownTipe>(DummyDropdownTipe("", 0));
final dropdownItems =
useState<List<DummyDropdownTipe>>(List.empty(growable: true));
final radioButtonItems =
useState<List<DummyRadioTipe>>(List.empty(growable: true));
final selectedRadio = useState<DummyRadioTipe>(DummyRadioTipe("", 0));
useEffect(() {
dropdownItems.value = [
DummyDropdownTipe("Pengantaran Hasil", 1),
DummyDropdownTipe("Pengambilan Bahan", 2),
DummyDropdownTipe("Lain-lain", 3),
];
selectedDropdown.value = dropdownItems.value[input];
// selectedDropdown.value = dropdownItems.value[1];
radioButtonItems.value = [
DummyRadioTipe("Pasien", 1),
DummyRadioTipe("Instansi", 2),
DummyRadioTipe("Dokter", 3),
];
selectedRadio.value = radioButtonItems.value[tipe];
}, []);
final isLoading = useState(false);
final isMounted = useIsMounted();
return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: Constant.backgroundWhite,
appBar: AppBar(
toolbarHeight: Constant.getActualY(context: context, y: 110),
backgroundColor: Constant.backgroundWhite,
elevation: 0,
titleSpacing: 0,
centerTitle: false,
title: Text(
'Kembali',
style: Constant.body1(context: context).copyWith(
color: Constant.textBlack,
fontWeight: FontWeight.w600,
),
),
leading: GestureDetector(
child: Icon(
Icons.arrow_back_ios,
color: Constant.textBlack,
size: Constant.getActualY(context: context, y: 16),
),
onTap: () {
Navigator.pop(context);
},
),
automaticallyImplyLeading: true,
),
body: SingleChildScrollView(
child: SizedBox(
width: Constant.getActualX(context: context, x: 390),
height: Constant.getActualY(context: context, y: 760),
child: Padding(
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 35),
right: Constant.getActualX(context: context, x: 35),
// bottom: Constant.getActualY(context: context, y: 40)
),
child: Column(
children: [
// dropdown
if (dropdownItems.value.isEmpty) ...[
Text('Dropdown No Data')
] else ...[
DropdownButtonHideUnderline(
child: DropdownButton2<DummyDropdownTipe>(
isExpanded: true,
hint: Row(
children: [
Expanded(
child: Text(
'Select Item',
style: Constant.body1(context: context)
.copyWith(
fontWeight: FontWeight.w600,
color: Constant.primaryDark),
overflow: TextOverflow.ellipsis,
),
),
],
),
items:
dropdownItems.value.map((DummyDropdownTipe option) {
return DropdownMenuItem<DummyDropdownTipe>(
value: option,
child: Text(
option.options,
style: Constant.body1(context: context).copyWith(
color: Constant.primaryBlue,
fontWeight: FontWeight.w600),
),
);
}).toList(),
value: selectedDropdown.value,
onChanged: (DummyDropdownTipe? newValue) {
// if (newValue) {
selectedDropdown.value = newValue!;
print(selectedDropdown.value.id);
// }
},
buttonStyleData: ButtonStyleData(
height: Constant.getActualY(context: context, y: 56),
width: Constant.getActualX(context: context, x: 320),
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
),
decoration: BoxDecoration(
color: Constant.backgroundWhite,
border:
Border.all(color: Constant.textBlack, width: 1),
borderRadius: BorderRadius.circular(8),
),
elevation: 2,
),
iconStyleData: IconStyleData(
icon: Icon(
Icons.keyboard_arrow_down_outlined,
),
iconSize: 24,
iconEnabledColor: Constant.textBlack,
iconDisabledColor: Colors.grey,
),
dropdownStyleData: DropdownStyleData(
maxHeight:
Constant.getActualY(context: context, y: 200),
width: Constant.getActualX(context: context, x: 320),
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 10),
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
bottom:
Constant.getActualY(context: context, y: 10),
),
decoration: BoxDecoration(
color: Constant.backgroundWhite,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 20.0,
spreadRadius: 2.0,
offset: Offset(0.0, 0.0),
),
],
),
elevation: 8,
offset: const Offset(0, -10),
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(40),
thickness: MaterialStateProperty.all<double>(6),
thumbVisibility:
MaterialStateProperty.all<bool>(true),
),
),
menuItemStyleData: MenuItemStyleData(
height: Constant.getActualY(context: context, y: 56),
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 10),
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
),
),
),
),
],
SizedBox(
height: Constant.getActualY(context: context, y: 32),
),
// form
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 612),
// color: Colors.green,
child: Column(
children: [
if (selectedDropdown.value.id == 1) ...[
// radio button
SizedBox(
width:
Constant.getActualX(context: context, x: 320),
height:
Constant.getActualY(context: context, y: 36),
// color: Colors.green,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
if (radioButtonItems.value.isEmpty) ...[
Text('Radio Button Empty')
] else ...[
for (var i = 0;
i < radioButtonItems.value.length;
i++) ...[
Expanded(
flex: 1,
child: Row(
children: [
Radio<DummyRadioTipe>(
activeColor: Constant.primaryMain,
value: radioButtonItems.value[i],
groupValue: selectedRadio.value,
onChanged: (DummyRadioTipe? index) {
if (isMounted()) {
selectedRadio.value = index!;
ref
.read(barcodeScanResult
.notifier)
.update((state) => "");
ref
.read(isFromScanScreen
.notifier)
.update((state) => false);
} else {
return;
}
},
),
Expanded(
child: Text(
radioButtonItems.value[i].text,
style: Constant.body3(
context: context)
.copyWith(
color:
Constant.textPrimary,
fontWeight:
FontWeight.w400),
),
)
],
),
),
]
]
],
),
),
SizedBox(
height:
Constant.getActualY(context: context, y: 32),
),
// form scan dan inputan
Container(
width:
Constant.getActualX(context: context, x: 320),
height:
Constant.getActualY(context: context, y: 544),
// color: Colors.amber,
child: Wrap(
children: [
if (selectedRadio.value.id == 1) ...[
// InputPengantaranHasilPasienScreen(data: {
// "tipePekerjaan": selectedDropdown.value.id.toString(),
// "tipePengantaranHasil": selectedRadio.value.id.toString()
// }),
const InputPengantaranHasilPasienScreen(
data: {
"tipePekerjaan": "1",
"tipePengantaranHasil": ""
}),
],
if (selectedRadio.value.id == 2) ...[
const InputPengantaranHasilInstansiScreen(
data: {
"tipePekerjaan": "2",
"tipePengantaranHasil": ""
})
],
if (selectedRadio.value.id == 3) ...[
const InputPengantaranHasilDokterScreen(
data: {
"tipePekerjaan": "3",
"tipePengantaranHasil": ""
},
)
]
],
),
),
] else ...[
// height 36 + 544 + 32
if (selectedDropdown.value.id == 2) ...[
// Text('Antar Bahan')
Container(
width:
Constant.getActualX(context: context, x: 320),
height:
Constant.getActualY(context: context, y: 612),
// color: Colors.amber,
child: const InputPengambilanBahanScreen(
data: {
"tipePekerjaan": "5",
"tipePengantaranHasil": ""
},
),
),
],
if (selectedDropdown.value.id == 3) ...[
const InputLainLain(
data: {
"tipePekerjaan": "4",
"tipePengantaranHasil": ""
},
)
]
]
],
),
),
// spacing
SizedBox(
height: Constant.getActualY(context: context, y: 32),
),
],
),
),
),
),
),
);
}
}

View File

@@ -0,0 +1,614 @@
import 'dart:async';
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/models/company_model.dart';
import '/models/response_list_branch_model.dart';
import '../../repository/company_repository.dart';
import '/screen/input_pekerjaan/pengambilan_bahan_loadcabang_provider.dart';
import '/screen/input_pekerjaan/search_company_provider.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../app/route.dart';
import '../../provider/current_user_provider.dart';
import '../../provider/dio_provider.dart';
import '../../widget/custom_textfield.dart';
import '../../widget/sas_textfield.dart';
import '../../widget/snackbar_widget.dart';
import 'pengambilan_bahan_save_provider.dart';
import 'pengantaran_hasil_dokter_save_provider.dart';
class DummyCabang {
final String namaCabang;
final int idCabang;
DummyCabang(this.namaCabang, this.idCabang);
}
class InputPengambilanBahanScreen extends HookConsumerWidget {
// const InputPengambilanBahanScreen({super.key});
const InputPengambilanBahanScreen({super.key, required this.data});
final Map<String, dynamic> data;
@override
Widget build(BuildContext context, WidgetRef ref) {
// print(data);
final mCourirID =
ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0";
final tipePekerjaanIDSave = data['tipePekerjaan'];
final deliveryIDSave = useState<String>("");
// cabang
final selectedDropdownCabang = useState<ResponseListBranchModel>(
ResponseListBranchModel(
branchid: "", branchaddress: "", branchcode: "", branchname: ""));
final dropdownItemsCabang =
useState<List<ResponseListBranchModel>>(List.empty(growable: true));
final selectedCompany = useState<CompanyModel>(CompanyModel());
final companyInput = useTextEditingController();
final searchCompanyLoading = useState(false);
final searchCompanyErrorMsg = useState("");
final focusNodeNamaTujuan = useFocusNode();
final namaTujuanhasFocus = useState(false);
final focusNodeAlamat = useFocusNode();
final alamathasFocus = useState(false);
final ctrlAlamat = useTextEditingController(text: "");
final ctrlNamaTujuan = useTextEditingController(text: "");
final isLoading = useState(false);
final errorMessage = useState("");
focusNodeNamaTujuan.addListener(() {
if (focusNodeNamaTujuan.hasFocus) {
namaTujuanhasFocus.value = true;
} else {
namaTujuanhasFocus.value = false;
}
});
focusNodeAlamat.addListener(() {
if (focusNodeAlamat.hasFocus) {
alamathasFocus.value = true;
} else {
alamathasFocus.value = false;
}
});
// populate list cabang
ref.listen(pengambilanBahanListCabang, (prev, next) {
if (next is PengambilanBahanStateLoading) {
isLoading.value = true;
} else if (next is PengambilanBahanStateError) {
isLoading.value = false;
errorMessage.value = next.message ?? "";
SanckbarWidget(context, "${next.message}", snackbarType.error);
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is PengambilanBahanStateDone) {
if (next.model.isNotEmpty) {
dropdownItemsCabang.value = next.model;
selectedDropdownCabang.value = next.model[0];
} else {
dropdownItemsCabang.value = [
ResponseListBranchModel(
branchid: "0",
branchcode: "",
branchname: "Cabang Belum Ada",
branchaddress: ""),
];
selectedDropdownCabang.value = dropdownItemsCabang.value[0];
SanckbarWidget(context, "Data Cabang Belum Ada", snackbarType.error);
return;
}
isLoading.value = false;
}
});
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
ref
.read(pengambilanBahanListCabang.notifier)
.loadListCabangPengambilanBahan();
});
return () {};
}, []);
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
ref
.read(pengambilanBahanListCabang.notifier)
.loadListCabangPengambilanBahan();
});
return () {};
}, []);
// save pengambilan bahan
ref.listen(pengambilanBahanSave, (prev, next) {
if (next is PengambilanBahanSaveStateLoading) {
isLoading.value = true;
} else if (next is PengambilanBahanSaveStateError) {
isLoading.value = false;
errorMessage.value = next.message ?? "";
SanckbarWidget(context, "${next.message}", snackbarType.error);
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is PengambilanBahanSaveStateDone) {
if (next.model.status != "OK") {
SanckbarWidget(context, "${next.model.message}", snackbarType.error);
} else {
Navigator.of(context).pushNamedAndRemoveUntil(
konfirmasiRoute,
(route) => false,
);
}
isLoading.value = false;
}
});
Future<List<CompanyModel>> searchCompany({required String keyword}) async {
// http: //10.9.9.3/one-api/v1/courier/mobile/inputcourier/search_company_all/?search=sas
try {
searchCompanyLoading.value = true;
// final url =
// "${Constant.baseUrl}/v1/courier/mobile/inputcourier/search_comsdfpany_all/?search=$keyword";
final url =
"${Constant.baseUrl}/v1/courier/mobile/inputcourier/search_company_all/?search=$keyword";
final coba = await Dio().get(url);
final resp = jsonDecode(coba.toString());
// final resp = await get(service: url);
List<CompanyModel> data;
// print(resp['data']);
if (resp['status'] == 'OK') {
data = [];
if (resp['data'] != null) {
resp['data']['records'].forEach((e) {
final model = CompanyModel.fromJson(e);
data.add(model);
});
} else {
data = [];
}
} else {
data = [];
}
print("company repo");
print(jsonEncode(data));
searchCompanyLoading.value = false;
return data;
} catch (e) {
searchCompanyErrorMsg.value = e.toString();
SanckbarWidget(context, e.toString(), snackbarType.error);
searchCompanyLoading.value = false;
return [];
}
}
return Column(
children: [
// nama tujuan
// Container(
// width: Constant.getActualX(context: context, x: 320),
// height: Constant.getActualY(context: context, y: 56),
// child: SasTextField(
// controller: ctrlNamaTujuan,
// hintText: "Nama Tujuan",
// labelText: "Nama Tujuan",
// hasFocus: namaTujuanhasFocus.value,
// focusNode: focusNodeNamaTujuan,
// ),
// ),
Autocomplete<CompanyModel>(
fieldViewBuilder:
(context, textEditingController, focusNode, onFieldSubmitted) {
ctrlNamaTujuan.text = textEditingController.text;
return TextField(
controller: textEditingController,
focusNode: focusNode,
decoration: InputDecoration(
hintText: "Nama Tujuan",
labelText: "Nama Tujuan",
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: Constant.textGrey,
width: 2,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: Constant.primaryMain,
width: 2,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color: Constant.primaryBlue,
width: 3,
),
)));
},
optionsBuilder: (tv) async {
final debouncer = Debouncer(milliseconds: 500);
final search = tv.text.toString();
List<CompanyModel> data = List.empty(growable: true);
// print(tv.text.length);
if (search == "" || search.isEmpty) {
data = List.empty();
} else {
// var data = await searchCompany(keyword: search);
if (search.length >= 3) {
final dio = ref.read(dioProvider);
data = await searchCompany(keyword: search);
// return CompanyRepository(dio: dio).search(keyword: search);
}
}
return data;
},
displayStringForOption: (option) {
return option.mCompanyName.toString();
},
optionsViewBuilder: (BuildContext context, onSelected, options) {
return Align(
alignment: Alignment.topLeft,
child: Material(
elevation: 10,
// borderRadius: BorderRadius.all(Radius.circular(50)),
color: Colors.white,
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10)),
child: Container(
width: Constant.getActualX(context: context, x: 320),
height: searchCompanyLoading.value
? Constant.getActualY(context: context, y: 50)
: Constant.getActualY(context: context, y: 250),
decoration: const BoxDecoration(
// color: Colors.white,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10))),
child: searchCompanyLoading.value
? Center(
child: LoadingAnimationWidget.staggeredDotsWave(
color: Constant.primaryBlue, size: 30),
)
: Scrollbar(
trackVisibility: true,
// isAlwaysShown: true,
child: ListView.builder(
shrinkWrap: true,
padding: EdgeInsets.all(10.0),
itemCount: options.length,
itemBuilder: (BuildContext context, int index) {
final CompanyModel option =
options.elementAt(index);
return SizedBox(
child: ListTile(
// tileColor: Colors.green,
onTap: () {
onSelected(option);
selectedCompany.value = option;
companyInput.text =
option.mCompanyName ?? "";
ctrlAlamat.text =
option.mCompanyAddress ?? "";
ctrlNamaTujuan.text =
option.mCompanyName ?? "";
},
// leading: Icon(Icons.location_on),
title: Text(option.mCompanyName.toString(),
style:
const TextStyle(color: Colors.black)),
subtitle:
Text(option.mCompanyAddress.toString()),
),
);
},
),
),
),
),
);
},
),
SizedBox(
height: Constant.getActualY(context: context, y: 28),
),
// alamat pengambilan
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 120),
// color: Colors.green,
child: SasTextFieldArea(
controller: ctrlAlamat,
hintText: "Alamat Pengambilan",
labelText: "Alamat Pengambilan",
hasFocus: alamathasFocus.value,
focusNode: focusNodeAlamat,
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 28),
),
// dropdown cabang
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 56),
child: DropdownButtonHideUnderline(
child: DropdownButton2<ResponseListBranchModel>(
isExpanded: true,
hint: Row(
children: [
Expanded(
child: Text(
'Select Item',
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600,
color: Constant.primaryDark),
overflow: TextOverflow.ellipsis,
),
),
],
),
items: dropdownItemsCabang.value
.map((ResponseListBranchModel option) {
return DropdownMenuItem<ResponseListBranchModel>(
value: option,
child: Text(
option.branchname.toString(),
style: Constant.body1(context: context).copyWith(
color: Constant.primaryBlue,
fontWeight: FontWeight.w600),
),
);
}).toList(),
value: selectedDropdownCabang.value,
onChanged: (ResponseListBranchModel? newValue) {
// if (newValue) {
selectedDropdownCabang.value = newValue!;
print(
"Branch ID Selected : ${selectedDropdownCabang.value.branchid}");
print(
"Branch Code Selected : ${selectedDropdownCabang.value.branchcode}");
// }
},
buttonStyleData: ButtonStyleData(
height: Constant.getActualY(context: context, y: 56),
width: Constant.getActualX(context: context, x: 320),
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
),
decoration: BoxDecoration(
color: Constant.backgroundWhite,
border: Border.all(color: Constant.textBlack, width: 1),
borderRadius: BorderRadius.circular(8),
),
elevation: 2,
),
iconStyleData: IconStyleData(
icon: isLoading.value
? LoadingAnimationWidget.discreteCircle(
color: Constant.primaryBlue, size: 20)
: Icon(
Icons.keyboard_arrow_down_outlined,
),
iconSize: 24,
iconEnabledColor: Constant.textBlack,
iconDisabledColor: Colors.grey,
),
dropdownStyleData: DropdownStyleData(
maxHeight: Constant.getActualY(context: context, y: 200),
width: Constant.getActualX(context: context, x: 320),
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 10),
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
bottom: Constant.getActualY(context: context, y: 10),
),
decoration: BoxDecoration(
color: Constant.backgroundWhite,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 20.0,
spreadRadius: 2.0,
offset: Offset(0.0, 0.0),
),
],
),
elevation: 8,
offset: const Offset(0, -10),
scrollbarTheme: ScrollbarThemeData(
radius: const Radius.circular(40),
thickness: MaterialStateProperty.all<double>(6),
thumbVisibility: MaterialStateProperty.all<bool>(true),
),
),
menuItemStyleData: MenuItemStyleData(
height: Constant.getActualY(context: context, y: 56),
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 10),
left: Constant.getActualX(context: context, x: 10),
right: Constant.getActualX(context: context, x: 10),
),
),
),
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 30),
),
// loading
// if (isLoading.value) ...[
// // Center(
// // child: SizedBox(
// // width: Constant.getActualX(context: context, x: 20),
// // height: Constant.getActualY(context: context, y: 20),
// // child: CircularProgressIndicator(),
// // ),
// // ),
// const Center(
// child: CircularProgressIndicator(),
// ),
// SizedBox(
// height: Constant.getActualY(context: context, y: 20),
// ),
// ],
// button batal & simpan
Align(
alignment: Alignment.bottomCenter,
child: Container(
width: Constant.getActualX(context: context, x: 317),
height: Constant.getActualY(context: context, y: 36),
// color: Colors.pink,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// batal
SizedBox(
width: Constant.getActualX(context: context, x: 80),
height: Constant.getActualY(context: context, y: 36),
child: ElevatedButton(
onPressed: isLoading.value
? null
: () {
Navigator.pop(context);
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.backgroundWhite),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(color: Constant.blueButton),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Batal',
style: Constant.body3(context: context).copyWith(
color: Constant.blueButton,
fontWeight: FontWeight.w700,
),
),
),
),
),
// simpan
SizedBox(
// width: Constant.getActualX(context: context, x: 83),
height: Constant.getActualY(context: context, y: 36),
child: ElevatedButton(
onPressed: (isLoading.value)
? null
: () {
if (ctrlNamaTujuan.text == "" ||
ctrlAlamat.text == "") {
SanckbarWidget(
context,
"Nama dan Alamat Silahkan Diisi",
snackbarType.warning);
} else {
print(selectedDropdownCabang.value.branchid);
if (selectedDropdownCabang.value.branchid == "") {
SanckbarWidget(context, "Data Cabang Belum Ada",
snackbarType.warning);
} else {
ref
.read(pengambilanBahanSave.notifier)
.pengambilanBahanSave(
courierID: mCourirID,
tipeID: tipePekerjaanIDSave,
branchID: selectedDropdownCabang
.value.branchid
.toString(),
branchCode: selectedDropdownCabang
.value.branchcode
.toString(),
destination: ctrlAlamat.text,
name: ctrlNamaTujuan.text);
}
}
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.blueButton),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
// side: BorderSide(color: Constant.blueButton),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: isLoading.value
? LoadingAnimationWidget.staggeredDotsWave(
color: Colors.white, size: 20)
: Text(
'Simpan',
style: Constant.body3(context: context).copyWith(
color: Constant.backgroundWhite,
fontWeight: FontWeight.w700,
),
),
),
),
),
],
),
),
),
],
);
}
}
class Debouncer {
Debouncer({required this.milliseconds});
final int milliseconds;
Timer? _timer;
run(action) {
if (_timer?.isActive ?? false) {
_timer?.cancel();
}
_timer = Timer(Duration(milliseconds: milliseconds), action);
}
}

View File

@@ -0,0 +1,794 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/app/route.dart';
import '/models/patient_model.dart';
import '/widget/patient_card.dart';
import '../../app/constant.dart';
import '../../models/response_search_pengantaran_hasil_model.dart';
import '../../provider/current_scan_provider.dart';
import '../../provider/current_user_provider.dart';
import '../../provider/dio_provider.dart';
import '../../repository/pengantaran_hasil_dokter_repository.dart';
import '../../widget/custom_textfield.dart';
import '../../widget/sas_textfield.dart';
import '../../widget/snackbar_widget.dart';
import 'pengantaran_hasil_dokter_loadnolab_provider.dart';
import 'pengantaran_hasil_dokter_save_provider.dart';
class InputPengantaranHasilDokterScreen extends HookConsumerWidget {
const InputPengantaranHasilDokterScreen({super.key, required this.data});
final Map<String, dynamic> data;
@override
Widget build(BuildContext context, WidgetRef ref) {
print(data);
final tipePekerjaanIDSave = data['tipePekerjaan'];
final deliveryIDSave = useState<String>("");
final mCourirID =
ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0";
final isForm = useState(true);
final isScan = useState(false);
final hasilSearchData = useState<List<ResponseSearchPengantaranHasilModel>>(
List.empty(growable: true));
final focusNodeNoDokter = useFocusNode();
final nodokterhasFocus = useState(false);
final isLoadingSearchNoDokter = useState(false);
final ctrlNoDokter = useTextEditingController(text: "");
final ctrlNama = useTextEditingController(text: "");
final focusNodeNama = useFocusNode();
final namahasFocus = useState(false);
final ctrlAlamat = useTextEditingController(text: "");
final focusNodeAlamat = useFocusNode();
final alamathasFocus = useState(false);
final errorMessage = useState("");
final isFromScanScreenProvider = ref.read(isFromScanScreen);
final listPatient =
useState<List<PatientModel>>(List.empty(growable: true));
final listViewBuilderShow = useState(false);
final singleListSearchShow = useState(true);
focusNodeNoDokter.addListener(() {
if (focusNodeNoDokter.hasFocus) {
nodokterhasFocus.value = true;
} else {
nodokterhasFocus.value = false;
}
});
focusNodeNama.addListener(() {
if (focusNodeNama.hasFocus) {
namahasFocus.value = true;
} else {
namahasFocus.value = false;
}
});
focusNodeAlamat.addListener(() {
if (focusNodeAlamat.hasFocus) {
alamathasFocus.value = true;
} else {
alamathasFocus.value = false;
}
});
// useEffect(() {
// isForm.value = true;
// isScan.value = false;
// }, []);
// search
ref.listen(pengantaranHasilDokterSearch, (prev, next) {
if (next is PengantaranhasilDokterStateLoading) {
isLoadingSearchNoDokter.value = true;
} else if (next is PengantaranhasilDokterStateError) {
isLoadingSearchNoDokter.value = false;
errorMessage.value = next.message ?? "";
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is PengantaranhasilDokterStateDone) {
isLoadingSearchNoDokter.value = false;
if (next.model.isNotEmpty) {
hasilSearchData.value = next.model;
// klu lebih dari 1 length nya dibikin list view builder
// klu cm 1 seperti ini
if (hasilSearchData.value.length > 1) {
listViewBuilderShow.value = true;
singleListSearchShow.value = false;
} else {
// deliveryid merupakan json dari id
print('Delivery ID : ${hasilSearchData.value[0].deliveryid}');
print('Tipe ID : ${hasilSearchData.value[0].tipeid}');
print('Selected No Lab : ${hasilSearchData.value[0].nomor}');
print('Selected Nama : ${hasilSearchData.value[0].nama}');
print('Selected Alamat : ${hasilSearchData.value[0].alamat}');
// ctrlNoDokter.text = hasilSearchData.value[0].nomor.toString();
ctrlNoDokter.text = hasilSearchData.value[0].detail.toString();
ctrlNama.text = hasilSearchData.value[0].nama.toString();
ctrlAlamat.text = hasilSearchData.value[0].alamat.toString();
deliveryIDSave.value =
hasilSearchData.value[0].deliveryid.toString();
if (hasilSearchData.value[0].patients!.isNotEmpty) {
// hasilSearchData.value[0].patients?.forEach((element) {
// listPatient.value.add(element);
// });
listPatient.value = hasilSearchData.value[0].patients!;
}
}
} else {
listPatient.value = [];
hasilSearchData.value = [];
ctrlNoDokter.text = "";
ctrlNama.text = "";
ctrlAlamat.text = "";
SanckbarWidget(context, "Data Tidak Ditemukan", snackbarType.warning);
}
}
});
// save pengantaran hasil
ref.listen(pengantaranHasilDokterSave, (prev, next) {
if (next is PengantaranhasilDokterSaveStateLoading) {
isLoadingSearchNoDokter.value = true;
} else if (next is PengantaranhasilDokterSaveStateError) {
isLoadingSearchNoDokter.value = false;
errorMessage.value = next.message ?? "";
SanckbarWidget(context, "${next.message}", snackbarType.error);
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is PengantaranhasilDokterSaveStateDone) {
isLoadingSearchNoDokter.value = false;
if (next.model.status != "OK") {
SanckbarWidget(context, "${next.model.message}", snackbarType.error);
} else {
Navigator.of(context).pushNamedAndRemoveUntil(
konfirmasiRoute,
(route) => false,
);
}
}
});
// check kalau pake scan
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final barcodeScanResultValue = ref.read(barcodeScanResult);
print("barcode Scan Result: $barcodeScanResultValue");
print("Is from scan : ${isFromScanScreen}");
if (isFromScanScreenProvider == true) {
if (barcodeScanResultValue != "") {
isForm.value = true;
isScan.value = false;
ref
.read(pengantaranHasilDokterSearch.notifier)
.loadListNoDokterPengantaranHasilDokter(
search: barcodeScanResultValue,
);
}
} else {
ref.read(barcodeScanResult.notifier).update((state) => "");
ref.read(isFromScanScreen.notifier).update((state) => false);
}
});
}, []);
return Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 544),
padding: EdgeInsets.only(
bottom: Constant.getActualY(context: context, y: 20),
),
// color: Colors.pink,
child: ListView(
children: [
// tab nolab & scanner
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 36),
child: Row(
children: [
// button form kiri
SizedBox(
width: Constant.getActualX(context: context, x: 156),
height: Constant.getActualY(context: context, y: 36),
child: ElevatedButton(
// onPressed: () {
// isForm.value = !isForm.value;
// isScan.value = !isScan.value;
// },
onPressed: () {
if (isForm.value == true) {
return;
} else {
isForm.value = true;
isScan.value = false;
}
},
style: ButtonStyle(
backgroundColor: (isForm.value == true)
? MaterialStateColor.resolveWith(
(st) => Constant.primaryMain)
: MaterialStateColor.resolveWith(
(st) => Constant.buttonIsNotActive),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(12),
topLeft: Radius.circular(12)),
// side: BorderSide(color: Colors.red),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Form',
style: Constant.buttonLarge(context: context).copyWith(
color: (isForm.value == true)
? Constant.backgroundWhite
: Constant.textBlack,
fontWeight: FontWeight.w700,
),
),
),
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 8),
),
// button scan kanan
SizedBox(
width: Constant.getActualX(context: context, x: 156),
height: Constant.getActualY(context: context, y: 36),
child: ElevatedButton(
// onPressed: () {
// isScan.value = !isScan.value;
// isForm.value = !isForm.value;
// },
onPressed: () {
// isScan.value = !isScan.value;
// isForm.value = !isForm.value;
if (isScan.value == true) {
return;
} else {
isForm.value = false;
isScan.value = true;
}
},
style: ButtonStyle(
backgroundColor: (isScan.value == true)
? MaterialStateColor.resolveWith(
(st) => Constant.primaryMain)
: MaterialStateColor.resolveWith(
(st) => Constant.buttonIsNotActive),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(12),
topRight: Radius.circular(12),
),
// side: BorderSide(color: Colors.red),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Scan',
style: Constant.buttonLarge(context: context).copyWith(
color: (isScan.value == true)
? Constant.backgroundWhite
: Constant.textBlack,
fontWeight: FontWeight.w700,
),
),
),
),
),
],
),
),
if (isForm.value == true) ...[
// button batal & simpan jika isForm true
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
// loading
if (isLoadingSearchNoDokter.value) ...[
// Center(
// child: SizedBox(
// width: Constant.getActualX(context: context, x: 20),
// height: Constant.getActualY(context: context, y: 20),
// child: CircularProgressIndicator(),
// ),
// ),
const Center(
child: CircularProgressIndicator(),
),
],
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
// muncul jika hasil search data > 1
if (listViewBuilderShow.value) ...[
Container(
width: Constant.getActualX(context: context, x: 320),
// height: Constant.getActualY(context: context, y: 56),
child: SasTextFieldSearch(
controller: ctrlNoDokter,
hintText: "Nama[Kode]",
labelText: "Nama[Kode]",
focusNode: focusNodeNoDokter,
hasFocus: nodokterhasFocus.value,
isReadOnly: false,
onPressed: () {
if (ctrlNoDokter.text != "" ||
ctrlNoDokter.text.isNotEmpty) {
if (ctrlNoDokter.text.length >= 3) {
ref
.read(pengantaranHasilDokterSearch.notifier)
.loadListNoDokterPengantaranHasilDokter(
search: ctrlNoDokter.text.toString(),
);
}
} else {
SanckbarWidget(
context,
"Silahkan Masukkan Keyword Pencarian",
snackbarType.warning);
}
},
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 10),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 0.9, vertical: 0.5),
height: Constant.getActualY(context: context, y: 290),
child: ListView.builder(
itemCount: hasilSearchData.value.length,
itemBuilder: (context, index) {
return InkWell(
onTap: () {
// ctrlNoDokter.text =
// hasilSearchData.value[index].nomor.toString();
ctrlNoDokter.text =
hasilSearchData.value[index].detail.toString();
ctrlNama.text =
hasilSearchData.value[index].nama.toString();
ctrlAlamat.text =
hasilSearchData.value[index].alamat.toString();
deliveryIDSave.value = hasilSearchData
.value[index].deliveryid
.toString();
if (hasilSearchData
.value[index].patients!.isNotEmpty) {
// hasilSearchData.value[index].patients?.forEach((element) {
// listPatient.value.add(element);
// });
listPatient.value =
hasilSearchData.value[index].patients!;
}
listViewBuilderShow.value = false;
singleListSearchShow.value = true;
},
child: Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 24),
vertical: Constant.getActualY(
context: context, y: 20)),
margin: EdgeInsets.symmetric(
vertical:
Constant.getActualY(context: context, y: 4),
horizontal: Constant.getActualX(
context: context, x: 1)),
// height: Constant.getActualY(context: context, y: 76),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(color: Colors.grey, width: 0.1),
boxShadow: [
BoxShadow(
color: Colors.grey.shade300,
offset: const Offset(0.0, 1), //(x,y)
blurRadius: 2,
),
],
borderRadius: BorderRadius.circular(12)),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Nomor",
style: Constant.caption1(
context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
hasilSearchData.value[index].nomor
.toString(),
// 's',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.caption1(
context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
SizedBox(
height: Constant.getActualY(
context: context, y: 4),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Nama",
style: Constant.caption1(
context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
hasilSearchData.value[index].nama
.toString(),
// 's',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.caption1(
context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Alamat Pengantaran",
style: Constant.caption1(
context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
hasilSearchData.value[index].alamat
.toString(),
// 's',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.caption1(
context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
],
),
),
),
);
}),
),
],
// single list show
if (singleListSearchShow.value) ...[
// no lab autocomplete
Container(
width: Constant.getActualX(context: context, x: 320),
// height: Constant.getActualY(context: context, y: 56),
child: SasTextFieldSearch(
controller: ctrlNoDokter,
hintText: "Nama[Kode]",
labelText: "Nama[Kode]",
focusNode: focusNodeNoDokter,
hasFocus: nodokterhasFocus.value,
isReadOnly: false,
onPressed: () {
if (ctrlNoDokter.text != "" ||
ctrlNoDokter.text.isNotEmpty) {
if (ctrlNoDokter.text.length >= 3) {
ref
.read(pengantaranHasilDokterSearch.notifier)
.loadListNoDokterPengantaranHasilDokter(
search: ctrlNoDokter.text.toString(),
);
}
} else {
SanckbarWidget(
context,
"Silahkan Masukkan Keyword Pencarian",
snackbarType.warning);
}
},
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
// // nama
// Container(
// width: Constant.getActualX(context: context, x: 320),
// height: Constant.getActualY(context: context, y: 56),
// child: SasTextField(
// hintText: "Nama",
// labelText: "Nama",
// focusNode: focusNodeNama,
// hasFocus: namahasFocus.value,
// controller: ctrlNama,
// isReadOnly: true,
// ),
// ),
// SizedBox(
// height: Constant.getActualY(context: context, y: 20),
// ),
// alamat
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 120),
// color: Colors.green,
child: SasTextFieldArea(
hintText: "Alamat Pengantaran",
labelText: "Alamat Pengantaran",
focusNode: focusNodeAlamat,
hasFocus: alamathasFocus.value,
controller: ctrlAlamat,
isReadOnly: true,
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 10),
),
if (listPatient.value.isNotEmpty) ...[
for (var i = 0; i < listPatient.value.length; i++) ...[
Padding(
padding: EdgeInsets.only(
bottom: Constant.getActualY(context: context, y: 10)),
child: PatientCard(
name: listPatient.value[i].pasien.toString(),
noLab:
listPatient.value[i].tOrderHeaderLabNumber.toString(),
),
),
],
] else ...[
SizedBox.shrink(),
SizedBox(
height: Constant.getActualY(context: context, y: 40),
)
],
],
// SizedBox(
// height: Constant.getActualY(context: context, y: 100),
// ),
Padding(
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 20),
bottom: Constant.getActualY(context: context, y: 20),
),
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
// width: Constant.getActualX(context: context, x: 317),
// height: Constant.getActualY(context: context, y: 36),
// padding: EdgeInsets.symmetric(
// horizontal: Constant.getActualX(context: context, x: 10)),
height: Constant.getActualY(context: context, y: 36),
// color: Colors.pink,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// batal
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.backgroundWhite),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(color: Constant.blueButton),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Batal',
style: Constant.body3(context: context).copyWith(
color: Constant.blueButton,
fontWeight: FontWeight.w700,
),
),
),
),
// simpan
ElevatedButton(
onPressed: (isLoadingSearchNoDokter.value)
? null
: () {
print("kurir id : $mCourirID");
print("tipe id : $tipePekerjaanIDSave");
print("delivery id : ${deliveryIDSave.value}");
if (deliveryIDSave.value == "") {
SanckbarWidget(
context,
"Silahkan Cari No Dokter",
snackbarType.warning);
} else {
ref
.read(pengantaranHasilDokterSave.notifier)
.pengantaranHasilDokterSave(
courierID: mCourirID,
tipeID: tipePekerjaanIDSave,
deliveryID: deliveryIDSave.value,
);
}
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.blueButton,
),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
// side: BorderSide(color: Constant.blueButton),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Simpan',
style: Constant.body3(context: context).copyWith(
color: Constant.backgroundWhite,
fontWeight: FontWeight.w700,
),
),
),
),
],
),
),
),
),
] else ...[
// button scan barcode
SizedBox(
height: Constant.getActualY(context: context, y: 445),
),
Container(
width: Constant.getActualX(context: context, x: 317),
height: Constant.getActualY(context: context, y: 36),
// color: Colors.pink,
child: SizedBox(
width: Constant.getActualX(context: context, x: 83),
height: Constant.getActualY(context: context, y: 36),
child: ElevatedButton(
onPressed: () {
FocusManager.instance.primaryFocus?.unfocus();
ref.read(isFromScanScreen.notifier).update((state) => true);
Navigator.of(context).pushNamedAndRemoveUntil(
inputScanRoute, (route) => false,
arguments: InputScanPekerjaanProp(0, 2));
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.blueButton),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
// side: BorderSide(color: Constant.blueButton),
),
),
shadowColor: MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.document_scanner),
SizedBox(
width: Constant.getActualX(context: context, x: 10),
),
Text(
'Scan Barcode',
style: Constant.body3(context: context).copyWith(
color: Constant.backgroundWhite,
fontWeight: FontWeight.w700,
),
),
],
),
),
),
),
],
],
),
);
}
}

View File

@@ -0,0 +1,811 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/app/route.dart';
import '../../app/constant.dart';
import '../../models/patient_model.dart';
import '../../models/response_search_pengantaran_hasil_model.dart';
import '../../provider/current_scan_provider.dart';
import '../../provider/current_user_provider.dart';
import '../../provider/dio_provider.dart';
import '../../repository/pengantaran_hasil_instansi_repository.dart';
import '../../widget/custom_textfield.dart';
import '../../widget/patient_card.dart';
import '../../widget/sas_textfield.dart';
import '../../widget/snackbar_widget.dart';
import 'pengantaran_hasil_instansi_loadnosuratjalan_provider.dart';
import 'pengantaran_hasil_instansi_save_provider.dart';
class InputPengantaranHasilInstansiScreen extends HookConsumerWidget {
// const InputPengantaranHasilInstansiScreen({
// super.key,
// });
const InputPengantaranHasilInstansiScreen({super.key, required this.data});
final Map<String, dynamic> data;
@override
Widget build(BuildContext context, WidgetRef ref) {
print(data);
final tipePekerjaanIDSave = data['tipePekerjaan'];
final deliveryIDSave = useState<String>("");
final mCourirID =
ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0";
final isForm = useState(true);
final isScan = useState(false);
final dummySuratJalan =
useState<List<DummyNoSuratJalan>>(List.empty(growable: true));
final focusNodeCompany = useFocusNode();
final companyhasFocus = useState(false);
final isLoadingSearchSuratJalan = useState(false);
final ctrlNoCompany = useTextEditingController(text: "");
final dummyInstansiList =
useState<List<DummyNoSuratJalan>>(List.empty(growable: true));
final listPatient =
useState<List<PatientModel>>(List.empty(growable: true));
final hasilSearchData = useState<List<ResponseSearchPengantaranHasilModel>>(
List.empty(growable: true));
final ctrlNama = useTextEditingController(text: "");
final focusNodeNama = useFocusNode();
final namahasFocus = useState(false);
final ctrlAlamat = useTextEditingController(text: "");
final focusNodeAlamat = useFocusNode();
final alamathasFocus = useState(false);
final errorMessage = useState("");
final isFromScanScreenProvider = ref.read(isFromScanScreen);
final listViewBuilderShow = useState(false);
final singleListSearchShow = useState(true);
focusNodeCompany.addListener(() {
if (focusNodeCompany.hasFocus) {
companyhasFocus.value = true;
} else {
companyhasFocus.value = false;
}
});
focusNodeNama.addListener(() {
if (focusNodeNama.hasFocus) {
namahasFocus.value = true;
} else {
namahasFocus.value = false;
}
});
focusNodeAlamat.addListener(() {
if (focusNodeAlamat.hasFocus) {
alamathasFocus.value = true;
} else {
alamathasFocus.value = false;
}
});
// useEffect(() {
// isForm.value = true;
// isScan.value = false;
// }, []);
// search
ref.listen(pengantaranHasilInstansi, (prev, next) {
if (next is PengantaranhasilInstansiStateLoading) {
isLoadingSearchSuratJalan.value = true;
} else if (next is PengantaranhasilInstansiStateError) {
isLoadingSearchSuratJalan.value = false;
errorMessage.value = next.message ?? "";
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is PengantaranhasilInstansiStateDone) {
isLoadingSearchSuratJalan.value = false;
// listSearch.value = next.model;
if (next.model.isNotEmpty) {
hasilSearchData.value = next.model;
// klu lebih dari 1 length nya dibikin list view builder
// klu cm 1 seperti ini
if (hasilSearchData.value.length > 1) {
listViewBuilderShow.value = true;
singleListSearchShow.value = false;
} else {
// hanya 1
listViewBuilderShow.value = false;
singleListSearchShow.value = true;
// deliveryid merupakan json dari id
print('Delivery ID : ${hasilSearchData.value[0].deliveryid}');
print('Tipe ID : ${hasilSearchData.value[0].tipeid}');
print('Selected No Instansi : ${hasilSearchData.value[0].nomor}');
print('Selected Detail : ${hasilSearchData.value[0].detail}');
print('Selected Nama : ${hasilSearchData.value[0].nama}');
print('Selected Alamat : ${hasilSearchData.value[0].alamat}');
// ctrlNoCompany.text = hasilSearchData.value[0].nomor.toString();
ctrlNoCompany.text = hasilSearchData.value[0].detail.toString();
ctrlNama.text = hasilSearchData.value[0].nama.toString();
ctrlAlamat.text = hasilSearchData.value[0].alamat.toString();
deliveryIDSave.value =
hasilSearchData.value[0].deliveryid.toString();
if (hasilSearchData.value[0].patients!.isNotEmpty) {
// hasilSearchData.value[0].patients?.forEach((element) {
// listPatient.value.add(element);
// });
listPatient.value = hasilSearchData.value[0].patients!;
}
}
} else {
listPatient.value = [];
hasilSearchData.value = [];
ctrlNoCompany.text = "";
ctrlNama.text = "";
ctrlAlamat.text = "";
ref.read(barcodeScanResult.notifier).update((state) => "");
ref.read(isFromScanScreen.notifier).update((state) => false);
SanckbarWidget(context, "Data Tidak Ditemukan", snackbarType.warning);
}
}
});
// save pengantaran hasil
ref.listen(pengantaranHasilCompanySave, (prev, next) {
if (next is PengantaranhasilCompanySaveStateLoading) {
isLoadingSearchSuratJalan.value = true;
} else if (next is PengantaranhasilCompanySaveStateError) {
isLoadingSearchSuratJalan.value = false;
errorMessage.value = next.message ?? "";
SanckbarWidget(context, "${next.message}", snackbarType.error);
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is PengantaranhasilCompanySaveStateDone) {
isLoadingSearchSuratJalan.value = false;
if (next.model.status != "OK") {
SanckbarWidget(context, "${next.model.message}", snackbarType.error);
} else {
Navigator.of(context).pushNamedAndRemoveUntil(
konfirmasiRoute,
(route) => false,
);
}
}
});
// check kalau pake scan
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final barcodeScanResultValue = ref.read(barcodeScanResult);
print("barcode Scan Result: $barcodeScanResultValue");
print("Is from scan : ${isFromScanScreen}");
if (isFromScanScreenProvider == true) {
if (barcodeScanResultValue != "") {
isForm.value = true;
isScan.value = false;
ref
.read(pengantaranHasilInstansi.notifier)
.loadListNoSuratJalanPengantaranHasilInstansi(
search: barcodeScanResultValue,
);
}
} else {
ref.read(barcodeScanResult.notifier).update((state) => "");
ref.read(isFromScanScreen.notifier).update((state) => false);
}
});
}, []);
return Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 544),
// color: Colors.pink,
child: ListView(
children: [
// tab nolab & scanner
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 36),
child: Row(
children: [
// button form kiri
SizedBox(
width: Constant.getActualX(context: context, x: 156),
height: Constant.getActualY(context: context, y: 36),
child: ElevatedButton(
// onPressed: () {
// isForm.value = !isForm.value;
// isScan.value = !isScan.value;
// },
onPressed: () {
if (isForm.value == true) {
return;
} else {
isForm.value = true;
isScan.value = false;
}
},
style: ButtonStyle(
backgroundColor: (isForm.value == true)
? MaterialStateColor.resolveWith(
(st) => Constant.primaryMain)
: MaterialStateColor.resolveWith(
(st) => Constant.buttonIsNotActive),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(12),
topLeft: Radius.circular(12)),
// side: BorderSide(color: Colors.red),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Form',
style: Constant.buttonLarge(context: context).copyWith(
color: (isForm.value == true)
? Constant.backgroundWhite
: Constant.textBlack,
fontWeight: FontWeight.w700,
),
),
),
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 8),
),
// button scan kanan
SizedBox(
width: Constant.getActualX(context: context, x: 156),
height: Constant.getActualY(context: context, y: 36),
child: ElevatedButton(
// onPressed: () {
// isScan.value = !isScan.value;
// isForm.value = !isForm.value;
// },
onPressed: () {
if (isScan.value == true) {
return;
} else {
isForm.value = false;
isScan.value = true;
}
},
style: ButtonStyle(
backgroundColor: (isScan.value == true)
? MaterialStateColor.resolveWith(
(st) => Constant.primaryMain)
: MaterialStateColor.resolveWith(
(st) => Constant.buttonIsNotActive),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(12),
topRight: Radius.circular(12),
),
// side: BorderSide(color: Colors.red),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Scan',
style: Constant.buttonLarge(context: context).copyWith(
color: (isScan.value == true)
? Constant.backgroundWhite
: Constant.textBlack,
fontWeight: FontWeight.w700,
),
),
),
),
),
],
),
),
if (isForm.value == true) ...[
// button batal & simpan jika isForm true
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
// loading
if (isLoadingSearchSuratJalan.value) ...[
// Center(
// child: SizedBox(
// width: Constant.getActualX(context: context, x: 20),
// height: Constant.getActualY(context: context, y: 20),
// child: CircularProgressIndicator(),
// ),
// ),
const Center(
child: CircularProgressIndicator(),
),
],
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
// muncul jika hasil search data > 1
if (listViewBuilderShow.value) ...[
Container(
width: Constant.getActualX(context: context, x: 320),
// height: Constant.getActualY(context: context, y: 56),
child: SasTextFieldSearch(
controller: ctrlNoCompany,
// hintText: "No Company",
// labelText: "No Company",
hintText: "Nama[Kode]",
labelText: "Nama[Kode]",
focusNode: focusNodeCompany,
hasFocus: companyhasFocus.value,
isReadOnly: false,
onPressed: () {
if (ctrlNoCompany.text != "" ||
ctrlNoCompany.text.isNotEmpty) {
if (ctrlNoCompany.text.length >= 3) {
ref
.read(pengantaranHasilInstansi.notifier)
.loadListNoSuratJalanPengantaranHasilInstansi(
search: ctrlNoCompany.text.toString(),
);
}
} else {
SanckbarWidget(
context,
"Silahkan Masukkan Keyword Pencarian",
snackbarType.warning);
}
},
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 10),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 0.9, vertical: 0.5),
height: Constant.getActualY(context: context, y: 290),
child: ListView.builder(
itemCount: hasilSearchData.value.length,
itemBuilder: (context, index) {
return InkWell(
onTap: () {
// ctrlNoCompany.text =
// hasilSearchData.value[index].nomor.toString();
ctrlNoCompany.text =
hasilSearchData.value[index].detail.toString();
ctrlNama.text =
hasilSearchData.value[index].nama.toString();
ctrlAlamat.text =
hasilSearchData.value[index].alamat.toString();
if (hasilSearchData
.value[index].patients!.isNotEmpty) {
// hasilSearchData.value[index].patients?.forEach((element) {
// listPatient.value.add(element);
// });
listPatient.value =
hasilSearchData.value[index].patients!;
}
deliveryIDSave.value =
hasilSearchData.value[index].deliveryid.toString();
listViewBuilderShow.value = false;
singleListSearchShow.value = true;
},
child: Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(
context: context, x: 24),
vertical: Constant.getActualY(
context: context, y: 20)),
margin: EdgeInsets.symmetric(
vertical:
Constant.getActualY(context: context, y: 4),
horizontal: Constant.getActualX(
context: context, x: 1)),
// height: Constant.getActualY(context: context, y: 76),
decoration: BoxDecoration(
color: Colors.white,
border:
Border.all(color: Colors.grey, width: 0.1),
boxShadow: [
BoxShadow(
color: Colors.grey.shade300,
offset: const Offset(0.0, 1), //(x,y)
blurRadius: 2,
),
],
borderRadius: BorderRadius.circular(12)),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Nomor",
style: Constant.caption1(
context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
hasilSearchData.value[index].nomor
.toString(),
// 's',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.caption1(
context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
SizedBox(
height: Constant.getActualY(
context: context, y: 4),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Nama",
style: Constant.caption1(
context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
hasilSearchData.value[index].nama
.toString(),
// 's',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.caption1(
context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Text(
"Alamat Pengantaran",
style: Constant.caption1(
context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
Expanded(
child: Text(
hasilSearchData.value[index].alamat
.toString(),
// 's',
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: Constant.caption1(
context: context)
.copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
)
],
),
],
),
),
),
);
}),
)
],
// single list show
if (singleListSearchShow.value) ...[
// no lab autocomplete
Container(
width: Constant.getActualX(context: context, x: 320),
// height: Constant.getActualY(context: context, y: 56),
child: SasTextFieldSearch(
controller: ctrlNoCompany,
hintText: "Nama[Kode]",
labelText: "Nama[Kode]",
// labelText: "No Company",
focusNode: focusNodeCompany,
hasFocus: companyhasFocus.value,
isReadOnly: false,
onPressed: () {
if (ctrlNoCompany.text != "" ||
ctrlNoCompany.text.isNotEmpty) {
if (ctrlNoCompany.text.length >= 3) {
ref
.read(pengantaranHasilInstansi.notifier)
.loadListNoSuratJalanPengantaranHasilInstansi(
search: ctrlNoCompany.text.toString(),
);
}
} else {
SanckbarWidget(
context,
"Silahkan Masukkan Keyword Pencarian",
snackbarType.warning);
}
},
),
),
// SizedBox(
// height: Constant.getActualY(context: context, y: 20),
// ),
// // nama
// Container(
// width: Constant.getActualX(context: context, x: 320),
// height: Constant.getActualY(context: context, y: 56),
// child: SasTextField(
// hintText: "Nama",
// labelText: "Nama",
// focusNode: focusNodeNama,
// hasFocus: namahasFocus.value,
// controller: ctrlNama,
// isReadOnly: true,
// ),
// ),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
// alamat
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 120),
// color: Colors.green,
child: SasTextFieldArea(
hintText: "Alamat Pengantaran",
labelText: "Alamat Pengantaran",
focusNode: focusNodeAlamat,
hasFocus: alamathasFocus.value,
controller: ctrlAlamat,
isReadOnly: true,
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 10),
),
if (listPatient.value.isNotEmpty) ...[
for (var i = 0; i < listPatient.value.length; i++) ...[
Padding(
padding: EdgeInsets.only(
bottom: Constant.getActualY(context: context, y: 10),
),
child: PatientCard(
name: listPatient.value[i].pasien.toString(),
noLab:
listPatient.value[i].tOrderHeaderLabNumber.toString(),
),
),
],
] else ...[
SizedBox.shrink(),
SizedBox(
height: Constant.getActualY(context: context, y: 40),
)
],
],
// SizedBox(
// height: Constant.getActualY(context: context, y: 156),
// ),
Padding(
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 20),
bottom: Constant.getActualY(context: context, y: 20),
),
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
// width: Constant.getActualX(context: context, x: 317),
// height: Constant.getActualY(context: context, y: 36),
// padding: EdgeInsets.symmetric(
// horizontal: Constant.getActualX(context: context, x: 10),
// ),
height: Constant.getActualY(context: context, y: 36),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// batal
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.backgroundWhite),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(color: Constant.blueButton),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Batal',
style: Constant.body3(context: context).copyWith(
color: Constant.blueButton,
fontWeight: FontWeight.w700,
),
),
),
),
// simpan
ElevatedButton(
onPressed: (isLoadingSearchSuratJalan.value)
? null
: () {
print("kurir id : $mCourirID");
print("tipe id : $tipePekerjaanIDSave");
print("delivery id : ${deliveryIDSave.value}");
if (deliveryIDSave.value == "") {
SanckbarWidget(
context,
"Silahkan Cari No Company",
snackbarType.warning);
} else {
ref
.read(
pengantaranHasilCompanySave.notifier)
.pengantaranHasilCompanySave(
courierID: mCourirID,
tipeID: tipePekerjaanIDSave,
deliveryID: deliveryIDSave.value,
);
}
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.blueButton,
),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
// side: BorderSide(color: Constant.blueButton),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Simpan',
style: Constant.body3(context: context).copyWith(
color: Constant.backgroundWhite,
fontWeight: FontWeight.w700,
),
),
),
),
],
),
),
),
),
] else ...[
// button scan barcode
SizedBox(
height: Constant.getActualY(context: context, y: 445),
),
Container(
width: Constant.getActualX(context: context, x: 317),
height: Constant.getActualY(context: context, y: 36),
// color: Colors.pink,
child: SizedBox(
width: Constant.getActualX(context: context, x: 83),
height: Constant.getActualY(context: context, y: 36),
child: ElevatedButton(
onPressed: () {
FocusManager.instance.primaryFocus?.unfocus();
ref.read(isFromScanScreen.notifier).update((state) => true);
Navigator.of(context).pushNamedAndRemoveUntil(
inputScanRoute, (route) => false,
arguments: InputScanPekerjaanProp(0, 1));
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.blueButton),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
// side: BorderSide(color: Constant.blueButton),
),
),
shadowColor: MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.document_scanner),
SizedBox(
width: Constant.getActualX(context: context, x: 10),
),
Text(
'Scan Barcode',
style: Constant.body3(context: context).copyWith(
color: Constant.backgroundWhite,
fontWeight: FontWeight.w700,
),
),
],
),
),
),
),
],
],
),
);
}
}

View File

@@ -0,0 +1,545 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/app/route.dart';
import '/screen/input_pekerjaan/pengantaran_hasil_pasien_loadnolab_provider.dart';
import '/widget/sas_textfield.dart';
import '../../app/constant.dart';
import '../../models/response_search_pengantaran_hasil_model.dart';
import '../../provider/current_scan_provider.dart';
import '../../provider/current_user_provider.dart';
import '../../provider/dio_provider.dart';
import '../../repository/pengantaran_hasil_pasien_repository.dart';
import '../../widget/custom_textfield.dart';
import '../../widget/snackbar_widget.dart';
import 'pengantaran_hasil_pasien_save_provider.dart';
class InputPengantaranHasilPasienScreen extends HookConsumerWidget {
// const InputPengantaranHasilPasienScreen({
// super.key,
// });
const InputPengantaranHasilPasienScreen({super.key, required this.data});
final Map<String, dynamic> data;
@override
Widget build(BuildContext context, WidgetRef ref) {
print(data);
final isForm = useState(true);
final isScan = useState(false);
final mCourirID =
ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0";
final isFromScanScreenProvider = ref.read(isFromScanScreen);
final tipePekerjaanIDSave = data['tipePekerjaan'];
final deliveryIDSave = useState<String>("");
final hasilSearchData = useState<List<ResponseSearchPengantaranHasilModel>>(
List.empty(growable: true));
final isLoadingSearchNoLab = useState(false);
final focusNodeNoLab = useFocusNode();
final nolabhasFocus = useState(false);
final ctrlNoLab = useTextEditingController(text: "");
final ctrlNama = useTextEditingController(text: "");
final focusNodeNama = useFocusNode();
final namahasFocus = useState(false);
final ctrlAlamat = useTextEditingController(text: "");
final focusNodeAlamat = useFocusNode();
final alamathasFocus = useState(false);
final errorMessage = useState("");
focusNodeNoLab.addListener(() {
if (focusNodeNoLab.hasFocus) {
nolabhasFocus.value = true;
} else {
nolabhasFocus.value = false;
}
});
focusNodeNama.addListener(() {
if (focusNodeNama.hasFocus) {
namahasFocus.value = true;
} else {
namahasFocus.value = false;
}
});
focusNodeAlamat.addListener(() {
if (focusNodeAlamat.hasFocus) {
alamathasFocus.value = true;
} else {
alamathasFocus.value = false;
}
});
// useEffect(() {
// isForm.value = true;
// isScan.value = false;
// }, []);
// search no lab
ref.listen(pengantaranHasilPasienSearchNoLab, (prev, next) {
if (next is PengantaranhasilPasienStateLoading) {
isLoadingSearchNoLab.value = true;
} else if (next is PengantaranhasilPasienStateError) {
isLoadingSearchNoLab.value = false;
errorMessage.value = next.message ?? "";
SanckbarWidget(context, "${next.message}", snackbarType.error);
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is PengantaranhasilPasienStateDone) {
isLoadingSearchNoLab.value = false;
if (next.model.isNotEmpty) {
hasilSearchData.value = next.model;
// deliveryid merupakan json dari id
print('Delivery ID : ${hasilSearchData.value[0].deliveryid}');
print('Tipe ID : ${hasilSearchData.value[0].tipeid}');
print('Selected No Lab : ${hasilSearchData.value[0].nomor}');
print('Selected Nama : ${hasilSearchData.value[0].nama}');
print('Selected Alamat : ${hasilSearchData.value[0].alamat}');
ctrlNoLab.text = hasilSearchData.value[0].nomor.toString();
ctrlNama.text = hasilSearchData.value[0].nama.toString();
ctrlAlamat.text = hasilSearchData.value[0].alamat.toString();
deliveryIDSave.value = hasilSearchData.value[0].deliveryid.toString();
} else {
hasilSearchData.value = [];
ctrlNoLab.text = "";
ctrlNama.text = "";
ctrlAlamat.text = "";
SanckbarWidget(context, "Data Tidak Ditemukan", snackbarType.warning);
}
}
});
// save pengantaran hasil
ref.listen(pengantaranHasilPasienSave, (prev, next) {
if (next is PengantaranhasilPasienSaveStateLoading) {
isLoadingSearchNoLab.value = true;
} else if (next is PengantaranhasilPasienSaveStateError) {
isLoadingSearchNoLab.value = false;
errorMessage.value = next.message ?? "";
SanckbarWidget(context, "${next.message}", snackbarType.error);
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is PengantaranhasilPasienSaveStateDone) {
isLoadingSearchNoLab.value = false;
ref.read(barcodeScanResult.notifier).update((state) => "");
if (next.model.status != "OK") {
SanckbarWidget(context, "${next.model.message}", snackbarType.error);
} else {
Navigator.of(context).pushNamedAndRemoveUntil(
konfirmasiRoute,
(route) => false,
);
}
}
});
// check kalau pake scan
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
final barcodeScanResultValue = ref.read(barcodeScanResult);
print("barcode Scan Result: $barcodeScanResultValue");
print("Is from scan : ${isFromScanScreen}");
if (isFromScanScreenProvider == true) {
if (barcodeScanResultValue != "") {
isForm.value = true;
isScan.value = false;
ref
.read(pengantaranHasilPasienSearchNoLab.notifier)
.loadListNoLabPengantaranHasilPasien(
search: barcodeScanResultValue,
);
}
} else {
ref.read(barcodeScanResult.notifier).update((state) => "");
ref.read(isFromScanScreen.notifier).update((state) => false);
}
});
}, []);
return Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 544),
// color: Colors.pink,
child: ListView(
children: [
// tab nolab & scanner
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 36),
child: Row(
children: [
// button form kiri
SizedBox(
width: Constant.getActualX(context: context, x: 156),
height: Constant.getActualY(context: context, y: 36),
child: ElevatedButton(
onPressed: () {
if (isForm.value == true) {
return;
} else {
isForm.value = true;
isScan.value = false;
}
// isForm.value = !isForm.value;
// isScan.value = !isScan.value;
},
// onPressed: null,
style: ButtonStyle(
backgroundColor: (isForm.value == true)
? MaterialStateColor.resolveWith(
(st) => Constant.primaryMain)
: MaterialStateColor.resolveWith(
(st) => Constant.buttonIsNotActive),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(12),
topLeft: Radius.circular(12)),
// side: BorderSide(color: Colors.red),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Form',
style: Constant.buttonLarge(context: context).copyWith(
color: (isForm.value == true)
? Constant.backgroundWhite
: Constant.textBlack,
fontWeight: FontWeight.w700,
),
),
),
),
),
SizedBox(
width: Constant.getActualX(context: context, x: 8),
),
// button scan kanan
SizedBox(
width: Constant.getActualX(context: context, x: 156),
height: Constant.getActualY(context: context, y: 36),
child: ElevatedButton(
onPressed: () {
// isScan.value = !isScan.value;
// isForm.value = !isForm.value;
if (isScan.value == true) {
return;
} else {
isForm.value = false;
isScan.value = true;
}
},
// onPressed: null,
style: ButtonStyle(
backgroundColor: (isScan.value == true)
? MaterialStateColor.resolveWith(
(st) => Constant.primaryMain)
: MaterialStateColor.resolveWith(
(st) => Constant.buttonIsNotActive),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(12),
topRight: Radius.circular(12),
),
// side: BorderSide(color: Colors.red),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Scan',
style: Constant.buttonLarge(context: context).copyWith(
color: (isScan.value == true)
? Constant.backgroundWhite
: Constant.textBlack,
fontWeight: FontWeight.w700,
),
),
),
),
),
],
),
),
if (isForm.value == true) ...[
// button batal & simpan jika isForm true
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
// loading
if (isLoadingSearchNoLab.value) ...[
// Center(
// child: SizedBox(
// width: Constant.getActualX(context: context, x: 20),
// height: Constant.getActualY(context: context, y: 20),
// child: CircularProgressIndicator(),
// ),
// ),
const Center(
child: CircularProgressIndicator(),
),
],
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
// no lab search with icon
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 56),
child: SasTextFieldSearch(
controller: ctrlNoLab,
hintText: "No Lab",
labelText: "No Lab",
focusNode: focusNodeNoLab,
hasFocus: nolabhasFocus.value,
isReadOnly: false,
onPressed: () {
if (ctrlNoLab.text != "" || ctrlNoLab.text.isNotEmpty) {
if (ctrlNoLab.text.length > 3) {
ref
.read(pengantaranHasilPasienSearchNoLab.notifier)
.loadListNoLabPengantaranHasilPasien(
search: ctrlNoLab.text.toString(),
);
}
} else {
SanckbarWidget(
context,
"Silahkan Masukkan Keyword Pencarian",
snackbarType.warning);
}
},
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
// nama
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 56),
child: SasTextField(
hintText: "Nama",
labelText: "Nama",
focusNode: focusNodeNama,
hasFocus: namahasFocus.value,
controller: ctrlNama,
isReadOnly: true,
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
// alamat
Container(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 120),
// color: Colors.green,
child: SasTextFieldArea(
hintText: "Alamat Pengantaran",
labelText: "Alamat Pengantaran",
focusNode: focusNodeAlamat,
hasFocus: alamathasFocus.value,
controller: ctrlAlamat,
isReadOnly: true,
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 50),
),
Padding(
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 20),
bottom: Constant.getActualY(context: context, y: 20),
),
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
// width: Constant.getActualX(context: context, x: 317),
// height: Constant.getActualY(context: context, y: 36),
// padding: EdgeInsets.symmetric(
// horizontal: Constant.getActualX(context: context, x: 10)),
height: Constant.getActualY(context: context, y: 36),
// color: Colors.pink,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// batal
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.backgroundWhite),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: Constant.blueButton,
),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Batal',
style: Constant.body3(context: context).copyWith(
color: Constant.blueButton,
fontWeight: FontWeight.w700,
),
),
),
),
// simpan
ElevatedButton(
onPressed: (isLoadingSearchNoLab.value)
? null
: () {
print("kurir id : $mCourirID");
print("tipe id : $tipePekerjaanIDSave");
print("delivery id : ${deliveryIDSave.value}");
if (deliveryIDSave.value == "") {
SanckbarWidget(
context,
"Silahkan Cari No Lab",
snackbarType.warning);
} else {
ref
.read(pengantaranHasilPasienSave.notifier)
.pengantaranHasilPasienSave(
courierID: mCourirID,
tipeID: tipePekerjaanIDSave,
deliveryID: deliveryIDSave.value,
);
}
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.blueButton,
),
shape:
MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
// side: BorderSide(color: Constant.blueButton),
),
),
shadowColor:
MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Simpan',
style: Constant.body3(context: context).copyWith(
color: Constant.backgroundWhite,
fontWeight: FontWeight.w700,
),
),
),
),
],
),
),
),
),
] else ...[
// button scan barcode
SizedBox(
height: Constant.getActualY(context: context, y: 445),
),
Container(
width: Constant.getActualX(context: context, x: 317),
height: Constant.getActualY(context: context, y: 36),
// color: Colors.pink,
child: SizedBox(
width: Constant.getActualX(context: context, x: 83),
height: Constant.getActualY(context: context, y: 36),
child: ElevatedButton(
onPressed: () {
FocusManager.instance.primaryFocus?.unfocus();
ref.read(isFromScanScreen.notifier).update((state) => true);
Navigator.of(context).popAndPushNamed(inputScanRoute,
arguments: InputScanPekerjaanProp(0, 0));
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.blueButton),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
// side: BorderSide(color: Constant.blueButton),
),
),
shadowColor: MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.document_scanner),
SizedBox(
width: Constant.getActualX(context: context, x: 10),
),
Text(
'Scan Barcode',
style: Constant.body3(context: context).copyWith(
color: Constant.backgroundWhite,
fontWeight: FontWeight.w700,
),
),
],
),
),
),
),
],
],
),
);
}
}

View File

@@ -0,0 +1,103 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import '../../app/route.dart';
import '../../provider/current_scan_provider.dart';
class InputScanScreen extends HookConsumerWidget {
const InputScanScreen({super.key, required this.data});
final InputScanPekerjaanProp data;
@override
Widget build(BuildContext context, WidgetRef ref) {
print("DATAXSCAN : ${data.input} - ${data.tipe}");
MobileScannerController cameraController = MobileScannerController();
final hasilScan = useState<String>("");
return Scaffold(
appBar: AppBar(
title: const Text('Scan Barcode'),
actions: [
IconButton(
color: Colors.white,
icon: ValueListenableBuilder(
valueListenable: cameraController.torchState,
builder: (context, state, child) {
switch (state as TorchState) {
case TorchState.off:
return const Icon(Icons.flash_off, color: Colors.grey);
case TorchState.on:
return const Icon(Icons.flash_on, color: Colors.yellow);
}
},
),
iconSize: 32.0,
onPressed: () => cameraController.toggleTorch(),
),
IconButton(
color: Colors.white,
icon: ValueListenableBuilder(
valueListenable: cameraController.cameraFacingState,
builder: (context, state, child) {
switch (state as CameraFacing) {
case CameraFacing.front:
return const Icon(Icons.camera_front);
case CameraFacing.back:
return const Icon(Icons.camera_rear);
}
},
),
iconSize: 32.0,
onPressed: () => cameraController.switchCamera(),
),
],
),
body: MobileScanner(
// fit: BoxFit.contain,
controller: cameraController,
onDetect: (capture) {
final List<Barcode> barcodes = capture.barcodes;
for (final barcode in barcodes) {
hasilScan.value = barcode.rawValue.toString();
debugPrint('Barcode found! ${barcode.rawValue}');
}
if (hasilScan.value.isNotEmpty) {
// set ke provider global
ref
.read(barcodeScanResult.notifier)
.update((state) => hasilScan.value);
if (data.tipe == 0) {
Navigator.of(context).popAndPushNamed(
inputPekerjaan,
arguments: inputPekerjaanProp(0, 0),
);
} else {
if (data.tipe == 1) {
Navigator.of(context).popAndPushNamed(
inputPekerjaan,
arguments: inputPekerjaanProp(0, 1),
);
} else {
if (data.tipe == 2) {
Navigator.of(context).popAndPushNamed(
inputPekerjaan,
arguments: inputPekerjaanProp(0, 2),
);
}
}
}
// Navigator.pop(context);
}
},
),
);
}
}

View File

@@ -0,0 +1,63 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '/models/response_list_branch_model.dart';
import '/models/response_search_pengantaran_hasil_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/pengambilan_bahan_repository.dart';
import '../../repository/pengantaran_hasil_pasien_repository.dart';
// 3. state provider
final pengambilanBahanListCabang = StateNotifierProvider<PengambilanBahanNotifier, PengambilanBahanState>(
(ref) => PengambilanBahanNotifier(ref: ref));
// 2. notifier
class PengambilanBahanNotifier extends StateNotifier<PengambilanBahanState> {
final Ref ref;
PengambilanBahanNotifier({required this.ref}) : super(PengambilanBahanStateInit());
void loadListCabangPengambilanBahan() async {
try {
state = PengambilanBahanStateLoading();
final resp = await PengambilanBahanRepository(dio: ref.read(dioProvider))
.loadListCabangPengambilanBahan();
state = PengambilanBahanStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = PengambilanBahanStateError(message: e.message ?? "");
} else {
state = PengambilanBahanStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class PengambilanBahanState extends Equatable {
final DateTime date;
const PengambilanBahanState(this.date);
@override
List<Object?> get props => [date];
}
class PengambilanBahanStateInit extends PengambilanBahanState {
PengambilanBahanStateInit() : super(DateTime.now());
}
class PengambilanBahanStateLoading extends PengambilanBahanState {
PengambilanBahanStateLoading() : super(DateTime.now());
}
class PengambilanBahanStateError extends PengambilanBahanState {
final String? message;
PengambilanBahanStateError({
required this.message,
}) : super(DateTime.now());
}
class PengambilanBahanStateDone extends PengambilanBahanState {
final List<ResponseListBranchModel> model;
PengambilanBahanStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,77 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../models/response_save_pengantaran_hasil_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/pengambilan_bahan_repository.dart';
import '../../repository/pengantaran_hasil_dokter_repository.dart';
// 3. state provider
final pengambilanBahanSave = StateNotifierProvider<PengambilanBahanSaveNotifier,
PengambilanBahanSaveState>((ref) => PengambilanBahanSaveNotifier(ref: ref));
// 2. notifier
class PengambilanBahanSaveNotifier
extends StateNotifier<PengambilanBahanSaveState> {
final Ref ref;
PengambilanBahanSaveNotifier({required this.ref})
: super(PengambilanBahanSaveStateInit());
void pengambilanBahanSave({
required String courierID,
required String tipeID,
required String branchID,
required String branchCode,
required String name,
required String destination,
}) async {
try {
state = PengambilanBahanSaveStateLoading();
final resp = await PengambilanBahanRepository(dio: ref.read(dioProvider))
.pengambilanBahanSave(
courierID: courierID,
tipeID: tipeID,
branchID: branchID,
branchCode: branchCode,
name: name,
destination: destination);
state = PengambilanBahanSaveStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = PengambilanBahanSaveStateError(message: e.message ?? "");
} else {
state = PengambilanBahanSaveStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class PengambilanBahanSaveState extends Equatable {
final DateTime date;
const PengambilanBahanSaveState(this.date);
@override
List<Object?> get props => [date];
}
class PengambilanBahanSaveStateInit extends PengambilanBahanSaveState {
PengambilanBahanSaveStateInit() : super(DateTime.now());
}
class PengambilanBahanSaveStateLoading extends PengambilanBahanSaveState {
PengambilanBahanSaveStateLoading() : super(DateTime.now());
}
class PengambilanBahanSaveStateError extends PengambilanBahanSaveState {
final String? message;
PengambilanBahanSaveStateError({
required this.message,
}) : super(DateTime.now());
}
class PengambilanBahanSaveStateDone extends PengambilanBahanSaveState {
final ResponseSavePengantaranHasilModel model;
PengambilanBahanSaveStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,64 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../models/response_search_pengantaran_hasil_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/pengantaran_hasil_dokter_repository.dart';
// 3. state provider
final pengantaranHasilDokterSearch = StateNotifierProvider<PengantaranhasilDokterNotifier, PengantaranhasilDokterState>(
(ref) => PengantaranhasilDokterNotifier(ref: ref));
// 2. notifier
class PengantaranhasilDokterNotifier extends StateNotifier<PengantaranhasilDokterState> {
final Ref ref;
PengantaranhasilDokterNotifier({required this.ref}) : super(PengantaranhasilDokterStateInit());
void loadListNoDokterPengantaranHasilDokter(
{
required String search
}) async {
try {
state = PengantaranhasilDokterStateLoading();
final resp = await PengantaranHasilDokterRepository(dio: ref.read(dioProvider))
.loadListNoDokterPengantaranHasilDokter(search: search);
state = PengantaranhasilDokterStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = PengantaranhasilDokterStateError(message: e.message ?? "");
} else {
state = PengantaranhasilDokterStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class PengantaranhasilDokterState extends Equatable {
final DateTime date;
const PengantaranhasilDokterState(this.date);
@override
List<Object?> get props => [date];
}
class PengantaranhasilDokterStateInit extends PengantaranhasilDokterState {
PengantaranhasilDokterStateInit() : super(DateTime.now());
}
class PengantaranhasilDokterStateLoading extends PengantaranhasilDokterState {
PengantaranhasilDokterStateLoading() : super(DateTime.now());
}
class PengantaranhasilDokterStateError extends PengantaranhasilDokterState {
final String? message;
PengantaranhasilDokterStateError({
required this.message,
}) : super(DateTime.now());
}
class PengantaranhasilDokterStateDone extends PengantaranhasilDokterState {
final List<ResponseSearchPengantaranHasilModel> model;
PengantaranhasilDokterStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,77 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../models/response_save_pengantaran_hasil_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/pengantaran_hasil_dokter_repository.dart';
// 3. state provider
final pengantaranHasilDokterSave = StateNotifierProvider<
PengantaranhasilDokterSaveNotifier, PengantaranhasilDokterSaveState>(
(ref) => PengantaranhasilDokterSaveNotifier(ref: ref));
// 2. notifier
class PengantaranhasilDokterSaveNotifier
extends StateNotifier<PengantaranhasilDokterSaveState> {
final Ref ref;
PengantaranhasilDokterSaveNotifier({required this.ref})
: super(PengantaranhasilDokterSaveStateInit());
void pengantaranHasilDokterSave({
required String courierID,
required String tipeID,
required String deliveryID,
}) async {
try {
state = PengantaranhasilDokterSaveStateLoading();
final resp =
await PengantaranHasilDokterRepository(dio: ref.read(dioProvider))
.pengantaranHasilDokterSave(
courierID: courierID,
tipeID: tipeID,
deliveryID: deliveryID
);
state = PengantaranhasilDokterSaveStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = PengantaranhasilDokterSaveStateError(message: e.message ?? "");
} else {
state = PengantaranhasilDokterSaveStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class PengantaranhasilDokterSaveState extends Equatable {
final DateTime date;
const PengantaranhasilDokterSaveState(this.date);
@override
List<Object?> get props => [date];
}
class PengantaranhasilDokterSaveStateInit
extends PengantaranhasilDokterSaveState {
PengantaranhasilDokterSaveStateInit() : super(DateTime.now());
}
class PengantaranhasilDokterSaveStateLoading
extends PengantaranhasilDokterSaveState {
PengantaranhasilDokterSaveStateLoading() : super(DateTime.now());
}
class PengantaranhasilDokterSaveStateError
extends PengantaranhasilDokterSaveState {
final String? message;
PengantaranhasilDokterSaveStateError({
required this.message,
}) : super(DateTime.now());
}
class PengantaranhasilDokterSaveStateDone
extends PengantaranhasilDokterSaveState {
final ResponseSavePengantaranHasilModel model;
PengantaranhasilDokterSaveStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,65 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../models/response_search_pengantaran_hasil_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/pengantaran_hasil_instansi_repository.dart';
import '../../repository/pengantaran_hasil_pasien_repository.dart';
// 3. state provider
final pengantaranHasilInstansi = StateNotifierProvider<PengantaranhasilInstansiNotifier, PengantaranhasilInstansiState>(
(ref) => PengantaranhasilInstansiNotifier(ref: ref));
// 2. notifier
class PengantaranhasilInstansiNotifier extends StateNotifier<PengantaranhasilInstansiState> {
final Ref ref;
PengantaranhasilInstansiNotifier({required this.ref}) : super(PengantaranhasilInstansiStateInit());
void loadListNoSuratJalanPengantaranHasilInstansi(
{
required String search
}) async {
try {
state = PengantaranhasilInstansiStateLoading();
final resp = await PengantaranHasilInstansiRepository(dio: ref.read(dioProvider))
.loadListNoSuratJalanPengantaranHasilInstansi(search: search);
state = PengantaranhasilInstansiStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = PengantaranhasilInstansiStateError(message: e.message ?? "");
} else {
state = PengantaranhasilInstansiStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class PengantaranhasilInstansiState extends Equatable {
final DateTime date;
const PengantaranhasilInstansiState(this.date);
@override
List<Object?> get props => [date];
}
class PengantaranhasilInstansiStateInit extends PengantaranhasilInstansiState {
PengantaranhasilInstansiStateInit() : super(DateTime.now());
}
class PengantaranhasilInstansiStateLoading extends PengantaranhasilInstansiState {
PengantaranhasilInstansiStateLoading() : super(DateTime.now());
}
class PengantaranhasilInstansiStateError extends PengantaranhasilInstansiState {
final String? message;
PengantaranhasilInstansiStateError({
required this.message,
}) : super(DateTime.now());
}
class PengantaranhasilInstansiStateDone extends PengantaranhasilInstansiState {
final List<ResponseSearchPengantaranHasilModel> model;
PengantaranhasilInstansiStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,78 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../models/response_save_pengantaran_hasil_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/pengantaran_hasil_dokter_repository.dart';
import '../../repository/pengantaran_hasil_instansi_repository.dart';
// 3. state provider
final pengantaranHasilCompanySave = StateNotifierProvider<
PengantaranhasilCompanySaveNotifier, PengantaranhasilCompanySaveState>(
(ref) => PengantaranhasilCompanySaveNotifier(ref: ref));
// 2. notifier
class PengantaranhasilCompanySaveNotifier
extends StateNotifier<PengantaranhasilCompanySaveState> {
final Ref ref;
PengantaranhasilCompanySaveNotifier({required this.ref})
: super(PengantaranhasilCompanySaveStateInit());
void pengantaranHasilCompanySave({
required String courierID,
required String tipeID,
required String deliveryID,
}) async {
try {
state = PengantaranhasilCompanySaveStateLoading();
final resp =
await PengantaranHasilInstansiRepository(dio: ref.read(dioProvider))
.pengantaranHasilInstansiSave(
courierID: courierID,
tipeID: tipeID,
deliveryID: deliveryID
);
state = PengantaranhasilCompanySaveStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = PengantaranhasilCompanySaveStateError(message: e.message ?? "");
} else {
state = PengantaranhasilCompanySaveStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class PengantaranhasilCompanySaveState extends Equatable {
final DateTime date;
const PengantaranhasilCompanySaveState(this.date);
@override
List<Object?> get props => [date];
}
class PengantaranhasilCompanySaveStateInit
extends PengantaranhasilCompanySaveState {
PengantaranhasilCompanySaveStateInit() : super(DateTime.now());
}
class PengantaranhasilCompanySaveStateLoading
extends PengantaranhasilCompanySaveState {
PengantaranhasilCompanySaveStateLoading() : super(DateTime.now());
}
class PengantaranhasilCompanySaveStateError
extends PengantaranhasilCompanySaveState {
final String? message;
PengantaranhasilCompanySaveStateError({
required this.message,
}) : super(DateTime.now());
}
class PengantaranhasilCompanySaveStateDone
extends PengantaranhasilCompanySaveState {
final ResponseSavePengantaranHasilModel model;
PengantaranhasilCompanySaveStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,64 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '/models/response_search_pengantaran_hasil_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/pengantaran_hasil_pasien_repository.dart';
// 3. state provider
final pengantaranHasilPasienSearchNoLab = StateNotifierProvider<PengantaranhasilPasienNotifier, PengantaranhasilPasienState>(
(ref) => PengantaranhasilPasienNotifier(ref: ref));
// 2. notifier
class PengantaranhasilPasienNotifier extends StateNotifier<PengantaranhasilPasienState> {
final Ref ref;
PengantaranhasilPasienNotifier({required this.ref}) : super(PengantaranhasilPasienStateInit());
void loadListNoLabPengantaranHasilPasien(
{
required String search
}) async {
try {
state = PengantaranhasilPasienStateLoading();
final resp = await PengantaranHasilPasienRepository(dio: ref.read(dioProvider))
.loadListNoLabPengantaranHasilPasien(search: search);
state = PengantaranhasilPasienStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = PengantaranhasilPasienStateError(message: e.message ?? "");
} else {
state = PengantaranhasilPasienStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class PengantaranhasilPasienState extends Equatable {
final DateTime date;
const PengantaranhasilPasienState(this.date);
@override
List<Object?> get props => [date];
}
class PengantaranhasilPasienStateInit extends PengantaranhasilPasienState {
PengantaranhasilPasienStateInit() : super(DateTime.now());
}
class PengantaranhasilPasienStateLoading extends PengantaranhasilPasienState {
PengantaranhasilPasienStateLoading() : super(DateTime.now());
}
class PengantaranhasilPasienStateError extends PengantaranhasilPasienState {
final String? message;
PengantaranhasilPasienStateError({
required this.message,
}) : super(DateTime.now());
}
class PengantaranhasilPasienStateDone extends PengantaranhasilPasienState {
final List<ResponseSearchPengantaranHasilModel> model;
PengantaranhasilPasienStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,77 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../models/response_save_pengantaran_hasil_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/pengantaran_hasil_pasien_repository.dart';
// 3. state provider
final pengantaranHasilPasienSave = StateNotifierProvider<
PengantaranhasilPasienSaveNotifier, PengantaranhasilPasienSaveState>(
(ref) => PengantaranhasilPasienSaveNotifier(ref: ref));
// 2. notifier
class PengantaranhasilPasienSaveNotifier
extends StateNotifier<PengantaranhasilPasienSaveState> {
final Ref ref;
PengantaranhasilPasienSaveNotifier({required this.ref})
: super(PengantaranhasilPasienSaveStateInit());
void pengantaranHasilPasienSave({
required String courierID,
required String tipeID,
required String deliveryID,
}) async {
try {
state = PengantaranhasilPasienSaveStateLoading();
final resp =
await PengantaranHasilPasienRepository(dio: ref.read(dioProvider))
.pengantaranHasilPasienSave(
courierID: courierID,
tipeID: tipeID,
deliveryID: deliveryID
);
state = PengantaranhasilPasienSaveStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = PengantaranhasilPasienSaveStateError(message: e.message ?? "");
} else {
state = PengantaranhasilPasienSaveStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class PengantaranhasilPasienSaveState extends Equatable {
final DateTime date;
const PengantaranhasilPasienSaveState(this.date);
@override
List<Object?> get props => [date];
}
class PengantaranhasilPasienSaveStateInit
extends PengantaranhasilPasienSaveState {
PengantaranhasilPasienSaveStateInit() : super(DateTime.now());
}
class PengantaranhasilPasienSaveStateLoading
extends PengantaranhasilPasienSaveState {
PengantaranhasilPasienSaveStateLoading() : super(DateTime.now());
}
class PengantaranhasilPasienSaveStateError
extends PengantaranhasilPasienSaveState {
final String? message;
PengantaranhasilPasienSaveStateError({
required this.message,
}) : super(DateTime.now());
}
class PengantaranhasilPasienSaveStateDone
extends PengantaranhasilPasienSaveState {
final ResponseSavePengantaranHasilModel model;
PengantaranhasilPasienSaveStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,68 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '/models/company_model.dart';
import '/models/work_list_model.dart';
import '../../repository/company_repository.dart';
import '../../repository/work_list_repository.dart';
import '../../models/pending_work_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/home_screen_repository.dart';
abstract class SearchCompanyState extends Equatable {
final DateTime date;
const SearchCompanyState(this.date);
@override
List<Object?> get props => [date];
}
class SearchCompanyStateInit extends SearchCompanyState {
SearchCompanyStateInit() : super(DateTime.now());
}
class SearchCompanyStateLoading extends SearchCompanyState {
SearchCompanyStateLoading() : super(DateTime.now());
}
class SearchCompanyStateError extends SearchCompanyState {
final String message;
SearchCompanyStateError({
required this.message,
}) : super(DateTime.now());
}
class SearchCompanyStateDone extends SearchCompanyState {
final List<CompanyModel> model;
SearchCompanyStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class SearchCompanyNotifier extends StateNotifier<SearchCompanyState> {
final Ref ref;
SearchCompanyNotifier({
required this.ref,
}) : super(SearchCompanyStateInit());
void getData({required String keyword}) async {
try {
state = SearchCompanyStateLoading();
final dio = ref.read(dioProvider);
final resp = await CompanyRepository(dio: dio).search(keyword: keyword);
state = SearchCompanyStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = SearchCompanyStateError(message: e.message.toString());
} else {
state = SearchCompanyStateError(message: e.toString());
}
}
}
}
//provider
final SearchCompanyProvider =
StateNotifierProvider<SearchCompanyNotifier, SearchCompanyState>(
(ref) => SearchCompanyNotifier(ref: ref));

View File

@@ -0,0 +1,91 @@
import 'package:flutter/material.dart';
import '/app/route.dart';
import '../../app/constant.dart';
class KonfirmasiScreen extends StatelessWidget {
const KonfirmasiScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: Constant.backgroundWhite,
body: SizedBox(
width: Constant.getActualX(context: context, x: 390),
height: Constant.getActualY(context: context, y: 844),
child: Column(
children: [
// image
Padding(
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 196),
left: Constant.getActualX(context: context, x: 30),
right: Constant.getActualX(context: context, x: 30),
),
child: Container(
// width: Constant.getActualX(context: context, x: 251),
// height: Constant.getActualY(context: context, y: 78),
// color: Colors.green,
child: Image.asset(
"assets/logo_kurir_konfirmasiv2.png",
// fit: BoxFit.fill,
// scale: 1,
),
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 40),
),
SizedBox(
width: Constant.getActualX(context: context, x: 268),
height: Constant.getActualY(context: context, y: 40),
child: Text(
'Input pekerjaan baru berhasil. Harap menunggu konfirmasi.',
style: Constant.body3(
context: context,
).copyWith(fontWeight: FontWeight.w600),
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 68),
),
// button konfirmasi
SizedBox(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 46),
child: ElevatedButton(
onPressed: () {
Navigator.of(context)
.pushNamedAndRemoveUntil(menuRoute, (route) => false);
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.primaryDark),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
// side: BorderSide(color: Colors.red),
),
),
shadowColor: MaterialStateProperty.all(Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Kembali ke Beranda',
style: Constant.buttonLarge(context: context).copyWith(
color: Constant.backgroundWhite,
fontWeight: FontWeight.w700,
),
),
),
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,70 @@
import 'dart:convert';
import 'package:equatable/equatable.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../repository/base_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/kurir_tolak_repository.dart';
//provider
final kurirTolakProvider =
StateNotifierProvider<KurirTolakNotifier, KurirTolakState>(
(ref) => KurirTolakNotifier(ref: ref));
// notifier
class KurirTolakNotifier extends StateNotifier<KurirTolakState> {
final Ref ref;
KurirTolakNotifier({
required this.ref,
}) : super(KurirTolakStateInit());
void tolakKurir(
{required String id,
required String tipeId,
required String deliveryId,
required String note}) async {
try {
state = KurirTolakStateLoading();
final dio = ref.read(dioProvider);
final resp = await KurirTolakRepository(dio: dio).getKurirTolak(
id: id, tipeId: tipeId, deliveryId: deliveryId, note: note);
state = KurirTolakStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = KurirTolakStateError(message: e.message.toString());
} else {
state = KurirTolakStateError(message: e.toString());
}
}
}
}
abstract class KurirTolakState extends Equatable {
final DateTime date;
const KurirTolakState(this.date);
@override
List<Object?> get props => [date];
}
class KurirTolakStateInit extends KurirTolakState {
KurirTolakStateInit() : super(DateTime.now());
}
class KurirTolakStateLoading extends KurirTolakState {
KurirTolakStateLoading() : super(DateTime.now());
}
class KurirTolakStateError extends KurirTolakState {
final String message;
KurirTolakStateError({
required this.message,
}) : super(DateTime.now());
}
class KurirTolakStateDone extends KurirTolakState {
final bool model;
KurirTolakStateDone({
required this.model,
}) : super(DateTime.now());
}

View File

@@ -0,0 +1,94 @@
import 'dart:convert';
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../app/constant.dart';
import '../../models/auth_model.dart';
import '../../provider/current_user_provider.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,
bool isRememberMe = false}) async {
try {
state = LoginStateLoading();
final resp = await AuthRepository(dio: ref.read(dioProvider))
.login(username: username, password: password);
state = LoginStateDone(model: resp);
//Simpan ke token jk remember me
if (isRememberMe == true) {
final shared = await SharedPreferences.getInstance();
final token = {"date": DateTime.now().toString(), "model": resp.model};
final tokenEncode = jsonEncode(token);
await shared.setString(Constant.tokenName, tokenEncode);
await shared.setString("usernameX", username);
await shared.setString("passwordX", password);
await shared.setBool("isRememberMeX", isRememberMe);
}
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");
}
ref.read(currentUserProvider.notifier).state = AuthModel(
token: resp.token,
model: resp.model,
);
// 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,325 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../app/constant.dart';
import '../../app/route.dart';
import '../../models/auth_model.dart';
import '../../provider/current_user_provider.dart';
import '../../widget/sas_textfield.dart';
import 'login_provider.dart';
class LoginScreen extends HookConsumerWidget {
const LoginScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final isPasswordObscured = useState<bool>(true);
final ctrlUsername = useTextEditingController(text: "");
final ctrlPassword = useTextEditingController(text: "");
final focusNodeUsername = useFocusNode();
final focusNodePassword = useFocusNode();
final usernamehasFocus = useState(false);
final passwordhasFocus = useState(false);
final isRememberMe = useState(false);
final errorMessage = useState("");
final isLoading = useState(false);
final isSuccess = useState(false);
final isValidEntry = useState(false);
final usernameFromSharePref = useState("");
final passwordFromSharePref = useState("");
focusNodeUsername.addListener(() {
if (focusNodeUsername.hasFocus) {
usernamehasFocus.value = true;
passwordhasFocus.value = false;
} else {
usernamehasFocus.value = false;
}
});
focusNodePassword.addListener(() {
if (focusNodePassword.hasFocus) {
usernamehasFocus.value = false;
passwordhasFocus.value = true;
} else {
passwordhasFocus.value = false;
}
});
// aksi login
ref.listen(loginProvider, (prev, next) async {
if (next is LoginStateLoading) {
isLoading.value = true;
} else if (next is LoginStateError) {
isLoading.value = false;
errorMessage.value = next.message ?? "";
// print(errorMessage.value);
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is LoginStateDone) {
isLoading.value = false;
isSuccess.value = true;
Navigator.of(context)
.pushNamedAndRemoveUntil(menuRoute, (route) => false);
}
});
ctrlUsername.addListener(
() {
if (ctrlUsername.text.isEmpty || ctrlPassword.text.isEmpty) {
isValidEntry.value = false;
} else {
isValidEntry.value = true;
}
},
);
ctrlPassword.addListener(
() {
if (ctrlUsername.text.isEmpty || ctrlPassword.text.isEmpty) {
isValidEntry.value = false;
} else {
isValidEntry.value = true;
}
},
);
return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: Constant.backgroundWhite,
body: SizedBox(
width: Constant.getActualX(context: context, x: 390),
height: Constant.getActualY(context: context, y: 844),
child: ListView(
children: [
// bg login
Padding(
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 80),
left: Constant.getActualX(context: context, x: 16),
right: Constant.getActualX(context: context, x: 16),
),
child: Image.asset(
"assets/bg_login.png",
// fit: BoxFit.fill,
// scale: 1,
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 10),
),
// Error From Backend Start
if (errorMessage.value != "")
Padding(
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 27),
left: Constant.getActualX(context: context, x: 38),
right: Constant.getActualX(context: context, x: 32),
),
child: Align(
alignment: Alignment.center,
child: Text(
"Peringatan : ${errorMessage.value}",
style: Constant.body1(context: context)
.copyWith(color: Constant.primaryRed),
),
),
),
// Error From Backend End
// loading
if (isLoading.value)
Padding(
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 10),
left: Constant.getActualX(context: context, x: 38),
right: Constant.getActualX(context: context, x: 32),
),
child: Center(
child: SizedBox(
width: Constant.getActualX(context: context, x: 40),
height: Constant.getActualY(context: context, y: 40),
child: CircularProgressIndicator(
color: Constant.primaryBlue,
),
),
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 10),
),
Padding(
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 27),
left: Constant.getActualX(context: context, x: 38),
right: Constant.getActualX(context: context, x: 32),
),
child: SizedBox(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 412),
// color: Colors.amber,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Login",
style: Constant.heading2(context: context).copyWith(
color: Constant.textPrimary,
fontWeight: FontWeight.w600),
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
SasTextField(
hintText: "Username",
labelText: "Username",
controller: ctrlUsername,
focusNode: focusNodeUsername,
hasFocus: usernamehasFocus.value,
style: Constant.body1(context: context)
.copyWith(color: Constant.textBlack),
),
SizedBox(
height: Constant.getActualY(context: context, y: 16),
),
SasTextFieldPassword(
hintText: "Password",
labelText: "Password",
controller: ctrlPassword,
focusNode: focusNodePassword,
hasFocus: passwordhasFocus.value,
onToggle: () {
isPasswordObscured.value = !isPasswordObscured.value;
},
obscureText:
(isPasswordObscured.value == true) ? true : false,
),
SizedBox(
height: Constant.getActualY(context: context, y: 16),
),
SizedBox(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 20),
// color: Colors.green,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Checkbox(
value: isRememberMe.value,
onChanged: (value) {
if (value != null) {
isRememberMe.value = value;
// checkIsLogin(isRememberMe.value);
}
},
),
const SizedBox(width: 8.0),
Text(
"Ingat saya",
style:
Constant.caption1(context: context).copyWith(
color: Constant.textPrimary,
fontWeight: FontWeight.w400,
),
),
],
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 32),
),
// button login
SizedBox(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 48),
child: ElevatedButton(
onPressed: (isLoading.value == true)
? null
: () {
if (ctrlUsername.text.isEmpty ||
ctrlPassword.text.isEmpty) {
isLoading.value = false;
errorMessage.value = 'Inputan harus diisi';
Timer(const Duration(seconds: 3), () {
isLoading.value = false;
errorMessage.value = "";
});
} else {
ref.read(loginProvider.notifier).login(
username: ctrlUsername.text,
password: ctrlPassword.text,
isRememberMe: isRememberMe.value,
);
}
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.primaryMain),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
// side: BorderSide(color: Colors.red),
),
),
shadowColor: MaterialStateProperty.all(
const Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Login',
style: Constant.buttonLarge(context: context)
.copyWith(
color: Constant.backgroundWhite,
fontWeight: FontWeight.w700,
),
),
),
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 16),
),
// Center(
// child: InkWell(
// onTap: () {
// Navigator.of(context).pushNamedAndRemoveUntil(
// problemLoginRoute,
// (route) => true,
// );
// },
// child: Text(
// "Problem login",
// style: Constant.caption1(context: context).copyWith(
// color: Constant.errorDark,
// fontWeight: FontWeight.w400),
// ),
// ),
// ),
],
),
),
),
],
),
),
),
);
}
}

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,95 @@
import 'package:fancy_bottom_navigation_2/fancy_bottom_navigation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter/src/widgets/placeholder.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/screen/history_screen/history_screen.dart';
import '/screen/profile_screen/profile_screen.dart';
import '/screen/work_list_screen/work_list_screen.dart';
import 'package:loader_overlay/loader_overlay.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../provider/current_user_provider.dart';
import '../home_screen/home_screen.dart';
import '../home_screen/pending_work_provider.dart';
import '../home_screen/total_work_provider.dart';
import '../work_list_screen/work_status_provider.dart';
import '../work_list_screen/work_supervisor_moder.dart';
import '../work_list_screen/work_type_provider.dart';
class MenuScreen extends HookConsumerWidget {
const MenuScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final current_page = useState(0);
final mUsername =
ref.watch(currentUserProvider)?.model.user?.mStaffName ?? "0";
final mCourirID =
ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0";
changeMenu() {
switch (current_page.value) {
case 0:
return HomeScreen();
break;
case 1:
return WorkListScreen();
break;
case 2:
return HistoryScreen();
break;
case 3:
return ProfilScreen();
break;
default:
return HomeScreen();
}
}
return LoaderOverlay(
useDefaultLoading: false,
overlayColor: Colors.black,
overlayWidget: Center(
child: LoadingAnimationWidget.inkDrop(
color: Constant.primaryBlue, size: 50),
),
child: Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor:
current_page.value == 1 ? const Color(0XFFF4F6F8) : Colors.white,
bottomNavigationBar: Container(
height: Constant.getActualY(context: context, y: 67),
child: SizedBox(
height: Constant.getActualY(context: context, y: 67),
child: FancyBottomNavigation(
tabs: [
TabData(iconData: Icons.home_outlined, title: "Beranda"),
TabData(
iconData: Icons.work_history_outlined,
title: "List Pekerjaan"),
TabData(iconData: Icons.map_outlined, title: "Riwayat"),
TabData(iconData: Icons.person_outlined, title: "Profil")
],
onTabChangedListener: (position) {
current_page.value = position;
// if (position == 0) {
// ref.read(TotalWorkProvider.notifier).getData(id: mCourirID);
// ref.read(PendingWorkProvider.notifier).getData(id: mCourirID);
// ref.read(WorkTypeProvider.notifier).getData();
// ref.read(WorkStatusProvider.notifier).getData();
// ref.read(WorkSupervisorProvider.notifier).getData();
// }
},
),
),
),
body: changeMenu(),
),
);
}
}

View File

@@ -0,0 +1,67 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '/models/personal_information_model.dart';
import '../../repository/personal_information_repository.dart';
import '../../repository/work_list_repository.dart';
import '../../models/pending_work_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/home_screen_repository.dart';
abstract class PersonalInformationState extends Equatable {
final DateTime date;
const PersonalInformationState(this.date);
@override
List<Object?> get props => [date];
}
class PersonalInformationStateInit extends PersonalInformationState {
PersonalInformationStateInit() : super(DateTime.now());
}
class PersonalInformationStateLoading extends PersonalInformationState {
PersonalInformationStateLoading() : super(DateTime.now());
}
class PersonalInformationStateError extends PersonalInformationState {
final String message;
PersonalInformationStateError({
required this.message,
}) : super(DateTime.now());
}
class PersonalInformationStateDone extends PersonalInformationState {
final List<PersonalInformationModel> model;
PersonalInformationStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class PersonalInformationNotifier extends StateNotifier<PersonalInformationState> {
final Ref ref;
PersonalInformationNotifier({
required this.ref,
}) : super(PersonalInformationStateInit());
void getData(
{required String mCourierID}) async {
try {
state = PersonalInformationStateLoading();
final dio = ref.read(dioProvider);
final resp = await PersonalInformationRepository(dio: dio).getPersonalInformation(mCourierID: mCourierID);
state = PersonalInformationStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = PersonalInformationStateError(message: e.message.toString());
} else {
state = PersonalInformationStateError(message: e.toString());
}
}
}
}
//provider
final PersonalInformationProvider = StateNotifierProvider<PersonalInformationNotifier, PersonalInformationState>(
(ref) => PersonalInformationNotifier(ref: ref));

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