Add Projects feature; sync Note/Task models with backend additions

## New: Projects
- Project model, API, repository, Riverpod provider
- ProjectListScreen: active/archived sections, create dialog, long-press status/delete
- ProjectSelector widget: DropdownButtonFormField for note + task editors
- Projects tab added to shell (bottom nav + navigation rail, 4th position)
- /projects route registered in GoRouter ShellRoute

## Updated: Note model
- Added tags: List<String>, projectId: int?, milestoneId: int?
- NotesApi.create/update pass tags and project_id
- NotesRepository and NotesNotifier signatures updated
- NoteEditScreen: chip-based tag input + ProjectSelector

## Updated: Task model
- Added projectId: int?, milestoneId: int?, parentId: int?
- TasksApi.create passes project_id; update payload includes project_id
- TasksRepository and TasksNotifier signatures updated
- TaskEditScreen: ProjectSelector added; project_id sent on save

## Provider fix
- ProjectsNotifier.update renamed to updateProject to avoid conflict
  with AsyncNotifier.update(FutureOr<State> Function(State)) base method

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-02 20:52:59 -05:00
parent f30aa8d273
commit fceae5529d
19 changed files with 821 additions and 21 deletions
+12 -1
View File
@@ -17,6 +17,7 @@ import 'screens/chat/conversations_list_screen.dart';
import 'screens/notes/note_detail_screen.dart';
import 'screens/notes/note_edit_screen.dart';
import 'screens/notes/notes_list_screen.dart';
import 'screens/projects/project_list_screen.dart';
import 'screens/settings/settings_screen.dart';
import 'screens/setup/setup_screen.dart';
import 'screens/splash/splash_screen.dart';
@@ -118,6 +119,10 @@ final routerProvider = Provider<GoRouter>((ref) {
path: Routes.tasks,
builder: (_, _) => const TasksListScreen(),
),
GoRoute(
path: Routes.projects,
builder: (_, _) => const ProjectListScreen(),
),
GoRoute(
path: Routes.conversations,
builder: (_, _) => const ConversationsListScreen(),
@@ -137,7 +142,7 @@ class _Shell extends ConsumerStatefulWidget {
}
class _ShellState extends ConsumerState<_Shell> {
static const _tabs = [Routes.notes, Routes.tasks, Routes.conversations];
static const _tabs = [Routes.notes, Routes.tasks, Routes.projects, Routes.conversations];
@override
void initState() {
@@ -253,6 +258,11 @@ class _ShellState extends ConsumerState<_Shell> {
selectedIcon: Icon(Icons.check_box),
label: Text('Tasks'),
),
NavigationRailDestination(
icon: Icon(Icons.folder_outlined),
selectedIcon: Icon(Icons.folder),
label: Text('Projects'),
),
NavigationRailDestination(
icon: Icon(Icons.chat_bubble_outline),
selectedIcon: Icon(Icons.chat_bubble),
@@ -284,6 +294,7 @@ class _ShellState extends ConsumerState<_Shell> {
destinations: const [
NavigationDestination(icon: Icon(Icons.note), label: 'Notes'),
NavigationDestination(icon: Icon(Icons.check_box), label: 'Tasks'),
NavigationDestination(icon: Icon(Icons.folder), label: 'Projects'),
NavigationDestination(
icon: Icon(Icons.chat_bubble), label: 'Chat'),
],