import 'package:flutter/material.dart'; void main() { runApp(const SupermarketCalcApp()); } class SupermarketCalcApp extends StatelessWidget { const SupermarketCalcApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Calc Margen', debugShowCheckedModeBanner: false, // Configuración Material You (M3) theme: ThemeData( useMaterial3: true, colorScheme: ColorScheme.fromSeed( seedColor: Colors.red, brightness: Brightness.light, ), ), home: const HomePage(), ); } } class HomePage extends StatefulWidget { const HomePage({super.key}); @override State createState() => _HomePageState(); } class _HomePageState extends State { final _costController = TextEditingController(text: "1.50"); final _marginController = TextEditingController(text: "40"); double _exactPrice = 2.10; double _profit = 0.60; String _suggestedPrice = "2.50 €"; @override void initState() { super.initState(); _calculate(); } void _calculate() { final double cost = double.tryParse(_costController.text) ?? 0; final double marginPercent = double.tryParse(_marginController.text) ?? 0; if (cost <= 0 || marginPercent <= 0) { setState(() { _suggestedPrice = "---"; }); return; } _profit = cost * (marginPercent / 100); _exactPrice = cost + _profit; // Lógica de Redondeo Psicológico (.50, .95, .99) int floorPrice = _exactPrice.floor(); double finalVal; if (_exactPrice <= 1) { finalVal = (_exactPrice < 0.50) ? 0.99 : (_exactPrice.ceil() - 0.01); } else { if (_exactPrice <= floorPrice + 0.50) { finalVal = floorPrice + 0.50; } else if (_exactPrice <= floorPrice + 0.95) { finalVal = floorPrice + 0.95; } else { finalVal = floorPrice + 0.99; } if (finalVal < _exactPrice) { finalVal = _exactPrice.ceil() + 0.99; } } setState(() { _suggestedPrice = "${finalVal.toStringAsFixed(2)} €"; }); } @override Widget build(BuildContext context) { final colors = Theme.of(context).colorScheme; return Scaffold( backgroundColor: colors.surface, appBar: AppBar( title: const Text("Calculadora de Margen"), centerTitle: true, backgroundColor: colors.surface, elevation: 0, ), body: SingleChildScrollView( padding: const EdgeInsets.all(24.0), child: Column( children: [ // Card de entrada de datos Card( elevation: 0, color: colors.surfaceContainerHighest.withOpacity(0.3), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)), child: Padding( padding: const EdgeInsets.all(20.0), child: Column( children: [ TextField( controller: _costController, keyboardType: const TextInputType.numberWithOptions(decimal: true), onChanged: (_) => _calculate(), decoration: InputDecoration( labelText: "Costo Base", prefixText: "€ ", border: OutlineInputBorder(borderRadius: BorderRadius.circular(16)), filled: true, fillColor: colors.surface, ), ), const SizedBox(height: 16), TextField( controller: _marginController, keyboardType: TextInputType.number, onChanged: (_) => _calculate(), decoration: InputDecoration( labelText: "Margen Deseado", suffixText: "%", border: OutlineInputBorder(borderRadius: BorderRadius.circular(16)), filled: true, fillColor: colors.surface, ), ), ], ), ), ), const SizedBox(height: 24), // Resultados Intermedios Row( children: [ _buildInfoTile("Precio Exacto", "${_exactPrice.toStringAsFixed(2)} €", colors), const SizedBox(width: 12), _buildInfoTile("Ganancia", "${_profit.toStringAsFixed(2)} €", colors), ], ), const SizedBox(height: 24), // Card de Resultado Final (Material You Hero) Container( width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 32, horizontal: 16), decoration: BoxDecoration( color: colors.primaryContainer, borderRadius: BorderRadius.circular(28), ), child: Column( children: [ Text( "PRECIO SUGERIDO", style: TextStyle( color: colors.onPrimaryContainer, fontWeight: FontWeight.w900, letterSpacing: 1.2, ), ), const SizedBox(height: 8), Text( _suggestedPrice, style: TextStyle( fontSize: 56, fontWeight: FontWeight.bold, color: colors.onPrimaryContainer, ), ), Icon(Icons.auto_awesome, color: colors.primary, size: 30), ], ), ), ], ), ), ); } Widget _buildInfoTile(String label, String value, ColorScheme colors) { return Expanded( child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( border: Border.all(color: colors.outlineVariant), borderRadius: BorderRadius.circular(20), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(label, style: TextStyle(fontSize: 12, color: colors.secondary)), Text(value, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), ], ), ), ); } }