From 4e8313c1b625f9d63cb738c4fda63ced139820a3 Mon Sep 17 00:00:00 2001 From: nilsreichardt Date: Sun, 10 Mar 2024 23:47:09 +0100 Subject: [PATCH 1/3] Add flavors (prod & dev) to our console --- console/lib/firebase_options_dev.g.dart | 73 +++++++++++++++++++ ...ions.dart => firebase_options_prod.g.dart} | 0 console/lib/flavor.dart | 29 ++++++++ console/lib/main.dart | 16 +++- 4 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 console/lib/firebase_options_dev.g.dart rename console/lib/{firebase_options.dart => firebase_options_prod.g.dart} (100%) create mode 100644 console/lib/flavor.dart diff --git a/console/lib/firebase_options_dev.g.dart b/console/lib/firebase_options_dev.g.dart new file mode 100644 index 000000000..13d642da8 --- /dev/null +++ b/console/lib/firebase_options_dev.g.dart @@ -0,0 +1,73 @@ +// Copyright (c) 2024 Sharezone UG (haftungsbeschränkt) +// Licensed under the EUPL-1.2-or-later. +// +// You may obtain a copy of the Licence at: +// https://joinup.ec.europa.eu/software/page/eupl +// +// SPDX-License-Identifier: EUPL-1.2 + +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + return web; + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for android - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.iOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for ios - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.macOS: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for macos - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions web = FirebaseOptions( + apiKey: 'AIzaSyBqC6TzoF4xtsQeaCPduIR0J0ygja8Y0_8', + appId: '1:366164701221:web:5fe0bac2db3098c6bfcfcc', + messagingSenderId: '366164701221', + projectId: 'sharezone-debug', + authDomain: 'sharezone-debug.firebaseapp.com', + databaseURL: 'https://sharezone-debug.firebaseio.com', + storageBucket: 'sharezone-debug.appspot.com', + measurementId: 'G-4Z0HJ3D9Q6', + ); +} diff --git a/console/lib/firebase_options.dart b/console/lib/firebase_options_prod.g.dart similarity index 100% rename from console/lib/firebase_options.dart rename to console/lib/firebase_options_prod.g.dart diff --git a/console/lib/flavor.dart b/console/lib/flavor.dart new file mode 100644 index 000000000..50f578c9c --- /dev/null +++ b/console/lib/flavor.dart @@ -0,0 +1,29 @@ +// Copyright (c) 2023 Sharezone UG (haftungsbeschränkt) +// Licensed under the EUPL-1.2-or-later. +// +// You may obtain a copy of the Licence at: +// https://joinup.ec.europa.eu/software/page/eupl +// +// SPDX-License-Identifier: EUPL-1.2 + +/// The flavor of the console. +/// +/// The flavor is used to determine which environment the console is running +/// in. +enum Flavor { + /// The flavor for the production environment. + /// + /// Should be used for the release build. + prod, + + /// The flavor for the development environment. + /// + /// Should be used for the debug build. + dev; + + static Flavor fromEnvironment() { + return Flavor.values.byName( + const String.fromEnvironment('FLAVOR', defaultValue: 'dev'), + ); + } +} diff --git a/console/lib/main.dart b/console/lib/main.dart index 1f9370409..4cc8195f8 100644 --- a/console/lib/main.dart +++ b/console/lib/main.dart @@ -9,7 +9,9 @@ import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/material.dart'; -import 'package:sharezone_console/firebase_options.dart'; +import 'package:sharezone_console/firebase_options_prod.g.dart' as prod; +import 'package:sharezone_console/firebase_options_dev.g.dart' as dev; +import 'package:sharezone_console/flavor.dart'; import 'package:sharezone_console/login_signup_page.dart'; import 'home_page.dart'; @@ -17,11 +19,21 @@ import 'home_page.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); + final flavor = Flavor.fromEnvironment(); + await _initFirebase(flavor); runApp(MyApp()); } +Future _initFirebase(Flavor flavor) async { + await Firebase.initializeApp( + options: switch (flavor) { + Flavor.prod => prod.DefaultFirebaseOptions.currentPlatform, + Flavor.dev => dev.DefaultFirebaseOptions.currentPlatform, + }, + ); +} + class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); From c749770524e491639b727ffcda136b84a1890f0e Mon Sep 17 00:00:00 2001 From: nilsreichardt Date: Sun, 10 Mar 2024 23:47:21 +0100 Subject: [PATCH 2/3] Add VS Code launch configurations for our console --- .vscode/launch.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index 221639ac7..34bb92ae8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -33,5 +33,23 @@ "--dart-define=FLAVOR=dev" ] }, + { + "name": "Console (prod)", + "request": "launch", + "type": "dart", + "program": "console/lib/main.dart", + "args": [ + "--dart-define=FLAVOR=prod" + ] + }, + { + "name": "Console (dev)", + "request": "launch", + "type": "dart", + "program": "console/lib/main.dart", + "args": [ + "--dart-define=FLAVOR=dev" + ] + }, ] } From 76d7b21c3a0cdb24d25c3087a6a428e465474fb8 Mon Sep 17 00:00:00 2001 From: nilsreichardt Date: Mon, 11 Mar 2024 00:03:09 +0100 Subject: [PATCH 3/3] WIP Feedbacks Page --- console/lib/home_page.dart | 10 ++- .../lib/pages/feedbacks/feedbacks_page.dart | 90 +++++++++++++++++++ console/pubspec.lock | 32 +++++++ console/pubspec.yaml | 2 + 4 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 console/lib/pages/feedbacks/feedbacks_page.dart diff --git a/console/lib/home_page.dart b/console/lib/home_page.dart index 39a4bd7b5..e051c2a66 100644 --- a/console/lib/home_page.dart +++ b/console/lib/home_page.dart @@ -9,6 +9,7 @@ import 'package:flutter/material.dart'; import 'package:sharezone_console/activation_codes/activation_codes_page.dart'; import 'package:sharezone_console/pages/change_type_of_user.dart'; +import 'package:sharezone_console/pages/feedbacks/feedbacks_page.dart'; Future openPage(BuildContext context, Widget widget) { return Navigator.push( @@ -39,7 +40,14 @@ class HomePage extends StatelessWidget { onTap: () { openActivationCodesPage(context); }, - ) + ), + ListTile( + leading: Icon(Icons.message), + title: const Text("Feedbacks"), + onTap: () { + openPage(context, FeedbacksPage()); + }, + ), ], ), ); diff --git a/console/lib/pages/feedbacks/feedbacks_page.dart b/console/lib/pages/feedbacks/feedbacks_page.dart new file mode 100644 index 000000000..11933558f --- /dev/null +++ b/console/lib/pages/feedbacks/feedbacks_page.dart @@ -0,0 +1,90 @@ +// Copyright (c) 2024 Sharezone UG (haftungsbeschränkt) +// Licensed under the EUPL-1.2-or-later. +// +// You may obtain a copy of the Licence at: +// https://joinup.ec.europa.eu/software/page/eupl +// +// SPDX-License-Identifier: EUPL-1.2 + +import 'dart:developer'; + +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:flutter/material.dart'; +import 'package:very_good_infinite_list/very_good_infinite_list.dart'; + +class FeedbacksPage extends StatefulWidget { + const FeedbacksPage({super.key}); + + @override + State createState() => _FeedbacksPageState(); +} + +class _FeedbacksPageState extends State { + var _items = >[]; + var _isLoading = false; + var _hasReachedMax = false; + + void _fetchData() async { + setState(() { + _isLoading = true; + }); + + log('Fetching data...'); + + // Load 10 more feedbacks from Firestore + Query> query = await FirebaseFirestore.instance + .collection('Feedback') + .orderBy('createdOn', descending: true) + .limit(20); + + if (_items.isNotEmpty) { + query = query.startAfter([ + _items.last['createdOn'] as Timestamp, + ]); + } + + final snapshot = await query.get(); + + if (!mounted) { + return; + } + + if (snapshot.docs.isEmpty) { + setState(() { + _isLoading = false; + _hasReachedMax = true; + }); + return; + } + + setState(() { + _isLoading = false; + _items = [ + ..._items, + ...snapshot.docs.map((doc) => doc.data()).toList(), + ]; + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Feedbacks'), + ), + body: InfiniteList( + itemCount: _items.length, + isLoading: _isLoading, + onFetchData: _fetchData, + hasReachedMax: _hasReachedMax, + separatorBuilder: (context, index) => const Divider(), + itemBuilder: (context, index) { + return ListTile( + dense: true, + title: Text(_items[index].toString()), + ); + }, + ), + ); + } +} diff --git a/console/pubspec.lock b/console/pubspec.lock index 10976a2d1..5a4842260 100644 --- a/console/pubspec.lock +++ b/console/pubspec.lock @@ -41,6 +41,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + cloud_firestore: + dependency: "direct main" + description: + name: cloud_firestore + sha256: "6f6a9e7f1c68f34ffe159c911a290fa7caf1a09b8a88aa1534c65f0246953970" + url: "https://pub.dev" + source: hosted + version: "4.15.6" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + sha256: "4e92549af19f0d2eec7e379ca44f909caef8eb52295a0cde5467b018cfae0378" + url: "https://pub.dev" + source: hosted + version: "6.1.7" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + sha256: "2b34cff977da11a4822151d967c5e6ce62640cbcb56d6e52a46382d2316350ac" + url: "https://pub.dev" + source: hosted + version: "3.10.6" cloud_functions: dependency: "direct main" description: @@ -309,6 +333,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + very_good_infinite_list: + dependency: "direct main" + description: + name: very_good_infinite_list + sha256: "6f5ad429edbce6084e1c600e56b26b1de8c6b138e8e8fc2de41b686166029aa5" + url: "https://pub.dev" + source: hosted + version: "0.7.1" vm_service: dependency: transitive description: diff --git a/console/pubspec.yaml b/console/pubspec.yaml index f4da83816..f33a91bb3 100644 --- a/console/pubspec.yaml +++ b/console/pubspec.yaml @@ -17,12 +17,14 @@ environment: dependencies: cloud_functions: ^4.6.6 + cloud_firestore: ^4.15.5 firebase_auth: ^4.17.6 firebase_core: ^2.25.5 flutter: sdk: flutter intl: ^0.17.0 rxdart: ^0.27.7 + very_good_infinite_list: ^0.7.1 dev_dependencies: flutter_test: