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

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));