Multi step list and editor UI done

This commit is contained in:
Sewmina
2022-03-15 02:49:27 +05:30
parent 26c6907d43
commit 03cb6b81c4
3 changed files with 450 additions and 332 deletions

View File

@@ -90,10 +90,11 @@ class Queries{
}
class ProjectStep{
ProjectStep(this.stepName,this.eta);
ProjectStep(this.stepName,this.eta,this.progress);
String stepName;
int eta;
int progress;
}

View File

@@ -17,7 +17,7 @@ Future<void> showDurationSelector(BuildContext context, {required Function(Durat
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30)),
backgroundColor: Colors.white10,
backgroundColor: Color(0xFF1F1F1F),
title: Align(alignment: Alignment.center,
child: const Text('Select Time Range')),
content: Row(

View File

@@ -39,42 +39,29 @@ class _NewProjectState extends State<NewProject> {
appBar: AppBar(title: Text('New Project')),
body: Container(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
child: Column(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
SingleChildScrollView(
child: Padding(
padding: EdgeInsets.fromLTRB(20, 50, 20, 50),
child: Column(
children: [
Container(
padding: EdgeInsets.all(0),
child: Text('Project Name')),
Container(padding: EdgeInsets.all(0), child: Text('Project Name')),
Container(
padding: EdgeInsets.all(10),
child: TextField(
controller: nameController,
decoration: InputDecoration(
hintText:
'ex: Cool science project, Build a new game etc...',
border: OutlineInputBorder()),
decoration:
InputDecoration(hintText: 'ex: Cool science project, Build a new game etc...', border: OutlineInputBorder()),
),
),
Divider(),
Column(children: [
Container(
padding: EdgeInsets.all(0),
child: Text('Related Category')),
Container(padding: EdgeInsets.all(0), child: Text('Related Category')),
Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.symmetric(
horizontal: 12, vertical: 1),
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 1),
decoration: BoxDecoration(
color: Colors.white10,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: Colors.grey, width: 2)),
color: Colors.white10, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey, width: 2)),
child: DropdownButton<String>(
dropdownColor: Colors.black,
iconSize: 30,
@@ -82,9 +69,7 @@ class _NewProjectState extends State<NewProject> {
borderRadius: BorderRadius.circular(10),
value: selectedCat,
isExpanded: true,
items: getCategoryNames()
.map<DropdownMenuItem<String>>(
(String value) {
items: getCategoryNames().map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
@@ -98,13 +83,8 @@ class _NewProjectState extends State<NewProject> {
Divider(),
Container(
padding: EdgeInsets.all(10),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text('This project is',
style: TextStyle(fontSize: 18)),
child: Row(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
Text('This project is', style: TextStyle(fontSize: 18)),
FlutterSwitch(
width: 130,
height: 35.0,
@@ -119,16 +99,13 @@ class _NewProjectState extends State<NewProject> {
activeText: 'Multi step',
inactiveText: 'Single step',
activeColor: Colors.deepOrange,
activeIcon: Icon(Icons.linear_scale,
color: Colors.orange),
inactiveIcon: Icon(Icons.check,
color: Colors.green),
activeIcon: Icon(Icons.linear_scale, color: Colors.orange),
inactiveIcon: Icon(Icons.check, color: Colors.green),
inactiveColor: Colors.green,
onToggle: (val) {
setState(() {
multiLine = val;
print(
"Multi=Step : $multiLine");
print("Multi=Step : $multiLine");
});
},
)
@@ -137,8 +114,7 @@ class _NewProjectState extends State<NewProject> {
],
))),
Container(
padding:
EdgeInsets.symmetric(vertical: 10, horizontal: 20),
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
@@ -146,45 +122,33 @@ class _NewProjectState extends State<NewProject> {
Expanded(
flex: 5,
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 10, vertical: 0),
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.red,
shape: StadiumBorder()),
style: ElevatedButton.styleFrom(primary: Colors.red, shape: StadiumBorder()),
onPressed: () {
setState(() {
Navigator.pop(context);
});
},
child: Text('Cancel',
style: TextStyle(fontSize: 20))))),
child: Text('Cancel', style: TextStyle(fontSize: 20))))),
Expanded(
flex: 6,
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 10, vertical: 0),
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.green,
shape: StadiumBorder()),
style: ElevatedButton.styleFrom(primary: Colors.green, shape: StadiumBorder()),
onPressed: () {
// add_action();
if (nameController.text.length > 3) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
NewProject2(
projectName:
nameController.text,
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => NewProject2(
projectName: nameController.text,
)));
} else {
showAlertDialog(context, 'Really?',
'Enter a valid name for this project!');
showAlertDialog(context, 'Really?', 'Enter a valid name for this project!');
}
},
child: Text('Next',
style: TextStyle(fontSize: 20))))),
child: Text('Next', style: TextStyle(fontSize: 20))))),
],
))
])));
@@ -216,8 +180,7 @@ class _NewProjectState extends State<NewProject> {
String catName = nameController.value.text;
if (catName.length < 2) {
showAlertDialog(context, 'Category needs a name',
'Please enter a name for this category');
showAlertDialog(context, 'Category needs a name', 'Please enter a name for this category');
return;
}
var hex = '#${pickerColor.value.toRadixString(16)}';
@@ -272,13 +235,7 @@ class NewProject2 extends StatefulWidget {
class _NewProject2State extends State<NewProject2> {
bool knowEta = false;
int etaHours = 1;
List<ProjectStep> steps = [
ProjectStep('Step 1', 3),
ProjectStep('Step 2', 2),
ProjectStep('Ez Step', 1),
ProjectStep('Very hard', 10),
ProjectStep('Finishing', 5)
];
List<ProjectStep> steps = [];
DateTime deadline = DateTime.now().add(Duration(days: 7));
late String? projectName;
_NewProject2State({String? pName}) {
@@ -291,11 +248,9 @@ class _NewProject2State extends State<NewProject2> {
appBar: AppBar(title: Text(projectName ?? 'Error')),
body: Container(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
child: Column(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
padding: EdgeInsets.fromLTRB(20, 50, 20, 50),
child: (multiLine)
@@ -305,37 +260,89 @@ class _NewProject2State extends State<NewProject2> {
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
Container(padding: EdgeInsets.all(10), child: Text('List your steps down')),
LimitedBox(
maxHeight: 300,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.white10,
),
padding: EdgeInsets.all(10),
child: Text('List your steps down')
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
child: Column(
children: printSteps(),
),
)),
),
),
SizedBox(
height: 5,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.white10,
),
padding: EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.max,
children: [
InkWell(
onTap: () {
int maxProgress = 100;
steps.forEach((element) {
maxProgress -= element.progress;
});
if (maxProgress > 0) {
showStepEditor(context, maxProgress: maxProgress, onChange: (step) {
steps.add(step);
setState(() {});
});
} else {
showAlertDialog(context, 'Progress full',
'Progress has already reached 100%, Cannot add more steps since the work is done');
}
},
child: Container(margin: EdgeInsets.all(10), child: Icon(Icons.add))),
InkWell(
enableFeedback: (steps.length > 0),
onTap: () {
int maxProgress = 100;
steps.forEach((element) {
maxProgress -= element.progress;
});
int stepProgress = steps[selectedStep].progress;
showStepEditor(context,
editStep: steps[selectedStep],
maxProgress: (maxProgress > stepProgress) ? maxProgress : stepProgress, onChange: (step) {
steps[selectedStep] = step;
setState(() {});
});
},
child: Container(
margin: EdgeInsets.all(10),
child: Icon(Icons.edit, color: (steps.length > 0) ? Colors.white : Colors.grey))),
InkWell(onTap: () {
if(steps.length <= 0){return;}
steps.remove(steps[selectedStep]);
setState(() {
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child:Column(
children: printSteps(),
)
),
),
});
}, child: Container(margin: EdgeInsets.all(10), child: Icon(Icons.remove, color: (steps.length > 0) ? Colors.white : Colors.grey))),
],
))
],
)
],
)
: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: EdgeInsets.all(10),
child: Text(
"Estimated Time to reach target")),
Container(padding: EdgeInsets.all(10), child: Text("Estimated Time to reach target")),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
@@ -345,58 +352,46 @@ class _NewProject2State extends State<NewProject2> {
showDurationSelector(context, selectedHour: etaHours, onChange: (newVal) {
etaHours = newVal.inHours;
knowEta = true;
setState(() {
});
setState(() {});
print("Selected $newVal");
});
},
child: Container(
decoration: BoxDecoration(
color: (knowEta) ? Colors.green : Colors.white10,
borderRadius:
BorderRadius.circular(30),
borderRadius: BorderRadius.circular(30),
),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 50, vertical: 10),
padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 10),
child: Text("${(knowEta) ? etaHours : '?'} Hours"),
),
),
),InkWell(
),
InkWell(
onTap: () {
knowEta = false;
setState(() {
});
setState(() {});
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: (knowEta) ? Colors.white10 :Colors.redAccent
),
borderRadius: BorderRadius.circular(30), color: (knowEta) ? Colors.white10 : Colors.redAccent),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: Text("I have no idea"),
)
),
)),
)
],
),
SizedBox(
height: 20,
),
Container(
padding: EdgeInsets.all(8),
child: Text("Deadline")),
Container(padding: EdgeInsets.all(8), child: Text("Deadline")),
InkWell(
onTap: () {
DatePicker.showDatePicker(
context,
DatePicker.showDatePicker(context,
showTitleActions: true,
minTime: DateTime.now(),
theme: DatePickerTheme(backgroundColor: Colors.white),
onChanged: (date) {
theme: DatePickerTheme(backgroundColor: Colors.white), onChanged: (date) {
// print('change $date');
}, onConfirm: (date) {
setState(() {
@@ -406,32 +401,24 @@ class _NewProject2State extends State<NewProject2> {
showAlertDialog(context, 'Come on!', 'Deadline was passed?');
}
});
},
currentTime: deadline,
locale: LocaleType.en);
setState(() {
});
}, currentTime: deadline, locale: LocaleType.en);
setState(() {});
},
child: Container(
decoration: BoxDecoration(
color: Colors.white10,
borderRadius:
BorderRadius.circular(30),
borderRadius: BorderRadius.circular(30),
),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 100, vertical: 10),
padding: const EdgeInsets.symmetric(horizontal: 100, vertical: 10),
child: Text(DateFormat("MMMM dd yyyy").format(deadline)),
),
),
),
],
))),
Container(
padding:
EdgeInsets.symmetric(vertical: 10, horizontal: 20),
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
@@ -439,44 +426,174 @@ class _NewProject2State extends State<NewProject2> {
Expanded(
flex: 5,
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 10, vertical: 0),
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.red,
shape: StadiumBorder()),
style: ElevatedButton.styleFrom(primary: Colors.red, shape: StadiumBorder()),
onPressed: () {
setState(() {
Navigator.pop(context);
});
},
child: Text('Back',
style: TextStyle(fontSize: 20))))),
child: Text('Back', style: TextStyle(fontSize: 20))))),
Expanded(
flex: 6,
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 10, vertical: 0),
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 0),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.green,
shape: StadiumBorder()),
style: ElevatedButton.styleFrom(primary: Colors.green, shape: StadiumBorder()),
onPressed: () {},
child: Text('Next',
style: TextStyle(fontSize: 20))))),
child: Text('Next', style: TextStyle(fontSize: 20))))),
],
))
])));
}
int selectedStep = 0;
List<Widget> printSteps() {
List<Widget> _steps = [];
for(int i=0; i < steps.)
_steps.add(
InkWell(onTap:(){se},child: Container(padding:EdgeInsets.symmetric(horizontal: 10,vertical: 2),child: Row(mainAxisSize:MainAxisSize.max,mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [Text(value.stepName), Icon(Icons.timelapse), Text(value.eta.toString() + " Hours")],))));
for (int i = 0; i < steps.length; i++) {
ProjectStep value = steps[i];
_steps.add(InkWell(
onTap: () {
selectedStep = i;
setState(() {});
},
child: Container(
height: 30,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5), color: (selectedStep == i) ? Colors.black26 : null),
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(flex: 4, child: Text(value.stepName)),
// Expanded(flex:1,child: Icon(Icons.timelapse)),
Expanded(flex: 1, child: Text("${value.progress}%")),
Expanded(
flex: 3,
child: Text(
value.eta.toString() + " Hours",
textAlign: TextAlign.end,
))
],
))));
}
return _steps;
}
Future<void> showStepEditor(BuildContext context, {required Function(ProjectStep) onChange, ProjectStep? editStep, int? maxProgress}) async {
TextEditingController nameController = TextEditingController();
int progress = 1;
int eta = 1;
bool editing = false;
int _maxP = maxProgress ?? 100;
if (editStep != null) {
editing = true;
nameController.text = editStep.stepName;
eta = editStep.eta;
progress = editStep.progress;
}
return showDialog<void>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return StatefulBuilder(builder: (context, setState) {
setState(() {});
return AlertDialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
backgroundColor: Color(0xFF1F1F1F),
title: Align(alignment: Alignment.center, child: Text((editing) ? 'Edit step' : 'Add new step')),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Step name'),
TextField(
controller: nameController,
decoration: InputDecoration(
filled: true, hintText: 'Collect resources', border: OutlineInputBorder(borderRadius: BorderRadius.circular(20))),
style: TextStyle(fontSize: 15),
)
],
),
SizedBox(
height: 20,
),
Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Progress : $progress%'),
Slider(
min: 1,
max: _maxP.toDouble(),
value: progress.toDouble(),
onChanged: (val) {
progress = val.toInt();
setState(() {});
},
label: 'Progress',
),
],
),
SizedBox(
height: 20,
),
Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.all(4.0),
child: Text('Estimated Time'),
),
InkWell(
onTap: () {
showDurationSelector(context, selectedHour: eta, onChange: (newVal) {
eta = newVal.inHours;
setState(() {});
print("Selected $newVal");
});
},
child: Container(
decoration: BoxDecoration(
color: Colors.white10,
borderRadius: BorderRadius.circular(30),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 10),
child: Text("${eta} Hours"),
),
),
)
],
),
],
),
actions: <Widget>[
TextButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
MaterialButton(
color: Colors.green,
child: Text((editing) ? 'Apply' : 'Add'),
onPressed: () {
ProjectStep step = ProjectStep(nameController.text, eta, progress);
onChange(step);
Navigator.of(context).pop();
},
),
],
);
});
},
);
}
}