import 'package:flutter/material.dart'; import 'package:notas/models/category.dart'; class MenuDrawer extends StatelessWidget { const MenuDrawer({ super.key, this.onMenuItemTapped, this.selectedItem, this.categories = const [], this.onCreateCategory, this.onEditCategory, }); final ValueChanged? onMenuItemTapped; final String? selectedItem; final List categories; final VoidCallback? onCreateCategory; final ValueChanged? onEditCategory; @override Widget build(BuildContext context) { return Container( decoration: const BoxDecoration( color: Color.fromARGB(255, 30, 31, 35), border: Border( right: BorderSide(color: Colors.white12, width: 0.5), ), ), child: Column( children: [ const SizedBox(height: 8), _MenuItemTile( icon: Icons.note, label: 'Todas mis notas', selected: selectedItem == 'all_notes', onTap: () => onMenuItemTapped?.call('all_notes'), ), Expanded( child: SingleChildScrollView( child: Column( children: [ if (categories.isNotEmpty) Padding( padding: const EdgeInsets.only(top: 8.0), child: Column( children: categories.map((category) { final categoryId = 'category_${category.id}'; final IconData categoryIcon = _iconForCodePoint( category.iconCodePoint, ); return _MenuItemTile( icon: categoryIcon, label: category.name, selected: selectedItem == categoryId, onTap: () => onMenuItemTapped?.call(categoryId), iconColor: Color(category.colorValue ?? 0xFFFFC107), textColor: Color(category.colorValue ?? 0xFFFFC107), trailing: selectedItem == categoryId ? IconButton( icon: const Icon( Icons.more_vert, color: Colors.white70, ), onPressed: () => onEditCategory?.call(category), ) : null, ); }).toList(), ), ), _MenuItemTile( icon: Icons.add_circle_outline, label: 'Crear categoría', onTap: onCreateCategory, ), ], ), ), ), _MenuItemTile( icon: Icons.delete_outline, label: 'Mis notas borradas', selected: selectedItem == 'deleted_notes', onTap: () => onMenuItemTapped?.call('deleted_notes'), iconColor: Colors.redAccent, textColor: Colors.redAccent, ), const Divider(color: Colors.white12, height: 16), _MenuItemTile( icon: Icons.settings, label: 'Configuración', onTap: () => onMenuItemTapped?.call('settings'), ), const SizedBox(height: 6), ], ), ); } } IconData _iconForCodePoint(int? codePoint) { if (codePoint == null) { return Icons.folder_outlined; } const List icons = [ Icons.folder, Icons.work, Icons.star, Icons.home, Icons.school, Icons.book, Icons.music_note, Icons.lightbulb, ]; for (final IconData icon in icons) { if (icon.codePoint == codePoint) { return icon; } } return Icons.folder_outlined; } class _MenuItemTile extends StatefulWidget { const _MenuItemTile({ required this.icon, required this.label, this.selected = false, this.onTap, this.iconColor, this.textColor, this.trailing, }); final IconData icon; final String label; final bool selected; final VoidCallback? onTap; final Color? iconColor; final Color? textColor; final Widget? trailing; @override State<_MenuItemTile> createState() => _MenuItemTileState(); } class _MenuItemTileState extends State<_MenuItemTile> { bool _hovering = false; @override Widget build(BuildContext context) { final bool active = widget.selected || _hovering; final Color backgroundColor = active ? Colors.white.withValues(alpha: 0.10) : Colors.transparent; final Color foregroundColor = active ? Colors.white : Colors.white70; return MouseRegion( onEnter: (_) { setState(() => _hovering = true); }, onExit: (_) { setState(() => _hovering = false); }, child: AnimatedContainer( duration: const Duration(milliseconds: 180), curve: Curves.easeOutCubic, margin: const EdgeInsets.only( right: 8, top: 2, bottom: 2, ), child: Material( color: backgroundColor, borderRadius: const BorderRadius.only( topRight: Radius.circular(999), bottomRight: Radius.circular(999), ), clipBehavior: Clip.antiAlias, child: ListTile( leading: Icon(widget.icon, color: widget.iconColor ?? foregroundColor), trailing: widget.trailing, title: Text( widget.label, style: TextStyle(color: widget.textColor ?? foregroundColor, fontSize: 14), ), onTap: widget.onTap, ), ), ), ); } }