Merge Firebase_aut branch and resolve pubspec.lock conflict
This commit is contained in:
+71
-42
@@ -1,19 +1,19 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
import 'package:firebase_auth/firebase_auth.dart';
|
||||||
import 'package:firebase_storage/firebase_storage.dart';
|
import 'package:firebase_storage/firebase_storage.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||||
import 'package:image/image.dart' as img;
|
import 'package:image/image.dart' as img;
|
||||||
|
|
||||||
|
|
||||||
class AddScreen extends StatefulWidget {
|
class AddScreen extends StatefulWidget {
|
||||||
final int initialIndex;
|
final int initialIndex;
|
||||||
|
|
||||||
const AddScreen({super.key, required this.initialIndex});
|
const AddScreen({Key? key, required this.initialIndex}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_AddScreenState createState() => _AddScreenState();
|
_AddScreenState createState() => _AddScreenState();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AddScreenState extends State<AddScreen> {
|
class _AddScreenState extends State<AddScreen> {
|
||||||
@@ -24,7 +24,6 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
bool _uploading = false;
|
bool _uploading = false;
|
||||||
int _selectedIndex = 0;
|
int _selectedIndex = 0;
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
@@ -42,14 +41,13 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
|
|
||||||
if (originalImage != null) {
|
if (originalImage != null) {
|
||||||
int originSize = min(originalImage.width, originalImage.height);
|
int originSize = min(originalImage.width, originalImage.height);
|
||||||
final croppedImage = img.copyCrop(
|
final croppedImage = img.copyCrop(originalImage,
|
||||||
originalImage,
|
x: (originalImage.width - originSize) ~/ 2,
|
||||||
x: (originalImage.width - originSize)~/2,
|
y: (originalImage.height - originSize) ~/ 2,
|
||||||
y: (originalImage.height - originSize)~/2,
|
|
||||||
width: originSize,
|
width: originSize,
|
||||||
height: originSize
|
height: originSize);
|
||||||
);
|
final newPath =
|
||||||
final newPath = imageFile.path.substring(0, imageFile.path.lastIndexOf('/'));
|
imageFile.path.substring(0, imageFile.path.lastIndexOf('/'));
|
||||||
final newFile = File('$newPath/cropped.jpg');
|
final newFile = File('$newPath/cropped.jpg');
|
||||||
await newFile.writeAsBytes(img.encodePng(croppedImage));
|
await newFile.writeAsBytes(img.encodePng(croppedImage));
|
||||||
return newFile;
|
return newFile;
|
||||||
@@ -71,33 +69,37 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
if (originalImage != null) {
|
if (originalImage != null) {
|
||||||
if (originalImage.width == originalImage.height) {
|
if (originalImage.width == originalImage.height) {
|
||||||
// Wenn das Bild bereits im 1:1-Format ist, überspringen Sie das Zuschneiden
|
// Wenn das Bild bereits im 1:1-Format ist, überspringen Sie das Zuschneiden
|
||||||
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_imageFile = tempFile;
|
_imageFile = tempFile;
|
||||||
print("1:1");
|
print("1:1");
|
||||||
});
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Wenn das Bild nicht im 1:1-Format ist, schneiden Sie es zu
|
// Wenn das Bild nicht im 1:1-Format ist, schneiden Sie es zu
|
||||||
File croppedFile = await _cropImage(tempFile);
|
File croppedFile = await _cropImage(tempFile);
|
||||||
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_imageFile = croppedFile;
|
_imageFile = croppedFile;
|
||||||
});
|
});
|
||||||
print("decode");
|
print("decode");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw Exception('Unable to decode image file.');
|
throw Exception('Unable to decode image file.');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('Die Dateigröße darf maximal 10 MB betragen.')),
|
const SnackBar(
|
||||||
|
content: Text('Die Dateigröße darf maximal 10 MB betragen.')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> addNewElementToFirestore(
|
||||||
|
String title, String description, File imageFile,
|
||||||
Future<void> addNewElementToFirestore(String title, String description, File imageFile, {required Function(bool) onComplete}) async {
|
{required Function(bool) onComplete}) async {
|
||||||
String collectionName;
|
String collectionName;
|
||||||
if (_selectedIndex == 0) {
|
if (_selectedIndex == 0) {
|
||||||
collectionName = "CitizensForum";
|
collectionName = "CitizensForum";
|
||||||
@@ -107,36 +109,45 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
collectionName = "Issues";
|
collectionName = "Issues";
|
||||||
}
|
}
|
||||||
|
|
||||||
String imageUrl = await uploadImageToFirebaseStorage(imageFile, collectionName);
|
String imageUrl =
|
||||||
try
|
await uploadImageToFirebaseStorage(imageFile, collectionName);
|
||||||
{
|
String? userId = FirebaseAuth.instance.currentUser?.uid; // get the user ID
|
||||||
|
|
||||||
|
try {
|
||||||
await FirebaseFirestore.instance.collection(collectionName).add({
|
await FirebaseFirestore.instance.collection(collectionName).add({
|
||||||
"title": title,
|
"title": title,
|
||||||
"description": description,
|
"description": description,
|
||||||
"imageUrl": imageUrl,
|
"imageUrl": imageUrl,
|
||||||
"createdDate": DateTime.now(),
|
"createdDate": DateTime.now(),
|
||||||
|
"author_uid": userId, // add the user ID to the document
|
||||||
});
|
});
|
||||||
onComplete(true);
|
onComplete(true);
|
||||||
}
|
} catch (e) {
|
||||||
catch(e)
|
|
||||||
{
|
|
||||||
onComplete(false);
|
onComplete(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> uploadImageToFirebaseStorage(File imageFile, String collectionName) async {
|
Future<String> uploadImageToFirebaseStorage(
|
||||||
Reference ref = FirebaseStorage.instance.ref().child("$collectionName/${DateTime.now().toString()}");
|
File imageFile, String collectionName) async {
|
||||||
|
String? userId = FirebaseAuth.instance.currentUser?.uid;
|
||||||
|
if (userId != null) {
|
||||||
|
Reference ref = FirebaseStorage.instance
|
||||||
|
.ref()
|
||||||
|
.child("$collectionName/$userId/${DateTime.now().toString()}");
|
||||||
UploadTask uploadTask = ref.putFile(imageFile);
|
UploadTask uploadTask = ref.putFile(imageFile);
|
||||||
return await (await uploadTask).ref.getDownloadURL();
|
return await (await uploadTask).ref.getDownloadURL();
|
||||||
|
} else {
|
||||||
|
throw Exception('Cannot upload without user ID');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
String appBarTitle = '';
|
String appBarTitle = '';
|
||||||
|
|
||||||
|
double keyboardHeight = MediaQuery.of(context).viewInsets.bottom;
|
||||||
|
|
||||||
if (_selectedIndex == 0) {
|
if (_selectedIndex == 0) {
|
||||||
appBarTitle = 'Neue BürgerForum Information';
|
appBarTitle = 'Neue BürgerForum Information';
|
||||||
} else if (_selectedIndex == 1) {
|
} else if (_selectedIndex == 1) {
|
||||||
@@ -166,20 +177,30 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
child: IconButton(
|
child: IconButton(
|
||||||
icon: const Icon(Icons.check),
|
icon: const Icon(Icons.check),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (_formKey.currentState!.validate() && _imageFile != null && !_uploading) {
|
if (_formKey.currentState!.validate() &&
|
||||||
|
_imageFile != null &&
|
||||||
|
!_uploading) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_uploading = true;
|
_uploading = true;
|
||||||
});
|
});
|
||||||
Navigator.pop(context); // Fenster direkt schließen, nachdem der Upload-Button gedrückt wurde.
|
Navigator.pop(
|
||||||
await addNewElementToFirestore(_titleController.text, _descriptionController.text, _imageFile!, onComplete: (bool success) {
|
context); // Fenster direkt schließen, nachdem der Upload-Button gedrückt wurde.
|
||||||
|
await addNewElementToFirestore(
|
||||||
|
_titleController.text,
|
||||||
|
_descriptionController.text,
|
||||||
|
_imageFile!, onComplete: (bool success) {
|
||||||
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_uploading = false;
|
_uploading = false;
|
||||||
});
|
});
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
content: Text(success ? 'Upload erfolgreich.' : 'Upload fehlgeschlagen.'),
|
content: Text(success
|
||||||
|
? 'Upload erfolgreich.'
|
||||||
|
: 'Upload fehlgeschlagen.'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -230,7 +251,18 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 16.0),
|
const SizedBox(height: 16.0),
|
||||||
_imageFile != null
|
_imageFile != null
|
||||||
? Image.file(_imageFile!)
|
? Expanded(
|
||||||
|
child: LayoutBuilder(
|
||||||
|
builder: (context, constraints) {
|
||||||
|
double imageHeight =
|
||||||
|
max(0, constraints.maxHeight - keyboardHeight);
|
||||||
|
return Container(
|
||||||
|
height: imageHeight,
|
||||||
|
child: Image.file(_imageFile!),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
: Container(
|
: Container(
|
||||||
height: 200.0,
|
height: 200.0,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
@@ -242,8 +274,7 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) =>
|
builder: (context) => Column(
|
||||||
Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
@@ -251,8 +282,8 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 16),
|
horizontal: 16),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment
|
mainAxisAlignment:
|
||||||
.spaceBetween,
|
MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
const Text(
|
const Text(
|
||||||
'Bild hinzufügen',
|
'Bild hinzufügen',
|
||||||
@@ -274,8 +305,8 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 80,
|
height: 80,
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: const Icon(
|
leading: const Icon(Icons.photo_library,
|
||||||
Icons.photo_library, size: 40),
|
size: 40),
|
||||||
title: const Text(
|
title: const Text(
|
||||||
'Galerie auswählen',
|
'Galerie auswählen',
|
||||||
style: TextStyle(fontSize: 20),
|
style: TextStyle(fontSize: 20),
|
||||||
@@ -291,8 +322,8 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 80,
|
height: 80,
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: const Icon(
|
leading: const Icon(Icons.camera_alt,
|
||||||
Icons.camera_alt, size: 40),
|
size: 40),
|
||||||
title: const Text(
|
title: const Text(
|
||||||
'Kamera verwenden',
|
'Kamera verwenden',
|
||||||
style: TextStyle(fontSize: 20),
|
style: TextStyle(fontSize: 20),
|
||||||
@@ -311,9 +342,7 @@ class _AddScreenState extends State<AddScreen> {
|
|||||||
child: Text(
|
child: Text(
|
||||||
'Bild hinzufügen',
|
'Bild hinzufügen',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme
|
color: Theme.of(context).primaryColor,
|
||||||
.of(context)
|
|
||||||
.primaryColor,
|
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
+6
-1
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:oggauergemeindetrommler/register.dart';
|
||||||
|
|
||||||
class LoginPage extends StatefulWidget {
|
class LoginPage extends StatefulWidget {
|
||||||
LoginPage({Key? key}) : super(key: key);
|
LoginPage({Key? key}) : super(key: key);
|
||||||
@@ -79,6 +80,11 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
// Navigiere zur Registrierungsseite
|
// Navigiere zur Registrierungsseite
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => const RegisterPage()),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
child: const Text('Registrieren'),
|
child: const Text('Registrieren'),
|
||||||
),
|
),
|
||||||
@@ -92,4 +98,3 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||||
|
import 'package:firebase_auth/firebase_auth.dart';
|
||||||
import 'package:firebase_storage/firebase_storage.dart';
|
import 'package:firebase_storage/firebase_storage.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:printing/printing.dart';
|
import 'package:printing/printing.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
import 'AddPage.dart';
|
import 'AddPage.dart';
|
||||||
import 'DetailPage.dart';
|
import 'DetailPage.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
@@ -11,6 +13,8 @@ import 'package:pdf/widgets.dart' as pdfWidgets;
|
|||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:image/image.dart' as img;
|
import 'package:image/image.dart' as img;
|
||||||
|
|
||||||
|
import 'anonym_aut.dart';
|
||||||
|
|
||||||
class UserDefinedItem extends StatelessWidget {
|
class UserDefinedItem extends StatelessWidget {
|
||||||
final String title;
|
final String title;
|
||||||
final String datum;
|
final String datum;
|
||||||
@@ -208,6 +212,9 @@ class _GenericListState extends State<GenericList> {
|
|||||||
final DateTime createdDate = data['createdDate'].toDate();
|
final DateTime createdDate = data['createdDate'].toDate();
|
||||||
final formattedDate =
|
final formattedDate =
|
||||||
DateFormat('dd.MM.yyyy').format(createdDate);
|
DateFormat('dd.MM.yyyy').format(createdDate);
|
||||||
|
final currentUser = FirebaseAuth.instance.currentUser;
|
||||||
|
|
||||||
|
if (currentUser != null && data['author_uid'] == currentUser.uid) {
|
||||||
return Dismissible(
|
return Dismissible(
|
||||||
key: UniqueKey(),
|
key: UniqueKey(),
|
||||||
direction: DismissDirection.endToStart,
|
direction: DismissDirection.endToStart,
|
||||||
@@ -256,6 +263,40 @@ class _GenericListState extends State<GenericList> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
return UserDefinedItem(
|
||||||
|
title: data['title'] ?? '',
|
||||||
|
datum: formattedDate,
|
||||||
|
description: data['description'] ?? '',
|
||||||
|
imageUrl: data['imageUrl'] ?? '',
|
||||||
|
isSelected: selectedItems.containsKey(documentId),
|
||||||
|
onTap: () {
|
||||||
|
clearSelectedItems();
|
||||||
|
// Open a new screen when the user taps on the list item
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => DetailPage(
|
||||||
|
title: data['title'],
|
||||||
|
datum: formattedDate,
|
||||||
|
description: data['description'],
|
||||||
|
imageUrl: data['imageUrl'],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onLongPress: () {
|
||||||
|
setState(() {
|
||||||
|
if (selectedItems.containsKey(documentId)) {
|
||||||
|
selectedItems.remove(documentId);
|
||||||
|
} else {
|
||||||
|
selectedItems[documentId] = data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -295,7 +336,10 @@ class _GenericListState extends State<GenericList> {
|
|||||||
],
|
],
|
||||||
|
|
||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: Consumer<AuthState>(
|
||||||
|
builder: (context, authState, child) {
|
||||||
|
if (authState.user != null) {
|
||||||
|
return FloatingActionButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
clearSelectedItems();
|
clearSelectedItems();
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@@ -305,7 +349,13 @@ class _GenericListState extends State<GenericList> {
|
|||||||
},
|
},
|
||||||
tooltip: "Neues Element hinzufügen",
|
tooltip: "Neues Element hinzufügen",
|
||||||
child: const Icon(Icons.add),
|
child: const Icon(Icons.add),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Container(); // Return an empty container when the user is not signed in
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,7 +368,7 @@ class _GenericListState extends State<GenericList> {
|
|||||||
final Uint8List bytes = response.bodyBytes;
|
final Uint8List bytes = response.bodyBytes;
|
||||||
|
|
||||||
final img.Image? image = img.decodeImage(bytes);
|
final img.Image? image = img.decodeImage(bytes);
|
||||||
final img.Image resizedImage = img.copyResize(image!, width: 500); // Beispielwert für die Breite
|
final img.Image resizedImage = img.copyResize(image!, width: 290); // Beispielwert für die Breite
|
||||||
final Uint8List resizedBytes = Uint8List.fromList(img.encodeJpg(resizedImage));
|
final Uint8List resizedBytes = Uint8List.fromList(img.encodeJpg(resizedImage));
|
||||||
|
|
||||||
final imageProvider = pdfWidgets.MemoryImage(resizedBytes);
|
final imageProvider = pdfWidgets.MemoryImage(resizedBytes);
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:firebase_auth/firebase_auth.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
class AuthState extends ChangeNotifier {
|
||||||
|
FirebaseAuth auth = FirebaseAuth.instance;
|
||||||
|
User? _user;
|
||||||
|
|
||||||
|
User? get user => _user;
|
||||||
|
|
||||||
|
AuthState() {
|
||||||
|
auth.authStateChanges().listen((User? user) {
|
||||||
|
if (user == null) {
|
||||||
|
print('User is currently signed out!');
|
||||||
|
_user = null;
|
||||||
|
} else {
|
||||||
|
print('User is signed in!');
|
||||||
|
_user = user;
|
||||||
|
}
|
||||||
|
notifyListeners();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> signInAnonymously() async {
|
||||||
|
try {
|
||||||
|
await auth.signInAnonymously();
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> signOut() async {
|
||||||
|
await auth.signOut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AnonymAuthScreen extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: Consumer<AuthState>(
|
||||||
|
builder: (context, authState, child) {
|
||||||
|
return ElevatedButton(
|
||||||
|
onPressed: authState.user == null
|
||||||
|
? authState.signInAnonymously
|
||||||
|
: authState.signOut,
|
||||||
|
child: Text(authState.user == null ? 'Anonym anmelden' : 'Abmelden'),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:oggauergemeindetrommler/LoginPage.dart';
|
import 'package:oggauergemeindetrommler/LoginPage.dart';
|
||||||
import 'UserDefinedList.dart';
|
import 'UserDefinedList.dart';
|
||||||
|
import 'anonym_aut.dart';
|
||||||
|
|
||||||
class MyHomePage extends StatefulWidget {
|
class MyHomePage extends StatefulWidget {
|
||||||
const MyHomePage({Key? key, required this.title});
|
const MyHomePage({Key? key, required this.title});
|
||||||
@@ -23,7 +24,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
const GenericList(collectionName: 'CitizensForum', selectedIndex: 0,),
|
const GenericList(collectionName: 'CitizensForum', selectedIndex: 0,),
|
||||||
const GenericList(collectionName: 'News', selectedIndex: 1,),
|
const GenericList(collectionName: 'News', selectedIndex: 1,),
|
||||||
const GenericList(collectionName: 'Issues', selectedIndex: 2,),
|
const GenericList(collectionName: 'Issues', selectedIndex: 2,),
|
||||||
LoginPage()
|
AnonymAuthScreen()
|
||||||
];
|
];
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
|||||||
+9
-2
@@ -1,4 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'anonym_aut.dart';
|
||||||
import 'home.dart';
|
import 'home.dart';
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'firebase_options.dart';
|
import 'firebase_options.dart';
|
||||||
@@ -8,10 +10,15 @@ void main() async {
|
|||||||
await Firebase.initializeApp(
|
await Firebase.initializeApp(
|
||||||
options: DefaultFirebaseOptions.currentPlatform,
|
options: DefaultFirebaseOptions.currentPlatform,
|
||||||
);
|
);
|
||||||
runApp(const MyApp());
|
runApp(
|
||||||
|
ChangeNotifierProvider(
|
||||||
|
create: (context) => AuthState(),
|
||||||
|
child: const MyApp(),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
const MyApp({super.key});
|
const MyApp({super.key});
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class RegisterPage extends StatefulWidget {
|
||||||
|
const RegisterPage({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_RegisterPageState createState() => _RegisterPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RegisterPageState extends State<RegisterPage> {
|
||||||
|
final _emailController = TextEditingController();
|
||||||
|
final _passwordController = TextEditingController();
|
||||||
|
final _confirmPasswordController = TextEditingController();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_emailController.dispose();
|
||||||
|
_passwordController.dispose();
|
||||||
|
_confirmPasswordController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValidEmail(String email) {
|
||||||
|
// Die gleiche Validierung wie in Ihrer LoginPage
|
||||||
|
return RegExp(r'^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$').hasMatch(email);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool arePasswordsMatching(String password, String confirmPassword) {
|
||||||
|
return password == confirmPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
TextFormField(
|
||||||
|
controller: _emailController,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'E-Mail',
|
||||||
|
),
|
||||||
|
validator: (value) {
|
||||||
|
if (value!.isEmpty) {
|
||||||
|
return 'Bitte geben Sie eine E-Mail-Adresse ein.';
|
||||||
|
} else if (!isValidEmail(value)) {
|
||||||
|
return 'Bitte geben Sie eine gültige E-Mail-Adresse ein.';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
TextFormField(
|
||||||
|
controller: _passwordController,
|
||||||
|
obscureText: true,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Passwort',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
TextFormField(
|
||||||
|
controller: _confirmPasswordController,
|
||||||
|
obscureText: true,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
labelText: 'Passwort bestätigen',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
String email = _emailController.text;
|
||||||
|
String password = _passwordController.text;
|
||||||
|
String confirmPassword = _confirmPasswordController.text;
|
||||||
|
if (isValidEmail(email) && arePasswordsMatching(password, confirmPassword)) {
|
||||||
|
// E-Mail und Passwörter sind gültig, führe die entsprechende Aktion aus
|
||||||
|
} else {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(
|
||||||
|
content: Text('Ungültige Eingaben'),
|
||||||
|
duration: Duration(seconds: 2),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: const Text('Registrieren'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -51,6 +51,7 @@ dependencies:
|
|||||||
printing: ^5.10.4
|
printing: ^5.10.4
|
||||||
image_cropper: ^8.0.1
|
image_cropper: ^8.0.1
|
||||||
logging: ^1.1.1
|
logging: ^1.1.1
|
||||||
|
provider: ^6.0.5
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|||||||
Reference in New Issue
Block a user