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"
}
}
},
"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_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_theme/ambito_theme.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/pages/actions/actions_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/calendar/calendar_page.dart';
import 'package:ambito/src/pages/calendar/calendar_page_year.dart';
import 'package:ambito/src/pages/dashboard/dashboard_page.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_i18n/flutter_i18n.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:get/get.dart';
import 'package:isar/isar.dart';
import 'package:logger/logger.dart';
import 'package:provider/provider.dart';
import 'package:screen_breakpoints/screen_breakpoints.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:syncfusion_localizations/syncfusion_localizations.dart';
@ -72,9 +74,29 @@ AmbitoTheme largeTheme = AmbitoThemeLarge();
AmbitoTheme mediumTheme = AmbitoThemeMedium();
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 {
WidgetsFlutterBinding.ensureInitialized();
await dotenv.load(fileName: '.env');
//await dotenv.load(fileName: '.env');
await AmbitoSharedPrefs.start();
await AmbitoIsarDB.init();
await Future.wait([
@ -105,91 +127,102 @@ class Ambito extends StatelessWidget {
Widget build(BuildContext context) {
return BreakpointConfigurator(
configuration: myBreakpoints,
child: GetMaterialApp(
debugShowCheckedModeBanner: false,
localizationsDelegates: [
FlutterI18nDelegate(
translationLoader: FileTranslationLoader(
fallbackFile: 'de',
basePath: 'i18n',
),
missingTranslationHandler: (key, locale) {
if (kDebugMode) {
print("--- Missing Key: $key, languageCode: $locale");
}
},
),
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
SfGlobalLocalizations.delegate,
],
title: 'AmBiTo',
supportedLocales: const [Locale('de')],
locale: const Locale('de'),
builder: FlutterI18n.rootAppBuilder(),
theme: (getTheme(context)).lightThemeData,
darkTheme: (getTheme(context)).darkThemeData,
themeMode: ThemeMode.light,
initialRoute: '/massnahmen',
getPages: [
GetPage(
name: '/',
page: () => const ActionsPrePage(),
),
GetPage(
name: '/kalender',
page: () => const CalendarPage(),
),
GetPage(
name: '/kalender/jahr',
page: () => const CalendarPageYear(),
),
GetPage(
name: '/massnahmen',
page: () => const ActionsPrePage(),
),
GetPage(
name: '/massnahmendatenbank',
page: () => const ActionsPage(),
),
GetPage(
name: '/dashboard',
page: () => DashboardPage(
businessId: prefs.getInt('currentUser') ?? 22,
userId: 0,
),
),
GetPage(
name: '/dashboard/meine-massnahmen',
page: () => DashboardPage(
businessId: prefs.getInt('currentUser') ?? 22,
userId: 0,
),
),
GetPage(
name: '/dashboard/urkunde',
page: () => DashboardPage(
businessId: prefs.getInt('currentUser') ?? 22,
userId: 0,
),
),
GetPage(
name: '/dashboard/flaechen',
page: () => DashboardPage(
businessId: prefs.getInt('currentUser') ?? 22,
userId: 0,
),
),
GetPage(
name: '/dashboard/stammdaten',
page: () => DashboardPage(
businessId: prefs.getInt('currentUser') ?? 22,
userId: 0,
),
),
GetPage(name: '/massnahme/:id', page: () => const ActionDetailPage())
],
child: ChangeNotifierProvider(
create: (_) => ThemeManager(),
child: Consumer<ThemeManager>(
builder: (context, ThemeManager themeManager, child) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
localizationsDelegates: [
FlutterI18nDelegate(
translationLoader: FileTranslationLoader(
fallbackFile: 'de',
basePath: 'i18n',
),
missingTranslationHandler: (key, locale) {
if (kDebugMode) {
print("--- Missing Key: $key, languageCode: $locale");
}
},
),
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
SfGlobalLocalizations.delegate,
],
title: 'AmBiTo',
supportedLocales: const [Locale('de')],
locale: const Locale('de'),
builder: FlutterI18n.rootAppBuilder(),
theme: ThemeManager().themeData?.lightThemeData,
darkTheme: ThemeManager().themeData?.darkThemeData,
themeMode: ThemeMode.light,
initialRoute: '/massnahmen',
getPages: [
GetPage(
name: '/',
page: () => const ActionsPrePage(),
),
GetPage(
name: '/kalender',
page: () => const CalendarPage(),
),
GetPage(
name: '/kalender/jahr',
page: () => const CalendarPageYear(),
),
GetPage(
name: '/massnahmen',
page: () => const ActionsPrePage(),
),
GetPage(
name: '/massnahmendatenbank',
page: () => const ActionsPage(),
),
GetPage(
name: '/dashboard',
page: () => DashboardPage(
businessId: prefs.getInt('currentUser') ?? 22,
userId: 0,
),
),
GetPage(
name: '/dashboard/meine-massnahmen',
page: () => DashboardPage(
businessId: prefs.getInt('currentUser') ?? 22,
userId: 0,
),
),
GetPage(
name: '/dashboard/urkunde',
page: () => DashboardPage(
businessId: prefs.getInt('currentUser') ?? 22,
userId: 0,
),
),
GetPage(
name: '/dashboard/flaechen',
page: () => DashboardPage(
businessId: prefs.getInt('currentUser') ?? 22,
userId: 0,
),
),
GetPage(
name: '/dashboard/stammdaten',
page: () => DashboardPage(
businessId: prefs.getInt('currentUser') ?? 22,
userId: 0,
),
),
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';
@JsonSerializable(explicitToJson: true)
@JsonSerializable(explicitToJson: true, includeIfNull: true)
@collection
class Measure extends BaseEntity with EntityWithId {
Measure();
@ -160,6 +160,29 @@ extension MeasureExtension on Measure {
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? image;
if (files != null && files!.isNotEmpty) {

View file

@ -10,6 +10,40 @@ class MeasureRepository extends BaseDB {
@override
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 {
Map<String, List<int>> filtersAreaType = {};
Map<String, List<int>> filtersMeasureGroup = {};
@ -111,7 +145,6 @@ class MeasureRepository extends BaseDB {
}
}
}
logger.d(files);
return true;
}
}

View file

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

View file

@ -4,7 +4,6 @@ import 'dart:async';
import 'dart:convert';
import 'package:ambito/main.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:http/http.dart' as http;
class RestClient {
@ -20,7 +19,7 @@ class RestClient {
var headers = {
"Content-Type": contentType,
"Accept": accept,
"Authorization": "Token ${dotenv.get('BASEROW_TOKEN')}",
"Authorization": "Token $BASEROW_TOKEN",
};
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:google_fonts/google_fonts.dart';
import 'package:screen_breakpoints/screen_breakpoints.dart';
@ -51,11 +52,14 @@ final actionAreaFGColors = {
AmbitoTheme getTheme(BuildContext context) {
var breakpoint = context.breakpoint;
if (breakpoint >= myBreakpoints.lg) {
ThemeManager().setTheme(largeTheme);
return largeTheme;
}
if (breakpoint >= myBreakpoints.sm) {
ThemeManager().setTheme(smallTheme);
return mediumTheme;
}
ThemeManager().setTheme(mediumTheme);
return smallTheme;
}

View file

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

View file

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

View file

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

View file

@ -44,7 +44,11 @@ class ActionsPrePageState extends State<ActionsPrePage> {
setState(() {});
});
},
onHover: (value) {},
onHover: (hovered) {},
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
focusColor: Colors.transparent,
hoverColor: Colors.transparent,
child: SizedBox(
width: 262,
height: 380,
@ -64,8 +68,7 @@ class ActionsPrePageState extends State<ActionsPrePage> {
padding: const EdgeInsets.only(left: 16, right: 16),
child: Text(
filter.name!,
style: largeTheme
.currentThemeData.textTheme.headlineMedium
style: largeTheme.currentThemeData.textTheme.labelMedium
?.copyWith(
color: actionAreaFGColors[filter.name!],
fontWeight: FontWeight.bold,
@ -148,20 +151,26 @@ class ActionsPrePageState extends State<ActionsPrePage> {
children: cards,
),
theme.verticalSpacerMax,
TextButton(
onPressed: () async {
InkWell(
onHover: (hovered) {},
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
focusColor: Colors.transparent,
hoverColor: Colors.transparent,
onTap: () async {
await prefs.setString('selected_areaType', '');
await Get.toNamed('/massnahmendatenbank');
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8)),
borderRadius:
const BorderRadius.all(Radius.circular(8)),
color:
theme.currentColorScheme.onSurface.withOpacity(.1),
),
width: Breakpoint.fromContext(context).width,
child: Padding(
padding: EdgeInsets.all(20),
padding: const EdgeInsets.all(20),
child: Text(
'Alle Maßnahmen anzeigen',
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:screen_breakpoints/screen_breakpoints.dart';
import '../../../../main.dart';
import '../../../packages/ambito_theme/ambito_theme.dart';
import '../../../widgets/appbar/ambito_appbar.dart';
import '../../ambito_page.dart';
import 'cards/_cards.dart';
@ -35,60 +35,8 @@ class ActionDetailPageState extends State<ActionDetailPage> {
void initState() {
id = Get.parameters['id'] ?? '';
if (id != '') {
massnahme = MeasureRepository().get(int.parse(id)) as Measure;
setState(() {
if (massnahme != null) {
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!);
}
massnahme = MeasureRepository().get(int.parse(id)) as Measure;
});
}
@ -102,11 +50,18 @@ class ActionDetailPageState extends State<ActionDetailPage> {
links: const ['dashboard', 'massnahmen'],
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(
children: [
Align(
@ -118,7 +73,10 @@ class ActionDetailPageState extends State<ActionDetailPage> {
onPressed: () {
Get.offAndToNamed('/');
},
child: const Text('Start'),
child: Text(
'Start',
style: theme.bodyMedium,
),
),
),
BreadCrumbItem(
@ -126,7 +84,10 @@ class ActionDetailPageState extends State<ActionDetailPage> {
onPressed: () {
Get.offAndToNamed('/massnahmendatenbank');
},
child: const Text('Massnahmen'),
child: Text(
'Massnahmen',
style: theme.bodyMedium,
),
),
),
BreadCrumbItem(
@ -138,64 +99,89 @@ class ActionDetailPageState extends State<ActionDetailPage> {
divider: const Icon(Icons.chevron_right),
),
),
Container(
SizedBox(
width: double.infinity,
height: 400,
color: largeTheme.currentColorScheme.primary,
child: massnahme.getImage(),
height: 300,
child: massnahme.getFullImage(),
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
largeTheme.verticalSpacer,
Align(
alignment: Alignment.centerLeft,
child: Text(
massnahme.name!,
style: largeTheme.currentThemeData.textTheme.titleLarge,
child: SizedBox(
width: 1152,
child: Column(
children: [
theme.verticalSpacer,
Align(
alignment: Alignment.centerLeft,
child: Text(
massnahme.name!,
style: theme.currentThemeData.textTheme.headlineMedium,
),
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: SingleChildScrollView(
child: ListView.builder(
shrinkWrap: true,
itemCount: contentItems.length,
itemBuilder: (BuildContext context, int index) {
return contentItems[index];
}),
theme.verticalSpacer,
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(children: [
DescriptionCard(
massnahme: massnahme!,
),
theme.verticalSpacer,
BackgroundCard(
massnahme: massnahme!,
),
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,
]),
),
),
largeTheme.horizontalSpacer,
SizedBox(
width: 300,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
AdvisorCard(
massnahme: massnahme,
),
largeTheme.verticalSpacer,
MaterialCard(
massnahme: massnahme,
),
largeTheme.verticalSpacer,
FactsheetCard(
massnahme: massnahme,
),
largeTheme.verticalSpacer,
ReviewCard(
massnahme: massnahme,
),
],
theme.horizontalSpacer,
SizedBox(
width: 300,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
AdvisorCard(
massnahme: massnahme,
),
theme.verticalSpacer,
MaterialCard(
massnahme: massnahme,
),
theme.verticalSpacer,
FactsheetCard(
massnahme: massnahme,
),
theme.verticalSpacer,
ReviewCard(
massnahme: massnahme,
),
],
),
),
),
],
),
],
],
),
],
),
),
),
),

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 '../../../../entity/entities.dart';
@ -15,30 +15,25 @@ class DescriptionCard extends StatelessWidget {
return SizedBox(
width: double.infinity,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(0),
),
elevation: 0,
color: theme.currentColorScheme.secondary,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
context.translate('page.actionDetailPage.description.title'),
style: theme.currentThemeData.textTheme.titleMedium,
),
theme.verticalSpacer,
Text(
massnahme.factsheetDefinition ?? '',
style: theme.currentThemeData.textTheme.bodyMedium,
),
],
child: ExpansionTileCard(
elevation: 0,
baseColor: theme.currentColorScheme.secondary,
title: Text(
massnahme.name ?? '',
style: theme.currentThemeData.textTheme.headlineMedium,
),
),
),
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
theme.verticalSpacer,
Text(
massnahme.factsheetDefinition ?? '',
style: theme.currentThemeData.textTheme.bodyMedium,
),
],
),
]),
);
}
}

View file

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

View file

@ -1,5 +1,6 @@
import 'package:ambito/main.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:get/get.dart';
import 'package:screen_breakpoints/screen_breakpoints.dart';
@ -15,7 +16,7 @@ class AmbitoAppbar extends AppBar {
child: InkWell(
onHover: (value) {},
onTap: () {
Get.toNamed('/');
Get.toNamed('/dashboard');
},
child: Image.asset(
'assets/images/logo_trans.png',
@ -63,12 +64,27 @@ class AmbitoAppbar extends AppBar {
),
),
if (breakpoint >= myBreakpoints.md)
IconButton(
onPressed: () {},
PopupMenuButton(
onSelected: (item) {},
icon: Icon(
Icons.person,
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(
width: 30,
@ -78,8 +94,6 @@ class AmbitoAppbar extends AppBar {
static Widget _links(BuildContext context, List<String>? links) {
List<Widget> linkButtons = [];
logger.d(context.breakpoint.breakpoint);
logger.d(myBreakpoints.sm?.breakpoint);
if (context.breakpoint.breakpoint >= myBreakpoints.md!.breakpoint &&
links != null &&
links.isNotEmpty) {

View file

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

View file

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