Files
ertl_filament_verwaltung/lib/pages/bauteil_view.dart
T
2026-10-29 15:03:48 +01:00

115 lines
4.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controller/bauteil_controller.dart';
import '../helper/display_formats.dart';
import '../models/bauteil_model.dart';
import '../widgets/bauteil_card.dart';
import '../widgets/bauteil_delete_dialog.dart';
import '../widgets/bauteil_form.dart';
import '../widgets/entry_panel.dart';
import 'bauteil_auswertung_view.dart';
class BauteilView extends GetView<BauteilController> {
static const routeName = '/bauteile-view';
const BauteilView({super.key});
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text(
'Gedruckte Bauteile',
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
actions: [
IconButton(
tooltip: 'Bauteile auswerten',
icon: const Icon(Icons.bar_chart_outlined),
onPressed: () => Get.toNamed(BauteilAuswertungView.routeName),
),
const SizedBox(width: 8),
],
),
body: SafeArea(
top: false,
child: Align(
alignment: Alignment.topCenter,
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 1000),
child: CustomScrollView(
controller: controller.scrollController,
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
slivers: [
SliverPadding(
padding: const EdgeInsets.all(16),
sliver: SliverToBoxAdapter(
child: BauteilForm(controller: controller),
),
),
SliverPadding(
padding: const EdgeInsets.fromLTRB(16, 4, 16, 24),
sliver: Obx(() {
final entries = controller.bauteile.toList();
return SavedEntries(
title: 'Deine Bauteile',
count: entries.length,
emptyText: 'Noch keine Bauteile gespeichert. Erfasse deinen ersten Druck.',
itemBuilder: (context, index) {
final entry = entries[index];
return BauteilCard(
key: ValueKey(entry.bauteilId),
bauteil: entry,
onAction: (action) =>
_handleAction(context, action, entry),
filamentDetails: entry.filamente
.map((item) {
final profile = controller.profile
.firstWhereOrNull(
(profile) =>
profile.anwendungId == item.anwendungId,
);
final suffix = profile == null
? ''
: ' · Profil ${DisplayFormats.number(profile.druckTemperatur)} °C / Bett ${DisplayFormats.number(profile.druckbettTemperatur)} °C';
final usage = item.verbrauchGramm > 0
? '${DisplayFormats.number(item.verbrauchGramm)} g'
: 'Verbrauch noch nicht erfasst';
return '${controller.filamentLabel(item.filamentId)} · $usage$suffix';
})
.join('\n'),
);
},
);
}),
),
],
),
),
),
),
);
Future<void> _handleAction(
BuildContext context,
String action,
BauteilModel entry,
) async {
switch (action) {
case 'edit':
await controller.editBauteil(entry);
break;
case 'duplicate':
await controller.duplicateBauteil(entry);
break;
case 'delete':
final confirmed = await showDialog<bool>(
context: context,
builder: (context) => BauteilDeleteDialog(name: entry.name),
);
if (confirmed == true) await controller.deleteBauteil(entry.bauteilId);
break;
}
}
}