2024-12-07
This commit is contained in:
parent
ec2cf3d860
commit
46fbb8bbf6
38 changed files with 8225 additions and 5389 deletions
BIN
images/measure/nist_brut_unterschlupforte.jpg
Normal file
BIN
images/measure/nist_brut_unterschlupforte.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 639 KiB |
|
@ -1,5 +1,6 @@
|
|||
import 'package:ambito/src/config/config.dart';
|
||||
import 'package:ambito/src/consts/consts.dart';
|
||||
import 'package:ambito/src/entity/enums/enum_details_type.dart';
|
||||
import 'package:ambito/src/entity/lists/list_measure.dart';
|
||||
import 'package:ambito/src/entity/lists/list_repository.dart';
|
||||
import 'package:ambito/src/packages/ambito_api/base_api.dart';
|
||||
|
@ -8,6 +9,7 @@ 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/pages/calendar/calendar_page.dart';
|
||||
import 'package:ambito/src/pages/calendar/calendar_page_year.dart';
|
||||
import 'package:ambito/src/pages/dashboard/areas/dashboard_areas_page.dart';
|
||||
import 'package:ambito/src/pages/dashboard/dashboard_page.dart';
|
||||
import 'package:ambito/src/pages/error/error_page.dart';
|
||||
import 'package:ambito/src/pages/measure/categories/measure_categories_page.dart';
|
||||
|
@ -41,7 +43,8 @@ void main() async {
|
|||
BaseApi().getContent('funding_program'),
|
||||
//BaseApi().getContent('location_requirements'),
|
||||
//BaseApi().getContent('reference_implementation'),
|
||||
//BaseApi().getContent('business'),
|
||||
BaseApi().getContent('business'),
|
||||
BaseApi().getContent('area'),
|
||||
//BaseApi().getContent('service_provider'),
|
||||
//BaseApi().getContent('service_provider_contact_person'),
|
||||
//BaseApi().getContent('material'),
|
||||
|
@ -132,35 +135,42 @@ class Ambito extends StatelessWidget {
|
|||
GetPage(
|
||||
name: '/dashboard',
|
||||
page: () => DashboardPage(
|
||||
businessId: prefs.getInt('currentUser') ?? 22,
|
||||
businessId: prefs.getInt('currentUser') ?? 100,
|
||||
userId: 0,
|
||||
),
|
||||
),
|
||||
GetPage(
|
||||
name: '/dashboard/meine-massnahmen',
|
||||
page: () => DashboardPage(
|
||||
businessId: prefs.getInt('currentUser') ?? 22,
|
||||
businessId: prefs.getInt('currentUser') ?? 100,
|
||||
userId: 0,
|
||||
),
|
||||
),
|
||||
GetPage(
|
||||
name: '/dashboard/urkunde',
|
||||
page: () => DashboardPage(
|
||||
businessId: prefs.getInt('currentUser') ?? 22,
|
||||
businessId: prefs.getInt('currentUser') ?? 100,
|
||||
userId: 0,
|
||||
),
|
||||
),
|
||||
GetPage(
|
||||
name: '/dashboard/flaechen',
|
||||
page: () => DashboardPage(
|
||||
businessId: prefs.getInt('currentUser') ?? 22,
|
||||
page: () => DashboardAreasPage(
|
||||
businessId: prefs.getInt('currentUser') ?? 100,
|
||||
userId: 0,
|
||||
),
|
||||
),
|
||||
GetPage(
|
||||
name: '/dashboard/flaechen/:index',
|
||||
page: () => DashboardAreasPage(
|
||||
businessId: prefs.getInt('currentUser') ?? 100,
|
||||
userId: 0,
|
||||
),
|
||||
),
|
||||
GetPage(
|
||||
name: '/dashboard/stammdaten',
|
||||
page: () => DashboardPage(
|
||||
businessId: prefs.getInt('currentUser') ?? 22,
|
||||
businessId: prefs.getInt('currentUser') ?? 100,
|
||||
userId: 0,
|
||||
),
|
||||
),
|
||||
|
@ -169,8 +179,9 @@ class Ambito extends StatelessWidget {
|
|||
page: () => const MeasureCreatePage(),
|
||||
),
|
||||
GetPage(
|
||||
name: '/massnahme/:id',
|
||||
page: () => const MeasureDetailPage(),
|
||||
name: '/massnahme/',
|
||||
page: () => const MeasureDetailPage(
|
||||
id: 0, type: EnumDetailsType.measure),
|
||||
),
|
||||
GetPage(
|
||||
name: '/error',
|
||||
|
|
|
@ -45,8 +45,11 @@ const BreakpointConfiguration myBreakpoints = BreakpointConfiguration(
|
|||
xxl: null,
|
||||
);
|
||||
|
||||
const googleApiKey = 'AIzaSyAb2d7gn5CLWnVZTaSapRYHjnZapSP9BQM';
|
||||
|
||||
const baserowToken = 'TFxO7vzBLVRCu9I3VMoHmTuCvSu8aCDi';
|
||||
const baserowIds = {
|
||||
"area": 403344,
|
||||
"measure": 328253,
|
||||
"measure_general": 396946,
|
||||
"measure_details": 342622,
|
||||
|
|
|
@ -14,5 +14,5 @@ class IdValue {
|
|||
factory IdValue.fromJson(Map<String, dynamic> json) =>
|
||||
_$IdValueFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$IdValueToJson(this);
|
||||
int? toJson() => id;
|
||||
}
|
||||
|
|
|
@ -15,5 +15,5 @@ class IdValueColor {
|
|||
factory IdValueColor.fromJson(Map<String, dynamic> json) =>
|
||||
_$IdValueColorFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$IdValueColorToJson(this);
|
||||
int? toJson() => id;
|
||||
}
|
||||
|
|
|
@ -15,5 +15,5 @@ class IdValueMix {
|
|||
factory IdValueMix.fromJson(Map<String, dynamic> json) =>
|
||||
_$IdValueMixFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$IdValueMixToJson(this);
|
||||
int? toJson() => id;
|
||||
}
|
||||
|
|
61
lib/src/entity/area/area.dart
Normal file
61
lib/src/entity/area/area.dart
Normal file
|
@ -0,0 +1,61 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:ambito/src/entity/base_entity.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import '../../consts/consts.dart';
|
||||
import '../_general/id_value/id_value.dart';
|
||||
|
||||
part 'area.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
@collection
|
||||
class Area extends BaseEntity with EntityWithId {
|
||||
Area();
|
||||
|
||||
@JsonKey(name: 'field_3077525')
|
||||
String? name;
|
||||
@JsonKey(name: 'field_3077543')
|
||||
List<IdValue>? business;
|
||||
@JsonKey(name: 'field_3077526')
|
||||
String? description;
|
||||
@JsonKey(name: 'field_3077544')
|
||||
String? size;
|
||||
@JsonKey(name: 'field_3077545')
|
||||
String? polygon;
|
||||
|
||||
factory Area.fromJson(Map<String, dynamic> json) => _$AreaFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$AreaToJson(this);
|
||||
}
|
||||
|
||||
extension AreaExtension on Area {
|
||||
Polygon? toPolygon() {
|
||||
if (polygon == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final json = jsonDecode(polygon!);
|
||||
|
||||
List<LatLng> points = [];
|
||||
|
||||
for (final point in json) {
|
||||
points.add(LatLng(point[0], point[1]));
|
||||
}
|
||||
|
||||
logger.d(points.toString());
|
||||
|
||||
return Polygon(
|
||||
polygonId: PolygonId(
|
||||
id.toString(),
|
||||
),
|
||||
strokeColor: const Color(0xFF60845E),
|
||||
fillColor: const Color(0xff87A34E).withOpacity(.7),
|
||||
strokeWidth: 2,
|
||||
points: points,
|
||||
);
|
||||
}
|
||||
}
|
1509
lib/src/entity/area/area.g.dart
Normal file
1509
lib/src/entity/area/area.g.dart
Normal file
File diff suppressed because it is too large
Load diff
138
lib/src/entity/area/area_datasource.dart
Normal file
138
lib/src/entity/area/area_datasource.dart
Normal file
|
@ -0,0 +1,138 @@
|
|||
import 'package:ambito/src/entity/area/area.dart';
|
||||
import 'package:ambito/src/widgets/dialogs/delete_entity/delete_entity_dialog.dart';
|
||||
import 'package:ambito/src/widgets/dialogs/edit_entity_dialog/edit_entity_dialog.dart';
|
||||
import 'package:ambito/src/widgets/dialogs/edit_field_dialog/edit_field_dialog.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
|
||||
|
||||
import '../../packages/ambito_theme/ambito_theme.dart';
|
||||
|
||||
class AreaDataSource extends DataGridSource {
|
||||
AreaDataSource(
|
||||
{required List<Area> areas, required BuildContext this.context}) {
|
||||
dataGridRows = areas
|
||||
.map<DataGridRow>(
|
||||
(dataGridRow) => DataGridRow(
|
||||
cells: [
|
||||
DataGridCell<int>(
|
||||
columnName: 'id',
|
||||
value: dataGridRow.id,
|
||||
),
|
||||
DataGridCell<String>(
|
||||
columnName: 'name',
|
||||
value: dataGridRow.name,
|
||||
),
|
||||
DataGridCell<String>(
|
||||
columnName: 'size',
|
||||
value: dataGridRow.size,
|
||||
),
|
||||
DataGridCell<String>(
|
||||
columnName: 'description',
|
||||
value: dataGridRow.description,
|
||||
),
|
||||
const DataGridCell(
|
||||
columnName: 'action',
|
||||
value: '',
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
|
||||
final BuildContext context;
|
||||
|
||||
List<DataGridRow> dataGridRows = [];
|
||||
|
||||
@override
|
||||
List<DataGridRow> get rows => dataGridRows;
|
||||
|
||||
@override
|
||||
DataGridRowAdapter? buildRow(DataGridRow row) {
|
||||
final AmbitoTheme theme = getTheme(context);
|
||||
final id = row.getCells().firstOrNull?.value;
|
||||
|
||||
NumberFormat numberFormat = NumberFormat.decimalPattern('de');
|
||||
|
||||
return DataGridRowAdapter(
|
||||
cells: row.getCells().map<Widget>(
|
||||
(dataGridCell) {
|
||||
if (dataGridCell.columnName == 'action') {
|
||||
return Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Row(
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () => EditEntityDialog.show(
|
||||
context: context,
|
||||
type: 'area',
|
||||
id: id,
|
||||
),
|
||||
icon: Icon(
|
||||
Icons.edit_outlined,
|
||||
color: theme.currentColorScheme.primary,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => DeleteEntityDialog.show(
|
||||
context: context,
|
||||
type: 'area',
|
||||
id: id,
|
||||
),
|
||||
icon: Icon(
|
||||
Icons.delete_outline,
|
||||
color: theme.currentColorScheme.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
if (dataGridCell.columnName == 'description') {
|
||||
return Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: IconButton(
|
||||
onPressed: () => EditFieldDialog.show(
|
||||
context: context,
|
||||
type: 'area_notice',
|
||||
id: id,
|
||||
),
|
||||
icon: Icon(
|
||||
Icons.description_outlined,
|
||||
color: theme.currentColorScheme.primary,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
if (dataGridCell.columnName == 'size') {
|
||||
return Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Text(
|
||||
'${numberFormat.format(float.parse(dataGridCell.value.toString()))} m²',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: theme.bodyMedium.copyWith(
|
||||
color: theme.currentColorScheme.primary,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Text(
|
||||
dataGridCell.value.toString(),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: theme.bodyMedium.copyWith(
|
||||
color: theme.currentColorScheme.primary,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
).toList());
|
||||
}
|
||||
}
|
21
lib/src/entity/area/area_repository.dart
Normal file
21
lib/src/entity/area/area_repository.dart
Normal file
|
@ -0,0 +1,21 @@
|
|||
import 'package:ambito/src/entity/area/area.dart';
|
||||
import 'package:ambito/src/packages/ambito_db/base_db.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
import '../../consts/consts.dart';
|
||||
|
||||
class AreaRepository extends BaseDB {
|
||||
@override
|
||||
IsarCollection collection = isar.areas;
|
||||
|
||||
List<Area> getAreasForBusiness(int id) {
|
||||
final all = isar.areas.where().findAll();
|
||||
List<Area> areas = [];
|
||||
for (final Area area in all) {
|
||||
if (area.business!.any((ele) => ele.id == id)) {
|
||||
areas.add(area);
|
||||
}
|
||||
}
|
||||
return areas;
|
||||
}
|
||||
}
|
|
@ -9,62 +9,70 @@ part 'business.g.dart';
|
|||
class Business extends BaseEntity with EntityWithId {
|
||||
Business();
|
||||
|
||||
@JsonKey(name: 'Modellbetrieb')
|
||||
@JsonKey(name: 'field_2404114')
|
||||
@Index()
|
||||
String? name;
|
||||
|
||||
@JsonKey(name: 'Ursprungsgebiet')
|
||||
IdValueColor? areaOfOrigin;
|
||||
@JsonKey(name: 'Ansprechpartner')
|
||||
String? businessOwner;
|
||||
@JsonKey(name: 'Feld 6')
|
||||
String? businessEmail;
|
||||
@JsonKey(name: 'Feld 7')
|
||||
String? businessPhone;
|
||||
@JsonKey(name: 'Feld 8')
|
||||
String? contactName;
|
||||
@JsonKey(name: 'Feld 9')
|
||||
String? contactPosition;
|
||||
@JsonKey(name: 'Feld 10')
|
||||
String? contactEmail;
|
||||
@JsonKey(name: 'Feld 11')
|
||||
String? contactPhone;
|
||||
@JsonKey(name: 'Feld 12')
|
||||
String? contact2Name;
|
||||
@JsonKey(name: 'Feld 13')
|
||||
String? contact2Position;
|
||||
@JsonKey(name: 'Feld 14')
|
||||
String? contact2Email;
|
||||
@JsonKey(name: 'Feld 15')
|
||||
String? contact2Phone;
|
||||
@JsonKey(name: 'Feld 16')
|
||||
String? contact3Name;
|
||||
@JsonKey(name: 'Feld 17')
|
||||
String? contact3Email;
|
||||
@JsonKey(name: 'Feld 18')
|
||||
String? addressComplete;
|
||||
@JsonKey(name: 'Feld 19')
|
||||
String? addressStreet;
|
||||
@JsonKey(name: 'Feld 20')
|
||||
String? addressPostalCode;
|
||||
@JsonKey(name: 'Feld 21')
|
||||
String? addressCity;
|
||||
@JsonKey(name: 'Feld 22')
|
||||
String? addressRegion;
|
||||
@JsonKey(name: 'Feld 23')
|
||||
String? addressFederalState;
|
||||
@JsonKey(name: 'Feld 24')
|
||||
String? unknown;
|
||||
@JsonKey(name: 'Feld 25')
|
||||
String? businessType;
|
||||
@JsonKey(name: 'Region')
|
||||
@JsonKey(name: 'field_3021727')
|
||||
IdValueColor? businessType;
|
||||
|
||||
@JsonKey(name: 'field_2404115')
|
||||
IdValueColor? businessOrigin;
|
||||
|
||||
@JsonKey(name: 'field_2404155')
|
||||
List<IdValue>? referenceImplementation;
|
||||
|
||||
@JsonKey(name: 'field_2404143')
|
||||
String? region;
|
||||
@JsonKey(name: 'Umgesetze_Maßnahmen')
|
||||
List<IdValueColor>? measures;
|
||||
@JsonKey(name: '05 Referenzumsetzung')
|
||||
List<IdValueColor>? referenceImplementation;
|
||||
@JsonKey(name: '07 Erfahrungsbericht Umsetuzung')
|
||||
List<IdValueColor>? experienceReport;
|
||||
|
||||
@JsonKey(name: 'field_2404117')
|
||||
String? businessContact;
|
||||
@JsonKey(name: 'field_2404119')
|
||||
String? businessEmail;
|
||||
@JsonKey(name: 'field_2404120')
|
||||
String? businessPhone;
|
||||
|
||||
@JsonKey(name: 'field_2404121')
|
||||
String? contact1Name;
|
||||
@JsonKey(name: 'field_2404122')
|
||||
String? contact1Position;
|
||||
@JsonKey(name: 'field_2404123')
|
||||
String? contact1Email;
|
||||
@JsonKey(name: 'field_2404124')
|
||||
String? contact1Phone;
|
||||
|
||||
@JsonKey(name: 'field_2404125')
|
||||
String? contact2Name;
|
||||
@JsonKey(name: 'field_2404126')
|
||||
String? contact2Position;
|
||||
@JsonKey(name: 'field_2404127')
|
||||
String? contact2Email;
|
||||
@JsonKey(name: 'field_2404128')
|
||||
String? contact2Phone;
|
||||
|
||||
@JsonKey(name: 'field_2404129')
|
||||
String? contact3Name;
|
||||
@JsonKey(name: 'field_2404130')
|
||||
String? contact3Email;
|
||||
|
||||
@JsonKey(name: 'field_2404131')
|
||||
String? addressComplete;
|
||||
@JsonKey(name: 'field_2404132')
|
||||
String? addressStreet;
|
||||
@JsonKey(name: 'field_2404133')
|
||||
String? addressPostalCode;
|
||||
@JsonKey(name: 'field_2404134')
|
||||
String? addressCity;
|
||||
@JsonKey(name: 'field_2404135')
|
||||
String? addressRegion;
|
||||
@JsonKey(name: 'field_2404136')
|
||||
String? addressFederalState;
|
||||
|
||||
@JsonKey(name: 'field_2404138')
|
||||
String? businessBio;
|
||||
|
||||
@JsonKey(name: 'field_2428872')
|
||||
List<IdValue>? experienceReport;
|
||||
|
||||
factory Business.fromJson(Map<String, dynamic> json) =>
|
||||
_$BusinessFromJson(json);
|
||||
|
|
File diff suppressed because it is too large
Load diff
1
lib/src/entity/enums/enum_details_type.dart
Normal file
1
lib/src/entity/enums/enum_details_type.dart
Normal file
|
@ -0,0 +1 @@
|
|||
enum EnumDetailsType { measure, type }
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||
class ListDisplay {
|
||||
ListDisplay();
|
||||
|
||||
int? id;
|
||||
String? title;
|
||||
String? description;
|
||||
Widget? image;
|
||||
|
|
|
@ -43,6 +43,7 @@ class ListMeasureSingle extends BaseEntity with EntityWithId {
|
|||
extension ListMeasureExtension on ListMeasureSingle {
|
||||
ListDisplay asListDisplay() {
|
||||
return ListDisplay()
|
||||
..id = toJson()['id']
|
||||
..title = name
|
||||
..description = description
|
||||
..image = getImage()
|
||||
|
|
|
@ -52,6 +52,7 @@ extension ListMeasureTypeGroupCategoryExtension
|
|||
.isNotEmpty;
|
||||
|
||||
return ListDisplay()
|
||||
..id = toJson()['id']
|
||||
..title = measureType
|
||||
..description = description
|
||||
..image = getImage()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:ambito/main.dart';
|
||||
import 'package:ambito/src/entity/area/area_repository.dart';
|
||||
import 'package:ambito/src/entity/entities.dart';
|
||||
import 'package:ambito/src/entity/measure/details/measure_details.dart';
|
||||
import 'package:ambito/src/entity/measure/details/measure_details_repository.dart';
|
||||
|
@ -11,6 +12,8 @@ import 'package:ambito/src/packages/ambito_api/restclient.dart';
|
|||
import 'package:get/get.dart';
|
||||
|
||||
import '../../config/config.dart';
|
||||
import '../../entity/area/area.dart';
|
||||
import '../../entity/business/business_repository.dart';
|
||||
import '../../entity/funding_program/funding_program_repository.dart';
|
||||
import '../../entity/measure/measure_repository.dart';
|
||||
|
||||
|
@ -22,6 +25,61 @@ class BaseApi {
|
|||
tables = baserowIds;
|
||||
}
|
||||
|
||||
_getMap() {
|
||||
return {
|
||||
'area': AreaRepository().put,
|
||||
'business': BusinessRepository().put,
|
||||
'funding_program': FundingProgramRepository().put,
|
||||
'measure_types': MeasureRepository().put,
|
||||
'measure_general': MeasureGeneralRepository().put,
|
||||
'measure_details': MeasureDetailsRepository().put,
|
||||
'measure_types_details': MeasureTypesDetailsRepository().put,
|
||||
};
|
||||
}
|
||||
|
||||
Future<bool> patchContent(String table, int id, dynamic body) async {
|
||||
init();
|
||||
int tableId = tables[table] ?? 0;
|
||||
|
||||
if (tableId <= 0) return false;
|
||||
|
||||
var response = await RestClient().patch('$tableId/$id/', body);
|
||||
if (response.statusCode != 200) Get.toNamed('/error');
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<bool> deleteContent(String table, int id) async {
|
||||
init();
|
||||
int tableId = tables[table] ?? 0;
|
||||
|
||||
if (tableId <= 0) return false;
|
||||
|
||||
var response = await RestClient().delete('$tableId/$id/');
|
||||
if (response.statusCode != 200) Get.toNamed('/error');
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<bool> postContent(String table, dynamic body) async {
|
||||
init();
|
||||
int tableId = tables[table] ?? 0;
|
||||
|
||||
if (tableId <= 0) return false;
|
||||
|
||||
final repositoryMap = _getMap();
|
||||
|
||||
var response = await RestClient().post('$tableId/', body);
|
||||
if (response.statusCode != 200) Get.toNamed('/error');
|
||||
|
||||
var model = _createModelFromJson(table, jsonDecode(response.body));
|
||||
|
||||
var repositoryFunction = repositoryMap[table];
|
||||
if (repositoryFunction == null) return false;
|
||||
|
||||
repositoryFunction(model);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<bool> getContent(String table) async {
|
||||
init();
|
||||
int tableId = tables[table] ?? 0;
|
||||
|
@ -36,18 +94,20 @@ class BaseApi {
|
|||
var results = json['results'];
|
||||
|
||||
final repositoryMap = {
|
||||
//'tree_type': TreeTypeRepository().put,
|
||||
//'measure': MeasureRepository().putMeasureGroups,
|
||||
'area': AreaRepository().put,
|
||||
'business': BusinessRepository().put,
|
||||
'funding_program': FundingProgramRepository().put,
|
||||
'measure_types': MeasureRepository().put,
|
||||
'measure_general': MeasureGeneralRepository().put,
|
||||
'measure_details': MeasureDetailsRepository().put,
|
||||
'measure_types_details': MeasureTypesDetailsRepository().put,
|
||||
//'measure_combination': MeasureCombinationRepository().put,
|
||||
//'organism': OrganismRepository().put,
|
||||
'funding_program': FundingProgramRepository().put,
|
||||
//'location_requirements': LocationRequirementsRepository().put,
|
||||
//'reference_implementation': ReferenceImplementationRepository().put,
|
||||
//'business': BusinessRepository().put,
|
||||
//'tree_type': TreeTypeRepository().put,
|
||||
//'measure': MeasureRepository().putMeasureGroups,
|
||||
|
||||
//'service_provider': ServiceProviderRepository().put,
|
||||
//'service_provider_contact_person':
|
||||
// ServiceProviderContactPersonRepository().put,
|
||||
|
@ -70,6 +130,10 @@ class BaseApi {
|
|||
|
||||
dynamic _createModelFromJson(String table, Map<String, dynamic> json) {
|
||||
switch (table) {
|
||||
case 'area':
|
||||
return Area.fromJson(json);
|
||||
case 'business':
|
||||
return Business.fromJson(json);
|
||||
case 'measure_types':
|
||||
final measureType = MeasureTypes.fromJson(json);
|
||||
listMeasures.add(measureType.toListMeasure());
|
||||
|
|
|
@ -127,6 +127,7 @@ class RestClient {
|
|||
final String uriString = '$baseUrl$endpoint';
|
||||
final Uri uri = Uri.parse(uriString);
|
||||
final Map<String, String> headers = _getHeaders();
|
||||
logger.d(jsonEncode(body));
|
||||
return _performRequest(
|
||||
() {
|
||||
return _client.patch(
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:ambito/src/entity/area/area.dart';
|
||||
import 'package:ambito/src/entity/entities.dart';
|
||||
import 'package:ambito/src/entity/lists/list_measure.dart';
|
||||
import 'package:ambito/src/entity/lists/list_measure_single.dart';
|
||||
|
@ -25,6 +26,7 @@ class AmbitoIsarDB {
|
|||
const engine = kIsWeb ? IsarEngine.sqlite : IsarEngine.isar;
|
||||
isar = Isar.open(
|
||||
schemas: [
|
||||
AreaSchema,
|
||||
ApprovalRequirementSchema,
|
||||
BusinessSchema,
|
||||
ExperienceReportSchema,
|
||||
|
@ -82,4 +84,10 @@ abstract class BaseDB {
|
|||
List<dynamic> getAll() {
|
||||
return collection.where().findAll();
|
||||
}
|
||||
|
||||
delete(int id) {
|
||||
isar.write((isar) {
|
||||
collection.delete(id);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ abstract class AmbitoTheme {
|
|||
onSecondary: Color(0xFFFFFFFF),
|
||||
secondaryContainer: Color(0xFFD2E5F4),
|
||||
onSecondaryContainer: Color(0xFF0A1D28),
|
||||
tertiary: Color(0xFFD9D9D9),
|
||||
tertiary: Color(0xFFf5f5f5),
|
||||
onTertiary: Color(0xFFFFFFFF),
|
||||
tertiaryContainer: Color(0xFFB8F483),
|
||||
onTertiaryContainer: Color(0xFF0D2000),
|
||||
|
|
634
lib/src/pages/dashboard/areas/dashboard_areas_page.dart
Normal file
634
lib/src/pages/dashboard/areas/dashboard_areas_page.dart
Normal file
|
@ -0,0 +1,634 @@
|
|||
import 'package:ambito/src/entity/_general/id_value/id_value.dart';
|
||||
import 'package:ambito/src/entity/area/area_datasource.dart';
|
||||
import 'package:ambito/src/entity/area/area_repository.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:google_geocoding_api/google_geocoding_api.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:screen_breakpoints/screen_breakpoints.dart';
|
||||
import 'package:syncfusion_flutter_core/theme.dart';
|
||||
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
|
||||
import 'package:toggle_switch/toggle_switch.dart';
|
||||
|
||||
import '../../../config/config.dart';
|
||||
import '../../../consts/consts.dart';
|
||||
import '../../../entity/area/area.dart';
|
||||
import '../../../entity/business/business.dart';
|
||||
import '../../../packages/ambito_api/base_api.dart';
|
||||
import '../../../packages/ambito_theme/ambito_theme.dart';
|
||||
import '../../../widgets/appbar/ambito_appbar.dart';
|
||||
import '../../../widgets/map/map_widget.dart';
|
||||
import '../../../widgets/map/marker_generator.dart';
|
||||
import '../../../widgets/page/base_page.dart';
|
||||
|
||||
class DashboardAreasPage extends StatefulWidget {
|
||||
const DashboardAreasPage(
|
||||
{super.key, required this.businessId, required this.userId});
|
||||
|
||||
final int businessId;
|
||||
final int userId;
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => DashboardAreasPageState();
|
||||
}
|
||||
|
||||
class DashboardAreasPageState extends State<DashboardAreasPage> {
|
||||
Widget mapWidget = const SizedBox();
|
||||
final api = GoogleGeocodingApi(googleApiKey, isLogged: false);
|
||||
Set<Marker> markers = {};
|
||||
Set<Polygon> polygons = {};
|
||||
List<Area> areas = [];
|
||||
Business? business;
|
||||
|
||||
int display = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
BaseApi().getContent('business').then((_) {
|
||||
business = isar.business.get(widget.businessId);
|
||||
|
||||
display = int.tryParse(Get.parameters['index'] ?? '0') ?? 0;
|
||||
|
||||
api
|
||||
.search(business!.addressComplete!, language: 'de')
|
||||
.then((GoogleGeocodingResponse response) {
|
||||
MarkerGenerator(64)
|
||||
.createBitmapDescriptorFromIconData(
|
||||
Icons.home,
|
||||
Colors.white,
|
||||
const Color(0xFF60845E),
|
||||
const Color(0xff87A34E),
|
||||
)
|
||||
.then((
|
||||
BitmapDescriptor bitMapDescriptor,
|
||||
) {
|
||||
final prettyAddress = response.results.firstOrNull?.mapToPretty();
|
||||
areas = AreaRepository().getAreasForBusiness(widget.businessId);
|
||||
|
||||
for (Area area in areas) {
|
||||
final polygon = area.toPolygon();
|
||||
if (polygon != null) {
|
||||
setState(() {
|
||||
polygons.add(polygon);
|
||||
});
|
||||
}
|
||||
}
|
||||
setState(() {
|
||||
markers.add(
|
||||
Marker(
|
||||
markerId: MarkerId(business!.name!),
|
||||
position: LatLng(
|
||||
prettyAddress?.latitude ?? 0,
|
||||
prettyAddress?.longitude ?? 0,
|
||||
),
|
||||
icon: bitMapDescriptor,
|
||||
),
|
||||
);
|
||||
mapWidget = MapWidget(
|
||||
markers: markers,
|
||||
polygons: polygons,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final AmbitoTheme theme = getTheme(context);
|
||||
|
||||
setState(() {});
|
||||
areas = AreaRepository().getAreasForBusiness(widget.businessId);
|
||||
|
||||
return BasePage().getPage(
|
||||
context,
|
||||
SingleChildScrollView(
|
||||
child: Align(
|
||||
alignment: Alignment.topCenter,
|
||||
child: Padding(
|
||||
padding: context.breakpoint.padding,
|
||||
child: SizedBox(
|
||||
width: 1152,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
theme.verticalSpacer,
|
||||
Text(
|
||||
'Flächen',
|
||||
style: theme.titleMedium,
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
Row(
|
||||
children: [
|
||||
ToggleSwitch(
|
||||
initialLabelIndex: display,
|
||||
totalSwitches: 2,
|
||||
minWidth: 200,
|
||||
borderWidth: 1,
|
||||
labels: const ['Karte', 'Liste'],
|
||||
activeBgColor: [theme.currentColorScheme.secondary],
|
||||
borderColor: [theme.currentColorScheme.secondary],
|
||||
inactiveBgColor: Colors.white,
|
||||
activeFgColor: theme.currentColorScheme.onSecondary,
|
||||
customTextStyles: [theme.bodyMedium],
|
||||
onToggle: (index) {
|
||||
setState(() {
|
||||
display = index ?? 0;
|
||||
});
|
||||
},
|
||||
),
|
||||
const Spacer(),
|
||||
OutlinedButton(
|
||||
style: OutlinedButton.styleFrom(
|
||||
minimumSize: const Size(200, 50),
|
||||
shape: RoundedRectangleBorder(
|
||||
side: const BorderSide(
|
||||
color: Colors.blue,
|
||||
width: 1,
|
||||
style: BorderStyle.solid),
|
||||
borderRadius: BorderRadius.circular(
|
||||
10,
|
||||
),
|
||||
),
|
||||
backgroundColor: theme.currentColorScheme.secondary,
|
||||
foregroundColor:
|
||||
theme.currentColorScheme.onSecondary,
|
||||
side: BorderSide(
|
||||
width: 1,
|
||||
color: theme.currentColorScheme.secondary),
|
||||
),
|
||||
onPressed: () async {
|
||||
final TextEditingController _controllerName =
|
||||
TextEditingController();
|
||||
final TextEditingController _controllerSize =
|
||||
TextEditingController();
|
||||
final TextEditingController _controllerDescription =
|
||||
TextEditingController();
|
||||
await showDialog<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) =>
|
||||
Dialog.fullscreen(
|
||||
child: Scaffold(
|
||||
appBar: AmbitoAppbar(
|
||||
links: const ['dashboard', 'massnahmen'],
|
||||
breakpoint:
|
||||
Breakpoint.fromContext(context),
|
||||
theme: theme),
|
||||
body: BreakpointBuilder(
|
||||
builder: (
|
||||
context,
|
||||
breakpoint,
|
||||
configuration,
|
||||
) {
|
||||
return SingleChildScrollView(
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width:
|
||||
Breakpoint.fromContext(context)
|
||||
.width,
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
theme.verticalSpacer,
|
||||
Text(
|
||||
'Fläche bearbeiten',
|
||||
style: theme.headlineMedium
|
||||
.copyWith(
|
||||
color: theme
|
||||
.currentColorScheme
|
||||
.onSurface,
|
||||
),
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
Align(
|
||||
alignment:
|
||||
Alignment.centerRight,
|
||||
child: Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.end,
|
||||
children: [
|
||||
OutlinedButton(
|
||||
style: OutlinedButton
|
||||
.styleFrom(
|
||||
minimumSize:
|
||||
const Size(
|
||||
200, 50),
|
||||
shape:
|
||||
RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
color: redColors[
|
||||
'primary']!,
|
||||
width: 1,
|
||||
style:
|
||||
BorderStyle
|
||||
.solid,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius
|
||||
.circular(
|
||||
10,
|
||||
),
|
||||
),
|
||||
backgroundColor: theme
|
||||
.currentColorScheme
|
||||
.surface
|
||||
.withOpacity(
|
||||
.1),
|
||||
foregroundColor: theme
|
||||
.currentColorScheme
|
||||
.primary,
|
||||
side: BorderSide(
|
||||
width: 1,
|
||||
color: theme
|
||||
.currentColorScheme
|
||||
.primary,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(
|
||||
context);
|
||||
},
|
||||
child: Text(
|
||||
'Abbrechen',
|
||||
style: theme
|
||||
.bodyMedium,
|
||||
),
|
||||
),
|
||||
theme.horizontalSpacer,
|
||||
OutlinedButton(
|
||||
onHover: (hover) {},
|
||||
style: OutlinedButton
|
||||
.styleFrom(
|
||||
minimumSize:
|
||||
const Size(
|
||||
200, 50),
|
||||
shape:
|
||||
RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
color: redColors[
|
||||
'primary']!,
|
||||
width: 1,
|
||||
style:
|
||||
BorderStyle
|
||||
.solid,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius
|
||||
.circular(
|
||||
10,
|
||||
),
|
||||
),
|
||||
backgroundColor: theme
|
||||
.currentColorScheme
|
||||
.secondary,
|
||||
foregroundColor: theme
|
||||
.currentColorScheme
|
||||
.onPrimary,
|
||||
side: BorderSide(
|
||||
width: 1,
|
||||
color: theme
|
||||
.currentColorScheme
|
||||
.secondary,
|
||||
),
|
||||
),
|
||||
onPressed: () async {
|
||||
Area area = Area()
|
||||
..id = isar.areas
|
||||
.autoIncrement()
|
||||
..description =
|
||||
_controllerDescription
|
||||
.value
|
||||
.text
|
||||
..business = [
|
||||
IdValue()
|
||||
..id = widget
|
||||
.businessId
|
||||
..value =
|
||||
business!
|
||||
.name!
|
||||
]
|
||||
..name =
|
||||
_controllerName
|
||||
.value
|
||||
.text
|
||||
..size =
|
||||
_controllerSize
|
||||
.value
|
||||
.text;
|
||||
await BaseApi()
|
||||
.postContent(
|
||||
'area',
|
||||
area.toJson());
|
||||
|
||||
await BaseApi()
|
||||
.getContent(
|
||||
'business');
|
||||
setState(() {
|
||||
areas = AreaRepository()
|
||||
.getAreasForBusiness(
|
||||
widget
|
||||
.businessId);
|
||||
logger.d(
|
||||
areas.length);
|
||||
});
|
||||
Navigator.pop(
|
||||
context);
|
||||
},
|
||||
child: Text(
|
||||
'Speichern',
|
||||
style: theme
|
||||
.bodyMedium,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
Card(
|
||||
elevation: 0,
|
||||
color: theme
|
||||
.currentColorScheme
|
||||
.tertiary,
|
||||
child: Padding(
|
||||
padding:
|
||||
EdgeInsets.all(20),
|
||||
child: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
children: [
|
||||
Text(
|
||||
'Allgemein',
|
||||
style: theme
|
||||
.headlineSmall,
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child:
|
||||
TextField(
|
||||
controller:
|
||||
_controllerName,
|
||||
maxLines: 1,
|
||||
decoration:
|
||||
InputDecoration(
|
||||
labelText:
|
||||
'Bezeichnung',
|
||||
isDense:
|
||||
true,
|
||||
hintText:
|
||||
'Bezeichnung',
|
||||
filled:
|
||||
true,
|
||||
fillColor:
|
||||
Colors
|
||||
.white,
|
||||
hoverColor:
|
||||
Colors
|
||||
.white,
|
||||
border:
|
||||
OutlineInputBorder(
|
||||
borderSide:
|
||||
BorderSide(
|
||||
color: redColors[
|
||||
'primary']!,
|
||||
width:
|
||||
1,
|
||||
style: BorderStyle
|
||||
.solid,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
8),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
theme
|
||||
.horizontalSpacer,
|
||||
Expanded(
|
||||
child:
|
||||
TextField(
|
||||
controller:
|
||||
_controllerSize,
|
||||
maxLines: 1,
|
||||
decoration:
|
||||
InputDecoration(
|
||||
suffixText:
|
||||
'm²',
|
||||
labelText:
|
||||
'Größe',
|
||||
isDense:
|
||||
true,
|
||||
hintText:
|
||||
'Größe',
|
||||
filled:
|
||||
true,
|
||||
fillColor:
|
||||
Colors
|
||||
.white,
|
||||
hoverColor:
|
||||
Colors
|
||||
.white,
|
||||
border:
|
||||
OutlineInputBorder(
|
||||
borderSide:
|
||||
BorderSide(
|
||||
color: redColors[
|
||||
'primary']!,
|
||||
width:
|
||||
1,
|
||||
style: BorderStyle
|
||||
.solid,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
8),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
TextField(
|
||||
controller:
|
||||
_controllerDescription,
|
||||
maxLines: 5,
|
||||
decoration:
|
||||
InputDecoration(
|
||||
labelText:
|
||||
'Notizen',
|
||||
isDense: true,
|
||||
hintText:
|
||||
'Notizen',
|
||||
filled: true,
|
||||
fillColor:
|
||||
Colors.white,
|
||||
hoverColor:
|
||||
Colors.white,
|
||||
border:
|
||||
OutlineInputBorder(
|
||||
borderSide:
|
||||
BorderSide(
|
||||
color: redColors[
|
||||
'primary']!,
|
||||
width: 1,
|
||||
style:
|
||||
BorderStyle
|
||||
.solid,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius
|
||||
.circular(
|
||||
8),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
Get.offAndToNamed('/dashboard/flaechen/1');
|
||||
},
|
||||
child: Text(
|
||||
'Neue Fläche',
|
||||
style: theme.bodyMedium,
|
||||
))
|
||||
],
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
(display == 0) ? mapWidget : gridWidget(areas),
|
||||
theme.verticalSpacer,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget gridWidget(List<Area> areas) {
|
||||
final AmbitoTheme theme = getTheme(context);
|
||||
|
||||
return SizedBox(
|
||||
width: 1152,
|
||||
child: SfDataGridTheme(
|
||||
data: SfDataGridThemeData(
|
||||
headerColor: theme.currentColorScheme.primaryContainer,
|
||||
sortIcon: Icon(
|
||||
Icons.keyboard_arrow_down,
|
||||
color: theme.currentColorScheme.primary,
|
||||
),
|
||||
),
|
||||
child: SfDataGrid(
|
||||
allowSorting: true,
|
||||
source: AreaDataSource(areas: areas, context: context),
|
||||
columnWidthMode: ColumnWidthMode.fill,
|
||||
columns: [
|
||||
GridColumn(
|
||||
visible: false,
|
||||
columnName: 'id',
|
||||
label: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'ID',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: theme.bodyMedium.copyWith(
|
||||
color: theme.currentColorScheme.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
GridColumn(
|
||||
columnName: 'name',
|
||||
label: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
'Bezeichnung',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: theme.bodyMedium.copyWith(
|
||||
color: theme.currentColorScheme.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
GridColumn(
|
||||
columnName: 'size',
|
||||
maximumWidth: 200,
|
||||
label: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
'Größe',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: theme.bodyMedium.copyWith(
|
||||
color: theme.currentColorScheme.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
GridColumn(
|
||||
columnName: 'description',
|
||||
maximumWidth: 100,
|
||||
allowSorting: false,
|
||||
label: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
'Notiz',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: theme.bodyMedium.copyWith(
|
||||
color: theme.currentColorScheme.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
GridColumn(
|
||||
columnName: 'action',
|
||||
allowSorting: false,
|
||||
maximumWidth: 150,
|
||||
label: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
'Aktion',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: theme.bodyMedium.copyWith(
|
||||
color: theme.currentColorScheme.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,18 @@
|
|||
import 'package:ambito/src/config/config.dart';
|
||||
import 'package:ambito/src/entity/business/business.dart';
|
||||
import 'package:ambito/src/packages/ambito_theme/ambito_theme.dart';
|
||||
import 'package:ambito/src/widgets/map/map_widget.dart';
|
||||
import 'package:ambito/src/widgets/map/marker_generator.dart';
|
||||
import 'package:ambito/src/widgets/page/base_page.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:google_geocoding_api/google_geocoding_api.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||
import 'package:screen_breakpoints/screen_breakpoints.dart';
|
||||
|
||||
import '../../consts/consts.dart';
|
||||
|
||||
part 'layouts/normal_layout_dashboard_page.dart';
|
||||
part 'layouts/small_layout_dashboard_page.dart';
|
||||
part 'parts/parts_dashboard_page.dart';
|
||||
|
@ -24,9 +31,49 @@ class DashboardPage extends StatefulWidget {
|
|||
class DashboardPageState extends State<DashboardPage> {
|
||||
List<Widget> cards = [];
|
||||
|
||||
Set<Marker> markers = {};
|
||||
|
||||
Widget mapWidget = CircularProgressIndicator();
|
||||
|
||||
final api = GoogleGeocodingApi(googleApiKey, isLogged: false);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
cards = [];
|
||||
Business? business = isar.business.get(100);
|
||||
|
||||
api
|
||||
.search(business!.addressComplete!, language: 'de')
|
||||
.then((GoogleGeocodingResponse response) {
|
||||
MarkerGenerator(64)
|
||||
.createBitmapDescriptorFromIconData(
|
||||
Icons.home,
|
||||
Colors.white,
|
||||
const Color(0xFF60845E),
|
||||
const Color(0xff87A34E),
|
||||
)
|
||||
.then((
|
||||
BitmapDescriptor bitMapDescriptor,
|
||||
) {
|
||||
final prettyAddress = response.results.firstOrNull?.mapToPretty();
|
||||
setState(() {
|
||||
markers.add(
|
||||
Marker(
|
||||
markerId: MarkerId(business.name!),
|
||||
position: LatLng(
|
||||
prettyAddress?.latitude ?? 0,
|
||||
prettyAddress?.longitude ?? 0,
|
||||
),
|
||||
icon: bitMapDescriptor,
|
||||
),
|
||||
);
|
||||
mapWidget = MapWidget(
|
||||
markers: markers,
|
||||
polygons: {},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ extension NormalLayoutDashboardPage on DashboardPageState {
|
|||
const Spacer(),
|
||||
SizedBox(
|
||||
width: 532,
|
||||
child: _fundingPart(theme),
|
||||
child: mapWidget,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'package:ambito/src/entity/entities.dart';
|
||||
import 'package:ambito/src/entity/measure/measure_repository.dart';
|
||||
import 'package:ambito/src/entity/enums/enum_details_type.dart';
|
||||
import 'package:ambito/src/extensions/extensions.dart';
|
||||
import 'package:animated_segmented_tab_control/animated_segmented_tab_control.dart';
|
||||
import 'package:expansion_tile_card/expansion_tile_card.dart';
|
||||
|
@ -17,7 +17,10 @@ import 'cards/_cards.dart';
|
|||
final Map<String, GlobalKey<ExpansionTileCardState>> globalKeys = {};
|
||||
|
||||
class MeasureDetailPage extends AmbitoPage {
|
||||
const MeasureDetailPage({super.key});
|
||||
const MeasureDetailPage({required this.id, required this.type, super.key});
|
||||
|
||||
final EnumDetailsType type;
|
||||
final int id;
|
||||
|
||||
@override
|
||||
final String path = 'massnahme';
|
||||
|
@ -29,7 +32,6 @@ class MeasureDetailPage extends AmbitoPage {
|
|||
}
|
||||
|
||||
class MeasureDetailPageState extends State<MeasureDetailPage> {
|
||||
late final String id;
|
||||
final ScrollController scrollController = ScrollController();
|
||||
bool showBackToTopButton = false;
|
||||
final Map<String, GlobalKey<ExpansionTileCardState>> expansionKeys = {};
|
||||
|
@ -42,10 +44,8 @@ class MeasureDetailPageState extends State<MeasureDetailPage> {
|
|||
void initState() {
|
||||
super.initState();
|
||||
|
||||
id = Get.parameters['id'] ?? '';
|
||||
if (id.isNotEmpty) {
|
||||
massnahme = MeasureRepository().get(int.parse(id)) as MeasureTypes;
|
||||
}
|
||||
//massnahme = MeasureRepository().get(int.parse(id)) as MeasureTypes;
|
||||
//}
|
||||
|
||||
scrollController.addListener(() {
|
||||
const showOffset = 10.0;
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import 'package:ambito/src/config/config.dart';
|
||||
import 'package:ambito/src/entity/enums/enum_details_type.dart';
|
||||
import 'package:ambito/src/entity/funding_program/funding_program_repository.dart';
|
||||
import 'package:ambito/src/entity/lists/list_display.dart';
|
||||
import 'package:ambito/src/entity/lists/list_repository.dart';
|
||||
import 'package:ambito/src/extensions/extensions.dart';
|
||||
import 'package:ambito/src/pages/ambito_page.dart';
|
||||
import 'package:ambito/src/pages/measure/detail/measure_detail_page.dart';
|
||||
import 'package:ambito/src/widgets/form/fields/field_title.dart';
|
||||
import 'package:ambito/src/widgets/form/form_widget.dart';
|
||||
import 'package:ambito/src/widgets/form/form_widget_type.dart';
|
||||
|
@ -13,6 +15,7 @@ import 'package:get/get.dart';
|
|||
import 'package:highlight_text/highlight_text.dart';
|
||||
import 'package:screen_breakpoints/screen_breakpoints.dart';
|
||||
|
||||
import '../../consts/consts.dart';
|
||||
import '../../entity/measure/measure_repository.dart';
|
||||
import '../../packages/ambito_notifier/notifier/filter_notifier.dart';
|
||||
import '../../packages/ambito_theme/ambito_theme.dart';
|
||||
|
@ -266,7 +269,15 @@ class MeasuresPageState extends State<MeasuresPage> {
|
|||
Get.toNamed(
|
||||
'/massnahmendatenbank/$filterCategory/$filterGroup/${measure.title!.toLowerCase().replaceUmlauts()}');
|
||||
} else if (measure.isMeasure == true) {
|
||||
Get.toNamed('/massnahme/${measure.title}');
|
||||
logger.d(measure.id);
|
||||
Get.to(
|
||||
() => MeasureDetailPage(
|
||||
id: measure.id!,
|
||||
type: measure.isMeasure!
|
||||
? EnumDetailsType.measure
|
||||
: EnumDetailsType.type,
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
onHover: (hovered) {},
|
||||
|
|
52
lib/src/widgets/buttons/outline_button.dart
Normal file
52
lib/src/widgets/buttons/outline_button.dart
Normal file
|
@ -0,0 +1,52 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../packages/ambito_theme/ambito_theme.dart';
|
||||
|
||||
class WidgetOutlineButton extends StatelessWidget {
|
||||
const WidgetOutlineButton({
|
||||
super.key,
|
||||
required this.onPressed,
|
||||
required this.title,
|
||||
required this.backgroundColor,
|
||||
required this.foregroundColor,
|
||||
required this.borderColor,
|
||||
});
|
||||
|
||||
final VoidCallback onPressed;
|
||||
final String title;
|
||||
final Color backgroundColor;
|
||||
final Color foregroundColor;
|
||||
final Color borderColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final AmbitoTheme theme = getTheme(context);
|
||||
return OutlinedButton(
|
||||
onHover: (hover) {},
|
||||
style: OutlinedButton.styleFrom(
|
||||
minimumSize: const Size(200, 50),
|
||||
shape: RoundedRectangleBorder(
|
||||
side: BorderSide(
|
||||
color: borderColor,
|
||||
width: 1,
|
||||
style: BorderStyle.solid,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(
|
||||
10,
|
||||
),
|
||||
),
|
||||
backgroundColor: backgroundColor,
|
||||
foregroundColor: foregroundColor,
|
||||
side: BorderSide(
|
||||
width: 1,
|
||||
color: borderColor,
|
||||
),
|
||||
),
|
||||
onPressed: onPressed,
|
||||
child: Text(
|
||||
title,
|
||||
style: theme.bodyMedium,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../../entity/area/area_repository.dart';
|
||||
import '../../../packages/ambito_api/base_api.dart';
|
||||
import '../../../packages/ambito_theme/ambito_theme.dart';
|
||||
import '../../buttons/outline_button.dart';
|
||||
|
||||
class DeleteAreaDialog extends StatelessWidget {
|
||||
const DeleteAreaDialog({super.key, required this.id});
|
||||
|
||||
final int id;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final AmbitoTheme theme = getTheme(context);
|
||||
return Dialog(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(10.0),
|
||||
),
|
||||
),
|
||||
child: SizedBox(
|
||||
width: 800,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'Fläche löschen',
|
||||
style: theme.headlineSmall.copyWith(
|
||||
color: theme.currentColorScheme.error,
|
||||
),
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
Text(
|
||||
'Möchten Sie die Fläche wirklich löschen?',
|
||||
style: theme.bodyMedium,
|
||||
),
|
||||
Text(
|
||||
'Diese wird auch in der Flächenliste entgültig gelöscht.',
|
||||
style: theme.bodyMedium,
|
||||
),
|
||||
theme.verticalSpacerMax,
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
WidgetOutlineButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
title: 'Abbrechen',
|
||||
backgroundColor: theme.currentColorScheme.tertiary,
|
||||
foregroundColor: theme.currentColorScheme.error,
|
||||
borderColor: theme.currentColorScheme.error,
|
||||
),
|
||||
theme.horizontalSpacer,
|
||||
WidgetOutlineButton(
|
||||
onPressed: () {
|
||||
AreaRepository().delete(id);
|
||||
BaseApi().deleteContent('area', id).then((_) {
|
||||
Navigator.pop(context);
|
||||
Get.offAndToNamed('/dashboard/flaechen/1');
|
||||
});
|
||||
},
|
||||
title: 'Löschen',
|
||||
backgroundColor: theme.currentColorScheme.error,
|
||||
foregroundColor: theme.currentColorScheme.onError,
|
||||
borderColor: theme.currentColorScheme.error,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:ambito/src/widgets/dialogs/delete_entity/delete_area_dialog.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class DeleteEntityDialog {
|
||||
static Future<dynamic> show(
|
||||
{required BuildContext context,
|
||||
required String type,
|
||||
required int id}) async {
|
||||
Map<String, dynamic> dialogs = {
|
||||
'area': DeleteAreaDialog,
|
||||
};
|
||||
|
||||
return await showDialog<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => DeleteAreaDialog(id: id),
|
||||
);
|
||||
}
|
||||
}
|
210
lib/src/widgets/dialogs/edit_entity_dialog/edit_area_dialog.dart
Normal file
210
lib/src/widgets/dialogs/edit_entity_dialog/edit_area_dialog.dart
Normal file
|
@ -0,0 +1,210 @@
|
|||
import 'package:ambito/src/widgets/buttons/outline_button.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:screen_breakpoints/screen_breakpoints.dart';
|
||||
|
||||
import '../../../consts/consts.dart';
|
||||
import '../../../entity/area/area.dart';
|
||||
import '../../../entity/area/area_repository.dart';
|
||||
import '../../../packages/ambito_api/base_api.dart';
|
||||
import '../../../packages/ambito_theme/ambito_theme.dart';
|
||||
import '../../appbar/ambito_appbar.dart';
|
||||
|
||||
class EditAreaDialog extends StatelessWidget {
|
||||
final TextEditingController _controllerName = TextEditingController();
|
||||
final TextEditingController _controllerSize = TextEditingController();
|
||||
final TextEditingController _controllerDescription = TextEditingController();
|
||||
final int id;
|
||||
|
||||
EditAreaDialog({super.key, required this.id});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final AmbitoTheme theme = getTheme(context);
|
||||
|
||||
Area? area = isar.areas.where().idEqualTo(id).findFirst();
|
||||
if (area != null) {
|
||||
_controllerName.text = area.name!;
|
||||
_controllerDescription.text = area.description!;
|
||||
_controllerSize.text = area.size!;
|
||||
}
|
||||
|
||||
return Dialog.fullscreen(
|
||||
child: Scaffold(
|
||||
appBar: AmbitoAppbar(
|
||||
links: const ['dashboard', 'massnahmen'],
|
||||
breakpoint: Breakpoint.fromContext(context),
|
||||
theme: theme),
|
||||
body: BreakpointBuilder(
|
||||
builder: (
|
||||
context,
|
||||
breakpoint,
|
||||
configuration,
|
||||
) {
|
||||
return SingleChildScrollView(
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: Breakpoint.fromContext(context).width,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
theme.verticalSpacer,
|
||||
Text(
|
||||
'Fläche bearbeiten',
|
||||
style: theme.headlineMedium.copyWith(
|
||||
color: theme.currentColorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
WidgetOutlineButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
title: 'Abbrechen',
|
||||
backgroundColor: theme
|
||||
.currentColorScheme.surface
|
||||
.withOpacity(.1),
|
||||
foregroundColor:
|
||||
theme.currentColorScheme.primary,
|
||||
borderColor: theme.currentColorScheme.primary,
|
||||
),
|
||||
theme.horizontalSpacer,
|
||||
WidgetOutlineButton(
|
||||
onPressed: () {
|
||||
Area area = isar.areas.get(id)!;
|
||||
area.description =
|
||||
_controllerDescription.value.text;
|
||||
area.name = _controllerName.value.text;
|
||||
area.size = _controllerSize.value.text;
|
||||
AreaRepository().put(area);
|
||||
BaseApi()
|
||||
.patchContent('area', id, area.toJson())
|
||||
.then((_) {
|
||||
Navigator.pop(context);
|
||||
Get.offAndToNamed('/dashboard/flaechen/1');
|
||||
});
|
||||
},
|
||||
title: 'Speichern',
|
||||
backgroundColor:
|
||||
theme.currentColorScheme.secondary,
|
||||
foregroundColor:
|
||||
theme.currentColorScheme.onPrimary,
|
||||
borderColor: theme.currentColorScheme.secondary,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
Card(
|
||||
elevation: 0,
|
||||
color: theme.currentColorScheme.tertiary,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(20),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Allgemein',
|
||||
style: theme.headlineSmall,
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _controllerName,
|
||||
maxLines: 1,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Bezeichnung',
|
||||
isDense: true,
|
||||
hintText: 'Bezeichnung',
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
hoverColor: Colors.white,
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: redColors['primary']!,
|
||||
width: 1,
|
||||
style: BorderStyle.solid,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
theme.horizontalSpacer,
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _controllerSize,
|
||||
maxLines: 1,
|
||||
decoration: InputDecoration(
|
||||
suffixText: 'm²',
|
||||
labelText: 'Größe',
|
||||
isDense: true,
|
||||
hintText: 'Größe',
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
hoverColor: Colors.white,
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: redColors['primary']!,
|
||||
width: 1,
|
||||
style: BorderStyle.solid,
|
||||
),
|
||||
borderRadius:
|
||||
BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
TextField(
|
||||
controller: _controllerDescription,
|
||||
maxLines: 5,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Notizen',
|
||||
isDense: true,
|
||||
hintText: 'Notizen',
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
hoverColor: Colors.white,
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: redColors['primary']!,
|
||||
width: 1,
|
||||
style: BorderStyle.solid,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
import 'package:ambito/src/widgets/dialogs/edit_entity_dialog/edit_area_dialog.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class EditEntityDialog {
|
||||
static Future<dynamic> show(
|
||||
{required BuildContext context,
|
||||
required String type,
|
||||
required int id}) async {
|
||||
Map<String, dynamic> dialogs = {
|
||||
'area': EditAreaDialog,
|
||||
};
|
||||
|
||||
return await showDialog<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => EditAreaDialog(id: id),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
import '../../../consts/consts.dart';
|
||||
import '../../../entity/area/area.dart';
|
||||
import '../../../entity/area/area_repository.dart';
|
||||
import '../../../packages/ambito_api/base_api.dart';
|
||||
import '../../../packages/ambito_theme/ambito_theme.dart';
|
||||
import '../../buttons/outline_button.dart';
|
||||
|
||||
class EditAreaNoticeDialog extends StatelessWidget {
|
||||
final TextEditingController _controllerDescription = TextEditingController();
|
||||
final int id;
|
||||
|
||||
EditAreaNoticeDialog({super.key, required this.id});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final AmbitoTheme theme = getTheme(context);
|
||||
|
||||
Area? area = isar.areas.where().idEqualTo(id).findFirst();
|
||||
if (area != null) {
|
||||
_controllerDescription.text = area.description!;
|
||||
}
|
||||
|
||||
return Dialog(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(10.0),
|
||||
),
|
||||
),
|
||||
child: SizedBox(
|
||||
width: 800,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'Notiz:',
|
||||
style: theme.headlineSmall.copyWith(
|
||||
color: theme.currentColorScheme.primary,
|
||||
),
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
TextField(
|
||||
controller: _controllerDescription,
|
||||
maxLines: 5,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Notizen',
|
||||
isDense: true,
|
||||
hintText: 'Notizen',
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: redColors['primary']!,
|
||||
width: 1,
|
||||
style: BorderStyle.solid,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
),
|
||||
),
|
||||
theme.verticalSpacer,
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
WidgetOutlineButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
title: 'Abbrechen',
|
||||
backgroundColor:
|
||||
theme.currentColorScheme.surface.withOpacity(.1),
|
||||
foregroundColor: theme.currentColorScheme.primary,
|
||||
borderColor: theme.currentColorScheme.primary,
|
||||
),
|
||||
theme.horizontalSpacer,
|
||||
WidgetOutlineButton(
|
||||
onPressed: () {
|
||||
Area area = isar.areas.get(id)!;
|
||||
area.description = _controllerDescription.value.text;
|
||||
AreaRepository().put(area);
|
||||
BaseApi()
|
||||
.patchContent('area', id, area.toJson())
|
||||
.then((_) {
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
title: 'Speichern',
|
||||
backgroundColor: theme.currentColorScheme.secondary,
|
||||
foregroundColor: theme.currentColorScheme.onPrimary,
|
||||
borderColor: theme.currentColorScheme.secondary,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'edit_area_notice_dialog.dart';
|
||||
|
||||
class EditFieldDialog {
|
||||
static Future<dynamic> show(
|
||||
{required BuildContext context,
|
||||
required String type,
|
||||
required int id}) async {
|
||||
Map<String, dynamic> dialogs = {
|
||||
'area_notice': EditAreaNoticeDialog,
|
||||
};
|
||||
|
||||
return await showDialog<String>(
|
||||
context: context,
|
||||
builder: (BuildContext context) => EditAreaNoticeDialog(id: id),
|
||||
);
|
||||
}
|
||||
}
|
25
lib/src/widgets/icons/icons_helpers.dart
Normal file
25
lib/src/widgets/icons/icons_helpers.dart
Normal file
|
@ -0,0 +1,25 @@
|
|||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
|
||||
Future<BitmapDescriptor> iconToBitmapDescriptor(IconData iconData) async {
|
||||
final pictureRecorder = PictureRecorder();
|
||||
final canvas = Canvas(pictureRecorder);
|
||||
final textPainter = TextPainter(textDirection: TextDirection.ltr);
|
||||
final iconStr = String.fromCharCode(iconData.codePoint);
|
||||
textPainter.text = TextSpan(
|
||||
text: iconStr,
|
||||
style: TextStyle(
|
||||
letterSpacing: 0.0,
|
||||
fontSize: 48.0,
|
||||
fontFamily: iconData.fontFamily,
|
||||
color: Colors.red,
|
||||
));
|
||||
textPainter.layout();
|
||||
textPainter.paint(canvas, const Offset(0.0, 0.0));
|
||||
final picture = pictureRecorder.endRecording();
|
||||
final image = await picture.toImage(48, 48);
|
||||
final bytes = await image.toByteData(format: ImageByteFormat.png);
|
||||
return BitmapDescriptor.bytes(bytes!.buffer.asUint8List());
|
||||
}
|
56
lib/src/widgets/map/map_widget.dart
Normal file
56
lib/src/widgets/map/map_widget.dart
Normal file
|
@ -0,0 +1,56 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
|
||||
class MapWidget extends StatefulWidget {
|
||||
const MapWidget({super.key, required this.markers, required this.polygons});
|
||||
|
||||
final Set<Marker>? markers;
|
||||
final Set<Polygon>? polygons;
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => MapWidgetState();
|
||||
}
|
||||
|
||||
class MapWidgetState extends State<MapWidget> {
|
||||
final Completer<GoogleMapController> _controller =
|
||||
Completer<GoogleMapController>();
|
||||
|
||||
static CameraPosition _initialPos = const CameraPosition(
|
||||
target: LatLng(0, 0),
|
||||
zoom: 14.4746,
|
||||
);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
if (widget.markers != null) {
|
||||
setState(() {
|
||||
_initialPos =
|
||||
CameraPosition(target: widget.markers!.first.position, zoom: 14);
|
||||
});
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: 525,
|
||||
child: GoogleMap(
|
||||
mapToolbarEnabled: true,
|
||||
mapType: MapType.hybrid,
|
||||
markers: widget.markers ?? {},
|
||||
polygons: widget.polygons ?? {},
|
||||
initialCameraPosition: _initialPos,
|
||||
onMapCreated: (GoogleMapController controller) {
|
||||
_controller.complete(controller);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
76
lib/src/widgets/map/marker_generator.dart
Normal file
76
lib/src/widgets/map/marker_generator.dart
Normal file
|
@ -0,0 +1,76 @@
|
|||
import 'dart:math';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
|
||||
class MarkerGenerator {
|
||||
final _markerSize;
|
||||
double _circleStrokeWidth = 0;
|
||||
double _circleOffset = 0;
|
||||
double _outlineCircleWidth = 0;
|
||||
double _fillCircleWidth = 0;
|
||||
double _iconSize = 0;
|
||||
double _iconOffset = 0;
|
||||
|
||||
MarkerGenerator(this._markerSize) {
|
||||
_circleStrokeWidth = _markerSize / 10.0;
|
||||
_circleOffset = _markerSize / 2;
|
||||
_outlineCircleWidth = _circleOffset - (_circleStrokeWidth / 2);
|
||||
_fillCircleWidth = _markerSize / 2;
|
||||
final outlineCircleInnerWidth = _markerSize - (2 * _circleStrokeWidth);
|
||||
_iconSize = sqrt(pow(outlineCircleInnerWidth, 2) / 2);
|
||||
final rectDiagonal = sqrt(2 * pow(_markerSize, 2));
|
||||
final circleDistanceToCorners =
|
||||
(rectDiagonal - outlineCircleInnerWidth) / 2;
|
||||
_iconOffset = sqrt(pow(circleDistanceToCorners, 2) / 2);
|
||||
}
|
||||
|
||||
Future<BitmapDescriptor> createBitmapDescriptorFromIconData(IconData iconData,
|
||||
Color iconColor, Color circleColor, Color backgroundColor) async {
|
||||
final pictureRecorder = PictureRecorder();
|
||||
final canvas = Canvas(pictureRecorder);
|
||||
|
||||
_paintCircleFill(canvas, backgroundColor);
|
||||
_paintCircleStroke(canvas, circleColor);
|
||||
_paintIcon(canvas, iconColor, iconData);
|
||||
|
||||
final picture = pictureRecorder.endRecording();
|
||||
final image =
|
||||
await picture.toImage(_markerSize.round(), _markerSize.round());
|
||||
final bytes = await image.toByteData(format: ImageByteFormat.png);
|
||||
|
||||
return BitmapDescriptor.bytes(bytes!.buffer.asUint8List());
|
||||
}
|
||||
|
||||
void _paintCircleFill(Canvas canvas, Color color) {
|
||||
final paint = Paint()
|
||||
..style = PaintingStyle.fill
|
||||
..color = color;
|
||||
canvas.drawCircle(
|
||||
Offset(_circleOffset, _circleOffset), _fillCircleWidth, paint);
|
||||
}
|
||||
|
||||
void _paintCircleStroke(Canvas canvas, Color color) {
|
||||
final paint = Paint()
|
||||
..style = PaintingStyle.stroke
|
||||
..color = color
|
||||
..strokeWidth = _circleStrokeWidth;
|
||||
canvas.drawCircle(
|
||||
Offset(_circleOffset, _circleOffset), _outlineCircleWidth, paint);
|
||||
}
|
||||
|
||||
void _paintIcon(Canvas canvas, Color color, IconData iconData) {
|
||||
final textPainter = TextPainter(textDirection: TextDirection.ltr);
|
||||
textPainter.text = TextSpan(
|
||||
text: String.fromCharCode(iconData.codePoint),
|
||||
style: TextStyle(
|
||||
letterSpacing: 0.0,
|
||||
fontSize: _iconSize,
|
||||
fontFamily: iconData.fontFamily,
|
||||
color: color,
|
||||
));
|
||||
textPainter.layout();
|
||||
textPainter.paint(canvas, Offset(_iconOffset, _iconOffset));
|
||||
}
|
||||
}
|
222
pubspec.lock
222
pubspec.lock
|
@ -246,14 +246,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.8"
|
||||
dart_earcut:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_earcut
|
||||
sha256: "41b493147e30a051efb2da1e3acb7f38fe0db60afba24ac1ea5684cee272721e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -270,14 +262,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.7.0"
|
||||
dio_cache_interceptor:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dio_cache_interceptor
|
||||
sha256: fb7905c0d12075d8786a6b63bffd64ae062d053f682cfaf28d145a2686507308
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.5.0"
|
||||
dio_web_adapter:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -379,14 +363,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.1"
|
||||
flutter_compass:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_compass
|
||||
sha256: "1b4d7e6c95a675ec8482b5c9c9ccf1ebf0ced3dbec59dce28ad609da953de850"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.8.1"
|
||||
flutter_dotenv:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -432,30 +408,14 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_map:
|
||||
dependency: "direct main"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_map
|
||||
sha256: "2ecb34619a4be19df6f40c2f8dce1591675b4eff7a6857bd8f533706977385da"
|
||||
name: flutter_plugin_android_lifecycle
|
||||
sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.2"
|
||||
flutter_map_cache:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_map_cache
|
||||
sha256: "47607b8d95ca791f0367d18955035d098faf80990e5e3bb0dbfa26271a6c2f43"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
flutter_map_location_marker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_map_location_marker
|
||||
sha256: "1971d9ad7c8bedb15cb6a03598c0a3ad66ac6f7f165ad90d801bd5f636120f38"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.1.1"
|
||||
version: "2.0.23"
|
||||
flutter_rating:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -570,6 +530,62 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.2.1"
|
||||
google_geocoding_api:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: google_geocoding_api
|
||||
sha256: "92080e6a0cfcd28b2a73454213e8d0c067342b237392a4431c2787ac10ffeca2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.2"
|
||||
google_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_maps
|
||||
sha256: "4d6e199c561ca06792c964fa24b2bac7197bf4b401c2e1d23e345e5f9939f531"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.1"
|
||||
google_maps_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: google_maps_flutter
|
||||
sha256: "209856c8e5571626afba7182cf634b2910069dc567954e76ec3e3fb37f5e9db3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.10.0"
|
||||
google_maps_flutter_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_maps_flutter_android
|
||||
sha256: bccf64ccbb2ea672dc62a61177b315a340af86b0228564484b023657544a3fd5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.14.11"
|
||||
google_maps_flutter_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_maps_flutter_ios
|
||||
sha256: "6f798adb0aa1db5adf551f2e39e24bd06c8c0fbe4de912fb2d9b5b3f48147b02"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.13.2"
|
||||
google_maps_flutter_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_maps_flutter_platform_interface
|
||||
sha256: a951981c22d790848efb9f114f81794945bc5c06bc566238a419a92f110af6cb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.9.5"
|
||||
google_maps_flutter_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_maps_flutter_web
|
||||
sha256: ff39211bd25d7fad125d19f757eba85bd154460907cd4d135e07e3d0f98a4130
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.10"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -698,14 +714,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.9.0"
|
||||
latlong2:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: latlong2
|
||||
sha256: "98227922caf49e6056f91b6c56945ea1c7b166f28ffcd5fb8e72fc0b453cc8fe"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.1"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -746,14 +754,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
lists:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lists
|
||||
sha256: "4ca5c19ae4350de036a7e996cdd1ee39c93ac0a2b840f4915459b7d0a7d4ab27"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
logger:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -778,14 +778,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.2-main.4"
|
||||
maps_toolkit:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: maps_toolkit
|
||||
sha256: "277877f9505208acacd2a0794ef190e836a5ffee58ebc8efc5b9ca8de50e3e2f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -810,14 +802,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
mgrs_dart:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mgrs_dart
|
||||
sha256: fb89ae62f05fa0bb90f70c31fc870bcbcfd516c843fb554452ab3396f78586f7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -870,18 +854,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
|
||||
sha256: "8c4967f8b7cb46dc914e178daa29813d83ae502e0529d7b0478330616a691ef7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.12"
|
||||
version: "2.2.14"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
||||
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "2.4.1"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -994,14 +978,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.8"
|
||||
polylabel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: polylabel
|
||||
sha256: "41b9099afb2aa6c1730bdd8a0fab1400d287694ec7615dd8516935fa3144214b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1010,14 +986,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.1"
|
||||
proj4dart:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: proj4dart
|
||||
sha256: c8a659ac9b6864aa47c171e78d41bbe6f5e1d7bd790a5814249e6b68bc44324e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1050,6 +1018,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.28.0"
|
||||
sanitize_html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sanitize_html
|
||||
sha256: "12669c4a913688a26555323fb9cec373d8f9fbe091f2d01c40c723b33caa8989"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
screen_breakpoints:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -1070,10 +1046,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
sha256: "3b9febd815c9ca29c9e3520d50ec32f49157711e143b7a4ca039eb87e8ade5ab"
|
||||
sha256: "7f172d1b06de5da47b6264c2692ee2ead20bbbc246690427cdb4fc301cd0c549"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.3"
|
||||
version: "2.3.4"
|
||||
shared_preferences_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1251,34 +1227,42 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_flutter_calendar
|
||||
sha256: "0f049bbc7ea1f86a22db7c9090d967c71dc1c72f36b83393c66090141c37f819"
|
||||
sha256: "20118a598cf5ae5b7ec84fa364e2b51070800f078466158fcd25864e1b5a2cfd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "27.2.3"
|
||||
version: "27.2.5"
|
||||
syncfusion_flutter_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: syncfusion_flutter_core
|
||||
sha256: a39ddfb22b30c7cba620fec7dc682e46f151998febd25bca5519c17431084951
|
||||
sha256: "325f519ce4ad8edd81811c21b853d72018529e353584490824da0555156ba076"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "27.2.3"
|
||||
version: "27.2.5"
|
||||
syncfusion_flutter_datagrid:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_flutter_datagrid
|
||||
sha256: "1ba098d01468ed9dd400bf69403eedfbbd3626dce675005697a2698834f05fde"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "27.2.5"
|
||||
syncfusion_flutter_datepicker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_flutter_datepicker
|
||||
sha256: "5af3301119607fe834ca0d222013102884e6644fc8324430a8ff56f73442e3d5"
|
||||
sha256: "2177e49eb8a1c0fce7081e40f5613c986d00e5e63cbeb98a6012f65ca156bfc7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "27.2.3"
|
||||
version: "27.2.5"
|
||||
syncfusion_localizations:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: syncfusion_localizations
|
||||
sha256: d6123f30f100a3e5e1dc235c6195194f5b82ca51fa8ce94718812b8b05120b60
|
||||
sha256: c08ffb408a7425b911538be8d607a00bac82cb3be8d24a1a6af7a531bd889db0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "27.2.3"
|
||||
version: "27.2.5"
|
||||
synchronized:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1319,6 +1303,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
toggle_switch:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: toggle_switch
|
||||
sha256: dca04512d7c23ed320d6c5ede1211a404f177d54d353bf785b07d15546a86ce5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
toml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1335,14 +1327,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
unicode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: unicode
|
||||
sha256: "0f69e46593d65245774d4f17125c6084d2c20b4e473a983f6e21b7d7762218f1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.1"
|
||||
universal_html:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -1415,14 +1399,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
wkt_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: wkt_parser
|
||||
sha256: "8a555fc60de3116c00aad67891bcab20f81a958e4219cc106e3c037aa3937f13"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
10
pubspec.yaml
10
pubspec.yaml
|
@ -13,11 +13,6 @@ dependencies:
|
|||
sdk: flutter
|
||||
cupertino_icons: ^1.0.6
|
||||
intl: ^0.19.0
|
||||
flutter_map: ^7.0.2
|
||||
latlong2: ^0.9.1
|
||||
flutter_map_location_marker: ^9.1.1
|
||||
flutter_map_cache: ^1.5.1
|
||||
maps_toolkit: ^3.0.0
|
||||
fast_immutable_collections: ^10.2.4
|
||||
badges: ^3.1.2
|
||||
logger: ^2.4.0
|
||||
|
@ -62,6 +57,11 @@ dependencies:
|
|||
bulleted_list: ^0.0.1+0.1a
|
||||
super_bullet_list: ^0.0.3
|
||||
animated_segmented_tab_control: ^2.0.0
|
||||
google_maps_flutter: ^2.10.0
|
||||
google_geocoding_api: ^1.5.2
|
||||
toggle_switch: ^2.3.0
|
||||
syncfusion_flutter_datagrid: ^27.2.5
|
||||
|
||||
|
||||
|
||||
dev_dependencies:
|
||||
|
|
|
@ -1,19 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!--
|
||||
If you are serving your web app in a path other than the root, change the
|
||||
href value below to reflect the base path you are serving from.
|
||||
|
||||
The path provided below has to start and end with a slash "/" in order for
|
||||
it to work correctly.
|
||||
|
||||
For more details:
|
||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
|
||||
|
||||
This is a placeholder for base href that will be replaced by the value of
|
||||
the `--base-href` argument provided to `flutter build`.
|
||||
-->
|
||||
<base href="$FLUTTER_BASE_HREF">
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
@ -96,6 +83,9 @@
|
|||
100%{transform:rotate(330deg);}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAb2d7gn5CLWnVZTaSapRYHjnZapSP9BQM&libraries=drawing"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="loader"></div>
|
||||
|
|
Loading…
Reference in a new issue