ionic-planb-logistic-app-fl.../lib/components/notes_dialog.dart
Mathias Beaulieu-Duncan bcc938fde1 auto-claude: subtask-2-2 - Create NotesDialog component for displaying delivery notes
- Add reusable NotesDialog component that extracts and displays notes from delivery orders
- Add static show() method for convenient dialog display with empty notes handling
- Add localization strings for notes dialog (EN/FR): notesTitle, noNotesMessage, close
- Follow existing dialog pattern from NavigationTermsAndConditionsDialog

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-20 11:28:31 -05:00

105 lines
3.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:planb_logistic/l10n/app_localizations.dart';
import '../models/delivery.dart';
/// A dialog component for displaying delivery notes.
///
/// This dialog extracts and displays all non-empty notes from the
/// orders associated with a delivery.
class NotesDialog extends StatelessWidget {
/// The delivery whose notes should be displayed.
final Delivery delivery;
const NotesDialog({
super.key,
required this.delivery,
});
/// Extracts non-empty notes from the delivery's orders.
List<String> _extractNotes() {
return delivery.orders
.where((order) => order.note != null && order.note!.isNotEmpty)
.map((order) => order.note!)
.toList();
}
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context);
final colorScheme = Theme.of(context).colorScheme;
final notes = _extractNotes();
return AlertDialog(
title: Text(
l10n.notesTitle(delivery.name),
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
color: colorScheme.onSurface,
),
),
content: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: notes
.map(
(note) => Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: Text(
note,
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: colorScheme.onSurface,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
)
.toList(),
),
),
actionsAlignment: MainAxisAlignment.center,
actionsPadding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
actions: [
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () => Navigator.of(context).pop(),
child: Text(
l10n.close,
style: TextStyle(color: colorScheme.onPrimary),
),
),
),
],
);
}
/// Shows the notes dialog for a delivery.
///
/// Returns `true` if the dialog was shown (i.e., the delivery has notes),
/// `false` otherwise.
///
/// If the delivery has no notes, this method returns `false` without
/// showing the dialog. The caller is responsible for handling this case,
/// typically by showing an info message.
static Future<bool> show(BuildContext context, Delivery delivery) async {
final notes = delivery.orders
.where((order) => order.note != null && order.note!.isNotEmpty)
.map((order) => order.note!)
.toList();
if (notes.isEmpty) {
return false;
}
await showDialog<void>(
context: context,
builder: (BuildContext dialogContext) {
return NotesDialog(delivery: delivery);
},
);
return true;
}
}