Agrega PRIVACY.md, actualiza AGENTS.md

This commit is contained in:
Super User
2026-06-14 15:34:53 -04:00
parent 9ac9e9e953
commit 0df1bf90cf
20 changed files with 685 additions and 166 deletions

View File

@@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:intl/intl.dart';
import 'package:table_calendar/table_calendar.dart';
import '../providers/factura_provider.dart';
import '../providers/servicio_provider.dart';
import '../providers/configuracion_provider.dart';
import '../utils/currency_utils.dart';
class CalendarioScreen extends StatefulWidget {
const CalendarioScreen({super.key});
@@ -54,7 +54,7 @@ class _CalendarioScreenState extends State<CalendarioScreen> {
context.watch<FacturaProvider>();
context.watch<ServicioProvider>();
final configProv = context.watch<ConfiguracionProvider>();
final symbol = configProv.config?.moneda == 'USD' ? '\$' : configProv.config?.moneda == 'EUR' ? '' : 'MX\$';
final moneda = configProv.config?.moneda ?? 'USD';
return Scaffold(
appBar: AppBar(title: const Text('Calendario de pagos')),
@@ -103,17 +103,41 @@ class _CalendarioScreenState extends State<CalendarioScreen> {
Expanded(
child: _selectedDay == null || (_eventos[DateTime(_selectedDay!.year, _selectedDay!.month, _selectedDay!.day)]?.isEmpty ?? true)
? Center(child: Text('Sin facturas en esta fecha', style: Theme.of(context).textTheme.bodyLarge))
: ListView(
children: (_eventos[DateTime(_selectedDay!.year, _selectedDay!.month, _selectedDay!.day)] ?? []).map((e) {
return Card(
child: ListTile(
leading: CircleAvatar(backgroundColor: e['color'] as Color, child: Text((e['servicio'] as String).substring(0, 2).toUpperCase(), style: const TextStyle(color: Colors.white, fontSize: 12))),
title: Text(e['servicio'] as String),
subtitle: Text('$symbol${NumberFormat('#,##0.00').format(e['monto'])}'),
trailing: Chip(label: Text(e['estado'] as String, style: TextStyle(fontSize: 12, color: e['estado'] == 'Pagada' ? Colors.green : Colors.orange))),
: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 16),
itemCount: (_eventos[DateTime(_selectedDay!.year, _selectedDay!.month, _selectedDay!.day)] ?? []).length,
itemBuilder: (_, i) {
final e = _eventos[DateTime(_selectedDay!.year, _selectedDay!.month, _selectedDay!.day)]![i];
final esPagada = e['estado'] == 'Pagada';
return TweenAnimationBuilder<double>(
tween: Tween(begin: 0, end: 1),
duration: Duration(milliseconds: 250 + i * 80),
curve: Curves.easeOutCubic,
builder: (context, value, child) {
return Opacity(
opacity: value,
child: Transform.translate(
offset: Offset(0, 16 * (1 - value)),
child: child,
),
);
},
child: Card(
margin: const EdgeInsets.only(bottom: 8),
child: ListTile(
leading: CircleAvatar(backgroundColor: e['color'] as Color, child: Text((e['servicio'] as String).substring(0, 2).toUpperCase(), style: const TextStyle(color: Colors.white, fontSize: 12))),
title: Text(e['servicio'] as String, style: const TextStyle(fontWeight: FontWeight.w500)),
subtitle: Text(CurrencyUtils.formatPrice((e['monto'] as num).toDouble(), moneda)),
trailing: Chip(
label: Text(e['estado'] as String, style: TextStyle(fontSize: 12, color: esPagada ? Colors.green : Colors.orange)),
backgroundColor: esPagada ? Colors.green.withValues(alpha: 0.12) : Colors.orange.withValues(alpha: 0.12),
side: BorderSide.none,
padding: const EdgeInsets.symmetric(horizontal: 4),
),
),
),
);
}).toList(),
},
),
),
],