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.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 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 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; }