# Implementeringsplan: "Se kvitto"-Modal för Kvittoimporten

**Mål**: MVP-vägen för split-view UX – lägg till modal som visar OCR-text från parsade kvittoraderna.
**Scope**: 2-3 timmar
**Status**: Planering

---

## 1. Ändringar i `receipt_import_tab.dart`

### 1.1 Lägg till knapp "Se kvitto" i header-raden (rad ~745-752)

**Plats**: Höger om "Välj alla/Avmarkera alla"-knappen

```dart
// Innan: Row med bara "Välj alla"-knapp
Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: [
    Text('${items.length} rader — tryck för att redigera', style: theme.textTheme.titleSmall),
    TextButton(...), // "Välj alla/Avmarkera alla"
  ],
)

// Efter: Lägg till "Se kvitto"-knapp
Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: [
    Text('${items.length} rader — tryck för att redigera', style: theme.textTheme.titleSmall),
    Row(
      children: [
        TextButton.icon(
          onPressed: items.isEmpty ? null : () => _showReceiptPreview(context, items),
          icon: const Icon(Icons.description_outlined),
          label: const Text('Se kvitto'),
        ),
        const SizedBox(width: 8),
        TextButton(
          onPressed: () => setState(...), // Befintlig "Välj alla"
          child: Text(...),
        ),
      ],
    ),
  ],
)
```

### 1.2 Implementera `_showReceiptPreview`-metod

Lägg till denna metod i `_ReceiptImportTabState`:

```dart
Future<void> _showReceiptPreview(BuildContext context, List<ParsedReceiptItem> items) async {
  if (!context.mounted) return;
  await showDialog(
    context: context,
    builder: (ctx) => _ReceiptPreviewDialog(items: items),
  );
}
```

---

## 2. Ny widget: `_ReceiptPreviewDialog`

Lägg till denna widget **i samma fil** (`receipt_import_tab.dart`), efter `_ReceiptImportResultRow`-klassen:

```dart
class _ReceiptPreviewDialog extends StatelessWidget {
  final List<ParsedReceiptItem> items;

  const _ReceiptPreviewDialog({required this.items});

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    
    return AlertDialog(
      title: const Text('Kvittotexten i sin helhet'),
      content: SizedBox(
        width: 600, // Responsiv bredd på desktop
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(
                'Här visas all OCR-parsad text från kvittot. En rad per artikel:',
                style: theme.textTheme.bodySmall?.copyWith(
                  color: theme.colorScheme.onSurfaceVariant,
                ),
              ),
              const SizedBox(height: 12),
              Container(
                decoration: BoxDecoration(
                  color: theme.colorScheme.surfaceContainerLowest,
                  border: Border.all(color: theme.colorScheme.outlineVariant),
                  borderRadius: BorderRadius.circular(8),
                ),
                padding: const EdgeInsets.all(12),
                child: SelectableText.rich(
                  TextSpan(
                    children: items.isEmpty
                        ? [TextSpan(text: '(Inga rader)', style: theme.textTheme.bodySmall)]
                        : items
                            .asMap()
                            .entries
                            .map((entry) {
                              final item = entry.value;
                              final lineNumber = entry.key + 1;
                              final lineText = _formatReceiptLine(item);
                              return TextSpan(
                                children: [
                                  TextSpan(
                                    text: '$lineNumber. ',
                                    style: theme.textTheme.labelSmall?.copyWith(
                                      color: theme.colorScheme.outlineVariant,
                                    ),
                                  ),
                                  TextSpan(
                                    text: lineText,
                                    style: theme.textTheme.bodySmall?.copyWith(
                                      fontFamily: 'monospace',
                                    ),
                                  ),
                                  const TextSpan(text: '\n'),
                                ],
                              );
                            })
                            .toList(),
                  ),
                  style: theme.textTheme.bodySmall,
                ),
              ),
            ],
          ),
        ),
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('Stäng'),
        ),
      ],
    );
  }

  String _formatReceiptLine(ParsedReceiptItem item) {
    final parts = <String>[];
    
    if (item.quantity != null) {
      parts.add('${item.quantity}');
    }
    
    if (item.unit != null) {
      parts.add(item.unit!);
    }
    
    parts.add(item.rawName);
    
    if (item.price != null) {
      parts.add('— ${item.price} kr');
    }
    
    return parts.join(' ');
  }
}
```

---

## 3. Implementeringssteg (steg-för-steg)

1. **Läs receipt_import_tab.dart** och identifiera raden med "Välj alla/Avmarkera alla"-knappen
2. **Refaktorera Row**: Lägg "Se kvitto"-knapp bredvid befintliga knapp
3. **Lägg till `_showReceiptPreview()`-metod** i `_ReceiptImportTabState`
4. **Implementera `_ReceiptPreviewDialog`-widget** på slutet av filen
5. **Testa**:
   - Ladda ett kvitto
   - Klicka "Se kvitto"-knappen
   - Verifiera att texten är lesbar och formaterad
   - Testa responsive bredd (dialog behöver minska på mobil)

---

## 4. Responsiv förbättring (optional)

Om dialogen behöver anpassas för mobil:

```dart
// I _ReceiptPreviewDialog.build():
final isWide = MediaQuery.of(context).size.width > 600;

return Dialog(
  insetPadding: const EdgeInsets.all(16),
  child: SizedBox(
    width: isWide ? 600 : double.maxFinite, // Full bredd på mobil
    // ...
  ),
);
```

---

## 5. Långsiktiga förbättringar (Phase 2)

Se `next_steps_flutter.md` för split-view roadmap:
- Horisontell split-view på desktop
- Scroll-synkronisering
- Tab-fallback på mobil
- AI-guiding labels

---

## Ärendemal

**Titel**: "Se kvitto"-modal för kvittoimporten  
**Branch**: `feat/receipt-preview-modal`  
**Labels**: `enhancement`, `import-ux`, `phase-1-mvp`  
**Estimate**: 2-3h

## 2026-05-10: Admin-inventarie (CRUD, merge, filter, sortering, preview, säkerhet), user-scope, IDOR-skydd, säkerhetshärdning, optimeringar och utökad testtäckning är nu genomförda och dokumenterade i README, TEKNISK_BESKRIVNING, SÄKERHETSHÄRDNINGSPLAN och SESSIONLOGGAR.

## 2026-05-10: Admin-inventarie (CRUD, merge, filter, sortering, preview, säkerhet), user-scope, IDOR-skydd, säkerhetshärdning, optimeringar och utökad testtäckning är nu genomförda och dokumenterade i README, TEKNISK_BESKRIVNING, SÄKERHETSHÄRDNINGSPLAN och SESSIONLOGGAR.

## 2026-05-10: Admin-inventarie (CRUD, merge, filter, sortering, preview, säkerhet), user-scope, IDOR-skydd, säkerhetshärdning, optimeringar och utökad testtäckning är nu genomförda och dokumenterade i README, TEKNISK_BESKRIVNING, SÄKERHETSHÄRDNINGSPLAN och SESSIONLOGGAR.

## 2026-05-10: Admin-inventarie (CRUD, merge, filter, sortering, preview, säkerhet), user-scope, IDOR-skydd, säkerhetshärdning, optimeringar och utökad testtäckning är nu genomförda och dokumenterade i README, TEKNISK_BESKRIVNING, SÄKERHETSHÄRDNINGSPLAN och SESSIONLOGGAR.

## 2026-05-10: Admin-inventarie (CRUD, merge, filter, sortering, preview, säkerhet), user-scope, IDOR-skydd, säkerhetshärdning, optimeringar och utökad testtäckning är nu genomförda och dokumenterade i README, TEKNISK_BESKRIVNING, SÄKERHETSHÄRDNINGSPLAN och SESSIONLOGGAR.

## 2026-05-10: Admin-inventarie (CRUD, merge, filter, sortering, preview, säkerhet), user-scope, IDOR-skydd, säkerhetshärdning, optimeringar och utökad testtäckning är nu genomförda och dokumenterade i README, TEKNISK_BESKRIVNING, SÄKERHETSHÄRDNINGSPLAN och SESSIONLOGGAR.

## 2026-05-10: Admin-inventarie (CRUD, merge, filter, sortering, preview, säkerhet), user-scope, IDOR-skydd, säkerhetshärdning, optimeringar och utökad testtäckning är nu genomförda och dokumenterade i README, TEKNISK_BESKRIVNING, SÄKERHETSHÄRDNINGSPLAN och SESSIONLOGGAR.

## 2026-05-10: Admin-inventarie (CRUD, merge, filter, sortering, preview, säkerhet), user-scope, IDOR-skydd, säkerhetshärdning, optimeringar och utökad testtäckning är nu genomförda och dokumenterade i README, TEKNISK_BESKRIVNING, SÄKERHETSHÄRDNINGSPLAN och SESSIONLOGGAR.
