import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:focusflow_shared/focusflow_shared.dart'; import '../../../../core/theme/app_colors.dart'; import '../../../../core/widgets/time_visualizer.dart'; import '../widgets/energy_selector.dart'; /// Task detail / edit screen. /// /// Shows title, description, energy level selector, time estimate, /// tags, category. Provides save and delete actions. class TaskDetailScreen extends StatefulWidget { final String taskId; const TaskDetailScreen({super.key, required this.taskId}); @override State createState() => _TaskDetailScreenState(); } class _TaskDetailScreenState extends State { final _formKey = GlobalKey(); final _titleController = TextEditingController(); final _descriptionController = TextEditingController(); final _minutesController = TextEditingController(); final _tagsController = TextEditingController(); final _categoryController = TextEditingController(); String _energyLevel = 'medium'; // Placeholder task — in production, load from BLoC. Task? _task; bool _loading = true; @override void initState() { super.initState(); _loadTask(); } Future _loadTask() async { // Simulated placeholder — in production the BLoC fetches from the API. await Future.delayed(const Duration(milliseconds: 300)); final task = Task( id: widget.taskId, userId: 'local', title: 'Sample Task', description: 'Tap to edit this task.', energyLevel: 'medium', estimatedMinutes: 25, actualMinutes: 20, tags: const ['work', 'focus'], category: 'work', createdAt: DateTime.now(), ); if (!mounted) return; setState(() { _task = task; _loading = false; _titleController.text = task.title; _descriptionController.text = task.description ?? ''; _minutesController.text = task.estimatedMinutes?.toString() ?? ''; _tagsController.text = task.tags.join(', '); _categoryController.text = task.category ?? ''; _energyLevel = task.energyLevel; }); } @override void dispose() { _titleController.dispose(); _descriptionController.dispose(); _minutesController.dispose(); _tagsController.dispose(); _categoryController.dispose(); super.dispose(); } void _save() { if (_formKey.currentState?.validate() ?? false) { // TODO: dispatch update via BLoC. ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Task saved.')), ); context.pop(); } } void _delete() { showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('Delete task?'), content: const Text('This cannot be undone.'), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), actions: [ TextButton(onPressed: () => Navigator.pop(ctx), child: const Text('Cancel')), TextButton( onPressed: () { Navigator.pop(ctx); // TODO: dispatch delete via BLoC. context.pop(); }, child: const Text('Delete', style: TextStyle(color: AppColors.error)), ), ], ), ); } @override Widget build(BuildContext context) { final theme = Theme.of(context); if (_loading) { return Scaffold( appBar: AppBar(title: const Text('Task')), body: const Center(child: CircularProgressIndicator()), ); } return Scaffold( appBar: AppBar( title: const Text('Task Detail'), actions: [ IconButton( icon: const Icon(Icons.delete_outline_rounded, color: AppColors.error), onPressed: _delete, tooltip: 'Delete', ), ], ), body: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // ── Title ────────────────────────────────────────── TextFormField( controller: _titleController, decoration: const InputDecoration(labelText: 'Title'), style: theme.textTheme.titleLarge, validator: (v) => (v == null || v.trim().isEmpty) ? 'Give it a name' : null, ), const SizedBox(height: 16), // ── Description ──────────────────────────────────── TextFormField( controller: _descriptionController, decoration: const InputDecoration(labelText: 'Description (optional)'), maxLines: 3, ), const SizedBox(height: 20), // ── Energy level ─────────────────────────────────── Text('Energy level', style: theme.textTheme.titleSmall), const SizedBox(height: 8), EnergySelector( value: _energyLevel, onChanged: (v) => setState(() => _energyLevel = v), ), const SizedBox(height: 20), // ── Time estimate ────────────────────────────────── TextFormField( controller: _minutesController, keyboardType: TextInputType.number, decoration: const InputDecoration( labelText: 'Estimated minutes', suffixText: 'min', ), ), const SizedBox(height: 20), // ── Time visualizer (if there is actual data) ────── if (_task != null && _task!.estimatedMinutes != null && _task!.actualMinutes != null) TimeVisualizer( estimatedMinutes: _task!.estimatedMinutes!, actualMinutes: _task!.actualMinutes, ), const SizedBox(height: 20), // ── Tags ─────────────────────────────────────────── TextFormField( controller: _tagsController, decoration: const InputDecoration( labelText: 'Tags (comma separated)', prefixIcon: Icon(Icons.label_outline), ), ), const SizedBox(height: 16), // ── Category ─────────────────────────────────────── TextFormField( controller: _categoryController, decoration: const InputDecoration( labelText: 'Category', prefixIcon: Icon(Icons.category_outlined), ), ), const SizedBox(height: 32), // ── Save button ──────────────────────────────────── FilledButton( onPressed: _save, child: const Text('Save'), ), ], ), ), ), ); } }