Commit fc2551fa authored by Ilham Maulana's avatar Ilham Maulana 💻

feat: paging book list

parent 50af315d
...@@ -489,11 +489,11 @@ class AuthProvider with ChangeNotifier { ...@@ -489,11 +489,11 @@ class AuthProvider with ChangeNotifier {
if (response.statusCode == 200) { if (response.statusCode == 200) {
final data = jsonDecode(response.body); final data = jsonDecode(response.body);
if (type == "upcoming") { if (type == "upcoming") {
nearOutstandingLoans = data; nearOutstandingLoans = data["data"];
} else if (type == "overdue") { } else if (type == "overdue") {
overduedLoans = data; overduedLoans = data["data"];
} else { } else {
loans = data; loans = data["data"];
} }
} else { } else {
final code = response.statusCode; final code = response.statusCode;
......
...@@ -12,6 +12,11 @@ class BookProvider with ChangeNotifier { ...@@ -12,6 +12,11 @@ class BookProvider with ChangeNotifier {
String? searchKeyword; String? searchKeyword;
String? filterByCategory; String? filterByCategory;
bool hasNextPage = false;
bool hasPrevPage = false;
int pageNumber = 1;
int? totalPages;
bool isLoading = false; bool isLoading = false;
void setLoading(bool value) { void setLoading(bool value) {
...@@ -26,6 +31,8 @@ class BookProvider with ChangeNotifier { ...@@ -26,6 +31,8 @@ class BookProvider with ChangeNotifier {
url += '?category=$filterByCategory'; url += '?category=$filterByCategory';
} else if (searchKeyword != null) { } else if (searchKeyword != null) {
url += "?search=$searchKeyword"; url += "?search=$searchKeyword";
} else if (pageNumber != null) {
url += "?page=$pageNumber";
} }
final response = await http.get( final response = await http.get(
...@@ -35,7 +42,11 @@ class BookProvider with ChangeNotifier { ...@@ -35,7 +42,11 @@ class BookProvider with ChangeNotifier {
if (response.statusCode == 200) { if (response.statusCode == 200) {
final data = jsonDecode(response.body); final data = jsonDecode(response.body);
books = data; books = data["data"];
hasNextPage = data["has_next"];
hasPrevPage = data["has_prev"];
pageNumber = data["page_number"];
totalPages = data["total_pages"];
} else { } else {
final code = response.statusCode; final code = response.statusCode;
debugPrint("Error: Fetch books failed, $code"); debugPrint("Error: Fetch books failed, $code");
...@@ -58,6 +69,11 @@ class BookProvider with ChangeNotifier { ...@@ -58,6 +69,11 @@ class BookProvider with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
void setPage(int value) {
pageNumber = value;
notifyListeners();
}
Future<void> getCategories() async { Future<void> getCategories() async {
try { try {
setLoading(true); setLoading(true);
......
...@@ -21,60 +21,106 @@ class _BookList extends State<BookList> { ...@@ -21,60 +21,106 @@ class _BookList extends State<BookList> {
Provider.of<BookProvider>(context, listen: false).getBooks(); Provider.of<BookProvider>(context, listen: false).getBooks();
} }
@override
void dispose() {
super.dispose();
}
ScrollController listScrollController = ScrollController();
void scrollToTop() {
if (listScrollController.hasClients) {
final position = listScrollController.position.minScrollExtent;
listScrollController.jumpTo(position);
}
}
Future<void> nextPage() async {
if (Provider.of<BookProvider>(context, listen: false).hasNextPage) {
Provider.of<BookProvider>(context, listen: false).setPage(
Provider.of<BookProvider>(context, listen: false).pageNumber + 1,
);
} else {
Provider.of<BookProvider>(context, listen: false).setPage(
Provider.of<BookProvider>(context, listen: false).totalPages!);
}
Provider.of<BookProvider>(context, listen: false).getBooks();
scrollToTop();
}
Future<void> prevPage() async {
if (Provider.of<BookProvider>(context, listen: false).hasPrevPage) {
Provider.of<BookProvider>(context, listen: false).setPage(
Provider.of<BookProvider>(context, listen: false).pageNumber - 1,
);
} else {
Provider.of<BookProvider>(context, listen: false).setPage(1);
}
Provider.of<BookProvider>(context, listen: false).getBooks();
scrollToTop();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<BookProvider>( return Consumer<BookProvider>(
builder: (context, bookProvider, child) { builder: (context, bookProvider, child) {
if (!bookProvider.isLoading) { final Iterable<Book> books = bookProvider.books!.map((book) {
final Iterable<Book> books = bookProvider.books!.map((book) { if (book["category"] != null) {
if (book["category"] != null) { final Category category = Category.fromJson(
final Category category = Category.fromJson( book["category"],
book["category"], );
);
return Book(
book["id"],
book["title"],
book["author"],
book["description"],
book["cover_image"],
category.name,
);
}
return Book( return Book(
book["id"], book["id"],
book["title"], book["title"],
book["author"], book["author"],
book["description"], book["description"],
book["cover_image"], book["cover_image"],
null, category.name,
); );
}); }
return NestedScrollView( return Book(
headerSliverBuilder: book["id"],
(BuildContext context, bool innerBoxIsScrolled) { book["title"],
return [const TopAppBar(title: "Books")]; book["author"],
}, book["description"],
body: ListView( book["cover_image"],
children: List.generate(books.length, (index) { null,
return BookItem(
books.elementAt(index),
);
}),
),
); );
} else { });
return NestedScrollView(
headerSliverBuilder: return NestedScrollView(
(BuildContext context, bool innerBoxIsScrolled) { headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [const TopAppBar(title: "Books")]; return [const TopAppBar(title: "Books")];
},
body: ListView.builder(
controller: listScrollController,
itemCount: books.length + 1,
itemBuilder: (context, index) {
if (index < books.length) {
return BookItem(books.elementAt(index));
} else {
return Container(
padding: const EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
onPressed: prevPage,
child: const Text('Prev'),
),
Text(bookProvider.pageNumber.toString()),
ElevatedButton(
onPressed: nextPage,
child: const Text('Next'),
),
],
),
);
}
}, },
body: const Center( ),
child: CircularProgressIndicator(), );
),
);
}
}, },
); );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment