import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../core/constants.dart'; import '../../providers/notes_provider.dart'; class NotesListScreen extends ConsumerStatefulWidget { const NotesListScreen({super.key}); @override ConsumerState createState() => _NotesListScreenState(); } class _NotesListScreenState extends ConsumerState { bool _showSearch = false; String _search = ''; @override Widget build(BuildContext context) { final notesAsync = ref.watch(notesProvider); return Scaffold( appBar: AppBar( automaticallyImplyLeading: false, title: _showSearch ? TextField( autofocus: true, decoration: const InputDecoration( hintText: 'Search notes…', border: InputBorder.none, ), onChanged: (v) => setState(() => _search = v.trim().toLowerCase()), ) : null, actions: [ if (_showSearch) IconButton( icon: const Icon(Icons.close), tooltip: 'Close search', onPressed: () => setState(() { _showSearch = false; _search = ''; }), ) else IconButton( icon: const Icon(Icons.search), tooltip: 'Search', onPressed: () => setState(() => _showSearch = true), ), ], ), body: notesAsync.when( loading: () => const Center(child: CircularProgressIndicator()), error: (_, _) => Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.cloud_off, size: 48), const SizedBox(height: 12), const Text('Could not load notes.'), const SizedBox(height: 4), TextButton( onPressed: () => ref.invalidate(notesProvider), child: const Text('Retry'), ), ], ), ), data: (notes) { final filtered = _search.isEmpty ? notes : notes .where((n) => n.title.toLowerCase().contains(_search) || n.body.toLowerCase().contains(_search)) .toList(); if (filtered.isEmpty) { return Center( child: Text( _search.isEmpty ? 'No notes yet. Tap + to create one.' : 'No notes match "$_search".', ), ); } return RefreshIndicator( onRefresh: () => ref.refresh(notesProvider.future), child: ListView.separated( itemCount: filtered.length, separatorBuilder: (_, _) => const Divider(height: 1), itemBuilder: (context, i) { final note = filtered[i]; final preview = note.body .split('\n') .firstWhere((l) => l.trim().isNotEmpty, orElse: () => '') .trim(); return ListTile( title: Text(note.title), subtitle: Text( preview.isNotEmpty ? preview : note.updatedAt.toLocal().toString().substring(0, 16), style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), onTap: () => context.push( Routes.noteDetail.replaceFirst(':id', '${note.id}'), ), ); }, ), ); }, ), floatingActionButton: FloatingActionButton( heroTag: 'notes_fab', onPressed: () => context.push(Routes.noteNew), child: const Icon(Icons.add), ), ); } }