diff --git a/runproof/lib/pages/camera_page.dart b/runproof/lib/pages/camera_page.dart index df2eb18..798f6d5 100644 --- a/runproof/lib/pages/camera_page.dart +++ b/runproof/lib/pages/camera_page.dart @@ -1,14 +1,350 @@ -// // import 'package:flutter/material.dart'; -// // import 'package:learning_input_image/learning_input_image.dart'; -// // import 'package:learning_text_recognition/learning_text_recognition.dart'; -// // import 'package:provider/provider.dart'; -// <<<<<<< Updated upstream -// // -// // import "package:gbg_varvet/widgets/drawer_widget.dart"; -// // -// ======= +import 'dart:async'; +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import "package:provider/provider.dart"; +import "package:gbg_varvet/utils/utils.dart"; +import 'package:gbg_varvet/widgets/drawer_widget.dart'; + +import 'package:flutter_scalable_ocr/text_recognizer_painter.dart'; + +import 'package:flutter/foundation.dart'; +import 'package:google_mlkit_text_recognition/google_mlkit_text_recognition.dart'; +import 'package:camera/camera.dart'; + +//Largely based on https://pub.dev/packages/flutter_scalable_ocr + +class CameraPage extends StatefulWidget { + const CameraPage({super.key}); + + final String title = 'Scan'; + + @override + State createState() => _CameraPageState(); +} + +class _CameraPageState extends State { + String text = ""; + final StreamController controller = StreamController(); + + void setText(value) { + controller.add(value); + } + + @override + void dispose() { + controller.close(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + var patientModel = context.watch(); + late String currentText; + + return Scaffold( + backgroundColor: const Color(0xFF1F4A7B), + drawer: const DrawerWidget(title: "RunProof"), + appBar: AppBar( + title: Image.asset('assets/images/runprooflogo.png', + fit: BoxFit.contain, height: 60), + backgroundColor: const Color.fromARGB(255, 142, 184, 223), + ), + body: Column( + children: [ + ScalableOCR( + paintboxCustom: Paint() + ..style = PaintingStyle.stroke + ..strokeWidth = 4.0 + ..color = const Color.fromARGB(153, 102, 160, 241), + boxLeftOff: 1, + boxBottomOff: 2, + boxRightOff: 15, + boxTopOff: 4, + boxHeight: MediaQuery.of(context).size.height / 1.5, + getRawData: (value) { + inspect(value); + }, + getScannedText: (value) { + setText(value); + }), + Center( + child: StreamBuilder( + stream: controller.stream, + builder: (BuildContext context, AsyncSnapshot snapshot) { + currentText = snapshot.data != null ? snapshot.data! : ""; + currentText = currentText.replaceAll(RegExp(r'[^0-9]'), ''); + return Result(text: currentText); + }, + )), + Center( + child: ElevatedButton( + onPressed: () { + patientModel.searchTerm = currentText; + Navigator.pop(context); + }, + child: const Text("Acceptera resultat", + style: TextStyle( + color: Colors.white, + fontSize: 20, + fontWeight: FontWeight.bold, + ))), + ), + ], + ), + ); + } +} + +class Result extends StatelessWidget { + const Result({ + Key? key, + required this.text, + }) : super(key: key); + + final String text; + + @override + Widget build(BuildContext context) { + return Container( + width: 300, + child: Row(children: [ + const Text( + "Nr: ", + textAlign: TextAlign.left, + style: TextStyle( + color: Colors.white, + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + Text( + "$text", + style: const TextStyle( + overflow: TextOverflow.ellipsis, + color: Colors.white, + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ) + ])); + } +} + +@override +class ScalableOCR extends StatefulWidget { + const ScalableOCR( + {Key? key, + this.boxLeftOff = 4, + this.boxRightOff = 4, + this.boxBottomOff = 2.7, + this.boxTopOff = 2.7, + this.boxHeight, + required this.getScannedText, + this.getRawData, + this.paintboxCustom}) + : super(key: key); + + /// Offset on recalculated image left + final double boxLeftOff; + + /// Offset on recalculated image bottom + final double boxBottomOff; + + /// Offset on recalculated image right + final double boxRightOff; + + /// Offset on recalculated image top + final double boxTopOff; + + /// Height of narowed image + final double? boxHeight; + + /// Function to get scanned text as a string + final Function getScannedText; -// // import "package:gbg_varvet/widgets/drawer_widget.dart"; + /// Get raw data from scanned image + final Function? getRawData; + + /// Narower box paint + final Paint? paintboxCustom; + + @override + ScalableOCRState createState() => ScalableOCRState(); +} + +class ScalableOCRState extends State { + final TextRecognizer _textRecognizer = TextRecognizer(); + final cameraPrev = GlobalKey(); + final thePainter = GlobalKey(); + + final bool _canProcess = true; + bool _isBusy = false; + bool converting = false; + CustomPaint? customPaint; + // String? _text; + CameraController? _controller; + late List _cameras; + double zoomLevel = 0.0, minZoomLevel = 0.0, maxZoomLevel = 10.0; + // Counting pointers (number of user fingers on screen) + final double _minAvailableZoom = 0.0; + final double _maxAvailableZoom = 10.0; + double _currentScale = 0.0; + double _baseScale = 0.0; + double maxWidth = 0; + double maxHeight = 0; + String convertingAmount = ""; + + @override + void initState() { + super.initState(); + startLiveFeed(); + } + + @override + void dispose() { + _stopLiveFeed(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + double sizeH = MediaQuery.of(context).size.height / 100; + return Padding( + padding: EdgeInsets.all(0), + child: SingleChildScrollView( + child: Column( + children: [ + _controller == null || + _controller?.value == null || + _controller?.value.isInitialized == false + ? Container( + width: MediaQuery.of(context).size.width, + height: sizeH * 19, + ) + : _liveFeedBody(), + SizedBox(height: sizeH * 2), + ], + ), + )); + } + + // Body of live camera stream + Widget _liveFeedBody() { + final CameraController? cameraController = _controller; + if (cameraController == null || !cameraController.value.isInitialized) { + return const Text('Tap a camera'); + } else { + const double previewAspectRatio = 1.1; + return SizedBox( + height: widget.boxHeight ?? MediaQuery.of(context).size.height / 5, + child: Stack( + alignment: Alignment.topCenter, + clipBehavior: Clip.none, + fit: StackFit.expand, + children: [ + Center( + child: SizedBox( + height: + widget.boxHeight ?? MediaQuery.of(context).size.height / 5, + key: cameraPrev, + child: AspectRatio( + aspectRatio: 1 / previewAspectRatio, + child: GestureDetector( + behavior: HitTestBehavior.translucent, + child: ClipRRect( + child: Transform.scale( + scale: cameraController.value.aspectRatio / + previewAspectRatio, + child: Center( + child: CameraPreview(cameraController, child: + LayoutBuilder(builder: (BuildContext context, + BoxConstraints constraints) { + maxWidth = constraints.maxWidth; + maxHeight = constraints.maxHeight; + + return GestureDetector( + behavior: HitTestBehavior.opaque, + onScaleStart: _handleScaleStart, + onScaleUpdate: _handleScaleUpdate, + onTapDown: (TapDownDetails details) => + onViewFinderTap(details, constraints), + ); + })), + ), + ), + ), + ), + ), + ), + ), + if (customPaint != null) + LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + maxWidth = constraints.maxWidth; + maxHeight = constraints.maxHeight; + return GestureDetector( + behavior: HitTestBehavior.opaque, + onScaleStart: _handleScaleStart, + onScaleUpdate: _handleScaleUpdate, + onTapDown: (TapDownDetails details) => + onViewFinderTap(details, constraints), + child: customPaint!, + ); + }), + ], + ), + ); + } + } + + // Start camera stream function + Future startLiveFeed() async { + _cameras = await availableCameras(); + _controller = CameraController(_cameras[0], ResolutionPreset.max); + final camera = _cameras[0]; + _controller = CameraController( + camera, + ResolutionPreset.high, + enableAudio: false, + ); + _controller?.initialize().then((_) { + if (!mounted) { + return; + } + _controller?.getMinZoomLevel().then((value) { + zoomLevel = value; + minZoomLevel = value; + }); + _controller?.getMaxZoomLevel().then((value) { + maxZoomLevel = value; + }); + _controller?.startImageStream(_processCameraImage); + setState(() {}); + }).catchError((Object e) { + if (e is CameraException) { + switch (e.code) { + case 'CameraAccessDenied': + log('User denied camera access.'); + break; + default: + log('Handle other errors.'); + break; + } + } + }); + } + + // Process image from camera stream + Future _processCameraImage(CameraImage image) async { + final WriteBuffer allBytes = WriteBuffer(); + for (final Plane plane in image.planes) { + allBytes.putUint8List(plane.bytes); + } + final bytes = allBytes.done().buffer.asUint8List(); + + final Size imageSize = + Size(image.width.toDouble(), image.height.toDouble()); // >>>>>>> Stashed changes // // class RecognitionTest extends StatelessWidget { @@ -37,148 +373,116 @@ // // // ======= -// >>>>>>> Stashed changes -// // class TextRecognitionPage extends StatefulWidget { -// // @override -// // _TextRecognitionPageState createState() => _TextRecognitionPageState(); -// // } -// <<<<<<< Updated upstream -// // -// // class _TextRecognitionPageState extends State { -// // TextRecognition? _textRecognition = TextRecognition(); -// // -// // /* TextRecognition? _textRecognition = TextRecognition( -// // options: TextRecognitionOptions.Japanese -// // ); */ -// // -// ======= + final inputImageFormat = + InputImageFormatValue.fromRawValue(image.format.raw); + if (inputImageFormat == null) return; -// // class _TextRecognitionPageState extends State { -// // TextRecognition? _textRecognition = TextRecognition(); + final planeData = image.planes.map( + (Plane plane) { + return InputImagePlaneMetadata( + bytesPerRow: plane.bytesPerRow, + height: plane.height, + width: plane.width, + ); + }, + ).toList(); -// // /* TextRecognition? _textRecognition = TextRecognition( -// // options: TextRecognitionOptions.Japanese -// // ); */ + final inputImageData = InputImageData( + size: imageSize, + imageRotation: imageRotation, + inputImageFormat: inputImageFormat, + planeData: planeData, + ); -// >>>>>>> Stashed changes -// // @override -// // void dispose() { -// // _textRecognition?.dispose(); -// // super.dispose(); -// // } -// <<<<<<< Updated upstream -// // -// // Future _startRecognition(InputImage image) async { -// // TextRecognitionState state = Provider.of(context, listen: false); -// // -// ======= + final inputImage = + InputImage.fromBytes(bytes: bytes, inputImageData: inputImageData); -// // Future _startRecognition(InputImage image) async { -// // TextRecognitionState state = Provider.of(context, listen: false); + processImage(inputImage); + } -// >>>>>>> Stashed changes -// // if (state.isNotProcessing) { -// // state.startProcessing(); -// // state.image = image; -// // state.data = await _textRecognition?.process(image); -// // state.stopProcessing(); -// // } -// // } -// <<<<<<< Updated upstream -// // -// ======= + // Scale image + void _handleScaleStart(ScaleStartDetails details) { + _baseScale = _currentScale; + } -// >>>>>>> Stashed changes -// // @override -// // Widget build(BuildContext context) { -// // return InputCameraView( -// // mode: InputCameraMode.gallery, -// // // resolutionPreset: ResolutionPreset.high, -// // title: 'Skanna löparnummer', -// // onImage: _startRecognition, -// // overlay: Consumer( -// // builder: (_, state, __) { -// // if (state.isNotEmpty) { -// // return Center( -// // child: Container( -// // padding: EdgeInsets.symmetric(vertical: 10, horizontal: 16), -// // decoration: BoxDecoration( -// // color: Colors.white.withOpacity(0.8), -// // borderRadius: BorderRadius.all(Radius.circular(4.0)), -// // ), -// // child: Text( -// // state.text, -// // style: TextStyle( -// // fontWeight: FontWeight.w500, -// // ), -// // ), -// // ), -// // ); -// // } -// <<<<<<< Updated upstream -// // -// ======= + // Handle scale update + Future _handleScaleUpdate(ScaleUpdateDetails details) async { + // When there are not exactly two fingers on screen don't scale + if (_controller == null) { + return; + } -// >>>>>>> Stashed changes -// // return Container(); -// // }, -// // ), -// // ); -// // } -// // } -// <<<<<<< Updated upstream -// // -// ======= + _currentScale = (_baseScale * details.scale) + .clamp(_minAvailableZoom, _maxAvailableZoom); -// >>>>>>> Stashed changes -// // class TextRecognitionState extends ChangeNotifier { -// // InputImage? _image; -// // RecognizedText? _data; -// // bool _isProcessing = false; -// <<<<<<< Updated upstream -// // -// ======= + await _controller!.setZoomLevel(_currentScale); + } -// >>>>>>> Stashed changes -// // InputImage? get image => _image; -// // RecognizedText? get data => _data; -// // String get text => _data!.text; -// // bool get isNotProcessing => !_isProcessing; -// // bool get isNotEmpty => _data != null && text.isNotEmpty; -// <<<<<<< Updated upstream -// // -// ======= + // Focus image + void onViewFinderTap(TapDownDetails details, BoxConstraints constraints) { + if (_controller == null) { + return; + } -// >>>>>>> Stashed changes -// // void startProcessing() { -// // _isProcessing = true; -// // notifyListeners(); -// // } -// <<<<<<< Updated upstream -// // -// ======= + final CameraController cameraController = _controller!; -// >>>>>>> Stashed changes -// // void stopProcessing() { -// // _isProcessing = false; -// // notifyListeners(); -// // } -// <<<<<<< Updated upstream -// // -// ======= + final Offset offset = Offset( + details.localPosition.dx / constraints.maxWidth, + details.localPosition.dy / constraints.maxHeight, + ); + cameraController.setExposurePoint(offset); + cameraController.setFocusPoint(offset); + } -// >>>>>>> Stashed changes -// // set image(InputImage? image) { -// // _image = image; -// // notifyListeners(); -// // } -// <<<<<<< Updated upstream -// // -// ======= + // Stop camera live stream + Future _stopLiveFeed() async { + await _controller?.stopImageStream(); + await _controller?.dispose(); + _controller = null; + } -// >>>>>>> Stashed changes -// // set data(RecognizedText? data) { -// // _data = data; -// // notifyListeners(); -// // } -// // } + // Process image + Future processImage(InputImage inputImage) async { + if (!_canProcess) return; + if (_isBusy) return; + _isBusy = true; + + final recognizedText = await _textRecognizer.processImage(inputImage); + if (inputImage.inputImageData?.size != null && + inputImage.inputImageData?.imageRotation != null && + cameraPrev.currentContext != null) { + final RenderBox renderBox = + cameraPrev.currentContext?.findRenderObject() as RenderBox; + + var painter = TextRecognizerPainter( + recognizedText, + inputImage.inputImageData!.size, + inputImage.inputImageData!.imageRotation, + renderBox, (value) { + widget.getScannedText(value); + }, getRawData: (value) { + if (widget.getRawData != null) { + widget.getRawData!(value); + } + }, + boxBottomOff: widget.boxBottomOff, + boxTopOff: widget.boxTopOff, + boxRightOff: widget.boxRightOff, + boxLeftOff: widget.boxRightOff, + paintboxCustom: widget.paintboxCustom); + + customPaint = CustomPaint(painter: painter); + } else { + customPaint = null; + } + Future.delayed(const Duration(milliseconds: 900)).then((value) { + if (!converting) { + _isBusy = false; + } + + if (mounted) { + setState(() {}); + } + }); + } +} diff --git a/runproof/lib/pages/choice_page.dart b/runproof/lib/pages/choice_page.dart new file mode 100644 index 0000000..40ab453 --- /dev/null +++ b/runproof/lib/pages/choice_page.dart @@ -0,0 +1,79 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import "package:gbg_varvet/pages/form_page.dart"; +import "package:gbg_varvet/utils/utils.dart"; +import "package:provider/provider.dart"; +import "package:gbg_varvet/pages/injury/injury_page.dart"; + +class ChoicePage extends StatelessWidget { + const ChoicePage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("hej"), + ), + body: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Center(child: Text("Vänligen välj en")), + const SizedBox( + height: 60, + ), + Center( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () { + var patientsModel = context.read(); + patientsModel.setAttribute("type", "injury"); + + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const InjuryPage())); + }, + style: ElevatedButton.styleFrom( + fixedSize: Size(MediaQuery.of(context).size.width * 0.4, + 60), // adjust button size based on screen width + // increase button size + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(20.0), // add rounded corners + ), + ), + child: const Text("Skada")), + SizedBox( + width: 16, + ), + ElevatedButton( + onPressed: () { + var patientsModel = context.read(); + patientsModel.setAttribute("type", "sickness"); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const FormPage())); + }, + style: ElevatedButton.styleFrom( + fixedSize: Size(MediaQuery.of(context).size.width * 0.4, + 60), // adjust button size based on screen width + // increase button size + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(20.0), // add rounded corners + ), + ), + child: const Text("Sjukdom"), + ) + ], + )), + ], + ), + ); + } +} diff --git a/runproof/lib/pages/diagnos_page.dart b/runproof/lib/pages/diagnos_page.dart new file mode 100644 index 0000000..c84f4c6 --- /dev/null +++ b/runproof/lib/pages/diagnos_page.dart @@ -0,0 +1,245 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:gbg_varvet/utils/utils.dart'; +import 'package:gbg_varvet/widgets/drawer_widget.dart'; +import 'package:flutter/services.dart'; +import 'package:gbg_varvet/pages/form_page_2.dart'; +import 'package:provider/provider.dart'; +import "package:gbg_varvet/utils/info_popup.dart"; +import 'package:gbg_varvet/widgets/design_widget.dart'; + +// TODO: kolla om detta sättet med state är ok, typ performance eller alternativa lösningar + +class DiagnosisPage extends StatefulWidget { + const DiagnosisPage({super.key}); + + @override + _DiagnosisPageState createState() => _DiagnosisPageState(); +} + +class CommaFormatter extends TextInputFormatter { + @override + TextEditingValue formatEditUpdate( + TextEditingValue oldValue, + TextEditingValue newValue, + ) { + String _text = newValue.text; + return newValue.copyWith( + text: _text.replaceAll('.', ','), + ); + } +} + +class _DiagnosisPageState extends State { + final _formKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + var patientsModel = context.watch(); + Map patient = patientsModel.activePatient; + print("$patient"); + bool eac = patient["eac"] ?? false; // svimnning eller kollaps + bool abdominalPain = patient["abdominalPain"] ?? false; + bool breathingProblems = patient["breathingProblems"] ?? false; + bool chestPain = patient["chestPain"] ?? false; + + + TextEditingController tempController = + TextEditingController(text: patient["temp"]); + + return Scaffold( + backgroundColor: const Color(0xFF1F4A7B), + drawer: DrawerWidget(title: "RunProof"), + appBar: AppBar( + title: Image.asset('assets/images/runprooflogo.png', + fit: BoxFit.contain, height: 60), + backgroundColor: Color.fromARGB(255, 142, 184, 223), + actions: [ + Row( + children: [ + Center( + child: ElevatedButton( + onPressed: () => SavePopup(context), + child: const Text("PAUSA"), + style: ElevatedButton.styleFrom( + shape: StadiumBorder(), + backgroundColor: Color.fromARGB(255, 108, 211, 92), + fixedSize: + Size(MediaQuery.of(context).size.width * 0.2, 20)), + )), + SizedBox( + width: MediaQuery.of(context).size.width * 0.1, + ) + ], + ), + ], + ), + body: Form( + key: _formKey, + child: ListView( + shrinkWrap: true, + children: [ + Padding( padding: const EdgeInsets.all(20), + + child: Center( + + child: TextTitle(text: "Diagnos",), + ),), + + Divider( + height: 10, + thickness: 2, + color: Colors.black, + indent: 20, + endIndent: 20, + ), + Center( + child: Column( + children: [ + + + CheckboxListTile( + title: const Text( + "Svimning", + style: TextStyle(fontSize: 20, color: Colors.white), + ), + autofocus: false, + selected: false, + value: eac, + onChanged: (bool? value) { + setState(() { + eac = value!; + patientsModel.setAttribute( + "eac", eac); + }); + }, + activeColor: Colors.green, + checkColor: Colors.white, + ), + CheckboxListTile( + title: const Text( + "Buksmärtor", + style: TextStyle(fontSize: 20, color: Colors.white), + ), + autofocus: false, + selected: false, + value: abdominalPain, + onChanged: (bool? value) { + setState(() { + abdominalPain = value!; + patientsModel.setAttribute( + "abdominalPain", abdominalPain); + }); + }, + activeColor: Colors.green, + checkColor: Colors.white, + ), + CheckboxListTile( + title: const Text( + "Andningssvår", + style: TextStyle(fontSize: 20, color: Colors.white), + ), + autofocus: false, + selected: false, + value: breathingProblems, + onChanged: (bool? value) { + setState(() { + breathingProblems = value!; + patientsModel.setAttribute( + "breathingProblems", breathingProblems); + }); + }, + activeColor: Colors.green, + checkColor: Colors.white, + ), + CheckboxListTile( + title: const Text( + "Bröstsmärtor", + style: TextStyle(fontSize: 20, color: Colors.white), + ), + autofocus: false, + selected: false, + value: chestPain, + onChanged: (bool? value) { + setState(() { + chestPain = value!; + patientsModel.setAttribute( + "chestPain", chestPain); + }); + }, + activeColor: Colors.green, + checkColor: Colors.white, + ), + + ], + ), + ), + + + Padding( + padding: EdgeInsets.only(left:20, top: 10, bottom: 1), + child: Text('Övrigt:', + style: + TextStyle(color: Colors.white, fontSize: 18))), + Center( + child: Padding( + padding: EdgeInsets.only( + top: 19.0, bottom: 1, left: 20, right: 20), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + TextFormField( + minLines: 1, + maxLines: 6, + keyboardType: TextInputType.multiline, + decoration: InputDecoration( + filled: true, + fillColor: Colors.white, + hintText: 'Förklaring ICD.', + hintStyle: TextStyle(color: Colors.grey), + border: OutlineInputBorder( + borderRadius: BorderRadius.all( + Radius.circular(20))))), + + ]))), + Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 80, top: 10), + child: SizedBox( + width: 100, + child: ElevatedButton( + onPressed: () => Navigator.pop(context), + style: ElevatedButton.styleFrom( + primary: Color.fromARGB(255, 165, 39, 75), + onPrimary: Colors.white), + child: const Text("TILLBAKA")), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 80, top: 10), + child: SizedBox( + width: 100, + child: ElevatedButton( + onPressed: () => { + if (_formKey.currentState!.validate()) + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + const DiagnosisPage())) + }, + style: ElevatedButton.styleFrom( + primary: Color.fromARGB(255, 108, 211, 92), + onPrimary: Colors.white), + child: const Text("NÄSTA"), + ), + )), + ], + ) + ], + ))); + } +} + diff --git a/runproof/lib/pages/form_page3.dart b/runproof/lib/pages/form_page3.dart index ad096cf..f0d4917 100644 --- a/runproof/lib/pages/form_page3.dart +++ b/runproof/lib/pages/form_page3.dart @@ -7,6 +7,7 @@ import 'package:gbg_varvet/pages/form_page_2.dart'; import 'package:gbg_varvet/pages/home_page.dart'; import 'package:provider/provider.dart'; import 'package:gbg_varvet/utils/utils.dart'; +import 'package:gbg_varvet/pages/diagnos_page.dart'; class FormPage3 extends StatefulWidget { const FormPage3({super.key}); @@ -21,11 +22,24 @@ class _FormPage3State extends State { bool isO2mask = false; //patient["isO2mask"]; //bool isNotO2mask = false; // patient["isNotO2mask"]; - - String dropdownvalue = '1'; + bool isO2grimma = false; + String dropdownvalue = '-'; + String dropdownvalue2 = '-'; // List of items in our dropdown menu var items = [ + '-', + '1', + '2', + '3', + '4', + '5', + '6', + '7', + '8', + ]; + var gcs = [ + '-', '1', '2', '3', @@ -40,6 +54,16 @@ class _FormPage3State extends State { @override Widget build(BuildContext context) { + var patientsModel = context.watch(); + Map activePatient = patientsModel.activePatient; + + final String datetime = activePatient.containsKey("startTime") + ? activePatient["startTime"] + : '${DateTime.now().hour} :${DateTime.now().minute}'; + + final TextEditingController datetimeController = + TextEditingController(text: datetime); + return Scaffold( //backgroundColor: // Color.fromARGB(255, 31, 74, 123), drawer: DrawerWidget(title: "RunProof"), @@ -50,20 +74,33 @@ class _FormPage3State extends State { ), body: ListView( children: [ + Center( + child: Text("Vitalparametrar", + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white, + fontSize: 40)), + ), + Divider( + height: 10, + thickness: 2, + color: Colors.black, + indent: 20, + endIndent: 20, + ), Center( child: TextFormField( textAlign: TextAlign.center, + controller: datetimeController, //minLines: 1, maxLines: 1, + style: TextStyle( + color: Colors.white, + fontSize: 35, + fontWeight: FontWeight.bold), keyboardType: TextInputType.number, decoration: InputDecoration( - filled: true, - //fillColor: Colors.white, - hintText: '${DateTime.now().hour} :${DateTime.now().minute}', - hintStyle: TextStyle( - color: Colors.white, - fontSize: 35, - fontWeight: FontWeight.bold), + filled: false, )), ), Padding( @@ -99,7 +136,7 @@ class _FormPage3State extends State { ), Divider( height: 10, - thickness: 2, + thickness: 1, color: Colors.black, indent: 20, endIndent: 20, @@ -368,6 +405,106 @@ class _FormPage3State extends State { ), ), ), + Center( + child: Padding( + padding: const EdgeInsets.only( + left: 15, + right: 15, + bottom: 15, + ), + child: Row( + children: [ + Text('GCS:', + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white, + fontSize: 20)), + Spacer(flex: 1), + Container( + padding: + EdgeInsets.only(top: 1, bottom: 1, left: 5, right: 5), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(20))), + child: DropdownButton( + // Initial Value + value: dropdownvalue2, + + // Down Arrow Icon + icon: const Icon(Icons.keyboard_arrow_down), + + // Array list of items + items: gcs.map((String gcs) { + return DropdownMenuItem( + value: gcs, + child: Text(gcs), + ); + }).toList(), + // After selecting the desired option,it will + // change button value to selected value + onChanged: (String? newValue) { + setState(() { + dropdownvalue2 = newValue!; + }); + }, + style: const TextStyle( + fontWeight: FontWeight.bold, + color: Colors.black, + fontSize: 20), + + dropdownColor: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(20)), + //underline: Container( + // height: 2, + // color: Colors.black, + //), + ), + ), + Spacer(flex: 2), + Text( + "O2 grimma:", + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white, + fontSize: 20), + ), + Spacer(flex: 1), + Transform.scale( + scale: 1.7, + child: Checkbox( + autofocus: false, + //selected: false, + value: isO2grimma, + onChanged: (bool? value) { + setState( + () { + isO2grimma = value!; // ? false : true; + + //patientsModel.setAttribute( + // "isNotO2mask", isO2mask); + }, + ); + }, + + activeColor: Colors.red, + checkColor: Colors.white, + //controlAffinity: ListTileControlAffinity + // .trailing, // <-- leading Checkbox + ), + ), + Spacer(flex: 1), + ], + ), + ), + ), + Text("PVK"), + Divider( + height: 10, + thickness: 1, + color: Colors.black, + indent: 20, + endIndent: 20, + ), Padding( padding: const EdgeInsets.only( top: 30, bottom: 15, left: 20.0, right: 20), @@ -376,10 +513,9 @@ class _FormPage3State extends State { Expanded( child: ElevatedButton( onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => const FormPage2())); + Navigator.pop( + context, + ); }, child: const Text("Back"), style: ElevatedButton.styleFrom( @@ -394,14 +530,20 @@ class _FormPage3State extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => const HomePage())); + builder: (context) => const DiagnosisPage())); }, - child: const Text("Home"), + child: const Text("NEXT"), style: ElevatedButton.styleFrom( backgroundColor: Colors.green, ), ), ), + ElevatedButton( + onPressed: () { + Navigator.push(context, + MaterialPageRoute(builder: (context) => FormPage3())); + }, + child: const Text("+")) ], ), ), diff --git a/runproof/lib/pages/home_page.dart b/runproof/lib/pages/home_page.dart index ad3256b..0354503 100644 --- a/runproof/lib/pages/home_page.dart +++ b/runproof/lib/pages/home_page.dart @@ -9,6 +9,8 @@ import 'package:gbg_varvet/pages/form_page.dart'; import 'package:gbg_varvet/utils/info_popup.dart'; import "package:gbg_varvet/widgets/drawer_widget.dart"; import "package:gbg_varvet/utils/utils.dart"; +import 'package:gbg_varvet/pages/camera_page.dart'; +import "package:gbg_varvet/widgets/add_patient.dart"; class HomePage extends StatefulWidget { const HomePage({super.key}); @@ -28,8 +30,6 @@ class _HomePageState extends State { // ?.getIdToken() // .then((value) => print(value)); - final searchController = TextEditingController(); - Future _showMyDialog() async { return showDialog( context: context, @@ -65,6 +65,9 @@ class _HomePageState extends State { @override Widget build(BuildContext context) { + var patientModel = context.watch(); + final searchController = + TextEditingController(text: patientModel.searchTerm); return Scaffold( backgroundColor: const Color(0xFF1F4A7B), appBar: AppBar( @@ -94,11 +97,16 @@ class _HomePageState extends State { ), ), floatingActionButton: FloatingActionButton( - child: Icon(Icons.camera_alt), onPressed: () {}), + child: Icon(Icons.camera_alt), + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const CameraPage()), + ); + }), floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, body: Center( child: ListView(shrinkWrap: true, children: [ - Center(child: Text(currentUser.email!)), const Center( child: Text( 'Ange löparnummer manuellt', @@ -131,6 +139,11 @@ class _HomePageState extends State { width: 150, child: ElevatedButton( onPressed: () { + // showDialog( + // context: context, + // builder: (BuildContext context) { + // return Dialog(child: AddNewPatient()); + // }); runnerInfoPopup(context, searchController.text); }, style: ElevatedButton.styleFrom( diff --git a/runproof/lib/pages/injury/injury_page.dart b/runproof/lib/pages/injury/injury_page.dart new file mode 100644 index 0000000..c22ac18 --- /dev/null +++ b/runproof/lib/pages/injury/injury_page.dart @@ -0,0 +1,331 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import 'package:gbg_varvet/utils/utils.dart'; +import 'package:gbg_varvet/widgets/drawer_widget.dart'; +import 'package:flutter/services.dart'; +import 'package:gbg_varvet/pages/form_page_2.dart'; +import 'package:provider/provider.dart'; +import "package:gbg_varvet/utils/info_popup.dart"; + +// TODO: kolla om detta sättet med state är ok, typ performance eller alternativa lösningar + +class InjuryPage extends StatefulWidget { + const InjuryPage({super.key}); + + @override + _InjuryPageState createState() => _InjuryPageState(); +} + +class CommaFormatter extends TextInputFormatter { + @override + TextEditingValue formatEditUpdate( + TextEditingValue oldValue, + TextEditingValue newValue, + ) { + String _text = newValue.text; + return newValue.copyWith( + text: _text.replaceAll('.', ','), + ); + } +} + +class _InjuryPageState extends State { + final _formKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + var patientsModel = context.watch(); + Map patient = patientsModel.activePatient; + print("$patient"); + bool chafe = patient["injury"]["chafe"] ?? false; // skavsår + bool sprain = patient["injury"]["sprain"] ?? false; + bool pain = patient["injury"]["pain"] ?? false; + bool cramp = patient["injury"]["cramp"] ?? false; + bool home = patient["injury"]["home"] ?? false; + bool hospital = patient["injury"]["hospital"] ?? false; + + TextEditingController tempController = + TextEditingController(text: patient["temp"]); + + return Scaffold( + backgroundColor: const Color(0xFF1F4A7B), + drawer: DrawerWidget(title: "RunProof"), + appBar: AppBar( + title: Image.asset('assets/images/runprooflogo.png', + fit: BoxFit.contain, height: 60), + backgroundColor: Color.fromARGB(255, 142, 184, 223), + actions: [ + Row( + children: [ + Center( + child: ElevatedButton( + onPressed: () => SavePopup(context), + child: const Text("PAUSA"), + style: ElevatedButton.styleFrom( + shape: StadiumBorder(), + backgroundColor: Color.fromARGB(255, 108, 211, 92), + fixedSize: + Size(MediaQuery.of(context).size.width * 0.2, 20)), + )), + SizedBox( + width: MediaQuery.of(context).size.width * 0.1, + ) + ], + ), + ], + ), + body: Form( + key: _formKey, + child: ListView( + shrinkWrap: true, + children: [ + Padding( + padding: const EdgeInsets.all(20), + child: Row( + children: const [ + Expanded( + child: Text('REGISTRERING AV SKADA', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 20, + fontWeight: FontWeight.bold, + ))), + ], + )), + Divider( + height: 10, + thickness: 2, + color: Colors.black, + indent: 20, + endIndent: 20, + ), + Center( + child: Padding( + padding: EdgeInsets.only(top: 10.0), + child: Text('TYP AV SKADA:', + style: TextStyle( + color: Colors.white, + fontSize: 25, + fontWeight: FontWeight.bold)))), + Padding( + padding: const EdgeInsets.only( + top: 15.0, bottom: 8, left: 50, right: 60), + child: Column( + children: [ + CheckboxListTile( + title: const Text( + "SKAVSÅR", + style: TextStyle(fontSize: 20, color: Colors.white), + ), + autofocus: false, + selected: false, + value: chafe, + onChanged: (bool? value) { + setState(() { + chafe = value!; + patientsModel.setAttribute( + "chafe", chafe, "injury"); + }); + }, + activeColor: Colors.green, + checkColor: Colors.white, + ), + CheckboxListTile( + title: const Text( + "STUKAD FOTLED", + style: TextStyle(fontSize: 20, color: Colors.white), + ), + autofocus: false, + selected: false, + value: sprain, + onChanged: (bool? value) { + setState(() { + sprain = value!; + patientsModel.setAttribute( + "sprain", sprain, "injury"); + }); + }, + activeColor: Colors.green, + checkColor: Colors.white, + ), + CheckboxListTile( + title: const Text( + "MUSKELVÄRK", + style: TextStyle(fontSize: 20, color: Colors.white), + ), + autofocus: false, + selected: false, + value: pain, + onChanged: (bool? value) { + setState(() { + pain = value!; + patientsModel.setAttribute("pain", pain, "injury"); + }); + }, + activeColor: Colors.green, + checkColor: Colors.white, + ), + CheckboxListTile( + title: const Text( + "KRAMP", + style: TextStyle(fontSize: 20, color: Colors.white), + ), + autofocus: false, + selected: false, + value: cramp, + onChanged: (bool? value) { + setState(() { + cramp = value!; + patientsModel.setAttribute( + "cramp", cramp, "injury"); + }); + }, + activeColor: Colors.green, + checkColor: Colors.white, + ), + ], + ), + ), + Divider( + height: 10, + thickness: 2, + color: Colors.black, + indent: 20, + endIndent: 20, + ), + Center( + child: Padding( + padding: EdgeInsets.only(top: 10.0, bottom: 10), + child: Text('FORTSÄTTER HEM', + style: TextStyle( + color: Colors.white, + fontSize: 25, + fontWeight: FontWeight.bold)))), + Column( + children: [ + Padding( + padding: const EdgeInsets.only(right: 45, left: 45), + child: Row( + children: [ + Expanded( + child: CheckboxListTile( + title: const Text( + "JA", + style: TextStyle(color: Colors.white), + ), + autofocus: false, + selected: false, + value: home, + onChanged: (bool? value) { + setState(() { + hospital = value! ? false : true; + home = value; + patientsModel.setAttribute( + "home", home, "injury"); + patientsModel.setAttribute( + "hospital", hospital, "injury"); + }); + }, + activeColor: Colors.green, + checkColor: Colors.white, + controlAffinity: ListTileControlAffinity.leading, + ), + ), + Expanded( + child: CheckboxListTile( + title: const Text( + "NEJ", + style: TextStyle(color: Colors.white), + ), + autofocus: false, + selected: false, + value: hospital, //isNotOver, + onChanged: (bool? value) { + setState(() { + home = value! ? false : true; + hospital = value; + patientsModel.setAttribute( + "home", home, "injury"); + patientsModel.setAttribute( + "hospital", hospital, "injury"); + }); + }, + activeColor: Colors.red, + checkColor: Colors.white, + controlAffinity: ListTileControlAffinity.leading, + ), + ), + ], + ), + ), + ], //Column children + ), + Center( + child: Padding( + padding: EdgeInsets.only(top: 10, bottom: 1), + child: Text('KOMMENTAR:', + style: + TextStyle(color: Colors.white, fontSize: 18)))), + Center( + child: Padding( + padding: EdgeInsets.only( + top: 19.0, bottom: 1, left: 15, right: 15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + TextFormField( + minLines: 4, + maxLines: 6, + keyboardType: TextInputType.multiline, + decoration: InputDecoration( + filled: true, + fillColor: Colors.white, + hintText: 'Skriv något här...', + hintStyle: TextStyle(color: Colors.grey), + border: OutlineInputBorder( + borderRadius: BorderRadius.all( + Radius.circular(20))))), + ]))), + Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 80, top: 10), + child: SizedBox( + width: 100, + child: ElevatedButton( + onPressed: () => Navigator.pop(context), + style: ElevatedButton.styleFrom( + primary: Color.fromARGB(255, 165, 39, 75), + onPrimary: Colors.white), + child: const Text("TILLBAKA")), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 80, top: 10), + child: SizedBox( + width: 100, + child: ElevatedButton( + onPressed: () => { + if (_formKey.currentState!.validate()) + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + const InjuryPage())) + }, + style: ElevatedButton.styleFrom( + primary: Color.fromARGB(255, 108, 211, 92), + onPrimary: Colors.white), + child: const Text("NÄSTA"), + ), + )), + ], + ) + ], + ))); + } +} diff --git a/runproof/lib/utils/info_popup.dart b/runproof/lib/utils/info_popup.dart index cfba256..1c3016d 100644 --- a/runproof/lib/utils/info_popup.dart +++ b/runproof/lib/utils/info_popup.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import "package:gbg_varvet/utils/db_functions.dart"; import "package:gbg_varvet/utils/utils.dart"; -import "package:gbg_varvet/pages/form_page.dart"; import 'package:provider/provider.dart'; +import "package:gbg_varvet/pages/choice_page.dart"; void errorPopup(BuildContext context, error) { showDialog( @@ -44,7 +44,7 @@ void runnerInfoPopup(BuildContext context, String searchNumber) { Padding(padding: EdgeInsets.all(7.0)), Row( children: [ - Icon(Icons.content_copy), + Icon(Icons.numbers), Expanded( child: Text( 'Löparnummer: $runningNumber', @@ -55,7 +55,18 @@ void runnerInfoPopup(BuildContext context, String searchNumber) { Padding(padding: EdgeInsets.all(7.0)), Row( children: [ - Icon(Icons.numbers), + Icon(Icons.person_outline), + Expanded( + child: Text( + 'Löparnummer: $runningNumber', + ), + ), + ], + ), + Padding(padding: EdgeInsets.all(7.0)), + Row( + children: [ + Icon(Icons.schedule), Expanded( child: Text( 'Name: $name', @@ -66,7 +77,7 @@ void runnerInfoPopup(BuildContext context, String searchNumber) { Padding(padding: EdgeInsets.all(7.0)), Row( children: [ - Icon(Icons.timer), + Icon(Icons.description), Expanded( child: Text( 'Personnummer: $idNumber', @@ -84,7 +95,7 @@ void runnerInfoPopup(BuildContext context, String searchNumber) { Navigator.push( context, MaterialPageRoute( - builder: (context) => const FormPage())); + builder: (context) => const ChoicePage())); Provider.of(context, listen: false) .addPatient( @@ -107,3 +118,72 @@ void runnerInfoPopup(BuildContext context, String searchNumber) { }) .catchError((error) => {print("$error"), errorPopup(context, error)}); } + +void SavePopup(BuildContext context) { + showDialog( + context: context, + builder: (BuildContext context) => AlertDialog( + backgroundColor: Color.fromARGB(255, 220, 237, 255), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), + insetPadding: EdgeInsets.symmetric( + horizontal: MediaQuery.of(context).size.width * 0.02), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: MediaQuery.of(context).size.width * 0.9, + height: MediaQuery.of(context).size.width * 0.3, + decoration: BoxDecoration( + color: Color.fromARGB(255, 31, 74, 123), + borderRadius: BorderRadius.circular(20)), + child: const Center( + child: Text( + "ÄR DU SÄKER PÅ ATT DU VILL SPARA & PAUSA?", + style: TextStyle(color: Colors.white), + textAlign: TextAlign.center, + )), + ), + Container( + margin: EdgeInsets.only(top: 20), + width: MediaQuery.of(context).size.width * 0.9, + height: MediaQuery.of(context).size.width * 0.5, + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(20)), + child: const Center( + child: Text( + "DU KAN ALLTID VÄLJA ATT SKANNA NUMMERLAPPEN IGEN OCH FORTSÄTTA VID SENARE TILLFÄLLE\n\nOBS!\n\nKOM IHÅG ATT AVSLUTA ÄRENDET OM PATIENTEN ÄR HELT KLAR", + style: TextStyle(color: Colors.black), + textAlign: TextAlign.center, + )), + ) + ], + ), + actions: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () => Navigator.pop(context), + child: const Text('NEJ'), + style: ElevatedButton.styleFrom( + fixedSize: Size(MediaQuery.of(context).size.width * 0.3, 20), + backgroundColor: Color.fromARGB(255, 87, 95, 110), + shape: const StadiumBorder()), + ), + const Padding(padding: EdgeInsets.all(20)), + ElevatedButton( + onPressed: () => + Navigator.of(context).popUntil((route) => route.isFirst), + child: const Text('SPARA'), + style: ElevatedButton.styleFrom( + fixedSize: Size(MediaQuery.of(context).size.width * 0.3, 20), + backgroundColor: Color.fromARGB(255, 108, 211, 92), + shape: const StadiumBorder()), + ), + ], + ), + ], + ), + ); +} diff --git a/runproof/lib/utils/utils.dart b/runproof/lib/utils/utils.dart index 59e2544..acb7ac3 100644 --- a/runproof/lib/utils/utils.dart +++ b/runproof/lib/utils/utils.dart @@ -8,6 +8,8 @@ import 'dart:convert'; class PatientsModel with ChangeNotifier { List _patientsList = []; + String _searchTerm = ""; + int activeFormPage = 0; PatientsModel() { _loadDataFromPrefs(); @@ -15,12 +17,21 @@ class PatientsModel with ChangeNotifier { int _activeIndex = 0; + String get searchTerm => _searchTerm; + + set searchTerm(searchTerm) { + _searchTerm = searchTerm; + notifyListeners(); + } + Map get activePatient => _patientsList[_activeIndex]; int get activeIndex => _activeIndex; - void setAttribute(String key, var attr) { - _patientsList[_activeIndex][key] = attr; + void setAttribute(String key, var attr, [String? nestedKey]) { + nestedKey == null + ? _patientsList[_activeIndex][key] = attr + : _patientsList[_activeIndex][nestedKey][key] = attr; notifyListeners(); _saveDataToPrefs(); } @@ -77,7 +88,8 @@ class PatientsModel with ChangeNotifier { Future _saveDataToPrefs() async { final prefs = await SharedPreferences.getInstance(); - final patientsJson = jsonEncode(_patientsList); + //final patientsJson = jsonEncode(_patientsList); + final patientsJson = json.encode(_patientsList); await prefs.setString('patients_list', patientsJson); } @@ -85,15 +97,9 @@ class PatientsModel with ChangeNotifier { // adding all attributes (keys) Map attributes = { - "isVal": false, - "isNotVal": false, - "isKon": false, - "isOko": false, - "isKra": false, - "isSal": false, - "isOver": false, - "isNotOver": false, - "temp": "", + "injury": {}, + "sickness": {}, + "filled_options": 0, }; _patientsList[_activeIndex].addAll(attributes); diff --git a/runproof/lib/widgets/add_patient.dart b/runproof/lib/widgets/add_patient.dart new file mode 100644 index 0000000..2530f5a --- /dev/null +++ b/runproof/lib/widgets/add_patient.dart @@ -0,0 +1,62 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; + +class AddNewPatient extends StatelessWidget { + const AddNewPatient({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding(padding: EdgeInsets.all(7.0)), + Row( + children: [ + Icon(Icons.numbers), + Expanded( + child: Text( + 'Löparnummer: ', + ), + ), + ], + ), + Padding(padding: EdgeInsets.all(7.0)), + Row( + children: [ + Icon(Icons.person_outline), + Expanded( + child: Text( + 'Löparnummer: ', + ), + ), + ], + ), + Padding(padding: EdgeInsets.all(7.0)), + Row( + children: [ + Icon(Icons.schedule), + Expanded( + child: Text( + 'Name: ', + ), + ), + ], + ), + Padding(padding: EdgeInsets.all(7.0)), + Row( + children: [ + Icon(Icons.description), + Expanded( + child: Text( + 'Personnummer: ', + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/runproof/lib/widgets/design_widget.dart b/runproof/lib/widgets/design_widget.dart new file mode 100644 index 0000000..88352f1 --- /dev/null +++ b/runproof/lib/widgets/design_widget.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; + + +class TextTitle extends StatelessWidget { + String text=""; + TextTitle({ + required this.text, + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Text(text, + style: const TextStyle( + color: Colors.white, + fontSize: 40, + fontWeight: FontWeight.bold, + )); + } +} + diff --git a/runproof/lib/widgets/drawer_widget.dart b/runproof/lib/widgets/drawer_widget.dart index 362712d..c0287ad 100644 --- a/runproof/lib/widgets/drawer_widget.dart +++ b/runproof/lib/widgets/drawer_widget.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:gbg_varvet/pages/injury/injury_page.dart'; import 'package:gbg_varvet/utils/utils.dart'; import 'package:provider/provider.dart'; import 'package:percent_indicator/percent_indicator.dart'; @@ -91,6 +92,7 @@ class DrawerWidget extends StatelessWidget { Expanded(child: _PatientsList()), Center( child: FloatingActionButton.extended( + heroTag: "test", extendedPadding: const EdgeInsets.all(20), onPressed: () => _showMyDialog(context), label: const Text('SIGN OUT'), @@ -142,9 +144,15 @@ class _PatientsList extends StatelessWidget { : null, onTap: () { patientsList.setActiveIndex(index); - Navigator.pop(context); - Navigator.push(context, - MaterialPageRoute(builder: (context) => const FormPage())); + Navigator.of(context).pop(); + Navigator.of(context).popUntil((route) => true); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + patientsList.activePatient["type"] == "sickness" + ? const FormPage() + : const InjuryPage())); }, ), );