From 0a3a1715a1530a37bba63db7542489f8823b7ace Mon Sep 17 00:00:00 2001 From: Fabian Date: Tue, 20 Feb 2024 21:16:48 +0100 Subject: [PATCH] Slider low and high text in frontend --- .../elements/feedback/slider_feedback.dart | 48 +++++-- .../feedback/slider_feedback_result.dart | 129 ++++++++++-------- .../models/feedback/feedback_question.dart | 9 +- .../pages/feedback/attend_feedback_page.dart | 5 +- .../pages/feedback/feedback_result_page.dart | 5 +- 5 files changed, 121 insertions(+), 75 deletions(-) diff --git a/frontend/lib/components/elements/feedback/slider_feedback.dart b/frontend/lib/components/elements/feedback/slider_feedback.dart index 6e944fc3..e27ee7e8 100644 --- a/frontend/lib/components/elements/feedback/slider_feedback.dart +++ b/frontend/lib/components/elements/feedback/slider_feedback.dart @@ -1,11 +1,18 @@ import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; class SliderFeedback extends StatefulWidget { final int initialFeedback; + final String rangeLow; + final String rangeHigh; final ValueChanged onFeedbackChanged; const SliderFeedback( - {super.key, this.initialFeedback = 5, required this.onFeedbackChanged}); + {super.key, + this.initialFeedback = 5, + this.rangeLow = "0", + this.rangeHigh = "10", + required this.onFeedbackChanged}); @override State createState() => _SliderFeedbackState(); @@ -37,20 +44,31 @@ class _SliderFeedbackState extends State { } } - return Slider( - value: _feedback, - min: 0, - max: 10, - divisions: 10, - onChanged: (newFeedback) { - setState(() { - _feedback = newFeedback; - _hasChanged = true; - }); - widget.onFeedbackChanged(newFeedback.toInt()); - }, - activeColor: activeColor, - label: _feedback.toInt().toString(), + return Column( + children: [ + Slider( + value: _feedback, + min: 0, + max: 10, + divisions: 10, + onChanged: (newFeedback) { + setState(() { + _feedback = newFeedback; + _hasChanged = true; + }); + widget.onFeedbackChanged(newFeedback.toInt()); + }, + activeColor: activeColor, + label: _feedback.toInt().toString(), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(widget.rangeLow), + Text(widget.rangeHigh), + ], + ), + ], ); } } diff --git a/frontend/lib/components/elements/feedback/slider_feedback_result.dart b/frontend/lib/components/elements/feedback/slider_feedback_result.dart index e9839331..f77569fc 100644 --- a/frontend/lib/components/elements/feedback/slider_feedback_result.dart +++ b/frontend/lib/components/elements/feedback/slider_feedback_result.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; class SliderFeedbackResult extends StatefulWidget { final List results; + final String rangeLow; + final String rangeHigh; final double average; final int min; final int max; @@ -9,6 +11,8 @@ class SliderFeedbackResult extends StatefulWidget { const SliderFeedbackResult({ super.key, required this.results, + this.rangeLow = "0", + this.rangeHigh = "10", required this.average, required this.min, required this.max, @@ -71,64 +75,75 @@ class _SliderFeedbackResultState extends State { Widget build(BuildContext context) { final colors = Theme.of(context).colorScheme; - return LayoutBuilder( - builder: (BuildContext context, BoxConstraints constraints) { - double width = constraints.maxWidth; - double height = width / 4; - double innerWidth = constraints.maxWidth - height; - - return SizedBox( - width: width, - height: height, - child: Stack( - children: List.generate(_itemCount + 2, (index) { - // Horizontal line - if (index == 0) { - return Positioned( - left: height / 2, - top: height / 2 - 1, - child: Container( - width: innerWidth, - height: 2, - decoration: BoxDecoration( - color: colors.tertiary.withAlpha(48), - ), - ), - ); - } - // Average line - if (index == _itemCount + 1) { - return Positioned( - left: height / 2 + - (widget.average - _min) * innerWidth / (_max - _min), - top: 0, - child: Container( - width: 2, - height: height, - decoration: BoxDecoration( - color: colors.secondary, + return Column( + children: [ + LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + double width = constraints.maxWidth; + double height = width / 4; + double innerWidth = constraints.maxWidth - height; + + return SizedBox( + width: width, + height: height, + child: Stack( + children: List.generate(_itemCount + 2, (index) { + // Horizontal line + if (index == 0) { + return Positioned( + left: height / 2, + top: height / 2 - 1, + child: Container( + width: innerWidth, + height: 2, + decoration: BoxDecoration( + color: colors.tertiary.withAlpha(48), + ), + ), + ); + } + // Average line + if (index == _itemCount + 1) { + return Positioned( + left: height / 2 + + (widget.average - _min) * innerWidth / (_max - _min), + top: 0, + child: Container( + width: 2, + height: height, + decoration: BoxDecoration( + color: colors.secondary, + ), + ), + ); + } + index--; + var size = 10 + _normCounts[index] * (height - 10); + return Positioned( + left: + height / 2 + (index) * innerWidth / (_max - _min) - size / 2, + top: height / 2 - size / 2, + child: Container( + width: size, + height: size, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: colors.primary.withOpacity(0.4), + ), ), - ), - ); - } - index--; - var size = 10 + _normCounts[index] * (height - 10); - return Positioned( - left: - height / 2 + (index) * innerWidth / (_max - _min) - size / 2, - top: height / 2 - size / 2, - child: Container( - width: size, - height: size, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: colors.primary.withOpacity(0.4), - ), - ), - ); - }), + ); + }), + ), + ); + }), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(widget.rangeLow), + Text(widget.rangeHigh), + ], ), - ); - }); + ], + ); } } diff --git a/frontend/lib/models/feedback/feedback_question.dart b/frontend/lib/models/feedback/feedback_question.dart index e1671aed..00a5132a 100644 --- a/frontend/lib/models/feedback/feedback_question.dart +++ b/frontend/lib/models/feedback/feedback_question.dart @@ -2,12 +2,17 @@ import 'package:frontend/models/question.dart'; class FeedbackQuestion extends Question { + final String rangeLow; + final String rangeHigh; + FeedbackQuestion( {required super.id, required super.name, required super.description, required super.type, - required super.options}); + required super.options, + required this.rangeLow, + required this.rangeHigh}); factory FeedbackQuestion.fromJson(Map json) { return FeedbackQuestion( @@ -16,6 +21,8 @@ class FeedbackQuestion extends Question { description: json['description'], type: json['type'], options: json['options'].cast(), + rangeLow: json['rangeLow'] ?? "0", + rangeHigh: json['rangeHigh'] ?? "10", ); } } diff --git a/frontend/lib/pages/feedback/attend_feedback_page.dart b/frontend/lib/pages/feedback/attend_feedback_page.dart index d8f5442f..f05b390a 100644 --- a/frontend/lib/pages/feedback/attend_feedback_page.dart +++ b/frontend/lib/pages/feedback/attend_feedback_page.dart @@ -6,6 +6,7 @@ import 'package:frontend/components/elements/feedback/slider_feedback.dart'; import 'package:frontend/components/elements/feedback/star_feedback.dart'; import 'package:frontend/global.dart'; import 'package:frontend/models/feedback/feedback_form.dart'; +import 'package:frontend/models/feedback/feedback_question.dart'; import 'package:frontend/theme/assets.dart'; import 'package:frontend/utils.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; @@ -207,7 +208,7 @@ class _AttendFeedbackPageState extends State { physics: const NeverScrollableScrollPhysics(), itemCount: _form.questions.length, itemBuilder: (context, index) { - var element = _form.questions[index]; + final element = _form.questions[index] as FeedbackQuestion; return Padding( padding: const EdgeInsets.all(32.0), child: Column( @@ -230,6 +231,8 @@ class _AttendFeedbackPageState extends State { else if (element.type == 'SLIDER') SliderFeedback( initialFeedback: _feedbackValues[element.id], + rangeLow: element.rangeLow, + rangeHigh: element.rangeHigh, onFeedbackChanged: (newFeedback) { setState(() { _feedbackValues[element.id] = newFeedback; diff --git a/frontend/lib/pages/feedback/feedback_result_page.dart b/frontend/lib/pages/feedback/feedback_result_page.dart index aa904752..efd7c122 100644 --- a/frontend/lib/pages/feedback/feedback_result_page.dart +++ b/frontend/lib/pages/feedback/feedback_result_page.dart @@ -6,6 +6,7 @@ import 'package:frontend/components/elements/feedback/slider_feedback_result.dar import 'package:frontend/components/elements/feedback/star_feedback_result.dart'; import 'package:frontend/global.dart'; import 'package:frontend/models/feedback/feedback_form.dart'; +import 'package:frontend/models/feedback/feedback_question.dart'; import 'package:frontend/utils.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; import 'package:http/http.dart' as http; @@ -222,7 +223,7 @@ class _FeedbackResultPageState extends State { physics: const NeverScrollableScrollPhysics(), itemCount: _form.questions.length, itemBuilder: (context, index) { - final element = _form.questions[index]; + final element = _form.questions[index] as FeedbackQuestion; final double average = _results[index]["average"]; final roundAverage = (average * 100).round() / 100; final values = _results[index]["values"]; @@ -241,6 +242,8 @@ class _FeedbackResultPageState extends State { else if (element.type == 'SLIDER') SliderFeedbackResult( results: values, + rangeLow: element.rangeLow, + rangeHigh: element.rangeHigh, average: average, min: 0, max: 10,