feat: Add category deletion functionality and enhance category dialog for editing
This commit is contained in:
@@ -85,6 +85,10 @@ class NoteRepository {
|
||||
debugPrint('Category inserted to database');
|
||||
}
|
||||
|
||||
Future<void> deleteCategory(String id) async {
|
||||
await _database.deleteCategory(id);
|
||||
}
|
||||
|
||||
Future<Note> createNote(Note note) async {
|
||||
await _database.insertNoteAtTop(
|
||||
NotesCompanion.insert(
|
||||
|
||||
@@ -291,9 +291,11 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _showCreateCategoryDialog() async {
|
||||
final TextEditingController controller = TextEditingController();
|
||||
Color? selectedColor;
|
||||
Future<void> _showCreateCategoryDialog([Category? category]) async {
|
||||
final TextEditingController controller = TextEditingController(text: category?.name ?? '');
|
||||
Color? selectedColor = category != null && category.colorValue != null
|
||||
? Color(category.colorValue!)
|
||||
: null;
|
||||
IconData? selectedIcon;
|
||||
|
||||
final List<Color> palette = [
|
||||
@@ -318,13 +320,20 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
Icons.lightbulb,
|
||||
];
|
||||
|
||||
if (category != null && category.iconCodePoint != null) {
|
||||
selectedIcon = icons.firstWhere(
|
||||
(i) => i.codePoint == category.iconCodePoint,
|
||||
orElse: () => icons.first,
|
||||
);
|
||||
}
|
||||
|
||||
final bool? result = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return StatefulBuilder(
|
||||
builder: (BuildContext ctx, StateSetter setState) {
|
||||
return AlertDialog(
|
||||
title: const Text('Crear categoría'),
|
||||
title: Text(category == null ? 'Crear categoría' : 'Editar categoría'),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -406,13 +415,46 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
if (category != null)
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
final bool? confirm = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Borrar categoría'),
|
||||
content: const Text('¿Seguro que quieres borrar esta categoría?'),
|
||||
actions: [
|
||||
TextButton(onPressed: () => Navigator.pop(context, false), child: const Text('Cancelar')),
|
||||
TextButton(onPressed: () => Navigator.pop(context, true), child: const Text('Borrar')),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
if (confirm == true) {
|
||||
try {
|
||||
await widget.repository.deleteCategory(category.id);
|
||||
await _loadCategories();
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Categoría borrada')));
|
||||
}
|
||||
try {
|
||||
await widget.onRequestSync();
|
||||
} catch (_) {}
|
||||
} catch (e) {
|
||||
if (mounted) ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Error al borrar categoría: $e')));
|
||||
}
|
||||
Navigator.pop(context, false);
|
||||
}
|
||||
},
|
||||
child: const Text('Borrar', style: TextStyle(color: Colors.red)),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, false),
|
||||
child: const Text('Cancelar'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context, true),
|
||||
child: const Text('Crear'),
|
||||
child: Text(category == null ? 'Crear' : 'Guardar'),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -428,19 +470,20 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
|
||||
try {
|
||||
final Category newCategory = Category(
|
||||
id: category?.id,
|
||||
name: controller.text.trim(),
|
||||
updatedAt: DateTime.now(),
|
||||
colorValue: selectedColor?.toARGB32(),
|
||||
iconCodePoint: selectedIcon?.codePoint,
|
||||
);
|
||||
debugPrint('Creating category: ${newCategory.name}, color: ${newCategory.colorValue}, icon: ${newCategory.iconCodePoint}');
|
||||
if (category == null) {
|
||||
debugPrint('Creating category: ${newCategory.name}, color: ${newCategory.colorValue}, icon: ${newCategory.iconCodePoint}');
|
||||
} else {
|
||||
debugPrint('Updating category: ${newCategory.name}, color: ${newCategory.colorValue}, icon: ${newCategory.iconCodePoint}');
|
||||
}
|
||||
await widget.repository.createCategory(newCategory);
|
||||
await _loadCategories();
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(const SnackBar(content: Text('Categoría creada')));
|
||||
}
|
||||
|
||||
try {
|
||||
await widget.onRequestSync();
|
||||
} catch (_) {}
|
||||
@@ -876,6 +919,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||
? 'deleted_notes'
|
||||
: 'all_notes'),
|
||||
categories: _categories,
|
||||
onEditCategory: (Category c) => _showCreateCategoryDialog(c),
|
||||
onCreateCategory: _showCreateCategoryDialog,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -8,12 +8,14 @@ class MenuDrawer extends StatelessWidget {
|
||||
this.selectedItem,
|
||||
this.categories = const [],
|
||||
this.onCreateCategory,
|
||||
this.onEditCategory,
|
||||
});
|
||||
|
||||
final ValueChanged<String>? onMenuItemTapped;
|
||||
final String? selectedItem;
|
||||
final List<Category> categories;
|
||||
final VoidCallback? onCreateCategory;
|
||||
final ValueChanged<Category>? onEditCategory;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -57,6 +59,15 @@ class MenuDrawer extends StatelessWidget {
|
||||
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(),
|
||||
),
|
||||
@@ -99,6 +110,7 @@ class _MenuItemTile extends StatelessWidget {
|
||||
this.onTap,
|
||||
this.iconColor,
|
||||
this.textColor,
|
||||
this.trailing,
|
||||
});
|
||||
|
||||
final IconData icon;
|
||||
@@ -107,6 +119,7 @@ class _MenuItemTile extends StatelessWidget {
|
||||
final VoidCallback? onTap;
|
||||
final Color? iconColor;
|
||||
final Color? textColor;
|
||||
final Widget? trailing;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -134,6 +147,7 @@ class _MenuItemTile extends StatelessWidget {
|
||||
),
|
||||
child: ListTile(
|
||||
leading: Icon(icon, color: iconColor ?? foregroundColor),
|
||||
trailing: trailing,
|
||||
title: Text(
|
||||
label,
|
||||
style: TextStyle(color: textColor ?? foregroundColor, fontSize: 14),
|
||||
|
||||
Reference in New Issue
Block a user