chore: update flyer import features and resources
- Remove outdated Willys flyer PDF (0001-0008_WIL_V21_ED1pdf.pdf) - Add new Willys flyer PDF (willys_reklamblad.pdf) - Improve offer detection logic in backend flyer-import service - Add offer limit text extraction and sanitization in Flutter UI - Fix Swedish character encoding issues in UI text
This commit is contained in:
@@ -116,6 +116,17 @@ class _FlyerImportTabState extends ConsumerState<FlyerImportTab> {
|
||||
return '$raw kr$unitPart';
|
||||
}
|
||||
|
||||
String _removeLimitTextFromOfferText(String offerText, String? limitText) {
|
||||
final trimmedOffer = offerText.trim();
|
||||
final trimmedLimit = limitText?.trim() ?? '';
|
||||
if (trimmedOffer.isEmpty || trimmedLimit.isEmpty) return trimmedOffer;
|
||||
|
||||
final escaped = RegExp.escape(trimmedLimit);
|
||||
final withoutLimit = trimmedOffer.replaceAll(RegExp(escaped, caseSensitive: false), '').trim();
|
||||
final withoutLeadingPunctuation = withoutLimit.replaceAll(RegExp(r'^[,.;:\s-]+'), '').trim();
|
||||
return withoutLeadingPunctuation.replaceAll(RegExp(r'[,.;:\s-]+$'), '').trim();
|
||||
}
|
||||
|
||||
Widget _buildOfferBadge(FlyerImportItem item, ThemeData theme) {
|
||||
final hasOffer = item.isOffer || (item.offerText?.trim().isNotEmpty ?? false) || item.price != null;
|
||||
if (!hasOffer) return const SizedBox.shrink();
|
||||
@@ -157,7 +168,7 @@ class _FlyerImportTabState extends ConsumerState<FlyerImportTab> {
|
||||
isImage ? Icons.image_outlined : Icons.picture_as_pdf_outlined,
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
title: const Text('Flyerförhandsvisning'),
|
||||
title: const Text('Flyerförhandsvisning'),
|
||||
subtitle: Text(file?.name ?? ''),
|
||||
trailing: isImage
|
||||
? null
|
||||
@@ -170,7 +181,7 @@ class _FlyerImportTabState extends ConsumerState<FlyerImportTab> {
|
||||
if (!context.mounted || opened) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('PDF kan bara öppnas direkt i webbversionen just nu.'),
|
||||
content: Text('PDF kan bara öppnas direkt i webbversionen just nu.'),
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -206,14 +217,14 @@ class _FlyerImportTabState extends ConsumerState<FlyerImportTab> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Ladda upp flyer, granska erbjudanden och planera inköp med ett klick.',
|
||||
'Ladda upp flyer, granska erbjudanden och planera inköp med ett klick.',
|
||||
style: theme.textTheme.bodyMedium,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
OutlinedButton.icon(
|
||||
onPressed: _isLoading ? null : _pickFile,
|
||||
icon: const Icon(Icons.attach_file),
|
||||
label: Text(_pickedFile?.name ?? 'Välj flyerfil'),
|
||||
label: Text(_pickedFile?.name ?? 'Välj flyerfil'),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
FilledButton.icon(
|
||||
@@ -242,7 +253,7 @@ class _FlyerImportTabState extends ConsumerState<FlyerImportTab> {
|
||||
}
|
||||
});
|
||||
},
|
||||
child: Text(selectedCount < items.length ? 'Välj alla' : 'Avmarkera alla'),
|
||||
child: Text(selectedCount < items.length ? 'Välj alla' : 'Avmarkera alla'),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -253,6 +264,9 @@ class _FlyerImportTabState extends ConsumerState<FlyerImportTab> {
|
||||
final priceText = _formatPrice(item.price, item.priceUnit);
|
||||
final comparisonText = _formatPrice(item.comparisonPrice, item.comparisonUnit);
|
||||
final limitText = item.offerLimitText?.trim();
|
||||
final sanitizedOfferText = item.offerText == null
|
||||
? ''
|
||||
: _removeLimitTextFromOfferText(item.offerText!, limitText);
|
||||
|
||||
return CheckboxListTile(
|
||||
value: _selected[index] ?? false,
|
||||
@@ -267,9 +281,16 @@ class _FlyerImportTabState extends ConsumerState<FlyerImportTab> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (priceText.isNotEmpty) Text('Pris: $priceText'),
|
||||
if (comparisonText.isNotEmpty) Text('Jämförpris: $comparisonText'),
|
||||
if (limitText != null && limitText.isNotEmpty) Text('Begränsning: $limitText'),
|
||||
if ((item.offerText?.trim().isNotEmpty ?? false)) Text(item.offerText!.trim()),
|
||||
if (comparisonText.isNotEmpty) Text('Jämförpris: $comparisonText'),
|
||||
if (limitText != null && limitText.isNotEmpty)
|
||||
Text(
|
||||
'Begränsning: $limitText',
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: Colors.orange.shade900,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
if (sanitizedOfferText.isNotEmpty) Text(sanitizedOfferText),
|
||||
if (item.matchedProductName != null) Text('Match: ${item.matchedProductName}'),
|
||||
],
|
||||
),
|
||||
@@ -296,5 +317,4 @@ class _FlyerImportTabState extends ConsumerState<FlyerImportTab> {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user