142 lines
4.3 KiB
Dart
142 lines
4.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import '../models/todo.dart';
|
|
import '../models/tag.dart';
|
|
import '../database/todo_database.dart';
|
|
import 'views/todo_list_view.dart';
|
|
import 'views/calendar_view.dart';
|
|
import 'views/stats_view.dart';
|
|
|
|
class HomePage extends StatefulWidget {
|
|
const HomePage({super.key});
|
|
|
|
@override
|
|
State<HomePage> createState() => _HomePageState();
|
|
}
|
|
|
|
class _HomePageState extends State<HomePage> {
|
|
List<Todo> _todos = [];
|
|
int _selectedIndex = 0;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_loadTodos();
|
|
}
|
|
|
|
Future<void> _loadTodos() async {
|
|
final todos = await TodoDatabase.instance.getAllTodos();
|
|
setState(() {
|
|
_todos = todos;
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final List<Widget> pages = [
|
|
TodoListView(todos: _todos, onTodosChanged: _loadTodos),
|
|
CalendarView(todos: _todos),
|
|
StatsView(todos: _todos),
|
|
];
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
title: const Text('Todo App'),
|
|
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
|
),
|
|
body: pages[_selectedIndex],
|
|
bottomNavigationBar: BottomNavigationBar(
|
|
currentIndex: _selectedIndex,
|
|
onTap: (index) => setState(() => _selectedIndex = index),
|
|
items: const [
|
|
BottomNavigationBarItem(icon: Icon(Icons.list), label: 'Todos'),
|
|
BottomNavigationBarItem(
|
|
icon: Icon(Icons.calendar_today), label: 'Calendar'),
|
|
BottomNavigationBarItem(icon: Icon(Icons.bar_chart), label: 'Stats'),
|
|
],
|
|
),
|
|
floatingActionButton: FloatingActionButton(
|
|
onPressed: () => _showAddTodoDialog(context),
|
|
child: const Icon(Icons.add),
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> _showAddTodoDialog(BuildContext context) async {
|
|
final titleController = TextEditingController();
|
|
final descriptionController = TextEditingController();
|
|
final selectedTags = <Tag>[];
|
|
final allTags = await TodoDatabase.instance.getAllTags();
|
|
|
|
await showDialog(
|
|
context: context,
|
|
builder: (context) => StatefulBuilder(
|
|
builder: (context, setState) => AlertDialog(
|
|
title: const Text('Add Todo'),
|
|
content: SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
TextField(
|
|
controller: titleController,
|
|
decoration: const InputDecoration(labelText: 'Title'),
|
|
),
|
|
TextField(
|
|
controller: descriptionController,
|
|
decoration: const InputDecoration(labelText: 'Description'),
|
|
),
|
|
const SizedBox(height: 16),
|
|
const Text('Tags (Optional):'),
|
|
Wrap(
|
|
spacing: 8,
|
|
children: allTags.map((tag) {
|
|
return FilterChip(
|
|
label: Text(tag.name),
|
|
selected: selectedTags.contains(tag),
|
|
onSelected: (selected) {
|
|
setState(() {
|
|
if (selected) {
|
|
selectedTags.add(tag);
|
|
} else {
|
|
selectedTags.remove(tag);
|
|
}
|
|
});
|
|
},
|
|
);
|
|
}).toList(),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.pop(context),
|
|
child: const Text('Cancel'),
|
|
),
|
|
TextButton(
|
|
onPressed: () async {
|
|
final todo = Todo(
|
|
title: titleController.text,
|
|
description: descriptionController.text,
|
|
createdAt: DateTime.now(),
|
|
tags: selectedTags,
|
|
);
|
|
final createdTodo = await TodoDatabase.instance.create(todo);
|
|
|
|
// Add selected tags to the todo
|
|
for (var tag in selectedTags) {
|
|
await TodoDatabase.instance
|
|
.addTagToTodo(createdTodo.id!, tag.id!);
|
|
}
|
|
|
|
Navigator.pop(context);
|
|
_loadTodos();
|
|
},
|
|
child: const Text('Add'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|