|
@@ -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>
|