From 7b939628b29f9f3222e4b21cbcf8f59e8692850b Mon Sep 17 00:00:00 2001 From: Andrei Stoica Date: Tue, 5 Nov 2024 04:28:18 -0500 Subject: [PATCH] adding tasks and templates --- lib/checklist.dart | 8 ++- lib/listpage.dart | 35 ++++++++++++ lib/listtemplates.dart | 65 ++++++++++++++++++++++ lib/main.dart | 83 ++++++++++++++++++++++++++-- lib/template_edit_page.dart | 104 ++++++++++++++++++++++++++++++++++++ lib/templates_page.dart | 44 +++++++++++++++ 6 files changed, 332 insertions(+), 7 deletions(-) create mode 100644 lib/listtemplates.dart create mode 100644 lib/template_edit_page.dart create mode 100644 lib/templates_page.dart diff --git a/lib/checklist.dart b/lib/checklist.dart index 6d6b104..09fc7a5 100644 --- a/lib/checklist.dart +++ b/lib/checklist.dart @@ -22,7 +22,12 @@ class _PrepPageState extends State { @override Widget build(BuildContext context) { - return ListView.builder( + return ListView.separated( + itemCount: prepLists.length, + separatorBuilder: (context, index) => const Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: Divider(color: Colors.grey), + ), itemBuilder: (context, index) { var list = prepLists[index]; return ListTile( @@ -36,7 +41,6 @@ class _PrepPageState extends State { }, ); }, - itemCount: prepLists.length, ); } } diff --git a/lib/listpage.dart b/lib/listpage.dart index 373bc3b..feace57 100644 --- a/lib/listpage.dart +++ b/lib/listpage.dart @@ -13,6 +13,36 @@ class ListPage extends StatefulWidget { class _ListPageState extends State { late Preplist list; + + void _showAddItem() async { + var item = await showDialog( + context: context, + builder: (context) { + GlobalKey formKey = GlobalKey(); + TextEditingController inputController = TextEditingController(); + + return AlertDialog( + title: const Text("Add item"), + content: Form( + key: formKey, + child: TextFormField( + controller: inputController, + decoration: const InputDecoration(hintText: "Task"), + )), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(inputController.text); + }, + child: const Text("Add")) + ], + ); + }); + setState(() { + list.tasks.add(Task(text: item)); + }); + } + @override void initState() { list = widget.list; @@ -44,6 +74,11 @@ class _ListPageState extends State { )); }, ), + floatingActionButton: FloatingActionButton( + shape: const CircleBorder(), + onPressed: _showAddItem, + child: const Icon(Icons.add), + ), ); } } diff --git a/lib/listtemplates.dart b/lib/listtemplates.dart new file mode 100644 index 0000000..4314bea --- /dev/null +++ b/lib/listtemplates.dart @@ -0,0 +1,65 @@ +import 'package:happy_camper_proto/preplist.dart'; +import 'package:happy_camper_proto/task.dart'; + +class ListTemplate { + ListTemplate({required this.name, List? lists}) { + this.lists = lists ?? []; + } + + String name; + late List lists; + + get length => lists.length; + + static List exampleData() { + return [ + ListTemplate( + name: "example template 1", + lists: [ + Preplist( + name: "Example List 1", + tasks: [Task(text: "task 1")], + ), + Preplist( + name: "Example List 2", + tasks: [ + Task(text: "task 2"), + Task(text: "task 3"), + ], + ), + ], + ), + ListTemplate( + name: "example template 2", + lists: [ + Preplist( + name: "Example List 3", + tasks: [ + Task(text: "task 4"), + Task(text: "task 5"), + ], + ) + ], + ), + ListTemplate( + name: "example template 3", + lists: [ + Preplist( + name: "Example List 4", + tasks: [ + Task(text: "task 6"), + Task(text: "task 7"), + ], + ), + Preplist( + name: "Example List 5", + tasks: [ + Task(text: "task 8"), + Task(text: "task 9"), + ], + ) + ], + ), + ]; + } +} diff --git a/lib/main.dart b/lib/main.dart index 7ba9f5a..0b22004 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:happy_camper_proto/checklist.dart'; +import 'package:happy_camper_proto/listtemplates.dart'; import 'package:happy_camper_proto/preplist.dart'; +import 'package:happy_camper_proto/templates_page.dart'; void main() { runApp(const MyApp()); @@ -35,7 +37,8 @@ class _MyHomePageState extends State { late Widget page; int _selectedPage = 0; - List prepLists = Preplist.exampleData(); + late List prepLists; + late List listTemplates; void _showPage(int i) { _selectedPage = i; @@ -43,6 +46,9 @@ class _MyHomePageState extends State { case 0: page = PrepPage(prepLists: prepLists); break; + case 1: + page = TemplatesPage(templates: listTemplates); + break; default: page = const Center( child: Text("Hello World"), @@ -51,8 +57,72 @@ class _MyHomePageState extends State { setState(() {}); } + void _fabOnPress() async { + switch (_selectedPage) { + case 0: + var item = await showDialog( + context: context, + builder: (context) { + GlobalKey formKey = GlobalKey(); + TextEditingController inputController = TextEditingController(); + + return AlertDialog( + title: const Text("New List"), + content: Form( + key: formKey, + child: TextFormField( + controller: inputController, + decoration: const InputDecoration(hintText: "Name"), + )), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(inputController.text); + }, + child: const Text("Add")) + ], + ); + }); + prepLists.add(Preplist(name: item, tasks: [])); + break; + case 1: + var value = await showDialog( + context: context, + builder: (context) { + GlobalKey formKey = GlobalKey(); + TextEditingController inputController = TextEditingController(); + + return AlertDialog( + title: const Text("New Template"), + content: Form( + key: formKey, + child: TextFormField( + controller: inputController, + decoration: const InputDecoration(hintText: "Name"), + )), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(inputController.text); + }, + child: const Text("Add")) + ], + ); + }); + listTemplates.add(ListTemplate(name: value)); + break; + default: + ScaffoldMessenger.of(context).showSnackBar(const SnackBar( + content: Text("This page should not have a FAB"), + )); + } + _showPage(_selectedPage); + } + @override void initState() { + prepLists = Preplist.exampleData(); + listTemplates = ListTemplate.exampleData(); page = PrepPage(prepLists: prepLists); super.initState(); } @@ -86,10 +156,13 @@ class _MyHomePageState extends State { ), ], ), - floatingActionButton: FloatingActionButton( - child: const Icon(Icons.add), - onPressed: () {}, - ), + floatingActionButton: (_selectedPage == 0 || _selectedPage == 1) + ? FloatingActionButton( + mini: true, + onPressed: _fabOnPress, + child: const Icon(Icons.add), + ) + : null, floatingActionButtonLocation: FloatingActionButtonLocation.miniCenterFloat, ); diff --git a/lib/template_edit_page.dart b/lib/template_edit_page.dart new file mode 100644 index 0000000..3c8b6fb --- /dev/null +++ b/lib/template_edit_page.dart @@ -0,0 +1,104 @@ +import 'package:flutter/material.dart'; +import 'package:happy_camper_proto/listtemplates.dart'; +import 'package:happy_camper_proto/preplist.dart'; + +class TemplateEditPage extends StatefulWidget { + const TemplateEditPage({super.key, required this.template}); + + final ListTemplate template; + + @override + State createState() => _TemplateEditPageState(); +} + +class _TemplateEditPageState extends State { + late ListTemplate template; + + @override + void initState() { + template = widget.template; + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(), + body: ListView.separated( + itemCount: template.length, + separatorBuilder: (context, index) => const Padding( + padding: EdgeInsets.symmetric(horizontal: 10), + child: Divider()), + itemBuilder: (context, index) => + ListDisplay(list: template.lists[index]))); + } +} + +class ListDisplay extends StatefulWidget { + const ListDisplay({super.key, required this.list, this.hidden = false}); + + final Preplist list; + final bool hidden; + + @override + State createState() => _ListDisplayState(); +} + +class _ListDisplayState extends State { + late Preplist list; + late bool hidden; + bool editMode = false; + + @override + void initState() { + list = widget.list; + hidden = widget.hidden; + super.initState(); + } + + void _toggleHidden() { + setState(() { + hidden = !hidden; + }); + } + + void _toggleEdit() { + setState(() { + editMode = !editMode; + }); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: _toggleHidden, + onLongPress: _toggleEdit, + child: Padding( + padding: const EdgeInsets.all(10), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text( + style: Theme.of(context).textTheme.titleLarge, + list.name, + ), + const Spacer(), + Visibility( + visible: editMode, child: const Icon(Icons.edit)), + Icon(hidden ? Icons.arrow_left : Icons.arrow_drop_down), + ], + ), + Visibility( + visible: !hidden, + child: Column( + children: list.tasks + .map((task) => Text(task.text, + style: Theme.of(context).textTheme.bodyLarge)) + .toList())), + ], + ))); + } +} diff --git a/lib/templates_page.dart b/lib/templates_page.dart new file mode 100644 index 0000000..5e0e532 --- /dev/null +++ b/lib/templates_page.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; +import 'package:happy_camper_proto/listtemplates.dart'; +import 'package:happy_camper_proto/template_edit_page.dart'; + +class TemplatesPage extends StatefulWidget { + const TemplatesPage({super.key, required this.templates}); + + final List templates; + + @override + State createState() => _TemplatesPageState(); +} + +class _TemplatesPageState extends State { + late List templates; + @override + void initState() { + templates = widget.templates; + super.initState(); + } + + @override + Widget build(BuildContext context) { + return ListView.separated( + itemCount: templates.length, + separatorBuilder: (context, index) => const Padding( + padding: EdgeInsets.symmetric(horizontal: 20), + child: Divider( + color: Colors.grey, + ), + ), + itemBuilder: (context, index) => ListTile( + title: Text(templates[index].name), + subtitle: Text("${templates[index].length} lists"), + onTap: () { + Navigator.of(context).push(MaterialPageRoute( + builder: (context) => TemplateEditPage( + template: templates[index], + ))); + }, + ), + ); + } +}