Browse Source

Updated Search Page

Savio Fernando 1 year ago
parent
commit
eae78f914c
3 changed files with 404 additions and 144 deletions
  1. 7 1
      src/navigation/SearchNavigator.jsx
  2. 294 0
      src/screens/Search/SearchListPage.js
  3. 103 143
      src/screens/Search/SearchPage.js

+ 7 - 1
src/navigation/SearchNavigator.jsx

@@ -2,6 +2,7 @@ import { View, Text} from 'react-native';
 import React from 'react';
 import { createNativeStackNavigator } from '@react-navigation/native-stack';
 import SearchPage from '../screens/Search/SearchPage';
+import SearchListPage from '../screens/Search/SearchListPage';
 
 const Stack = createNativeStackNavigator();
 
@@ -15,10 +16,15 @@ const SearchNavigator = () => {
         initialRouteName='SearchPage'
     >
         <Stack.Screen
-            name="LandingPage"
+            name="SearchPage"
             component={SearchPage}
             options={{...defaultScreenOptions}}
         />
+        <Stack.Screen
+            name="SearchListPage"
+            component={SearchListPage}
+            options={{...defaultScreenOptions}}
+        />
     </Stack.Navigator>
   )
 }

+ 294 - 0
src/screens/Search/SearchListPage.js

@@ -0,0 +1,294 @@
+import { FlatList, SafeAreaView, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'
+import React, { useState } from 'react'
+import colors from '../../constants/colors'
+import { horizontalScale, moderateScale, verticalScale } from '../../constants/metrics'
+import { useConstructor } from '../../constants/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'
+import NewscoutCenteredTitleHeader from '../../components/molecules/Header/NewscoutCenteredTitleHeader'
+import LoadingScreen from '../../components/organisms/Sections/LoadingScreen'
+import ThemedTextButton from '../../components/molecules/Buttons/ThemeTextButton'
+import fonts from '../../constants/fonts'
+import HorizontalNewsCardVariant from '../../components/molecules/Cards/HorizontalNewsCardVariant'
+
+const SearchListPage = props => {
+    const {
+        navigation,
+        route
+    } = props
+
+    const params = route.params
+
+    const [filtersData, setFiltersData] = useState({})
+    const [currentFilter, setCurrentFilter] = useState("Category")
+    const [pagesLoaded, setPagesLoaded] = useState(1)
+    const [news, setNews] = useState([])
+
+    const [isFiltersVisible, setFiltersVisible] = useState(false);
+    const showFilters = () => setFiltersVisible(true);
+    const hideFilters = () => setFiltersVisible(false);
+
+    const styles = StyleSheet.create({
+        pageContainer: {
+            backgroundColor: colors().dominant
+        },
+        newsContainer: {
+            backgroundColor: colors().dominant,
+            minHeight: "100%",
+            height: 'auto',
+            paddingHorizontal: horizontalScale(16),
+            flexDirection: 'row',
+            flexWrap: 'wrap',
+            gap: moderateScale(8),
+            paddingVertical: verticalScale(16),
+            numColumns: 2
+
+        },
+        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),
+            color: colors().recessive
+          },
+          listItem: {
+            paddingVertical: verticalScale(0)
+          }
+    })
+
+    const applyFilters = () => {
+        setNews([])
+        hideFilters()
+        setPagesLoaded(1)
+        console.log(createFilters(filtersData))
+        fetchSearchResults(params.query, 1, createFilters(filtersData))
+    }
+
+    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 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 fetchSearchResults = (search_text, page = 1, filters = "") => {
+        getArticlesBySearch(search_text, page, filters)
+            .then(res => setNews(prev => [...prev, ...res.data.body.results]))
+            .catch(err => console.log(err))
+    }
+
+
+    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
+    }
+
+    useConstructor(() => {
+        fetchFilters()
+        fetchSearchResults(params.query, 1, createFilters(filtersData))
+    })
+
+
+    return (
+        <PaperProvider>
+            <SafeAreaView style={styles.pageContainer}>
+                <Portal>
+                    <Modal visible={isFiltersVisible} onDismiss={hideFilters} contentContainerStyle={styles.filtersModalContainer}>
+                        <View style={styles.filtersHeader}>
+                            <Text style={styles.filterHeading}>Filters</Text>
+                            <View style={styles.utilContainer}>
+                                <ThemedTextButton theme={'primary-contained'} title={'Clear All'} buttonStyle={{ paddingVertical: verticalScale(6) }} onPress={clearAllFilters} />
+
+                                <IconButton
+                                    icon="close"
+                                    iconColor={colors().recessive}
+                                    size={moderateScale(24)}
+                                    onPress={hideFilters}
+                                    style={{ alignSelf: 'flex-end' }}
+                                />
+                            </View>
+                        </View>
+                        <View>
+                            <ScrollView horizontal contentContainerStyle={styles.filterPillContainer}>
+                                <ToggleButton.Group
+                                    onValueChange={value => {
+                                        setCurrentFilter(value)
+                                    }}
+                                >
+                                    {
+                                        Object.keys(filtersData).map(item =>
+                                            <ToggleButton
+                                                key={item}
+                                                icon={() => (
+                                                    <Text
+                                                        style={[
+                                                            item === currentFilter
+                                                                ? styles.selectedPillText
+                                                                : styles.pillText,
+                                                        ]}>
+                                                        {item}
+                                                    </Text>
+                                                )}
+                                                style={[
+                                                    item === currentFilter
+                                                        ? styles.selectedFilterPill
+                                                        : styles.filterPill,
+                                                    { marginHorizontal: horizontalScale(4) },
+                                                ]}
+                                                value={item}
+                                            />)
+                                    }
+                                </ToggleButton.Group>
+                            </ScrollView>
+                        </View>
+
+                        {
+                            // filtersData[currentFilter] 
+                            Object.keys(filtersData).length <= 0 ? <LoadingScreen />
+                                :
+                                <FlatList
+                                    contentContainerStyle={styles.filterCheckboxes}
+                                    showsVerticalScrollIndicator={false}
+                                    data={Object.entries(filtersData[currentFilter])}
+                                    renderItem={filter => <List.Item
+                                        key={filter.item[0]}
+                                        style={styles.listItem}
+                                        titleStyle={styles.listItemText}
+                                        title={filter.item[0]}
+                                        left={props => <Checkbox
+                                            status={filtersData[currentFilter][filter.item[0]] === true ? 'checked' : 'unchecked'}
+                                            onPress={() => {
+                                                setFiltersData({ ...filtersData, [currentFilter]: { ...filtersData[currentFilter], [filter.item[0]]: !filtersData[currentFilter][filter.item[0]] } })
+                                                console.log(filtersData[currentFilter][filter.item[0]])
+                                            }}
+
+                                            color={colors().secondaryColor}
+                                        />}
+
+                                    />}
+                                // keyExtractor={item => item.index}
+                                />}
+                        <ThemedTextButton onPress={applyFilters} theme={'secondary-contained'} title={'Apply'} buttonStyle={{ paddingVertical: verticalScale(8), marginTop: verticalScale(8) }} />
+                    </Modal>
+                </Portal>
+                <NewscoutCenteredTitleHeader title={"Search Results"} backButtonShown={true} onBackClick={() => navigation.goBack()}>
+                    <TouchableOpacity style={styles.filtersButton} onPress={showFilters}>
+                        <IonIcon name="filter" color={colors().recessive_variant} size={moderateScale(24)} />
+                    </TouchableOpacity>
+                </NewscoutCenteredTitleHeader>
+                {
+                    news.length <= 0 ?
+                        <LoadingScreen />
+                        :
+
+                        <FlatList
+                            contentContainerStyle={styles.newsContainer}
+                            showsVerticalScrollIndicator={false}
+                            data={news}
+                            renderItem={(news) =>
+                                <HorizontalNewsCardVariant
+                                  onPress={() => navigateToArticle(navigation, news.item.id, news.item.slug)}
+                                  timestamp={news.item.published_on}
+                                  headline={news.item.title}
+                                  image={{ uri: news.item.cover_image }}
+                                  category={news.item.category}
+                                  tagline={news.item.id}
+                                />}
+                            keyExtractor={item => item.index}
+                            onEndReached={() => {
+                                setPagesLoaded(pagesLoaded + 1)
+                                fetchSearchResults(params.query,pagesLoaded + 1,createFilters(filtersData))
+                            }}
+                            onEndReachedThreshold={200}
+                        />
+                }
+            </SafeAreaView>
+        </PaperProvider>
+
+    )
+}
+
+export default SearchListPage
+
+const styles = StyleSheet.create({})

+ 103 - 143
src/screens/Search/SearchPage.js

@@ -1,5 +1,5 @@
 import { FlatList, ScrollView, StyleSheet, Text, TouchableOpacity, TouchableWithoutFeedback, View } from 'react-native'
-import React, { useState } from 'react'
+import React, { useEffect, useState } from 'react'
 import { SafeAreaView } from 'react-native-safe-area-context'
 import NewscoutTitleHeader from '../../components/molecules/Header/NewscoutTitleHeader'
 import colors from '../../constants/colors'
@@ -8,7 +8,7 @@ import { horizontalScale, moderateScale, screenWidth, verticalScale } from '../.
 import IonIcon from 'react-native-vector-icons/Ionicons'
 import fonts from '../../constants/fonts'
 import { navigateToArticle, navigateToListViewPage, useConstructor } from '../../constants/functions'
-import { getArticlesBySearch, getCategories, getMenus } from '../../api/data'
+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'
@@ -24,21 +24,20 @@ const SearchPage = 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);
   const hideFilters = () => setFiltersVisible(false);
 
-
-
-
-
-
-
   const styles = StyleSheet.create({
     container: {
       backgroundColor: colors().dominant,
@@ -48,7 +47,7 @@ const SearchPage = props => {
     inputTextContainer: {
       backgroundColor: colors().dominant,
       paddingHorizontal: horizontalScale(16),
-      paddingBottom: verticalScale(16),
+      paddingVertical: verticalScale(16),
       flexDirection: 'row',
       alignItems: 'center',
       // gap: horizontalScale(16),
@@ -126,15 +125,17 @@ const SearchPage = props => {
     },
     selectedFilterPill: {
       paddingVertical: verticalScale(8),
-      paddingHorizontal: horizontalScale(16),
-      backgroundColor: colors().primaryColor,
-      borderRadius: moderateScale(18),
+      paddingHorizontal: horizontalScale(8),
+      // backgroundColor: colors().primaryColor,
+      borderRadius: 0,
       width: 'auto',
+      borderColor: colors().primaryColor,
+      borderBottomWidth: 3
     },
     selectedPillText: {
-      fontFamily: fonts.type.semibold,
-      fontSize: moderateScale(12),
-      color: colors().white,
+      fontFamily: fonts.type.bold,
+      fontSize: moderateScale(14),
+      color: colors().recessive,
     },
     pillText: {
       fontFamily: fonts.type.semibold,
@@ -142,7 +143,10 @@ const SearchPage = props => {
       color: colors().recessive,
     },
     filterCheckboxes: {
-      alignItems: 'flex-start'
+      alignItems: 'flex-start',
+      flexDirection: 'column',
+      gap: moderateScale(8),
+
     },
     listItemText: {
       fontFamily: fonts.type.medium,
@@ -159,9 +163,9 @@ const SearchPage = props => {
     getCategories().then(res => setCategories(res.data.body.results)).catch(err => console.log(err))
   }
 
-  const fetchSuggestions = (search_text) => {
-    getArticlesBySearch(search_text)
-      .then(res => setSuggestedNews(res.data.body.results.slice(0, PAGINATE_BY)))
+  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))
   }
 
@@ -177,120 +181,71 @@ const SearchPage = props => {
       })
   }
 
+  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) {
-      console.warn(text)
-      setSearching(true)
-      setSearchText(text)
+  const onChangeText = text => {
+    if (text.length <= 0) {
       setSuggestedNews([])
-      fetchSuggestions(text)
-
-    } else {
-      console.warn(text)
       setSearching(false)
-      setSearchText(text)
-      setSuggestedNews([])
     }
+    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}>
-        <Portal>
-          <Modal visible={isFiltersVisible} onDismiss={hideFilters} contentContainerStyle={styles.filtersModalContainer}>
-            <View style={styles.filtersHeader}>
-              <Text style={styles.filterHeading}>Filters</Text>
-              <View style={styles.utilContainer}>
-                <ThemedTextButton theme={'primary-contained'} title={'Clear All'} buttonStyle={{ paddingVertical: verticalScale(6) }} />
-                
-                <IconButton
-                  icon="close"
-                  iconColor={colors().recessive}
-                  size={moderateScale(24)}
-                  onPress={hideFilters}
-                  style={{ alignSelf: 'flex-end' }}
-                />
-              </View>
-            </View>
-            <View>
-              <ScrollView horizontal contentContainerStyle={styles.filterPillContainer}>
-                <ToggleButton.Group
-                  onValueChange={value => {
-                    setCurrentFilter(value)
-                  }}
-                >
-                  {
-                    Object.keys(filtersData).map(item =>
-                      <ToggleButton
-                        key={item}
-                        icon={() => (
-                          <Text
-                            style={[
-                              item === currentFilter
-                                ? styles.selectedPillText
-                                : styles.pillText,
-                            ]}>
-                            {item}
-                          </Text>
-                        )}
-                        style={[
-                          item === currentFilter
-                            ? styles.selectedFilterPill
-                            : styles.filterPill,
-                          { marginHorizontal: horizontalScale(4) },
-                        ]}
-                        value={item}
-                      />)
-                  }
-                </ToggleButton.Group>
-              </ScrollView>
-            </View>
 
-            {
-              // filtersData[currentFilter] 
-              Object.keys(filtersData).length <= 0 ? <LoadingScreen />
-                :
-                <FlatList
-                  contentContainerStyle={styles.filterCheckboxes}
-                  showsVerticalScrollIndicator={false}
-                  data={Object.entries(filtersData[currentFilter])}
-                  renderItem={filter => <List.Item
-                    key={filter.item[0]}
-                    style={styles.listItem}
-                    titleStyle={styles.listItemText}
-                    title={filter.item[0]}
-                    left={props => <Checkbox
-                      status={filtersData[currentFilter][filter.item[0]] === true ? 'checked' : 'unchecked'}
-                      onPress={() =>{
-                        setFiltersData({ ...filtersData, [currentFilter]: { ...filtersData[currentFilter], [filter.item[0]]: !filtersData[currentFilter][filter.item[0]] } })
-                        console.log(filtersData[currentFilter][filter.item[0]])
-                      }}
-                      
-                      color={colors().secondaryColor}
-                    />}
-
-                  />}
-                // keyExtractor={item => item.index}
-                />}
-          <ThemedTextButton theme={'secondary-contained'} title={'Apply'} buttonStyle={{ paddingVertical: verticalScale(6),marginTop: verticalScale(8) }} />
-
-
-
-
-
-          </Modal>
-        </Portal>
         <ScrollView>
-          <NewscoutTitleHeader title={"Search"} />
+          {/* <NewscoutTitleHeader title={"Search"} /> */}
 
           <View style={styles.inputTextContainer}>
             <TextInput
+              returnKeyType='search'
               editable
               mode='outlined'
               placeholder='Search Text'
@@ -299,8 +254,6 @@ const SearchPage = props => {
               style={{
                 backgroundColor: colors().grayShade_500,
                 paddingVertical: moderateScale(4),
-                // width: '100%',
-
                 flex: 1
 
               }}
@@ -318,37 +271,44 @@ const SearchPage = props => {
               left={() => <Text>fdsfdss</Text>}
               right={() => <TouchableOpacity onPress={() => navigateToListViewPage(navigation, 'search', searchText)}><IonIcon name="search" color={colors().grayShade_200} size={moderateScale(8)} /></TouchableOpacity>}
               onChangeText={onChangeText}
+              onSubmitEditing={onSearch}
             />
-            <TouchableOpacity style={styles.filtersButton} onPress={showFilters}>
-              <IonIcon name="filter" color={colors().recessive_variant} size={moderateScale(24)} />
-            </TouchableOpacity>
           </View>
-          {
-            isSearching === false ?
-              <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>
-              : suggestedNews.length <= 0 ?
-                <View style={{ alignItems: 'center', justifyContent: 'center', }}><LoadingScreen containerHeight={600} /></View> : <View style={styles.categoryContainer}>
-                  {suggestedNews.map((item) =>
-                    <HorizontalNewsCardVariant
-                      onPress={() => navigateToArticle(navigation, item.id, item.slug)}
-                      timestamp={item.published_on}
-                      headline={item.title}
-                      image={{ uri: item.cover_image }}
-                      category={item.category}
-                      tagline={item.id}
+          <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)} />}
+
                     />
-                  )}
-                </View>
-          }
+                  </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>
+
+
+
         </ScrollView>
       </SafeAreaView>
     </PaperProvider>