Merge branch 'feature/sleep-page' into 'main'

Feature/sleep page

See merge request Crondung/hsma_cpd!6
main
Parricc35 2023-02-21 19:40:05 +00:00
commit a5cd12d5cd
7 changed files with 258 additions and 21 deletions

View File

@ -1,10 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:smoke_cess_app/widgets/sleep_form.dart';
class SleepPage extends StatelessWidget { class SleepPage extends StatelessWidget {
const SleepPage({super.key}); const SleepPage({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return const Center(child: Text('Hier wird Schlafqualität abgefragt')); return const Center(child: SleepForm());
} }
} }

View File

@ -0,0 +1,39 @@
import 'package:flutter/material.dart';
class ElevatedCard extends StatelessWidget {
final Widget child;
final String title;
const ElevatedCard({
Key? key,
required this.child,
required this.title,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Card(
elevation: 4.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 8.0),
child,
],
),
),
);
}
}

View File

@ -12,7 +12,7 @@ class MoodForm extends StatefulWidget {
class _MoodFormState extends State<MoodForm> { class _MoodFormState extends State<MoodForm> {
final GlobalKey<FormState> _moodFormKey = GlobalKey<FormState>(); final GlobalKey<FormState> _moodFormKey = GlobalKey<FormState>();
MySlider slider = const MySlider(); MySlider slider = const MySlider('Bewerte deine Stimmung');
String _textInput = ""; String _textInput = "";
void submitForm() { void submitForm() {
@ -35,7 +35,7 @@ class _MoodFormState extends State<MoodForm> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
slider, slider,
MyTextFormField(onFormFieldSave), MyTextFormField('Beschreibe deine Stimmung', onFormFieldSave),
SubmitFormButton(submitForm) SubmitFormButton(submitForm)
], ],
)); ));

View File

@ -0,0 +1,89 @@
import 'package:flutter/material.dart';
import 'package:smoke_cess_app/widgets/elevated_card.dart';
import 'package:smoke_cess_app/widgets/slider.dart';
import 'package:smoke_cess_app/widgets/submit_form_button.dart';
import 'package:smoke_cess_app/widgets/text_formfield.dart';
import 'package:smoke_cess_app/widgets/timepicker.dart';
class SleepForm extends StatefulWidget {
const SleepForm({Key? key}) : super(key: key);
@override
State<SleepForm> createState() => _SleepFormState();
}
class _SleepFormState extends State<SleepForm> {
final GlobalKey<FormState> _sleepFormKey = GlobalKey<FormState>();
MySlider slider = const MySlider('');
String _textInput = "";
TimePicker sleepTimePicker = TimePicker(
const TimeOfDay(hour: 22, minute: 00),
);
TimePicker wakeUpTimePicker = TimePicker(
const TimeOfDay(hour: 8, minute: 00),
);
void submitForm() {
if (_sleepFormKey.currentState!.validate()) {
_sleepFormKey.currentState?.save(); //call every onSave Method
//TODO Businesslogik aufrufen!
print(_textInput);
print(slider.getSliderValue());
print('Eingeschlafen um: ${sleepTimePicker.getCurrentTime}');
_sleepFormKey.currentState?.reset();
}
}
void onFormFieldSave(String? newValue) => _textInput = newValue!;
@override
Widget build(BuildContext context) {
return Form(
key: _sleepFormKey,
child: Stack(
children: [
SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ElevatedCard(
title: 'Einschlafzeit',
child: sleepTimePicker,
),
const SizedBox(height: 16),
ElevatedCard(
title: 'Aufwachzeit',
child: wakeUpTimePicker,
),
const SizedBox(height: 16),
ElevatedCard(
title: 'Schlafbewertung',
child: slider,
),
const SizedBox(height: 16),
ElevatedCard(
title: 'Schlafbeschreibung',
child: MyTextFormField(
'Beschreibe deinen Schlaf', onFormFieldSave),
),
const SizedBox(
height: 80,
),
],
),
),
Positioned(
bottom: 0,
right: 0,
child: SizedBox(
width: 140,
height: 80,
child: SubmitFormButton(submitForm),
),
),
],
),
);
}
}

View File

@ -3,7 +3,8 @@ import 'package:flutter/material.dart';
double _currentSliderValue = 50; double _currentSliderValue = 50;
class MySlider extends StatefulWidget { class MySlider extends StatefulWidget {
const MySlider({super.key}); final String _title;
const MySlider(this._title, {Key? key}) : super(key: key);
@override @override
State<StatefulWidget> createState() => SliderState(); State<StatefulWidget> createState() => SliderState();
@ -14,24 +15,80 @@ class MySlider extends StatefulWidget {
} }
class SliderState extends State<MySlider> { class SliderState extends State<MySlider> {
TextEditingController _textFieldController = TextEditingController();
String? _errorText;
@override
void initState() {
super.initState();
_textFieldController.text = _currentSliderValue.toStringAsFixed(0);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Center(
children: [ child: Column(
const Text('Bewerte deine Stimmung'), mainAxisAlignment: MainAxisAlignment.center,
Row( children: [
mainAxisAlignment: MainAxisAlignment.center, Text(widget._title),
children: [ SizedBox(height: 16),
Slider( Row(
value: _currentSliderValue, mainAxisAlignment: MainAxisAlignment.center,
max: 100, children: [
label: _currentSliderValue.round().toString(), Expanded(
onChanged: (double value) => child: Slider(
{setState((() => _currentSliderValue = value))}), value: _currentSliderValue,
Text(_currentSliderValue.round().toString()) min: 1,
], max: 100,
) divisions: 99,
], label: _currentSliderValue.round().toString(),
onChanged: (double value) {
setState(() {
_currentSliderValue = value;
_textFieldController.text = _currentSliderValue.toStringAsFixed(0);
_errorText = null;
});
},
),
),
SizedBox(width: 16),
SizedBox(
width: 100,
child: TextFormField(
controller: _textFieldController,
keyboardType: TextInputType.number,
decoration: InputDecoration(
labelText: 'Stimmung',
errorText: _errorText,
),
onChanged: (text) {
if (text.isEmpty) {
setState(() {
_currentSliderValue = 1;
_textFieldController.clear();
_errorText = null;
});
return;
}
final value = double.tryParse(text);
if (value == null || value < 1 || value > 100) {
setState(() {
_textFieldController.clear();
_errorText = 'Please enter a value between 1 and 100.';
});
return;
}
setState(() {
_currentSliderValue = value;
_errorText = null;
});
},
),
),
],
),
],
),
); );
} }
} }

View File

@ -1,8 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MyTextFormField extends StatelessWidget { class MyTextFormField extends StatelessWidget {
final String _description;
final Function(String?) onSaveAction; final Function(String?) onSaveAction;
const MyTextFormField( const MyTextFormField(
this._description,
this.onSaveAction, { this.onSaveAction, {
super.key, super.key,
}); });
@ -11,7 +13,7 @@ class MyTextFormField extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return TextFormField( return TextFormField(
onSaved: onSaveAction, onSaved: onSaveAction,
decoration: const InputDecoration(hintText: 'Beschreibe deine Stimmung?'), decoration: InputDecoration(hintText: _description),
validator: (String? value) => validator: (String? value) =>
value == null || value.isEmpty ? 'Text eingeben' : null, value == null || value.isEmpty ? 'Text eingeben' : null,
keyboardType: TextInputType.multiline, keyboardType: TextInputType.multiline,

View File

@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
class TimePicker extends StatefulWidget {
TimeOfDay _initialTime;
TimePicker(this._initialTime, {Key? key});
TimeOfDay get getCurrentTime => _initialTime;
@override
State<StatefulWidget> createState() => TimePickerState();
}
class TimePickerState extends State<TimePicker> {
TimePickerState();
@override
Widget build(BuildContext context) {
return Center(
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Text(
'${widget._initialTime.hour.toString().padLeft(2, '0')}:${widget._initialTime.minute.toString().padLeft(2, '0')}',
style: const TextStyle(fontSize: 22),
),
const SizedBox(width: 16),
ElevatedButton(
onPressed: () async {
//TODO auslagern
TimeOfDay? newTime = await showTimePicker(
context: context,
initialTime: widget._initialTime,
builder: (context, child) {
return MediaQuery(
data: MediaQuery.of(context)
.copyWith(alwaysUse24HourFormat: true),
child: child!,
);
},
);
if (newTime == null) return;
setState(() {
widget._initialTime = newTime;
});
},
child: const Text('Zeit einstellen'))
]),
);
}
}