One UI in flutter
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

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