diff --git a/.circleci/config.yml b/.circleci/config.yml
index 0679d7af..c51fcfee 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -83,6 +83,9 @@ commands:
- run:
command: cp .env.prod .env
name: Apply Production Environment
+ - run:
+ command: fvm dart run build_runner build
+ name: Generate Swagger API
prepare_workspace:
description: Attach the workspace at ~/attached_workspace and list its contents
steps:
diff --git a/.circleci/src/commands/prepare_project.yml b/.circleci/src/commands/prepare_project.yml
index 087165a0..1f1a2220 100644
--- a/.circleci/src/commands/prepare_project.yml
+++ b/.circleci/src/commands/prepare_project.yml
@@ -1,7 +1,10 @@
-steps:
- - run:
- name: Generate Translations
- command: fvm dart run slang
- - run:
- name: Apply Production Environment
- command: cp .env.prod .env
+steps:
+ - run:
+ name: Generate Translations
+ command: fvm dart run slang
+ - run:
+ name: Apply Production Environment
+ command: cp .env.prod .env
+ - run:
+ command: fvm dart run build_runner build
+ name: Generate Swagger API
diff --git a/.gitignore b/.gitignore
index de3a35ab..81f5ce88 100644
--- a/.gitignore
+++ b/.gitignore
@@ -73,6 +73,7 @@ lib/generated_plugin_registrant.dart
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
+/.idea/caches/deviceStreaming.xml
# AWS User-specific
.idea/**/aws.xml
@@ -204,3 +205,5 @@ devtools_options.yaml
.env
report.xml
node_modules
+
+/lib/swagger_generated_code/
diff --git a/.idea/misc.xml b/.idea/misc.xml
index f4f6d798..964bcb8e 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,3 @@
-
@@ -6,4 +5,7 @@
+
+
+
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 5f7f0169..4b0defe6 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,7 +1,8 @@
{
"FSharp.suggestGitignore": false,
"cSpell.words": [
- "gruene"
+ "gruene",
+ "housenumber"
],
"files.eol": "\n"
}
\ No newline at end of file
diff --git a/README.md b/README.md
index c22eeabe..cc5d623a 100644
--- a/README.md
+++ b/README.md
@@ -38,3 +38,20 @@ The application uses the following environment variables:
You can copy the `.env.dev` file to `.env` and fill in the values.
Please note that it's not possible to use the OIDC login if issuer url does not have a secure connection.
+### Compiling the app
+
+installing flutter via fvm
+`fvm install`
+
+downloading flutter/dart packages
+`fvm flutter pub get`
+
+#### Creating translation files
+
+Before building the app, it's needed to generate the translation files
+
+`fvm flutter dart run slang`
+
+#### Generate SwaggerAPI Files
+
+`fvm dart run build_runner build`
\ No newline at end of file
diff --git a/analysis_options.yaml b/analysis_options.yaml
index c43aec85..78997bce 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1,7 +1,7 @@
include: package:flutter_lints/flutter.yaml
analyzer:
- exclude: [build/**]
+ exclude: [build/**, lib/swagger_generated_code/**]
errors:
always_use_package_imports: error
directives_ordering: error
diff --git a/assets/symbols/add_marker.svg b/assets/symbols/add_marker.svg
new file mode 100644
index 00000000..c9e77594
--- /dev/null
+++ b/assets/symbols/add_marker.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/assets/symbols/posters/poster.png b/assets/symbols/posters/poster.png
new file mode 100644
index 00000000..93ef9a87
Binary files /dev/null and b/assets/symbols/posters/poster.png differ
diff --git a/assets/symbols/posters/poster_damaged.png b/assets/symbols/posters/poster_damaged.png
new file mode 100644
index 00000000..71843634
Binary files /dev/null and b/assets/symbols/posters/poster_damaged.png differ
diff --git a/assets/symbols/posters/poster_taken_down.png b/assets/symbols/posters/poster_taken_down.png
new file mode 100644
index 00000000..dad832e0
Binary files /dev/null and b/assets/symbols/posters/poster_taken_down.png differ
diff --git a/build.yaml b/build.yaml
new file mode 100644
index 00000000..16cafd91
--- /dev/null
+++ b/build.yaml
@@ -0,0 +1,13 @@
+targets:
+ $default:
+ sources:
+ - swaggers/**
+ builders:
+ chopper_generator:
+ options:
+ header: "// Generated code"
+ swagger_dart_code_generator:
+ options:
+ input_folder: "swaggers/"
+ output_folder: "lib/swagger_generated_code/"
+ multipart_file_type: "MultipartFile"
\ No newline at end of file
diff --git a/lib/app/constants/config.dart b/lib/app/constants/config.dart
index 8ab03798..bc3d49e1 100644
--- a/lib/app/constants/config.dart
+++ b/lib/app/constants/config.dart
@@ -6,4 +6,8 @@ class Config {
static String get oidcClientId => dotenv.env['OIDC_CLIENT_ID'] ?? '';
static String get oidcIssuer => dotenv.env['OIDC_ISSUER'] ?? '';
static bool get useLogin => dotenv.env['USE_LOGIN'] == 'true';
+ static String get maplibreUrl => dotenv.env['MAP_MAPLIBRE_URL'] ?? '';
+ static String get addressSearchUrl => dotenv.env['MAP_ADDRESSSEARCH_URL'] ?? '';
+ static String get gruenesNetzApiUrl => dotenv.env['GRUENES_NETZ_API_URL'] ?? 'http://localhost:5000';
+ static String get gruenesNetzApiKey => dotenv.env['GRUENES_NETZ_API_KEY'] ?? '';
}
diff --git a/lib/app/geocode/nominatim.dart b/lib/app/geocode/nominatim.dart
new file mode 100644
index 00000000..67eec9dd
--- /dev/null
+++ b/lib/app/geocode/nominatim.dart
@@ -0,0 +1,222 @@
+import 'dart:convert';
+
+import 'package:gruene_app/app/constants/config.dart';
+import 'package:http/http.dart' as http;
+
+/// OSM Nominatim helper
+class Nominatim {
+ /// Searches for a place by it's coordinates or OSM object
+ ///
+ /// Use either [lat] and [lon] or [osmType] and [osmId], but don't combine
+ /// them.
+ ///
+ /// Using [addressDetails] will include a breakdown of the address into
+ /// elements. Default is false.
+ ///
+ /// Using [extraTags] will include additional information in the result if
+ /// available, e.g. wikipedia link, opening hours. Default is false.
+ ///
+ /// Using [nameDetails] will include a list of alternative names in the
+ /// results. These may include language variants, references, operator and
+ /// brand. Default is false.
+ ///
+ /// Using [language] will set the preferred language order for showing search
+ /// results, overrides the value specified in the `Accept-Language` HTTP
+ /// header if you are running in a browser. Either use a standard RFC2616
+ /// accept-language string or a simple comma-separated list of language codes.
+ ///
+ /// Using [zoom] will set the level of detail required for the address.
+ /// This is a number that corresponds roughly to the zoom level used in map
+ /// frameworks like Leaflet.js, Openlayers etc. In terms of address details
+ /// the zoom levels are as follows:
+ ///
+ ///
+ ///
+ /// zoom
+ /// address detail
+ ///
+ ///
+ ///
+ ///
+ /// 3
+ /// country
+ ///
+ ///
+ /// 5
+ /// state
+ ///
+ ///
+ /// 8
+ /// county
+ ///
+ ///
+ /// 10
+ /// city
+ ///
+ ///
+ /// 14
+ /// suburb
+ ///
+ ///
+ /// 16
+ /// major streets
+ ///
+ ///
+ /// 17
+ /// major and minor streets
+ ///
+ ///
+ /// 18
+ /// building
+ ///
+ ///
+ ///
+ static Future reverseSearch({
+ double? lat,
+ double? lon,
+ String? osmType,
+ int? osmId,
+ bool addressDetails = false,
+ bool extraTags = false,
+ bool nameDetails = false,
+ String? language,
+ int zoom = 18,
+ }) async {
+ final baseServer = Uri.parse(Config.addressSearchUrl);
+ assert(baseServer.scheme == 'https', 'It\'s required to have the address search on https');
+
+ final notNullParameters = [lat, lon, osmType, osmId].where((e) => e != null).length;
+ assert(
+ notNullParameters == 2,
+ 'Either provide lat and lon or osmType and osmId',
+ );
+ assert(
+ (lat != null && lon != null && osmType == null && osmId == null) ||
+ (lat == null && lon == null && osmType != null && osmId != null),
+ 'Do not mix coordinates and OSM object',
+ );
+ assert(
+ ['N', 'W', 'R', null].contains(osmType),
+ 'osmType needs to be one of N, W, R',
+ );
+ assert(
+ zoom >= 0 && zoom <= 18,
+ 'Zoom needs to be between 0 and 18',
+ );
+
+ final uri = Uri.https(
+ baseServer.host,
+ '${baseServer.path}/reverse',
+ {
+ 'format': 'jsonv2',
+ 'zoom': zoom.toString(),
+ if (lat != null) 'lat': lat.toString(),
+ if (lon != null) 'lon': lon.toString(),
+ if (osmType != null) 'osm_type': osmType,
+ if (osmId != null) 'osm_id': osmId.toString(),
+ if (addressDetails) 'addressdetails': '1',
+ if (extraTags) 'extratags': '1',
+ if (nameDetails) 'namedetails': '1',
+ if (language != null) 'accept-language': language,
+ },
+ );
+ final response = await http.get(uri);
+ final data = json.decode(response.body) as Map;
+ if (data['error'] != null) {
+ throw Exception(data['error']);
+ }
+ return Place.fromJson(data);
+ }
+}
+
+/// A place in the nominatim system
+class Place {
+ // ignore: public_member_api_docs
+ Place({
+ required this.placeId,
+ required this.osmType,
+ required this.osmId,
+ required this.boundingBox,
+ required this.lat,
+ required this.lon,
+ required this.displayName,
+ required this.placeRank,
+ required this.category,
+ required this.type,
+ required this.importance,
+ this.icon,
+ this.address,
+ this.extraTags,
+ this.nameDetails,
+ });
+
+ // ignore: public_member_api_docs
+ factory Place.fromJson(Map json) => Place(
+ placeId: json['place_id'] as int,
+ osmType: json['osm_type'] != null ? json['osm_type'] as String : null,
+ osmId: json['osm_id'] != null ? json['osm_id'] as int : null,
+ boundingBox: (json['boundingbox'] as List).map((e) => e as String).toList(),
+ lat: double.parse(json['lat'] as String),
+ lon: double.parse(json['lon'] as String),
+ displayName: json['display_name'] as String,
+ placeRank: json['place_rank'] as int,
+ category: json['category'] as String,
+ type: json['type'] as String,
+ importance: json['importance'] is int ? (json['importance'] as int).toDouble() : json['importance'] as double,
+ icon: json['icon'] != null ? json['icon'] as String : null,
+ address: json['address'] != null ? json['address'] as Map : null,
+ extraTags: json['extratags'] != null ? json['extratags'] as Map : null,
+ nameDetails: json['namedetails'] != null ? json['namedetails'] as Map : null,
+ );
+
+ /// Reference to the Nominatim internal database ID
+ /// See https://nominatim.org/release-docs/latest/api/Output/#place_id-is-not-a-persistent-id
+ final int placeId;
+
+ /// Reference to the OSM object
+ final String? osmType;
+
+ /// Reference to the OSM object
+ final int? osmId;
+
+ /// Area of corner coordinates
+ /// See https://nominatim.org/release-docs/latest/api/Output/#boundingbox
+ final List boundingBox;
+
+ /// Latitude of the centroid of the object
+ final double lat;
+
+ /// Longitude of the centroid of the object
+ final double lon;
+
+ /// Full comma-separated address
+ final String displayName;
+
+ /// Search rank of the object
+ final int placeRank;
+
+ /// Key of the main OSM tag
+ final String category;
+
+ /// Value of the main OSM tag
+ final String type;
+
+ /// Computed importance rank
+ final double importance;
+
+ /// Link to class icon (if available)
+ final String? icon;
+
+ /// Map of address details
+ /// Only with [Nominatim.searchByName(addressDetails: true)]
+ /// See https://nominatim.org/release-docs/latest/api/Output/#addressdetails
+ final Map? address;
+
+ /// Map with additional useful tags like website or max speed
+ /// Only with [Nominatim.searchByName(extraTags: true)]
+ final Map? extraTags;
+
+ /// Map with full list of available names including ref etc.
+ /// Only with [Nominatim.searchByName(nameDetails: true)]
+ final Map? nameDetails;
+}
diff --git a/lib/app/services/gruene_api_campaigns_service.dart b/lib/app/services/gruene_api_campaigns_service.dart
new file mode 100644
index 00000000..8616c939
--- /dev/null
+++ b/lib/app/services/gruene_api_campaigns_service.dart
@@ -0,0 +1,108 @@
+import 'package:chopper/chopper.dart';
+import 'package:gruene_app/app/constants/config.dart';
+import 'package:gruene_app/features/campaigns/models/marker_item_model.dart';
+import 'package:gruene_app/features/campaigns/models/posters/poster_create_model.dart';
+import 'package:gruene_app/swagger_generated_code/gruene_api.swagger.dart';
+import 'package:http/http.dart';
+import 'package:http_parser/http_parser.dart';
+import 'package:intl/intl.dart';
+import 'package:maplibre_gl_platform_interface/maplibre_gl_platform_interface.dart';
+
+part 'gruene_api_core.dart';
+
+class GrueneApiCampaignsService {
+ late GrueneApi grueneApi;
+
+ final PoiServiceType poiType;
+
+ GrueneApiCampaignsService({required this.poiType}) {
+ grueneApi = _GrueneApiCore().getService();
+ }
+
+ Future> loadPoisInRegion(LatLng locationSW, LatLng locationNE) async {
+ final getPoisType = _getPoiGetType();
+ final getPoisResult = await grueneApi.v1CampaignsPoisGet(
+ type: getPoisType,
+ bbox: [locationSW.latitude, locationSW.longitude, locationNE.latitude, locationNE.longitude].join(','),
+ );
+ return getPoisResult.body!.data.map(_transformToMarkerItem).toList();
+ }
+
+ V1CampaignsPoisGetType _getPoiGetType() {
+ switch (poiType) {
+ case PoiServiceType.poster:
+ return V1CampaignsPoisGetType.poster;
+ case PoiServiceType.door:
+ return V1CampaignsPoisGetType.house;
+ case PoiServiceType.flyer:
+ return V1CampaignsPoisGetType.flyerSpot;
+ }
+ }
+
+ CreatePoiType _getPoiCreateType() {
+ switch (poiType) {
+ case PoiServiceType.poster:
+ return CreatePoiType.poster;
+ case PoiServiceType.door:
+ return CreatePoiType.house;
+ case PoiServiceType.flyer:
+ return CreatePoiType.flyerSpot;
+ }
+ }
+
+ MarkerItemModel _transformToMarkerItem(Poi poi) {
+ final String statusSuffix = _getPosterStatusSuffix(poi.poster!.status);
+ return MarkerItemModel(
+ id: int.parse(poi.id),
+ location: LatLng(poi.coords[0], poi.coords[1]),
+ status: '${poiType.name}$statusSuffix',
+ );
+ }
+
+ Future createNewPoster(PosterCreateModel newPoster) async {
+ final requestParam = CreatePoi(
+ coords: [newPoster.location.latitude, newPoster.location.longitude],
+ type: _getPoiCreateType(),
+ address: PoiAddress(
+ city: newPoster.city!,
+ zip: newPoster.zipCode!,
+ street: newPoster.street!,
+ houseNumber: newPoster.houseNumber!,
+ ),
+ );
+ // saving POI
+ final newPoiResponse = await grueneApi.v1CampaignsPoisPost(body: requestParam);
+
+ if (newPoiResponse.error == null && newPoster.photo != null) {
+ // saving Photo along with POI
+ var poiId = newPoiResponse.body!.id;
+ var timeStamp = DateFormat('yyMMdd_HHmmss').format(DateTime.now());
+ // ignore: unused_local_variable
+ final savePoiPhotoResponse = await grueneApi.v1CampaignsPoisPoiIdPhotosPost(
+ poiId: poiId,
+ image: MultipartFile.fromBytes(
+ 'image',
+ newPoster.photo!,
+ filename: 'poi_${poiId}_$timeStamp.jpg',
+ contentType: MediaType('image', 'jpeg'),
+ ),
+ );
+ }
+
+ return _transformToMarkerItem(newPoiResponse.body!);
+ }
+
+ String _getPosterStatusSuffix(PoiPosterStatus status) {
+ switch (status) {
+ case PoiPosterStatus.damaged:
+ return '_${status.name}';
+ case PoiPosterStatus.removed:
+ case PoiPosterStatus.missing:
+ return '_taken_down';
+ default:
+ return '';
+ }
+ }
+}
+
+enum PoiServiceType { poster, door, flyer }
diff --git a/lib/app/services/gruene_api_core.dart b/lib/app/services/gruene_api_core.dart
new file mode 100644
index 00000000..6621019c
--- /dev/null
+++ b/lib/app/services/gruene_api_core.dart
@@ -0,0 +1,22 @@
+part of 'gruene_api_campaigns_service.dart';
+
+class _GrueneApiCore {
+ late GrueneApi _grueneApiService;
+
+ _GrueneApiCore() {
+ _grueneApiService = GrueneApi.create(
+ baseUrl: Uri.parse(Config.gruenesNetzApiUrl),
+ interceptors: [
+ HeadersInterceptor(
+ {
+ 'x-api-key': Config.gruenesNetzApiKey,
+ },
+ ),
+ ],
+ );
+ }
+
+ GrueneApi getService() {
+ return _grueneApiService;
+ }
+}
diff --git a/lib/app/services/nominatim_service.dart b/lib/app/services/nominatim_service.dart
new file mode 100644
index 00000000..0e4bd243
--- /dev/null
+++ b/lib/app/services/nominatim_service.dart
@@ -0,0 +1,31 @@
+import 'package:gruene_app/app/geocode/nominatim.dart';
+import 'package:maplibre_gl/maplibre_gl.dart';
+
+class NominatimService {
+ Future getLocationAddress(LatLng location) async {
+ final place = await Nominatim.reverseSearch(
+ lat: location.latitude,
+ lon: location.longitude,
+ );
+ final address = AddressModel.convertFromPlace(place);
+ return address;
+ }
+}
+
+class AddressModel {
+ final String? street;
+ final String? city;
+ final String? zipCode;
+ final String? houseNumber;
+
+ const AddressModel({this.street, this.houseNumber, this.zipCode, this.city});
+
+ static AddressModel convertFromPlace(Place place) {
+ return AddressModel(
+ street: place.address?['road']?.toString(),
+ houseNumber: place.address?['house_number']?.toString(),
+ zipCode: place.address?['postcode']?.toString(),
+ city: place.address?['city']?.toString(),
+ );
+ }
+}
diff --git a/lib/app/theme/theme.dart b/lib/app/theme/theme.dart
index 57ba7e9f..8e8f1728 100644
--- a/lib/app/theme/theme.dart
+++ b/lib/app/theme/theme.dart
@@ -77,6 +77,24 @@ class _ThemeTextStyles {
color: ThemeColors.text,
),
);
+
+ static TextStyle labelMedium = GoogleFonts.ptSans(
+ textStyle: TextStyle(
+ fontSize: 13,
+ fontWeight: FontWeight.w400,
+ height: 1.3,
+ letterSpacing: 0.01,
+ ),
+ );
+
+ static TextStyle labelLarge = GoogleFonts.ptSans(
+ textStyle: TextStyle(
+ fontSize: 16,
+ fontWeight: FontWeight.w400,
+ height: 1.3,
+ letterSpacing: 0.01,
+ ),
+ );
}
final ThemeData appTheme = ThemeData.light().copyWith(
@@ -96,6 +114,8 @@ final ThemeData appTheme = ThemeData.light().copyWith(
titleMedium: _ThemeTextStyles.titleMedium,
bodyLarge: _ThemeTextStyles.bodyLarge,
bodyMedium: _ThemeTextStyles.bodyMedium,
+ labelLarge: _ThemeTextStyles.labelLarge,
+ labelMedium: _ThemeTextStyles.labelMedium,
labelSmall: _ThemeTextStyles.labelSmall,
),
bottomNavigationBarTheme: BottomNavigationBarThemeData(
diff --git a/lib/features/campaigns/helper/latlng_extensions.dart b/lib/features/campaigns/helper/latlng_extensions.dart
new file mode 100644
index 00000000..1b47bf41
--- /dev/null
+++ b/lib/features/campaigns/helper/latlng_extensions.dart
@@ -0,0 +1,7 @@
+import 'package:maplibre_gl/maplibre_gl.dart';
+
+extension LatLngToString on LatLng {
+ String toLatLngString() {
+ return '${latitude.toString()},${longitude.toString()}';
+ }
+}
diff --git a/lib/features/campaigns/helper/marker_item_helper.dart b/lib/features/campaigns/helper/marker_item_helper.dart
new file mode 100644
index 00000000..afae2227
--- /dev/null
+++ b/lib/features/campaigns/helper/marker_item_helper.dart
@@ -0,0 +1,20 @@
+import 'package:gruene_app/features/campaigns/models/marker_item_model.dart';
+import 'package:turf/bbox_polygon.dart';
+import 'package:turf/helpers.dart';
+import 'package:turf/transform.dart';
+
+class MarkerItemHelper {
+ static FeatureCollection transformListToGeoJson(List markerItems) {
+ return FeatureCollection(features: markerItems.map(transformMarkerItemToGeoJson).toList());
+ }
+
+ static Feature transformMarkerItemToGeoJson(MarkerItemModel markerItem) {
+ return Feature(
+ id: markerItem.id,
+ properties: {
+ 'type': markerItem.status ?? 'poster',
+ },
+ geometry: Point(coordinates: Position(markerItem.location.longitude, markerItem.location.latitude)),
+ );
+ }
+}
diff --git a/lib/features/campaigns/helper/media_helper.dart b/lib/features/campaigns/helper/media_helper.dart
new file mode 100644
index 00000000..e34b59fd
--- /dev/null
+++ b/lib/features/campaigns/helper/media_helper.dart
@@ -0,0 +1,68 @@
+import 'dart:io';
+import 'dart:typed_data';
+
+import 'package:camerawesome/camerawesome_plugin.dart';
+import 'package:flutter/widgets.dart';
+import 'package:gruene_app/features/campaigns/widgets/app_route.dart';
+import 'package:image/image.dart' as image_lib;
+
+class MediaHelper {
+ static const int maxUploadDimension = 1200;
+
+ static Future acquirePhoto(BuildContext context) async {
+ var image = await Navigator.of(context, rootNavigator: true).push(
+ AppRoute(
+ builder: (context) {
+ return CameraAwesomeBuilder.awesome(
+ saveConfig: SaveConfig.photo(),
+ onMediaCaptureEvent: (mediaCapture) async {
+ if (mediaCapture.status == MediaCaptureStatus.success) {
+ final imageFile = File(mediaCapture.captureRequest.path!);
+ Navigator.maybePop(context, imageFile);
+ }
+ },
+ );
+ },
+ ),
+ );
+ return image;
+ }
+
+ static Future resizeAndReduceImage(Uint8List originalImage, ImageType outputType) async {
+ Uint8List? resizedImg;
+
+ final compressAction = Future.delayed(Duration.zero, () async {
+ image_lib.Image? img = image_lib.decodeImage(originalImage);
+ image_lib.Image resized;
+ if (img!.height > maxUploadDimension || img.width > maxUploadDimension) {
+ int desiredWidth, desiredHeight;
+ if (img.width > img.height) {
+ desiredWidth = maxUploadDimension;
+ desiredHeight = (img.height / img.width * maxUploadDimension).round();
+ } else {
+ desiredHeight = maxUploadDimension;
+ desiredWidth = (img.width / img.height * maxUploadDimension).round();
+ }
+
+ resized = image_lib.copyResize(
+ img,
+ width: desiredWidth,
+ height: desiredHeight,
+ maintainAspect: true,
+ );
+ } else {
+ resized = img;
+ }
+
+ resizedImg = switch (outputType) {
+ ImageType.jpeg => Uint8List.fromList(image_lib.encodeJpg(resized, quality: 60)),
+ ImageType.png => Uint8List.fromList(image_lib.encodePng(resized))
+ };
+ });
+
+ await compressAction;
+ return resizedImg!;
+ }
+}
+
+enum ImageType { jpeg, png }
diff --git a/lib/features/campaigns/helper/util.dart b/lib/features/campaigns/helper/util.dart
new file mode 100644
index 00000000..88ac3f0a
--- /dev/null
+++ b/lib/features/campaigns/helper/util.dart
@@ -0,0 +1,9 @@
+import 'package:flutter/services.dart';
+import 'package:maplibre_gl/maplibre_gl.dart';
+
+/// Adds an asset image to the currently displayed style
+Future addImageFromAsset(MapLibreMapController controller, String name, String assetName) async {
+ final bytes = await rootBundle.load(assetName);
+ final list = bytes.buffer.asUint8List();
+ return controller.addImage(name, list);
+}
diff --git a/lib/features/campaigns/models/marker_item_model.dart b/lib/features/campaigns/models/marker_item_model.dart
new file mode 100644
index 00000000..20e58181
--- /dev/null
+++ b/lib/features/campaigns/models/marker_item_model.dart
@@ -0,0 +1,13 @@
+import 'package:maplibre_gl/maplibre_gl.dart';
+
+class MarkerItemModel {
+ final LatLng location;
+ final int? id;
+ final String? status;
+
+ const MarkerItemModel({
+ this.id,
+ this.status,
+ required this.location,
+ });
+}
diff --git a/lib/features/campaigns/models/posters/poster_create_model.dart b/lib/features/campaigns/models/posters/poster_create_model.dart
new file mode 100644
index 00000000..9fa0d45a
--- /dev/null
+++ b/lib/features/campaigns/models/posters/poster_create_model.dart
@@ -0,0 +1,21 @@
+import 'dart:typed_data';
+
+import 'package:maplibre_gl/maplibre_gl.dart';
+
+class PosterCreateModel {
+ final String? street;
+ final String? houseNumber;
+ final String? zipCode;
+ final String? city;
+ final LatLng location;
+ final Uint8List? photo;
+
+ const PosterCreateModel({
+ this.street,
+ this.houseNumber,
+ this.zipCode,
+ this.city,
+ this.photo,
+ required this.location,
+ });
+}
diff --git a/lib/features/campaigns/screens/poster_add.dart b/lib/features/campaigns/screens/poster_add.dart
new file mode 100644
index 00000000..4dd8e96b
--- /dev/null
+++ b/lib/features/campaigns/screens/poster_add.dart
@@ -0,0 +1,236 @@
+import 'dart:io';
+import 'dart:typed_data';
+
+import 'package:flutter/material.dart';
+import 'package:gruene_app/app/services/nominatim_service.dart';
+import 'package:gruene_app/app/theme/theme.dart';
+import 'package:gruene_app/features/campaigns/helper/media_helper.dart';
+import 'package:gruene_app/features/campaigns/models/posters/poster_create_model.dart';
+import 'package:gruene_app/features/campaigns/widgets/textinputfield.dart';
+import 'package:gruene_app/i18n/translations.g.dart';
+import 'package:maplibre_gl/maplibre_gl.dart';
+
+class PosterAddScreen extends StatefulWidget {
+ final LatLng location;
+ final AddressModel address;
+ final File? photo;
+
+ const PosterAddScreen({super.key, this.photo, required this.address, required this.location});
+
+ @override
+ State createState() => _PostersAddState();
+}
+
+class _PostersAddState extends State {
+ TextEditingController streetTextController = TextEditingController();
+ TextEditingController houseNumberTextController = TextEditingController();
+ TextEditingController zipCodeTextController = TextEditingController();
+ TextEditingController cityTextController = TextEditingController();
+ File? _currentPhoto;
+
+ @override
+ void initState() {
+ streetTextController.text = widget.address.street ?? '';
+ houseNumberTextController.text = widget.address.houseNumber ?? '';
+ zipCodeTextController.text = widget.address.zipCode ?? '';
+ cityTextController.text = widget.address.city ?? '';
+ _currentPhoto = widget.photo;
+ super.initState();
+ }
+
+ @override
+ void dispose() {
+ streetTextController.dispose();
+ houseNumberTextController.dispose();
+ zipCodeTextController.dispose();
+ cityTextController.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final theme = Theme.of(context);
+ return Container(
+ margin: EdgeInsets.all(24),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Row(
+ children: [
+ Expanded(
+ child: Text(
+ t.campaigns.posters.addPoster,
+ style: theme.textTheme.displayMedium,
+ ),
+ ),
+ Container(
+ alignment: Alignment.centerRight,
+ width: 50,
+ height: 50,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ border: Border.all(color: ThemeColors.background, width: 1),
+ gradient: LinearGradient(
+ colors: [Color(0xFF03BD4E), Color(0xFF875CFF)],
+ ),
+ ),
+ child: getPhotoPreviewOrIcon(),
+ ),
+ ],
+ ),
+ Container(
+ padding: EdgeInsets.symmetric(vertical: 6),
+ child: Row(
+ children: [
+ Expanded(
+ child: TextInputField(
+ textController: streetTextController,
+ labelText: t.campaigns.address.street,
+ ),
+ ),
+ Container(
+ padding: EdgeInsets.only(left: 6),
+ child: TextInputField(
+ width: 75,
+ labelText: t.campaigns.address.housenumber,
+ textController: houseNumberTextController,
+ ),
+ ),
+ ],
+ ),
+ ),
+ Container(
+ padding: EdgeInsets.symmetric(vertical: 6),
+ child: Row(
+ children: [
+ Container(
+ padding: EdgeInsets.only(right: 6),
+ child: TextInputField(
+ width: 75,
+ labelText: t.campaigns.address.zipcode,
+ textController: zipCodeTextController,
+ ),
+ ),
+ Expanded(
+ child: TextInputField(
+ labelText: t.campaigns.address.city_or_place,
+ textController: cityTextController,
+ ),
+ ),
+ ],
+ ),
+ ),
+ Container(
+ padding: EdgeInsets.symmetric(vertical: 24),
+ child: Row(
+ children: [
+ Expanded(
+ child: Container(
+ height: 48,
+ padding: EdgeInsets.only(right: 6),
+ child: ElevatedButton(
+ style: ElevatedButton.styleFrom(
+ backgroundColor: ThemeColors.background,
+ foregroundColor: ThemeColors.primary,
+ ),
+ child: Text(
+ t.common.actions.cancel,
+ style: theme.textTheme.titleMedium?.apply(
+ color: ThemeColors.primary,
+ ),
+ ),
+ onPressed: () => Navigator.maybePop(context),
+ ),
+ ),
+ ),
+ Expanded(
+ child: Container(
+ height: 48,
+ padding: EdgeInsets.only(left: 6),
+ child: ElevatedButton(
+ style: ElevatedButton.styleFrom(
+ backgroundColor: ThemeColors.primary,
+ foregroundColor: ThemeColors.background,
+ ),
+ child: Text(
+ t.common.actions.save,
+ style: theme.textTheme.titleMedium?.apply(
+ color: ThemeColors.background,
+ ),
+ ),
+ onPressed: () => onSavePressed(context),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+ Widget getPhotoPreviewOrIcon() {
+ if (_currentPhoto != null) {
+ return Container(
+ width: 150,
+ height: 120,
+ clipBehavior: Clip.antiAlias,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ ),
+ child: GestureDetector(
+ onTap: acquireNewPhoto,
+ child: Image.file(
+ _currentPhoto!,
+ fit: BoxFit.cover,
+ ),
+ ),
+ );
+ } else {
+ return Center(
+ child: GestureDetector(
+ onTap: acquireNewPhoto,
+ child: Icon(
+ Icons.photo_camera,
+ color: Colors.white,
+ size: 30.0,
+ ),
+ ),
+ );
+ }
+ }
+
+ void acquireNewPhoto() async {
+ final photo = await MediaHelper.acquirePhoto(context);
+ // final photoBytes = await reduceAndResize(photo);
+
+ if (photo != null) {
+ setState(() {
+ _currentPhoto = photo;
+ });
+ }
+ }
+
+ Future reduceAndResize(File? photo) async {
+ if (photo == null) return null;
+ final fileContent = await photo.readAsBytes();
+ return await MediaHelper.resizeAndReduceImage(fileContent, ImageType.jpeg);
+ }
+
+ void onSavePressed(BuildContext localContext) async {
+ final reducedImage = await reduceAndResize(_currentPhoto);
+ if (!localContext.mounted) return;
+ Navigator.maybePop(
+ localContext,
+ PosterCreateModel(
+ location: widget.location,
+ street: streetTextController.text,
+ houseNumber: houseNumberTextController.text,
+ zipCode: zipCodeTextController.text,
+ city: cityTextController.text,
+ photo: reducedImage,
+ ),
+ );
+ }
+}
diff --git a/lib/features/campaigns/screens/posters_screen.dart b/lib/features/campaigns/screens/posters_screen.dart
index 48fe1458..ea3628bf 100644
--- a/lib/features/campaigns/screens/posters_screen.dart
+++ b/lib/features/campaigns/screens/posters_screen.dart
@@ -1,8 +1,20 @@
import 'package:flutter/widgets.dart';
+import 'package:go_router/go_router.dart';
+import 'package:gruene_app/app/services/gruene_api_campaigns_service.dart';
+import 'package:gruene_app/app/services/nominatim_service.dart';
+import 'package:gruene_app/app/theme/theme.dart';
+import 'package:gruene_app/features/campaigns/helper/media_helper.dart';
+import 'package:gruene_app/features/campaigns/models/posters/poster_create_model.dart';
+import 'package:gruene_app/features/campaigns/screens/poster_add.dart';
+import 'package:gruene_app/features/campaigns/widgets/app_route.dart';
+import 'package:gruene_app/features/campaigns/widgets/content_page.dart';
import 'package:gruene_app/features/campaigns/widgets/filter_chip_widget.dart';
+import 'package:gruene_app/features/campaigns/widgets/map.dart';
+import 'package:gruene_app/features/campaigns/widgets/map_controller.dart';
import 'package:gruene_app/i18n/translations.g.dart';
+import 'package:maplibre_gl/maplibre_gl.dart';
-class PostersScreen extends StatelessWidget {
+class PostersScreen extends StatefulWidget {
PostersScreen({super.key});
final List postersFilter = [
@@ -10,13 +22,97 @@ class PostersScreen extends StatelessWidget {
FilterChipModel(t.campaigns.filters.polling_stations, false),
FilterChipModel(t.campaigns.filters.experience_areas, false),
];
+
+ @override
+ State createState() => _PostersScreenState();
+}
+
+class _PostersScreenState extends State {
+ late MapController _mapController;
+ final GrueneApiCampaignsService _grueneApiService = GrueneApiCampaignsService(poiType: PoiServiceType.poster);
+ final NominatimService _nominatimService = NominatimService();
+
@override
- Widget build(BuildContext context) {
+ Widget build(localContext) {
+ MapContainer mapContainer = MapContainer(
+ onMapCreated: onMapCreated,
+ addPOIClicked: addPOIClicked,
+ loadVisibleItems: loadVisibleItems,
+ getMarkerImages: getMarkerImages,
+ );
+
return Column(
children: [
- FilterChipCampaign(postersFilter, >{}),
- Center(child: Text(t.campaigns.posters.label)),
+ FilterChipCampaign(widget.postersFilter, >{}),
+ Expanded(
+ child: mapContainer,
+ ),
],
);
}
+
+ void onMapCreated(MapController controller) {
+ _mapController = controller;
+ }
+
+ void addPOIClicked(LatLng location) async {
+ final currentRoute = GoRouterState.of(context);
+
+ var locationAddress = _nominatimService.getLocationAddress(location);
+
+ final photo = await MediaHelper.acquirePhoto(context);
+
+ var navState = getNavState();
+ final result = await navState.push(
+ AppRoute(
+ builder: (context) {
+ return FutureBuilder(
+ future: locationAddress.timeout(const Duration(milliseconds: 800), onTimeout: () => AddressModel()),
+ builder: (context, AsyncSnapshot snapshot) {
+ if (!snapshot.hasData && !snapshot.hasError) {
+ return Container(
+ color: ThemeColors.secondary,
+ );
+ }
+
+ final address = snapshot.data;
+ return ContentPage(
+ title: currentRoute.name ?? '',
+ child: PosterAddScreen(
+ location: location,
+ address: address!,
+ photo: photo,
+ ),
+ );
+ },
+ );
+ },
+ ),
+ );
+
+ if (result != null) {
+ final newPoster = result;
+
+ final markerItem = await _grueneApiService.createNewPoster(newPoster);
+ _mapController.addMarkerItem(markerItem);
+ }
+ }
+
+ NavigatorState getNavState() => Navigator.of(context, rootNavigator: true);
+
+ void loadVisibleItems(LatLng locationSW, LatLng locationNE) async {
+ // final resultHealth = await _grueneApiService.getHealth();
+ // print(resultHealth.error);
+
+ final markerItems = await _grueneApiService.loadPoisInRegion(locationSW, locationNE);
+ _mapController.setMarkerSource(markerItems);
+ }
+
+ Map getMarkerImages() {
+ return {
+ 'poster': 'assets/symbols/posters/poster.png',
+ 'poster_damaged': 'assets/symbols/posters/poster_damaged.png',
+ 'poster_taken_down': 'assets/symbols/posters/poster_taken_down.png',
+ };
+ }
}
diff --git a/lib/features/campaigns/widgets/app_route.dart b/lib/features/campaigns/widgets/app_route.dart
new file mode 100644
index 00000000..652f26bf
--- /dev/null
+++ b/lib/features/campaigns/widgets/app_route.dart
@@ -0,0 +1,11 @@
+import 'package:flutter/material.dart';
+
+class AppRoute extends MaterialPageRoute {
+ AppRoute({required WidgetBuilder builder, super.settings})
+ : super(
+ builder: (BuildContext context) {
+ // final theme = Theme.of(context);
+ return Material(child: builder(context));
+ },
+ );
+}
diff --git a/lib/features/campaigns/widgets/content_page.dart b/lib/features/campaigns/widgets/content_page.dart
new file mode 100644
index 00000000..fb518c41
--- /dev/null
+++ b/lib/features/campaigns/widgets/content_page.dart
@@ -0,0 +1,21 @@
+import 'package:flutter/material.dart';
+import 'package:gruene_app/features/campaigns/widgets/custom_app_bar.dart';
+
+class ContentPage extends StatelessWidget {
+ final String title;
+ final Widget child;
+
+ const ContentPage({super.key, required this.title, required this.child});
+
+ @override
+ Widget build(BuildContext context) {
+ final theme = Theme.of(context);
+ return Scaffold(
+ backgroundColor: theme.colorScheme.secondary,
+ body: child,
+ appBar: CustomAppBar(
+ title: title,
+ ),
+ );
+ }
+}
diff --git a/lib/features/campaigns/widgets/custom_app_bar.dart b/lib/features/campaigns/widgets/custom_app_bar.dart
new file mode 100644
index 00000000..0414ba56
--- /dev/null
+++ b/lib/features/campaigns/widgets/custom_app_bar.dart
@@ -0,0 +1,37 @@
+import 'package:flutter/material.dart';
+import 'package:go_router/go_router.dart';
+import 'package:gruene_app/app/constants/routes.dart';
+import 'package:gruene_app/app/theme/theme.dart';
+import 'package:gruene_app/app/widgets/icon.dart';
+
+class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
+ final String title;
+ const CustomAppBar({super.key, required this.title});
+
+ @override
+ Widget build(BuildContext context) {
+ final theme = Theme.of(context);
+ return AppBar(
+ title: Text(
+ title,
+ style: theme.textTheme.displayMedium?.apply(color: theme.colorScheme.surface),
+ ),
+ leading: BackButton(),
+ foregroundColor: theme.colorScheme.surface,
+ backgroundColor: theme.primaryColor,
+ centerTitle: true,
+ actions: [
+ IconButton(
+ icon: CustomIcon(
+ path: 'assets/icons/settings.svg',
+ color: ThemeColors.background,
+ ),
+ onPressed: () => context.push(Routes.settings),
+ ),
+ ],
+ );
+ }
+
+ @override
+ Size get preferredSize => const Size.fromHeight(kToolbarHeight);
+}
diff --git a/lib/features/campaigns/widgets/custom_sliver_app_bar.dart b/lib/features/campaigns/widgets/custom_sliver_app_bar.dart
new file mode 100644
index 00000000..0b8fa680
--- /dev/null
+++ b/lib/features/campaigns/widgets/custom_sliver_app_bar.dart
@@ -0,0 +1,34 @@
+import 'package:flutter/material.dart';
+import 'package:go_router/go_router.dart';
+import 'package:gruene_app/app/constants/routes.dart';
+import 'package:gruene_app/app/theme/theme.dart';
+import 'package:gruene_app/app/widgets/icon.dart';
+
+class CustomSliverAppBar extends StatelessWidget {
+ final String title;
+
+ const CustomSliverAppBar({super.key, required this.title});
+
+ @override
+ Widget build(BuildContext context) {
+ final theme = Theme.of(context);
+ final foregroundColor = theme.primaryColor;
+ return SliverAppBar(
+ backgroundColor: foregroundColor,
+ leading: BackButton(color: foregroundColor),
+ iconTheme: IconThemeData(color: foregroundColor),
+ title: Text(title, style: theme.textTheme.titleMedium?.apply(color: theme.appBarTheme.foregroundColor)),
+ centerTitle: true,
+ actions: [
+ IconButton(
+ icon: CustomIcon(
+ path: 'assets/icons/settings.svg',
+ color: ThemeColors.background,
+ ),
+ onPressed: () => context.push(Routes.settings),
+ ),
+ ],
+ pinned: true,
+ );
+ }
+}
diff --git a/lib/features/campaigns/widgets/map.dart b/lib/features/campaigns/widgets/map.dart
new file mode 100644
index 00000000..6a487c36
--- /dev/null
+++ b/lib/features/campaigns/widgets/map.dart
@@ -0,0 +1,155 @@
+import 'dart:math';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:gruene_app/app/constants/config.dart';
+import 'package:gruene_app/features/campaigns/helper/marker_item_helper.dart';
+import 'package:gruene_app/features/campaigns/helper/util.dart';
+import 'package:gruene_app/features/campaigns/models/marker_item_model.dart';
+import 'package:gruene_app/features/campaigns/widgets/map_controller.dart';
+import 'package:maplibre_gl/maplibre_gl.dart';
+
+typedef OnMapCreatedCallback = void Function(MapController controller);
+typedef AddPOIClickedCallback = void Function(LatLng location);
+typedef LoadVisibleItemsCallBack = void Function(LatLng locationSW, LatLng locationNE);
+typedef GetMarkerImagesCallback = Map Function();
+
+class MapContainer extends StatefulWidget {
+ final OnMapCreatedCallback? onMapCreated;
+ final AddPOIClickedCallback? addPOIClicked;
+ final LoadVisibleItemsCallBack? loadVisibleItems;
+ final GetMarkerImagesCallback getMarkerImages;
+
+ const MapContainer({
+ super.key,
+ required this.onMapCreated,
+ required this.addPOIClicked,
+ required this.loadVisibleItems,
+ required this.getMarkerImages,
+ });
+
+ @override
+ State createState() => _MapContainerState();
+}
+
+class _MapContainerState extends State implements MapController {
+ MapLibreMapController? _controller;
+ final MarkerItemManager _markerItemManager = MarkerItemManager();
+ bool _isMapInitialized = false;
+
+ final LatLngBounds _cameraTargetBounds = LatLngBounds(
+ southwest: LatLng(46.8, 5.6),
+ northeast: LatLng(55.1, 15.5),
+ ); //typically Germany
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ body: Stack(
+ children: [
+ MapLibreMap(
+ // minMaxZoomPreference: MinMaxZoomPreference(14, 18),
+ styleString: Config.maplibreUrl,
+ onMapCreated: _onMapCreated,
+ initialCameraPosition: const CameraPosition(target: LatLng(52.528810, 13.379300), zoom: 16),
+ onStyleLoadedCallback: _onStyleLoadedCallback,
+ cameraTargetBounds: CameraTargetBounds(_cameraTargetBounds),
+ trackCameraPosition: true,
+ onCameraIdle: _onCameraIdle,
+ onMapClick: _onMapClick,
+
+ // rotateGesturesEnabled: false,
+ ),
+ Center(
+ child: Container(
+ padding:
+ EdgeInsets.only(bottom: 65 /* height of the add_marker icon to position it exactly on the middle */),
+ child: GestureDetector(
+ onTap: _onIconTap,
+ child: SvgPicture.asset('assets/symbols/add_marker.svg'),
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+ void _onMapCreated(MapLibreMapController controller) async {
+ if (!mounted) return;
+
+ setState(() {
+ _controller = controller;
+ _isMapInitialized = true;
+ });
+
+ final onMapCreated = widget.onMapCreated;
+ if (onMapCreated != null) {
+ onMapCreated(this);
+ }
+ }
+
+ void _onIconTap() {
+ final addPOIClicked = widget.addPOIClicked;
+
+ if (addPOIClicked != null) {
+ addPOIClicked(_controller!.cameraPosition!.target);
+ }
+ }
+
+ void _onMapClick(Point point, LatLng coordinates) {}
+
+ void _onCameraIdle() async {
+ if (!_isMapInitialized) return;
+ final visRegion = await _controller?.getVisibleRegion();
+
+ widget.loadVisibleItems!(visRegion!.southwest, visRegion.northeast);
+ }
+
+ void _onStyleLoadedCallback() async {
+ widget.getMarkerImages().forEach((x, y) async {
+ await addImageFromAsset(_controller!, x, y);
+ });
+
+ _controller!.addGeoJsonSource('markers', MarkerItemHelper.transformListToGeoJson([]).toJson());
+
+ await _controller!.addSymbolLayer(
+ 'markers',
+ 'symbols',
+ const SymbolLayerProperties(
+ iconImage: ['get', 'type'],
+ iconSize: 2,
+ iconAllowOverlap: true,
+ ),
+ filter: [
+ '!',
+ ['has', 'point_count'],
+ ],
+ );
+ }
+
+ @override
+ void setMarkerSource(List poiList) {
+ _markerItemManager.addMarkers(poiList);
+ _controller!
+ .setGeoJsonSource('markers', MarkerItemHelper.transformListToGeoJson(_markerItemManager.getMarkers()).toJson());
+ }
+
+ @override
+ void addMarkerItem(MarkerItemModel markerItem) {
+ setMarkerSource([markerItem]);
+ }
+}
+
+class MarkerItemManager {
+ final List loadedMarkers = [];
+
+ void addMarkers(List poiList) {
+ loadedMarkers.retainWhere((oldMarker) => poiList.any((newMarker) => newMarker.id != oldMarker.id));
+ loadedMarkers.addAll(poiList);
+ }
+
+ List getMarkers() {
+ return loadedMarkers;
+ }
+}
diff --git a/lib/features/campaigns/widgets/map_controller.dart b/lib/features/campaigns/widgets/map_controller.dart
new file mode 100644
index 00000000..3ec4c669
--- /dev/null
+++ b/lib/features/campaigns/widgets/map_controller.dart
@@ -0,0 +1,7 @@
+import 'package:gruene_app/features/campaigns/models/marker_item_model.dart';
+
+abstract class MapController {
+ void setMarkerSource(List poiList) {}
+
+ void addMarkerItem(MarkerItemModel markerItem) {}
+}
diff --git a/lib/features/campaigns/widgets/sliver_content_page.dart b/lib/features/campaigns/widgets/sliver_content_page.dart
new file mode 100644
index 00000000..aca184f5
--- /dev/null
+++ b/lib/features/campaigns/widgets/sliver_content_page.dart
@@ -0,0 +1,29 @@
+import 'package:flutter/material.dart';
+import 'package:gruene_app/features/campaigns/widgets/custom_sliver_app_bar.dart';
+
+class SliverContentPage extends StatelessWidget {
+ final String title;
+ final List children;
+
+ const SliverContentPage({super.key, required this.title, required this.children});
+
+ @override
+ Widget build(BuildContext context) {
+ final theme = Theme.of(context);
+
+ return DecoratedBox(
+ decoration: BoxDecoration(color: theme.colorScheme.primary),
+ child: CustomScrollView(
+ slivers: [
+ CustomSliverAppBar(title: title),
+ SliverPadding(
+ padding: const EdgeInsets.all(10),
+ sliver: SliverList(
+ delegate: SliverChildListDelegate(children),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/features/campaigns/widgets/textinputfield.dart b/lib/features/campaigns/widgets/textinputfield.dart
new file mode 100644
index 00000000..5272ecd3
--- /dev/null
+++ b/lib/features/campaigns/widgets/textinputfield.dart
@@ -0,0 +1,40 @@
+import 'package:flutter/material.dart';
+import 'package:gruene_app/app/theme/theme.dart';
+
+class TextInputField extends StatefulWidget {
+ final String labelText;
+
+ final double? width;
+
+ final TextEditingController? textController;
+
+ const TextInputField({required this.labelText, this.width, this.textController, super.key});
+
+ @override
+ State createState() => _TextInputFieldState();
+}
+
+class _TextInputFieldState extends State {
+ @override
+ Widget build(BuildContext context) {
+ final theme = Theme.of(context);
+ return Container(
+ width: widget.width,
+ padding: EdgeInsets.symmetric(vertical: 6, horizontal: 9),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(5),
+ ),
+ child: TextFormField(
+ controller: widget.textController,
+ style: theme.textTheme.bodyMedium?.apply(color: ThemeColors.text),
+ decoration: InputDecoration(
+ labelText: widget.labelText,
+ border: InputBorder.none,
+ labelStyle: theme.textTheme.labelMedium?.apply(color: ThemeColors.textDisabled),
+ floatingLabelStyle: theme.textTheme.labelSmall?.apply(color: ThemeColors.textDisabled),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/i18n/app_de.json b/lib/i18n/app_de.json
index 2cc6304f..b503dd7e 100644
--- a/lib/i18n/app_de.json
+++ b/lib/i18n/app_de.json
@@ -1,6 +1,10 @@
{
"common": {
- "appName": "Grüne App"
+ "appName": "Grüne App",
+ "actions": {
+ "save": "Speichern",
+ "cancel": "Abbrechen"
+ }
},
"news": {
"news": "Artikel",
@@ -17,7 +21,8 @@
"experience_areas": "Erfahrungsgebiete"
},
"posters": {
- "label": "Plakate"
+ "label": "Plakate",
+ "addPoster": "Plakat eintragen"
},
"door": {
"label": "Haustür"
@@ -30,6 +35,12 @@
},
"statistic": {
"label": "Statistik"
+ },
+ "address": {
+ "street": "Straße",
+ "housenumber": "Hausnr.",
+ "zipcode": "PLZ",
+ "city_or_place": "Stadt / Ort"
}
},
"profiles": {
@@ -72,4 +83,4 @@
"discover": "App erkunden",
"discoverDescription": "Erfahre hier, was Dich erwartet."
}
-}
+}
\ No newline at end of file
diff --git a/pubspec.lock b/pubspec.lock
index 17af80d3..9cb44803 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1,714 +1,1255 @@
-# Generated by pub
-# See https://dart.dev/tools/pub/glossary#lockfile
-packages:
- ansicolor:
- dependency: transitive
- description:
- name: ansicolor
- sha256: "50e982d500bc863e1d703448afdbf9e5a72eb48840a4f766fa361ffd6877055f"
- url: "https://pub.dev"
- source: hosted
- version: "2.0.3"
- archive:
- dependency: transitive
- description:
- name: archive
- sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
- url: "https://pub.dev"
- source: hosted
- version: "3.6.1"
- args:
- dependency: transitive
- description:
- name: args
- sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
- url: "https://pub.dev"
- source: hosted
- version: "2.6.0"
- async:
- dependency: transitive
- description:
- name: async
- sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
- url: "https://pub.dev"
- source: hosted
- version: "2.12.0"
- bloc:
- dependency: transitive
- description:
- name: bloc
- sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e"
- url: "https://pub.dev"
- source: hosted
- version: "8.1.4"
- characters:
- dependency: transitive
- description:
- name: characters
- sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
- url: "https://pub.dev"
- source: hosted
- version: "1.3.0"
- clock:
- dependency: transitive
- description:
- name: clock
- sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
- url: "https://pub.dev"
- source: hosted
- version: "1.1.1"
- collection:
- dependency: transitive
- description:
- name: collection
- sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
- url: "https://pub.dev"
- source: hosted
- version: "1.18.0"
- crypto:
- dependency: transitive
- description:
- name: crypto
- sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
- url: "https://pub.dev"
- source: hosted
- version: "3.0.6"
- csslib:
- dependency: transitive
- description:
- name: csslib
- sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
- url: "https://pub.dev"
- source: hosted
- version: "1.0.2"
- csv:
- dependency: transitive
- description:
- name: csv
- sha256: c6aa2679b2a18cb57652920f674488d89712efaf4d3fdf2e537215b35fc19d6c
- url: "https://pub.dev"
- source: hosted
- version: "6.0.0"
- dio:
- dependency: "direct main"
- description:
- name: dio
- sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260"
- url: "https://pub.dev"
- source: hosted
- version: "5.7.0"
- dio_web_adapter:
- dependency: transitive
- description:
- name: dio_web_adapter
- sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8"
- url: "https://pub.dev"
- source: hosted
- version: "2.0.0"
- equatable:
- dependency: "direct main"
- description:
- name: equatable
- sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
- url: "https://pub.dev"
- source: hosted
- version: "2.0.5"
- ffi:
- dependency: transitive
- description:
- name: ffi
- sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
- url: "https://pub.dev"
- source: hosted
- version: "2.1.3"
- flutter:
- dependency: "direct main"
- description: flutter
- source: sdk
- version: "0.0.0"
- flutter_appauth:
- dependency: "direct main"
- description:
- name: flutter_appauth
- sha256: "6ab0e7fb2cb66db472a71c00e0f0d0888f186d308beaef4bba1a6113fa861096"
- url: "https://pub.dev"
- source: hosted
- version: "8.0.0+1"
- flutter_appauth_platform_interface:
- dependency: transitive
- description:
- name: flutter_appauth_platform_interface
- sha256: ccf5e1d8c40dd35b297290b33cc1896648b4b92a2ec3f62a436c62a8eef9a9db
- url: "https://pub.dev"
- source: hosted
- version: "8.0.0"
- flutter_bloc:
- dependency: "direct main"
- description:
- name: flutter_bloc
- sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a
- url: "https://pub.dev"
- source: hosted
- version: "8.1.6"
- flutter_dotenv:
- dependency: "direct main"
- description:
- name: flutter_dotenv
- sha256: b7c7be5cd9f6ef7a78429cabd2774d3c4af50e79cb2b7593e3d5d763ef95c61b
- url: "https://pub.dev"
- source: hosted
- version: "5.2.1"
- flutter_inappwebview:
- dependency: "direct main"
- description:
- name: flutter_inappwebview
- sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5"
- url: "https://pub.dev"
- source: hosted
- version: "6.1.5"
- flutter_inappwebview_android:
- dependency: transitive
- description:
- name: flutter_inappwebview_android
- sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba"
- url: "https://pub.dev"
- source: hosted
- version: "1.1.3"
- flutter_inappwebview_internal_annotations:
- dependency: transitive
- description:
- name: flutter_inappwebview_internal_annotations
- sha256: "5f80fd30e208ddded7dbbcd0d569e7995f9f63d45ea3f548d8dd4c0b473fb4c8"
- url: "https://pub.dev"
- source: hosted
- version: "1.1.1"
- flutter_inappwebview_ios:
- dependency: transitive
- description:
- name: flutter_inappwebview_ios
- sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d"
- url: "https://pub.dev"
- source: hosted
- version: "1.1.2"
- flutter_inappwebview_macos:
- dependency: transitive
- description:
- name: flutter_inappwebview_macos
- sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1
- url: "https://pub.dev"
- source: hosted
- version: "1.1.2"
- flutter_inappwebview_platform_interface:
- dependency: transitive
- description:
- name: flutter_inappwebview_platform_interface
- sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500
- url: "https://pub.dev"
- source: hosted
- version: "1.3.0+1"
- flutter_inappwebview_web:
- dependency: transitive
- description:
- name: flutter_inappwebview_web
- sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598"
- url: "https://pub.dev"
- source: hosted
- version: "1.1.2"
- flutter_inappwebview_windows:
- dependency: transitive
- description:
- name: flutter_inappwebview_windows
- sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055"
- url: "https://pub.dev"
- source: hosted
- version: "0.6.0"
- flutter_lints:
- dependency: "direct dev"
- description:
- name: flutter_lints
- sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
- url: "https://pub.dev"
- source: hosted
- version: "5.0.0"
- flutter_localizations:
- dependency: "direct main"
- description: flutter
- source: sdk
- version: "0.0.0"
- flutter_native_splash:
- dependency: "direct main"
- description:
- name: flutter_native_splash
- sha256: ee5c9bd2b74ea8676442fd4ab876b5d41681df49276488854d6c81a5377c0ef1
- url: "https://pub.dev"
- source: hosted
- version: "2.4.2"
- flutter_secure_storage:
- dependency: "direct main"
- description:
- name: flutter_secure_storage
- sha256: "165164745e6afb5c0e3e3fcc72a012fb9e58496fb26ffb92cf22e16a821e85d0"
- url: "https://pub.dev"
- source: hosted
- version: "9.2.2"
- flutter_secure_storage_linux:
- dependency: transitive
- description:
- name: flutter_secure_storage_linux
- sha256: "4d91bfc23047422cbcd73ac684bc169859ee766482517c22172c86596bf1464b"
- url: "https://pub.dev"
- source: hosted
- version: "1.2.1"
- flutter_secure_storage_macos:
- dependency: transitive
- description:
- name: flutter_secure_storage_macos
- sha256: "1693ab11121a5f925bbea0be725abfcfbbcf36c1e29e571f84a0c0f436147a81"
- url: "https://pub.dev"
- source: hosted
- version: "3.1.2"
- flutter_secure_storage_platform_interface:
- dependency: transitive
- description:
- name: flutter_secure_storage_platform_interface
- sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
- url: "https://pub.dev"
- source: hosted
- version: "1.1.2"
- flutter_secure_storage_web:
- dependency: transitive
- description:
- name: flutter_secure_storage_web
- sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
- url: "https://pub.dev"
- source: hosted
- version: "1.2.1"
- flutter_secure_storage_windows:
- dependency: transitive
- description:
- name: flutter_secure_storage_windows
- sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
- url: "https://pub.dev"
- source: hosted
- version: "3.1.2"
- flutter_svg:
- dependency: "direct main"
- description:
- name: flutter_svg
- sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2"
- url: "https://pub.dev"
- source: hosted
- version: "2.0.10+1"
- flutter_web_plugins:
- dependency: transitive
- description: flutter
- source: sdk
- version: "0.0.0"
- get_it:
- dependency: "direct main"
- description:
- name: get_it
- sha256: ff97e5e7b2e82e63c82f5658c6ba2605ea831f0f7489b0d2fb255d817ec4eb5e
- url: "https://pub.dev"
- source: hosted
- version: "8.0.0"
- go_router:
- dependency: "direct main"
- description:
- name: go_router
- sha256: "6f1b756f6e863259a99135ff3c95026c3cdca17d10ebef2bba2261a25ddc8bbc"
- url: "https://pub.dev"
- source: hosted
- version: "14.3.0"
- google_fonts:
- dependency: "direct main"
- description:
- name: google_fonts
- sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82
- url: "https://pub.dev"
- source: hosted
- version: "6.2.1"
- html:
- dependency: transitive
- description:
- name: html
- sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec"
- url: "https://pub.dev"
- source: hosted
- version: "0.15.5"
- http:
- dependency: transitive
- description:
- name: http
- sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
- url: "https://pub.dev"
- source: hosted
- version: "1.2.2"
- http_parser:
- dependency: transitive
- description:
- name: http_parser
- sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
- url: "https://pub.dev"
- source: hosted
- version: "4.0.2"
- image:
- dependency: transitive
- description:
- name: image
- sha256: f31d52537dc417fdcde36088fdf11d191026fd5e4fae742491ebd40e5a8bea7d
- url: "https://pub.dev"
- source: hosted
- version: "4.3.0"
- intl:
- dependency: transitive
- description:
- name: intl
- sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
- url: "https://pub.dev"
- source: hosted
- version: "0.19.0"
- js:
- dependency: transitive
- description:
- name: js
- sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
- url: "https://pub.dev"
- source: hosted
- version: "0.6.7"
- json2yaml:
- dependency: transitive
- description:
- name: json2yaml
- sha256: da94630fbc56079426fdd167ae58373286f603371075b69bf46d848d63ba3e51
- url: "https://pub.dev"
- source: hosted
- version: "3.0.1"
- jwt_decoder:
- dependency: "direct main"
- description:
- name: jwt_decoder
- sha256: "54774aebf83f2923b99e6416b4ea915d47af3bde56884eb622de85feabbc559f"
- url: "https://pub.dev"
- source: hosted
- version: "2.0.1"
- lints:
- dependency: transitive
- description:
- name: lints
- sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413"
- url: "https://pub.dev"
- source: hosted
- version: "5.0.0"
- logger:
- dependency: "direct main"
- description:
- name: logger
- sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32"
- url: "https://pub.dev"
- source: hosted
- version: "2.4.0"
- logging:
- dependency: transitive
- description:
- name: logging
- sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
- url: "https://pub.dev"
- source: hosted
- version: "1.3.0"
- material_color_utilities:
- dependency: transitive
- description:
- name: material_color_utilities
- sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
- url: "https://pub.dev"
- source: hosted
- version: "0.11.1"
- meta:
- dependency: transitive
- description:
- name: meta
- sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
- url: "https://pub.dev"
- source: hosted
- version: "1.15.0"
- nested:
- dependency: transitive
- description:
- name: nested
- sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
- url: "https://pub.dev"
- source: hosted
- version: "1.0.0"
- path:
- dependency: transitive
- description:
- name: path
- sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
- url: "https://pub.dev"
- source: hosted
- version: "1.9.0"
- path_parsing:
- dependency: transitive
- description:
- name: path_parsing
- sha256: "45f7d6bba1128761de5540f39d5ca000ea8a1f22f06b76b61094a60a2997bd0e"
- url: "https://pub.dev"
- source: hosted
- version: "1.0.2"
- path_provider:
- dependency: transitive
- description:
- name: path_provider
- sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
- url: "https://pub.dev"
- source: hosted
- version: "2.1.4"
- path_provider_android:
- dependency: transitive
- description:
- name: path_provider_android
- sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
- url: "https://pub.dev"
- source: hosted
- version: "2.2.12"
- path_provider_foundation:
- dependency: transitive
- description:
- name: path_provider_foundation
- sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
- url: "https://pub.dev"
- source: hosted
- version: "2.4.0"
- path_provider_linux:
- dependency: transitive
- description:
- name: path_provider_linux
- sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
- url: "https://pub.dev"
- source: hosted
- version: "2.2.1"
- path_provider_platform_interface:
- dependency: transitive
- description:
- name: path_provider_platform_interface
- sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
- url: "https://pub.dev"
- source: hosted
- version: "2.1.2"
- path_provider_windows:
- dependency: transitive
- description:
- name: path_provider_windows
- sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
- url: "https://pub.dev"
- source: hosted
- version: "2.3.0"
- petitparser:
- dependency: transitive
- description:
- name: petitparser
- sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
- url: "https://pub.dev"
- source: hosted
- version: "6.0.2"
- platform:
- dependency: transitive
- description:
- name: platform
- sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
- url: "https://pub.dev"
- source: hosted
- version: "3.1.6"
- plugin_platform_interface:
- dependency: transitive
- description:
- name: plugin_platform_interface
- sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
- url: "https://pub.dev"
- source: hosted
- version: "2.1.8"
- provider:
- dependency: transitive
- description:
- name: provider
- sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
- url: "https://pub.dev"
- source: hosted
- version: "6.1.2"
- sky_engine:
- dependency: transitive
- description: flutter
- source: sdk
- version: "0.0.99"
- slang:
- dependency: "direct main"
- description:
- name: slang
- sha256: b04db2dbaf927b28600a2f8a272a3bf2ae309556dcc5d6beb02d66af0be39e4c
- url: "https://pub.dev"
- source: hosted
- version: "4.1.0"
- slang_flutter:
- dependency: "direct main"
- description:
- name: slang_flutter
- sha256: "59988f37bb8b50d96ee46832a8a389036c0da26c04b1b1d4aa6690c00f70eccf"
- url: "https://pub.dev"
- source: hosted
- version: "4.1.0"
- source_span:
- dependency: transitive
- description:
- name: source_span
- sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
- url: "https://pub.dev"
- source: hosted
- version: "1.10.0"
- string_scanner:
- dependency: transitive
- description:
- name: string_scanner
- sha256: "0bd04f5bb74fcd6ff0606a888a30e917af9bd52820b178eaa464beb11dca84b6"
- url: "https://pub.dev"
- source: hosted
- version: "1.4.0"
- term_glyph:
- dependency: transitive
- description:
- name: term_glyph
- sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
- url: "https://pub.dev"
- source: hosted
- version: "1.2.1"
- typed_data:
- dependency: transitive
- description:
- name: typed_data
- sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
- url: "https://pub.dev"
- source: hosted
- version: "1.4.0"
- universal_io:
- dependency: transitive
- description:
- name: universal_io
- sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad"
- url: "https://pub.dev"
- source: hosted
- version: "2.2.2"
- vector_graphics:
- dependency: transitive
- description:
- name: vector_graphics
- sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3"
- url: "https://pub.dev"
- source: hosted
- version: "1.1.11+1"
- vector_graphics_codec:
- dependency: transitive
- description:
- name: vector_graphics_codec
- sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da
- url: "https://pub.dev"
- source: hosted
- version: "1.1.11+1"
- vector_graphics_compiler:
- dependency: transitive
- description:
- name: vector_graphics_compiler
- sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81"
- url: "https://pub.dev"
- source: hosted
- version: "1.1.11+1"
- vector_math:
- dependency: transitive
- description:
- name: vector_math
- sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
- url: "https://pub.dev"
- source: hosted
- version: "2.1.4"
- watcher:
- dependency: transitive
- description:
- name: watcher
- sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
- url: "https://pub.dev"
- source: hosted
- version: "1.1.0"
- web:
- dependency: transitive
- description:
- name: web
- sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
- url: "https://pub.dev"
- source: hosted
- version: "1.1.0"
- webview_flutter:
- dependency: "direct main"
- description:
- name: webview_flutter
- sha256: "889a0a678e7c793c308c68739996227c9661590605e70b1f6cf6b9a6634f7aec"
- url: "https://pub.dev"
- source: hosted
- version: "4.10.0"
- webview_flutter_android:
- dependency: transitive
- description:
- name: webview_flutter_android
- sha256: "86c2d01c37c4578ee46560109cf2e18fb271f0d080a796f09188d0952352e057"
- url: "https://pub.dev"
- source: hosted
- version: "4.0.2"
- webview_flutter_platform_interface:
- dependency: transitive
- description:
- name: webview_flutter_platform_interface
- sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d
- url: "https://pub.dev"
- source: hosted
- version: "2.10.0"
- webview_flutter_wkwebview:
- dependency: transitive
- description:
- name: webview_flutter_wkwebview
- sha256: "3be297aa4ca78205abdd284cf55f168c35246c75b3079990ad8ba9d257681a30"
- url: "https://pub.dev"
- source: hosted
- version: "3.16.2"
- win32:
- dependency: transitive
- description:
- name: win32
- sha256: "84ba388638ed7a8cb3445a320c8273136ab2631cd5f2c57888335504ddab1bc2"
- url: "https://pub.dev"
- source: hosted
- version: "5.8.0"
- xdg_directories:
- dependency: transitive
- description:
- name: xdg_directories
- sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
- url: "https://pub.dev"
- source: hosted
- version: "1.1.0"
- xml:
- dependency: transitive
- description:
- name: xml
- sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
- url: "https://pub.dev"
- source: hosted
- version: "6.5.0"
- yaml:
- dependency: transitive
- description:
- name: yaml
- sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
- url: "https://pub.dev"
- source: hosted
- version: "3.1.2"
-sdks:
- dart: ">=3.5.3 <4.0.0"
- flutter: ">=3.24.0"
+# Generated by pub
+# See https://dart.dev/tools/pub/glossary#lockfile
+packages:
+ _fe_analyzer_shared:
+ dependency: transitive
+ description:
+ name: _fe_analyzer_shared
+ sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
+ url: "https://pub.dev"
+ source: hosted
+ version: "72.0.0"
+ _macros:
+ dependency: transitive
+ description: dart
+ source: sdk
+ version: "0.3.2"
+ analyzer:
+ dependency: transitive
+ description:
+ name: analyzer
+ sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.7.0"
+ ansicolor:
+ dependency: transitive
+ description:
+ name: ansicolor
+ sha256: "50e982d500bc863e1d703448afdbf9e5a72eb48840a4f766fa361ffd6877055f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.3"
+ archive:
+ dependency: transitive
+ description:
+ name: archive
+ sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.6.1"
+ args:
+ dependency: transitive
+ description:
+ name: args
+ sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.6.0"
+ async:
+ dependency: transitive
+ description:
+ name: async
+ sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.12.0"
+ benchmark:
+ dependency: transitive
+ description:
+ name: benchmark
+ sha256: cb3eeea01e3f054df76ee9775ca680f3afa5f19f39b2bb426ba78ba27654493b
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.3.0"
+ bloc:
+ dependency: transitive
+ description:
+ name: bloc
+ sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "8.1.4"
+ boolean_selector:
+ dependency: transitive
+ description:
+ name: boolean_selector
+ sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.2"
+ build:
+ dependency: transitive
+ description:
+ name: build
+ sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.1"
+ build_config:
+ dependency: transitive
+ description:
+ name: build_config
+ sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.1"
+ build_daemon:
+ dependency: transitive
+ description:
+ name: build_daemon
+ sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.0.2"
+ build_resolvers:
+ dependency: transitive
+ description:
+ name: build_resolvers
+ sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.2"
+ build_runner:
+ dependency: "direct dev"
+ description:
+ name: build_runner
+ sha256: "028819cfb90051c6b5440c7e574d1896f8037e3c96cf17aaeb054c9311cfbf4d"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.13"
+ build_runner_core:
+ dependency: transitive
+ description:
+ name: build_runner_core
+ sha256: f8126682b87a7282a339b871298cc12009cb67109cfa1614d6436fb0289193e0
+ url: "https://pub.dev"
+ source: hosted
+ version: "7.3.2"
+ built_collection:
+ dependency: transitive
+ description:
+ name: built_collection
+ sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.1.1"
+ built_value:
+ dependency: transitive
+ description:
+ name: built_value
+ sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb
+ url: "https://pub.dev"
+ source: hosted
+ version: "8.9.2"
+ camerawesome:
+ dependency: "direct main"
+ description:
+ name: camerawesome
+ sha256: "3619d5605fb14ab72c815532c1d9f635512c75df07b5a742b60a9a4b03b6081e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.0"
+ carousel_slider:
+ dependency: transitive
+ description:
+ name: carousel_slider
+ sha256: "7b006ec356205054af5beaef62e2221160ea36b90fb70a35e4deacd49d0349ae"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.0.0"
+ characters:
+ dependency: transitive
+ description:
+ name: characters
+ sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.0"
+ checked_yaml:
+ dependency: transitive
+ description:
+ name: checked_yaml
+ sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.3"
+ chopper:
+ dependency: "direct main"
+ description:
+ name: chopper
+ sha256: "40899b729fb6d8969d967264b189efaf2452bc3ccf6ed0782d00f1d8a6161c31"
+ url: "https://pub.dev"
+ source: hosted
+ version: "8.0.3"
+ chopper_generator:
+ dependency: "direct dev"
+ description:
+ name: chopper_generator
+ sha256: de438569cba1e2a2888e8d91e3c2ac60106574eea7f36823ed0334e96146328a
+ url: "https://pub.dev"
+ source: hosted
+ version: "8.0.3"
+ clock:
+ dependency: transitive
+ description:
+ name: clock
+ sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.1"
+ code_builder:
+ dependency: transitive
+ description:
+ name: code_builder
+ sha256: "0ec10bf4a89e4c613960bf1e8b42c64127021740fb21640c29c909826a5eea3e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.10.1"
+ collection:
+ dependency: transitive
+ description:
+ name: collection
+ sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.18.0"
+ colorfilter_generator:
+ dependency: transitive
+ description:
+ name: colorfilter_generator
+ sha256: ccc2995e440b1d828d55d99150e7cad64624f3cb4a1e235000de3f93cf10d35c
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.0.8"
+ convert:
+ dependency: transitive
+ description:
+ name: convert
+ sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.2"
+ cross_file:
+ dependency: transitive
+ description:
+ name: cross_file
+ sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.3.4+2"
+ crypto:
+ dependency: transitive
+ description:
+ name: crypto
+ sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.6"
+ csslib:
+ dependency: transitive
+ description:
+ name: csslib
+ sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.2"
+ csv:
+ dependency: transitive
+ description:
+ name: csv
+ sha256: c6aa2679b2a18cb57652920f674488d89712efaf4d3fdf2e537215b35fc19d6c
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.0.0"
+ dart_sort_queue:
+ dependency: transitive
+ description:
+ name: dart_sort_queue
+ sha256: f3353ba8b4850e072d3368757f62edb79af34a9703c3e3df9c59342721f5f5b1
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.0.2+3"
+ dart_style:
+ dependency: transitive
+ description:
+ name: dart_style
+ sha256: "7856d364b589d1f08986e140938578ed36ed948581fbc3bc9aef1805039ac5ab"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.7"
+ dio:
+ dependency: "direct main"
+ description:
+ name: dio
+ sha256: "5598aa796bbf4699afd5c67c0f5f6e2ed542afc956884b9cd58c306966efc260"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.7.0"
+ dio_web_adapter:
+ dependency: transitive
+ description:
+ name: dio_web_adapter
+ sha256: "33259a9276d6cea88774a0000cfae0d861003497755969c92faa223108620dc8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.0"
+ equatable:
+ dependency: "direct main"
+ description:
+ name: equatable
+ sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.5"
+ ffi:
+ dependency: transitive
+ description:
+ name: ffi
+ sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.3"
+ file:
+ dependency: transitive
+ description:
+ name: file
+ sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
+ url: "https://pub.dev"
+ source: hosted
+ version: "7.0.1"
+ fixnum:
+ dependency: transitive
+ description:
+ name: fixnum
+ sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.1"
+ flutter:
+ dependency: "direct main"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_appauth:
+ dependency: "direct main"
+ description:
+ name: flutter_appauth
+ sha256: "6ab0e7fb2cb66db472a71c00e0f0d0888f186d308beaef4bba1a6113fa861096"
+ url: "https://pub.dev"
+ source: hosted
+ version: "8.0.0+1"
+ flutter_appauth_platform_interface:
+ dependency: transitive
+ description:
+ name: flutter_appauth_platform_interface
+ sha256: ccf5e1d8c40dd35b297290b33cc1896648b4b92a2ec3f62a436c62a8eef9a9db
+ url: "https://pub.dev"
+ source: hosted
+ version: "8.0.0"
+ flutter_bloc:
+ dependency: "direct main"
+ description:
+ name: flutter_bloc
+ sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a
+ url: "https://pub.dev"
+ source: hosted
+ version: "8.1.6"
+ flutter_dotenv:
+ dependency: "direct main"
+ description:
+ name: flutter_dotenv
+ sha256: b7c7be5cd9f6ef7a78429cabd2774d3c4af50e79cb2b7593e3d5d763ef95c61b
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.2.1"
+ flutter_inappwebview:
+ dependency: "direct main"
+ description:
+ name: flutter_inappwebview
+ sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.1.5"
+ flutter_inappwebview_android:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_android
+ sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.3"
+ flutter_inappwebview_internal_annotations:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_internal_annotations
+ sha256: "5f80fd30e208ddded7dbbcd0d569e7995f9f63d45ea3f548d8dd4c0b473fb4c8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.1"
+ flutter_inappwebview_ios:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_ios
+ sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.2"
+ flutter_inappwebview_macos:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_macos
+ sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.2"
+ flutter_inappwebview_platform_interface:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_platform_interface
+ sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.0+1"
+ flutter_inappwebview_web:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_web
+ sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.2"
+ flutter_inappwebview_windows:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_windows
+ sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.6.0"
+ flutter_lints:
+ dependency: "direct dev"
+ description:
+ name: flutter_lints
+ sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.0.0"
+ flutter_localizations:
+ dependency: "direct main"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_native_splash:
+ dependency: "direct main"
+ description:
+ name: flutter_native_splash
+ sha256: ee5c9bd2b74ea8676442fd4ab876b5d41681df49276488854d6c81a5377c0ef1
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.2"
+ flutter_secure_storage:
+ dependency: "direct main"
+ description:
+ name: flutter_secure_storage
+ sha256: "165164745e6afb5c0e3e3fcc72a012fb9e58496fb26ffb92cf22e16a821e85d0"
+ url: "https://pub.dev"
+ source: hosted
+ version: "9.2.2"
+ flutter_secure_storage_linux:
+ dependency: transitive
+ description:
+ name: flutter_secure_storage_linux
+ sha256: "4d91bfc23047422cbcd73ac684bc169859ee766482517c22172c86596bf1464b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.1"
+ flutter_secure_storage_macos:
+ dependency: transitive
+ description:
+ name: flutter_secure_storage_macos
+ sha256: "1693ab11121a5f925bbea0be725abfcfbbcf36c1e29e571f84a0c0f436147a81"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.2"
+ flutter_secure_storage_platform_interface:
+ dependency: transitive
+ description:
+ name: flutter_secure_storage_platform_interface
+ sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.2"
+ flutter_secure_storage_web:
+ dependency: transitive
+ description:
+ name: flutter_secure_storage_web
+ sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.1"
+ flutter_secure_storage_windows:
+ dependency: transitive
+ description:
+ name: flutter_secure_storage_windows
+ sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.2"
+ flutter_svg:
+ dependency: "direct main"
+ description:
+ name: flutter_svg
+ sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.10+1"
+ flutter_web_plugins:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ frontend_server_client:
+ dependency: transitive
+ description:
+ name: frontend_server_client
+ sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.0.0"
+ geotypes:
+ dependency: transitive
+ description:
+ name: geotypes
+ sha256: "5bedf57de92283133dd221e363812ef50eaaba414f0823b1974ef7d84b86991f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.0.2"
+ get_it:
+ dependency: "direct main"
+ description:
+ name: get_it
+ sha256: ff97e5e7b2e82e63c82f5658c6ba2605ea831f0f7489b0d2fb255d817ec4eb5e
+ url: "https://pub.dev"
+ source: hosted
+ version: "8.0.0"
+ glob:
+ dependency: transitive
+ description:
+ name: glob
+ sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.2"
+ go_router:
+ dependency: "direct main"
+ description:
+ name: go_router
+ sha256: "6f1b756f6e863259a99135ff3c95026c3cdca17d10ebef2bba2261a25ddc8bbc"
+ url: "https://pub.dev"
+ source: hosted
+ version: "14.3.0"
+ google_fonts:
+ dependency: "direct main"
+ description:
+ name: google_fonts
+ sha256: b1ac0fe2832c9cc95e5e88b57d627c5e68c223b9657f4b96e1487aa9098c7b82
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.2.1"
+ graphs:
+ dependency: transitive
+ description:
+ name: graphs
+ sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.2"
+ html:
+ dependency: transitive
+ description:
+ name: html
+ sha256: "1fc58edeaec4307368c60d59b7e15b9d658b57d7f3125098b6294153c75337ec"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.15.5"
+ http:
+ dependency: "direct main"
+ description:
+ name: http
+ sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.2"
+ http_multi_server:
+ dependency: transitive
+ description:
+ name: http_multi_server
+ sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.2.1"
+ http_parser:
+ dependency: "direct main"
+ description:
+ name: http_parser
+ sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.0.2"
+ image:
+ dependency: "direct main"
+ description:
+ name: image
+ sha256: f31d52537dc417fdcde36088fdf11d191026fd5e4fae742491ebd40e5a8bea7d
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.3.0"
+ intl:
+ dependency: "direct main"
+ description:
+ name: intl
+ sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.19.0"
+ io:
+ dependency: transitive
+ description:
+ name: io
+ sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.4"
+ js:
+ dependency: transitive
+ description:
+ name: js
+ sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.6.7"
+ json2yaml:
+ dependency: transitive
+ description:
+ name: json2yaml
+ sha256: da94630fbc56079426fdd167ae58373286f603371075b69bf46d848d63ba3e51
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.1"
+ json_annotation:
+ dependency: "direct main"
+ description:
+ name: json_annotation
+ sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.9.0"
+ json_serializable:
+ dependency: "direct dev"
+ description:
+ name: json_serializable
+ sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.8.0"
+ jwt_decoder:
+ dependency: "direct main"
+ description:
+ name: jwt_decoder
+ sha256: "54774aebf83f2923b99e6416b4ea915d47af3bde56884eb622de85feabbc559f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ lints:
+ dependency: transitive
+ description:
+ name: lints
+ sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.0.0"
+ logger:
+ dependency: "direct main"
+ description:
+ name: logger
+ sha256: "697d067c60c20999686a0add96cf6aba723b3aa1f83ecf806a8097231529ec32"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.0"
+ logging:
+ dependency: transitive
+ description:
+ name: logging
+ sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.0"
+ macros:
+ dependency: transitive
+ description:
+ name: macros
+ sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.1.2-main.4"
+ maplibre_gl:
+ dependency: "direct main"
+ description:
+ name: maplibre_gl
+ sha256: ea2fa443e7d5dc18db7f37a0f6f5af40642888c56b81a14441aeddea077adaea
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.20.0"
+ maplibre_gl_platform_interface:
+ dependency: "direct main"
+ description:
+ name: maplibre_gl_platform_interface
+ sha256: "718c3503f36936fbf35c34d6ddf8bf770474c5ba1e6cb1d8caece44efae424af"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.20.0"
+ maplibre_gl_web:
+ dependency: transitive
+ description:
+ name: maplibre_gl_web
+ sha256: e7d71b08f24dca70e9c9cf841b096704a677e6239447d87220ec071355768149
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.20.0"
+ markdown:
+ dependency: transitive
+ description:
+ name: markdown
+ sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051
+ url: "https://pub.dev"
+ source: hosted
+ version: "7.2.2"
+ matcher:
+ dependency: transitive
+ description:
+ name: matcher
+ sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.12.17"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.11.1"
+ matrix2d:
+ dependency: transitive
+ description:
+ name: matrix2d
+ sha256: "188718dd3bc2a31e372cfd0791b0f77f4f13ea76164147342cc378d9132949e7"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.4"
+ meta:
+ dependency: transitive
+ description:
+ name: meta
+ sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.15.0"
+ mime:
+ dependency: transitive
+ description:
+ name: mime
+ sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.0"
+ nested:
+ dependency: transitive
+ description:
+ name: nested
+ sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.0"
+ package_config:
+ dependency: transitive
+ description:
+ name: package_config
+ sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.0"
+ path:
+ dependency: transitive
+ description:
+ name: path
+ sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.9.0"
+ path_parsing:
+ dependency: transitive
+ description:
+ name: path_parsing
+ sha256: "45f7d6bba1128761de5540f39d5ca000ea8a1f22f06b76b61094a60a2997bd0e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.2"
+ path_provider:
+ dependency: transitive
+ description:
+ name: path_provider
+ sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.4"
+ path_provider_android:
+ dependency: transitive
+ description:
+ name: path_provider_android
+ sha256: c464428172cb986b758c6d1724c603097febb8fb855aa265aeecc9280c294d4a
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.12"
+ path_provider_foundation:
+ dependency: transitive
+ description:
+ name: path_provider_foundation
+ sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.0"
+ path_provider_linux:
+ dependency: transitive
+ description:
+ name: path_provider_linux
+ sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.1"
+ path_provider_platform_interface:
+ dependency: transitive
+ description:
+ name: path_provider_platform_interface
+ sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.2"
+ path_provider_windows:
+ dependency: transitive
+ description:
+ name: path_provider_windows
+ sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.0"
+ petitparser:
+ dependency: transitive
+ description:
+ name: petitparser
+ sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.0.2"
+ platform:
+ dependency: transitive
+ description:
+ name: platform
+ sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.6"
+ plugin_platform_interface:
+ dependency: transitive
+ description:
+ name: plugin_platform_interface
+ sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.8"
+ pool:
+ dependency: transitive
+ description:
+ name: pool
+ sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.5.1"
+ provider:
+ dependency: transitive
+ description:
+ name: provider
+ sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.1.2"
+ pub_semver:
+ dependency: transitive
+ description:
+ name: pub_semver
+ sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.4"
+ pubspec_parse:
+ dependency: transitive
+ description:
+ name: pubspec_parse
+ sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.0"
+ qs_dart:
+ dependency: transitive
+ description:
+ name: qs_dart
+ sha256: be73d060d29c0716ded88380ba32e87ce8105f0ba234edb3edefa0d74d47d64b
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.4"
+ rbush:
+ dependency: transitive
+ description:
+ name: rbush
+ sha256: "48b683421b4afb43a642f82c6aa31911e54f3069143d31c7d33cbe329df13403"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.1"
+ recase:
+ dependency: transitive
+ description:
+ name: recase
+ sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.1.0"
+ recursive_regex:
+ dependency: transitive
+ description:
+ name: recursive_regex
+ sha256: f7252e3d3dfd1665e594d9fe035eca6bc54139b1f2fee38256fa427ea41adc60
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.0"
+ rxdart:
+ dependency: transitive
+ description:
+ name: rxdart
+ sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.28.0"
+ shelf:
+ dependency: transitive
+ description:
+ name: shelf
+ sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.4.1"
+ shelf_web_socket:
+ dependency: transitive
+ description:
+ name: shelf_web_socket
+ sha256: cc36c297b52866d203dbf9332263c94becc2fe0ceaa9681d07b6ef9807023b67
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ sky_engine:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.99"
+ slang:
+ dependency: "direct main"
+ description:
+ name: slang
+ sha256: b04db2dbaf927b28600a2f8a272a3bf2ae309556dcc5d6beb02d66af0be39e4c
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.1.0"
+ slang_flutter:
+ dependency: "direct main"
+ description:
+ name: slang_flutter
+ sha256: "59988f37bb8b50d96ee46832a8a389036c0da26c04b1b1d4aa6690c00f70eccf"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.1.0"
+ source_gen:
+ dependency: transitive
+ description:
+ name: source_gen
+ sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.5.0"
+ source_helper:
+ dependency: transitive
+ description:
+ name: source_helper
+ sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.4"
+ source_span:
+ dependency: transitive
+ description:
+ name: source_span
+ sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.10.0"
+ stack_trace:
+ dependency: transitive
+ description:
+ name: stack_trace
+ sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.12.0"
+ stream_channel:
+ dependency: transitive
+ description:
+ name: stream_channel
+ sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.2"
+ stream_transform:
+ dependency: transitive
+ description:
+ name: stream_transform
+ sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.0"
+ string_scanner:
+ dependency: transitive
+ description:
+ name: string_scanner
+ sha256: "0bd04f5bb74fcd6ff0606a888a30e917af9bd52820b178eaa464beb11dca84b6"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.4.0"
+ swagger_dart_code_generator:
+ dependency: "direct dev"
+ description:
+ name: swagger_dart_code_generator
+ sha256: e6fab279c2adb3f91aa170c9126601d22e1485217dddc1443cf3c05eb6480d45
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.1"
+ sweepline_intersections:
+ dependency: transitive
+ description:
+ name: sweepline_intersections
+ sha256: a665c707200a4f07140a4029b41a7c4883beb3f04322cd8e08ebf650f69e1176
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.0.4"
+ term_glyph:
+ dependency: transitive
+ description:
+ name: term_glyph
+ sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.1"
+ test_api:
+ dependency: transitive
+ description:
+ name: test_api
+ sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.7.3"
+ timing:
+ dependency: transitive
+ description:
+ name: timing
+ sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.1"
+ turf:
+ dependency: "direct main"
+ description:
+ name: turf
+ sha256: "75347c45a5c1de805db7cb182286f05a3770e01546626c4dc292709d15cbe436"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.0.10"
+ turf_equality:
+ dependency: transitive
+ description:
+ name: turf_equality
+ sha256: f0f44ffe389547941358e0d3d4a747db2bd56115b32ff1cede5e5bdf3126a3e2
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.1.0"
+ turf_pip:
+ dependency: transitive
+ description:
+ name: turf_pip
+ sha256: ba4fd414baffd5d7b30880658ad6db82461c49ec023f8ffd0c23d398ad8b14be
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.0.2"
+ typed_data:
+ dependency: transitive
+ description:
+ name: typed_data
+ sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.4.0"
+ universal_io:
+ dependency: transitive
+ description:
+ name: universal_io
+ sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.2"
+ vector_graphics:
+ dependency: transitive
+ description:
+ name: vector_graphics
+ sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.11+1"
+ vector_graphics_codec:
+ dependency: transitive
+ description:
+ name: vector_graphics_codec
+ sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.11+1"
+ vector_graphics_compiler:
+ dependency: transitive
+ description:
+ name: vector_graphics_compiler
+ sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.11+1"
+ vector_math:
+ dependency: transitive
+ description:
+ name: vector_math
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.4"
+ watcher:
+ dependency: transitive
+ description:
+ name: watcher
+ sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.0"
+ weak_map:
+ dependency: transitive
+ description:
+ name: weak_map
+ sha256: "95ca338f0cdf5f0022cc283dfa4d97f6f6b03752f67eca85ebe6d7a679ffe3ed"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.1"
+ web:
+ dependency: transitive
+ description:
+ name: web
+ sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.0"
+ web_socket:
+ dependency: transitive
+ description:
+ name: web_socket
+ sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.1.6"
+ web_socket_channel:
+ dependency: transitive
+ description:
+ name: web_socket_channel
+ sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.1"
+ webview_flutter:
+ dependency: "direct main"
+ description:
+ name: webview_flutter
+ sha256: "889a0a678e7c793c308c68739996227c9661590605e70b1f6cf6b9a6634f7aec"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.10.0"
+ webview_flutter_android:
+ dependency: transitive
+ description:
+ name: webview_flutter_android
+ sha256: "86c2d01c37c4578ee46560109cf2e18fb271f0d080a796f09188d0952352e057"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.0.2"
+ webview_flutter_platform_interface:
+ dependency: transitive
+ description:
+ name: webview_flutter_platform_interface
+ sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.10.0"
+ webview_flutter_wkwebview:
+ dependency: transitive
+ description:
+ name: webview_flutter_wkwebview
+ sha256: "3be297aa4ca78205abdd284cf55f168c35246c75b3079990ad8ba9d257681a30"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.16.2"
+ win32:
+ dependency: transitive
+ description:
+ name: win32
+ sha256: "84ba388638ed7a8cb3445a320c8273136ab2631cd5f2c57888335504ddab1bc2"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.8.0"
+ xdg_directories:
+ dependency: transitive
+ description:
+ name: xdg_directories
+ sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.0"
+ xml:
+ dependency: transitive
+ description:
+ name: xml
+ sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.5.0"
+ yaml:
+ dependency: transitive
+ description:
+ name: yaml
+ sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.2"
+sdks:
+ dart: ">=3.5.3 <4.0.0"
+ flutter: ">=3.24.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 677a6c98..b35b8ec9 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,100 +1,121 @@
-name: gruene_app
-description: "App for the German party BÜNDNIS 90/DIE GRÜNEN"
-# The following line prevents the package from being accidentally published to
-# pub.dev using `flutter pub publish`. This is preferred for private packages.
-publish_to: 'none' # Remove this line if you wish to publish to pub.dev
-
-environment:
- sdk: ^3.5.3
-
-# Dependencies specify other packages that your package needs in order to work.
-# To automatically upgrade your package dependencies to the latest versions
-# consider running `flutter pub upgrade --major-versions`. Alternatively,
-# dependencies can be manually updated by changing the version numbers below to
-# the latest version available on pub.dev. To see which dependencies have newer
-# versions available, run `flutter pub outdated`.
-dependencies:
- flutter:
- sdk: flutter
- flutter_localizations:
- sdk: flutter
- flutter_bloc: ^8.1.6
- get_it: ^8.0.0
- dio: ^5.7.0
- slang: ^4.1.0
- slang_flutter: ^4.1.0
- go_router: ^14.3.0
- google_fonts: ^6.2.1
- flutter_svg: ^2.0.10+1
- flutter_appauth: ^8.0.0+1
- flutter_secure_storage: ^9.2.2
- flutter_dotenv: ^5.2.1
- flutter_inappwebview: ^6.1.5
- equatable: ^2.0.5
- logger: ^2.4.0
- jwt_decoder: ^2.0.1
- flutter_native_splash: ^2.4.2
- webview_flutter: ^4.10.0
-
-dev_dependencies:
-
- # The "flutter_lints" package below contains a set of recommended lints to
- # encourage good coding practices. The lint set provided by the package is
- # activated in the `analysis_options.yaml` file located at the root of your
- # package. See that file for information about deactivating specific lint
- # rules and activating additional ones.
- flutter_lints: ^5.0.0
-
-# For information on the generic Dart part of this file, see the
-# following page: https://dart.dev/tools/pub/pubspec
-
-# The following section is specific to Flutter packages.
-flutter:
- assets:
- - assets/bottom_navigation/
- - assets/icons/
- - assets/splash/
- - assets/graphics/
- - .env
-
-
- # To add assets to your application, add an assets section, like this:
- # assets:
- # - images/a_dot_burr.jpeg
- # - images/a_dot_ham.jpeg
-
- # An image asset can refer to one or more resolution-specific "variants", see
- # https://flutter.dev/to/resolution-aware-images
-
- # For details regarding adding assets from package dependencies, see
- # https://flutter.dev/to/asset-from-package
-
- # To add custom fonts to your application, add a fonts section here,
- # in this "flutter" section. Each entry in this list should have a
- # "family" key with the font family name, and a "fonts" key with a
- # list giving the asset and other descriptors for the font. For
- # example:
- # fonts:
- # - family: Schyler
- # fonts:
- # - asset: fonts/Schyler-Regular.ttf
- # - asset: fonts/Schyler-Italic.ttf
- # style: italic
- # - family: Trajan Pro
- # fonts:
- # - asset: fonts/TrajanPro.ttf
- # - asset: fonts/TrajanPro_Bold.ttf
- # weight: 700
- #
- # For details regarding fonts from package dependencies,
- # see https://flutter.dev/to/font-from-package
-
-flutter_native_splash:
- color: "#ffffff"
- image: assets/splash/logo.png
- android_12:
- color: "#ffffff"
- image: assets/splash/logo_android12.png
- web: false
- android_gravity: center
+name: gruene_app
+description: "App for the German party BÜNDNIS 90/DIE GRÜNEN"
+# The following line prevents the package from being accidentally published to
+# pub.dev using `flutter pub publish`. This is preferred for private packages.
+publish_to: 'none' # Remove this line if you wish to publish to pub.dev
+
+environment:
+ sdk: ^3.5.3
+
+# Dependencies specify other packages that your package needs in order to work.
+# To automatically upgrade your package dependencies to the latest versions
+# consider running `flutter pub upgrade --major-versions`. Alternatively,
+# dependencies can be manually updated by changing the version numbers below to
+# the latest version available on pub.dev. To see which dependencies have newer
+# versions available, run `flutter pub outdated`.
+dependencies:
+ flutter:
+ sdk: flutter
+ flutter_localizations:
+ sdk: flutter
+ flutter_bloc: ^8.1.6
+ get_it: ^8.0.0
+ dio: ^5.7.0
+ slang: ^4.1.0
+ slang_flutter: ^4.1.0
+ go_router: ^14.3.0
+ google_fonts: ^6.2.1
+ flutter_svg: ^2.0.10+1
+ flutter_appauth: ^8.0.0+1
+ flutter_secure_storage: ^9.2.2
+ flutter_dotenv: ^5.2.1
+ flutter_inappwebview: ^6.1.5
+ equatable: ^2.0.5
+ logger: ^2.4.0
+ jwt_decoder: ^2.0.1
+ flutter_native_splash: ^2.4.2
+ webview_flutter: ^4.10.0
+ maplibre_gl: ^0.20.0
+ maplibre_gl_platform_interface: ^0.20.0
+#--------- swagger_dart_code_generator --------------
+ chopper: ^8.0.0
+ json_annotation: ^4.8.0
+#----------------------------------------------------
+ http: ^1.2.2
+ turf: ^0.0.10
+ camerawesome: ^2.1.0
+ intl: ^0.19.0
+ image: ^4.3.0
+ http_parser: ^4.0.2
+
+dev_dependencies:
+
+ # The "flutter_lints" package below contains a set of recommended lints to
+ # encourage good coding practices. The lint set provided by the package is
+ # activated in the `analysis_options.yaml` file located at the root of your
+ # package. See that file for information about deactivating specific lint
+ # rules and activating additional ones.
+ flutter_lints: ^5.0.0
+#--------- swagger_dart_code_generator --------------
+ build_runner: ^2.3.3
+ chopper_generator: ^8.0.0
+ json_serializable: ^6.6.1
+ swagger_dart_code_generator: ^3.0.1
+#----------------------------------------------------
+
+# For information on the generic Dart part of this file, see the
+# following page: https://dart.dev/tools/pub/pubspec
+
+# The following section is specific to Flutter packages.
+flutter:
+ uses-material-design: true
+ assets:
+ - assets/bottom_navigation/
+ - assets/icons/
+ - assets/splash/
+ - assets/graphics/
+ - assets/symbols/
+ - assets/symbols/posters/
+ - .env
+
+
+ # To add assets to your application, add an assets section, like this:
+ # assets:
+ # - images/a_dot_burr.jpeg
+ # - images/a_dot_ham.jpeg
+
+ # An image asset can refer to one or more resolution-specific "variants", see
+ # https://flutter.dev/to/resolution-aware-images
+
+ # For details regarding adding assets from package dependencies, see
+ # https://flutter.dev/to/asset-from-package
+
+ # To add custom fonts to your application, add a fonts section here,
+ # in this "flutter" section. Each entry in this list should have a
+ # "family" key with the font family name, and a "fonts" key with a
+ # list giving the asset and other descriptors for the font. For
+ # example:
+ # fonts:
+ # - family: Schyler
+ # fonts:
+ # - asset: fonts/Schyler-Regular.ttf
+ # - asset: fonts/Schyler-Italic.ttf
+ # style: italic
+ # - family: Trajan Pro
+ # fonts:
+ # - asset: fonts/TrajanPro.ttf
+ # - asset: fonts/TrajanPro_Bold.ttf
+ # weight: 700
+ #
+ # For details regarding fonts from package dependencies,
+ # see https://flutter.dev/to/font-from-package
+
+flutter_native_splash:
+ color: "#ffffff"
+ image: assets/splash/logo.png
+ android_12:
+ color: "#ffffff"
+ image: assets/splash/logo_android12.png
+ web: false
+ android_gravity: center
ios_content_mode: scaleAspectFit
\ No newline at end of file
diff --git a/swaggers/gruene-api.yaml b/swaggers/gruene-api.yaml
new file mode 100644
index 00000000..69865efc
--- /dev/null
+++ b/swaggers/gruene-api.yaml
@@ -0,0 +1,2659 @@
+openapi: 3.0.0
+paths:
+ /v1/users:
+ get:
+ operationId: findUsers
+ summary: Find users
+ parameters:
+ - name: search
+ required: false
+ in: query
+ description: Search term to look for in firstname, lastname, email, username.
+ schema:
+ type: string
+ - name: userIds
+ required: false
+ in: query
+ description: Only return users with matching user id.
+ schema:
+ type: array
+ items:
+ type: string
+ - name: limit
+ required: false
+ in: query
+ schema:
+ minimum: 1
+ maximum: 200
+ type: number
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FindUsersResponse'
+ '401':
+ description: ''
+ tags:
+ - users
+ security:
+ - bearer: []
+ - basic: []
+ - api_key: []
+ /v1/users/self:
+ get:
+ operationId: getSelf
+ summary: Get the authenticated user
+ parameters: []
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/User'
+ '400':
+ description: No user provided by used authentication method
+ '401':
+ description: ''
+ tags:
+ - users
+ security:
+ - bearer: []
+ - basic: []
+ - api_key: []
+ /v1/users/{userId}:
+ get:
+ operationId: getUser
+ summary: Get user by id
+ parameters:
+ - name: userId
+ required: true
+ in: path
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/User '
+ '401':
+ description: ''
+ '404':
+ description: ''
+ tags:
+ - users
+ security:
+ - bearer: []
+ - basic: []
+ - api_key: []
+ /v1/users/{userId}/rbac-structure:
+ get:
+ operationId: getUserRbacStructure
+ summary: Get user RBAC structure
+ parameters:
+ - name: userId
+ required: true
+ in: path
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserRbacStructure'
+ '401':
+ description: ''
+ '404':
+ description: ''
+ tags:
+ - users
+ security:
+ - bearer: []
+ - basic: []
+ - api_key: []
+ /v1/party/organizations:
+ get:
+ operationId: findOrganizations
+ summary: Find all organizations
+ parameters: []
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FindNbOrganizationsResponse'
+ '401':
+ description: ''
+ tags:
+ - nb-api
+ security:
+ - basic: []
+ - api_key: []
+ /v1/party/groups:
+ get:
+ operationId: findGroups
+ summary: Find all groups
+ parameters:
+ - required: false
+ description: Filter by external reference type
+ name: filter[external_refs.type]
+ in: query
+ schema:
+ example: SHERPA
+ enum:
+ - SHERPA
+ type: string
+ - required: false
+ description: Filter by external reference ID (sherpa role id)
+ name: filter[external_refs.key]
+ in: query
+ schema:
+ example: '12345678'
+ type: string
+ - required: false
+ description: Filter by role level
+ name: filter[level]
+ in: query
+ schema:
+ enum:
+ - DE:BUNDESVERBAND
+ - DE:LANDESVERBAND
+ - DE:KREISVERBAND
+ - DE:ORTSVERBAND
+ type: string
+ - required: false
+ description: Filter by role type
+ name: filter[type]
+ in: query
+ schema:
+ example: EXECUTIVE_BOARD
+ type: string
+ - required: false
+ description: Filter by role slug
+ name: filter[slug]
+ in: query
+ schema:
+ example: KV_EXECUTIVE_BOARD
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FindNbGroupsResponse'
+ '401':
+ description: ''
+ tags:
+ - nb-api
+ security:
+ - basic: []
+ - api_key: []
+ /v1/party/regionalchapters:
+ get:
+ operationId: findRegionalChapters
+ summary: Find all regional chapters
+ parameters:
+ - name: limit
+ required: false
+ in: query
+ description: Page limit
+ schema:
+ minimum: 1
+ type: number
+ - name: offset
+ required: false
+ in: query
+ description: Page offset
+ schema:
+ minimum: 0
+ type: number
+ - required: false
+ description: Filter by query
+ name: filter[query]
+ in: query
+ schema:
+ type: string
+ - required: false
+ description: Filter by ID prefix
+ name: filter[id_prefix]
+ in: query
+ schema:
+ maxLength: 8
+ type: string
+ - required: false
+ description: Filter by type
+ name: filter[type]
+ in: query
+ schema:
+ enum:
+ - BV
+ - LV
+ - KV
+ - OV
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FindNbRegionalChaptersResponse'
+ '401':
+ description: ''
+ tags:
+ - nb-api
+ security:
+ - basic: []
+ - api_key: []
+ /v1/party/regionalchapters/{divisionKey}:
+ get:
+ operationId: getRegionalChapter
+ summary: Get regional chapter by division key
+ parameters:
+ - name: divisionKey
+ required: true
+ in: path
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/NbRegionalChapter'
+ '401':
+ description: ''
+ tags:
+ - nb-api
+ security:
+ - basic: []
+ - api_key: []
+ /v1/profiles:
+ get:
+ operationId: findProfiles
+ summary: Find user profiles
+ parameters:
+ - name: limit
+ required: false
+ in: query
+ schema:
+ minimum: 1
+ default: 20
+ type: number
+ - name: tags
+ required: false
+ in: query
+ description: Filter by profile tag ids
+ schema:
+ type: array
+ items:
+ type: string
+ - name: offset
+ required: false
+ in: query
+ schema:
+ minimum: 0
+ type: number
+ - name: search
+ required: false
+ in: query
+ description: Search term to look for in firstName, lastName and username
+ schema:
+ type: string
+ - name: division
+ required: false
+ in: query
+ description: |-
+ Division key to filter profiles.
+ Only include profiles that are member of given division.
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FindProfilesResponse'
+ '401':
+ description: ''
+ tags:
+ - profiles
+ security:
+ - api_key: []
+ - bearer: []
+ - oauth2: []
+ post:
+ operationId: createProfile
+ summary: Create user profile
+ parameters: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CreateProfile'
+ responses:
+ '201':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Profile'
+ '401':
+ description: ''
+ tags:
+ - profiles
+ security:
+ - api_key: []
+ - bearer: []
+ - oauth2: []
+ /v1/profiles/self:
+ get:
+ operationId: getOwnProfile
+ summary: Get the authenticated user's profile
+ parameters: []
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Profile'
+ '400':
+ description: No user provided by used authentication method
+ '401':
+ description: ''
+ tags:
+ - profiles
+ security:
+ - api_key: []
+ - bearer: []
+ - oauth2: []
+ /v1/profiles/{profileId}:
+ get:
+ operationId: getProfile
+ summary: Get a user profile
+ parameters:
+ - name: profileId
+ required: true
+ in: path
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/PublicProfile'
+ '401':
+ description: ''
+ '404':
+ description: ''
+ tags:
+ - profiles
+ security:
+ - api_key: []
+ - bearer: []
+ - oauth2: []
+ put:
+ operationId: updateProfile
+ summary: Update user profile
+ description: >-
+ When updating the collection attributes like `messengers` all items must
+ be included. Omitting an item means it will be deleted. If an `id`
+ attribute is present it means update the give item. Omitting the `id`
+ attribute will add a new item to the collection.
+ parameters:
+ - name: profileId
+ required: true
+ in: path
+ schema:
+ type: string
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdateProfile'
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Profile'
+ '400':
+ description: No user provided by used authentication method
+ '401':
+ description: ''
+ tags:
+ - profiles
+ security:
+ - api_key: []
+ - bearer: []
+ - oauth2: []
+ delete:
+ operationId: deleteProfile
+ summary: Delete user profile
+ parameters:
+ - name: profileId
+ required: true
+ in: path
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Profile'
+ '401':
+ description: ''
+ '404':
+ description: ''
+ tags:
+ - profiles
+ security:
+ - api_key: []
+ - bearer: []
+ - oauth2: []
+ /v1/profiles/{profileId}/image:
+ put:
+ operationId: updateProfileImage
+ summary: Update profile image
+ requestBody:
+ content:
+ multipart/form-data:
+ schema:
+ type: object
+ required:
+ - profileImage
+ properties:
+ profileImage:
+ type: file
+ parameters:
+ - name: profileId
+ required: true
+ in: path
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Profile'
+ '400':
+ description: No user provided by used authentication method
+ '401':
+ description: ''
+ tags:
+ - profiles
+ security:
+ - api_key: []
+ - bearer: []
+ - oauth2: []
+ delete:
+ operationId: deleteProfileImage
+ summary: Delete user profile image
+ parameters:
+ - name: profileId
+ required: true
+ in: path
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Profile'
+ '400':
+ description: No user provided by used authentication method
+ '401':
+ description: ''
+ tags:
+ - profiles
+ security:
+ - api_key: []
+ - bearer: []
+ - oauth2: []
+ /v1/profile-tags:
+ get:
+ operationId: findProfileTags
+ summary: List profile tags
+ parameters:
+ - name: limit
+ required: false
+ in: query
+ schema:
+ minimum: 1
+ default: 20
+ type: number
+ - name: offset
+ required: false
+ in: query
+ schema:
+ minimum: 0
+ type: number
+ - name: search
+ required: false
+ in: query
+ description: Search label attributes for substring
+ schema:
+ type: string
+ - name: type
+ required: false
+ in: query
+ description: Filter by type
+ schema:
+ example: interest
+ enum:
+ - skill
+ - interest
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FindProfileTagsResponse'
+ '401':
+ description: ''
+ tags:
+ - profiles
+ security:
+ - bearer: []
+ - api_key: []
+ /v1/offboarding/users/self:
+ get:
+ operationId: findUsersToOffboard
+ summary: >-
+ Find users to offboard for the service associated with the used
+ credentials
+ parameters:
+ - name: limit
+ required: false
+ in: query
+ description: >-
+ Amount of items to retrieve. This value is ignored when a cursor is
+ set.
+ schema:
+ minimum: 1
+ maximum: 1000
+ default: 200
+ type: number
+ - name: after
+ required: false
+ in: query
+ description: Cursor for the next result set.
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FindOffboardingUsersResponse'
+ '401':
+ description: ''
+ tags:
+ - offboarding
+ security:
+ - basic: []
+ /v1/offboarding/users/self/batch:
+ post:
+ operationId: batchUpdateOffboardingServiceUsers
+ summary: Batch update offboarding users for the authenticated service.
+ parameters: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/BatchUpdateOffboardingServiceUsers'
+ responses:
+ '201':
+ description: ''
+ '401':
+ description: ''
+ tags:
+ - offboarding
+ security:
+ - basic: []
+ /v1/divisions:
+ get:
+ operationId: findDivisions
+ summary: Find divisions
+ parameters:
+ - name: limit
+ required: false
+ in: query
+ schema:
+ minimum: 1
+ default: 20
+ type: number
+ - name: offset
+ required: false
+ in: query
+ schema:
+ minimum: 0
+ type: number
+ - name: hierarchy
+ required: false
+ in: query
+ description: Filter by hierarchy
+ schema:
+ example: GR
+ enum:
+ - GR
+ - GJ
+ - KPV
+ type: string
+ - name: level
+ required: false
+ in: query
+ description: Filter by hierarchy level
+ schema:
+ example: BV
+ enum:
+ - BV
+ - LV
+ - KV
+ - OV
+ type: string
+ - name: division_key
+ required: false
+ in: query
+ description: Filter by division keys
+ schema:
+ type: array
+ items:
+ type: string
+ - name: search
+ required: false
+ in: query
+ description: Search name attributes for substring
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FindDivisionsResponse'
+ '401':
+ description: ''
+ tags:
+ - divisions
+ security:
+ - bearer: []
+ - basic: []
+ - api_key: []
+ /v1/divisions/{divisionId}:
+ get:
+ operationId: getDivision
+ summary: Get division by id
+ parameters:
+ - name: divisionId
+ required: true
+ in: path
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Division'
+ '401':
+ description: ''
+ '404':
+ description: ''
+ tags:
+ - divisions
+ security:
+ - bearer: []
+ - basic: []
+ - api_key: []
+ /v1/roles:
+ get:
+ operationId: findRoles
+ summary: Find roles
+ parameters:
+ - name: limit
+ required: false
+ in: query
+ schema:
+ minimum: 1
+ default: 20
+ type: number
+ - name: offset
+ required: false
+ in: query
+ schema:
+ minimum: 0
+ type: number
+ - name: search
+ required: false
+ in: query
+ description: Search term to look for in role name
+ schema:
+ type: string
+ - name: category
+ required: false
+ in: query
+ description: Filter by category id
+ schema:
+ type: array
+ items:
+ type: string
+ - name: tag
+ required: false
+ in: query
+ description: Filter by tag id
+ schema:
+ type: array
+ items:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FindRolesResponse'
+ '401':
+ description: ''
+ tags:
+ - roles
+ security:
+ - bearer: []
+ - basic: []
+ - api_key: []
+ /v1/roles/{roleId}:
+ get:
+ operationId: getRole
+ summary: Get role by id
+ parameters:
+ - name: roleId
+ required: true
+ in: path
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Role'
+ '401':
+ description: ''
+ '404':
+ description: ''
+ tags:
+ - roles
+ security:
+ - bearer: []
+ - basic: []
+ - api_key: []
+ /v1/role-tags:
+ get:
+ operationId: findRoleTags
+ summary: Find role tags
+ parameters:
+ - name: limit
+ required: false
+ in: query
+ schema:
+ minimum: 1
+ default: 20
+ type: number
+ - name: offset
+ required: false
+ in: query
+ schema:
+ minimum: 0
+ type: number
+ - name: search
+ required: false
+ in: query
+ description: Search name attribute for substring
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FindRoleTagsResponse'
+ '401':
+ description: ''
+ tags:
+ - roles
+ security:
+ - bearer: []
+ - basic: []
+ - api_key: []
+ /v1/role-categories:
+ get:
+ operationId: findRoleCategories
+ summary: Find role categories
+ parameters:
+ - name: limit
+ required: false
+ in: query
+ schema:
+ minimum: 1
+ default: 20
+ type: number
+ - name: offset
+ required: false
+ in: query
+ schema:
+ minimum: 0
+ type: number
+ - name: search
+ required: false
+ in: query
+ description: Search name attribute for substring
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FindRoleCategoriesResponse'
+ '401':
+ description: ''
+ tags:
+ - roles
+ security:
+ - bearer: []
+ - basic: []
+ - api_key: []
+ /v1/campaigns/pois:
+ post:
+ operationId: createPoi
+ summary: Create a new POI
+ parameters: []
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/CreatePoi'
+ responses:
+ '201':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Poi'
+ '401':
+ description: ''
+ tags:
+ - campaigns
+ security:
+ - bearer: []
+ - oauth2: []
+ get:
+ operationId: findPois
+ summary: Find POIs
+ parameters:
+ - name: type
+ required: false
+ in: query
+ description: filter by POI type
+ schema:
+ example: POSTER
+ enum:
+ - FLYER_SPOT
+ - POSTER
+ - HOUSE
+ type: string
+ - name: bbox
+ required: false
+ in: query
+ schema:
+ example: '-74.006,40.7128,-73.935242,40.789142'
+ type: string
+ - name: agent_id
+ required: false
+ in: query
+ description: Filter by agent id
+ schema:
+ example: '1005'
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/FindPoisResponse'
+ '401':
+ description: ''
+ tags:
+ - campaigns
+ security:
+ - bearer: []
+ - oauth2: []
+ /v1/campaigns/pois/{poiId}:
+ get:
+ operationId: getPoi
+ summary: Get a POI
+ parameters:
+ - name: poiId
+ required: true
+ in: path
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Poi'
+ '401':
+ description: ''
+ '404':
+ description: ''
+ tags:
+ - campaigns
+ security:
+ - bearer: []
+ - oauth2: []
+ put:
+ operationId: updatePoi
+ summary: Update a POI
+ parameters:
+ - name: poiId
+ required: true
+ in: path
+ schema:
+ type: string
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UpdatePoi'
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Poi'
+ '401':
+ description: ''
+ '404':
+ description: ''
+ tags:
+ - campaigns
+ security:
+ - bearer: []
+ - oauth2: []
+ delete:
+ operationId: deletePoi
+ summary: Delete a POI
+ parameters:
+ - name: poiId
+ required: true
+ in: path
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Poi'
+ '401':
+ description: ''
+ '404':
+ description: ''
+ tags:
+ - campaigns
+ security:
+ - bearer: []
+ - oauth2: []
+ /v1/campaigns/pois/{poiId}/photos:
+ post:
+ operationId: addPoiPhoto
+ summary: Add POI photo
+ requestBody:
+ content:
+ multipart/form-data:
+ schema:
+ type: object
+ required:
+ - image
+ properties:
+ image:
+ type: file
+ parameters:
+ - name: poiId
+ required: true
+ in: path
+ schema:
+ type: string
+ responses:
+ '201':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Poi'
+ '401':
+ description: ''
+ '404':
+ description: ''
+ tags:
+ - campaigns
+ security:
+ - bearer: []
+ - oauth2: []
+ /v1/campaigns/pois/{poiId}/photos/{photoId}:
+ delete:
+ operationId: deletePoiPhoto
+ summary: Delete a POI Photo
+ parameters:
+ - name: poiId
+ required: true
+ in: path
+ schema:
+ type: string
+ - name: photoId
+ required: true
+ in: path
+ schema:
+ type: string
+ responses:
+ '200':
+ description: ''
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/Poi'
+ '401':
+ description: ''
+ '404':
+ description: ''
+ tags:
+ - campaigns
+ security:
+ - bearer: []
+ - oauth2: []
+ /health:
+ get:
+ tags:
+ - health
+ security: []
+ description: health check endpoint
+ responses:
+ '200':
+ description: health check response
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/HealthCheckResponse'
+info:
+ title: Gruene API
+ description: >
+
+ ## OpenAPI Endpoints
+
+ OpenAPI Spec in JSON
+
+ OpenAPI Spec in YAML
+
+
+ ### Offboarding
+
+ Every service conntected to Grünes Netz needs to remove users when they are
+ removed from `saml.gruene.de`.
+
+ Connected services need to pull a list of users waiting for removal at least
+ once a week.
+
+ api.gruene.de needs to be informed whether the user did not exist or was
+ removed.
+
+ API tokens can be obtained from `technik@verdigado.com`.
+ version: 0.1.0
+ contact: {}
+tags: []
+servers:
+ - url: https://api.gruene.de
+ description: Production
+ - url: http://192.168.178.35:5000
+ description: Development
+components:
+ securitySchemes:
+ basic:
+ type: http
+ scheme: basic
+ bearer:
+ scheme: bearer
+ bearerFormat: JWT
+ type: http
+ api_key:
+ type: apiKey
+ in: header
+ name: x-api-key
+ description: Api Key Authentication
+ schemas:
+ 'User':
+ type: object
+ properties:
+ id:
+ type: string
+ description: The User Id (Sherpa Id)
+ example: '12345678'
+ disabled:
+ type: boolean
+ description: |-
+ Flag that indicates if the user is not in sherpa anymore or has no
+ active memberships.
+ username:
+ type: string
+ description: The users username. Used to log in to Grünes Netz (gnetz username)
+ example: JohnDoe1
+ email:
+ type: string
+ description: Main user email address. Used to log in to Grünes Netz (gnetz email)
+ example: john.doe@example.com
+ firstName:
+ type: string
+ description: User first name
+ example: John
+ lastName:
+ type: string
+ description: User last name
+ example: Doe
+ required:
+ - id
+ - username
+ - email
+ - firstName
+ - lastName
+ FindUsersResponse:
+ type: object
+ properties:
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
+ required:
+ - data
+ UserRbacGroup:
+ type: object
+ properties:
+ id:
+ type: string
+ description: |-
+ The group id.
+ Contains the division id.
+ example: '2092'
+ divisionKey:
+ type: string
+ description: Division key of the division this group represents.
+ example: '10100000'
+ parentKey:
+ type: string
+ nullable: true
+ description: Division key of the parent division if there is one.
+ example: '10000000'
+ implicit:
+ type: boolean
+ description: >-
+ Indicate if user has a direct or indirect membership in the
+ division.
+
+ A indrect membership can be inherited, eg user is member if a KV so
+ the user is also
+
+ member of the LV/KV, or if the user has a role of a division he is
+ not part of.
+ example: true
+ name:
+ type: string
+ description: Name of the Group (division name)
+ example: Baden-Württemberg
+ displayName:
+ type: string
+ description: Descriptive name of the division.
+ example: Baden-Württemberg LV
+ hierarchy:
+ description: The root hierarchy the division belongs to
+ example: GR
+ enum:
+ - GR
+ - GJ
+ - KPV
+ type: string
+ level:
+ description: Level in the hierarchy
+ example: BV
+ enum:
+ - BV
+ - LV
+ - KV
+ - OV
+ type: string
+ required:
+ - id
+ - divisionKey
+ - parentKey
+ - implicit
+ - name
+ - displayName
+ - hierarchy
+ - level
+ UserRbacRole:
+ type: object
+ properties:
+ id:
+ type: string
+ description: The role id.
+ example: '6051228'
+ groupId:
+ type: string
+ description: |-
+ The group id this role refers to.
+ Contains the division id.
+ example: '7874541'
+ divisionKey:
+ type: string
+ description: The division key this role refers to.
+ example: '10206400'
+ label:
+ type: string
+ description: Role name.
+ example: Kreisverband GR - Mitgliederbeauftragte
+ required:
+ - id
+ - groupId
+ - divisionKey
+ - label
+ UserRbacStructure:
+ type: object
+ properties:
+ userId:
+ type: string
+ description: |-
+ User id
+ @example: '1234'
+ groups:
+ description: List of RBAC groups
+ type: array
+ items:
+ $ref: '#/components/schemas/UserRbacGroup'
+ roles:
+ description: List of RBAC roles
+ type: array
+ items:
+ $ref: '#/components/schemas/UserRbacRole'
+ required:
+ - userId
+ - groups
+ - roles
+ NbOrganization:
+ type: object
+ properties:
+ id:
+ type: string
+ description: Unique character code to identify organization
+ example: GR
+ name:
+ type: string
+ description: Organization name
+ example: BÜNDNIS 90/DIE GRÜNEN
+ regional_chapter_id_prefix:
+ type: string
+ description: >-
+ Division keys belonging to this organization are always beginning
+ with this sequence.
+ example: '1'
+ required:
+ - id
+ - name
+ - regional_chapter_id_prefix
+ FindNbOrganizationsResponse:
+ type: object
+ properties:
+ items:
+ type: array
+ items:
+ $ref: '#/components/schemas/NbOrganization'
+ count:
+ type: number
+ required:
+ - items
+ - count
+ NbExternalRef:
+ type: object
+ properties:
+ type:
+ type: string
+ description: Type of the external ref
+ example: SHERPA
+ key:
+ type: string
+ description: Id in the external system
+ example: '12345678'
+ required:
+ - type
+ - key
+ NbGroup:
+ type: object
+ properties:
+ name:
+ type: string
+ example: BAG Demokratie und Recht
+ slug:
+ type: string
+ example: BAG_DEMOKRATIE_RECHT
+ type:
+ type: string
+ example: WORKGROUP
+ active:
+ type: boolean
+ example: true
+ level:
+ type: string
+ example: DE:BUNDESVERBAND
+ organization:
+ $ref: '#/components/schemas/NbOrganization'
+ external_refs:
+ type: array
+ items:
+ $ref: '#/components/schemas/NbExternalRef'
+ required:
+ - name
+ - slug
+ - type
+ - active
+ - level
+ - organization
+ - external_refs
+ FindNbGroupsResponse:
+ type: object
+ properties:
+ items:
+ type: array
+ items:
+ $ref: '#/components/schemas/NbGroup'
+ required:
+ - items
+ NbRegionalChapter:
+ type: object
+ properties:
+ id:
+ type: string
+ description: Id of the regional chapter (division key)
+ example: '11004410'
+ name:
+ type: string
+ description: Regional chapter name
+ example: Neunkirchen-Seelscheid
+ type:
+ description: |-
+ Regional chapter type
+ Possible values: BV | LV | KV | OV
+ example: OV
+ enum:
+ - BV
+ - LV
+ - KV
+ - OV
+ type: string
+ organization:
+ $ref: '#/components/schemas/NbOrganization'
+ zip_code:
+ type: string
+ description: Zip code of office location
+ example: '53819'
+ required:
+ - id
+ - name
+ - type
+ - organization
+ - zip_code
+ FindNbRegionalChaptersResponse:
+ type: object
+ properties:
+ count:
+ type: number
+ items:
+ type: array
+ items:
+ $ref: '#/components/schemas/NbRegionalChapter'
+ required:
+ - count
+ - items
+ ImageLink:
+ type: object
+ properties:
+ url:
+ type: string
+ description: Image url
+ example: >-
+ https://static.example.com/profiles/10b4be70-9e3d-40a5-a46a-b0668bdf7e03.jpg
+ mimetype:
+ type: string
+ description: Image mimetype
+ example: image/jpeg
+ width:
+ type: number
+ description: Width in pixels
+ example: 150
+ minimum: 0
+ height:
+ type: number
+ description: Height in pixels
+ example: 150
+ minimum: 0
+ required:
+ - url
+ - mimetype
+ - width
+ - height
+ ProfileImage:
+ type: object
+ properties:
+ thumbnail:
+ $ref: '#/components/schemas/ImageLink'
+ large:
+ $ref: '#/components/schemas/ImageLink'
+ required:
+ - thumbnail
+ - large
+ PhoneNumberEntry:
+ type: object
+ properties:
+ id:
+ type: string
+ example: '123'
+ country:
+ type: string
+ description: Country code in german format
+ example: '0049'
+ number:
+ type: string
+ description: Phone number
+ example: '177234512345'
+ required:
+ - id
+ - country
+ - number
+ MessengerEntry:
+ type: object
+ properties:
+ id:
+ type: string
+ example: '123'
+ type:
+ type: string
+ example: threema
+ enum:
+ - threema
+ externalId:
+ type: string
+ example: 822d7a5a
+ required:
+ - id
+ - type
+ - externalId
+ SocialMediaEntry:
+ type: object
+ properties:
+ id:
+ type: string
+ example: '123'
+ type:
+ description: Type of social media entry
+ example: mastodon
+ enum:
+ - facebook
+ - instagram
+ - mastodon
+ - twitter
+ - chatbegruenung
+ type: string
+ url:
+ type: string
+ description: Url to the platform account
+ example: https://mastodon.online/@saxgruen
+ required:
+ - id
+ - type
+ - url
+ ProfileTag:
+ type: object
+ properties:
+ id:
+ type: string
+ description: Tag id
+ example: '1'
+ type:
+ description: Tag type
+ example: '"interest'
+ enum:
+ - skill
+ - interest
+ type: string
+ label:
+ type: string
+ description: Tag label
+ example: Zeitpolitik
+ externalId:
+ type: string
+ description: External id
+ example: '100'
+ required:
+ - id
+ - type
+ - label
+ Address:
+ type: object
+ properties:
+ city:
+ type: string
+ description: Location city
+ example: Berlin
+ zip:
+ type: string
+ description: Location zip code
+ example: '10176'
+ line1:
+ type: string
+ description: First address line for street and house number
+ example: Bahnhofstr. 5
+ required:
+ - city
+ - zip
+ - line1
+ DivisionEmail:
+ type: object
+ properties:
+ tags:
+ description: Tags associated with email as string values
+ example:
+ - BV-GRÜNE-Info
+ type: array
+ items:
+ type: string
+ purposes:
+ description: Purposes associated with email
+ examples:
+ - - privat
+ - - grüne
+ - - dienstlich
+ - - Postanschrift
+ - - Rechnungsanschrift
+ - - Lieferanschrift
+ type: array
+ items:
+ type: string
+ address:
+ type: string
+ description: Email address
+ example: john.doe@example.com
+ isFavorite:
+ type: boolean
+ description: Indicate if this email is preferred for general inquiries
+ example: false
+ required:
+ - tags
+ - purposes
+ - address
+ - isFavorite
+ Division:
+ type: object
+ properties:
+ urls:
+ description: List of internet presences
+ example:
+ - https://example.com
+ type: array
+ items:
+ type: string
+ id:
+ type: string
+ description: The division id
+ example: '123'
+ divisionKey:
+ type: string
+ description: The division key
+ example: '10000000'
+ name1:
+ type: string
+ example: Landesverband
+ name2:
+ type: string
+ example: Baden-Württemberg
+ shortName:
+ type: string
+ description: Descriptive name of the division.
+ example: Baden-Württemberg LV
+ hierarchy:
+ type: object
+ description: The root hierarchy the division belongs to
+ example: GR
+ level:
+ description: Level in the hierarchy
+ example: BV
+ enum:
+ - BV
+ - LV
+ - KV
+ - OV
+ type: string
+ officeAddress:
+ nullable: true
+ description: Office address
+ allOf:
+ - $ref: '#/components/schemas/Address'
+ emails:
+ description: Email Addresses
+ type: array
+ items:
+ $ref: '#/components/schemas/DivisionEmail'
+ required:
+ - urls
+ - id
+ - divisionKey
+ - name1
+ - name2
+ - shortName
+ - hierarchy
+ - level
+ - officeAddress
+ - emails
+ DivisionMembership:
+ type: object
+ properties:
+ division:
+ $ref: '#/components/schemas/Division'
+ joinedAt:
+ format: date-time
+ type: string
+ required:
+ - division
+ - joinedAt
+ ProfileRole:
+ type: object
+ properties:
+ id:
+ type: string
+ example: '12345'
+ type:
+ example: role
+ enum:
+ - role
+ - mandate
+ - office
+ type: string
+ name:
+ type: string
+ example: LAG Verkehr Mitarbeitende
+ alias:
+ type: string
+ example: LAG Mobilität
+ required:
+ - id
+ - type
+ - name
+ - alias
+ PublicProfile:
+ type: object
+ properties:
+ id:
+ type: string
+ example: 71eb2937-12f2-4483-906a-f01a972afecf
+ userId:
+ type: string
+ description: User id (Sherpa user id)
+ example: '12345678'
+ personalId:
+ type: string
+ description: personal identification number
+ example: '12345678'
+ username:
+ type: string
+ example: JohnDoe1
+ firstName:
+ type: string
+ example: John
+ lastName:
+ type: string
+ example: Doe
+ image:
+ $ref: '#/components/schemas/ProfileImage'
+ phoneNumbers:
+ type: array
+ items:
+ $ref: '#/components/schemas/PhoneNumberEntry'
+ messengers:
+ type: array
+ items:
+ $ref: '#/components/schemas/MessengerEntry'
+ socialMedia:
+ type: array
+ items:
+ $ref: '#/components/schemas/SocialMediaEntry'
+ tags:
+ type: array
+ items:
+ $ref: '#/components/schemas/ProfileTag'
+ joinedAt:
+ format: date-time
+ type: string
+ description: First entry date in the BV
+ memberships:
+ type: array
+ items:
+ $ref: '#/components/schemas/DivisionMembership'
+ roles:
+ type: array
+ items:
+ $ref: '#/components/schemas/ProfileRole'
+ achievements:
+ example:
+ - Silberne Sonnenblume
+ type: array
+ items:
+ type: string
+ email:
+ type: string
+ example: john.doe@example.com
+ required:
+ - id
+ - userId
+ - personalId
+ - username
+ - firstName
+ - lastName
+ - phoneNumbers
+ - messengers
+ - socialMedia
+ - tags
+ - roles
+ - achievements
+ FindProfilesResponse:
+ type: object
+ properties:
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/PublicProfile'
+ meta:
+ type: object
+ properties:
+ count:
+ required: true
+ type: number
+ offset:
+ required: true
+ type: number
+ limit:
+ required: true
+ type: number
+ hasNext:
+ required: true
+ type: boolean
+ required:
+ - data
+ - meta
+ CreateProfile:
+ type: object
+ properties:
+ userId:
+ type: string
+ required:
+ - userId
+ ProfilePrivacySettings:
+ type: object
+ properties:
+ overall:
+ example: BV_WIDE
+ enum:
+ - PRIVATE
+ - PUBLIC
+ - BV_WIDE
+ - LV_WIDE
+ - KV_WIDE
+ - OV_WIDE
+ type: string
+ email:
+ example: PRIVATE
+ enum:
+ - PRIVATE
+ - PUBLIC
+ - BV_WIDE
+ - LV_WIDE
+ - KV_WIDE
+ - OV_WIDE
+ type: string
+ chatbegruenung:
+ example: PUBLIC
+ enum:
+ - PRIVATE
+ - PUBLIC
+ - BV_WIDE
+ - LV_WIDE
+ - KV_WIDE
+ - OV_WIDE
+ type: string
+ required:
+ - overall
+ - email
+ - chatbegruenung
+ Profile:
+ type: object
+ properties:
+ id:
+ type: string
+ example: 71eb2937-12f2-4483-906a-f01a972afecf
+ userId:
+ type: string
+ description: User id (Sherpa user id)
+ example: '12345678'
+ personalId:
+ type: string
+ description: personal identification number
+ example: '12345678'
+ username:
+ type: string
+ example: JohnDoe1
+ firstName:
+ type: string
+ example: John
+ lastName:
+ type: string
+ example: Doe
+ email:
+ type: string
+ example: john.doe@example.com
+ image:
+ $ref: '#/components/schemas/ProfileImage'
+ phoneNumbers:
+ type: array
+ items:
+ $ref: '#/components/schemas/PhoneNumberEntry'
+ messengers:
+ type: array
+ items:
+ $ref: '#/components/schemas/MessengerEntry'
+ socialMedia:
+ type: array
+ items:
+ $ref: '#/components/schemas/SocialMediaEntry'
+ tags:
+ type: array
+ items:
+ $ref: '#/components/schemas/ProfileTag'
+ joinedAt:
+ format: date-time
+ type: string
+ description: First entry date in the BV
+ memberships:
+ type: array
+ items:
+ $ref: '#/components/schemas/DivisionMembership'
+ roles:
+ type: array
+ items:
+ $ref: '#/components/schemas/ProfileRole'
+ achievements:
+ example:
+ - Silberne Sonnenblume
+ type: array
+ items:
+ type: string
+ privacy:
+ $ref: '#/components/schemas/ProfilePrivacySettings'
+ required:
+ - id
+ - userId
+ - personalId
+ - username
+ - firstName
+ - lastName
+ - email
+ - phoneNumbers
+ - messengers
+ - socialMedia
+ - tags
+ - roles
+ - achievements
+ - privacy
+ UpdatePhoneNumber:
+ type: object
+ properties:
+ country:
+ type: string
+ description: Country code in german format
+ example: '0049'
+ number:
+ type: string
+ description: Phone number
+ example: '177234512345'
+ id:
+ type: string
+ example: '123'
+ required:
+ - country
+ - number
+ UpdateMessengerEntry:
+ type: object
+ properties:
+ type:
+ type: string
+ example: threema
+ enum:
+ - threema
+ externalId:
+ type: string
+ example: 822d7a5a
+ id:
+ type: string
+ example: '123'
+ required:
+ - type
+ - externalId
+ UpdateSocialMediaEntry:
+ type: object
+ properties:
+ type:
+ type: string
+ description: Type of social media entry
+ example: mastodon
+ enum:
+ - facebook
+ - instagram
+ - mastodon
+ - twitter
+ - chatbegruenung
+ url:
+ type: string
+ description: Url to the platform account
+ example: https://mastodon.online/@saxgruen
+ id:
+ type: string
+ example: '123'
+ required:
+ - type
+ - url
+ UpdateProfile:
+ type: object
+ properties:
+ email:
+ type: string
+ example: john.doe2@example.com
+ phoneNumbers:
+ type: array
+ items:
+ $ref: '#/components/schemas/UpdatePhoneNumber'
+ messengers:
+ type: array
+ items:
+ $ref: '#/components/schemas/UpdateMessengerEntry'
+ socialMedia:
+ type: array
+ items:
+ $ref: '#/components/schemas/UpdateSocialMediaEntry'
+ tags:
+ description: List of external tag ids
+ example:
+ - '501'
+ - '14003317'
+ type: array
+ items:
+ type: string
+ privacy:
+ $ref: '#/components/schemas/ProfilePrivacySettings'
+ required:
+ - email
+ - phoneNumbers
+ - messengers
+ - socialMedia
+ - tags
+ - privacy
+ FindProfileTagsResponse:
+ type: object
+ properties:
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/ProfileTag'
+ meta:
+ type: object
+ properties:
+ count:
+ required: true
+ type: number
+ total:
+ required: true
+ type: number
+ offset:
+ required: true
+ type: number
+ limit:
+ required: true
+ type: number
+ required:
+ - data
+ - meta
+ OffboardingUserInfo:
+ type: object
+ properties:
+ id:
+ type: string
+ description: The User Id (Sherpa Id)
+ example: '12345678'
+ username:
+ type: string
+ description: The users username. Used to log in to Grünes Netz (gnetz username)
+ example: JohnDoe1
+ email:
+ type: string
+ description: The users email address.
+ example: john.doe@example.com
+ required:
+ - id
+ - username
+ FindOffboardingUsersResponse:
+ type: object
+ properties:
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/OffboardingUserInfo'
+ meta:
+ type: object
+ properties:
+ cursorNext:
+ required: false
+ type: string
+ required:
+ - data
+ - meta
+ UpsertOffboardingServiceUser:
+ type: object
+ properties:
+ id:
+ type: string
+ description: The user's id.
+ example: '12345678'
+ status:
+ enum:
+ - deleted
+ - not_found
+ - anonymized
+ type: string
+ required:
+ - id
+ - status
+ BatchUpdateOffboardingServiceUsers:
+ type: object
+ properties:
+ upsert:
+ type: array
+ items:
+ $ref: '#/components/schemas/UpsertOffboardingServiceUser'
+ FindDivisionsResponse:
+ type: object
+ properties:
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/Division'
+ meta:
+ type: object
+ properties:
+ count:
+ required: true
+ type: number
+ total:
+ required: true
+ type: number
+ offset:
+ required: true
+ type: number
+ limit:
+ required: true
+ type: number
+ required:
+ - data
+ - meta
+ RoleAlias:
+ type: object
+ properties:
+ id:
+ type: string
+ description: Id of the role alias
+ example: '503'
+ label:
+ type: string
+ description: Label of the alias
+ divisionId:
+ type: string
+ description: Division id where this alias applies
+ example: '2092'
+ divisionKey:
+ type: string
+ description: Division key where this alias applies
+ example: '10100000'
+ required:
+ - id
+ - label
+ - divisionId
+ - divisionKey
+ RoleCategory:
+ type: object
+ properties:
+ id:
+ type: string
+ description: The role category id
+ example: '84'
+ label:
+ type: string
+ description: Name of the role category
+ aliases:
+ description: Role category aliases
+ type: array
+ items:
+ $ref: '#/components/schemas/RoleAlias'
+ required:
+ - id
+ - label
+ - aliases
+ RoleTag:
+ type: object
+ properties:
+ id:
+ type: string
+ description: Id of the role tag
+ example: '6590132'
+ name:
+ type: string
+ description: Name of the role tag
+ required:
+ - id
+ - name
+ Role:
+ type: object
+ properties:
+ id:
+ type: string
+ description: The role id
+ example: '123'
+ name:
+ type: string
+ description: Name of the role
+ hierarchy:
+ description: Hierarchy this role refers to
+ example: GR
+ enum:
+ - GR
+ - GJ
+ - KPV
+ type: string
+ type:
+ description: Type of role
+ example: ROLLE
+ enum:
+ - AMT
+ - BEZ
+ - MANDAT
+ - ROLLE
+ - SYSTEM
+ type: string
+ minAge:
+ type: number
+ nullable: true
+ description: Role min age
+ example: 0
+ maxAge:
+ type: number
+ description: Role max age
+ example: 99
+ level:
+ description: Hierarchy level this role applies to
+ example: LV
+ enum:
+ - ALL
+ - BV
+ - LV
+ - KV
+ - OV
+ - BEZV
+ type: string
+ categories:
+ description: Role categories
+ type: array
+ items:
+ $ref: '#/components/schemas/RoleCategory'
+ tags:
+ description: Role tags
+ type: array
+ items:
+ $ref: '#/components/schemas/RoleTag'
+ aliases:
+ description: Role Aliases
+ type: array
+ items:
+ $ref: '#/components/schemas/RoleAlias'
+ required:
+ - id
+ - name
+ - hierarchy
+ - type
+ - minAge
+ - maxAge
+ - level
+ - categories
+ - tags
+ - aliases
+ FindRolesResponse:
+ type: object
+ properties:
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/Role'
+ meta:
+ type: object
+ properties:
+ count:
+ required: true
+ type: number
+ total:
+ required: true
+ type: number
+ offset:
+ required: true
+ type: number
+ limit:
+ required: true
+ type: number
+ required:
+ - data
+ - meta
+ FindRoleTagsResponse:
+ type: object
+ properties:
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/RoleTag'
+ meta:
+ type: object
+ properties:
+ count:
+ required: true
+ type: number
+ total:
+ required: true
+ type: number
+ offset:
+ required: true
+ type: number
+ limit:
+ required: true
+ type: number
+ required:
+ - data
+ - meta
+ FindRoleCategoriesResponse:
+ type: object
+ properties:
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/RoleCategory'
+ meta:
+ type: object
+ properties:
+ count:
+ required: true
+ type: number
+ total:
+ required: true
+ type: number
+ offset:
+ required: true
+ type: number
+ limit:
+ required: true
+ type: number
+ required:
+ - data
+ - meta
+ PoiAddress:
+ type: object
+ properties:
+ city:
+ type: string
+ description: Location city
+ example: Berlin
+ zip:
+ type: string
+ description: Location zip code
+ example: '10176'
+ street:
+ type: string
+ description: First address line for street and house number
+ example: Bahnhofstraße
+ houseNumber:
+ type: string
+ description: First address line for street and house number
+ example: 12/a
+ required:
+ - city
+ - zip
+ - street
+ - houseNumber
+ PoiPoster:
+ type: object
+ properties:
+ status:
+ description: Current status of the poster.
+ example: OK
+ enum:
+ - OK
+ - DAMAGED
+ - REMOVED
+ - MISSING
+ type: string
+ comment:
+ type: string
+ nullable: true
+ description: A short text to describe the state of the poster.
+ example: Poster was sprayed with graffiti.
+ required:
+ - status
+ - comment
+ PoiFlyerSpot:
+ type: object
+ properties:
+ flyerCount:
+ type: number
+ description: Number of flyers on this spot.
+ minimum: 0
+ required:
+ - flyerCount
+ PoiHouse:
+ type: object
+ properties:
+ countOpenedDoors:
+ type: number
+ description: Number of apartment doors that were opened for a conversation.
+ minimum: 0
+ countClosedDoors:
+ type: number
+ description: Number of appartment doors that remained closed.
+ minimum: 0
+ required:
+ - countOpenedDoors
+ - countClosedDoors
+ UpdatePoi:
+ type: object
+ properties:
+ address:
+ nullable: true
+ allOf:
+ - $ref: '#/components/schemas/PoiAddress'
+ poster:
+ nullable: true
+ allOf:
+ - $ref: '#/components/schemas/PoiPoster'
+ flyerSpot:
+ nullable: true
+ allOf:
+ - $ref: '#/components/schemas/PoiFlyerSpot'
+ house:
+ nullable: true
+ allOf:
+ - $ref: '#/components/schemas/PoiHouse'
+ CreatePoi:
+ type: object
+ properties:
+ coords:
+ description: Coordinates represented in GeoJSON [longitude, latitude]
+ example:
+ - 120.123
+ - -35.456
+ minItems: 2
+ maxItems: 2
+ type: array
+ items:
+ type: number
+ type:
+ enum:
+ - FLYER_SPOT
+ - POSTER
+ - HOUSE
+ type: string
+ address:
+ nullable: true
+ allOf:
+ - $ref: '#/components/schemas/PoiAddress'
+ poster:
+ nullable: true
+ allOf:
+ - $ref: '#/components/schemas/PoiPoster'
+ flyerSpot:
+ nullable: true
+ allOf:
+ - $ref: '#/components/schemas/PoiFlyerSpot'
+ house:
+ nullable: true
+ allOf:
+ - $ref: '#/components/schemas/PoiHouse'
+ required:
+ - coords
+ - type
+ Image:
+ type: object
+ properties:
+ id:
+ type: string
+ type:
+ type: string
+ description: Image url
+ example: thumbnail
+ url:
+ type: string
+ description: Image url
+ example: >-
+ https://static.example.com/profiles/10b4be70-9e3d-40a5-a46a-b0668bdf7e03.jpg
+ mimetype:
+ type: string
+ description: Image mimetype
+ example: image/jpeg
+ width:
+ type: number
+ description: Width in pixels
+ example: 150
+ height:
+ type: number
+ description: Height in pixels
+ example: 150
+ required:
+ - id
+ - url
+ - mimetype
+ - width
+ - height
+ ImageSrcSet:
+ type: object
+ properties:
+ id:
+ type: string
+ original:
+ $ref: '#/components/schemas/Image'
+ srcset:
+ type: array
+ items:
+ $ref: '#/components/schemas/Image'
+ required:
+ - id
+ - original
+ - srcset
+ Poi:
+ type: object
+ properties:
+ coords:
+ description: Coordinates represented in GeoJSON [longitude, latitude]
+ example:
+ - 120.123
+ - -35.456
+ minItems: 2
+ maxItems: 2
+ type: array
+ items:
+ type: number
+ id:
+ type: string
+ example: '1'
+ agentId:
+ type: string
+ divisionKey:
+ type: string
+ createdAt:
+ format: date-time
+ type: string
+ photos:
+ type: array
+ items:
+ $ref: '#/components/schemas/ImageSrcSet'
+ address:
+ nullable: true
+ allOf:
+ - $ref: '#/components/schemas/PoiAddress'
+ type:
+ enum:
+ - FLYER_SPOT
+ - POSTER
+ - HOUSE
+ type: string
+ poster:
+ $ref: '#/components/schemas/PoiPoster'
+ flyerSpot:
+ $ref: '#/components/schemas/PoiFlyerSpot'
+ house:
+ $ref: '#/components/schemas/PoiHouse'
+ required:
+ - coords
+ - id
+ - agentId
+ - divisionKey
+ - createdAt
+ - photos
+ - address
+ - type
+ FindPoisResponse:
+ type: object
+ properties:
+ data:
+ type: array
+ items:
+ $ref: '#/components/schemas/Poi'
+ required:
+ - data
+ HealthCheckResponse:
+ type: object
+ properties:
+ status:
+ type: string
+ example: error
+ info:
+ type: object
+ additionalProperties:
+ type: object
+ required:
+ - status
+ properties:
+ status:
+ type: string
+ enum:
+ - up
+ - down
+ example:
+ memory_heap:
+ status: up
+ ldap:
+ status: up
+ sherpa:
+ status: up
+ error:
+ type: object
+ additionalProperties:
+ type: object
+ required:
+ - status
+ properties:
+ status:
+ type: string
+ enum:
+ - up
+ - down
+ message:
+ type: string
+ example:
+ keycloak:
+ status: down
+ example: client not authenticated
+ details:
+ type: object
+ additionalProperties:
+ type: object
+ required:
+ - status
+ properties:
+ status:
+ type: string
+ enum:
+ - up
+ - down
+ message:
+ type: string
+ example:
+ memory_heap:
+ status: up
+ ldap:
+ status: up
+ sherpa:
+ status: up
+ keycloak:
+ status: down
+ example: client not authenticated