dashboard overhaul
All checks were successful
Release / meta (push) Successful in 8s
Release / linux-build (push) Successful in 7m15s
Release / android-build (push) Successful in 18m37s
Release / release-master (push) Successful in 23s
Release / release-dev (push) Successful in 26s

This commit is contained in:
2025-12-22 19:39:50 +00:00
parent 7feb672e7e
commit b1a8f7baf4
6 changed files with 659 additions and 283 deletions

View File

@@ -268,6 +268,7 @@ class _TripsPageState extends State<TripsPage> {
isScrollControlled: true,
builder: (_) {
bool renaming = false;
bool deleting = false;
String tripName = trip.name;
return StatefulBuilder(
builder: (sheetCtx, setSheetState) {
@@ -285,6 +286,58 @@ class _TripsPageState extends State<TripsPage> {
}
}
Future<void> handleDelete() async {
if (deleting || trip.legs.isNotEmpty) return;
final ok = await showDialog<bool>(
context: sheetCtx,
builder: (ctx) {
return AlertDialog(
title: const Text('Delete trip?'),
content: Text(
'This will delete "${trip.name}". This cannot be undone.',
),
actions: [
TextButton(
onPressed: () => Navigator.of(ctx).pop(false),
child: const Text('Cancel'),
),
FilledButton(
onPressed: () => Navigator.of(ctx).pop(true),
child: const Text('Delete'),
),
],
);
},
);
if (ok != true) return;
final data = context.read<DataService>();
final api = data.api;
final messenger = ScaffoldMessenger.maybeOf(context);
setSheetState(() => deleting = true);
try {
await api.delete('/trips/delete/${trip.id}');
await Future.wait([
data.fetchTripDetails(),
data.fetchTrips(),
]);
if (context.mounted) {
messenger?.showSnackBar(
SnackBar(content: Text('Deleted "${trip.name}"')),
);
Navigator.of(sheetCtx).pop();
}
} catch (e) {
if (context.mounted) {
messenger?.showSnackBar(
SnackBar(content: Text('Failed to delete trip: $e')),
);
}
} finally {
if (mounted) setSheetState(() => deleting = false);
}
}
return SafeArea(
child: Padding(
padding: const EdgeInsets.all(16.0),
@@ -317,6 +370,21 @@ class _TripsPageState extends State<TripsPage> {
tooltip: 'Rename trip',
onPressed: renaming ? null : handleRename,
),
if (trip.legs.isEmpty) ...[
const SizedBox(width: 4),
IconButton(
icon: deleting
? const SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(strokeWidth: 2),
)
: const Icon(Icons.delete_outline),
tooltip: 'Delete trip',
onPressed: deleting ? null : handleDelete,
color: Theme.of(context).colorScheme.error,
),
],
const SizedBox(width: 4),
Text('${trip.mileage.toStringAsFixed(1)} mi'),
],