115 lines
4.1 KiB
Dart
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;
|
|
}
|
|
}
|
|
}
|