You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1197 lines
34 KiB
Dart
1197 lines
34 KiB
Dart
import 'dart:ui';
|
|
import 'package:doctor_app_flutter/core/model/pharmacy-intervention-model/intervention_history.dart';
|
|
import 'package:doctor_app_flutter/core/model/pharmacy-intervention-model/pharmacy_intervention_item.dart';
|
|
import 'package:doctor_app_flutter/widgets/shared/app_texts_widget.dart';
|
|
|
|
import 'viewmodel/pharmacy_intervention_view_model.dart';
|
|
import 'package:doctor_app_flutter/core/viewModel/project_view_model.dart';
|
|
import 'package:doctor_app_flutter/screens/base/base_view.dart';
|
|
import 'package:doctor_app_flutter/screens/patients/patient_search/patient_search_header.dart';
|
|
import 'package:doctor_app_flutter/utils/translations_delegate_base_utils.dart';
|
|
import 'package:doctor_app_flutter/widgets/shared/app_scaffold_widget.dart';
|
|
import 'package:doctor_app_flutter/widgets/shared/buttons/app_buttons_widget.dart';
|
|
import 'package:flutter/gestures.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:two_dimensional_scrollables/two_dimensional_scrollables.dart';
|
|
|
|
import '../../config/config.dart';
|
|
|
|
class PharmacyIntervention extends StatefulWidget {
|
|
@override
|
|
State<PharmacyIntervention> createState() => _PharmacyInterventionState();
|
|
}
|
|
|
|
class _PharmacyInterventionState extends State<PharmacyIntervention> {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
ProjectViewModel projectsProvider = Provider.of<ProjectViewModel>(context);
|
|
|
|
return BaseView<PharmacyInterventionViewModel>(builder: (_, model, __) {
|
|
if (model.interventionHistoryList != null) {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
showBottomSheet(
|
|
context,
|
|
model,
|
|
model.interventionHistoryList!.history!,
|
|
);
|
|
});
|
|
}
|
|
return AppScaffold(
|
|
isShowAppBar: true,
|
|
appBar: PatientSearchHeader(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.pharmacyApproval,
|
|
fontSize: 18,
|
|
showSearchIcon: true,
|
|
onSearchPressed: () {
|
|
SearchDialog(context);
|
|
},
|
|
),
|
|
appBarTitle: TranslationBase
|
|
.of(context)
|
|
.pharmacyApproval,
|
|
body: Column(
|
|
mainAxisSize: MainAxisSize.max,
|
|
children: [
|
|
Expanded(
|
|
child: ListView.builder(
|
|
itemCount: model.medicationList?.medication?.length ?? 0,
|
|
itemBuilder: (context, index) =>
|
|
InterventionCardItem(
|
|
medication: model.medicationList!.medication![index],
|
|
model: model,
|
|
)))
|
|
],
|
|
),
|
|
);
|
|
});
|
|
}
|
|
|
|
final _sheet = GlobalKey();
|
|
|
|
final _controller = DraggableScrollableController();
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_controller.addListener(_onChanged);
|
|
}
|
|
|
|
void _onChanged() {
|
|
final currentSize = _controller.size;
|
|
if (currentSize <= 0.05) _collapse();
|
|
}
|
|
|
|
void _collapse() => _animateSheet(sheet.snapSizes!.first);
|
|
|
|
void _anchor() => _animateSheet(sheet.snapSizes!.last);
|
|
|
|
void _expand() => _animateSheet(sheet.maxChildSize);
|
|
|
|
void _hide() => _animateSheet(sheet.minChildSize);
|
|
|
|
void _animateSheet(double size) {
|
|
_controller.animateTo(
|
|
size,
|
|
duration: const Duration(milliseconds: 50),
|
|
curve: Curves.easeInOut,
|
|
);
|
|
}
|
|
@override
|
|
void dispose() {
|
|
super.dispose();
|
|
_controller.dispose();
|
|
}
|
|
|
|
DraggableScrollableSheet get sheet =>
|
|
(_sheet.currentWidget as DraggableScrollableSheet);
|
|
|
|
void showBottomSheet(BuildContext context,
|
|
PharmacyInterventionViewModel model,
|
|
List<InterventionHistory> interventionHistory,) {
|
|
showModalBottomSheet(
|
|
isDismissible: true,
|
|
context: context,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(20), topRight: Radius.circular(20))),
|
|
builder: (_) {
|
|
return DraggableScrollableSheet(
|
|
key: _sheet,
|
|
initialChildSize: 0.5,
|
|
minChildSize: 0.5,
|
|
maxChildSize: 1,
|
|
snapSizes: [
|
|
0.5 ,// constraints.maxHeight,
|
|
0.9,
|
|
],
|
|
expand: false,
|
|
controller: _controller,
|
|
builder:(_, controller) =>
|
|
InterventionHistoryBottomSheet(
|
|
interventionList: interventionHistory,
|
|
controller: controller,
|
|
));
|
|
},
|
|
).then((value) => model.toggleShowBottomSheetValue());
|
|
}
|
|
|
|
void SearchDialog(BuildContext context) {
|
|
showDialog(
|
|
context: context,
|
|
barrierDismissible: true, // user must tap button!
|
|
builder: (_) {
|
|
return PharmacyInterventionDialog(
|
|
onDispose: (dateFrom, dateTo, admissionNumber, patientId) {});
|
|
});
|
|
}
|
|
}
|
|
|
|
class InterventionCardItem extends StatelessWidget {
|
|
final Medication medication;
|
|
final PharmacyInterventionViewModel model;
|
|
|
|
const InterventionCardItem(
|
|
{super.key, required this.medication, required this.model});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: Card(
|
|
color: Colors.white,
|
|
elevation: 5,
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: Column(
|
|
children: [
|
|
InterventionCardBody(
|
|
medication: medication,
|
|
model: model,
|
|
),
|
|
InterventionCardFooter(model: model)
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class InterventionCardFooter extends StatelessWidget {
|
|
final PharmacyInterventionViewModel model;
|
|
|
|
const InterventionCardFooter({super.key, required this.model});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(children: [
|
|
Row(children: [
|
|
Expanded(
|
|
child: AppButton(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.details,
|
|
hasBorder: true,
|
|
borderColor: Colors.grey,
|
|
color: Colors.grey,
|
|
fontColor: Colors.white,
|
|
onPressed: () async {},
|
|
),
|
|
),
|
|
]),
|
|
SizedBox(
|
|
height: 8,
|
|
),
|
|
Row(children: [
|
|
Expanded(
|
|
child: AppButton(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.reject,
|
|
hasBorder: true,
|
|
borderColor: Color(0xFFB8382B),
|
|
color: AppGlobal.appRedColor,
|
|
fontColor: Colors.white,
|
|
onPressed: () async {},
|
|
),
|
|
),
|
|
SizedBox(
|
|
width: 6,
|
|
),
|
|
Expanded(
|
|
child: AppButton(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.accept,
|
|
hasBorder: true,
|
|
borderColor: AppGlobal.appGreenColor,
|
|
color: AppGlobal.appGreenColor,
|
|
fontColor: Colors.white,
|
|
onPressed: () async {},
|
|
),
|
|
),
|
|
]),
|
|
]);
|
|
}
|
|
}
|
|
|
|
class InterventionCardBody extends StatelessWidget {
|
|
final Medication medication;
|
|
final PharmacyInterventionViewModel model;
|
|
|
|
const InterventionCardBody(
|
|
{super.key, required this.medication, required this.model});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
children: [
|
|
SizedBox(
|
|
height: 10,
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.accessLevel,
|
|
data: medication.accessLevel.toString() ?? '',
|
|
),
|
|
),
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.patientID,
|
|
data: medication.patientID.toString() ?? '',
|
|
))
|
|
],
|
|
),
|
|
SizedBox(
|
|
height: 10,
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.patientName,
|
|
data: medication.patientName.toString() ?? '',
|
|
),
|
|
),
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.nursingStation,
|
|
data: medication.nursingStation.toString() ?? '',
|
|
))
|
|
],
|
|
),
|
|
SizedBox(
|
|
height: 10,
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.admissionNumber,
|
|
data: medication.admissionNo.toString() ?? '',
|
|
),
|
|
),
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.medication,
|
|
data: medication.medication.toString() ?? '',
|
|
))
|
|
],
|
|
),
|
|
SizedBox(
|
|
height: 10,
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.dosageDetails,
|
|
data: medication.dosageDetail.toString() ?? '',
|
|
),
|
|
),
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.doctorComments,
|
|
data: medication.doctorComments.toString() ?? '',
|
|
))
|
|
],
|
|
),
|
|
SizedBox(
|
|
height: 10,
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.startDate,
|
|
data: model.getDate(medication.startDatetime.toString() ?? ''),
|
|
),
|
|
),
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.stopDate,
|
|
data: model.getDate(medication.stopDatetime.toString() ?? ''),
|
|
))
|
|
],
|
|
),
|
|
SizedBox(
|
|
height: 10,
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.status,
|
|
data: medication.status.toString() ?? '',
|
|
),
|
|
),
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.doctor,
|
|
data: medication.doctorName.toString() ?? '',
|
|
))
|
|
],
|
|
),
|
|
SizedBox(
|
|
height: 10,
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.authorizedBy,
|
|
data: medication.authorizedBy.toString() ?? '-',
|
|
),
|
|
),
|
|
Expanded(
|
|
child: InterventionDetails(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.pharmacyRemarks,
|
|
data: medication.pharmacyRemarks.toString() ?? '-',
|
|
))
|
|
],
|
|
),
|
|
SizedBox(
|
|
height: 10,
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class InterventionDetails extends StatelessWidget {
|
|
final String title;
|
|
final String data;
|
|
|
|
const InterventionDetails(
|
|
{super.key, required this.title, required this.data});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Column(
|
|
children: [
|
|
Text(
|
|
title,
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(
|
|
color: Colors.black,
|
|
fontWeight: FontWeight.w600,
|
|
fontSize: 13,
|
|
),
|
|
),
|
|
SizedBox(
|
|
height: 8,
|
|
),
|
|
Text(
|
|
data,
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(
|
|
color: Colors.grey,
|
|
fontWeight: FontWeight.w400,
|
|
fontSize: 12,
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class InterventionHistoryBottomSheet extends StatelessWidget {
|
|
final List<InterventionHistory> interventionList;
|
|
final ScrollController controller;
|
|
|
|
const InterventionHistoryBottomSheet(
|
|
{super.key, required this.interventionList, required this.controller});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Material(
|
|
color: Color(0xFFF7F7F7),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(20), topRight: Radius.circular(20))),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 20.0, vertical: 32),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
AppText(
|
|
TranslationBase
|
|
.of(context)
|
|
.histories,
|
|
fontWeight: FontWeight.w700,
|
|
fontSize: 24,
|
|
color: Color(0xFF2B353E),
|
|
),
|
|
SizedBox(
|
|
height: 16,
|
|
),
|
|
Expanded(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Expanded(
|
|
child: ListView.separated(
|
|
shrinkWrap: true,
|
|
controller: controller,
|
|
itemCount: interventionList.length,
|
|
itemBuilder: (context, index) =>
|
|
Material(
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(10)),
|
|
color: Colors.white,
|
|
child: InterventionHistoryItem(
|
|
interventionHistory: interventionList[index],
|
|
),
|
|
),
|
|
separatorBuilder: (_, __) => Divider(),
|
|
))
|
|
],
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class InterventionHistoryItem extends StatelessWidget {
|
|
final InterventionHistory interventionHistory;
|
|
|
|
const InterventionHistoryItem({super.key, required this.interventionHistory});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
AppText(
|
|
interventionHistory.commentedByName ?? '',
|
|
fontWeight: FontWeight.w600,
|
|
fontSize: 12,
|
|
color: Color(0xFF2B353E),
|
|
),
|
|
SizedBox(
|
|
height: 4,
|
|
),
|
|
AppText(
|
|
"${TranslationBase
|
|
.of(context)
|
|
.remarks}: ${interventionHistory.remark?.isNotEmpty == true
|
|
? interventionHistory.remark
|
|
: TranslationBase
|
|
.of(context)
|
|
.noRemarks}",
|
|
fontWeight: FontWeight.w600,
|
|
fontSize: 12,
|
|
color: Color(0xFF2B353E),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class TableCell extends StatelessWidget {
|
|
final String text;
|
|
|
|
const TableCell(this.text, {super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
width: 150, // Adjust column width
|
|
padding: const EdgeInsets.all(8.0),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(color: Colors.black),
|
|
),
|
|
child: Text(text),
|
|
);
|
|
}
|
|
}
|
|
|
|
class TableHeaderCell extends StatelessWidget {
|
|
final String text;
|
|
|
|
const TableHeaderCell(this.text, {super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
width: 150, // Adjust column width
|
|
padding: const EdgeInsets.all(8.0),
|
|
decoration: BoxDecoration(
|
|
color: Colors.grey[300],
|
|
border: Border.all(color: Colors.black),
|
|
),
|
|
child: Text(
|
|
text,
|
|
style: const TextStyle(fontWeight: FontWeight.bold),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class DataTable extends StatelessWidget {
|
|
int? _rowCount = 100;
|
|
int? _columnCount = 100;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: TableView.builder(
|
|
cellBuilder: _buildCell,
|
|
columnCount: _columnCount,
|
|
columnBuilder: _buildColumn,
|
|
rowCount: _rowCount,
|
|
rowBuilder: _buildRowSpan,
|
|
pinnedRowCount: 1,
|
|
diagonalDragBehavior: DiagonalDragBehavior.free,
|
|
verticalDetails: ScrollableDetails.vertical(
|
|
controller: ScrollController(),
|
|
physics: BouncingScrollPhysics(),
|
|
),
|
|
horizontalDetails: ScrollableDetails.horizontal(
|
|
controller: ScrollController(),
|
|
physics: BouncingScrollPhysics(),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
TableViewCell _buildCell(BuildContext context, TableVicinity vicinity) {
|
|
final Color boxColor =
|
|
switch ((vicinity.row.isEven, vicinity.column.isEven)) {
|
|
(true, false) || (false, true) => Colors.white,
|
|
(false, false) => Colors.indigo[100]!,
|
|
(true, true) => Colors.indigo[200]!
|
|
};
|
|
return TableViewCell(
|
|
child: ColoredBox(
|
|
color: boxColor,
|
|
child: Center(
|
|
child: Text('${vicinity.column}:${vicinity.row}'),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
TableSpan _buildRowSpan(int index) {
|
|
return const TableSpan(
|
|
extent: MinSpanExtent(FixedSpanExtent(10), FixedSpanExtent(300)));
|
|
}
|
|
|
|
TableSpan _buildColumn(int index) {
|
|
return const TableSpan(
|
|
extent: MinSpanExtent(FixedSpanExtent(50), FixedSpanExtent(300)));
|
|
}
|
|
}
|
|
|
|
class TableExample extends StatefulWidget {
|
|
const TableExample({super.key, required this.model});
|
|
|
|
final PharmacyInterventionViewModel model;
|
|
|
|
@override
|
|
State<TableExample> createState() => _TableExampleState();
|
|
}
|
|
|
|
class _TableExampleState extends State<TableExample> {
|
|
late final ScrollController _verticalController = ScrollController();
|
|
int _rowCount = 0;
|
|
int _columnCount = 14;
|
|
final List<String> headersList = [];
|
|
|
|
@override
|
|
void dispose() {
|
|
_verticalController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
print('the length is ${widget.model.medicationList?.medication?.length}');
|
|
_rowCount = ((widget.model.medicationList?.medication?.length ?? 0) + 1);
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
body: TableView.builder(
|
|
verticalDetails: ScrollableDetails.vertical(
|
|
controller: _verticalController,
|
|
),
|
|
cellBuilder: _buildCell,
|
|
columnCount: _columnCount,
|
|
pinnedRowCount: 1,
|
|
columnBuilder: _buildColumnSpan,
|
|
rowCount: _rowCount,
|
|
rowBuilder: _buildRowSpan,
|
|
),
|
|
persistentFooterButtons: <Widget>[
|
|
TextButton(
|
|
onPressed: () {
|
|
_verticalController.jumpTo(0);
|
|
},
|
|
child: const Text('Jump to Top'),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
TableViewCell _buildCell(BuildContext context, TableVicinity vicinity) {
|
|
if (vicinity.row == 0) {
|
|
var title = '';
|
|
switch (vicinity.column) {
|
|
case 0:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.accessLevel;
|
|
break;
|
|
case 1:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.patientID;
|
|
break;
|
|
case 2:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.patientName;
|
|
break;
|
|
case 3:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.nursingStation;
|
|
break;
|
|
case 4:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.admissionNumber;
|
|
break;
|
|
case 5:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.medication;
|
|
break;
|
|
case 6:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.dosageDetails;
|
|
break;
|
|
case 7:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.doctorComments;
|
|
break;
|
|
case 8:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.startDate;
|
|
break;
|
|
case 9:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.stopDate;
|
|
break;
|
|
case 10:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.status;
|
|
break;
|
|
case 11:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.doctor;
|
|
break;
|
|
case 12:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.authorizedBy;
|
|
break;
|
|
case 13:
|
|
title = TranslationBase
|
|
.of(context)
|
|
.pharmacyRemarks;
|
|
break;
|
|
}
|
|
|
|
return TableViewCell(
|
|
child: ColoredBox(
|
|
color: Colors.grey,
|
|
child: Center(
|
|
child: Text(title),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
return TableViewCell(
|
|
child: Center(
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(2.0),
|
|
child: Text(
|
|
widget.model.medicationList?.medication?[vicinity.row - 1]
|
|
.getValue(vicinity.column)
|
|
.toString() ??
|
|
'',
|
|
textAlign: TextAlign.center,
|
|
maxLines: 2,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
TableSpan _buildColumnSpan(int index) {
|
|
const TableSpanDecoration decoration = TableSpanDecoration(
|
|
border: TableSpanBorder(
|
|
trailing: BorderSide(),
|
|
),
|
|
);
|
|
|
|
switch (index) {
|
|
case 0:
|
|
return TableSpan(
|
|
foregroundDecoration: decoration,
|
|
extent: const FractionalTableSpanExtent(0.3),
|
|
onEnter: (_) => print('Entered column $index'),
|
|
cursor: SystemMouseCursors.contextMenu,
|
|
);
|
|
break;
|
|
case 1:
|
|
return TableSpan(
|
|
foregroundDecoration: decoration,
|
|
extent: const FractionalTableSpanExtent(0.4),
|
|
onEnter: (_) => print('Entered column $index'),
|
|
cursor: SystemMouseCursors.contextMenu,
|
|
);
|
|
break;
|
|
case 2:
|
|
return TableSpan(
|
|
foregroundDecoration: decoration,
|
|
extent: const FractionalTableSpanExtent(0.5),
|
|
onEnter: (_) => print('Entered column $index'),
|
|
cursor: SystemMouseCursors.contextMenu,
|
|
);
|
|
break;
|
|
case 3:
|
|
return TableSpan(
|
|
foregroundDecoration: decoration,
|
|
extent: const FractionalTableSpanExtent(0.4),
|
|
onEnter: (_) => print('Entered column $index'),
|
|
cursor: SystemMouseCursors.contextMenu,
|
|
);
|
|
break;
|
|
case 4:
|
|
return TableSpan(
|
|
foregroundDecoration: decoration,
|
|
extent: const FractionalTableSpanExtent(0.5),
|
|
onEnter: (_) => print('Entered column $index'),
|
|
cursor: SystemMouseCursors.contextMenu,
|
|
);
|
|
break;
|
|
case 5:
|
|
return TableSpan(
|
|
foregroundDecoration: decoration,
|
|
extent: const FractionalTableSpanExtent(0.7),
|
|
onEnter: (_) => print('Entered column $index'),
|
|
cursor: SystemMouseCursors.contextMenu,
|
|
);
|
|
break;
|
|
case 6:
|
|
return TableSpan(
|
|
foregroundDecoration: decoration,
|
|
extent: const FractionalTableSpanExtent(0.7),
|
|
onEnter: (_) => print('Entered column $index'),
|
|
cursor: SystemMouseCursors.contextMenu,
|
|
);
|
|
break;
|
|
case 7:
|
|
return TableSpan(
|
|
foregroundDecoration: decoration,
|
|
extent: const FractionalTableSpanExtent(0.8),
|
|
onEnter: (_) => print('Entered column $index'),
|
|
cursor: SystemMouseCursors.contextMenu,
|
|
);
|
|
break;
|
|
case 8:
|
|
case 9:
|
|
case 10:
|
|
return TableSpan(
|
|
foregroundDecoration: decoration,
|
|
extent: const FractionalTableSpanExtent(0.4),
|
|
onEnter: (_) => print('Entered column $index'),
|
|
cursor: SystemMouseCursors.contextMenu,
|
|
);
|
|
case 11:
|
|
case 12:
|
|
return TableSpan(
|
|
foregroundDecoration: decoration,
|
|
extent: const FractionalTableSpanExtent(0.6),
|
|
onEnter: (_) => print('Entered column $index'),
|
|
cursor: SystemMouseCursors.contextMenu,
|
|
);
|
|
case 13:
|
|
return TableSpan(
|
|
foregroundDecoration: decoration,
|
|
extent: const FractionalTableSpanExtent(0.7),
|
|
onEnter: (_) => print('Entered column $index'),
|
|
cursor: SystemMouseCursors.contextMenu,
|
|
);
|
|
break;
|
|
}
|
|
// switch (index % 5) {
|
|
// case 0:
|
|
// return TableSpan(
|
|
// foregroundDecoration: decoration,
|
|
// extent: const FixedTableSpanExtent(100),
|
|
// onEnter: (_) => print('Entered column $index'),
|
|
// recognizerFactories: <Type, GestureRecognizerFactory>{
|
|
// TapGestureRecognizer:
|
|
// GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
|
|
// () => TapGestureRecognizer(),
|
|
// (TapGestureRecognizer t) =>
|
|
// t.onTap = () => print('Tap column $index'),
|
|
// ),
|
|
// },
|
|
// );
|
|
// case 1:
|
|
// return TableSpan(
|
|
// foregroundDecoration: decoration,
|
|
// extent: const FractionalTableSpanExtent(0.5),
|
|
// onEnter: (_) => print('Entered column $index'),
|
|
// cursor: SystemMouseCursors.contextMenu,
|
|
// );
|
|
// case 2:
|
|
// return TableSpan(
|
|
// foregroundDecoration: decoration,
|
|
// extent: const FixedTableSpanExtent(140),
|
|
// onEnter: (_) => print('Entered column $index'),
|
|
// );
|
|
// case 3:
|
|
// return TableSpan(
|
|
// foregroundDecoration: decoration,
|
|
// extent: const FixedTableSpanExtent(200),
|
|
// onEnter: (_) => print('Entered column $index'),
|
|
// );
|
|
// case 4:
|
|
// return TableSpan(
|
|
// foregroundDecoration: decoration,
|
|
// extent: const FixedTableSpanExtent(200),
|
|
// onEnter: (_) => print('Entered column $index'),
|
|
// );
|
|
// }
|
|
throw AssertionError(
|
|
'This should be unreachable, as every index is accounted for in the '
|
|
'switch clauses.',
|
|
);
|
|
}
|
|
|
|
TableSpan _buildRowSpan(int index) {
|
|
final TableSpanDecoration decoration = TableSpanDecoration(
|
|
border: const TableSpanBorder(
|
|
trailing: BorderSide(
|
|
width: 1,
|
|
),
|
|
),
|
|
);
|
|
if (index == 0) {
|
|
TableSpan(
|
|
backgroundDecoration: decoration,
|
|
extent: const FixedTableSpanExtent(30),
|
|
recognizerFactories: <Type, GestureRecognizerFactory>{
|
|
TapGestureRecognizer:
|
|
GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
|
|
() => TapGestureRecognizer(),
|
|
(TapGestureRecognizer t) =>
|
|
t.onTap = () => print('Tap row $index'),
|
|
),
|
|
},
|
|
);
|
|
}
|
|
return TableSpan(
|
|
backgroundDecoration: decoration,
|
|
extent: const FixedTableSpanExtent(65),
|
|
cursor: SystemMouseCursors.click,
|
|
);
|
|
// switch (index) {
|
|
// case 0:
|
|
// return TableSpan(
|
|
// backgroundDecoration: decoration,
|
|
// extent: const FixedTableSpanExtent(30),
|
|
// recognizerFactories: <Type, GestureRecognizerFactory>{
|
|
// TapGestureRecognizer:
|
|
// GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
|
|
// () => TapGestureRecognizer(),
|
|
// (TapGestureRecognizer t) =>
|
|
// t.onTap = () => print('Tap row $index'),
|
|
// ),
|
|
// },
|
|
// );
|
|
// case 1:
|
|
// return TableSpan(
|
|
// backgroundDecoration: decoration,
|
|
// extent: const FixedTableSpanExtent(65),
|
|
// cursor: SystemMouseCursors.click,
|
|
// );
|
|
// case 2:
|
|
// return TableSpan(
|
|
// backgroundDecoration: decoration,
|
|
// extent: const FractionalTableSpanExtent(0.15),
|
|
// );
|
|
// }
|
|
throw AssertionError(
|
|
'This should be unreachable, as every index is accounted for in the '
|
|
'switch clauses.',
|
|
);
|
|
}
|
|
}
|
|
|
|
class PharmacyInterventionDialog extends StatefulWidget {
|
|
final Function(
|
|
String,
|
|
String,
|
|
String,
|
|
String,
|
|
) onDispose;
|
|
|
|
const PharmacyInterventionDialog({super.key, required this.onDispose});
|
|
|
|
@override
|
|
State<PharmacyInterventionDialog> createState() =>
|
|
_PharmacyInterventionDialogState();
|
|
}
|
|
|
|
class _PharmacyInterventionDialogState
|
|
extends State<PharmacyInterventionDialog> {
|
|
final TextEditingController admissionNumber = TextEditingController();
|
|
final TextEditingController nursingStation = TextEditingController();
|
|
|
|
final TextEditingController patientId = TextEditingController();
|
|
|
|
String dateFrom = '';
|
|
|
|
String dateTo = '';
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
// initFromDate();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Dialog(
|
|
backgroundColor: Colors.white,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(24),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
_titleAndTextField(TranslationBase
|
|
.of(context)
|
|
.nursingStation,
|
|
nursingStation, TextInputType.number),
|
|
SizedBox(
|
|
height: 4,
|
|
),
|
|
_titleAndTextField(TranslationBase
|
|
.of(context)
|
|
.admissionNumber,
|
|
admissionNumber, TextInputType.number),
|
|
SizedBox(
|
|
height: 4,
|
|
),
|
|
_titleAndTextField(TranslationBase
|
|
.of(context)
|
|
.patientID, patientId,
|
|
TextInputType.number),
|
|
SizedBox(
|
|
height: 4,
|
|
),
|
|
_dateSelection(TranslationBase
|
|
.of(context)
|
|
.dateFrom, (date) {
|
|
setState(() {
|
|
dateFrom = date;
|
|
});
|
|
}, dateFrom),
|
|
SizedBox(
|
|
height: 4,
|
|
),
|
|
_dateSelection(TranslationBase
|
|
.of(context)
|
|
.dateTo, (date) {
|
|
setState(() {
|
|
dateTo = date;
|
|
});
|
|
}, dateTo),
|
|
SizedBox(
|
|
height: 8,
|
|
),
|
|
Row(children: [
|
|
Expanded(
|
|
child: AppButton(
|
|
title: TranslationBase
|
|
.of(context)
|
|
.search,
|
|
hasBorder: true,
|
|
borderColor: Color(0xFFB8382B),
|
|
color: AppGlobal.appRedColor,
|
|
fontColor: Colors.white,
|
|
onPressed: () async {},
|
|
),
|
|
),
|
|
]),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _dateSelection(String title, Function(String) onDateSelected,
|
|
String selectedDate) {
|
|
return GestureDetector(
|
|
onTap: () => _selectDate(onDateSelected),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text(title),
|
|
Expanded(
|
|
child: ListTile(
|
|
title: Text(
|
|
selectedDate,
|
|
),
|
|
trailing: Icon(Icons.arrow_drop_down_outlined),
|
|
),
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Future _selectDate(Function(String) updateDate) async {
|
|
final DateTime? picked = await showDatePicker(
|
|
context: context,
|
|
initialDate: DateTime.now(),
|
|
firstDate: DateTime(DateTime
|
|
.now()
|
|
.year - 150),
|
|
lastDate: DateTime(DateTime
|
|
.now()
|
|
.year + 150),
|
|
initialEntryMode: DatePickerEntryMode.calendar,
|
|
builder: (_, child) {
|
|
return Theme(
|
|
data: ThemeData.light().copyWith(
|
|
colorScheme: ColorScheme.fromSwatch(
|
|
primarySwatch: Colors.red,
|
|
accentColor: AppGlobal.appRedColor,
|
|
),
|
|
dialogBackgroundColor: Colors.white,
|
|
),
|
|
child: child!,
|
|
);
|
|
});
|
|
if (picked != null) {
|
|
updateDate(getFormattedDate(picked));
|
|
}
|
|
// }
|
|
}
|
|
|
|
Widget _titleAndTextField(String title, TextEditingController controller,
|
|
TextInputType? inputType) {
|
|
return Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text(title),
|
|
Expanded(
|
|
child: TextFormField(
|
|
keyboardType: inputType,
|
|
decoration: InputDecoration(
|
|
hintText: '',
|
|
focusedBorder: InputBorder.none,
|
|
enabledBorder: InputBorder.none,
|
|
contentPadding: EdgeInsetsDirectional.only(start: 10.0),
|
|
),
|
|
textAlign: TextAlign.end,
|
|
controller: controller,
|
|
),
|
|
)
|
|
],
|
|
);
|
|
}
|
|
|
|
void initFromDate() {
|
|
var time = DateTime.now();
|
|
dateFrom = getFormattedDate(time);
|
|
}
|
|
|
|
String getFormattedDate(DateTime time) {
|
|
return DateFormat('MM/dd/yyyy').format(time);
|
|
}
|
|
}
|