176 lines
5.7 KiB
Dart
176 lines
5.7 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:get/get.dart';
|
||
|
||
import '../controller/home_controller.dart';
|
||
import '../models/kauf_filament_model.dart';
|
||
import '../theme/app_theme.dart';
|
||
import '../widgets/filament_form.dart';
|
||
import '../widgets/filament_inventory.dart';
|
||
import '../widgets/app_version.dart';
|
||
import 'anwendung_view.dart';
|
||
import 'bauteil_view.dart';
|
||
import 'export_view.dart';
|
||
|
||
class HomeView extends GetView<HomeController> {
|
||
static const routeName = '/home-view';
|
||
const HomeView({super.key});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Scaffold(
|
||
appBar: AppBar(
|
||
toolbarHeight: 80,
|
||
actions: [
|
||
IconButton(
|
||
tooltip: 'Bauteile verwalten',
|
||
icon: const Icon(Icons.view_in_ar_outlined),
|
||
onPressed: () => Get.toNamed(BauteilView.routeName),
|
||
),
|
||
const SizedBox(width: 8),
|
||
],
|
||
title: LayoutBuilder(
|
||
builder: (context, constraints) => Row(
|
||
children: [
|
||
if (constraints.maxWidth >= 260) ...[
|
||
const Icon(
|
||
Icons.all_inbox_rounded,
|
||
color: AppTheme.teal,
|
||
size: 28,
|
||
),
|
||
const SizedBox(width: 12),
|
||
],
|
||
const Flexible(
|
||
child: Text(
|
||
'Filamentverwaltung',
|
||
maxLines: 2,
|
||
overflow: TextOverflow.ellipsis,
|
||
style: TextStyle(fontSize: 21, fontWeight: FontWeight.w700),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
drawer: Drawer(
|
||
child: SafeArea(
|
||
child: ListView(
|
||
padding: const EdgeInsets.all(16),
|
||
children: [
|
||
const ListTile(title: Text('Filamentverwaltung')),
|
||
const AppVersion(),
|
||
const Divider(),
|
||
ListTile(
|
||
leading: const Icon(Icons.import_export),
|
||
title: const Text('Daten exportieren / importieren'),
|
||
onTap: () {
|
||
Navigator.of(context).pop();
|
||
Get.toNamed(ExportView.routeName);
|
||
},
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
body: SafeArea(
|
||
top: false,
|
||
child: Align(
|
||
alignment: Alignment.topCenter,
|
||
child: ConstrainedBox(
|
||
constraints: const BoxConstraints(maxWidth: 1320),
|
||
child: LayoutBuilder(
|
||
builder: (context, constraints) {
|
||
final wide = constraints.maxWidth >= 900;
|
||
final form = FilamentForm(controller: controller);
|
||
final inventory = FilamentInventory(
|
||
controller: controller,
|
||
onOpen: (filament) => Get.toNamed(
|
||
'${AnwendungView.routeName}/${Uri.encodeComponent(filament.filamentId)}',
|
||
),
|
||
onAction: (action, filament) =>
|
||
_handleAction(context, action, filament),
|
||
);
|
||
if (wide) {
|
||
return Padding(
|
||
padding: const EdgeInsets.fromLTRB(24, 8, 24, 24),
|
||
child: Row(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
SizedBox(
|
||
width: 390,
|
||
child: SingleChildScrollView(
|
||
controller: controller.formScrollController,
|
||
child: form,
|
||
),
|
||
),
|
||
const SizedBox(width: 24),
|
||
Expanded(
|
||
child: CustomScrollView(
|
||
controller: controller.pageScrollController,
|
||
slivers: [inventory],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
return CustomScrollView(
|
||
controller: controller.pageScrollController,
|
||
keyboardDismissBehavior:
|
||
ScrollViewKeyboardDismissBehavior.onDrag,
|
||
slivers: [
|
||
SliverPadding(
|
||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 20),
|
||
sliver: SliverToBoxAdapter(child: form),
|
||
),
|
||
SliverPadding(
|
||
padding: const EdgeInsets.fromLTRB(16, 0, 16, 24),
|
||
sliver: inventory,
|
||
),
|
||
],
|
||
);
|
||
},
|
||
),
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Future<void> _handleAction(
|
||
BuildContext context,
|
||
String action,
|
||
KaufFilamentModel filament,
|
||
) async {
|
||
switch (action) {
|
||
case 'edit':
|
||
await controller.editFilament(filament);
|
||
break;
|
||
case 'duplicate':
|
||
await controller.duplicateFilament(filament);
|
||
break;
|
||
case 'delete':
|
||
final confirmed = await showDialog<bool>(
|
||
context: context,
|
||
builder: (dialogContext) => AlertDialog(
|
||
title: const Text('Filament löschen?'),
|
||
content: Text('${filament.material} – ${filament.farbe} löschen?'),
|
||
actions: [
|
||
TextButton(
|
||
onPressed: () => Navigator.pop(dialogContext, false),
|
||
child: const Text('Abbrechen'),
|
||
),
|
||
FilledButton(
|
||
onPressed: () => Navigator.pop(dialogContext, true),
|
||
child: const Text('Löschen'),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
if (confirmed == true) {
|
||
await controller.deleteFilament(filament.filamentId);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|