Projects section usable, Sticky headers added
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:sticky_headers/sticky_headers/widget.dart';
|
||||
import 'main.dart' as Main;
|
||||
import 'newActivity.dart';
|
||||
import 'Data.dart';
|
||||
@@ -65,11 +66,12 @@ class _ActivitiesState extends State<Activities> {
|
||||
// progressDialog.update(value: 100);
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
Map<Widget, List<Widget>> activitiesGroups =<Widget, List<Widget>>{};
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// progressDialog = ProgressDialog(context: context);
|
||||
List<Widget> activities = PrintTasks();
|
||||
// List<Widget> activities = PrintTasks();
|
||||
activitiesGroups = PrintTasks();
|
||||
return Scaffold(
|
||||
floatingActionButton: FloatingActionButton.extended(
|
||||
onPressed: () {
|
||||
@@ -171,9 +173,15 @@ class _ActivitiesState extends State<Activities> {
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(0),
|
||||
child: ListView.builder(
|
||||
itemCount: activities.length,
|
||||
itemCount: activitiesGroups.length,
|
||||
itemBuilder: (context, index){
|
||||
return activities[index];
|
||||
// return activities[index];
|
||||
return StickyHeader(
|
||||
|
||||
header:activitiesGroups.keys.toList()[index],
|
||||
content:Column(children: activitiesGroups.values.toList()[index],)
|
||||
);
|
||||
|
||||
})
|
||||
// SingleChildScrollView(
|
||||
// child: Column(
|
||||
@@ -183,8 +191,8 @@ class _ActivitiesState extends State<Activities> {
|
||||
}
|
||||
|
||||
int searchTime = 0;
|
||||
List<Widget> PrintTasks() {
|
||||
List<Widget> _tasks = [];
|
||||
Map<Widget,List<Widget>> PrintTasks() {
|
||||
Map<Widget,List<Widget>> _tasks = <Widget,List<Widget>>{};
|
||||
print('Priting cats : ' + User.taskTypes.length.toString());
|
||||
String lastDate = "";
|
||||
DateFormat dFormat = DateFormat("MM/dd");
|
||||
@@ -239,7 +247,9 @@ class _ActivitiesState extends State<Activities> {
|
||||
if (thisDate != lastDate) {
|
||||
int prodActs = productivtyActs[thisDate] ?? 0;
|
||||
int unProdActs = unproductivtyActs[thisDate] ?? 0;
|
||||
_tasks.add(DateSeperator(thisDate, prodActs, unProdActs));
|
||||
//_tasks.add(DateSeperator(thisDate, prodActs, unProdActs));
|
||||
_tasks.putIfAbsent(DateSeperator(thisDate, prodActs, unProdActs), () => [Container()]);
|
||||
print('adding');
|
||||
lastDate = thisDate;
|
||||
}
|
||||
String name = element.taskType.name;
|
||||
@@ -250,7 +260,7 @@ class _ActivitiesState extends State<Activities> {
|
||||
bool productive = element.taskType.cat?.productive ?? true;
|
||||
Widget task = ActivityCard(context, name, element.startTime, element.endTime, productive, color, element, totalMinutes[thisDate] ?? 0);
|
||||
// print('Activity : ${name} ,sTime: ${element.startTime}, eTime: ${element.endTime}');
|
||||
_tasks.add(task);
|
||||
_tasks.values.toList()[_tasks.length-1].add(task);
|
||||
}
|
||||
//Check for gaps
|
||||
if(i < User.activities.length-1){
|
||||
@@ -258,7 +268,7 @@ class _ActivitiesState extends State<Activities> {
|
||||
if(gap > 10) {
|
||||
Widget addGap = timeGap(User.activities[i].trueStartTime, User.activities[i+1].trueEndTime);
|
||||
|
||||
_tasks.add(addGap);
|
||||
_tasks.values.toList()[_tasks.length-1].add(addGap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -317,9 +327,11 @@ class _ActivitiesState extends State<Activities> {
|
||||
future: Settings.getUntrackedUnproductive(),
|
||||
builder: (context, snapshot) {
|
||||
double prodPercentage = (User.ParseBool(snapshot.data))? ((prodActs / 1440) * 100) : ((prodActs / unprodActs) * 100);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(0, 20, 10, 0),
|
||||
return Container(
|
||||
color: Color(0xFF333333),
|
||||
padding: const EdgeInsets.fromLTRB(0, 10, 10, 10),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
@@ -538,4 +550,5 @@ class _ActivitiesState extends State<Activities> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
List<Activity> selectedActivities = [];
|
||||
|
||||
@@ -72,6 +72,54 @@ class Dialogs{
|
||||
}
|
||||
}
|
||||
|
||||
static showQuestionDialog(String title, String message, {bool hasCancel = false, required Function(bool) onResponse}) async{
|
||||
context=navigatorKey.currentContext;
|
||||
|
||||
if(context!=null) {
|
||||
return showDialog(
|
||||
context: context!,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
|
||||
backgroundColor: Color(0xFF1C1C1C),
|
||||
title: Text(title),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(message)
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
if(hasCancel)MaterialButton(
|
||||
onPressed: (){
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Cancel', style:TextStyle(color: Colors.grey)),
|
||||
),
|
||||
MaterialButton(
|
||||
onPressed: (){
|
||||
onResponse(false);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('No', style:TextStyle(color: Colors.red)),
|
||||
),
|
||||
MaterialButton(
|
||||
onPressed: (){
|
||||
onResponse(true);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Yes', style:TextStyle(color: Colors.green)),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
);
|
||||
}else{
|
||||
print('context is null');
|
||||
}
|
||||
}
|
||||
|
||||
static ongoing() async{
|
||||
List<String>? data= await User.getOngoingData();
|
||||
if(data == null){return;}
|
||||
|
||||
@@ -51,11 +51,12 @@ class _ProjectDetailsState extends State<ProjectDetails> {
|
||||
(chartRange == null) || (chartRange != null && chartRange!.start.isBefore(element.startTime) && chartRange!.end.isAfter(element.endTime));
|
||||
if (element.taskType.relatedProject != null && element.taskType.relatedProject!.name == project.name) {
|
||||
print('here');
|
||||
|
||||
if (firstDateTime == null) {
|
||||
firstDateTime = element.startTime;
|
||||
}
|
||||
lastDateTime = element.startTime;
|
||||
if (withinRange) {
|
||||
if (firstDateTime == null) {
|
||||
firstDateTime = element.startTime;
|
||||
}
|
||||
lastDateTime = element.startTime;
|
||||
|
||||
if (lastDay != element.startTime.day) {
|
||||
if (totalTimeSpent > 0) {
|
||||
@@ -321,11 +322,37 @@ class _ProjectDetailsState extends State<ProjectDetails> {
|
||||
child: Column(
|
||||
children: [
|
||||
Text('Actions'),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
if(project.steps.length<=0)ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.green,
|
||||
),
|
||||
onPressed: () {
|
||||
Dialogs.showQuestionDialog("WARNING!", 'You will lose all data about this project if you continue!\nAre you sure you want to delete?', onResponse: (value){
|
||||
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
FaIcon(FontAwesomeIcons.check),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text('Complete'),
|
||||
],
|
||||
)),
|
||||
ElevatedButton(
|
||||
onPressed: () {},
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(MaterialPageRoute(builder: (context)=>NewProject(multiline: project.steps.isNotEmpty, projectName: project.name, selectedCategory: project.cat!.name,m_steps: project.steps,)));
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
FaIcon(FontAwesomeIcons.edit),
|
||||
@@ -339,7 +366,11 @@ class _ProjectDetailsState extends State<ProjectDetails> {
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.red,
|
||||
),
|
||||
onPressed: () {},
|
||||
onPressed: () {
|
||||
Dialogs.showQuestionDialog("WARNING!", 'You will lose all data about this project if you continue!\nAre you sure you want to delete?', onResponse: (value){
|
||||
|
||||
});
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
FaIcon(FontAwesomeIcons.deleteLeft),
|
||||
@@ -370,10 +401,25 @@ class _ProjectDetailsState extends State<ProjectDetails> {
|
||||
ProjectStep value = project.steps[i];
|
||||
_steps.add(Row(
|
||||
children: [
|
||||
InkWell(onTap: (){
|
||||
Dialogs.completeStepDialog(project,(date) {
|
||||
User.UserOperations.CompleteProjectStep(project, project.steps[i], date);
|
||||
}, project.steps[i]);
|
||||
InkWell(onTap: ()async{
|
||||
if(project.steps[i].finishedDate!= null){
|
||||
await Dialogs.showQuestionDialog('Are you sure?', 'Do you want to undone following step?\n\n${project.steps[i].stepName}', onResponse: (value)async{
|
||||
if(value==true){
|
||||
await User.UserOperations.UndoProjectStep(project, project.steps[i]);
|
||||
}
|
||||
|
||||
});
|
||||
setState(() {
|
||||
|
||||
});
|
||||
}else {
|
||||
await Dialogs.completeStepDialog(project, (date)async {
|
||||
await User.UserOperations.CompleteProjectStep(project, project.steps[i], date);
|
||||
}, project.steps[i]);
|
||||
setState(() {
|
||||
|
||||
});
|
||||
}
|
||||
},child: Container(margin:EdgeInsets.all(2),child: Icon((project.steps[i].finishedDate!= null) ?Icons.check_box : Icons.check_box_outline_blank))),
|
||||
Expanded(
|
||||
child: Container(
|
||||
|
||||
@@ -1180,6 +1180,47 @@ class UserOperations {
|
||||
await executeQueries();
|
||||
}
|
||||
|
||||
static Future<void> UndoProjectStep(Project project, ProjectStep step) async {
|
||||
|
||||
project.steps.forEach((element) {
|
||||
if(element.stepName == step.stepName){
|
||||
element.finishedDate = null;
|
||||
}
|
||||
});
|
||||
|
||||
Map<String, String> queryBody = <String, String>{
|
||||
'name': username+project.name,
|
||||
'username': username,
|
||||
'steps': jsonEncode(project.steps),
|
||||
};
|
||||
|
||||
if (cacheEnabled) {
|
||||
//Add Query
|
||||
Map<String, Object> query = {Queries.colLink: 'update_projectSteps', Queries.colData: jsonEncode(queryBody)};
|
||||
|
||||
print("adding new query ${query[Queries.colLink]} : ${jsonEncode(queryBody)}");
|
||||
|
||||
await cacheDb.insert('Queries', query);
|
||||
await cacheDb.rawUpdate("UPDATE Projects SET steps='${jsonEncode(project.steps)}' WHERE ${Project.colName}='${project.name}'");
|
||||
//update Cache
|
||||
// Map<String, Object> data = {Project.colName: username+name, Project.colCat: category, Project.colSteps: jsonEncode(steps),Project.colEta: eta, Project.colDeadline: deadline.toString()};
|
||||
// await cacheDb.insert('Projects', data);
|
||||
await refreshUserData(forceOffline: true);
|
||||
} else {
|
||||
try {
|
||||
http.Response queryResponse = (await http.post(Uri.parse('http://161.97.127.136/task_tracker/update_projectSteps.php'), body: queryBody));
|
||||
print("Query executed : Results{${queryResponse.body}");
|
||||
if (queryResponse.body.toLowerCase().contains("success")) {
|
||||
//Success
|
||||
}
|
||||
} catch (e) {
|
||||
print('NC: Error completing prjctStep $e}');
|
||||
}
|
||||
}
|
||||
|
||||
await executeQueries();
|
||||
}
|
||||
|
||||
static Future<void> deleteTask(String name, {bulk = false}) async {
|
||||
Map<String, String> queryBody = <String, String>{
|
||||
'id': username + name,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:ui';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -19,7 +20,10 @@ class _WelcomePageState extends State<WelcomePage> {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
body: Container(
|
||||
color: Colors.pink,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(colors: [Colors.pink, Colors.purple],stops: [0,1],begin: Alignment.topLeft, end: Alignment.bottomRight)
|
||||
),
|
||||
//color: Colors.pink,
|
||||
child: Flex(
|
||||
direction: Axis.vertical,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
@@ -90,7 +94,10 @@ class _SignInPageState extends State<SignInPage> {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
body: Container(
|
||||
color: Colors.deepPurpleAccent,
|
||||
// color: Colors.deepPurpleAccent,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(colors: [Colors.deepPurple, Colors.purple],stops: [0,1],begin: Alignment.topLeft, end: Alignment.bottomRight)
|
||||
),
|
||||
child: Flex(
|
||||
direction: Axis.vertical,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
@@ -182,7 +189,10 @@ class _onlineLoginPageState extends State<onlineLoginPage>
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
body: Container(
|
||||
color: Colors.purpleAccent,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(colors: [Colors.blue, Colors.deepPurpleAccent],stops: [0,1],begin: Alignment.topLeft, end: Alignment.bottomRight)
|
||||
),
|
||||
// color: Colors.purpleAccent,
|
||||
child: Flex(
|
||||
direction: Axis.vertical,
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
@@ -210,7 +220,7 @@ class _onlineLoginPageState extends State<onlineLoginPage>
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
color: Colors.purple),
|
||||
color: Colors.black26),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: TabBar(
|
||||
@@ -220,8 +230,8 @@ class _onlineLoginPageState extends State<onlineLoginPage>
|
||||
borderRadius:
|
||||
BorderRadius.circular(10)),
|
||||
tabs: [
|
||||
TabItem('Our Account'),
|
||||
TabItem('OAuth')
|
||||
TabItem('Login / Register'),
|
||||
TabItem('Or, Continue with')
|
||||
],
|
||||
))),
|
||||
Divider(
|
||||
@@ -236,7 +246,7 @@ class _onlineLoginPageState extends State<onlineLoginPage>
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
color: Colors.purple),
|
||||
color: Colors.black26),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
@@ -253,18 +263,18 @@ class _onlineLoginPageState extends State<onlineLoginPage>
|
||||
)),
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(15),
|
||||
padding: EdgeInsets.symmetric(horizontal: 15,vertical: 0),
|
||||
child: TextField(
|
||||
controller: usernameController,
|
||||
autocorrect: false,
|
||||
style: TextStyle(
|
||||
color: Colors.black,
|
||||
// color: Colors.black,
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Username',
|
||||
filled: true,
|
||||
fillColor:
|
||||
Colors.white,
|
||||
Colors.white12,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius
|
||||
@@ -276,7 +286,7 @@ class _onlineLoginPageState extends State<onlineLoginPage>
|
||||
Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: EdgeInsets.fromLTRB(
|
||||
10, 10, 10, 0),
|
||||
10, 0, 10, 0),
|
||||
child: Text(
|
||||
'Password',
|
||||
style:
|
||||
@@ -284,7 +294,7 @@ class _onlineLoginPageState extends State<onlineLoginPage>
|
||||
)),
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(15),
|
||||
padding: EdgeInsets.symmetric(horizontal: 15,vertical: 0),
|
||||
child: TextField(
|
||||
controller: passwordController,
|
||||
obscureText: true,
|
||||
@@ -293,13 +303,13 @@ class _onlineLoginPageState extends State<onlineLoginPage>
|
||||
style: TextStyle(
|
||||
fontWeight:
|
||||
FontWeight.bold,
|
||||
color: Colors.black,
|
||||
// color: Colors.black,
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Password',
|
||||
filled: true,
|
||||
fillColor:
|
||||
Colors.white,
|
||||
Colors.white12,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius:
|
||||
BorderRadius
|
||||
@@ -329,7 +339,7 @@ class _onlineLoginPageState extends State<onlineLoginPage>
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
color: Colors.purple),
|
||||
color: Colors.black26),
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
@@ -339,7 +349,7 @@ class _onlineLoginPageState extends State<onlineLoginPage>
|
||||
height: 50,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.green,
|
||||
primary: Colors.blue,
|
||||
),
|
||||
onPressed: (){
|
||||
final provider = Provider.of<GoogleSignInProvider>(context, listen:false);
|
||||
@@ -354,9 +364,9 @@ class _onlineLoginPageState extends State<onlineLoginPage>
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(Icons.android),
|
||||
FaIcon(FontAwesomeIcons.google),
|
||||
SizedBox(width: 20,),
|
||||
Text("Sign with Google", style: TextStyle(fontSize: 20))
|
||||
Text("Google", style: TextStyle(fontSize: 20))
|
||||
],)),
|
||||
),
|
||||
Divider(height: 50,),
|
||||
|
||||
@@ -90,7 +90,10 @@ class _SplashScreenState extends State<SplashScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: Colors.redAccent,
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(colors: [Colors.lightBlue, Colors.blue],stops: [0,1],begin: Alignment.topLeft, end: Alignment.bottomRight)
|
||||
),
|
||||
// color: Colors.redAccent,
|
||||
padding: EdgeInsets.all(80),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
|
||||
@@ -553,6 +553,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
sticky_headers:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: sticky_headers
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -30,6 +30,7 @@ dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
sticky_headers: ^0.2.0
|
||||
flutter_switch: ^0.3.2
|
||||
sqflite_common_ffi: ^2.1.0+2
|
||||
flutter_spinkit: ^5.1.0
|
||||
|
||||
Reference in New Issue
Block a user