From 4a76558fc4b2ca6d93b9d656eb2178734fadbe4a Mon Sep 17 00:00:00 2001 From: Yashvardhan Arora Date: Mon, 18 Oct 2021 13:42:11 +0530 Subject: [PATCH 01/28] Separate API url for prod and dev --- frontend/.env.development | 1 + frontend/.env.production | 1 + frontend/src/URL.js | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 frontend/.env.development create mode 100644 frontend/.env.production diff --git a/frontend/.env.development b/frontend/.env.development new file mode 100644 index 0000000..e96244c --- /dev/null +++ b/frontend/.env.development @@ -0,0 +1 @@ +REACT_APP_API_ENDPOINT = https://notefy-test.herokuapp.com \ No newline at end of file diff --git a/frontend/.env.production b/frontend/.env.production new file mode 100644 index 0000000..3b28781 --- /dev/null +++ b/frontend/.env.production @@ -0,0 +1 @@ +REACT_APP_API_ENDPOINT = https://notefyapi.servatom.com \ No newline at end of file diff --git a/frontend/src/URL.js b/frontend/src/URL.js index ccf1eb7..18f70a4 100644 --- a/frontend/src/URL.js +++ b/frontend/src/URL.js @@ -1,4 +1,4 @@ -const URL = 'https://notefyapi.servatom.com'; +const URL = process.env.REACT_APP_API_ENDPOINT; export default URL; From af0b7db3e2c8a167bd924e9a0401069061060959 Mon Sep 17 00:00:00 2001 From: rdotjain Date: Mon, 18 Oct 2021 22:09:30 +0530 Subject: [PATCH 02/28] Enable gunicorn logging --- backend/Dockerfile | 1 + backend/docker-compose.yml | 1 + backend/run.sh | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 4bc7f8e..e13c665 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -14,6 +14,7 @@ RUN python -m pip install -r requirements.txt WORKDIR /app COPY . /app +RUN mkdir logs # Creates a non-root user with an explicit UID and adds permission to access the /app folder # For more info, please refer to https://aka.ms/vscode-docker-python-configure-containers diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index df9708a..d94ab73 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -10,4 +10,5 @@ services: - "6969:6969" volumes: - ./db.sqlite3:/app/db.sqlite3 + - logs:/app/logs restart: always \ No newline at end of file diff --git a/backend/run.sh b/backend/run.sh index 16ec178..7e9f706 100755 --- a/backend/run.sh +++ b/backend/run.sh @@ -1 +1 @@ -gunicorn --certfile=origin.pem --keyfile=key.pem --worker-class gevent --bind 0.0.0.0:6969 config.wsgi:application +gunicorn --access-logfile /app/logs/access.log --error-logfile /app/logs/error.log --certfile=origin.pem --keyfile=key.pem --worker-class gevent --bind 0.0.0.0:6969 config.wsgi:application From 7ce3a2907dd0a57b684f85061970652e6bb00a70 Mon Sep 17 00:00:00 2001 From: raghavTinker Date: Sat, 20 Nov 2021 19:57:54 +0000 Subject: [PATCH 03/28] bug in deletion --- backend/run.sh | 3 ++- backend/todo/views.py | 18 +++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/backend/run.sh b/backend/run.sh index 7e9f706..ec95db8 100755 --- a/backend/run.sh +++ b/backend/run.sh @@ -1 +1,2 @@ -gunicorn --access-logfile /app/logs/access.log --error-logfile /app/logs/error.log --certfile=origin.pem --keyfile=key.pem --worker-class gevent --bind 0.0.0.0:6969 config.wsgi:application +#gunicorn --access-logfile /app/logs/access.log --error-logfile /app/logs/error.log --certfile=origin.pem --keyfile=key.pem --worker-class gevent --bind 0.0.0.0:6969 config.wsgi:application +gunicorn --worker-class gevent --certfile=origin.pem --keyfile=key.pem --bind 0.0.0.0:6969 config.wsgi:application \ No newline at end of file diff --git a/backend/todo/views.py b/backend/todo/views.py index 8d07eee..e2bebf9 100644 --- a/backend/todo/views.py +++ b/backend/todo/views.py @@ -40,12 +40,16 @@ def delete(self, request): category = ToDoCategory.objects.get( author=request.user, id=request.data["cat_id"] ) - category.delete() - - # delete all items of category - items = ToDoItem.objects.filter(category=category) - items.delete() - return Response({"message": "Successfully Deleted"}, status=204) + if category is not None: + # delete all items of category + items = ToDoItem.objects.filter(category=category) + items.delete() + # delete category + category.delete() + print("here") + return Response({"message": "Successfully Deleted"}) + else: + return Response({"message": "Category not found"}, status=404) except: return Response({"message": "Error"}) @@ -107,7 +111,7 @@ def delete(self, request): category__author=request.user, id=todo_item ) todo_item.delete() - return Response({"message": "successfully deleted"}, status=204) + return Response({"message": "successfully deleted"}) except: return Response({"message": "Error"}, status=400) From 2247ee1963e074db0abdacf60c39204a91a6d61c Mon Sep 17 00:00:00 2001 From: Nirbhay Makhija Date: Sun, 21 Nov 2021 13:39:32 +0530 Subject: [PATCH 04/28] todo.dart and todo_components.dart and api calls --- App/lib/models/todo.dart | 227 ++++++++++++++++++++++++++++ App/lib/models/todo_components.dart | 31 ++++ 2 files changed, 258 insertions(+) create mode 100644 App/lib/models/todo.dart create mode 100644 App/lib/models/todo_components.dart diff --git a/App/lib/models/todo.dart b/App/lib/models/todo.dart new file mode 100644 index 0000000..b771186 --- /dev/null +++ b/App/lib/models/todo.dart @@ -0,0 +1,227 @@ +// ignore_for_file: avoid_print + +import 'dart:ffi'; + +import 'package:app/models/todo_components.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:http/http.dart' as http; +import 'dart:convert'; + +class ToDo with ChangeNotifier { + List _categories = []; + List _items = []; + + Future createCategory(String key, String categoryName) async { + try { + print('creating new category'); + http.Response response = await http.post( + Uri.parse('https://notefyapi.servatom.com/api/todo/category/'), + headers: {'Authorization': 'Token $key'}, + body: {"category": categoryName}, + ); + final data = jsonDecode(response.body); + print(data); + if (response.statusCode == 200) { + _categories.add( + Category( + id: data["id"], + category: data["category"], + createdAt: data["created_at"], + updatedAt: data["updated_at"], + ), + ); + notifyListeners(); + } else { + throw 'Error in creating a category'; + } + } catch (e) { + print(e); + } + } + + Future getCategoriesList(String key) async { + try { + print('getting list of categories'); + http.Response response = await http.get( + Uri.parse('https://notefyapi.servatom.com/api/todo/category/'), + headers: {'Authorization': 'Token $key'}, + ); + final data = jsonDecode(response.body); + print(data); + if (response.statusCode == 200) { + List tempCategories = data; + for (int i = 0; i < tempCategories.length; i++) { + _categories.add( + Category( + id: tempCategories[i]["id"], + category: tempCategories[i]["category"], + createdAt: tempCategories[i]["created_at"], + updatedAt: tempCategories[i]["updated_at"], + ), + ); + } + notifyListeners(); + } else { + throw 'Error in getting list of categories'; + } + } catch (e) { + print(e); + } + } + + Future updateCategory(String key, String newName, String catId) async { + try { + print('updating a category'); + http.Response response = await http.put( + Uri.parse('https://notefyapi.servatom.com/api/todo/category/'), + headers: {'Authorization': 'Token $key'}, + body: {"cat_id": catId, "category": newName}, + ); + final data = jsonDecode(response.body); + print(data); + int index = _categories.indexWhere((element) => element.id == catId); + if (response.statusCode == 200) { + _categories[index].updatedAt = data["updated_at"]; + _categories[index].category = data["category"]; + notifyListeners(); + } else { + throw "Error in update category"; + } + } catch (e) { + print(e); + } + } + + Future deleteCategory(String key, String catId) async { + try { + print('deleting category'); + http.Response response = await http.delete( + Uri.parse('https://notefyapi.servatom.com/api/todo/category/'), + headers: {'Authorization': 'Token $key'}, + body: {"cat_id": catId}, + ); + if (response.statusCode == 200) { + print('delete succesfully'); + int index = _categories.indexWhere((element) => element.id == catId); + _categories.remove(_categories[index]); + notifyListeners(); + } else { + throw 'Error in deleting note'; + } + } catch (e) { + print(e); + } + } + + Future createItem(String key, String catId, String item) async { + try { + print('creating new item'); + http.Response response = await http.post( + Uri.parse('https://notefyapi.servatom.com/api/todo/item/'), + headers: {'Authorization': 'Token $key'}, + body: {"cat_id": catId, "item": item}, + ); + final data = jsonDecode(response.body); + print(data); + if (response.statusCode == 200) { + _items.add( + TodoItem( + id: data["id"], + categoryId: data["category_id"], + categoryName: data["category"], + createdAt: data["created_at"], + isDone: data["isDone"], + item: data["item"], + updatedAt: data["updated_at"], + ), + ); + notifyListeners(); + } else { + throw 'Error in creating a new item'; + } + } catch (e) { + print(e); + } + } + + Future listAllTodoItems(String key) async { + try { + print('getting all the items as a list'); + http.Response response = await http.get( + Uri.parse('https://notefyapi.servatom.com/api/todo/item/'), + headers: {'Authorization': 'Token $key'}, + ); + final data = jsonDecode(response.body); + print(data); + if (response.statusCode == 200) { + List tempItems = data; + for (int i = 0; i < tempItems.length; i++) { + _items.add( + TodoItem( + id: tempItems[i]["id"], + categoryId: tempItems[i]["category_id"], + categoryName: tempItems[i]["category"], + createdAt: tempItems[i]["created_at"], + isDone: tempItems[i]["isDone"], + item: tempItems[i]["item"], + updatedAt: tempItems[i]["updated_at"], + ), + ); + } + notifyListeners(); + } else { + throw 'Error in getting the list of all items'; + } + } catch (e) { + print(e); + } + } + + Future updateToDoItem( + String key, String itemId, bool isDone, String item) async { + try { + print('updating an item'); + http.Response response = await http.put( + Uri.parse('https://notefyapi.servatom.com/api/todo/item/'), + headers: {'Authorization': 'Token $key'}, + body: {"todo_item_id": itemId, "is_done": isDone, "item": item}, + ); + final data = jsonDecode(response.body); + print(data); + int index = _items.indexWhere((element) => element.id == itemId); + if (response.statusCode == 200) { + _items[index].item = data["item"]; + _items[index].isDone = data["isDone"]; + _items[index].updatedAt = data["updated_at"]; + notifyListeners(); + } else { + throw 'error in updating item'; + } + } catch (e) { + print(e); + } + } + + Future deleteToDoItem(String key, String itemId) async { + try { + print('deleting an item'); + http.Response response = await http.delete( + Uri.parse('https://notefyapi.servatom.com/api/todo/item/'), + headers: {'Authorization': 'Token $key'}, + body: {"todo_item_id": itemId}, + ); + final data = jsonDecode(response.body); + print(data); + int index = _items.indexWhere((element) => element.id == itemId); + if (response.statusCode == 200) { + print('deleted succesfully'); + _items.remove(_items[index]); + notifyListeners(); + } else { + throw 'error in deleting item'; + } + } catch (e) { + print(e); + } + } +} diff --git a/App/lib/models/todo_components.dart b/App/lib/models/todo_components.dart new file mode 100644 index 0000000..a94d210 --- /dev/null +++ b/App/lib/models/todo_components.dart @@ -0,0 +1,31 @@ +class Category { + String id; + String category; + String createdAt; + String updatedAt; + Category({ + required this.id, + required this.category, + required this.createdAt, + required this.updatedAt, + }); +} + +class TodoItem { + String id; + String item; + String categoryName; + bool isDone; + String createdAt; + String updatedAt; + String categoryId; + TodoItem({ + required this.id, + required this.categoryId, + required this.categoryName, + required this.createdAt, + required this.isDone, + required this.item, + required this.updatedAt, + }); +} From 85fdf4f5e06699e6b7e247fa362ec3bb1a3b216b Mon Sep 17 00:00:00 2001 From: Nirbhay Makhija Date: Tue, 23 Nov 2021 22:18:29 +0530 Subject: [PATCH 05/28] fix padding issue on dashboard --- App/lib/screens/dashboard.dart | 113 ++++++++++++++++----------------- 1 file changed, 53 insertions(+), 60 deletions(-) diff --git a/App/lib/screens/dashboard.dart b/App/lib/screens/dashboard.dart index 053feb9..cbf447f 100644 --- a/App/lib/screens/dashboard.dart +++ b/App/lib/screens/dashboard.dart @@ -1,7 +1,5 @@ // ignore_for_file: prefer_const_constructors, use_key_in_widget_constructors, avoid_print, unused_import, curly_braces_in_flow_control_structures - - import 'package:app/models/auth.dart'; import 'package:app/components/drawer.dart'; import 'package:app/components/note_tile.dart'; @@ -26,66 +24,34 @@ class _DashBoardState extends State { List notesList = Provider.of(context, listen: true).notesList; return Scaffold( drawer: DashboardDrawer(), - body: NestedScrollView( - floatHeaderSlivers: true, - headerSliverBuilder: (context, innerBoxIsScrolled) => [ - SliverAppBar( - floating: true, - snap: true, - iconTheme: IconThemeData(color: kbgcolor), - title: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Notefy', - style: TextStyle( - color: kbgcolor, - fontFamily: 'roboto', - ), - ), - Image.asset( - 'images/logo.png', - scale: 10, - ), - ], + appBar: AppBar( + title: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Notefy', + style: TextStyle( + color: kbgcolor, + fontFamily: 'roboto', + ), ), - centerTitle: true, - actions: [ - IconButton( - onPressed: () { - print('hello'); - }, - icon: Icon( - Icons.search, - ), - ) - ], - ), - ], - body: NotificationListener( - onNotification: (notification) { - if (notification.direction == ScrollDirection.forward) { - if (!isVisible) - setState(() { - isVisible = true; - }); - } else if (notification.direction == ScrollDirection.reverse) { - if (isVisible) - setState(() { - isVisible = false; - }); - } - return true; - }, - child: ListView.builder( - itemCount: notesList.length, - itemBuilder: (context, index) { - return NoteTile( - note: notesList[index], - ); - }, - ), + Image.asset( + 'images/logo.png', + scale: 10, + ), + ], ), + centerTitle: true, + actions: [ + IconButton( + onPressed: () { + print('hello'); + }, + icon: Icon( + Icons.search, + ), + ) + ], ), floatingActionButton: isVisible ? FloatingActionButton( @@ -109,6 +75,33 @@ class _DashBoardState extends State { ), ) : null, + body: NotificationListener( + onNotification: (notification) { + if (notification.direction == ScrollDirection.forward) { + if (!isVisible) + setState(() { + isVisible = true; + }); + } else if (notification.direction == ScrollDirection.reverse) { + if (isVisible) + setState(() { + isVisible = false; + }); + } + return true; + }, + child: Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: ListView.builder( + itemCount: notesList.length, + itemBuilder: (context, index) { + return NoteTile( + note: notesList[index], + ); + }, + ), + ), + ), ); } } From d6ed3eaca47909a6d73e822844caddf2b58ecddc Mon Sep 17 00:00:00 2001 From: Nirbhay Makhija Date: Tue, 23 Nov 2021 23:51:49 +0530 Subject: [PATCH 06/28] add tab view and create notesdashboard.dart and tododashboard.dart --- App/lib/models/todo.dart | 4 +- App/lib/screens/dashboard.dart | 123 +++++++++++----------------- App/lib/screens/notesdashboard.dart | 74 +++++++++++++++++ App/lib/screens/tododashboard.dart | 18 ++++ 4 files changed, 142 insertions(+), 77 deletions(-) create mode 100644 App/lib/screens/notesdashboard.dart create mode 100644 App/lib/screens/tododashboard.dart diff --git a/App/lib/models/todo.dart b/App/lib/models/todo.dart index b771186..a4822a0 100644 --- a/App/lib/models/todo.dart +++ b/App/lib/models/todo.dart @@ -1,6 +1,4 @@ -// ignore_for_file: avoid_print - -import 'dart:ffi'; +// ignore_for_file: avoid_print, prefer_final_fields import 'package:app/models/todo_components.dart'; import 'package:flutter/cupertino.dart'; diff --git a/App/lib/screens/dashboard.dart b/App/lib/screens/dashboard.dart index cbf447f..8d4ca7d 100644 --- a/App/lib/screens/dashboard.dart +++ b/App/lib/screens/dashboard.dart @@ -1,4 +1,4 @@ -// ignore_for_file: prefer_const_constructors, use_key_in_widget_constructors, avoid_print, unused_import, curly_braces_in_flow_control_structures +// ignore_for_file: prefer_const_constructors, use_key_in_widget_constructors, avoid_print, unused_import, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables import 'package:app/models/auth.dart'; import 'package:app/components/drawer.dart'; @@ -6,9 +6,13 @@ import 'package:app/components/note_tile.dart'; import 'package:app/constants.dart'; import 'package:app/models/note.dart'; import 'package:app/models/notes.dart'; +import 'package:app/models/theme.dart'; import 'package:app/routers/routenames.dart'; +import 'package:app/screens/notesdashboard.dart'; +import 'package:app/screens/tododashboard.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; +import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; class DashBoard extends StatefulWidget { @@ -21,85 +25,56 @@ class _DashBoardState extends State { @override Widget build(BuildContext context) { - List notesList = Provider.of(context, listen: true).notesList; - return Scaffold( - drawer: DashboardDrawer(), - appBar: AppBar( - title: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Notefy', - style: TextStyle( - color: kbgcolor, - fontFamily: 'roboto', + return DefaultTabController( + length: 2, + child: Scaffold( + drawer: DashboardDrawer(), + appBar: AppBar( + bottom: TabBar( + tabs: [ + Tab( + icon: Icon(Icons.notes), ), - ), - Image.asset( - 'images/logo.png', - scale: 10, - ), - ], - ), - centerTitle: true, - actions: [ - IconButton( - onPressed: () { - print('hello'); - }, - icon: Icon( - Icons.search, - ), - ) - ], - ), - floatingActionButton: isVisible - ? FloatingActionButton( + Tab( + icon: Icon(Icons.check_box), + ), + ], + ), + iconTheme: IconThemeData(color: kbgcolor), + title: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Notefy', + style: TextStyle( + color: kbgcolor, + fontFamily: 'roboto', + ), + ), + Image.asset( + 'images/logo.png', + scale: 10, + ), + ], + ), + centerTitle: true, + actions: [ + IconButton( onPressed: () { - Navigator.pushNamed( - context, - RouteNames.noterscreen, - arguments: Note( - body: '', - title: '', - id: '', - createTime: '', - updateTime: '', - ), - ); + print('hello'); }, - child: Icon( - Icons.add, + icon: Icon( + Icons.search, color: kbgcolor, - size: 30, ), ) - : null, - body: NotificationListener( - onNotification: (notification) { - if (notification.direction == ScrollDirection.forward) { - if (!isVisible) - setState(() { - isVisible = true; - }); - } else if (notification.direction == ScrollDirection.reverse) { - if (isVisible) - setState(() { - isVisible = false; - }); - } - return true; - }, - child: Padding( - padding: EdgeInsets.symmetric(vertical: 20), - child: ListView.builder( - itemCount: notesList.length, - itemBuilder: (context, index) { - return NoteTile( - note: notesList[index], - ); - }, - ), + ], + ), + body: TabBarView( + children: [ + NotesDashBoard(), + ToDoDashBoard(), + ], ), ), ); diff --git a/App/lib/screens/notesdashboard.dart b/App/lib/screens/notesdashboard.dart new file mode 100644 index 0000000..38d7285 --- /dev/null +++ b/App/lib/screens/notesdashboard.dart @@ -0,0 +1,74 @@ +// ignore_for_file: prefer_const_constructors, curly_braces_in_flow_control_structures, use_key_in_widget_constructors + +import 'package:app/components/note_tile.dart'; +import 'package:app/models/note.dart'; +import 'package:app/models/notes.dart'; +import 'package:app/routers/routenames.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:provider/provider.dart'; +import 'package:app/constants.dart'; + +class NotesDashBoard extends StatefulWidget { + @override + State createState() => _NotesDashBoardState(); +} + +class _NotesDashBoardState extends State { + bool isVisible = true; + @override + Widget build(BuildContext context) { + List notesList = Provider.of(context, listen: true).notesList; + return Scaffold( + floatingActionButton: isVisible + ? FloatingActionButton( + onPressed: () { + Navigator.pushNamed( + context, + RouteNames.noterscreen, + arguments: Note( + body: '', + title: '', + id: '', + createTime: '', + updateTime: '', + ), + ); + }, + child: Icon( + Icons.add, + color: kbgcolor, + size: 30, + ), + ) + : null, + body: NotificationListener( + onNotification: (notification) { + if (notification.direction == ScrollDirection.forward) { + if (!isVisible) + setState(() { + isVisible = true; + }); + } else if (notification.direction == ScrollDirection.reverse) { + if (isVisible) + setState(() { + isVisible = false; + }); + } + return true; + }, + child: Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: ListView.builder( + itemCount: notesList.length, + itemBuilder: (context, index) { + return NoteTile( + note: notesList[index], + ); + }, + ), + ), + ), + ); + } +} diff --git a/App/lib/screens/tododashboard.dart b/App/lib/screens/tododashboard.dart new file mode 100644 index 0000000..f06f3cd --- /dev/null +++ b/App/lib/screens/tododashboard.dart @@ -0,0 +1,18 @@ +// ignore_for_file: use_key_in_widget_constructors, avoid_unnecessary_containers, prefer_const_constructors + +import 'package:flutter/material.dart'; + +class ToDoDashBoard extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + child: Center( + child: Text( + 'To Do dash board', + ), + ), + ), + ); + } +} From 692242c67807873003ff1db6a34de25c96ad91d7 Mon Sep 17 00:00:00 2001 From: Nirbhay Makhija Date: Thu, 25 Nov 2021 22:06:20 +0530 Subject: [PATCH 07/28] get categories list working and categories tile added --- App/lib/main.dart | 2 + App/lib/models/auth.dart | 3 ++ App/lib/models/todo.dart | 18 ++++++-- App/lib/screens/loginscreen.dart | 5 +++ App/lib/screens/tododashboard.dart | 71 +++++++++++++++++++++++++++--- 5 files changed, 90 insertions(+), 9 deletions(-) diff --git a/App/lib/main.dart b/App/lib/main.dart index c056c11..8c471af 100644 --- a/App/lib/main.dart +++ b/App/lib/main.dart @@ -2,6 +2,7 @@ import 'package:app/models/notes.dart'; import 'package:app/models/theme.dart'; +import 'package:app/models/todo.dart'; import 'package:app/models/user.dart'; import 'package:app/routers/approutes.dart'; import 'package:app/routers/routenames.dart'; @@ -23,6 +24,7 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider.value(value: Notes()), ChangeNotifierProvider.value(value: User()), ChangeNotifierProvider.value(value: CustomTheme()), + ChangeNotifierProvider.value(value: ToDo()), ], child: Homew(), ); diff --git a/App/lib/models/auth.dart b/App/lib/models/auth.dart index 3b9e68b..e8ae951 100644 --- a/App/lib/models/auth.dart +++ b/App/lib/models/auth.dart @@ -2,6 +2,7 @@ import 'package:app/models/notes.dart'; import 'package:app/models/theme.dart'; +import 'package:app/models/todo.dart'; import 'package:app/models/user.dart'; import 'package:app/routers/routenames.dart'; import 'package:flutter/cupertino.dart'; @@ -106,6 +107,8 @@ class Auth with ChangeNotifier { Provider.of(context, listen: false).getIsTheme(); Provider.of(context, listen: false).clearList(); Provider.of(context, listen: false).getList(key); + Provider.of(context, listen: false).getCategoriesList(key); + Provider.of(context, listen: false).clearList(); Navigator.pushReplacementNamed(context, RouteNames.dashboard); } } diff --git a/App/lib/models/todo.dart b/App/lib/models/todo.dart index a4822a0..2512cec 100644 --- a/App/lib/models/todo.dart +++ b/App/lib/models/todo.dart @@ -9,6 +9,11 @@ class ToDo with ChangeNotifier { List _categories = []; List _items = []; + List getCateList() { + print(_categories); + return [..._categories]; + } + Future createCategory(String key, String categoryName) async { try { print('creating new category'); @@ -22,7 +27,7 @@ class ToDo with ChangeNotifier { if (response.statusCode == 200) { _categories.add( Category( - id: data["id"], + id: data["id"].toString(), category: data["category"], createdAt: data["created_at"], updatedAt: data["updated_at"], @@ -51,7 +56,7 @@ class ToDo with ChangeNotifier { for (int i = 0; i < tempCategories.length; i++) { _categories.add( Category( - id: tempCategories[i]["id"], + id: tempCategories[i]["id"].toString(), category: tempCategories[i]["category"], createdAt: tempCategories[i]["created_at"], updatedAt: tempCategories[i]["updated_at"], @@ -124,7 +129,7 @@ class ToDo with ChangeNotifier { if (response.statusCode == 200) { _items.add( TodoItem( - id: data["id"], + id: data["id"].toString(), categoryId: data["category_id"], categoryName: data["category"], createdAt: data["created_at"], @@ -156,7 +161,7 @@ class ToDo with ChangeNotifier { for (int i = 0; i < tempItems.length; i++) { _items.add( TodoItem( - id: tempItems[i]["id"], + id: tempItems[i]["id"].toString(), categoryId: tempItems[i]["category_id"], categoryName: tempItems[i]["category"], createdAt: tempItems[i]["created_at"], @@ -222,4 +227,9 @@ class ToDo with ChangeNotifier { print(e); } } + + void clearList() { + _categories = []; + _items = []; + } } diff --git a/App/lib/screens/loginscreen.dart b/App/lib/screens/loginscreen.dart index 3dfa2b7..fd5be2d 100644 --- a/App/lib/screens/loginscreen.dart +++ b/App/lib/screens/loginscreen.dart @@ -5,6 +5,7 @@ import 'package:app/components/error_box.dart'; import 'package:app/components/inputfield.dart'; import 'package:app/constants.dart'; import 'package:app/models/notes.dart'; +import 'package:app/models/todo.dart'; import 'package:app/models/user.dart'; import 'package:app/routers/routenames.dart'; import 'package:flutter/material.dart'; @@ -102,6 +103,10 @@ class _LoginScreenState extends State { .clearList(); Provider.of(context, listen: false) .getList(key); + + Provider.of(context, listen: false) + .getCategoriesList(key); + Provider.of(context, listen: false).clearList(); Navigator.pushNamed(context, RouteNames.dashboard); } catch (e) { showDialog( diff --git a/App/lib/screens/tododashboard.dart b/App/lib/screens/tododashboard.dart index f06f3cd..b21f10d 100644 --- a/App/lib/screens/tododashboard.dart +++ b/App/lib/screens/tododashboard.dart @@ -1,15 +1,76 @@ -// ignore_for_file: use_key_in_widget_constructors, avoid_unnecessary_containers, prefer_const_constructors +// ignore_for_file: use_key_in_widget_constructors, avoid_unnecessary_containers, prefer_const_constructors, prefer_const_literals_to_create_immutables, avoid_print, must_be_immutable +import 'package:app/constants.dart'; +import 'package:app/models/theme.dart'; +import 'package:app/models/todo.dart'; +import 'package:app/models/todo_components.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class ToDoDashBoard extends StatelessWidget { @override Widget build(BuildContext context) { + List categoriesList = Provider.of(context).getCateList(); return Scaffold( - body: Container( - child: Center( - child: Text( - 'To Do dash board', + body: Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: ListView.builder( + itemCount: categoriesList.length, + itemBuilder: (context, index) { + return TodoCategoryTile( + categoryName: categoriesList[index].category, + ); + }, + ), + ), + ); + } +} + +class TodoCategoryTile extends StatelessWidget { + String categoryName; + TodoCategoryTile({required this.categoryName}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.only( + left: 20, + right: 20, + bottom: 10, + ), + child: GestureDetector( + onTap: () { + print('todo category tile clicked'); + }, + child: SizedBox( + height: 125, + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + 20, + ), + ), + color: Provider.of(context).isTheme + ? kgreyblack + : klightpink, + elevation: 5, + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: 15, + vertical: 10, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text( + categoryName, + style: TextStyle(color: kNoteTitle), + ), + ], + ), + ), ), ), ), From 9b145d920650fad2e7d925903c0f7a821be50464 Mon Sep 17 00:00:00 2001 From: Nirbhay Makhija Date: Thu, 25 Nov 2021 23:11:55 +0530 Subject: [PATCH 08/28] working on bottom modal sheet for adding new category --- App/lib/screens/add_new_todo.dart | 34 +++++++++++++++ App/lib/screens/tododashboard.dart | 66 +++++++++++++++++++++++++----- 2 files changed, 89 insertions(+), 11 deletions(-) create mode 100644 App/lib/screens/add_new_todo.dart diff --git a/App/lib/screens/add_new_todo.dart b/App/lib/screens/add_new_todo.dart new file mode 100644 index 0000000..f29fa97 --- /dev/null +++ b/App/lib/screens/add_new_todo.dart @@ -0,0 +1,34 @@ +// ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors, prefer_const_literals_to_create_immutables + +import 'package:app/models/theme.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class BottomModalSheetTodo extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + color: Provider.of(context).isTheme + ? Color(0xFF000000) + : Color(0xFF757575), + child: Container( + decoration: BoxDecoration( + color: Colors.yellow, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + 'Add Category', + textAlign: TextAlign.center, + ), + ], + ), + ), + ); + } +} diff --git a/App/lib/screens/tododashboard.dart b/App/lib/screens/tododashboard.dart index b21f10d..e4b7351 100644 --- a/App/lib/screens/tododashboard.dart +++ b/App/lib/screens/tododashboard.dart @@ -1,26 +1,70 @@ -// ignore_for_file: use_key_in_widget_constructors, avoid_unnecessary_containers, prefer_const_constructors, prefer_const_literals_to_create_immutables, avoid_print, must_be_immutable +// ignore_for_file: use_key_in_widget_constructors, avoid_unnecessary_containers, prefer_const_constructors, prefer_const_literals_to_create_immutables, avoid_print, must_be_immutable, curly_braces_in_flow_control_structures import 'package:app/constants.dart'; import 'package:app/models/theme.dart'; import 'package:app/models/todo.dart'; import 'package:app/models/todo_components.dart'; +import 'package:app/screens/add_new_todo.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; import 'package:provider/provider.dart'; -class ToDoDashBoard extends StatelessWidget { +class ToDoDashBoard extends StatefulWidget { + @override + State createState() => _ToDoDashBoardState(); +} + +class _ToDoDashBoardState extends State { + bool isVisible = true; @override Widget build(BuildContext context) { List categoriesList = Provider.of(context).getCateList(); return Scaffold( - body: Padding( - padding: EdgeInsets.symmetric(vertical: 20), - child: ListView.builder( - itemCount: categoriesList.length, - itemBuilder: (context, index) { - return TodoCategoryTile( - categoryName: categoriesList[index].category, - ); - }, + floatingActionButton: isVisible + ? FloatingActionButton( + onPressed: () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + builder: (context) => SingleChildScrollView( + child: Container( + child: BottomModalSheetTodo(), + ), + ), + ); + }, + child: Icon( + Icons.add, + color: kbgcolor, + size: 30, + ), + ) + : null, + body: NotificationListener( + onNotification: (notification) { + if (notification.direction == ScrollDirection.forward) { + if (!isVisible) + setState(() { + isVisible = true; + }); + } else if (notification.direction == ScrollDirection.reverse) { + if (isVisible) + setState(() { + isVisible = false; + }); + } + return true; + }, + child: Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: ListView.builder( + itemCount: categoriesList.length, + itemBuilder: (context, index) { + return TodoCategoryTile( + categoryName: categoriesList[index].category, + ); + }, + ), ), ), ); From 08a53449f6b60282551c650ec61975e7d84b0f3a Mon Sep 17 00:00:00 2001 From: Nirbhay Makhija Date: Fri, 26 Nov 2021 00:07:34 +0530 Subject: [PATCH 09/28] add category bottom modal sheet created --- App/lib/screens/add_new_todo.dart | 51 +++++++++++++++++++++++++++++- App/lib/screens/tododashboard.dart | 7 ++-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/App/lib/screens/add_new_todo.dart b/App/lib/screens/add_new_todo.dart index f29fa97..ea9de10 100644 --- a/App/lib/screens/add_new_todo.dart +++ b/App/lib/screens/add_new_todo.dart @@ -1,10 +1,14 @@ // ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors, prefer_const_literals_to_create_immutables +import 'package:app/constants.dart'; +import 'package:app/models/auth.dart'; import 'package:app/models/theme.dart'; +import 'package:app/models/todo.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class BottomModalSheetTodo extends StatelessWidget { + late String text; @override Widget build(BuildContext context) { return Container( @@ -12,8 +16,12 @@ class BottomModalSheetTodo extends StatelessWidget { ? Color(0xFF000000) : Color(0xFF757575), child: Container( + padding: EdgeInsets.symmetric( + horizontal: 30, + vertical: 20, + ), decoration: BoxDecoration( - color: Colors.yellow, + color: kyellow, borderRadius: BorderRadius.only( topLeft: Radius.circular(20), topRight: Radius.circular(20), @@ -25,6 +33,47 @@ class BottomModalSheetTodo extends StatelessWidget { Text( 'Add Category', textAlign: TextAlign.center, + style: TextStyle( + fontSize: 30, + color: kbgcolor, + ), + ), + TextField( + autofocus: true, + textAlign: TextAlign.center, + onChanged: (value) { + text = value; + }, + onSubmitted: (value) { + String key = Provider.of(context, listen: false).key; + Provider.of(context, listen: false) + .createCategory(key, text); + Navigator.pop(context); + }, + style: TextStyle( + fontSize: 18, + ), + ), + SizedBox( + height: 15, + ), + FlatButton( + color: Provider.of(context).isTheme + ? kgreyblack + : kpink, + onPressed: () { + String key = Provider.of(context, listen: false).key; + Provider.of(context, listen: false) + .createCategory(key, text); + Navigator.pop(context); + }, + child: Padding( + padding: EdgeInsets.all(10.0), + child: Text( + 'Add', + style: TextStyle(color: Colors.white), + ), + ), ), ], ), diff --git a/App/lib/screens/tododashboard.dart b/App/lib/screens/tododashboard.dart index e4b7351..8d8cee2 100644 --- a/App/lib/screens/tododashboard.dart +++ b/App/lib/screens/tododashboard.dart @@ -27,8 +27,11 @@ class _ToDoDashBoardState extends State { context: context, isScrollControlled: true, builder: (context) => SingleChildScrollView( - child: Container( - child: BottomModalSheetTodo(), + child: Padding( + padding: MediaQuery.of(context).viewInsets, + child: Container( + child: BottomModalSheetTodo(), + ), ), ), ); From 14691dd0e5ccbca21a9e937961427ec008b7175b Mon Sep 17 00:00:00 2001 From: Nirbhay Makhija Date: Fri, 26 Nov 2021 23:54:16 +0530 Subject: [PATCH 10/28] add item screen and make bottom modal sheet for both item and category --- App/lib/routers/approutes.dart | 8 ++ App/lib/routers/routenames.dart | 1 + App/lib/screens/add_new_todo.dart | 63 +++++++++---- App/lib/screens/items_screen.dart | 141 +++++++++++++++++++++++++++++ App/lib/screens/tododashboard.dart | 22 +++-- 5 files changed, 212 insertions(+), 23 deletions(-) create mode 100644 App/lib/screens/items_screen.dart diff --git a/App/lib/routers/approutes.dart b/App/lib/routers/approutes.dart index 67ace5c..32a78f5 100644 --- a/App/lib/routers/approutes.dart +++ b/App/lib/routers/approutes.dart @@ -1,6 +1,8 @@ import 'package:app/models/note.dart'; +import 'package:app/models/todo_components.dart'; import 'package:app/routers/routenames.dart'; import 'package:app/screens/dashboard.dart'; +import 'package:app/screens/items_screen.dart'; import 'package:app/screens/loginscreen.dart'; import 'package:app/screens/mainscreen.dart'; import 'package:app/screens/notescreen.dart'; @@ -32,6 +34,12 @@ class AppRoutes { return MaterialPageRoute(builder: (_) => ResetPassScreen()); case RouteNames.serverdownpage: return MaterialPageRoute(builder: (_) => ServerDown()); + case RouteNames.itemscreen: + var cat = settings.arguments as Category; + return MaterialPageRoute( + builder: (_) => ItemsScreen( + category: cat, + )); case RouteNames.noterscreen: var notes = settings.arguments as Note; return MaterialPageRoute( diff --git a/App/lib/routers/routenames.dart b/App/lib/routers/routenames.dart index d9b58bb..9d90c71 100644 --- a/App/lib/routers/routenames.dart +++ b/App/lib/routers/routenames.dart @@ -9,4 +9,5 @@ class RouteNames { static const String splash = '/splash'; static const String resetpasswordscreen = '/resetpassword'; static const String serverdownpage = '/serverdown'; + static const String itemscreen = '/itemscreen'; } diff --git a/App/lib/screens/add_new_todo.dart b/App/lib/screens/add_new_todo.dart index ea9de10..40a44e3 100644 --- a/App/lib/screens/add_new_todo.dart +++ b/App/lib/screens/add_new_todo.dart @@ -1,4 +1,4 @@ -// ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors, prefer_const_literals_to_create_immutables +// ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors, prefer_const_literals_to_create_immutables, must_be_immutable import 'package:app/constants.dart'; import 'package:app/models/auth.dart'; @@ -9,6 +9,16 @@ import 'package:provider/provider.dart'; class BottomModalSheetTodo extends StatelessWidget { late String text; + final String title; + final String buttonText; + final String catId; + final bool isCategory; // true for category and false for item + BottomModalSheetTodo({ + required this.title, + required this.buttonText, + required this.isCategory, + required this.catId, + }); @override Widget build(BuildContext context) { return Container( @@ -31,7 +41,7 @@ class BottomModalSheetTodo extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( - 'Add Category', + title, textAlign: TextAlign.center, style: TextStyle( fontSize: 30, @@ -57,21 +67,40 @@ class BottomModalSheetTodo extends StatelessWidget { SizedBox( height: 15, ), - FlatButton( - color: Provider.of(context).isTheme - ? kgreyblack - : kpink, - onPressed: () { - String key = Provider.of(context, listen: false).key; - Provider.of(context, listen: false) - .createCategory(key, text); - Navigator.pop(context); - }, - child: Padding( - padding: EdgeInsets.all(10.0), - child: Text( - 'Add', - style: TextStyle(color: Colors.white), + Container( + decoration: BoxDecoration( + color: Provider.of(context).isTheme + ? kgreyblack + : kpink, + borderRadius: BorderRadius.all( + Radius.circular(8), + ), + ), + child: GestureDetector( + onTap: () { + String key = Provider.of(context, listen: false).key; + if (isCategory) { + // creating a category + Provider.of(context, listen: false) + .createCategory(key, text); + } else { + // creating an item + Provider.of(context, listen: false).createItem( + key, + catId, // get catID + text, + ); + } + Navigator.pop(context); + }, + child: Center( + child: Padding( + padding: EdgeInsets.all(10.0), + child: Text( + buttonText, + style: TextStyle(color: Colors.white, fontSize: 20), + ), + ), ), ), ), diff --git a/App/lib/screens/items_screen.dart b/App/lib/screens/items_screen.dart new file mode 100644 index 0000000..06adf68 --- /dev/null +++ b/App/lib/screens/items_screen.dart @@ -0,0 +1,141 @@ +// ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors, prefer_const_constructors_in_immutables, curly_braces_in_flow_control_structures + +import 'package:app/constants.dart'; +import 'package:app/models/theme.dart'; +import 'package:app/models/todo_components.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:provider/provider.dart'; + +import 'add_new_todo.dart'; + +class ItemsScreen extends StatefulWidget { + final Category category; + ItemsScreen({required this.category}); + @override + State createState() => _ItemsScreenState(); +} + +class _ItemsScreenState extends State { + bool isVisible = true; + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Provider.of(context, listen: false).isTheme + ? kbgcolor + : Colors.white, + floatingActionButton: isVisible + ? FloatingActionButton( + onPressed: () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + builder: (context) => SingleChildScrollView( + child: Padding( + padding: MediaQuery.of(context).viewInsets, + child: BottomModalSheetTodo( + title: 'Add Item', + buttonText: 'Add', + isCategory: false, + catId: widget.category.category, + ), + ), + ), + ); + }, + child: Icon( + Icons.add, + color: kbgcolor, + size: 30, + ), + ) + : null, + appBar: AppBar( + backgroundColor: + Provider.of(context, listen: false).isTheme + ? kbgcolor + : Colors.white, + elevation: 0, + leading: IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: Icon( + Icons.keyboard_arrow_left, + color: Provider.of(context, listen: false).isTheme + ? kyellow + : kpink, + size: 35, + ), + ), + automaticallyImplyLeading: false, + actions: [ + IconButton( + onPressed: () {}, + icon: Icon(Icons.delete, color: Colors.red), + ), + ], + ), + body: NotificationListener( + onNotification: (notification) { + if (notification.direction == ScrollDirection.forward) { + if (!isVisible) + setState(() { + isVisible = true; + }); + } else if (notification.direction == ScrollDirection.reverse) { + if (isVisible) + setState(() { + isVisible = false; + }); + } + return true; + }, + child: Container( + padding: EdgeInsets.only( + left: 20, + right: 20, + bottom: 20, + ), + child: Column( + children: [ + TextFormField( + initialValue: widget.category.category, + textAlign: TextAlign.center, + onChanged: (value) { + // change the category name + }, + maxLines: 1, + style: TextStyle( + color: + Provider.of(context, listen: false).isTheme + ? Colors.white + : Colors.black, + fontSize: 30, + ), + decoration: InputDecoration( + hintText: 'Category Name', + border: OutlineInputBorder( + borderSide: BorderSide.none, + borderRadius: BorderRadius.circular(20), + ), + hintStyle: TextStyle( + fontSize: 25, + color: + Provider.of(context, listen: false).isTheme + ? Colors.grey + : Colors.black54, + ), + ), + onFieldSubmitted: (value) {}, + ), + Expanded( + child: Text('items'), + ), + ], + ), + ), + ), + ); + } +} diff --git a/App/lib/screens/tododashboard.dart b/App/lib/screens/tododashboard.dart index 8d8cee2..465cb9b 100644 --- a/App/lib/screens/tododashboard.dart +++ b/App/lib/screens/tododashboard.dart @@ -4,6 +4,7 @@ import 'package:app/constants.dart'; import 'package:app/models/theme.dart'; import 'package:app/models/todo.dart'; import 'package:app/models/todo_components.dart'; +import 'package:app/routers/routenames.dart'; import 'package:app/screens/add_new_todo.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; @@ -30,7 +31,12 @@ class _ToDoDashBoardState extends State { child: Padding( padding: MediaQuery.of(context).viewInsets, child: Container( - child: BottomModalSheetTodo(), + child: BottomModalSheetTodo( + title: 'Add Category', + buttonText: 'Add', + isCategory: true, + catId: '', + ), ), ), ), @@ -64,7 +70,7 @@ class _ToDoDashBoardState extends State { itemCount: categoriesList.length, itemBuilder: (context, index) { return TodoCategoryTile( - categoryName: categoriesList[index].category, + category: categoriesList[index], ); }, ), @@ -75,8 +81,8 @@ class _ToDoDashBoardState extends State { } class TodoCategoryTile extends StatelessWidget { - String categoryName; - TodoCategoryTile({required this.categoryName}); + Category category; + TodoCategoryTile({required this.category}); @override Widget build(BuildContext context) { @@ -88,7 +94,11 @@ class TodoCategoryTile extends StatelessWidget { ), child: GestureDetector( onTap: () { - print('todo category tile clicked'); + Navigator.pushNamed( + context, + RouteNames.itemscreen, + arguments: category, + ); }, child: SizedBox( height: 125, @@ -112,7 +122,7 @@ class TodoCategoryTile extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Text( - categoryName, + category.category, style: TextStyle(color: kNoteTitle), ), ], From f69b3d022fc45b12a1f7de92f7e2b98c44687cc8 Mon Sep 17 00:00:00 2001 From: Nirbhay Makhija Date: Mon, 29 Nov 2021 17:24:01 +0530 Subject: [PATCH 11/28] display list of items under a category --- .../{screens => components}/add_new_todo.dart | 17 +- App/lib/components/todo_category_tile.dart | 59 +++++++ App/lib/components/todo_item_tile.dart | 39 +++++ App/lib/models/auth.dart | 3 +- App/lib/models/todo.dart | 13 +- App/lib/screens/items_screen.dart | 149 +++++++++++------- App/lib/screens/loginscreen.dart | 4 +- App/lib/screens/tododashboard.dart | 66 ++------ 8 files changed, 233 insertions(+), 117 deletions(-) rename App/lib/{screens => components}/add_new_todo.dart (86%) create mode 100644 App/lib/components/todo_category_tile.dart create mode 100644 App/lib/components/todo_item_tile.dart diff --git a/App/lib/screens/add_new_todo.dart b/App/lib/components/add_new_todo.dart similarity index 86% rename from App/lib/screens/add_new_todo.dart rename to App/lib/components/add_new_todo.dart index 40a44e3..1ca3bee 100644 --- a/App/lib/screens/add_new_todo.dart +++ b/App/lib/components/add_new_todo.dart @@ -55,9 +55,21 @@ class BottomModalSheetTodo extends StatelessWidget { text = value; }, onSubmitted: (value) { + text = value; + print(text); String key = Provider.of(context, listen: false).key; - Provider.of(context, listen: false) - .createCategory(key, text); + if (isCategory) { + // creating a category + Provider.of(context, listen: false) + .createCategory(key, text); + } else { + // creating an item + Provider.of(context, listen: false).createItem( + key, + catId, // get catID + text, + ); + } Navigator.pop(context); }, style: TextStyle( @@ -78,6 +90,7 @@ class BottomModalSheetTodo extends StatelessWidget { ), child: GestureDetector( onTap: () { + print(text); String key = Provider.of(context, listen: false).key; if (isCategory) { // creating a category diff --git a/App/lib/components/todo_category_tile.dart b/App/lib/components/todo_category_tile.dart new file mode 100644 index 0000000..611eafe --- /dev/null +++ b/App/lib/components/todo_category_tile.dart @@ -0,0 +1,59 @@ +// ignore_for_file: prefer_const_constructors, must_be_immutable, use_key_in_widget_constructors + +import 'package:app/constants.dart'; +import 'package:app/models/theme.dart'; +import 'package:app/models/todo_components.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class TodoCategoryTile extends StatelessWidget { + Category category; + Function onTap; + TodoCategoryTile({required this.category, required this.onTap}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: EdgeInsets.only( + left: 20, + right: 20, + bottom: 10, + ), + child: GestureDetector( + onTap: () { + onTap(); + }, + child: SizedBox( + height: 125, + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular( + 20, + ), + ), + color: Provider.of(context).isTheme + ? kgreyblack + : klightpink, + elevation: 5, + child: Padding( + padding: EdgeInsets.symmetric( + horizontal: 15, + vertical: 10, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text( + category.category, + style: TextStyle(color: kNoteTitle), + ), + ], + ), + ), + ), + ), + ), + ); + } +} diff --git a/App/lib/components/todo_item_tile.dart b/App/lib/components/todo_item_tile.dart new file mode 100644 index 0000000..4f9f806 --- /dev/null +++ b/App/lib/components/todo_item_tile.dart @@ -0,0 +1,39 @@ +// ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors_in_immutables + +import 'package:app/models/theme.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class TodoItemListTile extends StatelessWidget { + final String taskTitle; + final bool isChecked; + TodoItemListTile({ + required this.isChecked, + required this.taskTitle, + }); + @override + Widget build(BuildContext context) { + return ListTile( + title: Text( + taskTitle, + style: TextStyle( + fontSize: 18, + color: Provider.of(context, listen: false).isTheme + ? Colors.white + : Colors.black, + decoration: isChecked ? TextDecoration.lineThrough : null, + ), + ), + trailing: Checkbox( + value: isChecked, + onChanged: (value) {}, + activeColor: Provider.of(context, listen: false).isTheme + ? Colors.white + : Colors.black, + checkColor: Provider.of(context, listen: false).isTheme + ? Colors.white + : Colors.black, + ), + ); + } +} diff --git a/App/lib/models/auth.dart b/App/lib/models/auth.dart index e8ae951..174c98e 100644 --- a/App/lib/models/auth.dart +++ b/App/lib/models/auth.dart @@ -107,8 +107,9 @@ class Auth with ChangeNotifier { Provider.of(context, listen: false).getIsTheme(); Provider.of(context, listen: false).clearList(); Provider.of(context, listen: false).getList(key); - Provider.of(context, listen: false).getCategoriesList(key); Provider.of(context, listen: false).clearList(); + Provider.of(context, listen: false).getCategoriesList(key); + Provider.of(context, listen: false).listAllTodoItems(key); Navigator.pushReplacementNamed(context, RouteNames.dashboard); } } diff --git a/App/lib/models/todo.dart b/App/lib/models/todo.dart index 2512cec..33f283e 100644 --- a/App/lib/models/todo.dart +++ b/App/lib/models/todo.dart @@ -14,6 +14,13 @@ class ToDo with ChangeNotifier { return [..._categories]; } + List getItemListForCategory(String catID) { + print('getting the list of all items in the todo list'); + List items = + _items.where((element) => element.categoryId == catID).toList(); + return items; + } + Future createCategory(String key, String categoryName) async { try { print('creating new category'); @@ -125,7 +132,7 @@ class ToDo with ChangeNotifier { body: {"cat_id": catId, "item": item}, ); final data = jsonDecode(response.body); - print(data); + print('data = $data'); if (response.statusCode == 200) { _items.add( TodoItem( @@ -138,6 +145,7 @@ class ToDo with ChangeNotifier { updatedAt: data["updated_at"], ), ); + print('addition succesful'); notifyListeners(); } else { throw 'Error in creating a new item'; @@ -162,7 +170,7 @@ class ToDo with ChangeNotifier { _items.add( TodoItem( id: tempItems[i]["id"].toString(), - categoryId: tempItems[i]["category_id"], + categoryId: tempItems[i]["category_id"].toString(), categoryName: tempItems[i]["category"], createdAt: tempItems[i]["created_at"], isDone: tempItems[i]["isDone"], @@ -171,6 +179,7 @@ class ToDo with ChangeNotifier { ), ); } + print('listing all the items'); notifyListeners(); } else { throw 'Error in getting the list of all items'; diff --git a/App/lib/screens/items_screen.dart b/App/lib/screens/items_screen.dart index 06adf68..5847a4e 100644 --- a/App/lib/screens/items_screen.dart +++ b/App/lib/screens/items_screen.dart @@ -1,13 +1,16 @@ -// ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors, prefer_const_constructors_in_immutables, curly_braces_in_flow_control_structures +// ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors, prefer_const_constructors_in_immutables, curly_braces_in_flow_control_structures, avoid_print +import 'package:app/components/todo_item_tile.dart'; import 'package:app/constants.dart'; +import 'package:app/models/auth.dart'; import 'package:app/models/theme.dart'; +import 'package:app/models/todo.dart'; import 'package:app/models/todo_components.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:provider/provider.dart'; -import 'add_new_todo.dart'; +import '../components/add_new_todo.dart'; class ItemsScreen extends StatefulWidget { final Category category; @@ -18,8 +21,24 @@ class ItemsScreen extends StatefulWidget { class _ItemsScreenState extends State { bool isVisible = true; + late String title; + void setVariable() { + print('item screen'); + print(widget.category); + title = widget.category.category; + } + + @override + void initState() { + setVariable(); + setState(() {}); + super.initState(); + } + @override Widget build(BuildContext context) { + List items = Provider.of(context) + .getItemListForCategory(widget.category.id.toString()); return Scaffold( backgroundColor: Provider.of(context, listen: false).isTheme ? kbgcolor @@ -58,6 +77,12 @@ class _ItemsScreenState extends State { elevation: 0, leading: IconButton( onPressed: () { + String key = Provider.of(context, listen: false).key; + Provider.of(context, listen: false).updateCategory( + key, + title, + widget.category.id, + ); Navigator.pop(context); }, icon: Icon( @@ -76,64 +101,80 @@ class _ItemsScreenState extends State { ), ], ), - body: NotificationListener( - onNotification: (notification) { - if (notification.direction == ScrollDirection.forward) { - if (!isVisible) - setState(() { - isVisible = true; - }); - } else if (notification.direction == ScrollDirection.reverse) { - if (isVisible) - setState(() { - isVisible = false; - }); - } - return true; - }, - child: Container( - padding: EdgeInsets.only( - left: 20, - right: 20, - bottom: 20, - ), - child: Column( - children: [ - TextFormField( - initialValue: widget.category.category, - textAlign: TextAlign.center, - onChanged: (value) { - // change the category name - }, - maxLines: 1, - style: TextStyle( + body: Container( + padding: EdgeInsets.only( + left: 20, + right: 20, + bottom: 20, + ), + child: Column( + children: [ + TextFormField( + initialValue: widget.category.category, + textAlign: TextAlign.center, + onChanged: (value) { + title = value; + }, + maxLines: 1, + style: TextStyle( + color: Provider.of(context, listen: false).isTheme + ? Colors.white + : Colors.black, + fontSize: 30, + ), + decoration: InputDecoration( + hintText: 'Category Name', + border: OutlineInputBorder( + borderSide: BorderSide.none, + borderRadius: BorderRadius.circular(20), + ), + hintStyle: TextStyle( + fontSize: 25, color: Provider.of(context, listen: false).isTheme - ? Colors.white - : Colors.black, - fontSize: 30, + ? Colors.grey + : Colors.black54, ), - decoration: InputDecoration( - hintText: 'Category Name', - border: OutlineInputBorder( - borderSide: BorderSide.none, - borderRadius: BorderRadius.circular(20), - ), - hintStyle: TextStyle( - fontSize: 25, - color: - Provider.of(context, listen: false).isTheme - ? Colors.grey - : Colors.black54, + ), + onFieldSubmitted: (value) { + String key = Provider.of(context, listen: false).key; + Provider.of(context, listen: false).updateCategory( + key, + title, + widget.category.id, + ); + }, + ), + NotificationListener( + onNotification: (notification) { + if (notification.direction == ScrollDirection.forward) { + if (!isVisible) + setState(() { + isVisible = true; + }); + } else if (notification.direction == ScrollDirection.reverse) { + if (isVisible) + setState(() { + isVisible = false; + }); + } + return true; + }, + child: Expanded( + child: Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: ListView.builder( + itemCount: items.length, + itemBuilder: (context, index) { + return TodoItemListTile( + isChecked: items[index].isDone, + taskTitle: items[index].item); + }, ), ), - onFieldSubmitted: (value) {}, ), - Expanded( - child: Text('items'), - ), - ], - ), + ), + ], ), ), ); diff --git a/App/lib/screens/loginscreen.dart b/App/lib/screens/loginscreen.dart index fd5be2d..bc1142b 100644 --- a/App/lib/screens/loginscreen.dart +++ b/App/lib/screens/loginscreen.dart @@ -104,9 +104,11 @@ class _LoginScreenState extends State { Provider.of(context, listen: false) .getList(key); + Provider.of(context, listen: false).clearList(); Provider.of(context, listen: false) .getCategoriesList(key); - Provider.of(context, listen: false).clearList(); + Provider.of(context, listen: false) + .listAllTodoItems(key); Navigator.pushNamed(context, RouteNames.dashboard); } catch (e) { showDialog( diff --git a/App/lib/screens/tododashboard.dart b/App/lib/screens/tododashboard.dart index 465cb9b..23c4c34 100644 --- a/App/lib/screens/tododashboard.dart +++ b/App/lib/screens/tododashboard.dart @@ -1,11 +1,11 @@ // ignore_for_file: use_key_in_widget_constructors, avoid_unnecessary_containers, prefer_const_constructors, prefer_const_literals_to_create_immutables, avoid_print, must_be_immutable, curly_braces_in_flow_control_structures +import 'package:app/components/todo_category_tile.dart'; import 'package:app/constants.dart'; -import 'package:app/models/theme.dart'; import 'package:app/models/todo.dart'; import 'package:app/models/todo_components.dart'; import 'package:app/routers/routenames.dart'; -import 'package:app/screens/add_new_todo.dart'; +import 'package:app/components/add_new_todo.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:provider/provider.dart'; @@ -71,6 +71,13 @@ class _ToDoDashBoardState extends State { itemBuilder: (context, index) { return TodoCategoryTile( category: categoriesList[index], + onTap: () { + Navigator.pushNamed( + context, + RouteNames.itemscreen, + arguments: categoriesList[index], + ); + }, ); }, ), @@ -79,58 +86,3 @@ class _ToDoDashBoardState extends State { ); } } - -class TodoCategoryTile extends StatelessWidget { - Category category; - TodoCategoryTile({required this.category}); - - @override - Widget build(BuildContext context) { - return Padding( - padding: EdgeInsets.only( - left: 20, - right: 20, - bottom: 10, - ), - child: GestureDetector( - onTap: () { - Navigator.pushNamed( - context, - RouteNames.itemscreen, - arguments: category, - ); - }, - child: SizedBox( - height: 125, - child: Card( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular( - 20, - ), - ), - color: Provider.of(context).isTheme - ? kgreyblack - : klightpink, - elevation: 5, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - vertical: 10, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Text( - category.category, - style: TextStyle(color: kNoteTitle), - ), - ], - ), - ), - ), - ), - ), - ); - } -} From 461c16999c46ce59deba63ce5f3b0a6137a369d7 Mon Sep 17 00:00:00 2001 From: Nirbhay Makhija Date: Mon, 29 Nov 2021 17:35:17 +0530 Subject: [PATCH 12/28] add new item feature --- App/lib/models/todo.dart | 4 ++-- App/lib/screens/items_screen.dart | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/App/lib/models/todo.dart b/App/lib/models/todo.dart index 33f283e..1b458b5 100644 --- a/App/lib/models/todo.dart +++ b/App/lib/models/todo.dart @@ -125,7 +125,7 @@ class ToDo with ChangeNotifier { Future createItem(String key, String catId, String item) async { try { - print('creating new item'); + print('creating new item = $catId = $item'); http.Response response = await http.post( Uri.parse('https://notefyapi.servatom.com/api/todo/item/'), headers: {'Authorization': 'Token $key'}, @@ -137,7 +137,7 @@ class ToDo with ChangeNotifier { _items.add( TodoItem( id: data["id"].toString(), - categoryId: data["category_id"], + categoryId: data["category_id"].toString(), categoryName: data["category"], createdAt: data["created_at"], isDone: data["isDone"], diff --git a/App/lib/screens/items_screen.dart b/App/lib/screens/items_screen.dart index 5847a4e..c0b0ce9 100644 --- a/App/lib/screens/items_screen.dart +++ b/App/lib/screens/items_screen.dart @@ -56,7 +56,7 @@ class _ItemsScreenState extends State { title: 'Add Item', buttonText: 'Add', isCategory: false, - catId: widget.category.category, + catId: widget.category.id, ), ), ), From b12e909a10a4f68bbf449b4410f0001f00f212be Mon Sep 17 00:00:00 2001 From: Nirbhay Makhija Date: Mon, 29 Nov 2021 18:17:58 +0530 Subject: [PATCH 13/28] todo dashboard ready --- App/lib/components/add_new_todo.dart | 2 +- App/lib/components/todo_category_tile.dart | 55 +++++++++++++++++++++- App/lib/components/todo_item_tile.dart | 7 +-- App/lib/models/todo.dart | 4 ++ App/lib/screens/dashboard.dart | 2 +- App/lib/screens/items_screen.dart | 26 ++++++---- 6 files changed, 81 insertions(+), 15 deletions(-) diff --git a/App/lib/components/add_new_todo.dart b/App/lib/components/add_new_todo.dart index 1ca3bee..4900107 100644 --- a/App/lib/components/add_new_todo.dart +++ b/App/lib/components/add_new_todo.dart @@ -1,4 +1,4 @@ -// ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors, prefer_const_literals_to_create_immutables, must_be_immutable +// ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors, prefer_const_literals_to_create_immutables, must_be_immutable, avoid_print import 'package:app/constants.dart'; import 'package:app/models/auth.dart'; diff --git a/App/lib/components/todo_category_tile.dart b/App/lib/components/todo_category_tile.dart index 611eafe..ba3fa43 100644 --- a/App/lib/components/todo_category_tile.dart +++ b/App/lib/components/todo_category_tile.dart @@ -2,6 +2,7 @@ import 'package:app/constants.dart'; import 'package:app/models/theme.dart'; +import 'package:app/models/todo.dart'; import 'package:app/models/todo_components.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -13,6 +14,8 @@ class TodoCategoryTile extends StatelessWidget { @override Widget build(BuildContext context) { + List items = + Provider.of(context).getItemListForCategory(category.id); return Padding( padding: EdgeInsets.only( left: 20, @@ -38,7 +41,7 @@ class TodoCategoryTile extends StatelessWidget { child: Padding( padding: EdgeInsets.symmetric( horizontal: 15, - vertical: 10, + vertical: 15, ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -46,7 +49,55 @@ class TodoCategoryTile extends StatelessWidget { children: [ Text( category.category, - style: TextStyle(color: kNoteTitle), + style: TextStyle( + color: Provider.of(context).isTheme + ? kNoteTitle + : Colors.black, + fontSize: 25, + ), + ), + SizedBox( + height: 2, + ), + Expanded( + child: (items.isNotEmpty) + ? ListView.builder( + physics: NeverScrollableScrollPhysics(), + itemCount: (items.length >= 2) ? 2 : items.length, + itemBuilder: (context, index) { + return Text( + items[index].item, + style: TextStyle( + color: + Provider.of(context).isTheme + ? kNoteBody + : Colors.black54, + decoration: items[index].isDone + ? TextDecoration.lineThrough + : null, + ), + ); + }, + ) + : Text( + 'No items yet', + style: TextStyle( + color: Provider.of(context).isTheme + ? kNoteBody + : Colors.black54, + ), + ), + ), + Container( + alignment: Alignment.bottomRight, + child: Text( + category.updatedAt, + style: TextStyle( + color: Provider.of(context).isTheme + ? kNotetime + : Colors.black38, + ), + ), ), ], ), diff --git a/App/lib/components/todo_item_tile.dart b/App/lib/components/todo_item_tile.dart index 4f9f806..bd6d843 100644 --- a/App/lib/components/todo_item_tile.dart +++ b/App/lib/components/todo_item_tile.dart @@ -1,5 +1,6 @@ // ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors_in_immutables +import 'package:app/constants.dart'; import 'package:app/models/theme.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -29,10 +30,10 @@ class TodoItemListTile extends StatelessWidget { onChanged: (value) {}, activeColor: Provider.of(context, listen: false).isTheme ? Colors.white - : Colors.black, + : kbgcolor, checkColor: Provider.of(context, listen: false).isTheme - ? Colors.white - : Colors.black, + ? kbgcolor + : Colors.white, ), ); } diff --git a/App/lib/models/todo.dart b/App/lib/models/todo.dart index 1b458b5..77ecdbd 100644 --- a/App/lib/models/todo.dart +++ b/App/lib/models/todo.dart @@ -21,6 +21,10 @@ class ToDo with ChangeNotifier { return items; } + List getAllItems() { + return [..._items]; + } + Future createCategory(String key, String categoryName) async { try { print('creating new category'); diff --git a/App/lib/screens/dashboard.dart b/App/lib/screens/dashboard.dart index 8d4ca7d..b75b173 100644 --- a/App/lib/screens/dashboard.dart +++ b/App/lib/screens/dashboard.dart @@ -33,7 +33,7 @@ class _DashBoardState extends State { bottom: TabBar( tabs: [ Tab( - icon: Icon(Icons.notes), + icon: Icon(Icons.create), ), Tab( icon: Icon(Icons.check_box), diff --git a/App/lib/screens/items_screen.dart b/App/lib/screens/items_screen.dart index c0b0ce9..1b69234 100644 --- a/App/lib/screens/items_screen.dart +++ b/App/lib/screens/items_screen.dart @@ -163,14 +163,24 @@ class _ItemsScreenState extends State { child: Expanded( child: Padding( padding: EdgeInsets.symmetric(vertical: 20), - child: ListView.builder( - itemCount: items.length, - itemBuilder: (context, index) { - return TodoItemListTile( - isChecked: items[index].isDone, - taskTitle: items[index].item); - }, - ), + child: (items.isNotEmpty) + ? ListView.builder( + itemCount: items.length, + itemBuilder: (context, index) { + return TodoItemListTile( + isChecked: items[index].isDone, + taskTitle: items[index].item); + }, + ) + : Text( + 'No items yet', + style: TextStyle( + color: Provider.of(context).isTheme + ? kNoteBody + : Colors.black54, + fontSize: 16, + ), + ), ), ), ), From a25dfcc348984fee24e856dd3a0211ca48b42751 Mon Sep 17 00:00:00 2001 From: Nirbhay Makhija Date: Mon, 29 Nov 2021 18:24:56 +0530 Subject: [PATCH 14/28] fix list orientation --- App/lib/screens/notesdashboard.dart | 3 ++- App/lib/screens/tododashboard.dart | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/App/lib/screens/notesdashboard.dart b/App/lib/screens/notesdashboard.dart index 38d7285..d4c5556 100644 --- a/App/lib/screens/notesdashboard.dart +++ b/App/lib/screens/notesdashboard.dart @@ -18,7 +18,8 @@ class _NotesDashBoardState extends State { bool isVisible = true; @override Widget build(BuildContext context) { - List notesList = Provider.of(context, listen: true).notesList; + List tempList = Provider.of(context, listen: true).notesList; + List notesList = tempList.reversed.toList(); return Scaffold( floatingActionButton: isVisible ? FloatingActionButton( diff --git a/App/lib/screens/tododashboard.dart b/App/lib/screens/tododashboard.dart index 23c4c34..d90d249 100644 --- a/App/lib/screens/tododashboard.dart +++ b/App/lib/screens/tododashboard.dart @@ -19,7 +19,8 @@ class _ToDoDashBoardState extends State { bool isVisible = true; @override Widget build(BuildContext context) { - List categoriesList = Provider.of(context).getCateList(); + List tempList = Provider.of(context).getCateList(); + List categoriesList = tempList.reversed.toList(); return Scaffold( floatingActionButton: isVisible ? FloatingActionButton( From 126a8a359a3390db9ecd8b14cc5b52c275708273 Mon Sep 17 00:00:00 2001 From: Nirbhay Makhija Date: Tue, 30 Nov 2021 22:29:17 +0530 Subject: [PATCH 15/28] delete feature --- App/lib/components/delete_dialog.dart | 50 ++++++++++++++++++++++++--- App/lib/constants.dart | 35 ++++++++++++++++++- App/lib/models/todo.dart | 6 ++++ App/lib/screens/items_screen.dart | 15 +++++++- App/lib/screens/settingsreen.dart | 26 ++++++++++++-- 5 files changed, 123 insertions(+), 9 deletions(-) diff --git a/App/lib/components/delete_dialog.dart b/App/lib/components/delete_dialog.dart index 2948624..b86e59f 100644 --- a/App/lib/components/delete_dialog.dart +++ b/App/lib/components/delete_dialog.dart @@ -1,16 +1,29 @@ -// ignore_for_file: prefer_const_constructors, use_key_in_widget_constructors +// ignore_for_file: prefer_const_constructors, use_key_in_widget_constructors, prefer_const_constructors_in_immutables, curly_braces_in_flow_control_structures import 'dart:ui'; import 'package:app/models/auth.dart'; import 'package:app/models/notes.dart'; import 'package:app/models/theme.dart'; +import 'package:app/models/todo.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../constants.dart'; class DeleteDialog extends StatelessWidget { + final String buttonTitle; + final String boxTitle; + final int toDelete; + final String catID; + final String itemId; + DeleteDialog({ + required this.boxTitle, + required this.buttonTitle, + required this.toDelete, + required this.catID, + required this.itemId, + }); @override Widget build(BuildContext context) { return BackdropFilter( @@ -28,7 +41,7 @@ class DeleteDialog extends StatelessWidget { ? kbgcolor : kpink, title: Text( - 'Do you want to delete all the tasks?', + boxTitle, style: TextStyle( color: Provider.of(context, listen: false).isTheme ? Colors.white @@ -72,14 +85,41 @@ class DeleteDialog extends StatelessWidget { color: Colors.red, onPressed: () { String key = Provider.of(context, listen: false).key; - Provider.of(context, listen: false).deleteAllNotes(key); + if (toDelete == 1) { + Provider.of(context, listen: false).deleteAllNotes(key); + } + if (toDelete == 2) { + Provider.of(context, listen: false) + .deleteCategory(key, catID); + } + if (toDelete == 3) { + Provider.of(context, listen: false) + .deleteToDoItem(key, itemId); + } + if (toDelete == 4) { + Provider.of(context, listen: false) + .deleteAllCategories(key); + } Navigator.pop(context); - ScaffoldMessenger.of(context).showSnackBar(snackBar); + if (toDelete == 1) + ScaffoldMessenger.of(context).showSnackBar(snackBarDeleteNotes); + if (toDelete == 2) { + ScaffoldMessenger.of(context) + .showSnackBar(snackBarDeleteCategory); + Navigator.pop(context); + } + if (toDelete == 3) { + ScaffoldMessenger.of(context).showSnackBar(snackBarDeleteItem); + } + if (toDelete == 4) { + ScaffoldMessenger.of(context) + .showSnackBar(snackBarDeleteAllCategories); + } }, child: Padding( padding: EdgeInsets.all(10.0), child: Text( - 'Delete All', + buttonTitle, style: TextStyle( color: Colors.white, fontSize: 18, diff --git a/App/lib/constants.dart b/App/lib/constants.dart index 362b6f2..17f0f5a 100644 --- a/App/lib/constants.dart +++ b/App/lib/constants.dart @@ -22,7 +22,7 @@ const kNoteTitle = Colors.white; const kNoteBody = Colors.grey; const kNotetime = Colors.grey; -final snackBar = SnackBar( +final snackBarDeleteNotes = SnackBar( content: Text( 'Poof! All notes deleted', style: TextStyle( @@ -33,3 +33,36 @@ final snackBar = SnackBar( duration: Duration(seconds: 2), backgroundColor: Colors.black, ); +final snackBarDeleteCategory = SnackBar( + content: Text( + 'Poof! Category deleted', + style: TextStyle( + fontSize: 20, + fontFamily: 'roboto', + ), + ), + duration: Duration(seconds: 2), + backgroundColor: Colors.black, +); +final snackBarDeleteItem = SnackBar( + content: Text( + 'Item deleted', + style: TextStyle( + fontSize: 20, + fontFamily: 'roboto', + ), + ), + duration: Duration(seconds: 2), + backgroundColor: Colors.black, +); +final snackBarDeleteAllCategories = SnackBar( + content: Text( + 'Poof! All Categories deleted', + style: TextStyle( + fontSize: 20, + fontFamily: 'roboto', + ), + ), + duration: Duration(seconds: 2), + backgroundColor: Colors.black, +); diff --git a/App/lib/models/todo.dart b/App/lib/models/todo.dart index 77ecdbd..ddfabbc 100644 --- a/App/lib/models/todo.dart +++ b/App/lib/models/todo.dart @@ -127,6 +127,12 @@ class ToDo with ChangeNotifier { } } + void deleteAllCategories(String key) { + for (int i = 0; i < _categories.length; i++) { + deleteCategory(key, _categories[i].id); + } + } + Future createItem(String key, String catId, String item) async { try { print('creating new item = $catId = $item'); diff --git a/App/lib/screens/items_screen.dart b/App/lib/screens/items_screen.dart index 1b69234..7a998f2 100644 --- a/App/lib/screens/items_screen.dart +++ b/App/lib/screens/items_screen.dart @@ -1,5 +1,6 @@ // ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors, prefer_const_constructors_in_immutables, curly_braces_in_flow_control_structures, avoid_print +import 'package:app/components/delete_dialog.dart'; import 'package:app/components/todo_item_tile.dart'; import 'package:app/constants.dart'; import 'package:app/models/auth.dart'; @@ -96,7 +97,19 @@ class _ItemsScreenState extends State { automaticallyImplyLeading: false, actions: [ IconButton( - onPressed: () {}, + onPressed: () { + showDialog( + context: context, + builder: (context) { + return DeleteDialog( + boxTitle: 'Do you want to delete this category?', + buttonTitle: 'Delete', + toDelete: 2, + catID: widget.category.id, + itemId: '', + ); + }); + }, icon: Icon(Icons.delete, color: Colors.red), ), ], diff --git a/App/lib/screens/settingsreen.dart b/App/lib/screens/settingsreen.dart index 9d40f31..dfd4566 100644 --- a/App/lib/screens/settingsreen.dart +++ b/App/lib/screens/settingsreen.dart @@ -46,7 +46,7 @@ class SettingsScreen extends StatelessWidget { padding: const EdgeInsets.all(10), child: Column( children: [ - InkWell( + InkWell( onTap: () { Navigator.pushNamed(context, RouteNames.resetpasswordscreen); }, @@ -65,11 +65,33 @@ class SettingsScreen extends StatelessWidget { showDialog( context: context, builder: (context) { - return DeleteDialog(); + return DeleteDialog( + boxTitle: 'Do you want to delete all the notes?', + buttonTitle: 'Delete All', + toDelete: 1, + catID: '', + itemId: '', + ); }); }, child: SettingTile(title: 'Delete all notes')), SizedBox(height: 15), + GestureDetector( + onTap: () { + showDialog( + context: context, + builder: (context) { + return DeleteDialog( + boxTitle: 'Do you want to delete all the categories?', + buttonTitle: 'Delete All', + toDelete: 4, + catID: '', + itemId: '', + ); + }); + }, + child: SettingTile(title: 'Delete all categories')), + SizedBox(height: 15), GestureDetector( onTap: () { Provider.of(context, listen: false).logoutUser(context); From bd7ff30c9220085efb4cc9ae2e2836c11289a6c1 Mon Sep 17 00:00:00 2001 From: Nirbhay Makhija Date: Thu, 2 Dec 2021 17:33:06 +0530 Subject: [PATCH 16/28] check item frontend and pop up menu button for items --- App/lib/components/setting_tile.dart | 2 +- App/lib/components/todo_item_tile.dart | 175 ++++++++++++++++++++++--- App/lib/models/todo.dart | 11 +- App/lib/screens/items_screen.dart | 98 ++++++++------ 4 files changed, 224 insertions(+), 62 deletions(-) diff --git a/App/lib/components/setting_tile.dart b/App/lib/components/setting_tile.dart index 08aa2a7..09630ca 100644 --- a/App/lib/components/setting_tile.dart +++ b/App/lib/components/setting_tile.dart @@ -33,7 +33,7 @@ class SettingTile extends StatelessWidget { color: Provider.of(context).isTheme ? Colors.white : Colors.black, - fontSize: 25, + fontSize: 23, ), ), ), diff --git a/App/lib/components/todo_item_tile.dart b/App/lib/components/todo_item_tile.dart index bd6d843..0a3ae89 100644 --- a/App/lib/components/todo_item_tile.dart +++ b/App/lib/components/todo_item_tile.dart @@ -1,39 +1,180 @@ -// ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors_in_immutables +// ignore_for_file: use_key_in_widget_constructors, prefer_const_constructors_in_immutables, must_be_immutable, prefer_const_constructors import 'package:app/constants.dart'; +import 'package:app/models/auth.dart'; import 'package:app/models/theme.dart'; +import 'package:app/models/todo.dart'; +import 'package:app/models/todo_components.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -class TodoItemListTile extends StatelessWidget { - final String taskTitle; - final bool isChecked; +class TodoItemListTile extends StatefulWidget { + late TodoItem item; TodoItemListTile({ - required this.isChecked, - required this.taskTitle, + required this.item, }); + + @override + State createState() => _TodoItemListTileState(); +} + +class _TodoItemListTileState extends State { @override Widget build(BuildContext context) { return ListTile( title: Text( - taskTitle, + widget.item.item, style: TextStyle( fontSize: 18, color: Provider.of(context, listen: false).isTheme ? Colors.white : Colors.black, - decoration: isChecked ? TextDecoration.lineThrough : null, + decoration: widget.item.isDone ? TextDecoration.lineThrough : null, ), ), - trailing: Checkbox( - value: isChecked, - onChanged: (value) {}, - activeColor: Provider.of(context, listen: false).isTheme - ? Colors.white - : kbgcolor, - checkColor: Provider.of(context, listen: false).isTheme - ? kbgcolor - : Colors.white, + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Theme( + data: ThemeData( + unselectedWidgetColor: + Provider.of(context, listen: false).isTheme + ? kyellow + : kbgcolor, + ), + child: Checkbox( + value: widget.item.isDone, + onChanged: (value) { + setState(() { + widget.item.isDone = !widget.item.isDone; + String key = Provider.of(context, listen: false).key; + Provider.of(context, listen: false).updateToDoItem( + key, + widget.item.id, + widget.item.isDone, + widget.item.item, + ); + }); + }, + activeColor: + Provider.of(context, listen: false).isTheme + ? kyellow + : kbgcolor, + checkColor: + Provider.of(context, listen: false).isTheme + ? kbgcolor + : Colors.white, + ), + ), + PopupMenuButton( + color: Provider.of(context, listen: false).isTheme + ? Colors.white + : kpink, + icon: Icon( + Icons.more_vert, + color: Provider.of(context, listen: false).isTheme + ? kyellow + : kbgcolor, + ), + itemBuilder: (context) { + return [ + PopupMenuItem( + child: Text('Edit'), + onTap: () { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular( + 10, + ), + ), + ), + backgroundColor: + Provider.of(context, listen: false) + .isTheme + ? kbgcolor + : kpink, + title: Text( + 'Edit Item', + style: TextStyle( + color: Provider.of(context, + listen: false) + .isTheme + ? Colors.white + : Colors.black, + ), + ), + actionsPadding: EdgeInsets.symmetric( + horizontal: 10, vertical: 10), + actions: [ + MaterialButton( + minWidth: 60, + height: 40, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + elevation: 10, + color: Provider.of(context, + listen: false) + .isTheme + ? kyellow + : Color(0xFF8CD4CB), + onPressed: () { + Navigator.pop(context); + }, + child: Padding( + padding: EdgeInsets.all(10.0), + child: Text( + 'Cancel', + style: TextStyle( + color: Colors.black, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + MaterialButton( + minWidth: 60, + height: 40, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + elevation: 10, + color: Colors.green, + onPressed: () {}, + child: Padding( + padding: EdgeInsets.all(10.0), + child: Text( + 'Okay', + style: TextStyle( + color: Colors.white, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ); + }); + }, + ), + PopupMenuItem( + child: Text('Delete'), + onTap: () { + String key = Provider.of(context, listen: false).key; + Provider.of(context, listen: false) + .deleteToDoItem(key, widget.item.id); + }, + ), + ]; + }, + ), + ], ), ); } diff --git a/App/lib/models/todo.dart b/App/lib/models/todo.dart index ddfabbc..90d3fad 100644 --- a/App/lib/models/todo.dart +++ b/App/lib/models/todo.dart @@ -206,7 +206,11 @@ class ToDo with ChangeNotifier { http.Response response = await http.put( Uri.parse('https://notefyapi.servatom.com/api/todo/item/'), headers: {'Authorization': 'Token $key'}, - body: {"todo_item_id": itemId, "is_done": isDone, "item": item}, + body: { + "todo_item_id": itemId, + "is_done": isDone.toString(), + "item": item + }, ); final data = jsonDecode(response.body); print(data); @@ -216,8 +220,9 @@ class ToDo with ChangeNotifier { _items[index].isDone = data["isDone"]; _items[index].updatedAt = data["updated_at"]; notifyListeners(); - } else { - throw 'error in updating item'; + // } else { + // throw 'error in updating item'; + // } } } catch (e) { print(e); diff --git a/App/lib/screens/items_screen.dart b/App/lib/screens/items_screen.dart index 7a998f2..5fdcf42 100644 --- a/App/lib/screens/items_screen.dart +++ b/App/lib/screens/items_screen.dart @@ -116,47 +116,51 @@ class _ItemsScreenState extends State { ), body: Container( padding: EdgeInsets.only( - left: 20, - right: 20, bottom: 20, ), child: Column( children: [ - TextFormField( - initialValue: widget.category.category, - textAlign: TextAlign.center, - onChanged: (value) { - title = value; - }, - maxLines: 1, - style: TextStyle( - color: Provider.of(context, listen: false).isTheme - ? Colors.white - : Colors.black, - fontSize: 30, + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 20, ), - decoration: InputDecoration( - hintText: 'Category Name', - border: OutlineInputBorder( - borderSide: BorderSide.none, - borderRadius: BorderRadius.circular(20), - ), - hintStyle: TextStyle( - fontSize: 25, + child: TextFormField( + initialValue: widget.category.category, + textAlign: TextAlign.center, + onChanged: (value) { + title = value; + }, + maxLines: 1, + style: TextStyle( color: Provider.of(context, listen: false).isTheme - ? Colors.grey - : Colors.black54, + ? Colors.white + : Colors.black, + fontSize: 30, + ), + decoration: InputDecoration( + hintText: 'Category Name', + border: OutlineInputBorder( + borderSide: BorderSide.none, + borderRadius: BorderRadius.circular(20), + ), + hintStyle: TextStyle( + fontSize: 25, + color: + Provider.of(context, listen: false).isTheme + ? Colors.grey + : Colors.black54, + ), ), + onFieldSubmitted: (value) { + String key = Provider.of(context, listen: false).key; + Provider.of(context, listen: false).updateCategory( + key, + title, + widget.category.id, + ); + }, ), - onFieldSubmitted: (value) { - String key = Provider.of(context, listen: false).key; - Provider.of(context, listen: false).updateCategory( - key, - title, - widget.category.id, - ); - }, ), NotificationListener( onNotification: (notification) { @@ -174,18 +178,30 @@ class _ItemsScreenState extends State { return true; }, child: Expanded( - child: Padding( - padding: EdgeInsets.symmetric(vertical: 20), - child: (items.isNotEmpty) - ? ListView.builder( + child: (items.isNotEmpty) + ? Padding( + padding: EdgeInsets.only( + top: 20, + bottom: 20, + left: 20, + right: 10, + ), + child: ListView.builder( itemCount: items.length, itemBuilder: (context, index) { return TodoItemListTile( - isChecked: items[index].isDone, - taskTitle: items[index].item); + item: items[index], + ); }, - ) - : Text( + ), + ) + : Padding( + padding: const EdgeInsets.only( + bottom: 20, + right: 20, + left: 20, + ), + child: Text( 'No items yet', style: TextStyle( color: Provider.of(context).isTheme @@ -194,7 +210,7 @@ class _ItemsScreenState extends State { fontSize: 16, ), ), - ), + ), ), ), ], From d98548ffb0f5b30063d28815cdbfe45d02fdcaf3 Mon Sep 17 00:00:00 2001 From: Yashvardhan Arora Date: Sat, 4 Dec 2021 00:37:26 +0530 Subject: [PATCH 17/28] Add Word count and Char count toggle --- frontend/src/assets/css/Settings.css | 37 +++++++-- frontend/src/components/AddNote.js | 46 ----------- frontend/src/components/ExpandNote.js | 86 --------------------- frontend/src/components/Note.js | 77 ------------------ frontend/src/components/Notes/AddNote.js | 7 +- frontend/src/components/Notes/ExpandNote.js | 8 +- frontend/src/components/Notes/Note.js | 2 +- frontend/src/components/Notes/NotesList.js | 4 +- frontend/src/components/NotesList.js | 34 -------- frontend/src/components/Searchbar.js | 20 ----- frontend/src/components/Settings.js | 11 +++ frontend/src/pages/Dashboard.js | 18 +++++ 12 files changed, 74 insertions(+), 276 deletions(-) delete mode 100644 frontend/src/components/AddNote.js delete mode 100644 frontend/src/components/ExpandNote.js delete mode 100644 frontend/src/components/Note.js delete mode 100644 frontend/src/components/NotesList.js delete mode 100644 frontend/src/components/Searchbar.js diff --git a/frontend/src/assets/css/Settings.css b/frontend/src/assets/css/Settings.css index 8d8c64d..2bcccab 100644 --- a/frontend/src/assets/css/Settings.css +++ b/frontend/src/assets/css/Settings.css @@ -36,9 +36,9 @@ .pfpContainer { - height: 150px; - width: 150px; - border-radius: 150px; + height: 100px; + width: 100px; + border-radius: 100px; margin: 0 auto; overflow: hidden; text-align: right; @@ -46,7 +46,7 @@ .pfp { width: 100%; - height: 150px; + height: 100px; object-fit: cover; object-position: center; } @@ -54,7 +54,7 @@ .changeAvatar { margin-top: 10px; - font-size: 0.9rem; + font-size: 0.8rem; cursor: pointer; } @@ -64,11 +64,36 @@ color: var(--yellowcolor); } +.controlContainer +{ + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + margin: 30px 0px 20px; + width: 75%; + padding: 10px 30px; + border: 2px dotted rgba(255, 255, 0, 0.589); + border-radius: 10px; +} +.option +{ + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-evenly; +} + +.option input +{ + margin: 0px 10px; +} + .settingsForm { padding: 0; margin: 0; - margin-top: 30px; + margin-top: 0px; } .settingsForm form diff --git a/frontend/src/components/AddNote.js b/frontend/src/components/AddNote.js deleted file mode 100644 index 185ee65..0000000 --- a/frontend/src/components/AddNote.js +++ /dev/null @@ -1,46 +0,0 @@ -import "../assets/css/Notes.css"; -import { useState } from "react"; -import {nanoid} from 'nanoid'; - -const AddNote=(props)=>{ - - const [noteText, setNoteText] = useState(""); - - const changeHandler =(event)=> - { - setNoteText(event.target.value); - } -const saveHandler=()=> -{ - if(noteText) - { - - let date= new Date; - const day = date.getDate(); - const month = date.getMonth() + 1; - const year = date.getFullYear(); - - let newnote={ - - text: noteText, - // date: day+"/"+month+"/"+year - }; - props.onSave(newnote); - setNoteText(""); - } -} - - return( -
-