import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import '../model/mitra_response_model.dart'; import '../screen/md_lab_mitra/mitra_search_provider.dart'; import 'fx_error_text.dart'; import 'fx_mitra_add_dialog.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, ), ); } 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; _MitraDataSource({ required this.list, required this.totalRow, required this.pageWidth, }); @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: () {}, child: Icon( Icons.edit_rounded, size: 24, color: Colors.green.shade700, ), ), InkWell( onTap: () {}, 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; }