Files
flutter_tank_web_app/lib/pages/edit_view.dart

291 lines
11 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controller/edit_controller.dart';
import '../widgets/edit_form_field_widget.dart';
class EditPage extends GetView<EditController> {
static const String namedRoute = '/tank-edit-page';
const EditPage({super.key});
@override
Widget build(BuildContext context) {
var editCtrl = controller;
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blueGrey,
foregroundColor: Colors.white,
title: Obx(
() => Text(
editCtrl.isNewEntry.value
? 'Neuer Tankeintrag'
: 'Tankeintrag bearbeiten',
),
),
centerTitle: true,
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => editCtrl.gotToList(),
),
),
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.blueGrey[800]!,
Colors.blueGrey[600]!,
Colors.blueGrey[300]!,
Colors.blue[100]!,
],
),
),
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
// Info Card
Obx(
() => Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Icon(
editCtrl.isNewEntry.value
? Icons.add_circle_outline
: Icons.edit,
color: Colors.blueGrey[700],
size: 32,
),
const SizedBox(width: 16),
Expanded(
child: Text(
editCtrl.isNewEntry.value
? 'Erfassen Sie einen neuen Tankeintrag'
: 'Bearbeiten Sie Ihren Tankeintrag',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Colors.blueGrey[900],
),
),
),
],
),
),
),
),
const SizedBox(height: 16),
// Form Card
Card(
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Datum
EditFormFieldWidget(
label: 'Datum',
icon: Icons.calendar_today,
controller: editCtrl.dateController,
isReadOnly: true,
onTap: () => editCtrl.selectDate(context),
required: true,
),
const SizedBox(height: 20),
// Kilometerstand
EditFormFieldWidget(
label: 'Kilometerstand',
icon: Icons.speed,
controller: editCtrl.odometerController,
keyboardType: TextInputType.number,
suffix: 'km',
required: true,
),
const SizedBox(height: 20),
// Liter
EditFormFieldWidget(
label: 'Liter',
icon: Icons.local_gas_station,
controller: editCtrl.litersController,
keyboardType: TextInputType.emailAddress,
suffix: 'L',
required: true,
),
const SizedBox(height: 20),
// Preis pro Liter
EditFormFieldWidget(
label: 'Preis pro Liter',
icon: Icons.euro,
controller: editCtrl.pricePerLiterController,
keyboardType: TextInputType.emailAddress,
suffix: '€/L',
required: true,
),
const SizedBox(height: 20),
// Standort
Obx(
() => editCtrl.isLoadingLocation.value == true
? CircularProgressIndicator()
: EditFormFieldWidget(
label: 'Standort',
icon: Icons.location_on,
controller: editCtrl.locationController,
hint: 'Optional - Tankstellenstandort',
maxLines: 2,
),
),
const SizedBox(height: 24),
// Berechneter Gesamtpreis
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.green[50],
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.green[200]!,
width: 2,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Icon(
Icons.receipt_long,
color: Colors.green[700],
size: 28,
),
const SizedBox(width: 12),
Text(
'Gesamtpreis',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Colors.green[900],
),
),
],
),
Obx(
() => Text(
'${editCtrl.calculatedTotal.value}',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.green[700],
),
),
),
],
),
),
],
),
),
),
const SizedBox(height: 24),
// Speichern Button
Obx(
() => SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: editCtrl.isLoading.value
? null
: () => editCtrl.saveTankEntry(),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blueGrey[700],
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 18),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
disabledBackgroundColor: Colors.grey[400],
),
child: editCtrl.isLoading.value
? const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
color: Colors.white,
),
)
: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(Icons.save),
const SizedBox(width: 8),
Text(
editCtrl.isNewEntry.value
? 'Speichern'
: 'Aktualisieren',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
),
const SizedBox(height: 16),
// Abbrechen Button
SizedBox(
width: double.infinity,
child: OutlinedButton(
onPressed: () => editCtrl.gotToList(),
style: OutlinedButton.styleFrom(
foregroundColor: Colors.white,
side: const BorderSide(color: Colors.white, width: 2),
padding: const EdgeInsets.symmetric(vertical: 18),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: const Text(
'Abbrechen',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
),
),
);
}
}