From 738808d48f231a49a1c09f1fbb617849e8f9ca75 Mon Sep 17 00:00:00 2001
From: Omer <56688420+omerfaunal@users.noreply.github.com>
Date: Sat, 23 Dec 2023 19:11:32 +0300
Subject: [PATCH] 646 fe home page advanced nodes (#677)

* New provider for getting nodes by type

* Create node options menu buttons

* Add buttons to home page
---
 .../lib/providers/node_provider.dart          | 36 +++++++++++
 .../lib/screens/home_page/home_page.dart      | 60 +++++++++++++----
 .../screens/home_page/mobile_home_page.dart   |  5 ++
 .../home_page/widgets/select_button.dart      | 64 +++++++++++++++++++
 .../home_page/widgets/select_buttons.dart     | 47 ++++++++++++++
 5 files changed, 198 insertions(+), 14 deletions(-)
 create mode 100644 project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_button.dart
 create mode 100644 project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_buttons.dart

diff --git a/project/FrontEnd/collaborative_science_platform/lib/providers/node_provider.dart b/project/FrontEnd/collaborative_science_platform/lib/providers/node_provider.dart
index 5532ab0e..0bd21156 100644
--- a/project/FrontEnd/collaborative_science_platform/lib/providers/node_provider.dart
+++ b/project/FrontEnd/collaborative_science_platform/lib/providers/node_provider.dart
@@ -152,6 +152,42 @@ class NodeProvider with ChangeNotifier {
     }
   }
 
+  Future<void> getNodeByType(String queryType) async {
+    Uri url = Uri.parse("${Constants.apiUrl}/search/?type=$queryType");
+    final Map<String, String> headers = {
+      "Accept": "application/json",
+      "content-type": "application/json"
+    };
+    try {
+      final response = await http.get(url, headers: headers);
+
+      if (response.statusCode == 200) {
+        final data = json.decode(response.body);
+        _searchNodeResult.clear();
+        _searchNodeResult.addAll((data['nodes'] as List<dynamic>).map((node) => Node(
+              contributors: (node['authors'] as List<dynamic>)
+                  .map((author) => User(
+                      id: author['id'],
+                      firstName: author['name'],
+                      lastName: author['surname'],
+                      email: author['username']))
+                  .toList(),
+              id: node['id'],
+              nodeTitle: node['title'],
+              publishDate: DateTime.parse(node['date']),
+            )));
+        notifyListeners();
+      } else if (response.statusCode == 400) {
+        throw SearchError();
+      } else {
+        print(response);
+        throw Exception("Error");
+      }
+    } catch (e) {
+      rethrow;
+    }
+  }
+
   Future<void> getNodeSuggestions() async {
     await search(SearchType.theorem, "", random: true, suggestions: true);
   }
diff --git a/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/home_page.dart b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/home_page.dart
index 00de7d9f..ef533621 100644
--- a/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/home_page.dart
+++ b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/home_page.dart
@@ -29,7 +29,7 @@ class _HomePageState extends State<HomePage> {
   @override
   void didChangeDependencies() {
     if (_firstTime) {
-      randomNodes();
+      onTypeChange(0);
       _firstTime = false;
     }
     super.didChangeDependencies();
@@ -41,23 +41,25 @@ class _HomePageState extends State<HomePage> {
     super.dispose();
   }
 
-  void randomNodes() async {
+  Future<void> onTypeChange(int index) async {
+    final nodeProvider = Provider.of<NodeProvider>(context, listen: false);
+    String type = "";
+    if (index == 0) {
+      type = "trending";
+    } else if (index == 1) {
+      type = "latest";
+    } else if (index == 2) {
+      type = "most_read";
+    } else if (index == 3) {
+      type = "random";
+    } else if (index == 4) {
+      type = "for_you";
+    }
     try {
-      final nodeProvider = Provider.of<NodeProvider>(context, listen: false);
       setState(() {
         isLoading = true;
       });
-      await nodeProvider.search(SearchType.both, "", random: true);
-    } on WrongSearchTypeError {
-      setState(() {
-        error = true;
-        errorMessage = WrongSearchTypeError().message;
-      });
-    } on SearchError {
-      setState(() {
-        error = true;
-        errorMessage = SearchError().message;
-      });
+      await nodeProvider.getNodeByType(type);
     } catch (e) {
       setState(() {
         error = true;
@@ -70,6 +72,35 @@ class _HomePageState extends State<HomePage> {
     }
   }
 
+  // void randomNodes() async {
+  //   try {
+  //     final nodeProvider = Provider.of<NodeProvider>(context, listen: false);
+  //     setState(() {
+  //       isLoading = true;
+  //     });
+  //     await nodeProvider.search(SearchType.both, "", random: true);
+  //   } on WrongSearchTypeError {
+  //     setState(() {
+  //       error = true;
+  //       errorMessage = WrongSearchTypeError().message;
+  //     });
+  //   } on SearchError {
+  //     setState(() {
+  //       error = true;
+  //       errorMessage = SearchError().message;
+  //     });
+  //   } catch (e) {
+  //     setState(() {
+  //       error = true;
+  //       errorMessage = "Something went wrong!";
+  //     });
+  //   } finally {
+  //     setState(() {
+  //       isLoading = false;
+  //     });
+  //   }
+  // }
+
   void search(String text) async {
     if (text.isEmpty) return;
     if (text.length < 4) return;
@@ -146,6 +177,7 @@ class _HomePageState extends State<HomePage> {
     return MobileHomePage(
       searchBarFocusNode: searchBarFocusNode,
       onSearch: search,
+      onTypeChange: onTypeChange,
       onSemanticSearch: semanticSearch,
       isLoading: isLoading,
       error: error,
diff --git a/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/mobile_home_page.dart b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/mobile_home_page.dart
index 9d860e7e..b8c343b3 100644
--- a/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/mobile_home_page.dart
+++ b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/mobile_home_page.dart
@@ -3,6 +3,7 @@ import 'package:collaborative_science_platform/providers/node_provider.dart';
 import 'package:collaborative_science_platform/providers/user_provider.dart';
 import 'package:collaborative_science_platform/screens/home_page/widgets/home_page_appbar.dart';
 import 'package:collaborative_science_platform/screens/home_page/widgets/node_cards.dart';
+import 'package:collaborative_science_platform/screens/home_page/widgets/select_buttons.dart';
 import 'package:collaborative_science_platform/screens/home_page/widgets/user_cards.dart';
 import 'package:collaborative_science_platform/screens/page_with_appbar/page_with_appbar.dart';
 import 'package:collaborative_science_platform/utils/responsive/responsive.dart';
@@ -14,6 +15,7 @@ import 'package:provider/provider.dart';
 class MobileHomePage extends StatelessWidget {
   final FocusNode searchBarFocusNode;
   final Function onSearch;
+  final Function onTypeChange;
   final Function onSemanticSearch;
   final bool isLoading;
   final bool error;
@@ -23,6 +25,7 @@ class MobileHomePage extends StatelessWidget {
     super.key,
     required this.searchBarFocusNode,
     required this.onSearch,
+    required this.onTypeChange,
     required this.onSemanticSearch,
     required this.isLoading,
     required this.error,
@@ -52,6 +55,8 @@ class MobileHomePage extends StatelessWidget {
                     desktop:
                         SearchBarExtended(exactSearch: onSearch, semanticSearch: onSemanticSearch)),
               ),
+              const SizedBox(height: 10.0),
+              SelectButtons(onTypeChange),
               Padding(
                   padding: const EdgeInsets.only(top: 10.0),
                   child: isLoading
diff --git a/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_button.dart b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_button.dart
new file mode 100644
index 00000000..3158ffe4
--- /dev/null
+++ b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_button.dart
@@ -0,0 +1,64 @@
+import 'package:flutter/material.dart';
+
+class SelectButton extends StatefulWidget {
+  final int index;
+  final String name;
+  final bool selected;
+  final Function onPressed;
+  const SelectButton(
+      {required this.index,
+      required this.name,
+      required this.selected,
+      required this.onPressed,
+      super.key});
+
+  @override
+  State<SelectButton> createState() => _SelectButtonState();
+}
+
+class _SelectButtonState extends State<SelectButton> {
+  bool isHovering = false;
+  @override
+  Widget build(BuildContext context) {
+    return MouseRegion(
+      cursor: SystemMouseCursors.click,
+      onEnter: (event) => setState(() => isHovering = true),
+      onExit: (event) => setState(() => isHovering = false),
+      child: GestureDetector(
+        onTap: () {
+          widget.onPressed(widget.index);
+        },
+        child: Container(
+          height: 35,
+          width: 90,
+          decoration: BoxDecoration(
+            borderRadius: BorderRadius.circular(6),
+            color: widget.selected
+                ? Colors.indigo[600]
+                : isHovering
+                    ? Colors.indigo[200]
+                    : Colors.grey[200],
+          ),
+          padding: const EdgeInsets.all(10),
+          margin: const EdgeInsets.only(right: 8),
+          child: Row(
+            mainAxisSize: MainAxisSize.min,
+            mainAxisAlignment: MainAxisAlignment.center,
+            children: [
+              SelectionContainer.disabled(
+                child: Text(
+                  widget.name,
+                  textAlign: TextAlign.center,
+                  style: TextStyle(
+                      fontSize: 12,
+                      fontWeight: FontWeight.w600,
+                      color: widget.selected ? Colors.white : Colors.grey[700]),
+                ),
+              ),
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+}
diff --git a/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_buttons.dart b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_buttons.dart
new file mode 100644
index 00000000..4c9ea42f
--- /dev/null
+++ b/project/FrontEnd/collaborative_science_platform/lib/screens/home_page/widgets/select_buttons.dart
@@ -0,0 +1,47 @@
+import 'package:collaborative_science_platform/screens/home_page/widgets/select_button.dart';
+import 'package:flutter/material.dart';
+
+class SelectButtons extends StatefulWidget {
+  final Function onTypeChange;
+  const SelectButtons(this.onTypeChange, {super.key});
+
+  @override
+  State<SelectButtons> createState() => _SelectButtonsState();
+}
+
+class _SelectButtonsState extends State<SelectButtons> {
+  int selectedIndex = 0;
+
+  void selectOne(int index) async {
+    setState(() {
+      selectedIndex = index;
+    });
+    widget.onTypeChange(index);
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Row(
+      mainAxisAlignment: MainAxisAlignment.center,
+      children: [
+        SelectButton(
+            index: 0, name: "Trending", selected: selectedIndex == 0, onPressed: selectOne),
+        const SizedBox(width: 10.0),
+        SelectButton(index: 1, name: "Latest", selected: selectedIndex == 1, onPressed: selectOne),
+        const SizedBox(width: 10.0),
+        SelectButton(
+            index: 2, name: "Most Read", selected: selectedIndex == 2, onPressed: selectOne),
+        const SizedBox(width: 10.0),
+        SelectButton(index: 3, name: "Random", selected: selectedIndex == 3, onPressed: selectOne),
+        // if (Provider.of<Auth>(context).isSignedIn)
+        //   Row(
+        //     children: [
+        //       const SizedBox(width: 10.0),
+        //       SelectButton(
+        //           index: 4, name: "For You", selected: selectedIndex == 4, onPressed: selectOne),
+        //     ],
+        //   ),
+      ],
+    );
+  }
+}