update edit and list and detail view
This commit is contained in:
@@ -9,9 +9,9 @@ class EditController extends GetxController {
|
|||||||
// Form Controllers
|
// Form Controllers
|
||||||
final nameController = TextEditingController();
|
final nameController = TextEditingController();
|
||||||
final typeController = TextEditingController();
|
final typeController = TextEditingController();
|
||||||
final colorController = TextEditingController();
|
|
||||||
final weightController = TextEditingController();
|
final weightController = TextEditingController();
|
||||||
final weightUsedController = TextEditingController();
|
final weightUsedController = TextEditingController();
|
||||||
|
final currentUsageController = TextEditingController();
|
||||||
final priceController = TextEditingController();
|
final priceController = TextEditingController();
|
||||||
final manufacturerController = TextEditingController();
|
final manufacturerController = TextEditingController();
|
||||||
final purchaseDateController = TextEditingController();
|
final purchaseDateController = TextEditingController();
|
||||||
@@ -20,6 +20,9 @@ class EditController extends GetxController {
|
|||||||
final printingTempController = TextEditingController();
|
final printingTempController = TextEditingController();
|
||||||
final bedTempController = TextEditingController();
|
final bedTempController = TextEditingController();
|
||||||
|
|
||||||
|
// Reactive color for UI updates
|
||||||
|
final selectedColor = 'White'.obs;
|
||||||
|
|
||||||
// Validation
|
// Validation
|
||||||
final formKey = GlobalKey<FormState>();
|
final formKey = GlobalKey<FormState>();
|
||||||
final isSaving = false.obs;
|
final isSaving = false.obs;
|
||||||
@@ -27,6 +30,7 @@ class EditController extends GetxController {
|
|||||||
// Available options
|
// Available options
|
||||||
final List<String> filamentTypes = [
|
final List<String> filamentTypes = [
|
||||||
'PLA',
|
'PLA',
|
||||||
|
'PLA+',
|
||||||
'ABS',
|
'ABS',
|
||||||
'PETG',
|
'PETG',
|
||||||
'TPU',
|
'TPU',
|
||||||
@@ -64,7 +68,8 @@ class EditController extends GetxController {
|
|||||||
if (filament != null) {
|
if (filament != null) {
|
||||||
nameController.text = filament.name;
|
nameController.text = filament.name;
|
||||||
typeController.text = filament.type;
|
typeController.text = filament.type;
|
||||||
colorController.text = filament.color;
|
selectedColor.value = filament.color;
|
||||||
|
selectedColor.value = filament.color;
|
||||||
weightController.text = filament.weight.toString();
|
weightController.text = filament.weight.toString();
|
||||||
weightUsedController.text = filament.weightUsed.toString();
|
weightUsedController.text = filament.weightUsed.toString();
|
||||||
priceController.text = filament.price.toString();
|
priceController.text = filament.price.toString();
|
||||||
@@ -83,13 +88,20 @@ class EditController extends GetxController {
|
|||||||
isSaving.value = true;
|
isSaving.value = true;
|
||||||
|
|
||||||
try {
|
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(
|
final updatedFilament = FilamentModel(
|
||||||
id: originalFilament.value?.id ?? DateTime.now().millisecondsSinceEpoch.toString(),
|
id:
|
||||||
|
originalFilament.value?.id ??
|
||||||
|
DateTime.now().millisecondsSinceEpoch.toString(),
|
||||||
name: nameController.text.trim(),
|
name: nameController.text.trim(),
|
||||||
type: typeController.text.trim(),
|
type: typeController.text.trim(),
|
||||||
color: colorController.text.trim(),
|
color: selectedColor.value.trim(),
|
||||||
weight: double.tryParse(weightController.text) ?? 0,
|
weight: double.tryParse(weightController.text) ?? 0,
|
||||||
weightUsed: double.tryParse(weightUsedController.text) ?? 0,
|
weightUsed: totalWeightUsed,
|
||||||
price: double.tryParse(priceController.text) ?? 0,
|
price: double.tryParse(priceController.text) ?? 0,
|
||||||
manufacturer: manufacturerController.text.trim().isEmpty
|
manufacturer: manufacturerController.text.trim().isEmpty
|
||||||
? null
|
? null
|
||||||
@@ -100,9 +112,9 @@ class EditController extends GetxController {
|
|||||||
notes: notesController.text.trim().isEmpty
|
notes: notesController.text.trim().isEmpty
|
||||||
? null
|
? null
|
||||||
: notesController.text.trim(),
|
: notesController.text.trim(),
|
||||||
pices: int.tryParse(piecesController.text),
|
pices: int.tryParse(piecesController.text) ?? 0,
|
||||||
printingTemp: int.tryParse(printingTempController.text),
|
printingTemp: int.tryParse(printingTempController.text) ?? 0,
|
||||||
bedTemp: int.tryParse(bedTempController.text),
|
bedTemp: int.tryParse(bedTempController.text) ?? 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
@@ -149,9 +161,9 @@ class EditController extends GetxController {
|
|||||||
void onClose() {
|
void onClose() {
|
||||||
nameController.dispose();
|
nameController.dispose();
|
||||||
typeController.dispose();
|
typeController.dispose();
|
||||||
colorController.dispose();
|
|
||||||
weightController.dispose();
|
weightController.dispose();
|
||||||
weightUsedController.dispose();
|
weightUsedController.dispose();
|
||||||
|
currentUsageController.dispose();
|
||||||
priceController.dispose();
|
priceController.dispose();
|
||||||
manufacturerController.dispose();
|
manufacturerController.dispose();
|
||||||
purchaseDateController.dispose();
|
purchaseDateController.dispose();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ class ListController extends GetxController {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
_loadListFillament();
|
loadListFillament();
|
||||||
super.onInit();
|
super.onInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ class ListController extends GetxController {
|
|||||||
@override
|
@override
|
||||||
void onClose() {}
|
void onClose() {}
|
||||||
|
|
||||||
Future<void> _loadListFillament() async {
|
Future<void> loadListFillament() async {
|
||||||
isLoadingFilament(true);
|
isLoadingFilament(true);
|
||||||
if (filamentList.isNotEmpty) {
|
if (filamentList.isNotEmpty) {
|
||||||
filamentList.clear();
|
filamentList.clear();
|
||||||
@@ -30,14 +30,18 @@ class ListController extends GetxController {
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addNewFilament() {}
|
void addNewFilament() async {
|
||||||
|
await Get.toNamed(EditPage.namedRoute);
|
||||||
|
loadListFillament();
|
||||||
|
}
|
||||||
|
|
||||||
void viewFilamentDetails(FilamentModel filament) {
|
void viewFilamentDetails(FilamentModel filament) {
|
||||||
Get.toNamed(DetailsPage.namedRoute, arguments: {'filament': filament});
|
Get.toNamed(DetailsPage.namedRoute, arguments: {'filament': filament});
|
||||||
}
|
}
|
||||||
|
|
||||||
void editFilament(FilamentModel filament) {
|
void editFilament(FilamentModel filament) async {
|
||||||
Get.toNamed(EditPage.namedRoute, arguments: {'filament': filament});
|
await Get.toNamed(EditPage.namedRoute, arguments: {'filament': filament});
|
||||||
|
loadListFillament();
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeFilament(FilamentModel filament) {
|
void removeFilament(FilamentModel filament) {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import 'helpers/sample_routes.dart';
|
|||||||
import 'pages/home_view.dart';
|
import 'pages/home_view.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
await Get.putAsync(() => FilamentRepository().init());
|
await Get.putAsync(() => FilamentRepository().init());
|
||||||
runApp(MyApp());
|
runApp(MyApp());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class FilamentModel {
|
|||||||
final String? manufacturer;
|
final String? manufacturer;
|
||||||
final String? purchaseDate;
|
final String? purchaseDate;
|
||||||
final String? notes;
|
final String? notes;
|
||||||
final int? pices;
|
final int pices;
|
||||||
final int? printingTemp;
|
final int? printingTemp;
|
||||||
final int? bedTemp;
|
final int? bedTemp;
|
||||||
|
|
||||||
@@ -26,9 +26,9 @@ class FilamentModel {
|
|||||||
this.manufacturer,
|
this.manufacturer,
|
||||||
this.purchaseDate,
|
this.purchaseDate,
|
||||||
this.notes,
|
this.notes,
|
||||||
this.pices,
|
required this.pices,
|
||||||
this.printingTemp,
|
this.printingTemp,
|
||||||
this.bedTemp
|
this.bedTemp,
|
||||||
});
|
});
|
||||||
|
|
||||||
// JSON Serialisierung
|
// JSON Serialisierung
|
||||||
@@ -46,7 +46,7 @@ class FilamentModel {
|
|||||||
'pices': pices,
|
'pices': pices,
|
||||||
'printingTemp': printingTemp,
|
'printingTemp': printingTemp,
|
||||||
'bedTemp': bedTemp,
|
'bedTemp': bedTemp,
|
||||||
'printWeightUsed': weightUsed,
|
'weightUsed': weightUsed,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,13 +57,13 @@ class FilamentModel {
|
|||||||
name: json['name'] as String,
|
name: json['name'] as String,
|
||||||
type: json['type'] as String,
|
type: json['type'] as String,
|
||||||
color: json['color'] as String,
|
color: json['color'] as String,
|
||||||
weight: (json['weight'] as num).toDouble(),
|
weight: (json['weight'] as num?)?.toDouble() ?? 0.0,
|
||||||
weightUsed: (json['weightUsed'] as num).toDouble(),
|
weightUsed: (json['weightUsed'] as num?)?.toDouble() ?? 0.0,
|
||||||
price: (json['price'] as num).toDouble(),
|
price: (json['price'] as num).toDouble(),
|
||||||
manufacturer: json['manufacturer'] as String?,
|
manufacturer: json['manufacturer'] as String?,
|
||||||
purchaseDate: json['purchaseDate'] as String?,
|
purchaseDate: json['purchaseDate'] as String?,
|
||||||
notes: json['notes'] as String?,
|
notes: json['notes'] as String?,
|
||||||
pices: json['pices'] as int?,
|
pices: json['pices'] as int,
|
||||||
printingTemp: json['printingTemp'] as int?,
|
printingTemp: json['printingTemp'] as int?,
|
||||||
bedTemp: json['bedTemp'] as int?,
|
bedTemp: json['bedTemp'] as int?,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -76,7 +76,9 @@ class EditPage extends GetView<EditController> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
isNewFilament ? 'Neues Filament anlegen' : 'Filament bearbeiten',
|
isNewFilament
|
||||||
|
? 'Neues Filament anlegen'
|
||||||
|
: 'Filament bearbeiten',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
@@ -145,14 +147,14 @@ class EditPage extends GetView<EditController> {
|
|||||||
|
|
||||||
SizedBox(height: 16),
|
SizedBox(height: 16),
|
||||||
|
|
||||||
ColorSelector(
|
Obx(
|
||||||
selectedColor: controller.colorController.text.isNotEmpty
|
() => ColorSelector(
|
||||||
? controller.colorController.text
|
selectedColor: controller.selectedColor.value,
|
||||||
: 'White',
|
colors: controller.availableColors,
|
||||||
colors: controller.availableColors,
|
onColorSelected: (color) {
|
||||||
onColorSelected: (color) {
|
controller.selectedColor.value = color;
|
||||||
controller.colorController.text = color;
|
},
|
||||||
},
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(height: 24),
|
SizedBox(height: 24),
|
||||||
@@ -193,6 +195,7 @@ class EditPage extends GetView<EditController> {
|
|||||||
hint: '0',
|
hint: '0',
|
||||||
icon: Icons.trending_down,
|
icon: Icons.trending_down,
|
||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
|
readOnly: true,
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value != null && value.isNotEmpty) {
|
if (value != null && value.isNotEmpty) {
|
||||||
if (double.tryParse(value) == null) {
|
if (double.tryParse(value) == null) {
|
||||||
@@ -208,6 +211,24 @@ class EditPage extends GetView<EditController> {
|
|||||||
|
|
||||||
SizedBox(height: 16),
|
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(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
@@ -309,9 +330,7 @@ class EditPage extends GetView<EditController> {
|
|||||||
builder: (context, child) {
|
builder: (context, child) {
|
||||||
return Theme(
|
return Theme(
|
||||||
data: Theme.of(context).copyWith(
|
data: Theme.of(context).copyWith(
|
||||||
colorScheme: ColorScheme.light(
|
colorScheme: ColorScheme.light(primary: Colors.blue),
|
||||||
primary: Colors.blue,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
child: child!,
|
child: child!,
|
||||||
);
|
);
|
||||||
@@ -319,10 +338,15 @@ class EditPage extends GetView<EditController> {
|
|||||||
);
|
);
|
||||||
if (date != null) {
|
if (date != null) {
|
||||||
final formatter = DateFormat('dd.MM.yyyy');
|
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),
|
SizedBox(height: 16),
|
||||||
@@ -338,48 +362,50 @@ class EditPage extends GetView<EditController> {
|
|||||||
SizedBox(height: 32),
|
SizedBox(height: 32),
|
||||||
|
|
||||||
// Save Button
|
// Save Button
|
||||||
Obx(() => AnimatedContainer(
|
Obx(
|
||||||
duration: Duration(milliseconds: 300),
|
() => AnimatedContainer(
|
||||||
height: 56,
|
duration: Duration(milliseconds: 300),
|
||||||
child: controller.isSaving.value
|
height: 56,
|
||||||
? Container(
|
child: controller.isSaving.value
|
||||||
decoration: BoxDecoration(
|
? Container(
|
||||||
color: Colors.blue.shade100,
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(12),
|
color: Colors.blue.shade100,
|
||||||
),
|
borderRadius: BorderRadius.circular(12),
|
||||||
child: Center(
|
),
|
||||||
child: Row(
|
child: Center(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
child: Row(
|
||||||
children: [
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
SizedBox(
|
children: [
|
||||||
width: 20,
|
SizedBox(
|
||||||
height: 20,
|
width: 20,
|
||||||
child: CircularProgressIndicator(
|
height: 20,
|
||||||
strokeWidth: 2,
|
child: CircularProgressIndicator(
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
strokeWidth: 2,
|
||||||
Colors.blue,
|
valueColor: AlwaysStoppedAnimation<Color>(
|
||||||
|
Colors.blue,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
SizedBox(width: 12),
|
||||||
SizedBox(width: 12),
|
Text(
|
||||||
Text(
|
'Wird gespeichert...',
|
||||||
'Wird gespeichert...',
|
style: TextStyle(
|
||||||
style: TextStyle(
|
color: Colors.blue,
|
||||||
color: Colors.blue,
|
fontWeight: FontWeight.w600,
|
||||||
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),
|
SizedBox(height: 16),
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class ColorSelector extends StatelessWidget {
|
|||||||
'pink': Colors.pink,
|
'pink': Colors.pink,
|
||||||
'grey': Colors.grey,
|
'grey': Colors.grey,
|
||||||
'brown': Colors.brown,
|
'brown': Colors.brown,
|
||||||
|
'wood' : Colors.brown[300]!,
|
||||||
};
|
};
|
||||||
return colorMap[colorName.toLowerCase()] ?? Colors.grey;
|
return colorMap[colorName.toLowerCase()] ?? Colors.grey;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,39 +30,46 @@ class DetailInfoCard extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.all(10),
|
padding: EdgeInsets.all(8),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: color.withAlpha(10),
|
color: color.withAlpha(10),
|
||||||
borderRadius: BorderRadius.circular(12),
|
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(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
label,
|
label,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 11,
|
||||||
color: Colors.grey.shade600,
|
color: Colors.grey.shade600,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
),
|
),
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
SizedBox(height: 4),
|
SizedBox(height: 4),
|
||||||
Text(
|
Text(
|
||||||
value,
|
value,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 18,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Colors.grey.shade800,
|
color: Colors.grey.shade800,
|
||||||
),
|
),
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user