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