import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:notas/models/note.dart'; // NoteEditorScreen: unified UI for creating and editing notes. // - Use `NoteEditorScreen.showDialog(context, note: existing)` to edit. // - Use `NoteEditorScreen.showDialog(context)` to create a new note. // The screen returns either a `Note` (saved) or the string `'delete'` when // the user confirmed deletion. `null` indicates the user closed without saving. class NoteEditorScreen extends StatefulWidget { const NoteEditorScreen({super.key, required this.note}); final Note? note; @override State createState() => _NoteEditorScreenState(); static Future showDialog(BuildContext context, {Note? note}) { return showGeneralDialog( context: context, barrierDismissible: false, barrierColor: Colors.transparent, transitionDuration: const Duration(milliseconds: 200), pageBuilder: (context, animation, secondaryAnimation) { return NoteEditorScreen(note: note); }, transitionBuilder: (context, animation, secondaryAnimation, child) { return ScaleTransition(scale: animation, child: child); }, ); } } class _NoteEditorScreenState extends State { late TextEditingController _titleController; late TextEditingController _bodyController; late Note _currentNote; late bool _isNewNote; @override void initState() { super.initState(); _isNewNote = widget.note?.id == null; if (_isNewNote) { final DateTime now = DateTime.now(); _currentNote = Note( title: '', body: '', createdAt: now, updatedAt: now, index: 0, ); } else { _currentNote = widget.note!; } _titleController = TextEditingController(text: _currentNote.title); _bodyController = TextEditingController(text: _currentNote.body); } @override void dispose() { _titleController.dispose(); _bodyController.dispose(); super.dispose(); } void _closeWithoutSaving() { Navigator.of(context).pop(); } void _saveNote() { final String title = _titleController.text.trim(); final String body = _bodyController.text.trim(); if (title.isEmpty && body.isEmpty) { Navigator.of(context).pop(); return; } final Note updatedNote = _currentNote.copyWith( title: title.isEmpty ? 'Sin título' : title, body: body, updatedAt: DateTime.now(), ); Navigator.of(context).pop(updatedNote); } void _deleteNote() { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( backgroundColor: const Color(0xFF303134), title: const Text( 'Eliminar nota', style: TextStyle(color: Colors.white), ), content: const Text( '¿Estás seguro de que deseas eliminar esta nota?', style: TextStyle(color: Colors.white70), ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text( 'Cancelar', style: TextStyle(color: Colors.white70), ), ), TextButton( onPressed: () { Navigator.of(context).pop(); Navigator.of(context).pop('delete'); }, child: const Text( 'Eliminar', style: TextStyle(color: Colors.red), ), ), ], ); }, ); } String _formatDate(DateTime date) { final DateTime now = DateTime.now(); final DateTime today = DateTime(now.year, now.month, now.day); final DateTime yesterday = today.subtract(const Duration(days: 1)); final DateTime noteDate = DateTime(date.year, date.month, date.day); if (noteDate == today) { return 'Hoy ${DateFormat('HH:mm').format(date)}'; } else if (noteDate == yesterday) { return 'Ayer ${DateFormat('HH:mm').format(date)}'; } else { return DateFormat('dd/MM/yyyy HH:mm').format(date); } } @override Widget build(BuildContext context) { return Material( color: Colors.transparent, child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { final double maxWidth = math.min(600, constraints.maxWidth - 48); final double maxHeight = math.min(constraints.maxHeight * 0.88, 720); final double overlayTop = MediaQuery.paddingOf(context).top + 32; return Stack( children: [ Positioned.fill( top: overlayTop, child: Container( color: const Color.fromARGB(127, 0, 0, 0).withValues(alpha: 0.5), ), ), SafeArea( child: Center( child: Padding( padding: EdgeInsets.only(top: overlayTop), child: ConstrainedBox( constraints: BoxConstraints( maxWidth: maxWidth, maxHeight: maxHeight, ), child: Container( decoration: BoxDecoration( color: const Color.fromRGBO(24, 25, 26, 1), borderRadius: BorderRadius.circular(16), border: Border.all(color: Colors.white24, width: 1), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.5), blurRadius: 24, offset: const Offset(0, 8), ), ], ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( border: Border( bottom: BorderSide(color: Colors.white12, width: 1), ), ), child: Row( children: [ IconButton( onPressed: _closeWithoutSaving, icon: const Icon(Icons.close, color: Colors.white70), tooltip: 'Cerrar sin guardar', ), const SizedBox(width: 8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( 'Creado: ${_formatDate(_currentNote.createdAt)}', style: const TextStyle(color: Colors.white54, fontSize: 12), ), if (_currentNote.updatedAt != _currentNote.createdAt) Text( 'Modificado: ${_formatDate(_currentNote.updatedAt)}', style: const TextStyle(color: Colors.white54, fontSize: 12), ), ], ), ), ], ), ), Expanded( child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextField( controller: _titleController, style: const TextStyle( color: Colors.white, fontSize: 28, fontWeight: FontWeight.bold, ), decoration: const InputDecoration( hintText: 'Título', hintStyle: TextStyle(color: Colors.white30), border: InputBorder.none, contentPadding: EdgeInsets.zero, ), ), const SizedBox(height: 16), TextField( controller: _bodyController, maxLines: null, style: const TextStyle( color: Colors.white, fontSize: 16, height: 1.6, ), decoration: const InputDecoration( hintText: 'Escribe tu nota...', hintStyle: TextStyle(color: Colors.white30), border: InputBorder.none, contentPadding: EdgeInsets.zero, ), ), ], ), ), ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), decoration: BoxDecoration( border: Border( top: BorderSide(color: Colors.white12, width: 1), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (!_isNewNote) IconButton( onPressed: _deleteNote, icon: const Icon(Icons.delete_outline, color: Colors.red), tooltip: 'Eliminar nota', ) else const SizedBox(width: 48), FilledButton( onPressed: _saveNote, child: const Text('Guardar'), ), ], ), ), ], ), ), ), ), ), ), ], ); }, ), ); } }