272 lines
7.7 KiB
Dart
272 lines
7.7 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:routemaster/routemaster.dart';
|
|
|
|
import '../../Services/date_service.dart';
|
|
import '../Misc/InputFields/date_range_picker.dart';
|
|
|
|
/// Stellt die Inputfelder für die Verlaufsübersicht dar
|
|
class InputFields extends StatefulWidget {
|
|
/// Erstellt eine neue Instanz dieser Klasse
|
|
const InputFields({
|
|
super.key,
|
|
this.amountMax,
|
|
this.amountMin,
|
|
this.dateFrom,
|
|
this.dateTo,
|
|
this.name,
|
|
});
|
|
|
|
/// Der Name der Transaktion, nach der gesucht werden soll
|
|
final String? name;
|
|
|
|
/// Der Mindestbetrag der Transaktion, nach der gesucht werden soll
|
|
final double? amountMin;
|
|
|
|
/// Der Maximalbetrag der Transaktion, nach der gesucht werden soll
|
|
final double? amountMax;
|
|
|
|
/// Das Datum der Transaktionen, ab dem gestartet wurde
|
|
final DateTime? dateFrom;
|
|
|
|
///Das Datum der Transaktionen, bis zu welchen beendet wurde
|
|
final DateTime? dateTo;
|
|
|
|
@override
|
|
State<StatefulWidget> createState() => _InputFields();
|
|
}
|
|
|
|
class _InputFields extends State<InputFields> {
|
|
final TextEditingController _nameController = TextEditingController();
|
|
final TextEditingController _amountMinController = TextEditingController();
|
|
final TextEditingController _amountMaxController = TextEditingController();
|
|
final TextEditingController _dateTimeController = TextEditingController();
|
|
|
|
static const double _filterBreakpoint = 600;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
if (widget.name != null) {
|
|
_nameController.text = widget.name!;
|
|
}
|
|
|
|
if (widget.amountMin != null) {
|
|
_amountMinController.text = widget.amountMin!.toString();
|
|
}
|
|
|
|
if (widget.amountMax != null) {
|
|
_amountMaxController.text = widget.amountMax!.toString();
|
|
}
|
|
|
|
if (widget.dateFrom != null && widget.dateTo != null) {
|
|
final DateTimeRange dateTimeRange = DateTimeRange(
|
|
start: widget.dateFrom!,
|
|
end: widget.dateTo!,
|
|
);
|
|
|
|
_dateTimeController.text = DateService.dateTimeRangeToString(
|
|
dateTimeRange,
|
|
)!;
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_nameController.dispose();
|
|
_amountMinController.dispose();
|
|
_amountMaxController.dispose();
|
|
_dateTimeController.dispose();
|
|
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(final BuildContext context) {
|
|
final ThemeData theme = Theme.of(context);
|
|
|
|
return LayoutBuilder(
|
|
builder: (final context, final constraints) {
|
|
if (constraints.maxWidth < _filterBreakpoint) {
|
|
return _buildFilterButton(context, theme);
|
|
}
|
|
|
|
return _buildInlineFilters(theme);
|
|
},
|
|
);
|
|
}
|
|
|
|
Widget _buildInlineFilters(final ThemeData theme) => Row(
|
|
children: <Widget>[
|
|
Expanded(
|
|
child: TextField(
|
|
controller: _nameController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Name',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
onChanged: (_) => _updateUrl(),
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
child: TextField(
|
|
controller: _amountMinController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Min Betrag €',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
|
onChanged: (_) => _updateUrl(),
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
child: TextField(
|
|
controller: _amountMaxController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Max Betrag €',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
|
onChanged: (_) => _updateUrl(),
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
child: DateRangePicker(
|
|
controller: _dateTimeController,
|
|
onChanged: (_) => _updateUrl(),
|
|
decoration: InputDecoration(
|
|
labelText: 'Zeitraum',
|
|
border: const OutlineInputBorder(),
|
|
suffixIcon: Icon(
|
|
Icons.calendar_month,
|
|
color: theme.colorScheme.onSurface,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
IconButton(onPressed: _clear, icon: const Icon(Icons.clear)),
|
|
],
|
|
);
|
|
|
|
Widget _buildFilterButton(
|
|
final BuildContext context,
|
|
final ThemeData theme,
|
|
) => Align(
|
|
alignment: Alignment.centerLeft,
|
|
child: ElevatedButton.icon(
|
|
icon: const Icon(Icons.filter_alt),
|
|
label: const Text('Filter'),
|
|
onPressed: () => _openFilterDialog(context),
|
|
),
|
|
);
|
|
|
|
void _openFilterDialog(final BuildContext context) {
|
|
unawaited(
|
|
showDialog(
|
|
context: context,
|
|
builder: (final context) => AlertDialog(
|
|
title: const Text('Filter'),
|
|
content: SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
TextField(
|
|
controller: _nameController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Name',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
),
|
|
const SizedBox(height: 12),
|
|
TextField(
|
|
controller: _amountMinController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Min Betrag €',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
keyboardType: const TextInputType.numberWithOptions(
|
|
decimal: true,
|
|
),
|
|
),
|
|
const SizedBox(height: 12),
|
|
TextField(
|
|
controller: _amountMaxController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Max Betrag €',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
keyboardType: const TextInputType.numberWithOptions(
|
|
decimal: true,
|
|
),
|
|
),
|
|
const SizedBox(height: 12),
|
|
DateRangePicker(
|
|
controller: _dateTimeController,
|
|
onChanged: (_) {},
|
|
decoration: const InputDecoration(
|
|
labelText: 'Zeitraum',
|
|
border: OutlineInputBorder(),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () {
|
|
_clear();
|
|
Navigator.of(context).pop();
|
|
},
|
|
child: const Text('Zurücksetzen'),
|
|
),
|
|
ElevatedButton(
|
|
onPressed: () {
|
|
_updateUrl();
|
|
Navigator.of(context).pop();
|
|
},
|
|
child: const Text('Anwenden'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
void _clear() {
|
|
_nameController.clear();
|
|
_amountMinController.clear();
|
|
_amountMaxController.clear();
|
|
_dateTimeController.clear();
|
|
_updateUrl();
|
|
}
|
|
|
|
void _updateUrl() {
|
|
final params = <String, String>{
|
|
if (_nameController.text != '') 'name': _nameController.text,
|
|
if (_amountMinController.text != '')
|
|
'amountMin': _amountMinController.text,
|
|
if (_amountMaxController.text != '')
|
|
'amountMax': _amountMaxController.text,
|
|
};
|
|
|
|
if (_dateTimeController.text != '') {
|
|
final DateTimeRange<DateTime>? range = DateService.stringToDateTimeRange(
|
|
_dateTimeController.text,
|
|
);
|
|
|
|
if (range != null) {
|
|
params['dateFrom'] = range.start.toIso8601String();
|
|
params['dateTo'] = range.end.toIso8601String();
|
|
}
|
|
}
|
|
|
|
Routemaster.of(context).replace('/trend', queryParameters: params);
|
|
}
|
|
}
|