From 28476c7789e74f314ebbda6c392b5137ad8211b1 Mon Sep 17 00:00:00 2001 From: angelindepthios Date: Sun, 21 Nov 2021 19:29:05 +0700 Subject: [PATCH 1/5] feat: integrate search --- src/components/Forms/IconForm.tsx | 3 + .../ecosystem/BusinessEcosystemScreen.tsx | 1 + src/screens/ecosystem/EcosystemSearch.tsx | 156 ++++++++++-------- src/service/typesense/searchEcosystem.ts | 7 +- src/service/typesense/searchUser.ts | 7 +- 5 files changed, 101 insertions(+), 73 deletions(-) diff --git a/src/components/Forms/IconForm.tsx b/src/components/Forms/IconForm.tsx index cd247a2..f71d694 100644 --- a/src/components/Forms/IconForm.tsx +++ b/src/components/Forms/IconForm.tsx @@ -17,6 +17,7 @@ type props = { search?: boolean; errorMessage?: string; onPress?: () => void; + onEndEditing?: () => void; }; const IconForm = ({ @@ -30,6 +31,7 @@ const IconForm = ({ search = false, errorMessage, onPress, + onEndEditing, }: props) => { const [isFocused, setIsFocused] = useState(false); const [showPass, setShowPass] = useState(password); @@ -65,6 +67,7 @@ const IconForm = ({ setIsError(false); } } + onEndEditing(); }; let iconName: React.ComponentProps["name"]; diff --git a/src/screens/ecosystem/BusinessEcosystemScreen.tsx b/src/screens/ecosystem/BusinessEcosystemScreen.tsx index c9af76d..c47c6ba 100644 --- a/src/screens/ecosystem/BusinessEcosystemScreen.tsx +++ b/src/screens/ecosystem/BusinessEcosystemScreen.tsx @@ -16,6 +16,7 @@ import { getByCreated } from "../../service/firestore/ecosystem/getByCreated"; import { IEcosystem } from "../../types/firestore/ecosystems"; import { getCategories } from "../../service/firestore/categories"; import { ICategory } from "../../types/firestore"; +import { MaterialIcons } from "@expo/vector-icons"; const wait = (timeout) => { return new Promise((resolve) => setTimeout(resolve, timeout)); diff --git a/src/screens/ecosystem/EcosystemSearch.tsx b/src/screens/ecosystem/EcosystemSearch.tsx index b06cbe5..5067282 100644 --- a/src/screens/ecosystem/EcosystemSearch.tsx +++ b/src/screens/ecosystem/EcosystemSearch.tsx @@ -1,5 +1,5 @@ import { - ActivityIndicator, + // ActivityIndicator FlatList, ListRenderItem, StyleSheet, @@ -11,82 +11,104 @@ import IconForm from "../../components/Forms/IconForm"; import { EcosystemStackScreenProps } from "../../types/navigation"; import DropdownForm from "../../components/Forms/DropdownForm"; import { IDD } from "../../types/firestore"; -import { getCategoriesAsDdFormat } from "../../helpers/ddConverter"; import SmallButton from "../../components/button/SmallButton"; -import { getByCategory } from "../../service/firestore/ecosystem/getByCategory"; +// import { getByCategory } from "../../service/firestore/ecosystem/getByCategory"; import { IEcosystem } from "../../types/firestore/ecosystems"; import Spacer from "../../components/Spacer/Spacer"; import HorizontalCards from "../../components/Cards/HorizontalCards"; import { useNavigation } from "@react-navigation/core"; +import { useCategory } from "../../hooks/reduxHooks"; +import { getCategoriesAsDdFormat } from "../../helpers/ddConverter"; +import { searchEcosystem } from "../../service/typesense/searchEcosystem"; +import { getEnv } from "../../helpers/getEnv"; +import { SearchResponseHit } from "typesense/lib/Typesense/Documents"; const EcosystemSearch = ({ route }: EcosystemStackScreenProps<"Search">) => { const [search, setSearch] = useState(""); const [picked, setPicked] = useState(""); const [categories, setCategories] = useState([]); const { headerTitle } = route.params; - const [ecosystems, setEcosystems] = useState([]); - const [lastVisibleId, setLastVisibleId] = useState(""); - const [loadingMore, setLoadingmore] = useState(false); + const [ecosystems, setEcosystems] = useState[]>( + [] + ); + // const [lastVisibleId, setLastVisibleId] = useState(""); + // const [loadingMore, setLoadingmore] = useState(false); const nav = useNavigation(); + const categoriesHook = useCategory(); + useEffect(() => { - getCategoriesAsDdFormat().then((res) => setCategories(res)); + setCategories(() => getCategoriesAsDdFormat(categoriesHook)); }, []); - const filterByCategory = async () => { - if (ecosystems.length > 0) { - console.log("test"); - ecosystems.length = 0; - } - const result = await getByCategory(picked, lastVisibleId); - setEcosystems([...ecosystems, ...result]); - }; - const handleOnEndReach = () => { - // setLoadingmore(true); - const lastIndexItem = ecosystems[ecosystems.length - 1]; - const lastIndexItemId = lastIndexItem.id; - setLastVisibleId(lastIndexItemId); - if (ecosystems.length - 1 === 0) { - setLoadingmore(false); - } else { - setLoadingmore(true); - } - // setLoadingmore(true); + // const filterByCategory = async () => { + // if (ecosystems.length > 0) { + // ecosystems.length = 0; + // } + // const result = await getByCategory(picked); + // setEcosystems(result); + // }; + // const handleOnEndReach = () => { + // // setLoadingmore(true); + // const lastIndexItem = ecosystems[ecosystems.length - 1]; + // const lastIndexItemId = lastIndexItem.id; + // setLastVisibleId(lastIndexItemId); + // if (ecosystems.length - 1 === 0) { + // setLoadingmore(false); + // } else { + // setLoadingmore(true); + // } + // // setLoadingmore(true); + // }; + + const onSearch = async () => { + const res = await searchEcosystem({ + env: getEnv(), + searchParams: { q: search, query_by: "name" }, + }); + console.log(res.searchHits[0]); + setEcosystems(res.searchHits); }; - const renderItem: ListRenderItem = ({ item }) => ( - - - { - nav.navigate("Ecosystem", { - screen: "EcosystemDetails", - params: { - headerTitle: item.name, - id: item.id, - title: item.name, - desc: item.description, - image: item.pic, - member: item.followerCount.toString(), - rating: item.rating.toString(), - }, - }); + + const renderItem: ListRenderItem> = ({ + item: _item, + }) => { + const item = _item.document; + return ( + + + > + { + nav.navigate("Ecosystem", { + screen: "EcosystemDetails", + params: { + headerTitle: item.name, + id: item.id, + title: item.name, + desc: item.description, + image: item.pic, + member: item.followerCount.toString(), + rating: item.rating.toString(), + }, + }); + }} + rate={item.rating.toString()} + /> + - - ); - const ListFooterComponent = () => ( - - - - ); + ); + }; + // const ListFooterComponent = () => ( + // + // + // + // ); return ( ) => { setText={setSearch} placeholder={"Cari dengan kata kunci ini.."} search + onPress={onSearch} + onEndEditing={onSearch} /> )} {headerTitle === "Filter" && ( @@ -129,7 +153,7 @@ const EcosystemSearch = ({ route }: EcosystemStackScreenProps<"Search">) => { text="Filter" colors="primary" onPress={() => { - filterByCategory(); + // filterByCategory(); }} /> @@ -142,15 +166,9 @@ const EcosystemSearch = ({ route }: EcosystemStackScreenProps<"Search">) => { renderItem={renderItem} ItemSeparatorComponent={() => } ListHeaderComponent={() => } - ListFooterComponent={() => - !loadingMore ? ( - - ) : ( - - ) - } + ListFooterComponent={() => } onEndReachedThreshold={0.5} - onEndReached={handleOnEndReach} + // onEndReached={handleOnEndReach} /> )} diff --git a/src/service/typesense/searchEcosystem.ts b/src/service/typesense/searchEcosystem.ts index aae3b56..a033ffc 100644 --- a/src/service/typesense/searchEcosystem.ts +++ b/src/service/typesense/searchEcosystem.ts @@ -1,7 +1,10 @@ import axios, { AxiosResponse } from "axios"; import { CLOUD_FUNCTIONS_URL } from "../../constants/urls"; import { IEcosystem } from "../../types/firestore/ecosystems"; -import { SearchParams } from "typesense/lib/Typesense/Documents"; +import { + SearchParams, + SearchResponseHit, +} from "typesense/lib/Typesense/Documents"; export type searchEcosystemParams = { env: string; @@ -21,5 +24,5 @@ export const searchEcosystem = async (params: searchEcosystemParams) => { }; type searchResponse = { - searchHits: IEcosystem[]; + searchHits: SearchResponseHit[]; }; diff --git a/src/service/typesense/searchUser.ts b/src/service/typesense/searchUser.ts index 3a61bd2..baf25d9 100644 --- a/src/service/typesense/searchUser.ts +++ b/src/service/typesense/searchUser.ts @@ -1,7 +1,10 @@ import axios, { AxiosResponse } from "axios"; import { CLOUD_FUNCTIONS_URL } from "../../constants/urls"; import { IUser } from "../../types/firestore/User"; -import { SearchParams } from "typesense/lib/Typesense/Documents"; +import { + SearchParams, + SearchResponseHit, +} from "typesense/lib/Typesense/Documents"; export const searchUser = async ( searchParams: SearchParams> @@ -26,5 +29,5 @@ export const searchUser = async ( }; type searchResponse = { - searchHits: IUser[]; + searchHits: SearchResponseHit[]; }; -- GitLab From ae3dbe538739de626d07f4b33d5336809104d6b1 Mon Sep 17 00:00:00 2001 From: angelindepthios Date: Sun, 21 Nov 2021 21:00:05 +0700 Subject: [PATCH 2/5] feat:category screen list --- .../ecosystem/CategoryEcosystemListScreen.tsx | 120 +++++++++++------- 1 file changed, 71 insertions(+), 49 deletions(-) diff --git a/src/screens/ecosystem/CategoryEcosystemListScreen.tsx b/src/screens/ecosystem/CategoryEcosystemListScreen.tsx index f3f9da2..3a4abc4 100644 --- a/src/screens/ecosystem/CategoryEcosystemListScreen.tsx +++ b/src/screens/ecosystem/CategoryEcosystemListScreen.tsx @@ -1,14 +1,24 @@ -import { FlatList, StyleSheet, ActivityIndicator } from "react-native"; -import React, { useEffect, useState } from "react"; +import { + // ActivityIndicator, + FlatList, + StyleSheet, +} from "react-native"; +import React, { + // useEffect, + useState, +} from "react"; import HorizontalCards from "../../components/Cards/HorizontalCards"; import { useNavigation } from "@react-navigation/core"; import Colors from "../../constants/Colors"; import { View } from "../../components/Themed"; import Spacer from "../../components/Spacer/Spacer"; import IconForm from "../../components/Forms/IconForm"; -import { getByCategory } from "../../service/firestore/ecosystem/getByCategory"; +// import { getByCategory } from "../../service/firestore/ecosystem/getByCategory"; import { IEcosystem } from "../../types/firestore/ecosystems"; import { EcosystemStackScreenProps } from "../../types/navigation"; +import { searchEcosystem } from "../../service/typesense/searchEcosystem"; +import { getEnv } from "../../helpers/getEnv"; +import { SearchResponseHit } from "typesense/lib/Typesense/Documents"; const CategoryEcosystemListScreen = ({ route, @@ -16,40 +26,50 @@ const CategoryEcosystemListScreen = ({ const nav = useNavigation(); const { toFetch } = route.params; const [search, setSearch] = useState(""); - const [listData, setListData] = useState([]); - const [loadingMore, setLoadingmore] = useState(false); - const [lastVisibleId, setLastVisibleId] = useState(""); + const [listData, setListData] = useState[]>([]); + // const [loadingMore, setLoadingmore] = useState(false); + // const [lastVisibleId, setLastVisibleId] = useState(""); - useEffect(() => { - getByCategory(toFetch, lastVisibleId).then((res) => { - setListData(res); - const lastIndexItem = res[res.length - 1]; - const lastIndexItemId = lastIndexItem.id; - setLastVisibleId(lastIndexItemId); - }); - }, []); + // useEffect(() => { + // getByCategory(toFetch, lastVisibleId).then((res) => { + // setListData(res.); + // const lastIndexItem = res[res.length - 1]; + // const lastIndexItemId = lastIndexItem.id; + // setLastVisibleId(lastIndexItemId); + // }); + // }, []); - const handleOnEndReach = () => { - // setLoadingmore(true); - getByCategory(toFetch, lastVisibleId).then((res) => { - setListData([...listData, ...res]); - const lastIndexItem = res[res.length - 1]; - const lastIndexItemId = lastIndexItem.id; - setLastVisibleId(lastIndexItemId); - if (res.length === 0) { - setLoadingmore(false); - } else { - setLoadingmore(true); - } - // setLoadingmore(false); + // const handleOnEndReach = () => { + // // setLoadingmore(true); + // getByCategory(toFetch, lastVisibleId).then((res) => { + // setListData([...listData, ...res]); + // const lastIndexItem = res[res.length - 1]; + // const lastIndexItemId = lastIndexItem.id; + // setLastVisibleId(lastIndexItemId); + // if (res.length === 0) { + // setLoadingmore(false); + // } else { + // setLoadingmore(true); + // } + // // setLoadingmore(false); + // }); + // }; + const onSearch = async () => { + const res = await searchEcosystem({ + env: getEnv(), + searchParams: { + q: search, + query_by: "name", + filter_by: "categoryId:" + toFetch, + }, }); + setListData(res.searchHits); }; - - const ListFooterComponent = () => ( - - - - ); + // const ListFooterComponent = () => ( + // + // + // + // ); return ( @@ -59,21 +79,21 @@ const CategoryEcosystemListScreen = ({ return ( nav.navigate("Ecosystem", { screen: "EcosystemDetails", params: { - headerTitle: item.name, - id: item.id, - title: item.name, - desc: item.description, - image: item.pic, - member: item.followerCount.toString(), - rating: item.rating.toString(), + headerTitle: item.document.name, + id: item.document.id, + title: item.document.name, + desc: item.document.description, + image: item.document.pic, + member: item.document.followerCount.toString(), + rating: item.document.rating.toString(), }, }) } @@ -81,13 +101,13 @@ const CategoryEcosystemListScreen = ({ ); }} - keyExtractor={(item) => item.id} + keyExtractor={(item) => item.document.id} ItemSeparatorComponent={() => } showsVerticalScrollIndicator={false} showsHorizontalScrollIndicator={false} - ListFooterComponent={() => - !loadingMore ? : - } + // ListFooterComponent={() => + // !loadingMore ? : + // } ListHeaderComponent={() => ( <> @@ -97,13 +117,15 @@ const CategoryEcosystemListScreen = ({ setText={setSearch} placeholder={"Cari di kategori ini"} search + onPress={onSearch} + onEndEditing={onSearch} /> )} onEndReachedThreshold={0.5} - onEndReached={handleOnEndReach} + // onEndReached={handleOnEndReach} /> ); -- GitLab From c514ea50969d6c231249f6b8bcf703d751fd7caf Mon Sep 17 00:00:00 2001 From: angelindepthios Date: Sun, 21 Nov 2021 21:20:07 +0700 Subject: [PATCH 3/5] Add search for categoryecosystem --- .../ecosystem/CategoryEcosystemListScreen.tsx | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/src/screens/ecosystem/CategoryEcosystemListScreen.tsx b/src/screens/ecosystem/CategoryEcosystemListScreen.tsx index 3a4abc4..f0ecac7 100644 --- a/src/screens/ecosystem/CategoryEcosystemListScreen.tsx +++ b/src/screens/ecosystem/CategoryEcosystemListScreen.tsx @@ -3,17 +3,14 @@ import { FlatList, StyleSheet, } from "react-native"; -import React, { - // useEffect, - useState, -} from "react"; +import React, { useEffect, useState } from "react"; import HorizontalCards from "../../components/Cards/HorizontalCards"; import { useNavigation } from "@react-navigation/core"; import Colors from "../../constants/Colors"; import { View } from "../../components/Themed"; import Spacer from "../../components/Spacer/Spacer"; import IconForm from "../../components/Forms/IconForm"; -// import { getByCategory } from "../../service/firestore/ecosystem/getByCategory"; +import { getByCategory } from "../../service/firestore/ecosystem/getByCategory"; import { IEcosystem } from "../../types/firestore/ecosystems"; import { EcosystemStackScreenProps } from "../../types/navigation"; import { searchEcosystem } from "../../service/typesense/searchEcosystem"; @@ -26,18 +23,20 @@ const CategoryEcosystemListScreen = ({ const nav = useNavigation(); const { toFetch } = route.params; const [search, setSearch] = useState(""); - const [listData, setListData] = useState[]>([]); + const [listData, setListData] = useState< + SearchResponseHit[] | IEcosystem[] + >([]); // const [loadingMore, setLoadingmore] = useState(false); // const [lastVisibleId, setLastVisibleId] = useState(""); - // useEffect(() => { - // getByCategory(toFetch, lastVisibleId).then((res) => { - // setListData(res.); - // const lastIndexItem = res[res.length - 1]; - // const lastIndexItemId = lastIndexItem.id; - // setLastVisibleId(lastIndexItemId); - // }); - // }, []); + useEffect(() => { + getByCategory(toFetch).then((res) => { + setListData(res); + // const lastIndexItem = res[res.length - 1]; + // const lastIndexItemId = lastIndexItem.id; + // setLastVisibleId(lastIndexItemId); + }); + }, []); // const handleOnEndReach = () => { // // setLoadingmore(true); @@ -73,27 +72,42 @@ const CategoryEcosystemListScreen = ({ return ( + <> + + + + + + { + renderItem={({ item: _item }) => { + const item: IEcosystem = _item.document ? _item.document : _item; return ( nav.navigate("Ecosystem", { screen: "EcosystemDetails", params: { - headerTitle: item.document.name, - id: item.document.id, - title: item.document.name, - desc: item.document.description, - image: item.document.pic, - member: item.document.followerCount.toString(), - rating: item.document.rating.toString(), + headerTitle: item.name, + id: item.id, + title: item.name, + desc: item.description, + image: item.pic, + member: item.followerCount.toString(), + rating: item.rating.toString(), }, }) } @@ -101,29 +115,15 @@ const CategoryEcosystemListScreen = ({ ); }} - keyExtractor={(item) => item.document.id} + // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access + keyExtractor={(item) => (item.document ? item.document.id : item.id)} ItemSeparatorComponent={() => } showsVerticalScrollIndicator={false} showsHorizontalScrollIndicator={false} // ListFooterComponent={() => // !loadingMore ? : // } - ListHeaderComponent={() => ( - <> - - - - - - - )} + onEndReachedThreshold={0.5} // onEndReached={handleOnEndReach} /> -- GitLab From fa89a847527b1bc09c3d19926d6c31d9a395cd7c Mon Sep 17 00:00:00 2001 From: Ahmad Izzudin Alifyandra Date: Sun, 21 Nov 2021 21:32:47 +0700 Subject: [PATCH 4/5] feature: add loading ui when searching category ecosystem --- .../ecosystem/CategoryEcosystemListScreen.tsx | 92 +++++++++++-------- 1 file changed, 52 insertions(+), 40 deletions(-) diff --git a/src/screens/ecosystem/CategoryEcosystemListScreen.tsx b/src/screens/ecosystem/CategoryEcosystemListScreen.tsx index 942b915..e8a01b4 100644 --- a/src/screens/ecosystem/CategoryEcosystemListScreen.tsx +++ b/src/screens/ecosystem/CategoryEcosystemListScreen.tsx @@ -1,4 +1,5 @@ import { + ActivityIndicator, // ActivityIndicator, FlatList, StyleSheet, @@ -25,6 +26,8 @@ const CategoryEcosystemListScreen = ({ const [listData, setListData] = useState< SearchResponseHit[] | IEcosystem[] >([]); + const [isSearchLoading, setIsSearchLoading] = useState(false); + // const [loadingMore, setLoadingmore] = useState(false); // const [lastVisibleId, setLastVisibleId] = useState(""); @@ -53,12 +56,14 @@ const CategoryEcosystemListScreen = ({ // }); // }; const onSearch = async () => { + setIsSearchLoading(true); const res = await searchEcosystem({ q: search, query_by: "name", filter_by: "categoryId:" + toFetch, }); setListData(res.searchHits); + setIsSearchLoading(false); }; // const ListFooterComponent = () => ( // @@ -82,47 +87,54 @@ const CategoryEcosystemListScreen = ({ - { - const item: IEcosystem = _item.document ? _item.document : _item; - return ( - - - nav.navigate("Ecosystem", { - screen: "EcosystemDetails", - params: { - headerTitle: item.name, - id: item.id, - title: item.name, - desc: item.description, - image: item.pic, - member: item.followerCount.toString(), - rating: item.rating.toString(), - }, - }) - } - /> - - ); - }} - // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access - keyExtractor={(item) => (item.document ? item.document.id : item.id)} - ItemSeparatorComponent={() => } - showsVerticalScrollIndicator={false} - showsHorizontalScrollIndicator={false} - // ListFooterComponent={() => - // !loadingMore ? : - // } + {!isSearchLoading ? ( + { + const item: IEcosystem = _item.document ? _item.document : _item; + return ( + + + nav.navigate("Ecosystem", { + screen: "EcosystemDetails", + params: { + headerTitle: item.name, + id: item.id, + title: item.name, + desc: item.description, + image: item.pic, + member: item.followerCount.toString(), + rating: item.rating.toString(), + }, + }) + } + /> + + ); + }} + // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access + keyExtractor={(item) => (item.document ? item.document.id : item.id)} + ItemSeparatorComponent={() => } + showsVerticalScrollIndicator={false} + showsHorizontalScrollIndicator={false} + // ListFooterComponent={() => + // !loadingMore ? : + // } - onEndReachedThreshold={0.5} - // onEndReached={handleOnEndReach} - /> + onEndReachedThreshold={0.5} + // onEndReached={handleOnEndReach} + /> + ) : ( + <> + + + + )} ); }; -- GitLab From c80acc8cff139f9b7e076bd1b309fcbec1dfc319 Mon Sep 17 00:00:00 2001 From: Ahmad Izzudin Alifyandra Date: Sun, 21 Nov 2021 21:47:46 +0700 Subject: [PATCH 5/5] Fix kategori bisnis bug --- src/screens/ecosystem/BusinessCategoryScreen.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/screens/ecosystem/BusinessCategoryScreen.tsx b/src/screens/ecosystem/BusinessCategoryScreen.tsx index 711e518..89b303e 100644 --- a/src/screens/ecosystem/BusinessCategoryScreen.tsx +++ b/src/screens/ecosystem/BusinessCategoryScreen.tsx @@ -3,9 +3,7 @@ import { StyleSheet } from "react-native"; import { View } from "../../components/Themed"; import Colors from "../../constants/Colors"; import AlphabetGroupList from "../../components/GroupList/AlphabetGroupList"; -import { useState, useEffect } from "react"; import { getCategoriesAsIData } from "../../helpers/alphabetConverter"; -import { IData } from "react-native-section-alphabet-list"; import { CreateEcosystemStackScreenProps } from "../../types/navigation"; import { useCategory } from "../../hooks/reduxHooks"; @@ -13,11 +11,8 @@ const BusinessCategoryScreen = ({ route, }: CreateEcosystemStackScreenProps<"BusinessCategory">) => { const { fromScreen, forGroup, ecosystemCategories } = route.params; - const [data, setData] = useState([]); - const categoriesHook = useCategory(); - useEffect(() => { - setData(() => getCategoriesAsIData(categoriesHook)); - }); + const categories = useCategory(); + const data = getCategoriesAsIData(categories); return ( -- GitLab