11import 'package:flutter/material.dart' ;
22import 'package:intl/intl.dart' ;
3+ import 'package:provider/provider.dart' ;
4+ import '../../../../core/theme/app_colors.dart' ;
35import '../../../../core/widgets/custom_input_field.dart' ;
6+ import '../../model/task_model.dart' ;
7+ import '../../viewmodel/task_viewmodel.dart' ;
48import '../widgets/task_widgets.dart' ;
9+ import '../widgets/priority_selector.dart' ;
10+ import '../widgets/tag_selector.dart' ;
511
612class CreateTaskScreen extends StatefulWidget {
713 const CreateTaskScreen ({super .key});
@@ -11,8 +17,12 @@ class CreateTaskScreen extends StatefulWidget {
1117}
1218
1319class _CreateTaskScreenState extends State <CreateTaskScreen > {
14- final TextEditingController _nameController = TextEditingController (text: 'Team Meeting' );
15- final TextEditingController _descController = TextEditingController (text: 'Discuss all questions about new projects' );
20+ final TextEditingController _nameController = TextEditingController (
21+ text: 'Team Meeting' ,
22+ );
23+ final TextEditingController _descController = TextEditingController (
24+ text: 'Discuss all questions about new projects' ,
25+ );
1626 DateTime _selectedDate = DateTime .now ();
1727 TimeOfDay _startTime = const TimeOfDay (hour: 10 , minute: 0 );
1828 TimeOfDay _endTime = const TimeOfDay (hour: 11 , minute: 0 );
@@ -28,15 +38,20 @@ class _CreateTaskScreenState extends State<CreateTaskScreen> {
2838 body: SafeArea (
2939 child: Column (
3040 children: [
41+ // ─── Header ───────────────────────────────────────
3142 Container (
3243 decoration: BoxDecoration (
3344 color: Theme .of (context).colorScheme.surface,
3445 borderRadius: const BorderRadius .only (
35- bottomLeft: Radius .circular (30 ), bottomRight: Radius .circular (30 )),
46+ bottomLeft: Radius .circular (30 ),
47+ bottomRight: Radius .circular (30 ),
48+ ),
3649 boxShadow: [
3750 BoxShadow (
38- color: Colors .black.withValues (alpha: 0.05 ),
39- blurRadius: 10 , offset: const Offset (0 , 5 ))
51+ color: Colors .black.withValues (alpha: 0.05 ),
52+ blurRadius: 10 ,
53+ offset: const Offset (0 , 5 ),
54+ ),
4055 ],
4156 ),
4257 padding: const EdgeInsets .symmetric (horizontal: 20 , vertical: 15 ),
@@ -61,25 +76,46 @@ class _CreateTaskScreenState extends State<CreateTaskScreen> {
6176 ],
6277 ),
6378 ),
79+
80+ // ─── Body ─────────────────────────────────────────
6481 Expanded (
6582 child: SingleChildScrollView (
6683 padding: const EdgeInsets .all (25.0 ),
6784 child: Column (
6885 crossAxisAlignment: CrossAxisAlignment .start,
6986 children: [
70- Text ('Create New Task' , style: Theme .of (context).textTheme.headlineMedium),
87+ Text (
88+ 'Create New Task' ,
89+ style: Theme .of (context).textTheme.headlineMedium,
90+ ),
7191 const SizedBox (height: 25 ),
72- CustomInputField (label: 'Task Name' , hint: 'Enter task name' , controller: _nameController),
92+
93+ // Task Name
94+ CustomInputField (
95+ label: 'Task Name' ,
96+ hint: 'Enter task name' ,
97+ controller: _nameController,
98+ ),
7399 const SizedBox (height: 20 ),
74- Text ('Select Category' , style: Theme .of (context).textTheme.labelLarge),
100+
101+ // Category
102+ Text (
103+ 'Select Category' ,
104+ style: Theme .of (context).textTheme.labelLarge,
105+ ),
75106 const SizedBox (height: 10 ),
76107 SizedBox (
77108 height: 40 ,
78109 child: ListView .builder (
79110 scrollDirection: Axis .horizontal,
80111 itemCount: 4 ,
81112 itemBuilder: (context, index) {
82- List <String > categories = ['Development' , 'Research' , 'Design' , 'Backend' ];
113+ List <String > categories = [
114+ 'Development' ,
115+ 'Research' ,
116+ 'Design' ,
117+ 'Backend' ,
118+ ];
83119 bool isSelected = index == _selectedCategoryIndex;
84120 return Padding (
85121 padding: const EdgeInsets .only (right: 10 ),
@@ -112,20 +148,38 @@ class _CreateTaskScreenState extends State<CreateTaskScreen> {
112148 ),
113149 ),
114150 const SizedBox (height: 20 ),
151+
152+ // ─── PRIORITY SELECTOR (MỚI) ──────────────
153+ const PrioritySelector (),
154+ const SizedBox (height: 20 ),
155+
156+ // ─── TAG SELECTOR (MỚI) ───────────────────
157+ const TagSelector (),
158+ const SizedBox (height: 20 ),
159+
160+ // Date
115161 Row (
116162 mainAxisAlignment: MainAxisAlignment .spaceBetween,
117163 children: [
118164 Column (
119165 crossAxisAlignment: CrossAxisAlignment .start,
120166 children: [
121- Text ('Date' , style: Theme .of (context).textTheme.labelLarge),
167+ Text (
168+ 'Date' ,
169+ style: Theme .of (context).textTheme.labelLarge,
170+ ),
122171 const SizedBox (height: 5 ),
123172 InkWell (
124173 onTap: () async {
125174 final DateTime ? picked = await showDatePicker (
126- context: context, initialDate: _selectedDate,
127- firstDate: DateTime (2000 ), lastDate: DateTime (2100 ));
128- if (picked != null ) setState (() => _selectedDate = picked);
175+ context: context,
176+ initialDate: _selectedDate,
177+ firstDate: DateTime (2000 ),
178+ lastDate: DateTime (2100 ),
179+ );
180+ if (picked != null ) {
181+ setState (() => _selectedDate = picked);
182+ }
129183 },
130184 child: Column (
131185 crossAxisAlignment: CrossAxisAlignment .start,
@@ -146,7 +200,7 @@ class _CreateTaskScreenState extends State<CreateTaskScreen> {
146200 )
147201 ],
148202 ),
149- )
203+ ),
150204 ],
151205 ),
152206 Container (
@@ -160,15 +214,24 @@ class _CreateTaskScreenState extends State<CreateTaskScreen> {
160214 ],
161215 ),
162216 const SizedBox (height: 25 ),
217+
218+ // Time
163219 Row (
164220 children: [
165221 Expanded (
166222 child: Column (
167223 crossAxisAlignment: CrossAxisAlignment .start,
168224 children: [
169- Text ('Start time' , style: Theme .of (context).textTheme.labelLarge),
225+ Text (
226+ 'Start time' ,
227+ style: Theme .of (context).textTheme.labelLarge,
228+ ),
170229 const SizedBox (height: 5 ),
171- TimePickerWidget (time: _startTime, onChanged: (newTime) => setState (() => _startTime = newTime)),
230+ TimePickerWidget (
231+ time: _startTime,
232+ onChanged: (t) =>
233+ setState (() => _startTime = t),
234+ ),
172235 ],
173236 ),
174237 ),
@@ -177,27 +240,73 @@ class _CreateTaskScreenState extends State<CreateTaskScreen> {
177240 child: Column (
178241 crossAxisAlignment: CrossAxisAlignment .start,
179242 children: [
180- Text ('End time' , style: Theme .of (context).textTheme.labelLarge),
243+ Text (
244+ 'End time' ,
245+ style: Theme .of (context).textTheme.labelLarge,
246+ ),
181247 const SizedBox (height: 5 ),
182- TimePickerWidget (time: _endTime, onChanged: (newTime) => setState (() => _endTime = newTime)),
248+ TimePickerWidget (
249+ time: _endTime,
250+ onChanged: (t) => setState (() => _endTime = t),
251+ ),
183252 ],
184253 ),
185254 ),
186255 ],
187256 ),
188257 const SizedBox (height: 25 ),
189- CustomInputField (label: 'Description' , hint: 'Enter task description' , controller: _descController, maxLines: 2 ),
258+
259+ // Description
260+ CustomInputField (
261+ label: 'Description' ,
262+ hint: 'Enter task description' ,
263+ controller: _descController,
264+ maxLines: 2 ,
265+ ),
190266 const SizedBox (height: 40 ),
267+
268+ // ─── Create Button ────────────────────────
191269 Center (
192270 child: ElevatedButton (
193- onPressed: () {},
271+ onPressed: () {
272+ final viewModel = context.read <TaskViewModel >();
273+ final List <String > categories = [
274+ 'Development' ,
275+ 'Research' ,
276+ 'Design' ,
277+ 'Backend' ,
278+ ];
279+ final newTask = TaskModel (
280+ id: DateTime .now ().millisecondsSinceEpoch
281+ .toString (),
282+ title: _nameController.text,
283+ description: _descController.text,
284+ category: categories[_selectedCategoryIndex],
285+ startTime: _startTime,
286+ endTime: _endTime,
287+ date: _selectedDate,
288+ priority: viewModel.selectedPriority,
289+ tags: List .from (viewModel.selectedTags),
290+ );
291+ viewModel.addTask (newTask);
292+ viewModel.reset ();
293+ Navigator .pop (context);
294+ },
194295 style: ElevatedButton .styleFrom (
195296 backgroundColor: Theme .of (context).colorScheme.primary,
196297 foregroundColor: Colors .white,
197- padding: const EdgeInsets .symmetric (horizontal: 100 , vertical: 15 ),
198- shape: RoundedRectangleBorder (borderRadius: BorderRadius .circular (15 )),
298+ padding: const EdgeInsets .symmetric (
299+ horizontal: 100 ,
300+ vertical: 15 ,
301+ ),
302+ shape: RoundedRectangleBorder (
303+ borderRadius: BorderRadius .circular (15 ),
304+ ),
305+ ),
306+ child: const Text (
307+ 'Create Task' ,
308+ style: TextStyle (fontSize: 18 ),
199309 ),
200- child: const Text ('Create Task' , style: TextStyle (fontSize: 18 )),
201310 ),
202311 ),
203312 ],
@@ -209,4 +318,4 @@ class _CreateTaskScreenState extends State<CreateTaskScreen> {
209318 ),
210319 );
211320 }
212- }
321+ }
0 commit comments