feat: riscrivi app in Flutter

Riscrittura completa da Vue 3 + Capacitor a Flutter/Dart.

Architettura feature-based (lib/features/):
- meal_planner: modello MealPlan/DayPlan, provider, pagina e widget
- converter: modello ConversionEntry, provider con ricerca, pagina
- shopping_list: modello ShoppingItem, provider con deduplicazione, pagina e widget

Core:
- Material 3 con seed color #2d6a4f
- NavigationBar + IndexedStack (preserva stato dei tab)
- Portrait lock via SystemChrome
- Persistenza con shared_preferences
- 50+ alimenti × metodi cottura in assets/data/conversions.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-16 17:41:26 +02:00
parent d49b31f21d
commit eb7912421c
20 changed files with 1656 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
class EmptyState extends StatelessWidget {
final IconData icon;
final String title;
final String? subtitle;
const EmptyState({
super.key,
required this.icon,
required this.title,
this.subtitle,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final muted = theme.colorScheme.onSurface.withValues(alpha: 0.4);
return Center(
child: Padding(
padding: const EdgeInsets.all(40),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(icon, size: 48, color: muted),
const SizedBox(height: 16),
Text(
title,
style: theme.textTheme.bodyLarge?.copyWith(color: muted),
textAlign: TextAlign.center,
),
if (subtitle != null) ...[
const SizedBox(height: 6),
Text(
subtitle!,
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurface.withValues(alpha: 0.3),
),
textAlign: TextAlign.center,
),
],
],
),
),
);
}
}