You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
313 lines
9.6 KiB
313 lines
9.6 KiB
import 'dart:async'; |
|
|
|
import 'package:flutter/material.dart'; |
|
import 'package:flutter_hooks/flutter_hooks.dart'; |
|
import 'package:hooks_riverpod/hooks_riverpod.dart'; |
|
import 'package:onemd/model/ac_company_response_model.dart'; |
|
import 'package:onemd/model/ac_doctor_model.dart'; |
|
import 'package:onemd/widget/provider/mitra_delete_provider.dart'; |
|
|
|
import '../model/ac_mou_response_model.dart'; |
|
import '../model/mitra_response_model.dart'; |
|
import '../screen/md_lab_mitra/mitra_lookup_mou_provider.dart'; |
|
import '../screen/md_lab_mitra/mitra_search_provider.dart'; |
|
import 'fx_error_text.dart'; |
|
import 'fx_mitra_add_dialog.dart'; |
|
import 'fx_mitra_edit_dialog.dart'; |
|
import 'provider/doctor_address_lookup_provider.dart'; |
|
import 'provider/selectedCompanyProvider.dart'; |
|
import 'provider/selectedDoctorProvider.dart'; |
|
|
|
class FxDataMitra extends HookConsumerWidget { |
|
final int rowsPerPage; |
|
const FxDataMitra({ |
|
Key? key, |
|
this.rowsPerPage = 10, |
|
}) : super(key: key); |
|
|
|
@override |
|
Widget build(BuildContext context, WidgetRef ref) { |
|
final list = useState<List<MitraResponseModel>>(List.empty()); |
|
final isLoading = useState(false); |
|
final errorMessage = useState(""); |
|
|
|
ref.listen(mitraSearchProvider, (prev, next) { |
|
if (next is MitraSearchStateLoading) { |
|
isLoading.value = true; |
|
} else if (next is MitraSearchStateError) { |
|
isLoading.value = false; |
|
errorMessage.value = next.message; |
|
Timer(const Duration(seconds: 3), () { |
|
errorMessage.value = ""; |
|
}); |
|
} else if (next is MitraSearchStateDone) { |
|
isLoading.value = false; |
|
list.value = next.list; |
|
} |
|
}); |
|
final pageWidth = MediaQuery.of(context).size.width - 200; |
|
return PaginatedDataTable( |
|
arrowHeadColor: Colors.red, |
|
columnSpacing: 10, |
|
header: Column( |
|
children: [ |
|
const FxNormalBlueText(title: "Daftar Lab Mitra"), |
|
if (isLoading.value) const LinearProgressIndicator(), |
|
if (errorMessage.value != "") FxErrorText(title: errorMessage.value) |
|
], |
|
), |
|
rowsPerPage: rowsPerPage, |
|
actions: [ |
|
SizedBox( |
|
width: 150, |
|
child: TextButton( |
|
child: Row( |
|
mainAxisSize: MainAxisSize.max, |
|
children: const [ |
|
Text("New Lab Mitra"), |
|
Icon(Icons.add_rounded, size: 24), |
|
], |
|
), |
|
onPressed: () async { |
|
await showDialog( |
|
context: context, |
|
builder: (context) { |
|
return const FxMitraAddDialog(); |
|
}); |
|
}), |
|
), |
|
], |
|
columns: [ |
|
titleColumn("Company"), |
|
titleColumn("Login"), |
|
titleColumn("ID"), |
|
titleColumn("Aggreement"), |
|
titleColumn(""), |
|
], |
|
source: _MitraDataSource( |
|
totalRow: list.value.length, |
|
list: list.value, |
|
pageWidth: pageWidth, |
|
onDelete: (model) async { |
|
await showDialog( |
|
context: context, |
|
builder: (context) { |
|
return AlertDialog( |
|
title: const Text("Delete Mitra"), |
|
content: Text( |
|
"Confirm delete ${model.mitraUsername} , ${model.mCompanyName} ?"), |
|
actions: [ |
|
TextButton( |
|
onPressed: () { |
|
ref |
|
.read(mitraDeleteProvider.notifier) |
|
.delete(mitraID: model.mitraID, query: ""); |
|
Navigator.of(context).pop(); |
|
}, |
|
style: ButtonStyle( |
|
backgroundColor: MaterialStateColor.resolveWith( |
|
(state) => Colors.red), |
|
), |
|
child: const Text("Delete", |
|
style: TextStyle(color: Colors.white)), |
|
), |
|
TextButton( |
|
style: ButtonStyle( |
|
backgroundColor: MaterialStateColor.resolveWith( |
|
(state) => Colors.green), |
|
), |
|
onPressed: () { |
|
Navigator.of(context).pop(); |
|
}, |
|
child: const Text("Cancel", |
|
style: TextStyle(color: Colors.white)), |
|
) |
|
], |
|
); |
|
}); |
|
}, |
|
onEdit: (model) async { |
|
ref.read(selectedMouProvider.notifier).state = model.aggrementID |
|
.map((id) => AcMouResponseModel( |
|
mMouID: id, |
|
mMouName: "", |
|
mMouNote: "", |
|
mMouIsMcu: "", |
|
mMouNumber: "", |
|
mMouEndDate: "", |
|
mMouIsActive: "Y", |
|
mMouStartDate: "", |
|
)) |
|
.toList(); |
|
ref.read(selectedAcCompanyProvider.notifier).state = AcCompanyModel( |
|
mCompanyID: model.mitraMCompanyID, |
|
mCompanyAddress: model.mCompanyAddress, |
|
mCompanyAddressLocation: "", |
|
mCompanyEmail: "", |
|
mCompanyHp: "", |
|
mCompanyName: model.mCompanyName, |
|
mCompanyNumber: "", |
|
mCompanyPhone: "", |
|
); |
|
ref |
|
.read(mitraLookupMouProvider.notifier) |
|
.lookup(companyID: model.mitraMCompanyID); |
|
ref.read(selectedAcDoctorProvider.notifier).state = |
|
AcDoctorResponseModel( |
|
fullName: model.mDoctorName, |
|
mDoctorID: model.mitraMDoctorID, |
|
); |
|
ref |
|
.read(doctorAddressLookupProvider.notifier) |
|
.lookup(doctorID: model.mitraMDoctorID); |
|
|
|
ref.read(selectedAcDoctorAddressProvider.notifier).state = |
|
AcDoctorAddressResponseModel( |
|
mDoctorAddressID: model.mitraMDoctorAddressID, |
|
mDoctorAddressDescription: "", |
|
); |
|
|
|
await showDialog( |
|
context: context, |
|
builder: (context) { |
|
return FxMitraEditDialog( |
|
login: model.mitraUsername, |
|
idNo: model.mitraIDNo, |
|
mitraID: model.mitraID, |
|
); |
|
}, |
|
); |
|
}), |
|
); |
|
} |
|
|
|
DataColumn titleColumn(String title) { |
|
return DataColumn( |
|
label: FxNormalBlueText(title: title), |
|
); |
|
} |
|
} |
|
|
|
class FxNormalBlueText extends StatelessWidget { |
|
final String title; |
|
final bool isBold; |
|
const FxNormalBlueText({ |
|
Key? key, |
|
required this.title, |
|
this.isBold = false, |
|
}) : super(key: key); |
|
|
|
@override |
|
Widget build(BuildContext context) { |
|
return Text( |
|
title, |
|
overflow: TextOverflow.ellipsis, |
|
style: TextStyle( |
|
fontSize: 16, |
|
fontWeight: isBold ? FontWeight.w700 : FontWeight.normal, |
|
color: Colors.blue.shade500, |
|
), |
|
); |
|
} |
|
} |
|
|
|
class _MitraDataSource extends DataTableSource { |
|
final List<MitraResponseModel> list; |
|
final int totalRow; |
|
final double pageWidth; |
|
final void Function(MitraResponseModel)? onEdit; |
|
final void Function(MitraResponseModel)? onDelete; |
|
_MitraDataSource({ |
|
required this.list, |
|
required this.totalRow, |
|
required this.pageWidth, |
|
this.onEdit, |
|
this.onDelete, |
|
}); |
|
@override |
|
DataRow? getRow(int index) { |
|
final model = list[index]; |
|
final List<double> width = [ |
|
pageWidth * 1.5 / 7, |
|
pageWidth * 0.8 / 7, |
|
pageWidth * 0.8 / 7, |
|
pageWidth * 3.9 / 7 |
|
]; |
|
final agreement = model.aggrement.replaceAll('^', ', '); |
|
return DataRow( |
|
color: (index % 2 == 0) |
|
? MaterialStateColor.resolveWith( |
|
(state) => Colors.blue.shade50.withOpacity(0.2)) |
|
: null, |
|
cells: [ |
|
dataCell(model.mCompanyName, width[0]), |
|
dataCell(model.mitraUsername, width[1]), |
|
dataCell(model.mitraIDNo, width[2]), |
|
dataCell(agreement, width[3]), |
|
DataCell( |
|
SizedBox( |
|
width: 60, |
|
child: Row( |
|
mainAxisSize: MainAxisSize.max, |
|
mainAxisAlignment: MainAxisAlignment.spaceAround, |
|
children: [ |
|
InkWell( |
|
onTap: () { |
|
if (onEdit != null) onEdit!(model); |
|
}, |
|
child: Icon( |
|
Icons.edit_rounded, |
|
size: 24, |
|
color: Colors.green.shade700, |
|
), |
|
), |
|
InkWell( |
|
onTap: () async { |
|
if (onDelete != null) { |
|
onDelete!(model); |
|
} |
|
}, |
|
child: Icon( |
|
Icons.delete_rounded, |
|
size: 24, |
|
color: Colors.red.shade700, |
|
), |
|
), |
|
], |
|
), |
|
), |
|
), |
|
], |
|
); |
|
} |
|
|
|
DataCell dataCell( |
|
String value, |
|
double width, |
|
) { |
|
return DataCell( |
|
SizedBox( |
|
width: width, |
|
child: Padding( |
|
padding: const EdgeInsets.all(5.0), |
|
child: Text( |
|
value, |
|
style: TextStyle( |
|
fontSize: 16, |
|
color: Colors.blue.shade500, |
|
), |
|
), |
|
), |
|
), |
|
); |
|
} |
|
|
|
@override |
|
bool get isRowCountApproximate => false; |
|
|
|
@override |
|
int get rowCount => list.length; |
|
|
|
@override |
|
int get selectedRowCount => 0; |
|
}
|
|
|