浏览代码

Filter Section Setup

Savio Fernando 1 年之前
父节点
当前提交
39ac106842
共有 1 个文件被更改,包括 226 次插入76 次删除
  1. 226 76
      src/screens/Search/SearchPage.js

+ 226 - 76
src/screens/Search/SearchPage.js

@@ -3,28 +3,40 @@ 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 { PaperProvider, TextInput } from 'react-native-paper'
+import { Checkbox, IconButton, List, Modal, PaperProvider, Portal, TextInput, ToggleButton } from 'react-native-paper'
 import { horizontalScale, moderateScale, screenWidth, 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 } from '../../api/data'
+import { getArticlesBySearch, getCategories, getMenus } 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 { FlatList } from 'react-native-gesture-handler'
 
 const SearchPage = props => {
 
+  const {
+    navigation,
+    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")
+
+  // * Filters Modal
+  const [isFiltersVisible, setFiltersVisible] = useState(false);
+  const showFilters = () => setFiltersVisible(true);
+  const hideFilters = () => setFiltersVisible(false);
+
+
+
 
-  const {
-    navigation,
-    route
-  } = props
 
 
 
@@ -38,10 +50,10 @@ const SearchPage = props => {
       backgroundColor: colors().dominant,
       paddingHorizontal: horizontalScale(16),
       paddingBottom: verticalScale(16),
-      flexDirection:'row',
+      flexDirection: 'row',
       alignItems: 'center',
       // gap: horizontalScale(16),
-      maxWidth:'100%'
+      maxWidth: '100%'
     },
     categoryContainer: {
       padding: verticalScale(16),
@@ -67,13 +79,69 @@ const SearchPage = props => {
       maxWidth: "80%",
       textAlign: 'right'
     },
-    filtersButton:{
+    filtersButton: {
       backgroundColor: colors().dominant,
       paddingRight: horizontalScale(8),
       paddingLeft: horizontalScale(16),
-      alignItems:'center',
-      justifyContent:'center',
-    }
+      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(16),
+      backgroundColor: colors().primaryColor,
+      borderRadius: moderateScale(18),
+      width: 'auto',
+    },
+    selectedPillText: {
+      fontFamily: fonts.type.semibold,
+      fontSize: moderateScale(12),
+      color: colors().white,
+    },
+    pillText: {
+      fontFamily: fonts.type.semibold,
+      fontSize: moderateScale(12),
+      color: colors().recessive,
+    },
   })
 
 
@@ -87,8 +155,19 @@ const SearchPage = props => {
       .catch(err => console.log(err))
   }
 
+  const fetchFilters = () => {
+    getMenus()
+      .then(res => {
+        let filtersPayload = res.data.body.results
+        setFiltersData(prev => ({ ...prev, "Category": filtersPayload.map(item => item.heading.submenu.reduce((current, value) => ({ ...current, [value]: false }), {})) }))
+        setFiltersData(prev => ({ ...prev, "Source": filtersPayload.map(item => item.heading.submenu.reduce((current, value) => ({ ...current, [value]: false }), {})) }))
+        setFiltersData(prev => ({ ...prev, "Hash Tags": filtersPayload.map(item => item.heading.submenu.reduce((current, value) => ({ ...current, [value]: false }), {})) }))
+      })
+  }
+
   useConstructor(() => {
     fetchCategories()
+    fetchFilters()
   })
 
   const onChangeText = (text) => {
@@ -109,72 +188,143 @@ const SearchPage = props => {
   }
   return (
     <PaperProvider>
-    <SafeAreaView style={styles.container}>
-      <ScrollView>
-        <NewscoutTitleHeader title={"Search"} />
-
-        <View style={styles.inputTextContainer}>
-          <TextInput
-            editable
-            mode='outlined'
-            placeholder='Search Text'
-            placeholderTextColor={colors().grayShade_300}
-            dense
-            style={{
-              backgroundColor: colors().grayShade_500,
-              paddingVertical: moderateScale(4),
-              // width: '100%',
-              
-              flex: 1
-             
-            }}
-            contentStyle={{
-              fontSize: moderateScale(16),
-              fontFamily: fonts.type.medium,
-              // height: moderateScale(16),
-            }}
-            outlineStyle={{
-              borderColor: colors().dominant_variant,
-              borderRadius: moderateScale(8),
-              borderWidth: moderateScale(1),
-            }}
-            // underlineStyle={{backgroundColor: colors().dominant}}
-            left={() => <Text>fdsfdss</Text>}
-            right={() => <TouchableOpacity onPress={() => navigateToListViewPage(navigation,'search',searchText)}><IonIcon name="search" color={colors().grayShade_200} size={moderateScale(8)} /></TouchableOpacity>}
-            onChangeText={onChangeText}
-          />
-          <TouchableOpacity style={styles.filtersButton} onPress={true}>
-            <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>
-
-              )}
+      <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>
-            : 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}
-                  />
+            <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>
+            <ScrollView showsVerticalScrollIndicator={false}>
+              {
+                // filtersData[currentFilter] 
+                Object.keys(filtersData).length <= 0 ? <LoadingScreen/> 
+                : Object.keys(filtersData[currentFilter]).map(item => 
+                  { console.log(item)
+                    return (<List.Item
+                  style={styles.listItem}
+                  titleStyle={styles.listItemText}
+                  title={item}
+
+                  right={props => <Checkbox  
+                      status={filtersData[currentFilter][item] === true ? 'checked' : 'unchecked'}
+                      onPress={() => 
+                        setFiltersData({...filtersData,[currentFilter]: {...filtersData[currentFilter],[item]: !filtersData[currentFilter][item]}})}
+                        // setSelectedTopics({...filtersData,[item.heading.name]: !selectedTopics[item.heading.name]})}
+                      color={colors().secondaryColor}
+                  />}
+              
+              />)}
+                )
+              }
+            </ScrollView>
+          </Modal>
+        </Portal>
+        <ScrollView>
+          <NewscoutTitleHeader title={"Search"} />
+
+          <View style={styles.inputTextContainer}>
+            <TextInput
+              editable
+              mode='outlined'
+              placeholder='Search Text'
+              placeholderTextColor={colors().grayShade_300}
+              dense
+              style={{
+                backgroundColor: colors().grayShade_500,
+                paddingVertical: moderateScale(4),
+                // width: '100%',
+
+                flex: 1
+
+              }}
+              contentStyle={{
+                fontSize: moderateScale(16),
+                fontFamily: fonts.type.medium,
+                // height: moderateScale(16),
+              }}
+              outlineStyle={{
+                borderColor: colors().dominant_variant,
+                borderRadius: moderateScale(8),
+                borderWidth: moderateScale(1),
+              }}
+              // underlineStyle={{backgroundColor: colors().dominant}}
+              left={() => <Text>fdsfdss</Text>}
+              right={() => <TouchableOpacity onPress={() => navigateToListViewPage(navigation, 'search', searchText)}><IonIcon name="search" color={colors().grayShade_200} size={moderateScale(8)} /></TouchableOpacity>}
+              onChangeText={onChangeText}
+            />
+            <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>
-        }
-      </ScrollView>
-    </SafeAreaView>
+              : 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>
+          }
+        </ScrollView>
+      </SafeAreaView>
     </PaperProvider>
   )
 }