diff --git a/lib/controllers/edit_controller.dart b/lib/controllers/edit_controller.dart index 73cae00..3a1eb09 100644 --- a/lib/controllers/edit_controller.dart +++ b/lib/controllers/edit_controller.dart @@ -5,13 +5,13 @@ import '../helpers/filament_repository.dart'; class EditController extends GetxController { Rx originalFilament = Rx(null); - + // Form Controllers final nameController = TextEditingController(); final typeController = TextEditingController(); - final colorController = TextEditingController(); final weightController = TextEditingController(); final weightUsedController = TextEditingController(); + final currentUsageController = TextEditingController(); final priceController = TextEditingController(); final manufacturerController = TextEditingController(); final purchaseDateController = TextEditingController(); @@ -20,6 +20,9 @@ class EditController extends GetxController { final printingTempController = TextEditingController(); final bedTempController = TextEditingController(); + // Reactive color for UI updates + final selectedColor = 'White'.obs; + // Validation final formKey = GlobalKey(); final isSaving = false.obs; @@ -27,6 +30,7 @@ class EditController extends GetxController { // Available options final List filamentTypes = [ 'PLA', + 'PLA+', 'ABS', 'PETG', 'TPU', @@ -64,7 +68,8 @@ class EditController extends GetxController { if (filament != null) { nameController.text = filament.name; typeController.text = filament.type; - colorController.text = filament.color; + selectedColor.value = filament.color; + selectedColor.value = filament.color; weightController.text = filament.weight.toString(); weightUsedController.text = filament.weightUsed.toString(); priceController.text = filament.price.toString(); @@ -83,26 +88,33 @@ class EditController extends GetxController { isSaving.value = true; try { + // Berechne den neuen Gesamtverbrauch + final currentWeightUsed = double.tryParse(weightUsedController.text) ?? 0; + final additionalUsage = double.tryParse(currentUsageController.text) ?? 0; + final totalWeightUsed = currentWeightUsed + additionalUsage; + final updatedFilament = FilamentModel( - id: originalFilament.value?.id ?? DateTime.now().millisecondsSinceEpoch.toString(), + id: + originalFilament.value?.id ?? + DateTime.now().millisecondsSinceEpoch.toString(), name: nameController.text.trim(), type: typeController.text.trim(), - color: colorController.text.trim(), + color: selectedColor.value.trim(), weight: double.tryParse(weightController.text) ?? 0, - weightUsed: double.tryParse(weightUsedController.text) ?? 0, + weightUsed: totalWeightUsed, price: double.tryParse(priceController.text) ?? 0, - manufacturer: manufacturerController.text.trim().isEmpty - ? null + manufacturer: manufacturerController.text.trim().isEmpty + ? null : manufacturerController.text.trim(), - purchaseDate: purchaseDateController.text.trim().isEmpty - ? null + purchaseDate: purchaseDateController.text.trim().isEmpty + ? null : purchaseDateController.text.trim(), - notes: notesController.text.trim().isEmpty - ? null + notes: notesController.text.trim().isEmpty + ? null : notesController.text.trim(), - pices: int.tryParse(piecesController.text), - printingTemp: int.tryParse(printingTempController.text), - bedTemp: int.tryParse(bedTempController.text), + pices: int.tryParse(piecesController.text) ?? 0, + printingTemp: int.tryParse(printingTempController.text) ?? 0, + bedTemp: int.tryParse(bedTempController.text) ?? 0, ); bool success; @@ -116,7 +128,7 @@ class EditController extends GetxController { Get.back(result: updatedFilament); Get.snackbar( 'Erfolg', - originalFilament.value != null + originalFilament.value != null ? 'Filament wurde aktualisiert' : 'Filament wurde erstellt', snackPosition: SnackPosition.BOTTOM, @@ -149,9 +161,9 @@ class EditController extends GetxController { void onClose() { nameController.dispose(); typeController.dispose(); - colorController.dispose(); weightController.dispose(); weightUsedController.dispose(); + currentUsageController.dispose(); priceController.dispose(); manufacturerController.dispose(); purchaseDateController.dispose(); diff --git a/lib/controllers/list_controller.dart b/lib/controllers/list_controller.dart index 9fd877d..ea6ff7e 100644 --- a/lib/controllers/list_controller.dart +++ b/lib/controllers/list_controller.dart @@ -10,7 +10,7 @@ class ListController extends GetxController { @override void onInit() { - _loadListFillament(); + loadListFillament(); super.onInit(); } @@ -20,7 +20,7 @@ class ListController extends GetxController { @override void onClose() {} - Future _loadListFillament() async { + Future loadListFillament() async { isLoadingFilament(true); if (filamentList.isNotEmpty) { filamentList.clear(); @@ -30,14 +30,18 @@ class ListController extends GetxController { update(); } - void addNewFilament() {} + void addNewFilament() async { + await Get.toNamed(EditPage.namedRoute); + loadListFillament(); + } void viewFilamentDetails(FilamentModel filament) { Get.toNamed(DetailsPage.namedRoute, arguments: {'filament': filament}); } - void editFilament(FilamentModel filament) { - Get.toNamed(EditPage.namedRoute, arguments: {'filament': filament}); + void editFilament(FilamentModel filament) async { + await Get.toNamed(EditPage.namedRoute, arguments: {'filament': filament}); + loadListFillament(); } void removeFilament(FilamentModel filament) { diff --git a/lib/main.dart b/lib/main.dart index cb0d18a..2d10263 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,6 +7,7 @@ import 'helpers/sample_routes.dart'; import 'pages/home_view.dart'; void main() async { + WidgetsFlutterBinding.ensureInitialized(); await Get.putAsync(() => FilamentRepository().init()); runApp(MyApp()); } diff --git a/lib/model/filament_model.dart b/lib/model/filament_model.dart index 541a561..5db99fd 100644 --- a/lib/model/filament_model.dart +++ b/lib/model/filament_model.dart @@ -11,7 +11,7 @@ class FilamentModel { final String? manufacturer; final String? purchaseDate; final String? notes; - final int? pices; + final int pices; final int? printingTemp; final int? bedTemp; @@ -26,9 +26,9 @@ class FilamentModel { this.manufacturer, this.purchaseDate, this.notes, - this.pices, + required this.pices, this.printingTemp, - this.bedTemp + this.bedTemp, }); // JSON Serialisierung @@ -46,7 +46,7 @@ class FilamentModel { 'pices': pices, 'printingTemp': printingTemp, 'bedTemp': bedTemp, - 'printWeightUsed': weightUsed, + 'weightUsed': weightUsed, }; } @@ -57,13 +57,13 @@ class FilamentModel { name: json['name'] as String, type: json['type'] as String, color: json['color'] as String, - weight: (json['weight'] as num).toDouble(), - weightUsed: (json['weightUsed'] as num).toDouble(), + weight: (json['weight'] as num?)?.toDouble() ?? 0.0, + weightUsed: (json['weightUsed'] as num?)?.toDouble() ?? 0.0, price: (json['price'] as num).toDouble(), manufacturer: json['manufacturer'] as String?, purchaseDate: json['purchaseDate'] as String?, notes: json['notes'] as String?, - pices: json['pices'] as int?, + pices: json['pices'] as int, printingTemp: json['printingTemp'] as int?, bedTemp: json['bedTemp'] as int?, ); diff --git a/lib/pages/edit_view.dart b/lib/pages/edit_view.dart index 27e3b93..6880c81 100644 --- a/lib/pages/edit_view.dart +++ b/lib/pages/edit_view.dart @@ -76,7 +76,9 @@ class EditPage extends GetView { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - isNewFilament ? 'Neues Filament anlegen' : 'Filament bearbeiten', + isNewFilament + ? 'Neues Filament anlegen' + : 'Filament bearbeiten', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, @@ -145,14 +147,14 @@ class EditPage extends GetView { SizedBox(height: 16), - ColorSelector( - selectedColor: controller.colorController.text.isNotEmpty - ? controller.colorController.text - : 'White', - colors: controller.availableColors, - onColorSelected: (color) { - controller.colorController.text = color; - }, + Obx( + () => ColorSelector( + selectedColor: controller.selectedColor.value, + colors: controller.availableColors, + onColorSelected: (color) { + controller.selectedColor.value = color; + }, + ), ), SizedBox(height: 24), @@ -193,6 +195,7 @@ class EditPage extends GetView { hint: '0', icon: Icons.trending_down, keyboardType: TextInputType.number, + readOnly: true, validator: (value) { if (value != null && value.isNotEmpty) { if (double.tryParse(value) == null) { @@ -208,6 +211,24 @@ class EditPage extends GetView { SizedBox(height: 16), + CustomTextField( + controller: controller.currentUsageController, + label: 'Aktueller Verbrauch hinzufügen (g)', + hint: '0', + icon: Icons.add_circle_outline, + keyboardType: TextInputType.number, + validator: (value) { + if (value != null && value.isNotEmpty) { + if (double.tryParse(value) == null) { + return 'Ungültige Zahl'; + } + } + return null; + }, + ), + + SizedBox(height: 16), + Row( children: [ Expanded( @@ -309,9 +330,7 @@ class EditPage extends GetView { builder: (context, child) { return Theme( data: Theme.of(context).copyWith( - colorScheme: ColorScheme.light( - primary: Colors.blue, - ), + colorScheme: ColorScheme.light(primary: Colors.blue), ), child: child!, ); @@ -319,10 +338,15 @@ class EditPage extends GetView { ); if (date != null) { final formatter = DateFormat('dd.MM.yyyy'); - controller.purchaseDateController.text = formatter.format(date); + controller.purchaseDateController.text = formatter.format( + date, + ); } }, - suffix: Icon(Icons.arrow_drop_down, color: Colors.blue.shade400), + suffix: Icon( + Icons.arrow_drop_down, + color: Colors.blue.shade400, + ), ), SizedBox(height: 16), @@ -338,48 +362,50 @@ class EditPage extends GetView { SizedBox(height: 32), // Save Button - Obx(() => AnimatedContainer( - duration: Duration(milliseconds: 300), - height: 56, - child: controller.isSaving.value - ? Container( - decoration: BoxDecoration( - color: Colors.blue.shade100, - borderRadius: BorderRadius.circular(12), - ), - child: Center( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox( - width: 20, - height: 20, - child: CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation( - Colors.blue, + Obx( + () => AnimatedContainer( + duration: Duration(milliseconds: 300), + height: 56, + child: controller.isSaving.value + ? Container( + decoration: BoxDecoration( + color: Colors.blue.shade100, + borderRadius: BorderRadius.circular(12), + ), + child: Center( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 20, + height: 20, + child: CircularProgressIndicator( + strokeWidth: 2, + valueColor: AlwaysStoppedAnimation( + Colors.blue, + ), ), ), - ), - SizedBox(width: 12), - Text( - 'Wird gespeichert...', - style: TextStyle( - color: Colors.blue, - fontWeight: FontWeight.w600, + SizedBox(width: 12), + Text( + 'Wird gespeichert...', + style: TextStyle( + color: Colors.blue, + fontWeight: FontWeight.w600, + ), ), - ), - ], + ], + ), ), + ) + : ActionButton( + icon: Icons.save, + label: isNewFilament ? 'Erstellen' : 'Speichern', + color: Colors.blue, + onPressed: controller.saveFilament, ), - ) - : ActionButton( - icon: Icons.save, - label: isNewFilament ? 'Erstellen' : 'Speichern', - color: Colors.blue, - onPressed: controller.saveFilament, - ), - )), + ), + ), SizedBox(height: 16), diff --git a/lib/widgets/color_selector.dart b/lib/widgets/color_selector.dart index 0d946bd..2c57269 100644 --- a/lib/widgets/color_selector.dart +++ b/lib/widgets/color_selector.dart @@ -25,6 +25,7 @@ class ColorSelector extends StatelessWidget { 'pink': Colors.pink, 'grey': Colors.grey, 'brown': Colors.brown, + 'wood' : Colors.brown[300]!, }; return colorMap[colorName.toLowerCase()] ?? Colors.grey; } diff --git a/lib/widgets/detail_info_card.dart b/lib/widgets/detail_info_card.dart index 75bad72..9bb1007 100644 --- a/lib/widgets/detail_info_card.dart +++ b/lib/widgets/detail_info_card.dart @@ -30,39 +30,46 @@ class DetailInfoCard extends StatelessWidget { ], ), child: Column( + mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( - padding: EdgeInsets.all(10), + padding: EdgeInsets.all(8), decoration: BoxDecoration( color: color.withAlpha(10), borderRadius: BorderRadius.circular(12), ), - child: Icon(icon, color: color, size: 24), + child: Icon(icon, color: color, size: 20), ), - SizedBox(width: 12), + SizedBox(width: 10), Expanded( child: Column( + mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: TextStyle( - fontSize: 12, + fontSize: 11, color: Colors.grey.shade600, fontWeight: FontWeight.w500, ), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), SizedBox(height: 4), Text( value, style: TextStyle( - fontSize: 18, + fontSize: 16, fontWeight: FontWeight.bold, color: Colors.grey.shade800, ), + maxLines: 2, + overflow: TextOverflow.ellipsis, ), ], ),