Started formbuilder lib

This commit is contained in:
reinjens 2024-09-27 15:30:39 +02:00
parent 6c6cc35574
commit 395ec03a69
10 changed files with 386 additions and 37 deletions

View file

@ -28,6 +28,24 @@
"title": "Recherchieren Sie in allen Biodiversitätsmaßnahmen", "title": "Recherchieren Sie in allen Biodiversitätsmaßnahmen",
"intro": "In dieser Datenbank finden Sie die Maßnahmen, die zu Ihrem Betrieb und Ihrer Region passen." "intro": "In dieser Datenbank finden Sie die Maßnahmen, die zu Ihrem Betrieb und Ihrer Region passen."
} }
},
"general": {
"lists": {
"months": {
"1": "Januar",
"2": "Februar",
"3": "März",
"4": "April",
"5": "Mai",
"6": "Juni",
"7": "Juli",
"8": "August",
"9": "September",
"10": "Oktober",
"11": "November",
"12": "Dezember"
}
}
} }
} }

View file

View file

@ -0,0 +1,69 @@
extension DateHelpers on DateTime {
String nowString() {
return DateTime.now().toUtc().toIso8601String();
}
bool isToday() {
final now = DateTime.now();
return _isSameDay(this, now);
}
bool isYesterday() {
final yesterday = DateTime.now().subtract(const Duration(days: 1));
return _isSameDay(this, yesterday);
}
bool isTomorrow() {
final tomorrow = DateTime.now().add(const Duration(days: 1));
return _isSameDay(this, tomorrow);
}
bool isMorning() => hour > 3 && hour <= 12;
bool isAfternoon() => hour > 12 && hour <= 18;
bool isEvening() => (hour >= 0 && hour <= 3) || (hour > 18 && hour <= 23);
String getTimeOfDay() {
if (isMorning()) return 'morning';
if (isAfternoon()) return 'afternoon';
return 'evening';
}
DateTime findFirstDateOfTheWeek() {
return subtract(Duration(days: weekday - 1));
}
DateTime findLastDateOfTheWeek() {
return add(Duration(days: DateTime.daysPerWeek - weekday));
}
String formatSeconds(int value) {
final hours = (value ~/ 3600).toString().padLeft(2, '0');
final minutes = ((value % 3600) ~/ 60).toString().padLeft(2, '0');
final seconds = (value % 60).toString().padLeft(2, '0');
return "$hours:$minutes:$seconds";
}
String formatMinutes(int value, {bool allowZero = false}) {
final hours = (value ~/ 3600).toString().padLeft(2, '0');
var minutes = ((value % 3600) ~/ 60).toString().padLeft(2, '0');
if (minutes == '00' && !allowZero) {
minutes = '01';
}
return "$hours:$minutes";
}
// Helper method to check if two dates are on the same day
bool _isSameDay(DateTime date1, DateTime date2) {
return date1.day == date2.day &&
date1.month == date2.month &&
date1.year == date2.year;
}
DateTime firstDayOfYear() {
return DateTime(year);
}
DateTime lastDayOfYear() {
return DateTime(year + 1, 1, 0);
}
}

View file

@ -1,6 +1,10 @@
import 'package:ambito/src/domain/entity/id_value_color/id_value_color.dart';
import 'package:ambito/src/domain/entity/massnahme/massnahme.dart'; import 'package:ambito/src/domain/entity/massnahme/massnahme.dart';
import 'package:ambito/src/packages/ambito_db/base_db.dart'; import 'package:ambito/src/packages/ambito_db/base_db.dart';
import 'package:ambito/src/widgets/form/dropdown_menu.dart'; import 'package:ambito/src/widgets/form/fields/field_daterangepicker.dart';
import 'package:ambito/src/widgets/form/fields/field_dropdown.dart';
import 'package:ambito/src/widgets/form/form_widget.dart';
import 'package:ambito/src/widgets/form/form_widget_type.dart';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:expandable_text/expandable_text.dart'; import 'package:expandable_text/expandable_text.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -32,6 +36,8 @@ class ActionsPageState extends State<ActionsPage> {
List<String> region = []; List<String> region = [];
String? filterSupport; String? filterSupport;
Set<String> support = {}; Set<String> support = {};
String? filterMonths;
Set<String> months = {};
@override @override
void initState() { void initState() {
@ -50,27 +56,34 @@ class ActionsPageState extends State<ActionsPage> {
Set<String> updatedTypes = {}; Set<String> updatedTypes = {};
Set<String> updatedAreaTypes = {}; Set<String> updatedAreaTypes = {};
Set<String> updatedSupports = {}; Set<String> updatedSupports = {};
Set<String> updatedMonths = {};
for (var massnahme in massnahmen) { for (var massnahme in massnahmen) {
if (massnahme.actionGroup != null) { if (massnahme.actionGroup != null) {
updatedTypes.add(massnahme.actionGroup!.value!); updatedTypes.add(massnahme.actionGroup!.value!);
} }
if (massnahme.factsheetAreaType != null) { if (massnahme.factsheetAreaType != null) {
for (var aType in massnahme.factsheetAreaType!) { for (IdValueColor aType in massnahme.factsheetAreaType!) {
updatedAreaTypes.add(aType.value!); updatedAreaTypes.add(aType.value!);
} }
} }
if (massnahme.fundingPrograms != null) { if (massnahme.fundingPrograms != null) {
for (var aType in massnahme.fundingPrograms!) { for (IdValueColor aType in massnahme.fundingPrograms!) {
updatedSupports.add(aType.value!); updatedSupports.add(aType.value!);
} }
} }
if (massnahme.timeFrame != null) {
for (IdValueColor tfType in massnahme.timeFrame!) {
updatedMonths.add(tfType.value!);
}
}
} }
setState(() { setState(() {
type.addAll(updatedTypes); type.addAll(updatedTypes);
areaType.addAll(updatedAreaTypes); areaType.addAll(updatedAreaTypes);
support.addAll(updatedSupports); support.addAll(updatedSupports);
months.addAll(updatedMonths.toList());
}); });
List<Widget> actionCards = massnahmen.map((massnahme) { List<Widget> actionCards = massnahmen.map((massnahme) {
@ -133,7 +146,100 @@ class ActionsPageState extends State<ActionsPage> {
} }
Widget getFilter(BuildContext context) { Widget getFilter(BuildContext context) {
return Row( List<FormWidgetField> fields = [];
fields.add(
FieldDropdown(
name: 'ort',
label: 'Ort der Maßnahme',
filterValue: filterAreaType,
onClear: () {
setState(() {
filterAreaType = null;
});
},
onSelected: ((String? value) {
setState(() {
filterAreaType = value;
});
}),
entries: areaType.toList(),
),
);
fields.add(
FieldDropdown(
name: 'art',
label: 'Art der Maßnahme',
filterValue: filterType,
onClear: () {
setState(() {
filterType = null;
});
},
onSelected: ((String? value) {
setState(() {
filterType = value;
});
}),
entries: type.toList(),
),
);
fields.add(
FieldDropdown(
name: 'support',
label: 'Förderprogramm',
filterValue: filterSupport,
onClear: () {
setState(() {
filterSupport = null;
});
},
onSelected: ((String? value) {
setState(() {
filterSupport = value;
});
}),
entries: support.toList(),
),
);
var monthsSorted = months.toList();
monthsSorted.sort((a, b) => a.toLowerCase().compareTo(b.toLowerCase()));
/*fields.add(
FieldDropdown(
name: 'months',
label: 'Beginn der Maßnahme',
filterValue: filterMonths,
onClear: () {
setState(() {
filterMonths = null;
});
},
onSelected: ((String? value) {
setState(() {
filterMonths = value;
});
}),
entries: monthsSorted,
),
);*/
fields.add(
FieldDaterangepicker(
name: 'months',
label: 'Beginn der Maßnahme',
filterValue: filterMonths,
onClear: () {},
onSelected: (String? value) {},
entries: months.toList(),
),
);
return FormWidget(type: FormWidgetType.vertical, fields: fields);
/*return Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
DropdownMenuWidget( DropdownMenuWidget(
@ -191,7 +297,7 @@ class ActionsPageState extends State<ActionsPage> {
entries: support.toList(), entries: support.toList(),
), ),
], ],
); );*/
} }
Widget getCard(BuildContext context, Massnahme massnahme) { Widget getCard(BuildContext context, Massnahme massnahme) {

View file

@ -0,0 +1,54 @@
import 'package:ambito/src/extensions/datetime_extensions.dart';
import 'package:ambito/src/widgets/form/form_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
class FieldDaterangepicker extends FormWidgetField {
FieldDaterangepicker(
{required this.name,
required this.label,
required this.filterValue,
required this.onClear,
required this.onSelected,
required this.entries});
final String name;
final String label;
final String? filterValue;
final VoidCallback onClear;
final void Function(String?) onSelected;
final List<String> entries;
FormBuilderField get() {
DateTime now = DateTime.now();
return FormBuilderDateRangePicker(
name: name,
firstDate: now.firstDayOfYear(),
lastDate: now.lastDayOfYear());
return FormBuilderDropdown<String>(
name: name,
initialValue: filterValue,
decoration: InputDecoration(
labelText: label,
prefix: IconButton(
icon: const Icon(Icons.cancel_outlined),
onPressed: onClear,
),
hintText: label,
),
onReset: onClear,
onChanged: onSelected,
items: entries
.map(
(entry) => DropdownMenuItem(
value: entry,
alignment: Alignment.centerLeft,
child: Text(entry),
),
)
.toList(),
);
}
}

View file

@ -0,0 +1,46 @@
import 'package:ambito/src/widgets/form/form_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
class FieldDropdown extends FormWidgetField {
FieldDropdown(
{required this.name,
required this.label,
required this.filterValue,
required this.onClear,
required this.onSelected,
required this.entries});
final String name;
final String label;
final String? filterValue;
final VoidCallback onClear;
final void Function(String?) onSelected;
final List<String> entries;
FormBuilderField get() {
return FormBuilderDropdown<String>(
name: name,
initialValue: filterValue,
decoration: InputDecoration(
labelText: label,
prefix: IconButton(
icon: const Icon(Icons.cancel_outlined),
onPressed: onClear,
),
hintText: label,
),
onReset: onClear,
onChanged: onSelected,
items: entries
.map(
(entry) => DropdownMenuItem(
value: entry,
alignment: Alignment.centerLeft,
child: Text(entry),
),
)
.toList(),
);
}
}

View file

@ -0,0 +1,33 @@
import 'package:ambito/src/widgets/form/form_widget_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
abstract class FormWidgetField {
FormBuilderField get() {
return FormBuilderTextField(name: '');
}
}
class FormWidget extends StatelessWidget {
FormWidget({super.key, required this.type, required this.fields});
final _formKey = GlobalKey<FormBuilderState>();
final FormWidgetType type;
final List<FormWidgetField> fields;
@override
Widget build(BuildContext context) {
return SizedBox(
child: FormBuilder(
key: _formKey,
child: (type == FormWidgetType.vertical)
? Column(
children: fields.map((element) => element.get()).toList(),
)
: Row(
children: fields.map((element) => element.get()).toList(),
),
));
}
}

View file

@ -0,0 +1 @@
enum FormWidgetType { vertical, horizontal }

View file

@ -5,18 +5,23 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: _fe_analyzer_shared name: _fe_analyzer_shared
sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "67.0.0" version: "72.0.0"
_macros:
dependency: transitive
description: dart
source: sdk
version: "0.3.2"
analyzer: analyzer:
dependency: transitive dependency: transitive
description: description:
name: analyzer name: analyzer
sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.4.1" version: "6.7.0"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -85,18 +90,18 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: build_runner name: build_runner
sha256: "644dc98a0f179b872f612d3eb627924b578897c629788e858157fa5e704ca0c7" sha256: dd09dd4e2b078992f42aac7f1a622f01882a8492fef08486b27ddde929c19f04
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.11" version: "2.4.12"
build_runner_core: build_runner_core:
dependency: transitive dependency: transitive
description: description:
name: build_runner_core name: build_runner_core
sha256: e3c79f69a64bdfcd8a776a3c28db4eb6e3fb5356d013ae5eb2e52007706d5dbe sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.3.1" version: "7.3.2"
built_collection: built_collection:
dependency: transitive dependency: transitive
description: description:
@ -221,10 +226,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: dart_style name: dart_style
sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.6" version: "2.3.7"
dio: dio:
dependency: transitive dependency: transitive
description: description:
@ -318,6 +323,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.0" version: "0.8.0"
flutter_form_builder:
dependency: "direct main"
description:
name: flutter_form_builder
sha256: b42ad8a9b3e8a629eb0fee8e4feaf7c2862fc40808ebf9f7ddc9da798e890136
url: "https://pub.dev"
source: hosted
version: "9.4.1"
flutter_i18n: flutter_i18n:
dependency: "direct main" dependency: "direct main"
description: description:
@ -561,18 +574,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker name: leak_tracker
sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.0.4" version: "10.0.5"
leak_tracker_flutter_testing: leak_tracker_flutter_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_flutter_testing name: leak_tracker_flutter_testing
sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.3" version: "3.0.5"
leak_tracker_testing: leak_tracker_testing:
dependency: transitive dependency: transitive
description: description:
@ -613,6 +626,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
macros:
dependency: transitive
description:
name: macros
sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
url: "https://pub.dev"
source: hosted
version: "0.1.2-main.4"
maps_toolkit: maps_toolkit:
dependency: "direct main" dependency: "direct main"
description: description:
@ -633,18 +654,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.0" version: "0.11.1"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.12.0" version: "1.15.0"
mgrs_dart: mgrs_dart:
dependency: transitive dependency: transitive
description: description:
@ -926,10 +947,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: sqflite_common name: sqflite_common
sha256: "3da423ce7baf868be70e2c0976c28a1bb2f73644268b7ffa7d2e08eab71f16a4" sha256: "4058172e418eb7e7f2058dcb7657d451a8fc264afa0dea4dbd0f304a57131611"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.5.4" version: "2.5.4+3"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -966,10 +987,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: synchronized name: synchronized
sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558" sha256: "51b08572b9f091f8c3eb4d9d4be253f196ff0075d5ec9b10a884026d5b55d7bc"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.0+1" version: "3.3.0+2"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
@ -982,10 +1003,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.0" version: "0.7.2"
timing: timing:
dependency: transitive dependency: transitive
description: description:
@ -1022,10 +1043,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: uuid name: uuid
sha256: f33d6bb662f0e4f79dcd7ada2e6170f3b3a2530c28fc41f49a411ddedd576a77 sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.5.0" version: "4.5.1"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@ -1038,10 +1059,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vm_service name: vm_service
sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.2.1" version: "14.2.5"
watcher: watcher:
dependency: transitive dependency: transitive
description: description:
@ -1054,10 +1075,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: web name: web
sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0" version: "1.1.0"
web_socket: web_socket:
dependency: transitive dependency: transitive
description: description:
@ -1115,5 +1136,5 @@ packages:
source: hosted source: hosted
version: "3.1.2" version: "3.1.2"
sdks: sdks:
dart: ">=3.4.4 <4.0.0" dart: ">=3.5.0 <4.0.0"
flutter: ">=3.22.0" flutter: ">=3.24.0"

View file

@ -37,6 +37,7 @@ dependencies:
path_provider: ^2.1.4 path_provider: ^2.1.4
cached_network_image: ^3.4.1 cached_network_image: ^3.4.1
http: ^1.2.2 http: ^1.2.2
flutter_form_builder: ^9.4.1
dev_dependencies: dev_dependencies: