step 3 : hapus ai_barcode_scanner, ai barcode, update permission_handler, flutter_map,latlong2
This commit is contained in:
@@ -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));
|
||||
268
lib/screen/change_password_screen/change_password_screen.dart
Normal file
268
lib/screen/change_password_screen/change_password_screen.dart
Normal 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)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
792
lib/screen/detail_history_screen/detail_history_screen.dart
Normal file
792
lib/screen/detail_history_screen/detail_history_screen.dart
Normal 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),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
207
lib/screen/history_screen/history_list_card.dart
Normal file
207
lib/screen/history_screen/history_list_card.dart
Normal 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),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
69
lib/screen/history_screen/history_list_provider.dart
Normal file
69
lib/screen/history_screen/history_list_provider.dart
Normal 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));
|
||||
466
lib/screen/history_screen/history_screen.dart
Normal file
466
lib/screen/history_screen/history_screen.dart
Normal 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),
|
||||
),
|
||||
],
|
||||
)),
|
||||
);
|
||||
}
|
||||
}
|
||||
68
lib/screen/history_screen/history_type_provider.dart
Normal file
68
lib/screen/history_screen/history_type_provider.dart
Normal 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));
|
||||
434
lib/screen/home_screen/home_screen.dart
Normal file
434
lib/screen/home_screen/home_screen.dart
Normal 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]);
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
64
lib/screen/home_screen/pending_work_provider.dart
Normal file
64
lib/screen/home_screen/pending_work_provider.dart
Normal 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));
|
||||
64
lib/screen/home_screen/total_work_provider.dart
Normal file
64
lib/screen/home_screen/total_work_provider.dart
Normal 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));
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
432
lib/screen/input_pekerjaan/input_lain_lain_screen.dart
Normal file
432
lib/screen/input_pekerjaan/input_lain_lain_screen.dart
Normal 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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
241
lib/screen/input_pekerjaan/input_pekerjaan_lain_lain.dart
Normal file
241
lib/screen/input_pekerjaan/input_pekerjaan_lain_lain.dart
Normal 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),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
376
lib/screen/input_pekerjaan/input_pekerjaan_screen.dart
Normal file
376
lib/screen/input_pekerjaan/input_pekerjaan_screen.dart
Normal 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),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
614
lib/screen/input_pekerjaan/input_pengambilan_bahan_screen.dart
Normal file
614
lib/screen/input_pekerjaan/input_pengambilan_bahan_screen.dart
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
103
lib/screen/input_pekerjaan/input_scan_screen.dart
Normal file
103
lib/screen/input_pekerjaan/input_scan_screen.dart
Normal 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);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
68
lib/screen/input_pekerjaan/search_company_provider.dart
Normal file
68
lib/screen/input_pekerjaan/search_company_provider.dart
Normal 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));
|
||||
91
lib/screen/konfirmasi/konfirmasi_screen.dart
Normal file
91
lib/screen/konfirmasi/konfirmasi_screen.dart
Normal 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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
70
lib/screen/kurir_konfirmasi_screen/kurir_tolak_provider.dart
Normal file
70
lib/screen/kurir_konfirmasi_screen/kurir_tolak_provider.dart
Normal 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());
|
||||
}
|
||||
94
lib/screen/login/login_provider.dart
Normal file
94
lib/screen/login/login_provider.dart
Normal 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());
|
||||
}
|
||||
325
lib/screen/login/login_screen.dart
Normal file
325
lib/screen/login/login_screen.dart
Normal 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),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
64
lib/screen/login/logout_provider.dart
Normal file
64
lib/screen/login/logout_provider.dart
Normal 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());
|
||||
}
|
||||
95
lib/screen/menu_screen/menu_screen.dart
Normal file
95
lib/screen/menu_screen/menu_screen.dart
Normal 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(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
@@ -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,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
||||
173
lib/screen/problemlogin/problem_login_screen.dart
Normal file
173
lib/screen/problemlogin/problem_login_screen.dart
Normal 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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
244
lib/screen/profile_screen/profile_screen.dart
Normal file
244
lib/screen/profile_screen/profile_screen.dart
Normal 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),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
101
lib/screen/splash_screen/splash_screen.dart
Normal file
101
lib/screen/splash_screen/splash_screen.dart
Normal 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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
129
lib/screen/test/test_home_screen.dart
Normal file
129
lib/screen/test/test_home_screen.dart
Normal 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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
70
lib/screen/work_list_screen/work_list_provider.dart
Normal file
70
lib/screen/work_list_screen/work_list_provider.dart
Normal 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));
|
||||
547
lib/screen/work_list_screen/work_list_screen.dart
Normal file
547
lib/screen/work_list_screen/work_list_screen.dart
Normal 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);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
65
lib/screen/work_list_screen/work_status_provider.dart
Normal file
65
lib/screen/work_list_screen/work_status_provider.dart
Normal 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));
|
||||
64
lib/screen/work_list_screen/work_supervisor_moder.dart
Normal file
64
lib/screen/work_list_screen/work_supervisor_moder.dart
Normal 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));
|
||||
65
lib/screen/work_list_screen/work_type_provider.dart
Normal file
65
lib/screen/work_list_screen/work_type_provider.dart
Normal 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));
|
||||
74
lib/screen/work_process_screen/detail_work_provider.dart
Normal file
74
lib/screen/work_process_screen/detail_work_provider.dart
Normal 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));
|
||||
@@ -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));
|
||||
@@ -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));
|
||||
@@ -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));
|
||||
@@ -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));
|
||||
@@ -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));
|
||||
@@ -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));
|
||||
@@ -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));
|
||||
@@ -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));
|
||||
@@ -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));
|
||||
69
lib/screen/work_process_screen/work_input_suhu_provider.dart
Normal file
69
lib/screen/work_process_screen/work_input_suhu_provider.dart
Normal 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());
|
||||
}
|
||||
3220
lib/screen/work_process_screen/work_process_screen.dart
Normal file
3220
lib/screen/work_process_screen/work_process_screen.dart
Normal file
File diff suppressed because it is too large
Load Diff
77
lib/screen/work_process_screen/work_tunda_provider.dart
Normal file
77
lib/screen/work_process_screen/work_tunda_provider.dart
Normal 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());
|
||||
}
|
||||
Reference in New Issue
Block a user