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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,185 @@
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter/src/widgets/placeholder.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/app/route.dart';
import '../../app/constant.dart';
import '../../provider/current_user_provider.dart';
import '../../widget/snackbar_widget.dart';
import 'personal_information_provider.dart';
class PersonalInformationScreen extends HookConsumerWidget {
const PersonalInformationScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final name = ref.watch(currentUserProvider)?.model.user?.mStaffName ?? "0";
final namaController = useTextEditingController(text: name);
final emailController = useTextEditingController(text: "-");
final nikController = useTextEditingController(text: "-");
final isLoading = useState<bool>(false);
final mCourirID =
ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0";
fetchData() {
ref
.read(PersonalInformationProvider.notifier)
.getData(mCourierID: mCourirID);
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
fetchData();
});
return () {};
}, []);
ref.listen(PersonalInformationProvider, (previous, next) {
if (next is PersonalInformationStateLoading) {
isLoading.value = true;
} else if (next is PersonalInformationStateError) {
isLoading.value = false;
// print(next.message);
SanckbarWidget(
context, next.message.substring(0, 30), snackbarType.error);
} else if (next is PersonalInformationStateDone) {
isLoading.value = false;
if (next.model.isNotEmpty) {
nikController.text = next.model[0].natStaffNIK.toString();
} else {
nikController.text = "-";
}
}
});
return Scaffold(
body: ListView(
children: [
Container(
// color: Colors.white,
height: Constant.getActualY(context: context, y: 56),
),
Container(
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 10)),
// color: Colors.white,
height: Constant.getActualY(context: context, y: 48),
child: Row(
children: [
IconButton(
onPressed: () {
Navigator.of(context).pop();
},
icon: Icon(Icons.arrow_back_ios_rounded),
),
Text(
"Informasi Pribadi",
style: Constant.body1(context: context).copyWith(
fontWeight: FontWeight.w600, color: Constant.textPrimary),
),
],
),
),
Container(
// color: Colors.white,
height: Constant.getActualY(context: context, y: 31),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 34)),
child: TextFormField(
style: TextStyle(color: Colors.grey),
enabled: false,
controller: namaController,
decoration: InputDecoration(
labelText: "Nama",
hintText: "Nama",
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
),
),
),
Container(
height: Constant.getActualY(context: context, y: 24),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 34)),
// child: TextFormField(
// style: TextStyle(color: Colors.grey),
// enabled: false,
// controller: emailController,
// decoration: InputDecoration(
// labelText: "Email",
// hintText: "Email",
// border:
// OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
// ),
// ),
child: TextFormField(
style: TextStyle(color: Colors.grey),
enabled: false,
controller: nikController,
decoration: InputDecoration(
labelText: "NIK",
hintText: "NIK",
border:
OutlineInputBorder(borderRadius: BorderRadius.circular(8)),
),
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
// loading
if (isLoading.value)
const Center(
child: CircularProgressIndicator(),
),
Container(
height: Constant.getActualY(context: context, y: 32),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 34)),
child: OutlinedButton(
onPressed: () {
Navigator.pushNamed(context, changePasswordRoute);
},
style: OutlinedButton.styleFrom(
shape: RoundedRectangleBorder(
side: BorderSide(
style: BorderStyle.solid, color: Constant.primaryBlue),
borderRadius: BorderRadius.circular(8),
),
),
child: SizedBox(
height: Constant.getActualY(context: context, y: 46),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Ubah Password",
style: Constant.body3(context: context)
.copyWith(color: Constant.textPrimary),
),
SizedBox(
width: Constant.getActualX(context: context, x: 8),
),
Icon(
Icons.arrow_forward_ios_rounded,
color: Constant.textPrimary,
)
],
),
),
),
),
],
));
}
}

View File

@@ -0,0 +1,173 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '../../app/constant.dart';
import '../../widget/sas_textfield.dart';
class ProblemLoginScreen extends HookConsumerWidget {
const ProblemLoginScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final ctrlEmail = useTextEditingController(text: "");
final ctrlNote = useTextEditingController(text: "");
final focusNodeEmail = useFocusNode();
final focusNodeNote = useFocusNode();
final emailhasFocus = useState(false);
final notehasFocus = useState(false);
focusNodeEmail.addListener(() {
if (focusNodeEmail.hasFocus) {
emailhasFocus.value = true;
notehasFocus.value = false;
} else {
emailhasFocus.value = false;
}
});
focusNodeNote.addListener(() {
if (focusNodeNote.hasFocus) {
emailhasFocus.value = false;
notehasFocus.value = true;
} else {
notehasFocus.value = false;
}
});
return GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Scaffold(
resizeToAvoidBottomInset: true,
backgroundColor: Constant.backgroundWhite,
body: SizedBox(
width: Constant.getActualX(context: context, x: 390),
height: Constant.getActualY(context: context, y: 844),
child: ListView(
children: [
// bg login
Padding(
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 70),
left: Constant.getActualX(context: context, x: 16),
right: Constant.getActualX(context: context, x: 16),
),
child: Image.asset(
"assets/bg_problem_login.png",
// fit: BoxFit.fill,
// scale: 1,
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 27),
),
Padding(
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 27),
left: Constant.getActualX(context: context, x: 38),
right: Constant.getActualX(context: context, x: 32),
),
child: SizedBox(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 360),
// color: Colors.amber,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Problem Login",
style: Constant.heading2(context: context).copyWith(
color: Constant.textPrimary,
fontWeight: FontWeight.w600),
),
SizedBox(
height: Constant.getActualY(context: context, y: 32),
),
// CustomTextFieldLogin(
// onChange: (String x) {
// // print(x);
// },
// isPassword: false,
// hintText: "Email",
// labelText: "Email",
// isError: false,
// ctrl: ctrlEmail,
// focusNode: focusNodeEmail,
// hasFocus: emailhasFocus.value,
// ),
SasTextField(
hintText: "Email",
labelText: "Email",
controller: ctrlEmail,
focusNode: focusNodeEmail,
hasFocus: emailhasFocus.value,
),
SizedBox(
height: Constant.getActualY(context: context, y: 16),
),
// CustomTextFieldLogin(
// onChange: (String x) {
// // print(x);
// },
// isPassword: false,
// hintText: "Error",
// labelText: "Note",
// isError: false,
// ctrl: ctrlNote,
// focusNode: focusNodeNote,
// hasFocus: notehasFocus.value,
// ),
SasTextField(
hintText: "Error",
labelText: "Error",
controller: ctrlNote,
focusNode: focusNodeNote,
hasFocus: notehasFocus.value,
),
SizedBox(
height: Constant.getActualY(context: context, y: 20),
),
// button login
SizedBox(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 48),
child: ElevatedButton(
onPressed: () {},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.primaryMain),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
// side: BorderSide(color: Colors.red),
),
),
shadowColor:
MaterialStateProperty.all(const Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Send',
style: Constant.buttonLarge(context: context)
.copyWith(
color: Constant.backgroundWhite,
fontWeight: FontWeight.w700,
),
),
),
),
),
],
),
),
),
],
),
),
),
);
}
}

View File

@@ -0,0 +1,244 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter/src/widgets/placeholder.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/app/route.dart';
import 'package:loader_overlay/loader_overlay.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../app/constant.dart';
import '../../models/pending_work_model.dart';
import '../../models/work_total_model.dart';
import '../../provider/current_user_provider.dart';
import '../../widget/header_widget.dart';
import '../../widget/information_card.dart';
import '../../widget/information_rpt_card.dart';
import '../../widget/snackbar_widget.dart';
import '../home_screen/total_work_provider.dart';
import '../login/logout_provider.dart';
class ProfilScreen extends HookConsumerWidget {
const ProfilScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final totalWork = useState<WorkTotalModel>(WorkTotalModel());
final totalWorkLoading = useState(false);
final mStaffName =
ref.watch(currentUserProvider)?.model.user?.mStaffName ?? "0";
final mCourirID =
ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0";
final mUsername =
ref.watch(currentUserProvider)?.model.user?.mUserUsername ?? "0";
final mUserID = ref.watch(currentUserProvider)?.model.user?.mUserID ?? "0";
final logoutLoading = useState(false);
final errorMessage = useState("");
// aksi logout
ref.listen(logoutProvider, (prev, next) async {
if (next is LogoutStateLoading) {
logoutLoading.value = true;
context.loaderOverlay.show();
} else if (next is LogoutStateError) {
logoutLoading.value = false;
errorMessage.value = next.message;
SanckbarWidget(context, next.message, snackbarType.error);
context.loaderOverlay.hide();
} else if (next is LogoutStateDone) {
logoutLoading.value = false;
final shared = await SharedPreferences.getInstance();
final token = shared.get(Constant.tokenName).toString();
// print(token);
if (token.isNotEmpty) {
shared.remove(token);
shared.remove("passwordX");
shared.remove("usernameX");
shared.clear();
// Navigator.popAndPushNamed(context, loginRoute);
SanckbarWidget(context, "Berhasil Sign Out", snackbarType.success);
context.loaderOverlay.hide();
Navigator.of(context)
.pushNamedAndRemoveUntil(loginRoute, (route) => false);
}
}
});
fetchData() {
// ref.read(TotalWorkProvider.notifier).getData(id: mCourirID);
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
fetchData();
});
return () {};
}, []);
ref.listen(
TotalWorkProvider,
(previous, next) {
if (next is TotalWorkStateLoading) {
totalWorkLoading.value = true;
} else if (next is TotalWorkStateError) {
print(next.message);
totalWorkLoading.value = false;
SanckbarWidget(context, next.message, snackbarType.error);
} else if (next is TotalWorkStateDone) {
// print(jsonEncode(next.model));
totalWork.value = next.model;
totalWorkLoading.value = false;
}
},
);
return RefreshIndicator(
onRefresh: () async {
fetchData();
},
child: ListView(
children: [
SizedBox(
height: Constant.getActualY(context: context, y: 56),
),
const HeaderWidget(teks: "Profil"),
SizedBox(
height: Constant.getActualY(context: context, y: 31),
),
Container(
width: Constant.getActualY(context: context, y: 121),
height: Constant.getActualY(context: context, y: 121),
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Color(0XFF3366FF), width: 2)),
child: Stack(
alignment: Alignment.center,
children: [
Container(
width: Constant.getActualY(context: context, y: 100),
height: Constant.getActualY(context: context, y: 100),
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Color(0XFF3366FF), width: 2),
),
child: Container(
width: Constant.getActualY(context: context, y: 100),
height: Constant.getActualY(context: context, y: 100),
child: CircleAvatar(
backgroundColor: Colors.transparent,
// backgroundImage: NetworkImage(
// "https://images.pexels.com/photos/220453/pexels-photo-220453.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500"),
// ),
child: Icon(
Icons.person,
color: Colors.grey,
size: Constant.getActualY(context: context, y: 80),
),
),
),
// camera commented
// Positioned(
// bottom: 1,
// right: Constant.getActualX(context: context, x: 140),
// child: InkWell(
// onTap: () {
// print("a");
// // context.loaderOverlay.show();
// },
// child: Container(
// width: Constant.getActualY(context: context, y: 34),
// height: Constant.getActualY(context: context, y: 34),
// decoration: BoxDecoration(
// color: Color(0XFF3366FF),
// shape: BoxShape.circle,
// border: Border.all(
// color: Constant.primaryBlue, width: 2)),
// child: Icon(
// Icons.camera_alt_outlined,
// color: Colors.white,
// )),
// ),
),
],
),
),
SizedBox(
height: Constant.getActualY(context: context, y: 28),
),
Align(
alignment: Alignment.center,
child: Text(
mStaffName,
style: Constant.body1(context: context)
.copyWith(fontWeight: FontWeight.w600),
)),
SizedBox(
height: Constant.getActualY(context: context, y: 40),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 34)),
child: InformationRptCard(mCourirID),
// InformationCard(
// elevation: true,
// data: totalWork.value,
// loading: totalWorkLoading.value,
// )
),
SizedBox(
height: Constant.getActualY(context: context, y: 40),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 34)),
child: ListTile(
onTap: () {
Navigator.pushNamed(context, personalInformationRoute);
},
leading: Image.asset(
"assets/icon_profile_profile.png",
width: Constant.getActualX(context: context, x: 25),
height: Constant.getActualY(context: context, y: 25),
),
trailing: Icon(Icons.arrow_forward_ios_rounded,
color: Constant.textPrimary),
title: Text(
"Informasi Pribadi",
style: Constant.body1(context: context)
.copyWith(fontWeight: FontWeight.w600),
),
),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 34)),
child: ListTile(
onTap: () {
ref.read(logoutProvider.notifier).logout(
M_UserID: mUserID,
M_UserUsername: mUsername,
);
},
leading: Image.asset(
"assets/icon_signout_profile.png",
width: Constant.getActualX(context: context, x: 25),
height: Constant.getActualY(context: context, y: 25),
),
trailing: null,
title: Text(
"Sign Out",
style: Constant.body1(context: context)
.copyWith(fontWeight: FontWeight.w600),
),
),
),
],
),
);
}
}

View File

@@ -0,0 +1,101 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/app/route.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../app/constant.dart';
import '../../models/auth_model.dart';
import '../../provider/current_user_provider.dart';
class SplashScreen extends HookConsumerWidget {
const SplashScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
// setelah 3 detik redirect ke login route
// Timer(const Duration(seconds: 3), () {
// Navigator.of(context).pushNamedAndRemoveUntil(
// loginRoute,
// (route) => false,
// );
// });
useEffect(() {
() async {
final shared = await SharedPreferences.getInstance();
bool remeberMe = shared.getBool("isRememberMeX") ?? false;
if (remeberMe) {
final jsonAuth = shared.get(Constant.tokenName).toString();
final auth = jsonDecode(jsonAuth);
if (auth == null) return;
final authmodel = AuthModel(
token: auth['model']['token'],
model: AuthKurirModel.fromJson(auth['model']),
);
final token = authmodel.token;
final authKurirModel = authmodel.model;
final authModel = AuthModel(
token: token,
model: authKurirModel,
);
ref.read(currentUserProvider.notifier).state = authModel;
Navigator.of(context)
.pushNamedAndRemoveUntil(menuRoute, (route) => false);
return;
} else {
Navigator.of(context)
.pushNamedAndRemoveUntil(loginRoute, (route) => false);
return;
}
}();
}, []);
return Scaffold(
backgroundColor: Constant.backgroundWhite,
body: SafeArea(
child: Column(
children: [
Padding(
padding: EdgeInsets.only(
top: Constant.getActualY(context: context, y: 103),
left: Constant.getActualX(context: context, x: 69),
right: Constant.getActualX(context: context, x: 70),
bottom: Constant.getActualY(context: context, y: 92)),
child: SizedBox(
width: Constant.getActualX(context: context, x: 251),
height: Constant.getActualY(context: context, y: 78),
child: Image.asset(
"assets/logo_kdr.png",
fit: BoxFit.fitHeight,
// scale: 1,
),
),
),
Padding(
padding: EdgeInsets.only(
left: Constant.getActualX(context: context, x: 30),
right: Constant.getActualX(context: context, x: 29),
),
child: SizedBox(
width: Constant.getActualX(context: context, x: 331),
height: Constant.getActualY(context: context, y: 366),
child: Image.asset(
"assets/bg_splashscreen.png",
fit: BoxFit.fitHeight,
// scale: 1,
),
// color: Colors.green,
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,129 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../app/constant.dart';
import '../../app/route.dart';
import '../../models/auth_model.dart';
import '../../provider/current_user_provider.dart';
import '../login/logout_provider.dart';
class TestHomeScreen extends HookConsumerWidget {
const TestHomeScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
// useEffect(() {
// WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
// Timer(const Duration(milliseconds: 500), () async {
// final shared = await SharedPreferences.getInstance();
// final jsonAuth = shared.get(Constant.tokenName).toString();
// final auth = jsonDecode(jsonAuth);
// if (auth == null) return;
// final mUserID =
// ref.watch(currentUserProvider)?.model.user?.mUserID ?? "0";
// if (mUserID == "0") {
// Navigator.of(context)
// .pushNamedAndRemoveUntil(loginRoute, (route) => false);
// return;
// }
// });
// });
// return () {};
// }, []);
final mUsername =
ref.watch(currentUserProvider)?.model.user?.mUserUsername ?? "0";
final mUserID = ref.watch(currentUserProvider)?.model.user?.mUserID ?? "0";
final isLoading = useState(false);
final errorMessage = useState("");
// aksi logout
ref.listen(logoutProvider, (prev, next) async {
if (next is LogoutStateLoading) {
isLoading.value = true;
} else if (next is LogoutStateError) {
isLoading.value = false;
errorMessage.value = next.message;
Timer(const Duration(seconds: 3), () {
errorMessage.value = "";
});
} else if (next is LogoutStateDone) {
isLoading.value = false;
final shared = await SharedPreferences.getInstance();
final token = shared.get(Constant.tokenName).toString();
// print(token);
if (token.isNotEmpty) {
shared.remove(token);
shared.remove("passwordX");
shared.remove("usernameX");
shared.clear();
// Navigator.popAndPushNamed(context, loginRoute);
Navigator.of(context)
.pushNamedAndRemoveUntil(loginRoute, (route) => false);
}
}
});
return Scaffold(
appBar: AppBar(
title: const Text('Test Home Screen'),
),
body: SafeArea(
child: ListView(
children: [
Text('Username $mUsername'),
Text('user id $mUserID'),
const SizedBox(
height: 20,
),
SizedBox(
width: Constant.getActualX(context: context, x: 320),
height: Constant.getActualY(context: context, y: 48),
child: ElevatedButton(
onPressed: () {
ref.read(logoutProvider.notifier).logout(
M_UserID: mUserID,
M_UserUsername: mUsername,
);
},
style: ButtonStyle(
backgroundColor: MaterialStateColor.resolveWith(
(st) => Constant.primaryMain),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
// side: BorderSide(color: Colors.red),
),
),
shadowColor:
MaterialStateProperty.all(const Color(0xffff48423d)),
elevation: MaterialStateProperty.all(4.0),
),
child: Align(
alignment: Alignment.center,
child: Text(
'Logout',
style: Constant.buttonLarge(context: context).copyWith(
color: Constant.backgroundWhite,
fontWeight: FontWeight.w700,
),
),
),
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,70 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '/models/work_list_model.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 WorkListState extends Equatable {
final DateTime date;
const WorkListState(this.date);
@override
List<Object?> get props => [date];
}
class WorkListStateInit extends WorkListState {
WorkListStateInit() : super(DateTime.now());
}
class WorkListStateLoading extends WorkListState {
WorkListStateLoading() : super(DateTime.now());
}
class WorkListStateError extends WorkListState {
final String message;
WorkListStateError({
required this.message,
}) : super(DateTime.now());
}
class WorkListStateDone extends WorkListState {
final List<WorkListModel> model;
WorkListStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class WorkListNotifier extends StateNotifier<WorkListState> {
final Ref ref;
WorkListNotifier({
required this.ref,
}) : super(WorkListStateInit());
void getData(
{required String id,
required String tipeId,
required String supervisor,
required String status}) async {
try {
state = WorkListStateLoading();
final dio = ref.read(dioProvider);
final resp = await WorkListRepository(dio: dio).getListWork(
id: id, status: status, supervisor: supervisor, tipeId: tipeId);
state = WorkListStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = WorkListStateError(message: e.message.toString());
} else {
state = WorkListStateError(message: e.toString());
}
}
}
}
//provider
final WorkListProvider = StateNotifierProvider<WorkListNotifier, WorkListState>(
(ref) => WorkListNotifier(ref: ref));

View File

@@ -0,0 +1,547 @@
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import '/models/pending_work_model.dart';
import '/models/work_list_model.dart';
import '/models/work_type_model.dart';
import '/widget/snackbar_widget.dart';
import '/widget/work_card.dart';
import '/screen/work_list_screen/work_list_provider.dart';
import '/screen/work_list_screen/work_status_provider.dart';
import '/screen/work_list_screen/work_supervisor_moder.dart';
import '/screen/work_list_screen/work_type_provider.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import '../../app/constant.dart';
import '../../models/work_status_model.dart';
import '../../models/work_supervisor_model.dart';
import '../../provider/current_user_provider.dart';
import '../../widget/header_widget.dart';
// ignore: camel_case_types
enum arrStatus { baru, pending, done }
class WorkListScreen extends HookConsumerWidget {
const WorkListScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final selectedStatus = useState<String>("");
final selectedTipe = useState<List<int>>(List.empty());
final selectedSupervisor = useState<List<String>>(List.empty());
final workTypeData = useState<List<WorkTypeModel>>([]);
final workTypeLoading = useState(false);
final workStatusData = useState<List<WorkStatusModel>>([]);
final workStatusLoading = useState(false);
final workSupervisorData = useState<List<WorkSupervisorModel>>([]);
final workSupervisorLoading = useState(false);
final workListData = useState<List<WorkListModel>>([]);
final workListLoading = useState(false);
final change = useState(1);
final mCourirID =
ref.watch(currentUserProvider)?.model.user?.mCourierID ?? "0";
fetchData() {
ref.read(WorkTypeProvider.notifier).getData();
ref.read(WorkStatusProvider.notifier).getData();
ref.read(WorkSupervisorProvider.notifier).getData();
// ref
// .read(WorkListProvider.notifier)
// .getData(id: mCourirID, tipeId: "x", status: "N-p", supervisor: "N");
ref.read(WorkListProvider.notifier).getData(
id: mCourirID,
tipeId: "1-2-3-4-5",
status: "N'-'P'-'D",
supervisor: "N'-'Y'-'X");
}
useEffect(() {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
fetchData();
});
return () {};
}, []);
filterData() {
var status =
selectedStatus.value.isNotEmpty ? selectedStatus.value : "N'-'P'-'D";
var supervisor = selectedSupervisor.value.isNotEmpty
? selectedSupervisor.value.join("'-'")
: "N'-'Y'-'X";
var tipe = selectedTipe.value.isNotEmpty
? selectedTipe.value.join('-')
: "1-2-3-4-5";
// print("selected status value : ${status}");
// print("selected supervisor value :" + supervisor);
// print("selected tipe value :" + tipe);
ref.read(WorkListProvider.notifier).getData(
id: mCourirID, tipeId: tipe, status: status, supervisor: supervisor);
}
ref.listen(WorkTypeProvider, (previous, next) {
if (next is WorkTypeStateLoading) {
workTypeLoading.value = true;
} else if (next is WorkTypeStateError) {
workTypeLoading.value = false;
// print(next.message);
SanckbarWidget(context, next.message, snackbarType.error);
} else if (next is WorkTypeStateDone) {
workTypeLoading.value = false;
workTypeData.value = next.model;
}
});
ref.listen(WorkStatusProvider, (previous, next) {
if (next is WorkStatusStateLoading) {
workStatusLoading.value = true;
} else if (next is WorkStatusStateError) {
workStatusLoading.value = false;
// print(next.message);
SanckbarWidget(context, next.message, snackbarType.error);
} else if (next is WorkStatusStateDone) {
// print(jsonEncode(next.model));
workStatusLoading.value = false;
var newData = next.model;
var newStatus = [];
next.model.forEach((e) {
newStatus.add(e.statusid);
});
newData.insert(
0,
WorkStatusModel(
statusid: newStatus.join("'-'"), statusname: "Semua"));
selectedStatus.value = newStatus.join("'-'");
workStatusData.value = newData;
}
});
ref.listen(WorkSupervisorProvider, (previous, next) {
if (next is WorkSupervisorStateLoading) {
workSupervisorLoading.value = true;
} else if (next is WorkSupervisorStateError) {
workSupervisorLoading.value = false;
// print(next.message);
SanckbarWidget(context, next.message, snackbarType.error);
} else if (next is WorkSupervisorStateDone) {
// print(jsonEncode(next.model));
workSupervisorLoading.value = false;
workSupervisorData.value = next.model;
}
});
ref.listen(WorkListProvider, (previous, next) {
if (next is WorkListStateLoading) {
workListLoading.value = true;
} else if (next is WorkListStateError) {
workListLoading.value = false;
// print(next.message);
SanckbarWidget(context, next.message, snackbarType.error);
} else if (next is WorkListStateDone) {
// print(jsonEncode(next.model));
workListLoading.value = false;
workListData.value = next.model;
}
});
selectedStatus.addListener(() {
// print("change");
change.value = change.value++;
});
return RefreshIndicator(
onRefresh: () async {
filterData();
},
child: Container(
color: const Color(0XFFF4F6F8),
child: Column(
children: [
Container(
color: Colors.white,
height: Constant.getActualY(context: context, y: 56),
),
const HeaderWidget(
teks: "List Pekerjaan",
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
// color: Colors.red,
child: InkWell(
// splashColor: Colors.red,
onTap: () {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return AlertDialog(
content: HookBuilder(builder: (context) {
final a = useState(1);
return SizedBox(
width: Constant.getActualX(
context: context, x: 280),
height: Constant.getActualY(
context: context, y: 692),
child: Column(
children: [
SizedBox(
height: Constant.getActualY(
context: context, y: 36),
width: Constant.getActualX(
context: context, x: 280),
// color: Colors.red,
child: Row(
// crossAxisAlignment:
// CrossAxisAlignment.end,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
"Filter",
style: Constant.body1(
context: context)
.copyWith(
fontWeight:
FontWeight.w600,
color: Constant
.textPrimary),
),
IconButton(
iconSize: 20,
splashRadius: 20,
onPressed: () {
filterData();
Navigator.pop(context);
},
icon: const Icon(Icons.clear))
],
),
),
const Divider(),
SizedBox(
height: Constant.getActualY(
context: context, y: 24),
),
Container(
height: Constant.getActualY(
context: context, y: 590),
margin: EdgeInsets.only(
left: Constant.getActualX(
context: context, x: 48)),
// color: Colors.red,
child: ListView(
children: [
Text(
"Tipe",
style: Constant.body1(
context: context)
.copyWith(
fontWeight:
FontWeight.w600,
color: Constant
.textPrimary),
),
SizedBox(
height: Constant.getActualY(
context: context, y: 8),
),
workTypeLoading.value
? LoadingAnimationWidget
.progressiveDots(
color: Constant
.primaryBlue,
size: 50)
: Column(
children:
workTypeData.value
.map(
(e) => SizedBox(
child: Row(
children: [
Checkbox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
5)),
value: selectedTipe.value.contains(e
.id),
onChanged:
(value) {
var sp =
selectedTipe.value.toSet().toList();
if (value ==
true) {
sp.add(int.parse(e.id.toString()));
} else {
sp.remove(int.parse(e.id.toString()));
}
selectedTipe.value =
sp;
// print(value);
// print(e.id);
a.value =
a.value++;
}),
SizedBox(
height: Constant.getActualY(
context:
context,
y: 8),
),
Expanded(
child:
Text(
e.name
.toString(),
maxLines:
2,
overflow:
TextOverflow.ellipsis,
style: Constant.body3(context: context).copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
),
),
],
),
),
)
.toList(),
),
SizedBox(
height: Constant.getActualY(
context: context, y: 24),
),
Text(
"Status",
style: Constant.body1(
context: context)
.copyWith(
fontWeight:
FontWeight.w600,
color: Constant
.textPrimary),
),
SizedBox(
height: Constant.getActualY(
context: context, y: 8),
),
workStatusLoading.value
? LoadingAnimationWidget
.progressiveDots(
color: Constant
.primaryBlue,
size: 50)
: Column(
children: workStatusData
.value
.map((e) {
return SizedBox(
child: Row(
children: [
Radio(
value: e
.statusid,
groupValue:
selectedStatus
.value,
onChanged:
(baru) {
selectedStatus
.value =
baru!;
a.value = a
.value++;
}),
SizedBox(
height: Constant
.getActualY(
context:
context,
y: 8),
),
Text(
"${e.statusname}",
style: Constant.body3(
context:
context)
.copyWith(
fontWeight:
FontWeight
.w400,
color: Constant
.textPrimary),
),
],
),
);
}).toList(),
),
SizedBox(
height: Constant.getActualY(
context: context, y: 24),
),
Text(
"Supervisor",
style: Constant.body1(
context: context)
.copyWith(
fontWeight:
FontWeight.w600,
color: Constant
.textPrimary),
),
SizedBox(
height: Constant.getActualY(
context: context, y: 8),
),
workSupervisorLoading.value
? LoadingAnimationWidget
.progressiveDots(
color: Constant
.primaryBlue,
size: 50)
: Column(
children:
workSupervisorData
.value
.map(
(e) => SizedBox(
child: Row(
children: [
Checkbox(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(
5)),
value: selectedSupervisor.value.contains(e
.supervisorid),
onChanged:
(value) {
var sp =
selectedSupervisor.value.toSet().toList();
if (value ==
true) {
sp.add(e.supervisorid!);
} else {
sp.remove(e.supervisorid!);
}
selectedSupervisor.value =
sp;
// print(value);
// print(e.supervisorid);
a.value =
a.value++;
}),
SizedBox(
height: Constant.getActualY(
context:
context,
y: 8),
),
Flexible(
child:
Text(
e.supervisorname
.toString(),
style: Constant.body3(context: context).copyWith(
fontWeight: FontWeight.w400,
color: Constant.textPrimary),
maxLines:
5,
overflow:
TextOverflow.ellipsis,
),
),
SizedBox(
height: Constant.getActualY(
context:
context,
y: 8),
),
if (e.supervisorid ==
"Y")
Icon(
size:
25,
Icons
.check_circle_outline_rounded,
color:
Constant.primaryGreen,
),
if (e.supervisorid ==
'N')
Icon(
size:
25,
Icons
.help_outline_rounded,
color:
Constant.primaryYellow,
),
if (e.supervisorid ==
"X")
Icon(
size:
25,
Icons
.cancel_outlined,
color:
Constant.primaryRed,
)
],
),
),
)
.toList(),
),
],
),
)
],
),
);
}),
);
},
);
},
child: Row(
children: [
Text(
"Filters",
style: Constant.caption1(context: context)
.copyWith(color: Constant.textPrimary),
),
Icon(
size:
Constant.getActualY(context: context, y: 20),
Icons.filter_alt_outlined,
color: Constant.textPrimary,
)
],
))),
],
),
Container(
height: Constant.getActualY(context: context, y: 641),
// color: Colors.red,
padding: EdgeInsets.symmetric(
horizontal: Constant.getActualX(context: context, x: 32),
vertical: 1),
child: workListLoading.value
? LoadingAnimationWidget.fourRotatingDots(
color: Constant.primaryBlue, size: 50)
: ListView.builder(
itemCount: workListData.value.length,
itemBuilder: (context, index) {
var data = workListData.value[index];
return WorkCardWidget(data: data);
},
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,65 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/filter_repository.dart';
import '../../models/work_status_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class WorkStatusState extends Equatable {
final DateTime date;
const WorkStatusState(this.date);
@override
List<Object?> get props => [date];
}
class WorkStatusStateInit extends WorkStatusState {
WorkStatusStateInit() : super(DateTime.now());
}
class WorkStatusStateLoading extends WorkStatusState {
WorkStatusStateLoading() : super(DateTime.now());
}
class WorkStatusStateError extends WorkStatusState {
final String message;
WorkStatusStateError({
required this.message,
}) : super(DateTime.now());
}
class WorkStatusStateDone extends WorkStatusState {
final List<WorkStatusModel> model;
WorkStatusStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class WorkStatusNotifier extends StateNotifier<WorkStatusState> {
final Ref ref;
WorkStatusNotifier({
required this.ref,
}) : super(WorkStatusStateInit());
void getData() async {
try {
state = WorkStatusStateLoading();
final dio = ref.read(dioProvider);
final resp = await FilterRepository(dio: dio).getStatus();
state = WorkStatusStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = WorkStatusStateError(message: e.message.toString());
} else {
state = WorkStatusStateError(message: e.toString());
}
}
}
}
//provider
final WorkStatusProvider =
StateNotifierProvider<WorkStatusNotifier, WorkStatusState>(
(ref) => WorkStatusNotifier(ref: ref));

View File

@@ -0,0 +1,64 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/filter_repository.dart';
import '../../models/work_supervisor_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class WorkSupervisorState extends Equatable {
final DateTime date;
const WorkSupervisorState(this.date);
@override
List<Object?> get props => [date];
}
class WorkSupervisorStateInit extends WorkSupervisorState {
WorkSupervisorStateInit() : super(DateTime.now());
}
class WorkSupervisorStateLoading extends WorkSupervisorState {
WorkSupervisorStateLoading() : super(DateTime.now());
}
class WorkSupervisorStateError extends WorkSupervisorState {
final String message;
WorkSupervisorStateError({
required this.message,
}) : super(DateTime.now());
}
class WorkSupervisorStateDone extends WorkSupervisorState {
final List<WorkSupervisorModel> model;
WorkSupervisorStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class WorkSupervisorNotifier extends StateNotifier<WorkSupervisorState> {
final Ref ref;
WorkSupervisorNotifier({
required this.ref,
}) : super(WorkSupervisorStateInit());
void getData() async {
try {
state = WorkSupervisorStateLoading();
final dio = ref.read(dioProvider);
final resp = await FilterRepository(dio: dio).getSupervisor();
state = WorkSupervisorStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = WorkSupervisorStateError(message: e.message.toString());
} else {
state = WorkSupervisorStateError(message: e.toString());
}
}
}
}
//provider
final WorkSupervisorProvider =
StateNotifierProvider<WorkSupervisorNotifier, WorkSupervisorState>(
(ref) => WorkSupervisorNotifier(ref: ref));

View File

@@ -0,0 +1,65 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/filter_repository.dart';
import '../../models/pending_work_model.dart';
import '../../models/work_type_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/home_screen_repository.dart';
abstract class WorkTypeState extends Equatable {
final DateTime date;
const WorkTypeState(this.date);
@override
List<Object?> get props => [date];
}
class WorkTypeStateInit extends WorkTypeState {
WorkTypeStateInit() : super(DateTime.now());
}
class WorkTypeStateLoading extends WorkTypeState {
WorkTypeStateLoading() : super(DateTime.now());
}
class WorkTypeStateError extends WorkTypeState {
final String message;
WorkTypeStateError({
required this.message,
}) : super(DateTime.now());
}
class WorkTypeStateDone extends WorkTypeState {
final List<WorkTypeModel> model;
WorkTypeStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class WorkTypeNotifier extends StateNotifier<WorkTypeState> {
final Ref ref;
WorkTypeNotifier({
required this.ref,
}) : super(WorkTypeStateInit());
void getData() async {
try {
state = WorkTypeStateLoading();
final dio = ref.read(dioProvider);
final resp = await FilterRepository(dio: dio).getType();
state = WorkTypeStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = WorkTypeStateError(message: e.message.toString());
} else {
state = WorkTypeStateError(message: e.toString());
}
}
}
}
//provider
final WorkTypeProvider = StateNotifierProvider<WorkTypeNotifier, WorkTypeState>(
(ref) => WorkTypeNotifier(ref: ref));

View File

@@ -0,0 +1,74 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '/models/detail_history_model.dart';
import '/models/detail_work_model.dart';
import '/models/history_model.dart';
import '../../repository/history_screen_repository.dart';
import '../../repository/work_list_repository.dart';
import '/screen/history_screen/history_screen.dart';
import '../../models/pending_work_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/home_screen_repository.dart';
abstract class DetailWorkState extends Equatable {
final DateTime date;
const DetailWorkState(this.date);
@override
List<Object?> get props => [date];
}
class DetailWorkStateInit extends DetailWorkState {
DetailWorkStateInit() : super(DateTime.now());
}
class DetailWorkStateLoading extends DetailWorkState {
DetailWorkStateLoading() : super(DateTime.now());
}
class DetailWorkStateError extends DetailWorkState {
final String message;
DetailWorkStateError({
required this.message,
}) : super(DateTime.now());
}
class DetailWorkStateDone extends DetailWorkState {
final DetailWorkModel model;
DetailWorkStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class DetailWorkNotifier extends StateNotifier<DetailWorkState> {
final Ref ref;
DetailWorkNotifier({
required this.ref,
}) : super(DetailWorkStateInit());
void getData(
{required String id,
required String tipeId,
required String deliveryId}) async {
try {
state = DetailWorkStateLoading();
final dio = ref.read(dioProvider);
final resp = await WorkListRepository(dio: dio)
.getDetail(id: id, tipeId: tipeId, deliveryId: deliveryId);
state = DetailWorkStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = DetailWorkStateError(message: e.message.toString());
} else {
state = DetailWorkStateError(message: e.toString());
}
}
}
}
//provider
final DetailWorkProvider =
StateNotifierProvider<DetailWorkNotifier, DetailWorkState>(
(ref) => DetailWorkNotifier(ref: ref));

View File

@@ -0,0 +1,71 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/get_other_repository.dart';
import '../../repository/result_delivery_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class OtherDeliverPersonState extends Equatable {
final DateTime date;
const OtherDeliverPersonState(this.date);
@override
List<Object?> get props => [date];
}
class OtherDeliverPersonStateInit extends OtherDeliverPersonState {
OtherDeliverPersonStateInit() : super(DateTime.now());
}
class OtherDeliverPersonStateLoading extends OtherDeliverPersonState {
OtherDeliverPersonStateLoading() : super(DateTime.now());
}
class OtherDeliverPersonStateError extends OtherDeliverPersonState {
final String message;
OtherDeliverPersonStateError({
required this.message,
}) : super(DateTime.now());
}
class OtherDeliverPersonStateDone extends OtherDeliverPersonState {
final bool model;
OtherDeliverPersonStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class OtherDeliverPersonNotifier
extends StateNotifier<OtherDeliverPersonState> {
final Ref ref;
OtherDeliverPersonNotifier({
required this.ref,
}) : super(OtherDeliverPersonStateInit());
void setData({
required String id,
required String name,
required String note,
}) async {
try {
state = OtherDeliverPersonStateLoading();
final dio = ref.read(dioProvider);
final resp = await GetOtherRepository(dio: dio)
.setDeliveryPerson(id: id, name: name, note: note);
state = OtherDeliverPersonStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = OtherDeliverPersonStateError(message: e.message.toString());
} else {
state = OtherDeliverPersonStateError(message: e.toString());
}
}
}
}
//provider
final OtherDeliverPersonProvider =
StateNotifierProvider<OtherDeliverPersonNotifier, OtherDeliverPersonState>(
(ref) => OtherDeliverPersonNotifier(ref: ref));

View File

@@ -0,0 +1,78 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/get_other_repository.dart';
import '../../repository/get_sample_repository.dart';
import '../../repository/result_delivery_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class OtherDeliveryLocationState extends Equatable {
final DateTime date;
const OtherDeliveryLocationState(this.date);
@override
List<Object?> get props => [date];
}
class OtherDeliveryLocationStateInit extends OtherDeliveryLocationState {
OtherDeliveryLocationStateInit() : super(DateTime.now());
}
class OtherDeliveryLocationStateLoading extends OtherDeliveryLocationState {
OtherDeliveryLocationStateLoading() : super(DateTime.now());
}
class OtherDeliveryLocationStateError extends OtherDeliveryLocationState {
final String message;
OtherDeliveryLocationStateError({
required this.message,
}) : super(DateTime.now());
}
class OtherDeliveryLocationStateDone extends OtherDeliveryLocationState {
final bool model;
OtherDeliveryLocationStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class OtherDeliveryLocationNotifier
extends StateNotifier<OtherDeliveryLocationState> {
final Ref ref;
OtherDeliveryLocationNotifier({
required this.ref,
}) : super(OtherDeliveryLocationStateInit());
void setData(
{required String id,
required String step,
required String lat,
required String long,
required String address,
required String branchID}) async {
try {
state = OtherDeliveryLocationStateLoading();
final dio = ref.read(dioProvider);
final resp = await GetOtherRepository(dio: dio).setLocation(
id: id,
step: step,
lat: lat,
long: long,
address: address,
branchID: branchID);
state = OtherDeliveryLocationStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = OtherDeliveryLocationStateError(message: e.message.toString());
} else {
state = OtherDeliveryLocationStateError(message: e.toString());
}
}
}
}
//provider
final OtherDeliveryLocationProvider = StateNotifierProvider<
OtherDeliveryLocationNotifier, OtherDeliveryLocationState>(
(ref) => OtherDeliveryLocationNotifier(ref: ref));

View File

@@ -0,0 +1,71 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/get_other_repository.dart';
import '../../repository/result_delivery_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class OtherReceivePersonState extends Equatable {
final DateTime date;
const OtherReceivePersonState(this.date);
@override
List<Object?> get props => [date];
}
class OtherReceivePersonStateInit extends OtherReceivePersonState {
OtherReceivePersonStateInit() : super(DateTime.now());
}
class OtherReceivePersonStateLoading extends OtherReceivePersonState {
OtherReceivePersonStateLoading() : super(DateTime.now());
}
class OtherReceivePersonStateError extends OtherReceivePersonState {
final String message;
OtherReceivePersonStateError({
required this.message,
}) : super(DateTime.now());
}
class OtherReceivePersonStateDone extends OtherReceivePersonState {
final bool model;
OtherReceivePersonStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class OtherReceivePersonNotifier
extends StateNotifier<OtherReceivePersonState> {
final Ref ref;
OtherReceivePersonNotifier({
required this.ref,
}) : super(OtherReceivePersonStateInit());
void setData({
required String id,
required String name,
required String note,
}) async {
try {
state = OtherReceivePersonStateLoading();
final dio = ref.read(dioProvider);
final resp = await GetOtherRepository(dio: dio)
.setReceivePerson(id: id, name: name, note: note);
state = OtherReceivePersonStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = OtherReceivePersonStateError(message: e.message.toString());
} else {
state = OtherReceivePersonStateError(message: e.toString());
}
}
}
}
//provider
final OtherReceivePersonProvider =
StateNotifierProvider<OtherReceivePersonNotifier, OtherReceivePersonState>(
(ref) => OtherReceivePersonNotifier(ref: ref));

View File

@@ -0,0 +1,70 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/result_delivery_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class ResultDeliverPersonState extends Equatable {
final DateTime date;
const ResultDeliverPersonState(this.date);
@override
List<Object?> get props => [date];
}
class ResultDeliverPersonStateInit extends ResultDeliverPersonState {
ResultDeliverPersonStateInit() : super(DateTime.now());
}
class ResultDeliverPersonStateLoading extends ResultDeliverPersonState {
ResultDeliverPersonStateLoading() : super(DateTime.now());
}
class ResultDeliverPersonStateError extends ResultDeliverPersonState {
final String message;
ResultDeliverPersonStateError({
required this.message,
}) : super(DateTime.now());
}
class ResultDeliverPersonStateDone extends ResultDeliverPersonState {
final bool model;
ResultDeliverPersonStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class ResultDeliverPersonNotifier
extends StateNotifier<ResultDeliverPersonState> {
final Ref ref;
ResultDeliverPersonNotifier({
required this.ref,
}) : super(ResultDeliverPersonStateInit());
void setData({
required String id,
required String name,
required String note,
}) async {
try {
state = ResultDeliverPersonStateLoading();
final dio = ref.read(dioProvider);
final resp = await ResultDeliveryRepository(dio: dio)
.setDeliveryPerson(id: id, name: name, note: note);
state = ResultDeliverPersonStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = ResultDeliverPersonStateError(message: e.message.toString());
} else {
state = ResultDeliverPersonStateError(message: e.toString());
}
}
}
}
//provider
final ResultDeliverPersonProvider = StateNotifierProvider<
ResultDeliverPersonNotifier,
ResultDeliverPersonState>((ref) => ResultDeliverPersonNotifier(ref: ref));

View File

@@ -0,0 +1,76 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/result_delivery_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class ResultDeliveryLocationState extends Equatable {
final DateTime date;
const ResultDeliveryLocationState(this.date);
@override
List<Object?> get props => [date];
}
class ResultDeliveryLocationStateInit extends ResultDeliveryLocationState {
ResultDeliveryLocationStateInit() : super(DateTime.now());
}
class ResultDeliveryLocationStateLoading extends ResultDeliveryLocationState {
ResultDeliveryLocationStateLoading() : super(DateTime.now());
}
class ResultDeliveryLocationStateError extends ResultDeliveryLocationState {
final String message;
ResultDeliveryLocationStateError({
required this.message,
}) : super(DateTime.now());
}
class ResultDeliveryLocationStateDone extends ResultDeliveryLocationState {
final bool model;
ResultDeliveryLocationStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class ResultDeliveryLocationNotifier
extends StateNotifier<ResultDeliveryLocationState> {
final Ref ref;
ResultDeliveryLocationNotifier({
required this.ref,
}) : super(ResultDeliveryLocationStateInit());
void setData(
{required String id,
required String step,
required String lat,
required String long,
required String address,
required String branchID}) async {
try {
state = ResultDeliveryLocationStateLoading();
final dio = ref.read(dioProvider);
final resp = await ResultDeliveryRepository(dio: dio).setLocation(
id: id,
step: step,
lat: lat,
long: long,
address: address,
branchID: branchID);
state = ResultDeliveryLocationStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = ResultDeliveryLocationStateError(message: e.message.toString());
} else {
state = ResultDeliveryLocationStateError(message: e.toString());
}
}
}
}
//provider
final ResultDeliveryLocationProvider = StateNotifierProvider<
ResultDeliveryLocationNotifier, ResultDeliveryLocationState>(
(ref) => ResultDeliveryLocationNotifier(ref: ref));

View File

@@ -0,0 +1,70 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/result_delivery_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class ResultReceivePersonState extends Equatable {
final DateTime date;
const ResultReceivePersonState(this.date);
@override
List<Object?> get props => [date];
}
class ResultReceivePersonStateInit extends ResultReceivePersonState {
ResultReceivePersonStateInit() : super(DateTime.now());
}
class ResultReceivePersonStateLoading extends ResultReceivePersonState {
ResultReceivePersonStateLoading() : super(DateTime.now());
}
class ResultReceivePersonStateError extends ResultReceivePersonState {
final String message;
ResultReceivePersonStateError({
required this.message,
}) : super(DateTime.now());
}
class ResultReceivePersonStateDone extends ResultReceivePersonState {
final bool model;
ResultReceivePersonStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class ResultReceivePersonNotifier
extends StateNotifier<ResultReceivePersonState> {
final Ref ref;
ResultReceivePersonNotifier({
required this.ref,
}) : super(ResultReceivePersonStateInit());
void setData({
required String id,
required String name,
required String note,
}) async {
try {
state = ResultReceivePersonStateLoading();
final dio = ref.read(dioProvider);
final resp = await ResultDeliveryRepository(dio: dio)
.setReceivePerson(id: id, name: name, note: note);
state = ResultReceivePersonStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = ResultReceivePersonStateError(message: e.message.toString());
} else {
state = ResultReceivePersonStateError(message: e.toString());
}
}
}
}
//provider
final ResultReceivePersonProvider = StateNotifierProvider<
ResultReceivePersonNotifier,
ResultReceivePersonState>((ref) => ResultReceivePersonNotifier(ref: ref));

View File

@@ -0,0 +1,92 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/get_sample_repository.dart';
import '../../repository/result_delivery_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class SampleDeliverPersonState extends Equatable {
final DateTime date;
const SampleDeliverPersonState(this.date);
@override
List<Object?> get props => [date];
}
class SampleDeliverPersonStateInit extends SampleDeliverPersonState {
SampleDeliverPersonStateInit() : super(DateTime.now());
}
class SampleDeliverPersonStateLoading extends SampleDeliverPersonState {
SampleDeliverPersonStateLoading() : super(DateTime.now());
}
class SampleDeliverPersonStateError extends SampleDeliverPersonState {
final String message;
SampleDeliverPersonStateError({
required this.message,
}) : super(DateTime.now());
}
class SampleDeliverPersonStateDone extends SampleDeliverPersonState {
final bool model;
SampleDeliverPersonStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class SampleDeliverPersonNotifier
extends StateNotifier<SampleDeliverPersonState> {
final Ref ref;
SampleDeliverPersonNotifier({
required this.ref,
}) : super(SampleDeliverPersonStateInit());
void setData({
required String id,
required String name,
required String note,
// Inputan INFO
required String jumlahPasien,
required String edtaRutin,
required String darahCitras,
required String serum,
required String urine,
required String pleura,
required String otherTextBahan,
required String totalOther,
}) async {
try {
state = SampleDeliverPersonStateLoading();
final dio = ref.read(dioProvider);
final resp = await GetSampleRepository(dio: dio).setDeliveryPerson(
id: id,
name: name,
note: note,
// INPUTAN INFO
jumlahPasien: jumlahPasien,
edtaRutin: edtaRutin,
darahCitras: darahCitras,
serum: serum,
urine: urine,
pleura: pleura,
otherTextBahan: otherTextBahan,
totalOther: totalOther
);
state = SampleDeliverPersonStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = SampleDeliverPersonStateError(message: e.message.toString());
} else {
state = SampleDeliverPersonStateError(message: e.toString());
}
}
}
}
//provider
final SampleDeliverPersonProvider = StateNotifierProvider<
SampleDeliverPersonNotifier,
SampleDeliverPersonState>((ref) => SampleDeliverPersonNotifier(ref: ref));

View File

@@ -0,0 +1,77 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/get_sample_repository.dart';
import '../../repository/result_delivery_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class SampleDeliveryLocationState extends Equatable {
final DateTime date;
const SampleDeliveryLocationState(this.date);
@override
List<Object?> get props => [date];
}
class SampleDeliveryLocationStateInit extends SampleDeliveryLocationState {
SampleDeliveryLocationStateInit() : super(DateTime.now());
}
class SampleDeliveryLocationStateLoading extends SampleDeliveryLocationState {
SampleDeliveryLocationStateLoading() : super(DateTime.now());
}
class SampleDeliveryLocationStateError extends SampleDeliveryLocationState {
final String message;
SampleDeliveryLocationStateError({
required this.message,
}) : super(DateTime.now());
}
class SampleDeliveryLocationStateDone extends SampleDeliveryLocationState {
final bool model;
SampleDeliveryLocationStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class SampleDeliveryLocationNotifier
extends StateNotifier<SampleDeliveryLocationState> {
final Ref ref;
SampleDeliveryLocationNotifier({
required this.ref,
}) : super(SampleDeliveryLocationStateInit());
void setData(
{required String id,
required String step,
required String lat,
required String long,
required String address,
required String branchID}) async {
try {
state = SampleDeliveryLocationStateLoading();
final dio = ref.read(dioProvider);
final resp = await GetSampleRepository(dio: dio).setLocation(
id: id,
step: step,
lat: lat,
long: long,
address: address,
branchID: branchID);
state = SampleDeliveryLocationStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = SampleDeliveryLocationStateError(message: e.message.toString());
} else {
state = SampleDeliveryLocationStateError(message: e.toString());
}
}
}
}
//provider
final SampleDeliveryLocationProvider = StateNotifierProvider<
SampleDeliveryLocationNotifier, SampleDeliveryLocationState>(
(ref) => SampleDeliveryLocationNotifier(ref: ref));

View File

@@ -0,0 +1,75 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../repository/get_sample_repository.dart';
import '../../repository/result_delivery_repository.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
abstract class SampleReceivePersonState extends Equatable {
final DateTime date;
const SampleReceivePersonState(this.date);
@override
List<Object?> get props => [date];
}
class SampleReceivePersonStateInit extends SampleReceivePersonState {
SampleReceivePersonStateInit() : super(DateTime.now());
}
class SampleReceivePersonStateLoading extends SampleReceivePersonState {
SampleReceivePersonStateLoading() : super(DateTime.now());
}
class SampleReceivePersonStateError extends SampleReceivePersonState {
final String message;
SampleReceivePersonStateError({
required this.message,
}) : super(DateTime.now());
}
class SampleReceivePersonStateDone extends SampleReceivePersonState {
final bool model;
SampleReceivePersonStateDone({
required this.model,
}) : super(DateTime.now());
}
//notifier
class SampleReceivePersonNotifier
extends StateNotifier<SampleReceivePersonState> {
final Ref ref;
SampleReceivePersonNotifier({
required this.ref,
}) : super(SampleReceivePersonStateInit());
void setData(
{required String id,
required String name,
required String note,
required String suhuSample}) async {
try {
state = SampleReceivePersonStateLoading();
final dio = ref.read(dioProvider);
final resp = await GetSampleRepository(dio: dio).setReceivePerson(
id: id,
name: name,
note: note,
suhuSample: suhuSample,
);
state = SampleReceivePersonStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = SampleReceivePersonStateError(message: e.message.toString());
} else {
state = SampleReceivePersonStateError(message: e.toString());
}
}
}
}
//provider
final SampleReceivePersonProvider = StateNotifierProvider<
SampleReceivePersonNotifier,
SampleReceivePersonState>((ref) => SampleReceivePersonNotifier(ref: ref));

View File

@@ -0,0 +1,69 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../models/response_save_work_suhu_model.dart';
import '../../provider/dio_provider.dart';
import '../../repository/base_repository.dart';
import '../../repository/work_input_suhu_repository.dart';
// 3. state provider
final workInputSuhuSave = StateNotifierProvider<WorkInputSuhuNotifier,
WorkInputSuhuState>((ref) => WorkInputSuhuNotifier(ref: ref));
// 2. notifier
class WorkInputSuhuNotifier
extends StateNotifier<WorkInputSuhuState> {
final Ref ref;
WorkInputSuhuNotifier({required this.ref})
: super(WorkInputSuhuStateInit());
void workInputSuhu({
required String deliveryId,
required String suhu
}) async {
try {
state = WorkInputSuhuStateLoading();
final resp = await WorkInputSuhuRepository(dio: ref.read(dioProvider))
.inputWorkSuhu(
deliveryId: deliveryId,
suhu: suhu,
);
state = WorkInputSuhuStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = WorkInputSuhuStateError(message: e.message ?? "");
} else {
state = WorkInputSuhuStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class WorkInputSuhuState extends Equatable {
final DateTime date;
const WorkInputSuhuState(this.date);
@override
List<Object?> get props => [date];
}
class WorkInputSuhuStateInit extends WorkInputSuhuState {
WorkInputSuhuStateInit() : super(DateTime.now());
}
class WorkInputSuhuStateLoading extends WorkInputSuhuState {
WorkInputSuhuStateLoading() : super(DateTime.now());
}
class WorkInputSuhuStateError extends WorkInputSuhuState {
final String? message;
WorkInputSuhuStateError({
required this.message,
}) : super(DateTime.now());
}
class WorkInputSuhuStateDone extends WorkInputSuhuState {
final ResponseSaveWorkSuhuModel model;
WorkInputSuhuStateDone({
required this.model,
}) : super(DateTime.now());
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,77 @@
import 'package:equatable/equatable.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '/models/response_save_work_tunda_model.dart';
import '../../repository/input_lain_lain_repository.dart';
import '../../repository/work_tunda_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 workTundaSave = StateNotifierProvider<WorkTundaSaveNotifier,
WorkTundaSaveState>((ref) => WorkTundaSaveNotifier(ref: ref));
// 2. notifier
class WorkTundaSaveNotifier
extends StateNotifier<WorkTundaSaveState> {
final Ref ref;
WorkTundaSaveNotifier({required this.ref})
: super(WorkTundaSaveStateInit());
void WorkTundaSave({
required String courierID,
required String tipeID,
required String deliveryID,
required String note
}) async {
try {
state = WorkTundaSaveStateLoading();
final resp = await WorkTundaRepository(dio: ref.read(dioProvider))
.inputWorkTunda(
courierID: courierID,
tipeID: tipeID,
deliveryID: deliveryID,
note: note
);
state = WorkTundaSaveStateDone(model: resp);
} catch (e) {
if (e is BaseRepositoryException) {
state = WorkTundaSaveStateError(message: e.message ?? "");
} else {
state = WorkTundaSaveStateError(message: e.toString());
}
}
}
}
// 1. state
abstract class WorkTundaSaveState extends Equatable {
final DateTime date;
const WorkTundaSaveState(this.date);
@override
List<Object?> get props => [date];
}
class WorkTundaSaveStateInit extends WorkTundaSaveState {
WorkTundaSaveStateInit() : super(DateTime.now());
}
class WorkTundaSaveStateLoading extends WorkTundaSaveState {
WorkTundaSaveStateLoading() : super(DateTime.now());
}
class WorkTundaSaveStateError extends WorkTundaSaveState {
final String? message;
WorkTundaSaveStateError({
required this.message,
}) : super(DateTime.now());
}
class WorkTundaSaveStateDone extends WorkTundaSaveState {
final ResponseSaveWorkTundaModel model;
WorkTundaSaveStateDone({
required this.model,
}) : super(DateTime.now());
}