backend
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:flutter_shopping_list/data/categories.dart';
|
||||
|
||||
import 'package:flutter_shopping_list/models/grocery_item.dart';
|
||||
import 'package:flutter_shopping_list/widgets/new_item.dart';
|
||||
@@ -11,7 +15,61 @@ class GroceryList extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _GroceryListState extends State<GroceryList> {
|
||||
final List<GroceryItem> _groceryItems = [];
|
||||
List<GroceryItem> _groceryItems = [];
|
||||
var _isLoading = true;
|
||||
String? _error;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadItems();
|
||||
}
|
||||
|
||||
void _loadItems() async {
|
||||
final url = Uri.https(
|
||||
'flutter-prep-dccfe-default-rtdb.firebaseio.com', 'shopping-list.json');
|
||||
|
||||
try {
|
||||
final response = await http.get(url);
|
||||
|
||||
if (response.statusCode >= 400) {
|
||||
setState(() {
|
||||
_error = 'Failed to fetch data. Please try again later.';
|
||||
});
|
||||
}
|
||||
|
||||
if (response.body == 'null') {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
final Map<String, dynamic> listData = json.decode(response.body);
|
||||
final List<GroceryItem> loadedItems = [];
|
||||
for (final item in listData.entries) {
|
||||
final category = categories.entries
|
||||
.firstWhere(
|
||||
(catItem) => catItem.value.title == item.value['category'])
|
||||
.value;
|
||||
loadedItems.add(GroceryItem(
|
||||
id: item.key,
|
||||
name: item.value['name'],
|
||||
quantity: item.value['quantity'],
|
||||
category: category,
|
||||
));
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_groceryItems = loadedItems;
|
||||
_isLoading = false;
|
||||
});
|
||||
} catch (error) {
|
||||
setState(() {
|
||||
_error = 'Something went wrong. Please try again later.';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _addItem() async {
|
||||
final newItem = await Navigator.of(context).push<GroceryItem>(
|
||||
@@ -29,16 +87,32 @@ class _GroceryListState extends State<GroceryList> {
|
||||
});
|
||||
}
|
||||
|
||||
void _removeItem(GroceryItem item) {
|
||||
void _removeItem(GroceryItem item) async {
|
||||
final index = _groceryItems.indexOf(item);
|
||||
setState(() {
|
||||
_groceryItems.remove(item);
|
||||
});
|
||||
|
||||
final url = Uri.https('flutter-prep-dccfe-default-rtdb.firebaseio.com',
|
||||
'shopping-list/${item.id}.json');
|
||||
|
||||
final response = await http.delete(url);
|
||||
|
||||
if (response.statusCode >= 400) {
|
||||
setState(() {
|
||||
_groceryItems.insert(index, item);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget content = const Center(child: Text('No items added yet.'));
|
||||
|
||||
if (_isLoading) {
|
||||
content = const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
if (_groceryItems.isNotEmpty) {
|
||||
content = ListView.builder(
|
||||
itemCount: _groceryItems.length,
|
||||
@@ -62,6 +136,10 @@ class _GroceryListState extends State<GroceryList> {
|
||||
);
|
||||
}
|
||||
|
||||
if (_error != null) {
|
||||
content = Center(child: Text(_error!));
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Your Groceries'),
|
||||
|
||||
@@ -22,10 +22,14 @@ class _NewItemState extends State<NewItem> {
|
||||
var _enteredName = '';
|
||||
var _enteredQuantity = 1;
|
||||
var _selectedCategory = categories[Categories.vegetables]!;
|
||||
var _isSending = false;
|
||||
|
||||
void _saveItem() async {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
_formKey.currentState!.save();
|
||||
setState(() {
|
||||
_isSending = true;
|
||||
});
|
||||
final url = Uri.https('flutter-prep-dccfe-default-rtdb.firebaseio.com',
|
||||
'shopping-list.json');
|
||||
final response = await http.post(
|
||||
@@ -40,14 +44,20 @@ class _NewItemState extends State<NewItem> {
|
||||
),
|
||||
);
|
||||
|
||||
print(response.body);
|
||||
print(response.statusCode);
|
||||
final Map<String, dynamic> resData = json.decode(response.body);
|
||||
|
||||
if (!context.mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop(
|
||||
GroceryItem(
|
||||
id: resData['name'],
|
||||
name: _enteredName,
|
||||
quantity: _enteredQuantity,
|
||||
category: _selectedCategory,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,14 +154,22 @@ class _NewItemState extends State<NewItem> {
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
onPressed: _isSending
|
||||
? null
|
||||
: () {
|
||||
_formKey.currentState!.reset();
|
||||
},
|
||||
child: const Text('Reset'),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: _saveItem,
|
||||
child: const Text('Add Item'),
|
||||
onPressed: _isSending ? null : _saveItem,
|
||||
child: _isSending
|
||||
? SizedBox(
|
||||
height: 16,
|
||||
width: 16,
|
||||
child: const CircularProgressIndicator(),
|
||||
)
|
||||
: const Text('Add Item'),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user