175 lines
5.2 KiB
Dart
175 lines
5.2 KiB
Dart
|
import 'dart:typed_data';
|
||
|
import 'package:flutter/material.dart';
|
||
|
import 'package:image_picker/image_picker.dart';
|
||
|
import 'package:firebase_storage/firebase_storage.dart';
|
||
|
import 'package:firebase_database/firebase_database.dart';
|
||
|
import 'package:path/path.dart';
|
||
|
|
||
|
class Recipeformpage extends StatefulWidget {
|
||
|
const Recipeformpage({super.key});
|
||
|
|
||
|
@override
|
||
|
RecipeformpageState createState() => RecipeformpageState();
|
||
|
}
|
||
|
|
||
|
class RecipeformpageState extends State<Recipeformpage> {
|
||
|
final _formKey = GlobalKey<FormState>();
|
||
|
String title = '';
|
||
|
String description1 = '';
|
||
|
String description2 = '';
|
||
|
String description3 = '';
|
||
|
String image1 = '';
|
||
|
String image2 = '';
|
||
|
String image3 = '';
|
||
|
|
||
|
final ImagePicker _picker = ImagePicker();
|
||
|
|
||
|
Future<void> _pickAndUploadImage(String fieldName) async {
|
||
|
final XFile? pickedFile = await _picker.pickImage(source: ImageSource.gallery);
|
||
|
if (pickedFile != null) {
|
||
|
// Lese die Datei als Byte-Array ein
|
||
|
Uint8List fileBytes = await pickedFile.readAsBytes();
|
||
|
String fileName = basename(pickedFile.path);
|
||
|
Reference storageRef = FirebaseStorage.instance.ref().child('rezeptbilder/$fileName');
|
||
|
|
||
|
// Starte den Upload-Prozess
|
||
|
UploadTask uploadTask = storageRef.putData(fileBytes);
|
||
|
|
||
|
// Warte auf das Ende des Uploads
|
||
|
await uploadTask.whenComplete(() {});
|
||
|
|
||
|
// Erhalte die Download-URL
|
||
|
String downloadUrl = await storageRef.getDownloadURL();
|
||
|
|
||
|
setState(() {
|
||
|
// Aktualisiere den entsprechenden Bild-URL-Zustand
|
||
|
switch (fieldName) {
|
||
|
case 'image1':
|
||
|
image1 = downloadUrl;
|
||
|
break;
|
||
|
case 'image2':
|
||
|
image2 = downloadUrl;
|
||
|
break;
|
||
|
case 'image3':
|
||
|
image3 = downloadUrl;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void _saveForm(BuildContext context) async {
|
||
|
|
||
|
if (_formKey.currentState!.validate()) {
|
||
|
_formKey.currentState!.save();
|
||
|
|
||
|
DatabaseReference databaseRef = FirebaseDatabase.instance.ref().child('rezepte');
|
||
|
String? rezeptId = databaseRef.push().key; // Eindeutiger Schlüssel für das neue Rezept
|
||
|
|
||
|
databaseRef.child(rezeptId!).set({
|
||
|
'titel': title,
|
||
|
'beschreibung1': description1,
|
||
|
'beschreibung2': description2,
|
||
|
'beschreibung3': description3,
|
||
|
'bild1': image1,
|
||
|
'bild2': image2,
|
||
|
'bild3': image3,
|
||
|
});
|
||
|
|
||
|
Navigator.of(context).pop(); // Schließt das Formular nach dem Speichern
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
return Scaffold(
|
||
|
appBar: AppBar(
|
||
|
title: const Text("Neues Rezept"),
|
||
|
),
|
||
|
body: Stack(
|
||
|
children: <Widget>[
|
||
|
Form(
|
||
|
key: _formKey,
|
||
|
child: ListView(
|
||
|
padding: const EdgeInsets.all(16),
|
||
|
children: <Widget>[
|
||
|
TextFormField(
|
||
|
decoration: const InputDecoration(labelText: 'Titel'),
|
||
|
onSaved: (value) => title = value ?? '',
|
||
|
validator: (value) {
|
||
|
if (value == null || value.isEmpty) {
|
||
|
return 'Bitte einen Titel eingeben';
|
||
|
}
|
||
|
return null;
|
||
|
},
|
||
|
),
|
||
|
TextFormField(
|
||
|
decoration: const InputDecoration(labelText: 'Zutaten: '),
|
||
|
onSaved: (value) => description1 = value ?? '',
|
||
|
),
|
||
|
TextFormField(
|
||
|
decoration: const InputDecoration(labelText: 'Anleitung: '),
|
||
|
onSaved: (value) => description2 = value ?? '',
|
||
|
),
|
||
|
TextFormField(
|
||
|
decoration: const InputDecoration(labelText: 'Anmerkungen: '),
|
||
|
onSaved: (value) => description3 = value ?? '',
|
||
|
),
|
||
|
_imageField('Anzeigebild', 'image1'),
|
||
|
_imageField('Handgeschriebenes Rezept', 'image2'),
|
||
|
_imageField('Textscan', 'image3'),
|
||
|
],
|
||
|
),
|
||
|
),
|
||
|
Positioned(
|
||
|
right: 16,
|
||
|
bottom: 16,
|
||
|
child: FloatingActionButton(
|
||
|
onPressed: () => _saveForm(context),
|
||
|
tooltip: 'Rezept speichern',
|
||
|
child: const Icon(Icons.save),
|
||
|
),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
Widget _imageField(String label, String fieldName) {
|
||
|
String? imageUrl;
|
||
|
switch (fieldName) {
|
||
|
case 'image1':
|
||
|
imageUrl = image1;
|
||
|
break;
|
||
|
case 'image2':
|
||
|
imageUrl = image2;
|
||
|
break;
|
||
|
case 'image3':
|
||
|
imageUrl = image3;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return Column(
|
||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||
|
children: [
|
||
|
if (imageUrl != null && imageUrl.isNotEmpty)
|
||
|
Image.network(imageUrl, width: 100, height: 100),
|
||
|
Row(
|
||
|
children: [
|
||
|
Expanded(
|
||
|
child: TextFormField(
|
||
|
decoration: InputDecoration(labelText: label),
|
||
|
),
|
||
|
),
|
||
|
IconButton(
|
||
|
icon: const Icon(Icons.photo_camera),
|
||
|
onPressed: () => _pickAndUploadImage(fieldName),
|
||
|
),
|
||
|
],
|
||
|
),
|
||
|
],
|
||
|
);
|
||
|
}
|
||
|
}
|