Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create, retrieve, display, and edit Items on shopping lists #12

Merged
merged 6 commits into from Jun 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 9 additions & 5 deletions lib/components/add_new.dart
@@ -1,19 +1,23 @@
import 'package:flutter/material.dart';
import 'package:grocery_go/models/shopping_list.dart';
import 'package:grocery_go/views/new_item.dart';

class AddNew extends StatelessWidget {

final list;
final listType;
AddNew({Key key, @required this.list, @required this.listType});
final listID;
final ShoppingList parentList;

AddNew({Key key, this.listType, this.listID, this.parentList});

goToAddNew(context) {
goToAddNew(context) async {
print(listType);
if (listType == 'shopping list') {
Navigator.pushNamed(context, '/newShoppingList');
} else if (listType == 'store') {
Navigator.pushNamed(context, '/newStore');
} else if (listType == 'item') {
Navigator.pushNamed(context, '/newItem', arguments: NewItemArguments('abc123'));
final result = await Navigator.pushNamed(context, '/newItem', arguments: NewItemArguments(parentList.id, parentList.name));
print("result: " + result.toString());
} else {
print('Error, unhandled listType in goToAddNew in item_list.dart');
}
Expand Down
19 changes: 15 additions & 4 deletions lib/components/item_list.dart
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:grocery_go/models/item.dart';
import 'package:grocery_go/models/shopping_list.dart';
import 'package:grocery_go/models/store.dart';

Expand All @@ -12,15 +13,16 @@ class ItemList extends StatelessWidget {
final String listType;
final onItemTap;
final onInfoTap;
final ShoppingList parentList;

ItemList({Key key, @required this.list, @required this.listType, @required this.onItemTap, @required this.onInfoTap});
ItemList({Key key, @required this.list, @required this.listType, @required this.onItemTap, @required this.onInfoTap, this.parentList});

@override
Widget build(BuildContext context) {

int getCount(item) {
if (listType == 'shopping list') {
return item.itemIDs?.length;
return item.itemCount;
} else {
return list.length;
}
Expand All @@ -34,16 +36,25 @@ class ItemList extends StatelessWidget {
if (index == list.length) {
if (listType == 'crossedOff') {
return DeleteAll();
} else { // store, shopping list
return AddNew(list: list, listType: listType);
} else if (listType == 'store' || listType == 'shopping list') {
return AddNew(listType: listType);
} else if (listType == 'item') {
return AddNew(listType: listType, parentList: parentList);
} else {
return Text("Invalid list type");
}
} else {

var listItem;

if (listType == 'shopping list') {
listItem = ShoppingList(list[index]);
} else if (listType == 'store') {
listItem = Store(list[index]);
} else if (listType == 'item') {
listItem = Item(list[index]);
} else {
print("Unhandled list item type");
}

return ListItem(item: listItem, listType: listType, count: getCount(listItem), onTap: onItemTap, onInfoTap: onInfoTap);
Expand Down
40 changes: 40 additions & 0 deletions lib/components/item_list_stream.dart
@@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
import 'package:grocery_go/components/add_new.dart';
import 'package:grocery_go/components/item_list.dart';


class ItemListStream extends StatelessWidget {

final dbStream;
final listType;
final onTap;
final onInfoTap;
final parentList;

ItemListStream({this.dbStream, this.listType, this.onTap, this.onInfoTap, this.parentList});

@override
Widget build(BuildContext context) {
return StreamBuilder(
stream: dbStream,
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
if (snapshot.hasData && !snapshot.data.documents.isEmpty) {
return ItemList(list: snapshot.data.documents, listType: listType, onItemTap: onTap, onInfoTap: onInfoTap, parentList: parentList);
} else {
return Column(
children: [
Padding(
padding: EdgeInsets.all(8),
child: Text("No items yet!"),
),
AddNew(listType: listType, parentList: parentList),
],
);
}
}
);
}
}
8 changes: 6 additions & 2 deletions lib/components/list_item.dart
Expand Up @@ -13,7 +13,11 @@ class ListItem extends StatelessWidget {
ListItem({Key key, this.item: "Unknown", this.listType, this.count, this.onTap, this.onInfoTap});

buildDateString(date) {
return DateFormat.yMMMd().format(DateTime.parse(date));
if (date != null && date.length > 0) {
return DateFormat.yMMMd().format(DateTime.parse(date));
} else {
return 'unknown date';
}
}

buildCrossedOffDate(date) {
Expand All @@ -37,7 +41,7 @@ class ListItem extends StatelessWidget {
} else if (listType == 'store') {
return item.address;
} else if (listType == 'item') {
return 'Added by ' + item.addedBy + ' on ' + buildDateString(item.lastUpdated);
return 'Added by ' + (item?.addedBy ?? 'no one') + ' on ' + buildDateString(item.lastUpdated);
} else if (listType == 'crossedOff') {
return '' + buildCrossedOffDate(item.lastUpdated) + ' at storeName';
} else {
Expand Down
47 changes: 47 additions & 0 deletions lib/db/database_manager.dart
@@ -1,4 +1,5 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:grocery_go/db/item_dto.dart';
import 'package:grocery_go/db/shopping_list_dto.dart';
import 'package:grocery_go/db/store_dto.dart';

Expand All @@ -15,6 +16,10 @@ class DatabaseManager {
return stores.orderBy("name").snapshots();
}

Stream<QuerySnapshot> getItemsStream(shoppingListID) {
return shoppingLists.document(shoppingListID).collection('items').snapshots();
}

Future<DocumentReference> addShoppingList(ShoppingListDTO shoppingList) async {
DocumentReference docRef = await shoppingLists.add(shoppingList.toJson());
shoppingLists.document(docRef.documentID).updateData({'id':docRef.documentID});
Expand All @@ -34,6 +39,26 @@ class DatabaseManager {
}
}

Future addItemToShoppingList(String listID, String itemID) async {
print("adding item[$itemID] to list[$listID]");
if (listID != null && listID.length > 0) {
DocumentReference docRef = shoppingLists.document(listID);
Firestore.instance.runTransaction((Transaction tx) async {
DocumentSnapshot doc = await tx.get(docRef);
if (doc.exists) {
List<String> newItemIDArr = [];
newItemIDArr.add(itemID);
await tx.update(docRef, {'itemIDs': FieldValue.arrayUnion(newItemIDArr)},);

}
}).catchError((e) {
print(e.toString());
});
} else {
print("List id is null/has no length");
}
}

Future<DocumentReference> addStore(StoreDTO store) async {
DocumentReference docRef = await stores.add(store.toJson());
stores.document(docRef.documentID).updateData({'id':docRef.documentID});
Expand All @@ -53,4 +78,26 @@ class DatabaseManager {
}
}

Future<DocumentReference> createItem(String parentListID, ItemDTO item) async {
shoppingLists.document(parentListID).updateData({'itemCount': FieldValue.increment(1)});
DocumentReference itemDocRef = await shoppingLists.document(parentListID).collection('items').add(item.toJson());
print(itemDocRef.documentID);
itemDocRef.updateData({'id':itemDocRef.documentID});
return itemDocRef;
}

Future updateItem(String parentListID, ItemDTO item) async {
print("item:" + item.toString());
if (parentListID != null && parentListID.length > 0) {
DocumentReference itemDocRef = shoppingLists.document(parentListID).collection('items').document(item.id);
Firestore.instance.runTransaction((Transaction tx) async {
await tx.update(itemDocRef, item.toJson());
}).catchError((e) {
print(e.toString());
});
} else {
print("ID is null/has no length");
}
}

}
32 changes: 32 additions & 0 deletions lib/db/item_dto.dart
@@ -0,0 +1,32 @@
class ItemDTO {

String id;
String name;
String date;
int quantity;
bool subsOk;
List substitutions;
String addedBy;
String lastUpdated;
bool private;
bool urgent;

String toString() {
return 'id: $id, name: $name, date: $date, '
'quantity: $quantity, subsOk: $subsOk, substitutions: $substitutions, '
'addedBy: $addedBy, lastUpdated: $lastUpdated, private: $private, urgent: $urgent';
}

Map<String, dynamic> toJson() => <String, dynamic> {
'id': this.id,
'name': this.name,
'date': this.date,
'quantity': this.quantity,
'subsOk': this.subsOk,
'substitutions': this.substitutions,
'addedBy': this.addedBy,
'lastUpdated': this.lastUpdated,
'private': this.private,
'urgent':this.urgent,
};
}
8 changes: 4 additions & 4 deletions lib/db/shopping_list_dto.dart
Expand Up @@ -3,16 +3,16 @@ class ShoppingListDTO {
String id;
String name;
String date;
List itemIDs;
int itemCount;

String toString() {
return 'id: $id, name: $name, date: $date, itemIDs: $itemIDs';
return 'id: $id, name: $name, date: $date, itemCount: $itemCount';
}

Map<String, dynamic> toJson() => <String, dynamic> {
'id': this.id ?? '',
'name': this.name,
'name': this.name ?? 'unnamed item',
'date': this.date,
'itemIDs': this.itemIDs,
'itemCount': this.itemCount ?? 0,
};
}