Stand 2024-11-18

This commit is contained in:
Jens Reinemuth 2024-11-18 15:19:07 +01:00
parent efa2ed6f5b
commit f3d53c90e5
92 changed files with 565 additions and 273 deletions

2
.env
View file

@ -1,2 +0,0 @@
BASEROW_TOKEN="TFxO7vzBLVRCu9I3VMoHmTuCvSu8aCDi"
BASEROW_IDS='{"measure": 328253,"measure_combination": 328217, "organism": 328255, "funding_program": 328256, "factsheet": 328273, "location_requirements": 328188, "reference_implementation": 328465, "business": 328472, "experience_report": 330802, "approval_requirement": 330806, "service_provider": 330824, "service_provider_contact_person": 330832, "material": 330836, "source": 334231, "tree_type": 342622, "aenderungfactsheet": 330946}'

View file

@ -1,2 +0,0 @@
BASEROWTOKEN='ENTER_THE_TOKEN_HERE'
BASEROW_IDS="{'massnahmen': 1, 'massnahmenkombination': 2, 'organismen': 3, 'foerderprogramme': 4, 'factsheet': 5, 'standortansprueche': 6, 'referenzumsetzung': 7, 'betriebsverzeichnis': 8, 'erfahrungsbericht': 9, 'genehmigungspflicht': 10, 'dienstleister': 11, 'ansprechperson': 12, 'material': 13, 'quellen': 14, 'baumarten': 15, 'aenderungfactsheet': 16,}"

1
assets/i18n Symbolic link
View file

@ -0,0 +1 @@
../i18n/

1
assets/images Symbolic link
View file

@ -0,0 +1 @@
../images/

View file

@ -83,6 +83,11 @@
"12": "Dezember" "12": "Dezember"
} }
} }
},
"fields": {
"measure": {
}
} }
} }

View file

Before

Width:  |  Height:  |  Size: 332 KiB

After

Width:  |  Height:  |  Size: 332 KiB

View file

Before

Width:  |  Height:  |  Size: 901 KiB

After

Width:  |  Height:  |  Size: 901 KiB

View file

Before

Width:  |  Height:  |  Size: 706 KiB

After

Width:  |  Height:  |  Size: 706 KiB

View file

Before

Width:  |  Height:  |  Size: 639 KiB

After

Width:  |  Height:  |  Size: 639 KiB

View file

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View file

Before

Width:  |  Height:  |  Size: 426 KiB

After

Width:  |  Height:  |  Size: 426 KiB

View file

Before

Width:  |  Height:  |  Size: 995 KiB

After

Width:  |  Height:  |  Size: 995 KiB

View file

Before

Width:  |  Height:  |  Size: 901 KiB

After

Width:  |  Height:  |  Size: 901 KiB

View file

Before

Width:  |  Height:  |  Size: 859 KiB

After

Width:  |  Height:  |  Size: 859 KiB

View file

Before

Width:  |  Height:  |  Size: 559 KiB

After

Width:  |  Height:  |  Size: 559 KiB

View file

Before

Width:  |  Height:  |  Size: 639 KiB

After

Width:  |  Height:  |  Size: 639 KiB

View file

Before

Width:  |  Height:  |  Size: 628 KiB

After

Width:  |  Height:  |  Size: 628 KiB

View file

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View file

Before

Width:  |  Height:  |  Size: 776 KiB

After

Width:  |  Height:  |  Size: 776 KiB

View file

Before

Width:  |  Height:  |  Size: 799 KiB

After

Width:  |  Height:  |  Size: 799 KiB

View file

Before

Width:  |  Height:  |  Size: 706 KiB

After

Width:  |  Height:  |  Size: 706 KiB

View file

Before

Width:  |  Height:  |  Size: 629 KiB

After

Width:  |  Height:  |  Size: 629 KiB

View file

Before

Width:  |  Height:  |  Size: 810 KiB

After

Width:  |  Height:  |  Size: 810 KiB

View file

Before

Width:  |  Height:  |  Size: 653 KiB

After

Width:  |  Height:  |  Size: 653 KiB

View file

Before

Width:  |  Height:  |  Size: 909 KiB

After

Width:  |  Height:  |  Size: 909 KiB

View file

Before

Width:  |  Height:  |  Size: 799 KiB

After

Width:  |  Height:  |  Size: 799 KiB

View file

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

View file

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -1,5 +1,6 @@
import 'package:ambito/src/packages/ambito_api/base_api.dart'; import 'package:ambito/src/packages/ambito_api/base_api.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/packages/ambito_notifier/notifier/theme_manager.dart';
import 'package:ambito/src/packages/ambito_sharedprefs/ambito_sharedprefs.dart'; import 'package:ambito/src/packages/ambito_sharedprefs/ambito_sharedprefs.dart';
import 'package:ambito/src/packages/ambito_theme/ambito_theme.dart'; import 'package:ambito/src/packages/ambito_theme/ambito_theme.dart';
import 'package:ambito/src/packages/ambito_theme/ambito_theme_large.dart'; import 'package:ambito/src/packages/ambito_theme/ambito_theme_large.dart';
@ -7,18 +8,19 @@ import 'package:ambito/src/packages/ambito_theme/ambito_theme_medium.dart';
import 'package:ambito/src/packages/ambito_theme/ambito_theme_small.dart'; import 'package:ambito/src/packages/ambito_theme/ambito_theme_small.dart';
import 'package:ambito/src/pages/actions/actions_page.dart'; import 'package:ambito/src/pages/actions/actions_page.dart';
import 'package:ambito/src/pages/actions/actions_pre_page.dart'; import 'package:ambito/src/pages/actions/actions_pre_page.dart';
import 'package:ambito/src/pages/actions/create/action_create_page.dart';
import 'package:ambito/src/pages/actions/detail/action_detail_page.dart'; import 'package:ambito/src/pages/actions/detail/action_detail_page.dart';
import 'package:ambito/src/pages/calendar/calendar_page.dart'; import 'package:ambito/src/pages/calendar/calendar_page.dart';
import 'package:ambito/src/pages/calendar/calendar_page_year.dart'; import 'package:ambito/src/pages/calendar/calendar_page_year.dart';
import 'package:ambito/src/pages/dashboard/dashboard_page.dart'; import 'package:ambito/src/pages/dashboard/dashboard_page.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_i18n/flutter_i18n.dart'; import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
import 'package:provider/provider.dart';
import 'package:screen_breakpoints/screen_breakpoints.dart'; import 'package:screen_breakpoints/screen_breakpoints.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:syncfusion_localizations/syncfusion_localizations.dart'; import 'package:syncfusion_localizations/syncfusion_localizations.dart';
@ -72,9 +74,29 @@ AmbitoTheme largeTheme = AmbitoThemeLarge();
AmbitoTheme mediumTheme = AmbitoThemeMedium(); AmbitoTheme mediumTheme = AmbitoThemeMedium();
AmbitoTheme smallTheme = AmbitoThemeSmall(); AmbitoTheme smallTheme = AmbitoThemeSmall();
const BASEROW_TOKEN = 'TFxO7vzBLVRCu9I3VMoHmTuCvSu8aCDi';
const BASEROW_IDS = {
"measure": 328253,
"measure_combination": 328217,
"organism": 328255,
"funding_program": 328256,
"factsheet": 328273,
"location_requirements": 328188,
"reference_implementation": 328465,
"business": 328472,
"experience_report": 330802,
"approval_requirement": 330806,
"service_provider": 330824,
"service_provider_contact_person": 330832,
"material": 330836,
"source": 334231,
"tree_type": 342622,
"aenderungfactsheet": 330946,
};
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await dotenv.load(fileName: '.env'); //await dotenv.load(fileName: '.env');
await AmbitoSharedPrefs.start(); await AmbitoSharedPrefs.start();
await AmbitoIsarDB.init(); await AmbitoIsarDB.init();
await Future.wait([ await Future.wait([
@ -105,7 +127,11 @@ class Ambito extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BreakpointConfigurator( return BreakpointConfigurator(
configuration: myBreakpoints, configuration: myBreakpoints,
child: GetMaterialApp( child: ChangeNotifierProvider(
create: (_) => ThemeManager(),
child: Consumer<ThemeManager>(
builder: (context, ThemeManager themeManager, child) {
return GetMaterialApp(
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
localizationsDelegates: [ localizationsDelegates: [
FlutterI18nDelegate( FlutterI18nDelegate(
@ -128,8 +154,8 @@ class Ambito extends StatelessWidget {
supportedLocales: const [Locale('de')], supportedLocales: const [Locale('de')],
locale: const Locale('de'), locale: const Locale('de'),
builder: FlutterI18n.rootAppBuilder(), builder: FlutterI18n.rootAppBuilder(),
theme: (getTheme(context)).lightThemeData, theme: ThemeManager().themeData?.lightThemeData,
darkTheme: (getTheme(context)).darkThemeData, darkTheme: ThemeManager().themeData?.darkThemeData,
themeMode: ThemeMode.light, themeMode: ThemeMode.light,
initialRoute: '/massnahmen', initialRoute: '/massnahmen',
getPages: [ getPages: [
@ -188,8 +214,15 @@ class Ambito extends StatelessWidget {
userId: 0, userId: 0,
), ),
), ),
GetPage(name: '/massnahme/:id', page: () => const ActionDetailPage()) GetPage(
name: '/massnahme/neu',
page: () => const ActionsCreatePage(),
),
GetPage(
name: '/massnahme/:id', page: () => const ActionDetailPage())
], ],
);
}),
), ),
); );
} }

View file

@ -6,7 +6,7 @@ import 'package:json_annotation/json_annotation.dart';
part 'measure.g.dart'; part 'measure.g.dart';
@JsonSerializable(explicitToJson: true) @JsonSerializable(explicitToJson: true, includeIfNull: true)
@collection @collection
class Measure extends BaseEntity with EntityWithId { class Measure extends BaseEntity with EntityWithId {
Measure(); Measure();
@ -160,6 +160,29 @@ extension MeasureExtension on Measure {
return image; return image;
} }
CachedNetworkImageProvider? getFullImageProvider() {
if (files != null && files!.isNotEmpty) {
if (files![0].url != null) {
return CachedNetworkImageProvider(files![0].url!);
}
}
}
CachedNetworkImage? getFullImage() {
CachedNetworkImage? image;
if (files != null && files!.isNotEmpty) {
if (files![0].url != null) {
image = CachedNetworkImage(
imageUrl: files![0].url!,
placeholder: (context, url) => const CircularProgressIndicator(),
errorWidget: (context, url, error) => const Icon(Icons.error),
fit: BoxFit.cover,
);
}
}
return image;
}
CachedNetworkImage? getImage() { CachedNetworkImage? getImage() {
CachedNetworkImage? image; CachedNetworkImage? image;
if (files != null && files!.isNotEmpty) { if (files != null && files!.isNotEmpty) {

View file

@ -10,6 +10,40 @@ class MeasureRepository extends BaseDB {
@override @override
IsarCollection collection = isar.measures; IsarCollection collection = isar.measures;
Future<bool> buildLists() async {
var measures = getAll();
Map<String, List<Map<String, IdValueColor>>> lists = {};
List<IsarPropertySchema> props = MeasureSchema.schema.properties;
for (var prop in props) {
if (prop.type == IsarType.objectList) {
lists[prop.name] = [];
}
}
logger.d(lists);
int counter = 0;
for (Measure measure in measures) {
var json = measure.toJson();
if (counter == 0) {
logger.d(json);
}
lists.forEach((key, value) {
if (counter == 0) {
logger.d(key);
}
if (json[key] != null) {
logger.d(json[key]);
}
});
counter++;
}
return true;
}
Future<bool> buildMeasureFilters() async { Future<bool> buildMeasureFilters() async {
Map<String, List<int>> filtersAreaType = {}; Map<String, List<int>> filtersAreaType = {};
Map<String, List<int>> filtersMeasureGroup = {}; Map<String, List<int>> filtersMeasureGroup = {};
@ -111,7 +145,6 @@ class MeasureRepository extends BaseDB {
} }
} }
} }
logger.d(files);
return true; return true;
} }
} }

View file

@ -2,8 +2,8 @@ import 'dart:convert';
import 'package:ambito/src/entity/entities.dart'; import 'package:ambito/src/entity/entities.dart';
import 'package:ambito/src/packages/ambito_api/restclient.dart'; import 'package:ambito/src/packages/ambito_api/restclient.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import '../../../main.dart';
import '../ambito_db/base_db.dart'; import '../ambito_db/base_db.dart';
class BaseApi { class BaseApi {
@ -11,7 +11,7 @@ class BaseApi {
init() { init() {
// read table ids from .env file... // read table ids from .env file...
tables = jsonDecode(dotenv.get('BASEROW_IDS')); tables = BASEROW_IDS;
} }
Future<bool> getContent(String table) async { Future<bool> getContent(String table) async {
@ -26,10 +26,6 @@ class BaseApi {
var json = _jsonDecoded(response.body); var json = _jsonDecoded(response.body);
//if (table == 'measure') {
// logger.d(json);
//}
var results = json['results']; var results = json['results'];
final repositoryMap = { final repositoryMap = {

View file

@ -4,7 +4,6 @@ import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:ambito/main.dart'; import 'package:ambito/main.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
class RestClient { class RestClient {
@ -20,7 +19,7 @@ class RestClient {
var headers = { var headers = {
"Content-Type": contentType, "Content-Type": contentType,
"Accept": accept, "Accept": accept,
"Authorization": "Token ${dotenv.get('BASEROW_TOKEN')}", "Authorization": "Token $BASEROW_TOKEN",
}; };
return headers; return headers;
} }

View file

@ -0,0 +1,112 @@
import 'package:ambito/src/entity/entities.dart';
import 'package:ambito/src/entity/measure/measure_repository.dart';
import 'package:ambito/src/extensions/extensions.dart';
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:isar/isar.dart';
import '../../../main.dart';
class AmbitoFormBuilder {
String type = '';
List<Widget> fields = [];
Widget init(BuildContext context, String dbType) {
MeasureRepository().buildLists();
switch (dbType) {
case 'Measure':
type = dbType.toLowerCase();
List<IsarPropertySchema> props = MeasureSchema.schema.properties;
for (var prop in props) {
switch (prop.type) {
case IsarType.bool:
fields.add(_getBoolInputField(context, prop.name));
break;
case IsarType.byte:
// TODO: Handle this case.
case IsarType.int:
// TODO: Handle this case.
case IsarType.float:
// TODO: Handle this case.
case IsarType.long:
// TODO: Handle this case.
case IsarType.double:
// TODO: Handle this case.
case IsarType.dateTime:
// TODO: Handle this case.
case IsarType.string:
fields.add(_getTextInputField(context, prop.name));
break;
case IsarType.object:
logger.d(prop.toJson());
logger.d(prop.target);
break;
case IsarType.json:
// TODO: Handle this case.
case IsarType.boolList:
// TODO: Handle this case.
case IsarType.byteList:
// TODO: Handle this case.
case IsarType.intList:
// TODO: Handle this case.
case IsarType.floatList:
// TODO: Handle this case.
case IsarType.longList:
// TODO: Handle this case.
case IsarType.doubleList:
// TODO: Handle this case.
case IsarType.dateTimeList:
// TODO: Handle this case.
case IsarType.stringList:
// TODO: Handle this case.
case IsarType.objectList:
//logger.d(prop.target);
break;
}
}
break;
}
return get();
}
Widget get() {
return FormBuilder(child: Column(children: fields));
}
_getField(BuildContext context, String type, String name) {}
_getTextInputField(BuildContext context, String name) {
return Padding(
padding: const EdgeInsets.only(bottom: 40),
child: FormBuilderTextField(
name: name,
decoration:
InputDecoration(labelText: context.translate('fields.$type.$name')),
obscureText: false,
),
);
}
_getBoolInputField(BuildContext context, String name) {
return Padding(
padding: const EdgeInsets.only(bottom: 40),
child: FormBuilderSwitch(
name: name,
title: Text(context.translate('fields.$type.$name')),
),
);
}
_getDropdownField(BuildContext context, String name) {
return Padding(
padding: const EdgeInsets.only(bottom: 40),
child: FormBuilderDropdown(
name: name,
decoration:
InputDecoration(labelText: context.translate('fields.$type.$name')),
items: [],
),
);
}
}

View file

@ -1,3 +1,4 @@
import 'package:ambito/src/packages/ambito_notifier/notifier/theme_manager.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:screen_breakpoints/screen_breakpoints.dart'; import 'package:screen_breakpoints/screen_breakpoints.dart';
@ -51,11 +52,14 @@ final actionAreaFGColors = {
AmbitoTheme getTheme(BuildContext context) { AmbitoTheme getTheme(BuildContext context) {
var breakpoint = context.breakpoint; var breakpoint = context.breakpoint;
if (breakpoint >= myBreakpoints.lg) { if (breakpoint >= myBreakpoints.lg) {
ThemeManager().setTheme(largeTheme);
return largeTheme; return largeTheme;
} }
if (breakpoint >= myBreakpoints.sm) { if (breakpoint >= myBreakpoints.sm) {
ThemeManager().setTheme(smallTheme);
return mediumTheme; return mediumTheme;
} }
ThemeManager().setTheme(mediumTheme);
return smallTheme; return smallTheme;
} }

View file

@ -28,13 +28,13 @@ class AmbitoThemeLarge extends AmbitoTheme {
letterSpacing: 0, letterSpacing: 0,
), ),
headlineMedium: GoogleFonts.openSans( headlineMedium: GoogleFonts.openSans(
fontSize: 28, fontSize: 40,
height: 1.29, height: 1.29,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
letterSpacing: 0, letterSpacing: 0,
), ),
headlineSmall: GoogleFonts.openSans( headlineSmall: GoogleFonts.openSans(
fontSize: 24, fontSize: 32,
height: 1.33, height: 1.33,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
letterSpacing: 0, letterSpacing: 0,

View file

@ -22,7 +22,7 @@ class AmbitoThemeMedium extends AmbitoTheme {
letterSpacing: 0, letterSpacing: 0,
), ),
headlineLarge: GoogleFonts.openSans( headlineLarge: GoogleFonts.openSans(
fontSize: 44, fontSize: 40,
height: 1.25, height: 1.25,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
letterSpacing: 0, letterSpacing: 0,

View file

@ -311,10 +311,10 @@ class ActionsPageState extends State<ActionsPage> {
return Visibility( return Visibility(
visible: visible[massnahme.id] ?? false, visible: visible[massnahme.id] ?? false,
child: InkWell( child: InkWell(
onHover: (hovered) {},
onTap: () async { onTap: () async {
Get.toNamed('/massnahme/${massnahme.id}'); Get.toNamed('/massnahme/${massnahme.id}');
}, },
onHover: (hovered) {},
highlightColor: Colors.transparent, highlightColor: Colors.transparent,
splashColor: Colors.transparent, splashColor: Colors.transparent,
focusColor: Colors.transparent, focusColor: Colors.transparent,

View file

@ -44,7 +44,11 @@ class ActionsPrePageState extends State<ActionsPrePage> {
setState(() {}); setState(() {});
}); });
}, },
onHover: (value) {}, onHover: (hovered) {},
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
focusColor: Colors.transparent,
hoverColor: Colors.transparent,
child: SizedBox( child: SizedBox(
width: 262, width: 262,
height: 380, height: 380,
@ -64,8 +68,7 @@ class ActionsPrePageState extends State<ActionsPrePage> {
padding: const EdgeInsets.only(left: 16, right: 16), padding: const EdgeInsets.only(left: 16, right: 16),
child: Text( child: Text(
filter.name!, filter.name!,
style: largeTheme style: largeTheme.currentThemeData.textTheme.labelMedium
.currentThemeData.textTheme.headlineMedium
?.copyWith( ?.copyWith(
color: actionAreaFGColors[filter.name!], color: actionAreaFGColors[filter.name!],
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@ -148,20 +151,26 @@ class ActionsPrePageState extends State<ActionsPrePage> {
children: cards, children: cards,
), ),
theme.verticalSpacerMax, theme.verticalSpacerMax,
TextButton( InkWell(
onPressed: () async { onHover: (hovered) {},
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
focusColor: Colors.transparent,
hoverColor: Colors.transparent,
onTap: () async {
await prefs.setString('selected_areaType', ''); await prefs.setString('selected_areaType', '');
await Get.toNamed('/massnahmendatenbank'); await Get.toNamed('/massnahmendatenbank');
}, },
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8)), borderRadius:
const BorderRadius.all(Radius.circular(8)),
color: color:
theme.currentColorScheme.onSurface.withOpacity(.1), theme.currentColorScheme.onSurface.withOpacity(.1),
), ),
width: Breakpoint.fromContext(context).width, width: Breakpoint.fromContext(context).width,
child: Padding( child: Padding(
padding: EdgeInsets.all(20), padding: const EdgeInsets.all(20),
child: Text( child: Text(
'Alle Maßnahmen anzeigen', 'Alle Maßnahmen anzeigen',
style: theme.headlineMedium.copyWith( style: theme.headlineMedium.copyWith(

View file

@ -0,0 +1,76 @@
import 'package:ambito/src/packages/ambito_formbuilder/ambito_formbuilder.dart';
import 'package:flutter/material.dart';
import 'package:screen_breakpoints/screen_breakpoints.dart';
import '../../../packages/ambito_theme/ambito_theme.dart';
import '../../../widgets/appbar/ambito_appbar.dart';
import '../../ambito_page.dart';
class ActionsCreatePage extends AmbitoPage {
const ActionsCreatePage({super.key});
@override
final String path = 'massnahmen';
@override
final String title = 'Maßnamen';
@override
State<StatefulWidget> createState() => ActionsCreatePageState();
}
class ActionsCreatePageState extends State<ActionsCreatePage> {
Widget form = const Center(
child: CircularProgressIndicator(),
);
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final AmbitoTheme theme = getTheme(context);
form = AmbitoFormBuilder().init(context, 'Measure');
return Scaffold(
appBar: AmbitoAppbar(
links: const ['dashboard', 'massnahmen'],
breakpoint: Breakpoint.fromContext(context),
),
body: BreakpointBuilder(builder: (
context,
breakpoint,
configuration,
) {
return SingleChildScrollView(
child: Center(
child: SizedBox(
width: Breakpoint.fromContext(context).width,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(breakpoint.toString()),
Text(theme.toString()),
theme.verticalSpacerMax,
Text(
'Neue Maßnahme anlegen',
textAlign: TextAlign.start,
style: theme.currentThemeData.textTheme.headlineLarge
?.copyWith(
color: theme.currentColorScheme.onSurface,
),
),
theme.verticalSpacerMax,
form,
],
),
),
),
);
}),
);
}
}

View file

@ -5,7 +5,7 @@ import 'package:flutter_breadcrumb/flutter_breadcrumb.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:screen_breakpoints/screen_breakpoints.dart'; import 'package:screen_breakpoints/screen_breakpoints.dart';
import '../../../../main.dart'; import '../../../packages/ambito_theme/ambito_theme.dart';
import '../../../widgets/appbar/ambito_appbar.dart'; import '../../../widgets/appbar/ambito_appbar.dart';
import '../../ambito_page.dart'; import '../../ambito_page.dart';
import 'cards/_cards.dart'; import 'cards/_cards.dart';
@ -35,60 +35,8 @@ class ActionDetailPageState extends State<ActionDetailPage> {
void initState() { void initState() {
id = Get.parameters['id'] ?? ''; id = Get.parameters['id'] ?? '';
if (id != '') { if (id != '') {
massnahme = MeasureRepository().get(int.parse(id)) as Measure;
setState(() { setState(() {
if (massnahme != null) { massnahme = MeasureRepository().get(int.parse(id)) as Measure;
contentItems = [
DescriptionCard(
massnahme: massnahme!,
),
largeTheme.verticalSpacer,
BackgroundCard(
massnahme: massnahme!,
),
largeTheme.verticalSpacer,
PresetsCard(
massnahme: massnahme!,
),
largeTheme.verticalSpacer,
BiodiverisityCard(
massnahme: massnahme!,
),
largeTheme.verticalSpacer,
CreationCard(
massnahme: massnahme!,
),
largeTheme.verticalSpacer,
MaintenanceCard(
massnahme: massnahme!,
),
largeTheme.verticalSpacer,
FundingCard(
massnahme: massnahme!,
),
largeTheme.verticalSpacer,
];
sidebarItems = [
AdvisorCard(
massnahme: massnahme!,
),
largeTheme.verticalSpacer,
MaterialCard(
massnahme: massnahme!,
),
largeTheme.verticalSpacer,
FactsheetCard(
massnahme: massnahme!,
),
largeTheme.verticalSpacer,
ReviewCard(
massnahme: massnahme!,
),
];
content = _buildInfoPage(massnahme!);
}
}); });
} }
@ -102,11 +50,18 @@ class ActionDetailPageState extends State<ActionDetailPage> {
links: const ['dashboard', 'massnahmen'], links: const ['dashboard', 'massnahmen'],
breakpoint: Breakpoint.fromContext(context), breakpoint: Breakpoint.fromContext(context),
), ),
body: content, body: _buildInfoPage(context, massnahme),
); );
} }
Widget _buildInfoPage(Measure massnahme) { Widget _buildInfoPage(BuildContext context, Measure? massnahme) {
final AmbitoTheme theme = getTheme(context);
if (massnahme == null) {
return const Center(
child: CircularProgressIndicator(),
);
}
return Column( return Column(
children: [ children: [
Align( Align(
@ -118,7 +73,10 @@ class ActionDetailPageState extends State<ActionDetailPage> {
onPressed: () { onPressed: () {
Get.offAndToNamed('/'); Get.offAndToNamed('/');
}, },
child: const Text('Start'), child: Text(
'Start',
style: theme.bodyMedium,
),
), ),
), ),
BreadCrumbItem( BreadCrumbItem(
@ -126,7 +84,10 @@ class ActionDetailPageState extends State<ActionDetailPage> {
onPressed: () { onPressed: () {
Get.offAndToNamed('/massnahmendatenbank'); Get.offAndToNamed('/massnahmendatenbank');
}, },
child: const Text('Massnahmen'), child: Text(
'Massnahmen',
style: theme.bodyMedium,
),
), ),
), ),
BreadCrumbItem( BreadCrumbItem(
@ -138,38 +99,62 @@ class ActionDetailPageState extends State<ActionDetailPage> {
divider: const Icon(Icons.chevron_right), divider: const Icon(Icons.chevron_right),
), ),
), ),
Container( SizedBox(
width: double.infinity, width: double.infinity,
height: 400, height: 300,
color: largeTheme.currentColorScheme.primary, child: massnahme.getFullImage(),
child: massnahme.getImage(),
), ),
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
child: SizedBox(
width: 1152,
child: Column( child: Column(
children: [ children: [
largeTheme.verticalSpacer, theme.verticalSpacer,
Align( Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Text( child: Text(
massnahme.name!, massnahme.name!,
style: largeTheme.currentThemeData.textTheme.titleLarge, style: theme.currentThemeData.textTheme.headlineMedium,
), ),
), ),
theme.verticalSpacer,
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded( Expanded(
child: SingleChildScrollView( child: Column(children: [
child: ListView.builder( DescriptionCard(
shrinkWrap: true, massnahme: massnahme!,
itemCount: contentItems.length,
itemBuilder: (BuildContext context, int index) {
return contentItems[index];
}),
), ),
theme.verticalSpacer,
BackgroundCard(
massnahme: massnahme!,
), ),
largeTheme.horizontalSpacer, theme.verticalSpacer,
PresetsCard(
massnahme: massnahme!,
),
theme.verticalSpacer,
BiodiverisityCard(
massnahme: massnahme!,
),
theme.verticalSpacer,
CreationCard(
massnahme: massnahme!,
),
theme.verticalSpacer,
MaintenanceCard(
massnahme: massnahme!,
),
theme.verticalSpacer,
FundingCard(
massnahme: massnahme!,
),
theme.verticalSpacer,
]),
),
theme.horizontalSpacer,
SizedBox( SizedBox(
width: 300, width: 300,
child: Column( child: Column(
@ -178,15 +163,15 @@ class ActionDetailPageState extends State<ActionDetailPage> {
AdvisorCard( AdvisorCard(
massnahme: massnahme, massnahme: massnahme,
), ),
largeTheme.verticalSpacer, theme.verticalSpacer,
MaterialCard( MaterialCard(
massnahme: massnahme, massnahme: massnahme,
), ),
largeTheme.verticalSpacer, theme.verticalSpacer,
FactsheetCard( FactsheetCard(
massnahme: massnahme, massnahme: massnahme,
), ),
largeTheme.verticalSpacer, theme.verticalSpacer,
ReviewCard( ReviewCard(
massnahme: massnahme, massnahme: massnahme,
), ),
@ -199,6 +184,7 @@ class ActionDetailPageState extends State<ActionDetailPage> {
), ),
), ),
), ),
),
], ],
); );
} }

View file

@ -1,4 +1,4 @@
import 'package:ambito/src/extensions/extensions.dart'; import 'package:expansion_tile_card/expansion_tile_card.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../../../../entity/entities.dart'; import '../../../../entity/entities.dart';
@ -15,21 +15,17 @@ class DescriptionCard extends StatelessWidget {
return SizedBox( return SizedBox(
width: double.infinity, width: double.infinity,
child: Card( child: ExpansionTileCard(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
elevation: 0, elevation: 0,
color: theme.currentColorScheme.secondary, baseColor: theme.currentColorScheme.secondary,
child: Padding( title: Text(
padding: const EdgeInsets.all(16), massnahme.name ?? '',
child: Column( style: theme.currentThemeData.textTheme.headlineMedium,
),
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text(
context.translate('page.actionDetailPage.description.title'),
style: theme.currentThemeData.textTheme.titleMedium,
),
theme.verticalSpacer, theme.verticalSpacer,
Text( Text(
massnahme.factsheetDefinition ?? '', massnahme.factsheetDefinition ?? '',
@ -37,8 +33,7 @@ class DescriptionCard extends StatelessWidget {
), ),
], ],
), ),
), ]),
),
); );
} }
} }

View file

@ -186,9 +186,8 @@ class DashboardPageState extends State<DashboardPage> {
SizedBox( SizedBox(
width: 532, width: 532,
child: Card( child: Card(
elevation: 4, elevation: 0,
surfaceTintColor: color: greenColors['primary']?.withOpacity(0.3),
greenColors['primary']?.withOpacity(0.3),
child: Padding( child: Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Column( child: Column(
@ -385,8 +384,8 @@ class DashboardPageState extends State<DashboardPage> {
return SizedBox( return SizedBox(
width: 532, width: 532,
child: Card( child: Card(
elevation: 4, elevation: 0,
surfaceTintColor: Colors.white, color: Theme.of(context).colorScheme.outline.withOpacity(.1),
child: Padding( child: Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Column( child: Column(

View file

@ -1,5 +1,6 @@
import 'package:ambito/main.dart'; import 'package:ambito/main.dart';
import 'package:ambito/src/extensions/extensions.dart'; import 'package:ambito/src/extensions/extensions.dart';
import 'package:ambito/src/packages/ambito_theme/ambito_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:screen_breakpoints/screen_breakpoints.dart'; import 'package:screen_breakpoints/screen_breakpoints.dart';
@ -15,7 +16,7 @@ class AmbitoAppbar extends AppBar {
child: InkWell( child: InkWell(
onHover: (value) {}, onHover: (value) {},
onTap: () { onTap: () {
Get.toNamed('/'); Get.toNamed('/dashboard');
}, },
child: Image.asset( child: Image.asset(
'assets/images/logo_trans.png', 'assets/images/logo_trans.png',
@ -63,12 +64,27 @@ class AmbitoAppbar extends AppBar {
), ),
), ),
if (breakpoint >= myBreakpoints.md) if (breakpoint >= myBreakpoints.md)
IconButton( PopupMenuButton(
onPressed: () {}, onSelected: (item) {},
icon: Icon( icon: Icon(
Icons.person, Icons.person,
color: largeTheme.currentColorScheme.primary, color: largeTheme.currentColorScheme.primary,
), ),
itemBuilder: (
BuildContext context,
) {
return [
PopupMenuItem(
onTap: () async {
Get.toNamed('/massnahme/neu');
},
child: Text(
'Neue Maßnahme',
style: getTheme(context).bodyMedium,
),
),
];
},
), ),
const SizedBox( const SizedBox(
width: 30, width: 30,
@ -78,8 +94,6 @@ class AmbitoAppbar extends AppBar {
static Widget _links(BuildContext context, List<String>? links) { static Widget _links(BuildContext context, List<String>? links) {
List<Widget> linkButtons = []; List<Widget> linkButtons = [];
logger.d(context.breakpoint.breakpoint);
logger.d(myBreakpoints.sm?.breakpoint);
if (context.breakpoint.breakpoint >= myBreakpoints.md!.breakpoint && if (context.breakpoint.breakpoint >= myBreakpoints.md!.breakpoint &&
links != null && links != null &&
links.isNotEmpty) { links.isNotEmpty) {

View file

@ -286,6 +286,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.0" version: "2.3.0"
expansion_tile_card:
dependency: "direct main"
description:
name: expansion_tile_card
sha256: "27ce4cb518f00e21d0f2309aaa6462b26b148e93cee2029a73088cecf42b1eb0"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@ -351,10 +359,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: flutter_compass name: flutter_compass
sha256: be642484f9f6975c1c6edff568281b001f2f1e604de27ecea18d97eebbdef22f sha256: "1b4d7e6c95a675ec8482b5c9c9ccf1ebf0ced3dbec59dce28ad609da953de850"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.8.0" version: "0.8.1"
flutter_dotenv: flutter_dotenv:
dependency: "direct main" dependency: "direct main"
description: description:
@ -446,10 +454,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: geolocator name: geolocator
sha256: "0ec58b731776bc43097fcf751f79681b6a8f6d3bc737c94779fe9f1ad73c1a81" sha256: d2ec66329cab29cb297d51d96c067d457ca519dca8589665fa0b82ebacb7dbe4
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "13.0.1" version: "13.0.2"
geolocator_android: geolocator_android:
dependency: transitive dependency: transitive
description: description:
@ -462,10 +470,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: geolocator_apple name: geolocator_apple
sha256: bc2aca02423ad429cb0556121f56e60360a2b7d694c8570301d06ea0c00732fd sha256: "6154ea2682563f69fc0125762ed7e91e7ed85d0b9776595653be33918e064807"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.7" version: "2.3.8+1"
geolocator_platform_interface: geolocator_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -694,10 +702,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: logger name: logger
sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32" sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.0" version: "2.5.0"
logging: logging:
dependency: transitive dependency: transitive
description: description:
@ -1187,34 +1195,34 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: syncfusion_flutter_calendar name: syncfusion_flutter_calendar
sha256: "769d3bbf8743922d74b242a968366661bd7b2973b3d34af9b9bc865874a520d9" sha256: "00703dd2e154ad534e7e898958f1e4c1573b15a19448c0b183365f4b9779f054"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "27.1.58" version: "27.2.2"
syncfusion_flutter_core: syncfusion_flutter_core:
dependency: transitive dependency: transitive
description: description:
name: syncfusion_flutter_core name: syncfusion_flutter_core
sha256: "31d2ddf410ee41abb3ecf85b7b6e8e1563307ad52ee784ddd91337e30280f715" sha256: "225b1cc135549bb4eef096d63b7323c30ee61c4b095c7e8a14bf9333e243d84b"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "27.1.58" version: "27.2.2"
syncfusion_flutter_datepicker: syncfusion_flutter_datepicker:
dependency: "direct main" dependency: "direct main"
description: description:
name: syncfusion_flutter_datepicker name: syncfusion_flutter_datepicker
sha256: e25797401bec43cd64c475150f87150e8bc3e67212d4d1273ff35483ea793a8b sha256: e2e2a97b033390f0791316c6019743991aa598563d09f603ba13230cd50b8905
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "27.1.58" version: "27.2.2"
syncfusion_localizations: syncfusion_localizations:
dependency: "direct main" dependency: "direct main"
description: description:
name: syncfusion_localizations name: syncfusion_localizations
sha256: a74b674f8d691927bebc10d19966539ecc92fa3b472c85df57e565f43e18483d sha256: c821c64ce38126ce1f5e5a36bc433157d49a03f04c19b45878cb82cca6267fde
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "27.1.58" version: "27.2.2"
synchronized: synchronized:
dependency: transitive dependency: transitive
description: description:

View file

@ -55,6 +55,7 @@ dependencies:
image_downloader_web: ^2.0.6 image_downloader_web: ^2.0.6
screen_breakpoints: ^1.0.5 screen_breakpoints: ^1.0.5
provider: ^6.1.2 provider: ^6.1.2
expansion_tile_card: ^3.0.0
dev_dependencies: dev_dependencies:
@ -66,7 +67,8 @@ dev_dependencies:
flutter: flutter:
uses-material-design: true uses-material-design: true
assets: assets:
- .env - i18n/
- images/
- assets/ - assets/
- assets/i18n/
- assets/images/ - assets/images/
- assets/i18n/