Files
TaskTracker/lib/NewTodo.dart
2022-03-31 15:12:31 +05:30

338 lines
14 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:intl/intl.dart';
import 'package:tasktracker/NewTask.dart';
import 'package:tasktracker/NotificationsManager.dart';
import 'Data.dart';
import 'Dialogs.dart';
import 'User.dart' as User;
DateFormat dateFormat = DateFormat("yyyy-MM-dd");
DateFormat dateTimeFormat = DateFormat("yyyy-MM-dd HH:mm");
DateFormat durationFormat = DateFormat("HH:mm:ss");
class NewTodo extends StatefulWidget {
NewTodo({Key? key, this.selectedTask, this.metadata, this.dueDate,this.notificationTime}) : super(key: key);
late String? metadata;
late String? selectedTask;
late DateTime? dueDate;
late DateTime? notificationTime;
@override
_NewActivity createState() => _NewActivity(selectedCat: selectedTask, metadata: metadata);
}
class _NewActivity extends State<NewTodo> {
late String init_selectedTask;
_NewActivity({String? metadata, String? selectedCat, DateTime? DueDate, this.notificationTime}) {
editing =selectedCat != null && DueDate !=null;
dueDate = DueDate ?? DateTime.now().add(Duration(days: 1));
this.metadataController.text = metadata ?? "";
if(this.metadataController.text.contains('[') && this.metadataController.text.contains(']') ){
this.metadataController.text = this.metadataController.text.substring(this.metadataController.text.indexOf(']')+1);
selectedStep = metadata!.substring(1,metadata!.indexOf(']'));
}else{
selectedStep='None';
}
this.init_selectedTask = this.selectedCat = selectedCat ?? User.taskTypes[0].name;
print(" meta:$metadata, task: $selectedCat");
}
TextEditingController metadataController = TextEditingController();
late String selectedCat;
late DateTime dueDate;
DateTime? notificationTime;
bool editing = false;
Map<String, TaskType?> taskTypes = <String, TaskType?>{};
Map<String, TaskType?> getActivities() {
Map<String, TaskType?> _cats = <String, TaskType?>{};
_cats.putIfAbsent("+Add New Task Type", () => null);
if (User.taskTypes.isEmpty) {
} else {
print(User.taskTypes[0].name + " : " + selectedCat);
}
User.taskTypes.forEach((element) {
String name = element.name;
if (_cats.keys.toString().contains(element.name)) {
} else {
String displayName = (name + ((element.relatedProject != null) ? ' [${element.relatedProject!.name}]' : ''));
_cats.putIfAbsent(displayName, () => element);
}
});
return _cats;
}
String? selectedStep = null;
@override
Widget build(BuildContext context) {
taskTypes = getActivities();
bool canSelectStep = false;
List<String> steps = ['None'];
if (taskTypes[selectedCat] != null) {
if (taskTypes[selectedCat]!.relatedProject != null) {
//Got a project. But is it multi step?
if (taskTypes[selectedCat]!.relatedProject!.steps.isNotEmpty) {
canSelectStep = true;
bool matchesSelectedStep = false;
taskTypes[selectedCat]!.relatedProject!.steps.forEach((element) {
if (element.finishedDate == null) {
steps.add(element.stepName);
if (selectedStep == null) {
selectedStep = element.stepName;
matchesSelectedStep = true;
}
if (element.stepName == selectedStep) {
matchesSelectedStep = true;
}
}
});
if (!matchesSelectedStep) {
selectedStep = steps[0];
}
}
}
}
return Scaffold(
appBar: AppBar(title: Text((editing) ? 'Edit To-Do' : 'New To-Do')),
body: Column(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Expanded(
flex: 9,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Padding(
padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
child: Column(
children: [
Column(children: [
Container(padding: EdgeInsets.all(10), child: Text('Task')),
Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 1),
decoration: BoxDecoration(
color: Colors.black12, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey, width: 2)),
child: DropdownButton<String>(
dropdownColor: Color(0xFF222222),
iconSize: 30,
elevation: 10,
borderRadius: BorderRadius.circular(10),
value: selectedCat,
isExpanded: true,
items: getActivities().keys.map<DropdownMenuItem<String>>((String value) {
print(value);
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String? _value) {
if (_value == '+Add New Task Type') {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewTask())).then((val) {
setState(() {});
});
} else {
selectedCat = _value ?? 'n/a';
}
setState(() {});
})),
if (canSelectStep) Container(padding: EdgeInsets.all(10), child: Text('Step')),
if (canSelectStep)
Container(
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 1),
decoration: BoxDecoration(
color: Colors.black12, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey, width: 2)),
child: DropdownButton<String>(
dropdownColor: Color(0xFF222222),
iconSize: 30,
elevation: 10,
borderRadius: BorderRadius.circular(10),
value: selectedStep,
isExpanded: true,
items: steps.map<DropdownMenuItem<String>>((String value) {
print(value);
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (String? _value) {
selectedStep = _value;
setState(() {});
})),
Container(
padding: EdgeInsets.all(10),
child: Column(
children: [
TextField(
controller: metadataController,
decoration: InputDecoration(
hintText: 'Description (required)',
filled: true,
border: OutlineInputBorder(borderRadius: BorderRadius.circular(20))),
),
],
)),
Container(
child: Divider(
)),
ListTile(
leading: FaIcon(FontAwesomeIcons.calendarDay),
title: Text('Due Date'),
subtitle: Text('When do you want to do this?'),
onTap:(){setState(() {
DatePicker.showDatePicker(context, showTitleActions: true, onChanged: (date) {
// print('change $date');
}, onConfirm: (date) {
setState(() {
dueDate=date;
});
}, currentTime: dueDate, locale: LocaleType.en);
});} ,
trailing: InkWell(
child:Text(dateFormat.format(dueDate), style: TextStyle(color: Colors.blue))
),
),
Divider(),
ListTile(
title: Text('Notification'),
leading: FaIcon((notificationTime==null) ?FontAwesomeIcons.bellSlash :FontAwesomeIcons.bell),
trailing: Switch.adaptive(value: notificationTime!=null, onChanged: (val){
if(notificationTime==null){
notificationTime = DateTime.now().add(Duration(days: 1));
}else{
notificationTime = null;
}
setState(() {
});
}),
)
]),
ListTile(
enabled: notificationTime!=null,
leading: FaIcon(FontAwesomeIcons.clock),
title: Text('Notify me at'),
subtitle: Text('When do you want to do this?'),
onTap:(){setState(() {
DatePicker.showDateTimePicker(context, showTitleActions: true, onChanged: (date) {
// print('change $date');
}, onConfirm: (date) {
setState(() {
notificationTime=date;
});
}, currentTime: notificationTime, locale: LocaleType.en);
});} ,
trailing: InkWell(
child:Text(dateTimeFormat.format(notificationTime ?? DateTime.now()), style: TextStyle(color: Colors.blue))
),
),
],
)),
),
),
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
flex: 5,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(primary: Colors.red, shape: StadiumBorder()),
onPressed: () {
Navigator.pop(context);
},
child: Text('Back', style: TextStyle(fontSize: 20))))),
Expanded(
flex: 6,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(primary: Colors.green, shape: StadiumBorder()),
onPressed: () {
if (editing) {
edit_action();
} else {
add_action();
}
},
child: Text((editing) ? 'Apply' : 'Add Todo', style: TextStyle(fontSize: 20))))),
],
)),
)
]));
}
Widget QuickTimeButton(text, {Function}) {
return InkWell(
child: Container(
padding: EdgeInsets.symmetric(horizontal: 15),
height: 30,
decoration: BoxDecoration(color: Colors.blueAccent, borderRadius: BorderRadius.circular(50)),
child: Align(
child: Text(text),
alignment: Alignment.center,
)),
onTap: () {
Function();
setState(() {});
},
);
}
void add_action() async {
if(metadataController.text.isEmpty){
Dialogs.showAlertDialog(context, 'Invalid data', 'Please enter description to add new todo');
return;
}
await User.UserOperations.addTodo(selectedCat, metadataController.text, dueDate, notificationTime);
Navigator.of(context).pop();
}
void edit_action() async {
}
}
String _printDuration(Duration duration) {
String twoDigits(int n) => n.toString().padLeft(2, "0");
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
return "${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
}
showAlertDialog(BuildContext context, String title, String message) {
// set up the button
Widget okButton = TextButton(
child: Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text(title),
content: Text(message),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}