import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../core/exceptions.dart'; import '../../providers/projects_provider.dart'; class ProjectEditScreen extends ConsumerStatefulWidget { final int? projectId; const ProjectEditScreen({super.key, this.projectId}); @override ConsumerState createState() => _ProjectEditScreenState(); } class _ProjectEditScreenState extends ConsumerState { final _titleController = TextEditingController(); final _descController = TextEditingController(); final _goalController = TextEditingController(); String _status = 'active'; bool _saving = false; late final Future _initFuture; @override void initState() { super.initState(); _initFuture = widget.projectId != null ? _loadExisting() : Future.value(); } @override void dispose() { _titleController.dispose(); _descController.dispose(); _goalController.dispose(); super.dispose(); } Future _loadExisting() async { final projects = ref.read(projectsProvider).value ?? []; final project = projects.where((p) => p.id == widget.projectId).firstOrNull; if (project != null) { _titleController.text = project.title; _descController.text = project.description ?? ''; _goalController.text = project.goal ?? ''; _status = project.status; } } Future _save() async { final title = _titleController.text.trim(); if (title.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Title is required.'))); return; } setState(() => _saving = true); try { if (widget.projectId == null) { await ref.read(projectsProvider.notifier).create( title: title, description: _descController.text.trim().isEmpty ? null : _descController.text.trim(), goal: _goalController.text.trim().isEmpty ? null : _goalController.text.trim(), ); } else { await ref.read(projectsProvider.notifier).updateProject( widget.projectId!, { 'title': title, 'description': _descController.text.trim(), 'goal': _goalController.text.trim(), 'status': _status, }, ); } if (mounted) context.pop(); } on AppException catch (e) { if (mounted) { ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text(e.message))); } } finally { if (mounted) setState(() => _saving = false); } } @override Widget build(BuildContext context) { return FutureBuilder( future: _initFuture, builder: (context, snapshot) => Scaffold( appBar: AppBar( title: Text( widget.projectId == null ? 'New Project' : 'Edit Project'), actions: [ IconButton( icon: _saving ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.check), onPressed: _saving ? null : _save, ), ], ), body: snapshot.connectionState == ConnectionState.waiting ? const Center(child: CircularProgressIndicator()) : ListView( padding: const EdgeInsets.all(16), children: [ TextField( controller: _titleController, decoration: const InputDecoration( labelText: 'Title *', border: OutlineInputBorder()), textInputAction: TextInputAction.next, ), const SizedBox(height: 12), TextField( controller: _descController, decoration: const InputDecoration( labelText: 'Description', border: OutlineInputBorder()), maxLines: 3, textInputAction: TextInputAction.next, ), const SizedBox(height: 12), TextField( controller: _goalController, decoration: const InputDecoration( labelText: 'Goal', border: OutlineInputBorder()), maxLines: 2, textInputAction: TextInputAction.done, ), if (widget.projectId != null) ...[ const SizedBox(height: 12), DropdownButtonFormField( initialValue: _status, decoration: const InputDecoration( labelText: 'Status', border: OutlineInputBorder()), items: const [ DropdownMenuItem( value: 'active', child: Text('Active')), DropdownMenuItem( value: 'completed', child: Text('Completed')), DropdownMenuItem( value: 'archived', child: Text('Archived')), ], onChanged: (v) => setState(() => _status = v!), ), ], ], ), ), ); } }