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/config/config.dart';
|
||||||
import 'package:ambito/src/consts/consts.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_measure.dart';
|
||||||
import 'package:ambito/src/entity/lists/list_repository.dart';
|
import 'package:ambito/src/entity/lists/list_repository.dart';
|
||||||
import 'package:ambito/src/packages/ambito_api/base_api.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/packages/ambito_sharedprefs/ambito_sharedprefs.dart';
|
||||||
import 'package:ambito/src/pages/calendar/calendar_page.dart';
|
import 'package:ambito/src/pages/calendar/calendar_page.dart';
|
||||||
import 'package:ambito/src/pages/calendar/calendar_page_year.dart';
|
import 'package:ambito/src/pages/calendar/calendar_page_year.dart';
|
||||||
|
import 'package:ambito/src/pages/dashboard/areas/dashboard_areas_page.dart';
|
||||||
import 'package:ambito/src/pages/dashboard/dashboard_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/error/error_page.dart';
|
||||||
import 'package:ambito/src/pages/measure/categories/measure_categories_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('funding_program'),
|
||||||
//BaseApi().getContent('location_requirements'),
|
//BaseApi().getContent('location_requirements'),
|
||||||
//BaseApi().getContent('reference_implementation'),
|
//BaseApi().getContent('reference_implementation'),
|
||||||
//BaseApi().getContent('business'),
|
BaseApi().getContent('business'),
|
||||||
|
BaseApi().getContent('area'),
|
||||||
//BaseApi().getContent('service_provider'),
|
//BaseApi().getContent('service_provider'),
|
||||||
//BaseApi().getContent('service_provider_contact_person'),
|
//BaseApi().getContent('service_provider_contact_person'),
|
||||||
//BaseApi().getContent('material'),
|
//BaseApi().getContent('material'),
|
||||||
|
@ -132,35 +135,42 @@ class Ambito extends StatelessWidget {
|
||||||
GetPage(
|
GetPage(
|
||||||
name: '/dashboard',
|
name: '/dashboard',
|
||||||
page: () => DashboardPage(
|
page: () => DashboardPage(
|
||||||
businessId: prefs.getInt('currentUser') ?? 22,
|
businessId: prefs.getInt('currentUser') ?? 100,
|
||||||
userId: 0,
|
userId: 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
GetPage(
|
GetPage(
|
||||||
name: '/dashboard/meine-massnahmen',
|
name: '/dashboard/meine-massnahmen',
|
||||||
page: () => DashboardPage(
|
page: () => DashboardPage(
|
||||||
businessId: prefs.getInt('currentUser') ?? 22,
|
businessId: prefs.getInt('currentUser') ?? 100,
|
||||||
userId: 0,
|
userId: 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
GetPage(
|
GetPage(
|
||||||
name: '/dashboard/urkunde',
|
name: '/dashboard/urkunde',
|
||||||
page: () => DashboardPage(
|
page: () => DashboardPage(
|
||||||
businessId: prefs.getInt('currentUser') ?? 22,
|
businessId: prefs.getInt('currentUser') ?? 100,
|
||||||
userId: 0,
|
userId: 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
GetPage(
|
GetPage(
|
||||||
name: '/dashboard/flaechen',
|
name: '/dashboard/flaechen',
|
||||||
page: () => DashboardPage(
|
page: () => DashboardAreasPage(
|
||||||
businessId: prefs.getInt('currentUser') ?? 22,
|
businessId: prefs.getInt('currentUser') ?? 100,
|
||||||
|
userId: 0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
GetPage(
|
||||||
|
name: '/dashboard/flaechen/:index',
|
||||||
|
page: () => DashboardAreasPage(
|
||||||
|
businessId: prefs.getInt('currentUser') ?? 100,
|
||||||
userId: 0,
|
userId: 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
GetPage(
|
GetPage(
|
||||||
name: '/dashboard/stammdaten',
|
name: '/dashboard/stammdaten',
|
||||||
page: () => DashboardPage(
|
page: () => DashboardPage(
|
||||||
businessId: prefs.getInt('currentUser') ?? 22,
|
businessId: prefs.getInt('currentUser') ?? 100,
|
||||||
userId: 0,
|
userId: 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -169,8 +179,9 @@ class Ambito extends StatelessWidget {
|
||||||
page: () => const MeasureCreatePage(),
|
page: () => const MeasureCreatePage(),
|
||||||
),
|
),
|
||||||
GetPage(
|
GetPage(
|
||||||
name: '/massnahme/:id',
|
name: '/massnahme/',
|
||||||
page: () => const MeasureDetailPage(),
|
page: () => const MeasureDetailPage(
|
||||||
|
id: 0, type: EnumDetailsType.measure),
|
||||||
),
|
),
|
||||||
GetPage(
|
GetPage(
|
||||||
name: '/error',
|
name: '/error',
|
||||||
|
|
|
@ -45,8 +45,11 @@ const BreakpointConfiguration myBreakpoints = BreakpointConfiguration(
|
||||||
xxl: null,
|
xxl: null,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const googleApiKey = 'AIzaSyAb2d7gn5CLWnVZTaSapRYHjnZapSP9BQM';
|
||||||
|
|
||||||
const baserowToken = 'TFxO7vzBLVRCu9I3VMoHmTuCvSu8aCDi';
|
const baserowToken = 'TFxO7vzBLVRCu9I3VMoHmTuCvSu8aCDi';
|
||||||
const baserowIds = {
|
const baserowIds = {
|
||||||
|
"area": 403344,
|
||||||
"measure": 328253,
|
"measure": 328253,
|
||||||
"measure_general": 396946,
|
"measure_general": 396946,
|
||||||
"measure_details": 342622,
|
"measure_details": 342622,
|
||||||
|
|
|
@ -14,5 +14,5 @@ class IdValue {
|
||||||
factory IdValue.fromJson(Map<String, dynamic> json) =>
|
factory IdValue.fromJson(Map<String, dynamic> json) =>
|
||||||
_$IdValueFromJson(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) =>
|
factory IdValueColor.fromJson(Map<String, dynamic> json) =>
|
||||||
_$IdValueColorFromJson(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) =>
|
factory IdValueMix.fromJson(Map<String, dynamic> json) =>
|
||||||
_$IdValueMixFromJson(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 {
|
class Business extends BaseEntity with EntityWithId {
|
||||||
Business();
|
Business();
|
||||||
|
|
||||||
@JsonKey(name: 'Modellbetrieb')
|
@JsonKey(name: 'field_2404114')
|
||||||
@Index()
|
@Index()
|
||||||
String? name;
|
String? name;
|
||||||
|
|
||||||
@JsonKey(name: 'Ursprungsgebiet')
|
@JsonKey(name: 'field_3021727')
|
||||||
IdValueColor? areaOfOrigin;
|
IdValueColor? businessType;
|
||||||
@JsonKey(name: 'Ansprechpartner')
|
|
||||||
String? businessOwner;
|
@JsonKey(name: 'field_2404115')
|
||||||
@JsonKey(name: 'Feld 6')
|
IdValueColor? businessOrigin;
|
||||||
String? businessEmail;
|
|
||||||
@JsonKey(name: 'Feld 7')
|
@JsonKey(name: 'field_2404155')
|
||||||
String? businessPhone;
|
List<IdValue>? referenceImplementation;
|
||||||
@JsonKey(name: 'Feld 8')
|
|
||||||
String? contactName;
|
@JsonKey(name: 'field_2404143')
|
||||||
@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')
|
|
||||||
String? region;
|
String? region;
|
||||||
@JsonKey(name: 'Umgesetze_Maßnahmen')
|
|
||||||
List<IdValueColor>? measures;
|
@JsonKey(name: 'field_2404117')
|
||||||
@JsonKey(name: '05 Referenzumsetzung')
|
String? businessContact;
|
||||||
List<IdValueColor>? referenceImplementation;
|
@JsonKey(name: 'field_2404119')
|
||||||
@JsonKey(name: '07 Erfahrungsbericht Umsetuzung')
|
String? businessEmail;
|
||||||
List<IdValueColor>? experienceReport;
|
@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) =>
|
factory Business.fromJson(Map<String, dynamic> json) =>
|
||||||
_$BusinessFromJson(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 {
|
class ListDisplay {
|
||||||
ListDisplay();
|
ListDisplay();
|
||||||
|
|
||||||
|
int? id;
|
||||||
String? title;
|
String? title;
|
||||||
String? description;
|
String? description;
|
||||||
Widget? image;
|
Widget? image;
|
||||||
|
|
|
@ -43,6 +43,7 @@ class ListMeasureSingle extends BaseEntity with EntityWithId {
|
||||||
extension ListMeasureExtension on ListMeasureSingle {
|
extension ListMeasureExtension on ListMeasureSingle {
|
||||||
ListDisplay asListDisplay() {
|
ListDisplay asListDisplay() {
|
||||||
return ListDisplay()
|
return ListDisplay()
|
||||||
|
..id = toJson()['id']
|
||||||
..title = name
|
..title = name
|
||||||
..description = description
|
..description = description
|
||||||
..image = getImage()
|
..image = getImage()
|
||||||
|
|
|
@ -52,6 +52,7 @@ extension ListMeasureTypeGroupCategoryExtension
|
||||||
.isNotEmpty;
|
.isNotEmpty;
|
||||||
|
|
||||||
return ListDisplay()
|
return ListDisplay()
|
||||||
|
..id = toJson()['id']
|
||||||
..title = measureType
|
..title = measureType
|
||||||
..description = description
|
..description = description
|
||||||
..image = getImage()
|
..image = getImage()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:ambito/main.dart';
|
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/entities.dart';
|
||||||
import 'package:ambito/src/entity/measure/details/measure_details.dart';
|
import 'package:ambito/src/entity/measure/details/measure_details.dart';
|
||||||
import 'package:ambito/src/entity/measure/details/measure_details_repository.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 'package:get/get.dart';
|
||||||
|
|
||||||
import '../../config/config.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/funding_program/funding_program_repository.dart';
|
||||||
import '../../entity/measure/measure_repository.dart';
|
import '../../entity/measure/measure_repository.dart';
|
||||||
|
|
||||||
|
@ -22,6 +25,61 @@ class BaseApi {
|
||||||
tables = baserowIds;
|
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 {
|
Future<bool> getContent(String table) async {
|
||||||
init();
|
init();
|
||||||
int tableId = tables[table] ?? 0;
|
int tableId = tables[table] ?? 0;
|
||||||
|
@ -36,18 +94,20 @@ class BaseApi {
|
||||||
var results = json['results'];
|
var results = json['results'];
|
||||||
|
|
||||||
final repositoryMap = {
|
final repositoryMap = {
|
||||||
//'tree_type': TreeTypeRepository().put,
|
'area': AreaRepository().put,
|
||||||
//'measure': MeasureRepository().putMeasureGroups,
|
'business': BusinessRepository().put,
|
||||||
|
'funding_program': FundingProgramRepository().put,
|
||||||
'measure_types': MeasureRepository().put,
|
'measure_types': MeasureRepository().put,
|
||||||
'measure_general': MeasureGeneralRepository().put,
|
'measure_general': MeasureGeneralRepository().put,
|
||||||
'measure_details': MeasureDetailsRepository().put,
|
'measure_details': MeasureDetailsRepository().put,
|
||||||
'measure_types_details': MeasureTypesDetailsRepository().put,
|
'measure_types_details': MeasureTypesDetailsRepository().put,
|
||||||
//'measure_combination': MeasureCombinationRepository().put,
|
//'measure_combination': MeasureCombinationRepository().put,
|
||||||
//'organism': OrganismRepository().put,
|
//'organism': OrganismRepository().put,
|
||||||
'funding_program': FundingProgramRepository().put,
|
|
||||||
//'location_requirements': LocationRequirementsRepository().put,
|
//'location_requirements': LocationRequirementsRepository().put,
|
||||||
//'reference_implementation': ReferenceImplementationRepository().put,
|
//'reference_implementation': ReferenceImplementationRepository().put,
|
||||||
//'business': BusinessRepository().put,
|
//'tree_type': TreeTypeRepository().put,
|
||||||
|
//'measure': MeasureRepository().putMeasureGroups,
|
||||||
|
|
||||||
//'service_provider': ServiceProviderRepository().put,
|
//'service_provider': ServiceProviderRepository().put,
|
||||||
//'service_provider_contact_person':
|
//'service_provider_contact_person':
|
||||||
// ServiceProviderContactPersonRepository().put,
|
// ServiceProviderContactPersonRepository().put,
|
||||||
|
@ -70,6 +130,10 @@ class BaseApi {
|
||||||
|
|
||||||
dynamic _createModelFromJson(String table, Map<String, dynamic> json) {
|
dynamic _createModelFromJson(String table, Map<String, dynamic> json) {
|
||||||
switch (table) {
|
switch (table) {
|
||||||
|
case 'area':
|
||||||
|
return Area.fromJson(json);
|
||||||
|
case 'business':
|
||||||
|
return Business.fromJson(json);
|
||||||
case 'measure_types':
|
case 'measure_types':
|
||||||
final measureType = MeasureTypes.fromJson(json);
|
final measureType = MeasureTypes.fromJson(json);
|
||||||
listMeasures.add(measureType.toListMeasure());
|
listMeasures.add(measureType.toListMeasure());
|
||||||
|
|
|
@ -127,6 +127,7 @@ class RestClient {
|
||||||
final String uriString = '$baseUrl$endpoint';
|
final String uriString = '$baseUrl$endpoint';
|
||||||
final Uri uri = Uri.parse(uriString);
|
final Uri uri = Uri.parse(uriString);
|
||||||
final Map<String, String> headers = _getHeaders();
|
final Map<String, String> headers = _getHeaders();
|
||||||
|
logger.d(jsonEncode(body));
|
||||||
return _performRequest(
|
return _performRequest(
|
||||||
() {
|
() {
|
||||||
return _client.patch(
|
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/entities.dart';
|
||||||
import 'package:ambito/src/entity/lists/list_measure.dart';
|
import 'package:ambito/src/entity/lists/list_measure.dart';
|
||||||
import 'package:ambito/src/entity/lists/list_measure_single.dart';
|
import 'package:ambito/src/entity/lists/list_measure_single.dart';
|
||||||
|
@ -25,6 +26,7 @@ class AmbitoIsarDB {
|
||||||
const engine = kIsWeb ? IsarEngine.sqlite : IsarEngine.isar;
|
const engine = kIsWeb ? IsarEngine.sqlite : IsarEngine.isar;
|
||||||
isar = Isar.open(
|
isar = Isar.open(
|
||||||
schemas: [
|
schemas: [
|
||||||
|
AreaSchema,
|
||||||
ApprovalRequirementSchema,
|
ApprovalRequirementSchema,
|
||||||
BusinessSchema,
|
BusinessSchema,
|
||||||
ExperienceReportSchema,
|
ExperienceReportSchema,
|
||||||
|
@ -82,4 +84,10 @@ abstract class BaseDB {
|
||||||
List<dynamic> getAll() {
|
List<dynamic> getAll() {
|
||||||
return collection.where().findAll();
|
return collection.where().findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete(int id) {
|
||||||
|
isar.write((isar) {
|
||||||
|
collection.delete(id);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ abstract class AmbitoTheme {
|
||||||
onSecondary: Color(0xFFFFFFFF),
|
onSecondary: Color(0xFFFFFFFF),
|
||||||
secondaryContainer: Color(0xFFD2E5F4),
|
secondaryContainer: Color(0xFFD2E5F4),
|
||||||
onSecondaryContainer: Color(0xFF0A1D28),
|
onSecondaryContainer: Color(0xFF0A1D28),
|
||||||
tertiary: Color(0xFFD9D9D9),
|
tertiary: Color(0xFFf5f5f5),
|
||||||
onTertiary: Color(0xFFFFFFFF),
|
onTertiary: Color(0xFFFFFFFF),
|
||||||
tertiaryContainer: Color(0xFFB8F483),
|
tertiaryContainer: Color(0xFFB8F483),
|
||||||
onTertiaryContainer: Color(0xFF0D2000),
|
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/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/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:ambito/src/widgets/page/base_page.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.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:percent_indicator/linear_percent_indicator.dart';
|
||||||
import 'package:screen_breakpoints/screen_breakpoints.dart';
|
import 'package:screen_breakpoints/screen_breakpoints.dart';
|
||||||
|
|
||||||
|
import '../../consts/consts.dart';
|
||||||
|
|
||||||
part 'layouts/normal_layout_dashboard_page.dart';
|
part 'layouts/normal_layout_dashboard_page.dart';
|
||||||
part 'layouts/small_layout_dashboard_page.dart';
|
part 'layouts/small_layout_dashboard_page.dart';
|
||||||
part 'parts/parts_dashboard_page.dart';
|
part 'parts/parts_dashboard_page.dart';
|
||||||
|
@ -24,9 +31,49 @@ class DashboardPage extends StatefulWidget {
|
||||||
class DashboardPageState extends State<DashboardPage> {
|
class DashboardPageState extends State<DashboardPage> {
|
||||||
List<Widget> cards = [];
|
List<Widget> cards = [];
|
||||||
|
|
||||||
|
Set<Marker> markers = {};
|
||||||
|
|
||||||
|
Widget mapWidget = CircularProgressIndicator();
|
||||||
|
|
||||||
|
final api = GoogleGeocodingApi(googleApiKey, isLogged: false);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
cards = [];
|
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();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ extension NormalLayoutDashboardPage on DashboardPageState {
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 532,
|
width: 532,
|
||||||
child: _fundingPart(theme),
|
child: mapWidget,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:ambito/src/entity/entities.dart';
|
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:ambito/src/extensions/extensions.dart';
|
||||||
import 'package:animated_segmented_tab_control/animated_segmented_tab_control.dart';
|
import 'package:animated_segmented_tab_control/animated_segmented_tab_control.dart';
|
||||||
import 'package:expansion_tile_card/expansion_tile_card.dart';
|
import 'package:expansion_tile_card/expansion_tile_card.dart';
|
||||||
|
@ -17,7 +17,10 @@ import 'cards/_cards.dart';
|
||||||
final Map<String, GlobalKey<ExpansionTileCardState>> globalKeys = {};
|
final Map<String, GlobalKey<ExpansionTileCardState>> globalKeys = {};
|
||||||
|
|
||||||
class MeasureDetailPage extends AmbitoPage {
|
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
|
@override
|
||||||
final String path = 'massnahme';
|
final String path = 'massnahme';
|
||||||
|
@ -29,7 +32,6 @@ class MeasureDetailPage extends AmbitoPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
class MeasureDetailPageState extends State<MeasureDetailPage> {
|
class MeasureDetailPageState extends State<MeasureDetailPage> {
|
||||||
late final String id;
|
|
||||||
final ScrollController scrollController = ScrollController();
|
final ScrollController scrollController = ScrollController();
|
||||||
bool showBackToTopButton = false;
|
bool showBackToTopButton = false;
|
||||||
final Map<String, GlobalKey<ExpansionTileCardState>> expansionKeys = {};
|
final Map<String, GlobalKey<ExpansionTileCardState>> expansionKeys = {};
|
||||||
|
@ -42,10 +44,8 @@ class MeasureDetailPageState extends State<MeasureDetailPage> {
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
id = Get.parameters['id'] ?? '';
|
//massnahme = MeasureRepository().get(int.parse(id)) as MeasureTypes;
|
||||||
if (id.isNotEmpty) {
|
//}
|
||||||
massnahme = MeasureRepository().get(int.parse(id)) as MeasureTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollController.addListener(() {
|
scrollController.addListener(() {
|
||||||
const showOffset = 10.0;
|
const showOffset = 10.0;
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import 'package:ambito/src/config/config.dart';
|
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/funding_program/funding_program_repository.dart';
|
||||||
import 'package:ambito/src/entity/lists/list_display.dart';
|
import 'package:ambito/src/entity/lists/list_display.dart';
|
||||||
import 'package:ambito/src/entity/lists/list_repository.dart';
|
import 'package:ambito/src/entity/lists/list_repository.dart';
|
||||||
import 'package:ambito/src/extensions/extensions.dart';
|
import 'package:ambito/src/extensions/extensions.dart';
|
||||||
import 'package:ambito/src/pages/ambito_page.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/fields/field_title.dart';
|
||||||
import 'package:ambito/src/widgets/form/form_widget.dart';
|
import 'package:ambito/src/widgets/form/form_widget.dart';
|
||||||
import 'package:ambito/src/widgets/form/form_widget_type.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:highlight_text/highlight_text.dart';
|
||||||
import 'package:screen_breakpoints/screen_breakpoints.dart';
|
import 'package:screen_breakpoints/screen_breakpoints.dart';
|
||||||
|
|
||||||
|
import '../../consts/consts.dart';
|
||||||
import '../../entity/measure/measure_repository.dart';
|
import '../../entity/measure/measure_repository.dart';
|
||||||
import '../../packages/ambito_notifier/notifier/filter_notifier.dart';
|
import '../../packages/ambito_notifier/notifier/filter_notifier.dart';
|
||||||
import '../../packages/ambito_theme/ambito_theme.dart';
|
import '../../packages/ambito_theme/ambito_theme.dart';
|
||||||
|
@ -266,7 +269,15 @@ class MeasuresPageState extends State<MeasuresPage> {
|
||||||
Get.toNamed(
|
Get.toNamed(
|
||||||
'/massnahmendatenbank/$filterCategory/$filterGroup/${measure.title!.toLowerCase().replaceUmlauts()}');
|
'/massnahmendatenbank/$filterCategory/$filterGroup/${measure.title!.toLowerCase().replaceUmlauts()}');
|
||||||
} else if (measure.isMeasure == true) {
|
} 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) {},
|
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"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.8"
|
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:
|
dart_style:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -270,14 +262,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.7.0"
|
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:
|
dio_web_adapter:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -379,14 +363,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.4.1"
|
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:
|
flutter_dotenv:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -432,30 +408,14 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
flutter_map:
|
flutter_plugin_android_lifecycle:
|
||||||
dependency: "direct main"
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_map
|
name: flutter_plugin_android_lifecycle
|
||||||
sha256: "2ecb34619a4be19df6f40c2f8dce1591675b4eff7a6857bd8f533706977385da"
|
sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.2"
|
version: "2.0.23"
|
||||||
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"
|
|
||||||
flutter_rating:
|
flutter_rating:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -570,6 +530,62 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.2.1"
|
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:
|
graphs:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -698,14 +714,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.9.0"
|
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:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -746,14 +754,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "4.0.0"
|
||||||
lists:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: lists
|
|
||||||
sha256: "4ca5c19ae4350de036a7e996cdd1ee39c93ac0a2b840f4915459b7d0a7d4ab27"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.1"
|
|
||||||
logger:
|
logger:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -778,14 +778,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.2-main.4"
|
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:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -810,14 +802,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0"
|
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:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -870,18 +854,18 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_android
|
name: path_provider_android
|
||||||
sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
|
sha256: "8c4967f8b7cb46dc914e178daa29813d83ae502e0529d7b0478330616a691ef7"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.12"
|
version: "2.2.14"
|
||||||
path_provider_foundation:
|
path_provider_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_foundation
|
name: path_provider_foundation
|
||||||
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
|
sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "2.4.1"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -994,14 +978,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.8"
|
version: "2.1.8"
|
||||||
polylabel:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: polylabel
|
|
||||||
sha256: "41b9099afb2aa6c1730bdd8a0fab1400d287694ec7615dd8516935fa3144214b"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.1"
|
|
||||||
pool:
|
pool:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1010,14 +986,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.1"
|
version: "1.5.1"
|
||||||
proj4dart:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: proj4dart
|
|
||||||
sha256: c8a659ac9b6864aa47c171e78d41bbe6f5e1d7bd790a5814249e6b68bc44324e
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.0"
|
|
||||||
provider:
|
provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -1050,6 +1018,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.28.0"
|
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:
|
screen_breakpoints:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -1070,10 +1046,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shared_preferences_android
|
name: shared_preferences_android
|
||||||
sha256: "3b9febd815c9ca29c9e3520d50ec32f49157711e143b7a4ca039eb87e8ade5ab"
|
sha256: "7f172d1b06de5da47b6264c2692ee2ead20bbbc246690427cdb4fc301cd0c549"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.3"
|
version: "2.3.4"
|
||||||
shared_preferences_foundation:
|
shared_preferences_foundation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1251,34 +1227,42 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: syncfusion_flutter_calendar
|
name: syncfusion_flutter_calendar
|
||||||
sha256: "0f049bbc7ea1f86a22db7c9090d967c71dc1c72f36b83393c66090141c37f819"
|
sha256: "20118a598cf5ae5b7ec84fa364e2b51070800f078466158fcd25864e1b5a2cfd"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "27.2.3"
|
version: "27.2.5"
|
||||||
syncfusion_flutter_core:
|
syncfusion_flutter_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: syncfusion_flutter_core
|
name: syncfusion_flutter_core
|
||||||
sha256: a39ddfb22b30c7cba620fec7dc682e46f151998febd25bca5519c17431084951
|
sha256: "325f519ce4ad8edd81811c21b853d72018529e353584490824da0555156ba076"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
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:
|
syncfusion_flutter_datepicker:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: syncfusion_flutter_datepicker
|
name: syncfusion_flutter_datepicker
|
||||||
sha256: "5af3301119607fe834ca0d222013102884e6644fc8324430a8ff56f73442e3d5"
|
sha256: "2177e49eb8a1c0fce7081e40f5613c986d00e5e63cbeb98a6012f65ca156bfc7"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "27.2.3"
|
version: "27.2.5"
|
||||||
syncfusion_localizations:
|
syncfusion_localizations:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: syncfusion_localizations
|
name: syncfusion_localizations
|
||||||
sha256: d6123f30f100a3e5e1dc235c6195194f5b82ca51fa8ce94718812b8b05120b60
|
sha256: c08ffb408a7425b911538be8d607a00bac82cb3be8d24a1a6af7a531bd889db0
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "27.2.3"
|
version: "27.2.5"
|
||||||
synchronized:
|
synchronized:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1319,6 +1303,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
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:
|
toml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1335,14 +1327,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.0"
|
||||||
unicode:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: unicode
|
|
||||||
sha256: "0f69e46593d65245774d4f17125c6084d2c20b4e473a983f6e21b7d7762218f1"
|
|
||||||
url: "https://pub.dev"
|
|
||||||
source: hosted
|
|
||||||
version: "0.3.1"
|
|
||||||
universal_html:
|
universal_html:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1415,14 +1399,6 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.1"
|
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:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
10
pubspec.yaml
10
pubspec.yaml
|
@ -13,11 +13,6 @@ dependencies:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
cupertino_icons: ^1.0.6
|
cupertino_icons: ^1.0.6
|
||||||
intl: ^0.19.0
|
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
|
fast_immutable_collections: ^10.2.4
|
||||||
badges: ^3.1.2
|
badges: ^3.1.2
|
||||||
logger: ^2.4.0
|
logger: ^2.4.0
|
||||||
|
@ -62,6 +57,11 @@ dependencies:
|
||||||
bulleted_list: ^0.0.1+0.1a
|
bulleted_list: ^0.0.1+0.1a
|
||||||
super_bullet_list: ^0.0.3
|
super_bullet_list: ^0.0.3
|
||||||
animated_segmented_tab_control: ^2.0.0
|
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:
|
dev_dependencies:
|
||||||
|
|
|
@ -1,19 +1,6 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<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">
|
<base href="$FLUTTER_BASE_HREF">
|
||||||
|
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
@ -96,6 +83,9 @@
|
||||||
100%{transform:rotate(330deg);}
|
100%{transform:rotate(330deg);}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAb2d7gn5CLWnVZTaSapRYHjnZapSP9BQM&libraries=drawing"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="loader"></div>
|
<div class="loader"></div>
|
||||||
|
|
Loading…
Reference in a new issue