#7 Match Search Page with Design #671

Öppen
savio wants to merge 5 commits from savio/issue_671 into savio/master

+ 1 - 1
src/components/molecules/Cards/CommentCard.js

@@ -6,7 +6,7 @@ import { Menu, Provider } from 'react-native-paper'
 import colors from '../../../constants/colors'
 import fonts from '../../../constants/fonts'
 import ButtonWrapper from '../../atoms/Buttons/ButtonWrapper'
-import { getTimestamp } from '../../../constants/functions'
+import { getTimestamp } from '../../../utils/functions'
 import images from '../../../assets/images/images'
 import { horizontalScale, moderateScale, verticalScale } from '../../../constants/metrics'
 

+ 1 - 1
src/components/molecules/Cards/HorizontalNewsCard.js

@@ -2,7 +2,7 @@ import { Image, StyleSheet, Text, TouchableWithoutFeedback, View } from 'react-n
 import React from 'react'
 import images from '../../../assets/images/images'
 import ShareButton from '../Buttons/ShareButton'
-import { getTimestamp } from '../../../constants/functions'
+import { getTimestamp } from '../../../utils/functions'
 import BookmarkButton from '../../atoms/Buttons/BookmarkButton'
 import { horizontalScale, moderateScale, screenWidth, verticalScale } from '../../../constants/metrics'
 import fonts from '../../../constants/fonts'

+ 1 - 1
src/components/molecules/Cards/HorizontalNewsCardVariant.js

@@ -5,7 +5,7 @@ import ShareButton from '../../atoms/Buttons/ShareButton'
 import { horizontalScale, moderateScale, screenWidth, verticalScale } from '../../../constants/metrics'
 import fonts from '../../../constants/fonts'
 import colors from '../../../constants/colors'
-import { getScreenType, getTimestamp } from '../../../constants/functions'
+import { getScreenType, getTimestamp } from '../../../utils/functions'
 import images from '../../../assets/images/images'
 import { ThemeContext } from '../../../context/theme.context'
 

+ 1 - 1
src/components/molecules/Cards/NotificationCard.js

@@ -3,7 +3,7 @@ import React from 'react'
 import images from '../../../assets/images/images'
 import { horizontalScale, moderateScale, verticalScale } from '../../../constants/metrics'
 import colors from '../../../constants/colors'
-import { getTimestamp } from '../../../constants/functions'
+import { getTimestamp } from '../../../utils/functions'
 import fonts from '../../../constants/fonts'
 
 

+ 1 - 1
src/components/molecules/Cards/VerticalNewsCard.js

@@ -5,7 +5,7 @@ import images from '../../../assets/images/images'
 import { horizontalScale, moderateScale, screenWidth, verticalScale } from '../../../constants/metrics'
 import fonts from '../../../constants/fonts'
 import { ThemeContext } from '../../../context/theme.context'
-import { getTimestamp } from '../../../constants/functions'
+import { getTimestamp } from '../../../utils/functions'
 import BookmarkButton from '../../atoms/Buttons/BookmarkButton'
 import ShareButton from '../../atoms/Buttons/ShareButton'
 

+ 89 - 0
src/components/organisms/Sections/CategorySearchSection.js

@@ -0,0 +1,89 @@
+import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'
+import React, { useState } from 'react'
+import { navigateToListViewPage, useConstructor } from '../../../utils/functions'
+import { getCategories } from '../../../api/data'
+import fonts from '../../../constants/fonts'
+import colors from '../../../constants/colors'
+import { horizontalScale, moderateScale, verticalScale } from '../../../constants/metrics'
+import { BASE_URL } from '../../../api/urls'
+import LoadingScreen from './LoadingScreen'
+
+const CategorySearchSection = props => {
+
+    const {
+        navigation,
+        route
+    } = props
+
+    const [categories, setCategories] = useState(null)
+
+    const fetchCategories = () => {
+        getCategories().then(res => setCategories(res.data.body.results)).catch(err => console.log(err))
+    }
+
+    useConstructor(() => {
+        fetchCategories()
+    })
+
+    const styles = StyleSheet.create({
+        sectionHeader: {
+            fontFamily: fonts.type.semibold,
+            color: colors().recessive,
+            paddingHorizontal: horizontalScale(16),
+
+
+        },
+        categoryContainer: {
+            padding: verticalScale(16),
+            flexDirection: 'row',
+            flexWrap: 'wrap',
+            gap: moderateScale(16),
+        },
+        category: {
+            height: verticalScale(110),
+            width: 170,
+            backgroundColor: colors().secondaryColor,
+            borderRadius: moderateScale(8),
+            padding: moderateScale(10),
+            alignItems: 'center',
+            justifyContent: 'center',
+            gap: verticalScale(8)
+        },
+        categoryIcon: {
+            height: moderateScale(36),
+            width: moderateScale(36),
+            tintColor: colors().white
+        },
+        categoryText: {
+            fontFamily: fonts.type.semibold,
+            color: colors().white,
+            fontSize: moderateScale(14),
+            textAlign: 'right'
+        },
+    })
+
+    return (
+        <View>
+            <Text style={styles.sectionHeader}>Browse by Categories</Text>
+            <View style={styles.categoryContainer}>
+                {
+                    categories !== null ?
+                        categories.length > 0 ?
+                            categories.map((item) =>
+                                <TouchableOpacity onPress={() => navigateToListViewPage(navigation, "category", item.heading.name)}>
+                                    <View style={styles.category}>
+                                        <Image source={{ uri: BASE_URL + "/" + item.heading.icon }} style={styles.categoryIcon} />
+                                        <Text style={styles.categoryText}>{item.heading.name}</Text>
+                                    </View>
+                                </TouchableOpacity>
+
+                            ) : <></>
+                        : <LoadingScreen containerHeight={verticalScale(240)}/>
+                }
+
+            </View>
+        </View>
+    )
+}
+
+export default CategorySearchSection

+ 1 - 1
src/components/organisms/Sections/CategorySection.js

@@ -10,7 +10,7 @@ import {
   navigateToArticle,
   navigateToListViewPage,
   onShare,
-} from '../../../constants/functions';
+} from '../../../utils/functions';
 import SectionHeader from '../../molecules/Header/SectionHeader';
 import {
   horizontalScale,

+ 1 - 1
src/components/organisms/Sections/NoBookmarkSection.js

@@ -5,7 +5,7 @@ import fonts from '../../../constants/fonts'
 import colors from '../../../constants/colors'
 import { horizontalScale, moderateScale, screenHeight, verticalScale } from '../../../constants/metrics'
 import ThemedTextButton from '../../molecules/Buttons/ThemeTextButton'
-import { navigateToHomePage } from '../../../constants/functions'
+import { navigateToHomePage } from '../../../utils/functions'
 import { useNavigation } from '@react-navigation/native'
 
 

+ 1 - 1
src/components/organisms/Sections/NotificationSection.js

@@ -3,7 +3,7 @@ import React from 'react'
 import fonts from '../../../constants/fonts'
 import colors from '../../../constants/colors'
 import images from '../../../assets/images/images'
-import { getDate } from '../../../constants/functions'
+import { getDate } from '../../../utils/functions'
 import NotificationCard from '../../molecules/Cards/NotificationCard'
 import { horizontalScale, moderateScale, verticalScale } from '../../../constants/metrics'
 

+ 1 - 1
src/components/organisms/Sections/RecentPostsSection.js

@@ -2,7 +2,7 @@ import { ScrollView, StyleSheet, Text, View } from 'react-native'
 import React, { useContext } from 'react'
 import { horizontalScale, moderateScale, verticalScale } from '../../../constants/metrics'
 import VerticalNewsCard from '../../molecules/Cards/VerticalNewsCard'
-import { navigateToArticle, useConstructor } from '../../../constants/functions'
+import { navigateToArticle, useConstructor } from '../../../utils/functions'
 import SectionHeader from '../../molecules/Header/SectionHeader'
 import { ThemeContext } from '../../../context/theme.context'
 import colors from '../../../constants/colors'

+ 69 - 0
src/components/organisms/Sections/RecentSearchesSection.js

@@ -0,0 +1,69 @@
+import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'
+import React, { useState } from 'react'
+import { horizontalScale, moderateScale, verticalScale } from '../../../constants/metrics'
+import colors from '../../../constants/colors'
+import fonts from '../../../constants/fonts'
+import { navigateToArticle, useConstructor } from '../../../utils/functions'
+import { getTrendingNews } from '../../../api/data'
+import { PAGINATE_BY } from '../../../api/urls'
+import { List } from 'react-native-paper'
+import IonIcon from 'react-native-vector-icons/Ionicons'
+import LoadingScreen from './LoadingScreen'
+
+const RecentSearchesSection = props => {
+
+    const [recentSearches, setRecentSearches] = useState(null)
+    const {
+        navigation,
+        route
+    } = props
+
+    const getRecentSearches = () => {
+        getTrendingNews().then(res => setRecentSearches(res.data.body.results.slice(0, PAGINATE_BY))).catch(err => console.error(err))
+    }
+
+    useConstructor(() => {
+        getRecentSearches()
+    })
+
+    const styles = StyleSheet.create({
+        sectionHeader: {
+            fontFamily: fonts.type.semibold,
+            color: colors().recessive,
+            paddingHorizontal: horizontalScale(16),
+        },
+        categoryContainer: {
+            padding: verticalScale(16),
+            flexDirection: 'row',
+            flexWrap: 'wrap',
+            gap: moderateScale(16),
+        },
+    })
+
+    return (
+        <View>
+            <Text style={styles.sectionHeader}>Recent Searches</Text>
+            <View style={[styles.categoryContainer, { gap: 0 }]}>
+                {
+                    recentSearches !== null ?
+                        recentSearches.length > 0 ?
+                            recentSearches.map(item => {
+                                const newsTag = item.articles[0]
+                                return <TouchableOpacity onPress={() => navigateToArticle(navigation, newsTag.id, newsTag.slug)}>
+                                    <List.Item
+                                        title={newsTag.title}
+                                        titleStyle={{ fontFamily: fonts.type.regular, fontSize: moderateScale(12), color: colors().grayShade_200 }}
+                                        style={{ paddingVertical: 0 }}
+                                        left={() => <IonIcon name="trending-up" color={colors().grayShade_300} size={moderateScale(16)} />}
+
+                                    />
+                                </TouchableOpacity>
+                            }) : <></> : <LoadingScreen containerHeight={verticalScale(240)}/>
+                }
+            </View>
+        </View>
+    )
+}
+
+export default RecentSearchesSection
+

+ 1 - 1
src/components/organisms/Sections/TrendingSection.js

@@ -2,7 +2,7 @@ import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
 import React, { useContext } from 'react';
 import Carousel from 'react-native-reanimated-carousel';
 import MaterialComIcon from 'react-native-vector-icons/MaterialCommunityIcons';
-import { navigateToArticle, navigateToListViewPage, useConstructor } from '../../../constants/functions';
+import { navigateToArticle, navigateToListViewPage, useConstructor } from '../../../utils/functions';
 import fonts from '../../../constants/fonts';
 import colors from '../../../constants/colors';
 import ImageBGCard from '../../molecules/Cards/ImageBGCard';

+ 1 - 1
src/navigation/HomePageNavigator.jsx

@@ -1,7 +1,7 @@
 import React, { useContext } from 'react'
 import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"
 import { createDrawerNavigator } from '@react-navigation/drawer';
-import { getScreenType } from '../constants/functions';
+import { getScreenType } from '../utils/functions';
 import colors from '../constants/colors';
 import SearchNavigator from './SearchNavigator';
 import MainPageNavigator from './MainPageNavigator';

+ 1 - 1
src/screens/Auth/ChooseTopicPage.js

@@ -7,7 +7,7 @@ import { horizontalScale, moderateScale, verticalScale } from '../../constants/m
 import ThemedTextButton from '../../components/molecules/Buttons/ThemeTextButton'
 import { getCategories } from '../../api/data'
 import { Checkbox, List } from 'react-native-paper'
-import { useConstructor } from '../../constants/functions'
+import { useConstructor } from '../../utils/functions'
 import { BASE_URL } from '../../api/urls'
 
 const ChooseTopicPage = props => {

+ 1 - 1
src/screens/Help/ContactPage.js

@@ -5,7 +5,7 @@ import NewscoutTitleHeader from '../../components/molecules/Header/NewscoutTitle
 import { ScrollView } from 'react-native-gesture-handler';
 import ThemedTextButton from '../../components/molecules/Buttons/ThemeTextButton';
 import FormTextInput from '../../components/atoms/Input/FormTextInput';
-import { capitalize } from '../../constants/functions';
+import { capitalize } from '../../utils/functions';
 import colors from '../../constants/colors';
 
 const ContactPage = props => {

+ 1 - 1
src/screens/News/NewsDetailPage.js

@@ -26,7 +26,7 @@ import {
   getTimestamp,
   navigateToArticle,
   useConstructor,
-} from '../../constants/functions';
+} from '../../utils/functions';
 import fonts from '../../constants/fonts';
 import BookmarkButton from '../../components/atoms/Buttons/BookmarkButton';
 import ShareButton from '../../components/atoms/Buttons/ShareButton';

+ 1 - 1
src/screens/News/NewsListPage.js

@@ -1,6 +1,6 @@
 import { FlatList, ScrollView, StyleSheet, Text, TouchableWithoutFeedback, View } from 'react-native'
 import React from 'react'
-import { navigateToArticle, useConstructor } from '../../constants/functions'
+import { navigateToArticle, useConstructor } from '../../utils/functions'
 import { getArticlesByCategory, getArticlesBySearch, getTrendingNews } from '../../api/data'
 import LoadingScreen from '../../components/organisms/Sections/LoadingScreen'
 import colors from '../../constants/colors'

+ 1 - 1
src/screens/Search/SearchListPage.js

@@ -2,7 +2,7 @@ import { FlatList, SafeAreaView, ScrollView, StyleSheet, Text, TouchableOpacity,
 import React, { useState } from 'react'
 import colors from '../../constants/colors'
 import { horizontalScale, moderateScale, verticalScale } from '../../constants/metrics'
-import { useConstructor } from '../../constants/functions'
+import { useConstructor } from '../../utils/functions'
 import IonIcon from 'react-native-vector-icons/Ionicons'
 import { Checkbox, IconButton, List, Modal, PaperProvider, Portal, ToggleButton } from 'react-native-paper'
 import { getArticlesBySearch, getMenus } from '../../api/data'

+ 10 - 227
src/screens/Search/SearchPage.js

@@ -1,18 +1,14 @@
-import { FlatList, ScrollView, StyleSheet, Text, TouchableOpacity, TouchableWithoutFeedback, View } from 'react-native'
-import React, { useEffect, useState } from 'react'
+import { ScrollView, StyleSheet, TouchableOpacity, View } from 'react-native'
+import React, { useState } from 'react'
 import { SafeAreaView } from 'react-native-safe-area-context'
-import NewscoutTitleHeader from '../../components/molecules/Header/NewscoutTitleHeader'
 import colors from '../../constants/colors'
-import { Checkbox, IconButton, List, Modal, PaperProvider, Portal, TextInput, ToggleButton } from 'react-native-paper'
-import { horizontalScale, moderateScale, screenWidth, verticalScale } from '../../constants/metrics'
+import { PaperProvider, TextInput } from 'react-native-paper'
+import { horizontalScale, moderateScale, verticalScale } from '../../constants/metrics'
 import IonIcon from 'react-native-vector-icons/Ionicons'
 import fonts from '../../constants/fonts'
-import { navigateToArticle, navigateToListViewPage, useConstructor } from '../../constants/functions'
-import { getArticlesBySearch, getCategories, getMenus, getTrendingNews } from '../../api/data'
-import LoadingScreen from '../../components/organisms/Sections/LoadingScreen'
-import { PAGINATE_BY } from '../../api/urls'
-import HorizontalNewsCardVariant from '../../components/molecules/Cards/HorizontalNewsCardVariant'
-import ThemedTextButton from '../../components/molecules/Buttons/ThemeTextButton'
+import {navigateToListViewPage} from '../../utils/functions'
+import CategorySearchSection from '../../components/organisms/Sections/CategorySearchSection'
+import RecentSearchesSection from '../../components/organisms/Sections/RecentSearchesSection'
 
 const SearchPage = props => {
 
@@ -21,18 +17,8 @@ const SearchPage = props => {
     route
   } = props
 
-  const [isSearching, setSearching] = useState(false)
-  const [categories, setCategories] = useState([])
   const [searchText, setSearchText] = useState("")
 
-  const [suggestedNews, setSuggestedNews] = useState([])
-
-  const [filtersData, setFiltersData] = useState({})
-  const [currentFilter, setCurrentFilter] = useState("Category")
-
-  const [recentSearches, setRecentSearches] = useState([])
-
-  const [pagesLoaded, setPagesLoaded] = useState(1)
   // * Filters Modal
   const [isFiltersVisible, setFiltersVisible] = useState(false);
   const showFilters = () => setFiltersVisible(true);
@@ -50,104 +36,13 @@ const SearchPage = props => {
       paddingVertical: verticalScale(16),
       flexDirection: 'row',
       alignItems: 'center',
-      // gap: horizontalScale(16),
       maxWidth: '100%'
     },
-    categoryContainer: {
-      padding: verticalScale(16),
-      flexDirection: 'row',
-      flexWrap: 'wrap',
-      gap: moderateScale(16),
-
-
-    },
-    category: {
-      height: 170,
-      width: 170,
-      backgroundColor: colors().secondaryColor,
-      borderRadius: moderateScale(8),
-      padding: moderateScale(11),
-      justifyContent: 'flex-end',
-    },
-    categoryText: {
-      fontFamily: fonts.type.semibold,
-      alignSelf: 'flex-end',
-      color: colors().white,
-      fontSize: moderateScale(14),
-      maxWidth: "80%",
-      textAlign: 'right'
-    },
-    filtersButton: {
-      backgroundColor: colors().dominant,
-      paddingRight: horizontalScale(8),
-      paddingLeft: horizontalScale(16),
-      alignItems: 'center',
-      justifyContent: 'center',
-    },
-    filtersModalContainer: {
-      padding: moderateScale(16),
-      width: '100%',
-      height: '100%',
-      // marginHorizontal: horizontalScale(32),
-      justifyContent: 'flex-start',
-      backgroundColor: colors().dominant,
-    },
-    filtersHeader: {
-      flexDirection: 'row',
-      alignItems: 'center',
-      justifyContent: 'space-between'
-    },
-    filterHeading: {
-      fontFamily: fonts.type.semibold,
-      color: colors().recessive,
-      fontSize: moderateScale(20)
-    },
     utilContainer: {
       flexDirection: 'row',
       gap: 8,
       alignItems: 'center'
     },
-    filterPillContainer: {
-      paddingVertical: verticalScale(8)
-    },
-    filterTitle: {
-      fontFamily: fonts.type.semibold,
-      color: colors().black,
-      fontSize: moderateScale(16),
-      paddingVertical: moderateScale(8)
-    },
-    filterPill: {
-      borderRadius: moderateScale(18),
-      paddingVertical: verticalScale(8),
-      paddingHorizontal: horizontalScale(12),
-      backgroundColor: colors().dominant,
-      width: 'auto',
-    },
-    selectedFilterPill: {
-      paddingVertical: verticalScale(8),
-      paddingHorizontal: horizontalScale(8),
-      // backgroundColor: colors().primaryColor,
-      borderRadius: 0,
-      width: 'auto',
-      borderColor: colors().primaryColor,
-      borderBottomWidth: 3
-    },
-    selectedPillText: {
-      fontFamily: fonts.type.bold,
-      fontSize: moderateScale(14),
-      color: colors().recessive,
-    },
-    pillText: {
-      fontFamily: fonts.type.semibold,
-      fontSize: moderateScale(12),
-      color: colors().recessive,
-    },
-    filterCheckboxes: {
-      alignItems: 'flex-start',
-      flexDirection: 'column',
-      gap: moderateScale(8),
-
-    },
     listItemText: {
       fontFamily: fonts.type.medium,
       fontSize: moderateScale(14),
@@ -158,91 +53,14 @@ const SearchPage = props => {
     }
   })
 
-
-  const fetchCategories = () => {
-    getCategories().then(res => setCategories(res.data.body.results)).catch(err => console.log(err))
-  }
-
-  const fetchSuggestions = (search_text, page = 1, filters = "") => {
-    getArticlesBySearch(search_text, page, filters)
-      .then(res => setSuggestedNews(prev => [...prev, ...res.data.body.results]))
-      .catch(err => console.log(err))
-  }
-
-  const fetchFilters = () => {
-    getMenus()
-      .then(res => {
-        let filtersPayload = res.data.body.results
-        //Reduce Submenus into a object
-        setFiltersData(prev => ({ ...prev, "Category": filtersPayload.flatMap(item => item.heading.submenu.map(category => category.name)).reduce((current, value) => ({ ...current, [value]: false }), {}) }))
-        setFiltersData(prev => ({ ...prev, "Source": filtersPayload.flatMap(item => item.heading.submenu.map(category => category.name)).reduce((current, value) => ({ ...current, [value]: false }), {}) }))
-        setFiltersData(prev => ({ ...prev, "Hash Tags": filtersPayload.flatMap(item => item.heading.submenu.map(category => category.hash_tags.map(tag => tag.name))).reduce((current, value) => ({ ...current, [value]: false }), {}) }))
-
-      })
-  }
-
-  const getRecentSearches = () => {
-    getTrendingNews().then(res => setRecentSearches(res.data.body.results.slice(0, PAGINATE_BY))).catch(err => console.error(err))
-  }
-
-  useConstructor(() => {
-    fetchCategories()
-    fetchFilters()
-    getRecentSearches()
-  })
-
-  const onChangeText = text => {
-    if (text.length <= 0) {
-      setSuggestedNews([])
-      setSearching(false)
-    }
-    setSearchText(text)
-
-  }
-
   const onSearch = () => {
     navigation.push('SearchListPage', { query: searchText })
   }
 
-  const clearAllFilters = () => {
-    setFiltersData(prev => ({ ...prev, "Category": Object.entries(filtersData['Category']).reduce((current, value) => ({ ...current, [value[0]]: false }), {}) }))
-    setFiltersData(prev => ({ ...prev, "Source": Object.entries(filtersData['Source']).reduce((current, value) => ({ ...current, [value[0]]: false }), {}) }))
-    setFiltersData(prev => ({ ...prev, "Hash Tags": Object.entries(filtersData['Hash Tags']).reduce((current, value) => ({ ...current, [value[0]]: false }), {}) }))
-  }
-
-  const applyFilters = () => {
-    setSuggestedNews([])
-    setSearching(true)
-    hideFilters()
-    setPagesLoaded(1)
-    console.log(createFilters(filtersData))
-    fetchSuggestions(searchText, 1, createFilters(filtersData))
-  }
-
-  const createFilters = (filterObject) => {
-    let filterText = ""
-    for (const obj of Object.entries(filterObject)) {
-      for (const category of Object.entries(obj[1])) {
-        if (category[1] === true) {
-          filterText += `&${obj[0].toLowerCase()}=${category[0]}`
-        }
-      }
-    }
-    return filterText
-  }
-
-  // useEffect(() => {
-  //   fetchSuggestions(searchText,pagesLoaded,createFilters(filtersData))
-  // },[pagesLoaded])
-
-
   return (
     <PaperProvider>
       <SafeAreaView style={styles.container}>
-
         <ScrollView>
-          {/* <NewscoutTitleHeader title={"Search"} /> */}
-
           <View style={styles.inputTextContainer}>
             <TextInput
               returnKeyType='search'
@@ -267,48 +85,13 @@ const SearchPage = props => {
                 borderRadius: moderateScale(8),
                 borderWidth: moderateScale(1),
               }}
-              // underlineStyle={{backgroundColor: colors().dominant}}
-              left={() => <Text>fdsfdss</Text>}
+              cursorColor={colors().primaryColor}
               right={() => <TouchableOpacity onPress={() => navigateToListViewPage(navigation, 'search', searchText)}><IonIcon name="search" color={colors().grayShade_200} size={moderateScale(8)} /></TouchableOpacity>}
-              onChangeText={onChangeText}
               onSubmitEditing={onSearch}
             />
           </View>
-
-          <View >
-            <View style={[styles.categoryContainer, { gap: 0 }]}>
-              {
-                recentSearches.map(item => {
-                  const newsTag = item.articles[0]
-                  return <TouchableOpacity onPress={() => navigateToArticle(navigation, newsTag.id, newsTag.slug)}>
-                    <List.Item
-                      title={newsTag.title}
-                      titleStyle={{ fontFamily: fonts.type.regular, fontSize: moderateScale(12), color: colors().grayShade_200 }}
-                      style={{ paddingVertical: 0 }}
-                      left={() => <IonIcon name="trending-up" color={colors().grayShade_300} size={moderateScale(16)} />}
-
-                    />
-                  </TouchableOpacity>
-                }
-
-                )
-
-              }
-            </View>
-            <View style={styles.categoryContainer}>
-              {categories.map((item) =>
-                <TouchableOpacity onPress={() => navigateToListViewPage(navigation, "category", item.heading.name)}>
-                  <View style={styles.category}>
-                    <Text style={styles.categoryText}>{item.heading.name}</Text>
-                  </View>
-                </TouchableOpacity>
-
-              )}
-            </View>
-          </View>
-
-
-
+          <RecentSearchesSection navigation={navigation} route={route} />
+          <CategorySearchSection navigation={navigation} route={route} />
         </ScrollView>
       </SafeAreaView>
     </PaperProvider>

+ 1 - 1
src/screens/Sidebar/SidebarPage.js

@@ -18,7 +18,7 @@ import fonts from '../../constants/fonts';
 import CircularPrimaryBackButton from '../../components/atoms/Buttons/CircularPrimaryBackButton';
 import colors from '../../constants/colors';
 import NewscoutHomeHeader from '../../components/molecules/Header/NewscoutHomeHeader';
-import { navigateToListViewPage, useConstructor } from '../../constants/functions';
+import { navigateToListViewPage, useConstructor } from '../../utils/functions';
 import { getArticlesByCategory, getCategories } from '../../api/data';
 import { BASE_URL } from '../../api/urls';
 import CustomSwitch from '../../components/atoms/Switch/CustomSwitch';

+ 69 - 35
src/constants/functions.js → src/utils/functions.js

@@ -1,10 +1,10 @@
 import { useState } from "react";
-import { screenWidth } from "./metrics";
 import { Share } from "react-native";
 
-
-/*
-    Executes before Render
+/** 
+* Custom Hook to only be executed at Initial Mount. Similar to componentDidMount Lifecycle Method.
+* @param {Function} callBack - Callback Function to be executed
+* @return {null}
 */
 export const useConstructor = (callBack = () => { }) => {
     const [hasBeenCalled, setHasBeenCalled] = useState(false);
@@ -13,6 +13,9 @@ export const useConstructor = (callBack = () => { }) => {
     setHasBeenCalled(true);
 }
 
+/**
+ * Datetime Constants
+ */
 const _MS_PER_SECOND = 1000;
 const _MS_PER_MINUTE = _MS_PER_SECOND * 60;
 const _MS_PER_HOUR = _MS_PER_MINUTE * 60;
@@ -20,8 +23,19 @@ const _MS_PER_DAY = _MS_PER_HOUR * 24;
 const _MS_PER_MONTH = _MS_PER_DAY * 31;
 const _MS_PER_YEAR = _MS_PER_MONTH * 12;
 
+/** 
+* Capitilize String.
+* @param {string} str - Text String
+* @return {string} Capitalized String.
+*/
 export const capitalize = (str) => str.charAt(0).toUpperCase() + str.substring(1, str.length).toLowerCase()
 
+/** 
+* Get Difference betweenn two dates.
+* @param {Date} startDate - Start Date
+* @param {Date} endDate - End Date 
+* @return {object} Returns differences in years,months, days, hours, minutes and seconds .
+*/
 export const getDifferenceInDates = (startDate, endDate) => {
     var diff = Math.floor(startDate.getTime() - endDate.getTime());
     return {
@@ -35,8 +49,13 @@ export const getDifferenceInDates = (startDate, endDate) => {
 
 }
 
-export const getTimestamp = (iso_date_str) => {
-    let diffObj = getDifferenceInDates(new Date(), new Date(iso_date_str))
+/** 
+* get Humanized Timestamp.
+* @param {string} isoTimestamp - ISO String for Timestamp
+* @return {string} Humanized Timestamp
+*/
+export const getTimestamp = (isoTimestamp) => {
+    let diffObj = getDifferenceInDates(new Date(), new Date(isoTimestamp))
     var result = "Timestamp Not Found"
     for (const key of Object.keys(diffObj)) {
         if (diffObj[key] > 0) {
@@ -48,6 +67,11 @@ export const getTimestamp = (iso_date_str) => {
 
 }
 
+/** 
+* Get Month Name.
+* @param {string} index - Month Index Number.
+* @return {string} Month Name
+*/
 const _getMonth = (index) => {
     const months = {
         0: "January",
@@ -70,56 +94,66 @@ const _getMonth = (index) => {
         return "Month Not Found"
     }
 
-}
-
-export const getDate = (iso_date_str) => {
-    let date = new Date(iso_date_str)
+/** 
+* Get Humanized DateTime.
+* @param {string} isoTimestamp - ISO String for Timestamp.
+* @return {string} Humanized Date String
+*/}
+export const getDate = (isoTimestamp) => {
+    let date = new Date(isoTimestamp)
     return `${date.getDate()} ${_getMonth(date.getMonth())} ${date.getFullYear()}`
 }
 
-const MOBILE_SCREEN_BREAKPOINT = 480;
-const TABLET_SCREEN_BREAKPOINT = 768;
-const LARGE_SCREEN_BREAKPOINT = 1180;
-
-
-export const MOBILE_SCREEN = "Mobile"
-export const TABLET_SCREEN = "Tablet"
-export const DESKTOP_SCREEN = "Desktop"
-
-export const getScreenType = () => {
-    let screenType;
-    if (screenWidth <= MOBILE_SCREEN_BREAKPOINT) {
-        screenType = MOBILE_SCREEN
-    } else if (screenWidth <= TABLET_SCREEN_BREAKPOINT) {
-        screenType = TABLET_SCREEN
-    } else {
-        screenType = DESKTOP_SCREEN
-    }
-    return screenType
-}
-
+/** 
+* Checks if Email is valid or not.
+* @param {string} email - Email to be Validated
+* @return {boolean}.
+* For the Email Regex, Refer: {@link https://regex101.com/r/sI6yF5/1} 
+*/
 export const validateEmail = (email) => {
-    const emailRegex = "^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$"
+    const emailRegex = "/^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$/"
     return String(email).match(emailRegex)
 }
 
 
+/** 
+* Navigate to News Detail Page.
+* @param {any} navigation - Navigation Prop
+* @param {String} article_id - Article ID 
+* @param {String} article_slug - Article Slug
+* @return {null}.
+*/
 export const navigateToArticle = (navigation, article_id, article_slug) => {
-    // navigation.navigate("HomePageNav",{screen:"MainNav",params:{screen:'NewsDetailPage',params:{slug: article_slug, id: article_id}}})
-
     navigation.push("NewsDetailPage", { slug: article_slug, id: article_id })
     navigation.navigate("NewsDetailPage",  { slug: article_slug, id: article_id })
 }
 
-
+/** 
+* Navigate to List View Page with Topic Type and Type.
+* @param {any} navigation - Navigation Prop
+* @param {any} topic_type - Topic Type 
+* @param {any} topic - Topic
+* @return {null}.
+*/
 export const navigateToListViewPage = (navigation, topic_type, topic) => {
     navigation.navigate("NewsListPage",  { type: topic_type, title: topic } )
 }
 
+/** 
+* Navigate to Home Page.
+* @param {any} navigation - Navigation Prop
+* @return {null}.
+*/
 export const navigateToHomePage = (navigation) => {
     navigation.navigate("MainPage")
 }
 
+
+/** 
+* Sharing Function to share data across other apps.
+* @param {object} myOptions - Parameters for Sharing Modal.
+* @return {null}.
+*/
 export const onShare = async (myOptions) => {
     try {
       await Share.share(myOptions);