BLoC/Cubit state management, ADHD-friendly theme (calming teal, no red), GetIt DI, GoRouter navigation. Screens: task dashboard, focus mode, task create/detail, streaks, time perception, settings, onboarding, auth. Custom widgets: TaskCard, RewardPopup, StreakRing, GentleNudgeCard. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
121 lines
4.1 KiB
Dart
121 lines
4.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
|
|
import '../widgets/energy_selector.dart';
|
|
|
|
/// Quick task creation screen — minimal friction.
|
|
///
|
|
/// Fields:
|
|
/// - Title (required).
|
|
/// - Energy level (default medium).
|
|
/// - Estimated minutes.
|
|
/// - Tags.
|
|
class CreateTaskScreen extends StatefulWidget {
|
|
const CreateTaskScreen({super.key});
|
|
|
|
@override
|
|
State<CreateTaskScreen> createState() => _CreateTaskScreenState();
|
|
}
|
|
|
|
class _CreateTaskScreenState extends State<CreateTaskScreen> {
|
|
final _formKey = GlobalKey<FormState>();
|
|
final _titleController = TextEditingController();
|
|
final _minutesController = TextEditingController(text: '15');
|
|
final _tagsController = TextEditingController();
|
|
String _energyLevel = 'medium';
|
|
|
|
@override
|
|
void dispose() {
|
|
_titleController.dispose();
|
|
_minutesController.dispose();
|
|
_tagsController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
void _create() {
|
|
if (_formKey.currentState?.validate() ?? false) {
|
|
// TODO: dispatch TaskCreated via BLoC.
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(content: Text('Task created!')),
|
|
);
|
|
context.pop();
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final theme = Theme.of(context);
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('New Task')),
|
|
body: SingleChildScrollView(
|
|
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16),
|
|
child: Form(
|
|
key: _formKey,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
'What do you need to do?',
|
|
style: theme.textTheme.titleLarge,
|
|
),
|
|
const SizedBox(height: 16),
|
|
|
|
// ── Title ──────────────────────────────────────────
|
|
TextFormField(
|
|
controller: _titleController,
|
|
autofocus: true,
|
|
textInputAction: TextInputAction.next,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Task title',
|
|
hintText: 'e.g. Reply to email',
|
|
),
|
|
validator: (v) =>
|
|
(v == null || v.trim().isEmpty) ? 'What is it?' : null,
|
|
),
|
|
const SizedBox(height: 24),
|
|
|
|
// ── Energy level ───────────────────────────────────
|
|
Text('How much energy will this take?',
|
|
style: theme.textTheme.titleSmall),
|
|
const SizedBox(height: 8),
|
|
EnergySelector(
|
|
value: _energyLevel,
|
|
onChanged: (v) => setState(() => _energyLevel = v),
|
|
),
|
|
const SizedBox(height: 24),
|
|
|
|
// ── Estimated minutes ──────────────────────────────
|
|
TextFormField(
|
|
controller: _minutesController,
|
|
keyboardType: TextInputType.number,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Estimated minutes',
|
|
suffixText: 'min',
|
|
),
|
|
),
|
|
const SizedBox(height: 24),
|
|
|
|
// ── Tags ───────────────────────────────────────────
|
|
TextFormField(
|
|
controller: _tagsController,
|
|
decoration: const InputDecoration(
|
|
labelText: 'Tags (optional, comma separated)',
|
|
prefixIcon: Icon(Icons.label_outline),
|
|
),
|
|
),
|
|
const SizedBox(height: 32),
|
|
|
|
// ── Create button ──────────────────────────────────
|
|
FilledButton(
|
|
onPressed: _create,
|
|
child: const Text('Create Task'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|