From 4a882ed4a91111ff61718cd94bbe428830148dca Mon Sep 17 00:00:00 2001 From: 23nosurrend Date: Mon, 20 May 2024 11:23:24 +0200 Subject: [PATCH] Feat(Favorite-Doctor) add filter functionality,to allow user filter his search based on category and rating --- app/(app)/ActionMenu/FavoriteDoctorScreen.tsx | 19 +- assets/icons/blueStar.ts | 4 + assets/icons/whiteStar.ts | 4 + components/FilterSearchComponent.tsx | 316 ++++++++++++++++++ components/Ratebtn.tsx | 132 ++++++++ components/SearchComponent.tsx | 7 +- 6 files changed, 477 insertions(+), 5 deletions(-) create mode 100644 assets/icons/blueStar.ts create mode 100644 assets/icons/whiteStar.ts create mode 100644 components/FilterSearchComponent.tsx create mode 100644 components/Ratebtn.tsx diff --git a/app/(app)/ActionMenu/FavoriteDoctorScreen.tsx b/app/(app)/ActionMenu/FavoriteDoctorScreen.tsx index 8a68ad4d..15ff5463 100644 --- a/app/(app)/ActionMenu/FavoriteDoctorScreen.tsx +++ b/app/(app)/ActionMenu/FavoriteDoctorScreen.tsx @@ -17,6 +17,7 @@ import SearchComponent from '@/components/SearchComponent'; import FoundDoctorCount from '@/components/FoundDoctorCount'; import NofoundComponent from '@/components/NofoundComponent'; import RemovefavoritePopup from '@/components/RemovefavoritePopup'; +import FilterPopup from '@/components/FilterSearchComponent'; import NotFoundScreen from '@/app/+not-found'; @@ -64,7 +65,8 @@ function DoctorScreen() { const [searchTerm, setSearchTerm] = useState('') const [selectedCategory, setSelectedCategory] = useState(data.categories[0]) const [showpopUp, setShowPopup] = useState(false) - const [selectedDoctor,setSelectedDoctor]=useState() + const [selectedDoctor, setSelectedDoctor] = useState() + const [showFilter,setShowfilter]=useState(false) const handleSearchPressed = () => { setShowSearch(true) @@ -77,6 +79,9 @@ function DoctorScreen() { setSelectedCategory(category), setSearchTerm('') } + const handleFilter = () => { + setShowfilter(true) + } const handleRemove = (doctor:any) => { setSelectedDoctor(doctor) @@ -99,7 +104,8 @@ function DoctorScreen() { ) : ( @@ -188,6 +194,15 @@ function DoctorScreen() { /> + setShowfilter(false)} + visible={showFilter} + onClose={() => setShowfilter(false)} + + + + /> + diff --git a/assets/icons/blueStar.ts b/assets/icons/blueStar.ts new file mode 100644 index 00000000..9b408dbf --- /dev/null +++ b/assets/icons/blueStar.ts @@ -0,0 +1,4 @@ +export const blueStar=` + + +` \ No newline at end of file diff --git a/assets/icons/whiteStar.ts b/assets/icons/whiteStar.ts new file mode 100644 index 00000000..b456ca94 --- /dev/null +++ b/assets/icons/whiteStar.ts @@ -0,0 +1,4 @@ +export const whiteStar=` + + +` \ No newline at end of file diff --git a/components/FilterSearchComponent.tsx b/components/FilterSearchComponent.tsx new file mode 100644 index 00000000..5362fd4b --- /dev/null +++ b/components/FilterSearchComponent.tsx @@ -0,0 +1,316 @@ +import React,{ReactElement, useState,useRef,useEffect} from 'react'; +import { StyleSheet, Text, Image, View,Animated, TouchableHighlight, SafeAreaView,ScrollView,Button, Alert, Platform, StatusBar, Dimensions,TextInput, Pressable,ImageURISource} from 'react-native' +import Typography from '@/constants/Typography'; +import { SvgXml } from "react-native-svg" +import { blueheart } from '@/assets/icons/blueHeart'; +import { star } from '@/assets/icons/star'; +import Removebtn from './Removebtn'; +import data from "../app/doctors.json" +import { overlay } from 'react-native-paper'; +import DoctorComponent from './DoctorComponent'; +import Ratebtn from './Ratebtn'; +import { Rating } from 'react-native-elements'; + + +interface iconMappingProp{ + [key :string]:ReactElement +} + + +interface RemovefavoritepopProps{ + visible: boolean, + onClose: () => void, + cancel: () => void, +} +export const iconMapping:iconMappingProp = { + heart: , + star: , +} + + + +function FilterPopup({ visible, onClose, cancel, }: RemovefavoritepopProps) { + const [selectedCategory, setSelectedCategory] = useState(data.categories[0]) + const [showpopUp, setShowPopup] = useState(false) + const [selectedDoctor, setSelectedDoctor] = useState() + const [selectedRating, setSelectedRating] = useState("All") + const handleSelectedRating = (Rating: string) => { + setSelectedRating(Rating) + } + const handleCategoryChange = (category:any) => { + setSelectedCategory(category) + } + + const translateY = useRef(new Animated.Value(0)).current + useEffect(() => { + if (visible) { + Animated.timing(translateY, { + toValue: -1, + duration: 300, + useNativeDriver:true + }).start() + } else { + Animated.timing(translateY, { + toValue: 1, + duration: 300, + useNativeDriver:true + }).start() + } + }, [visible]) + if(!visible) return null + return ( + + + + Filter + + + + Speciality + + + + {data.categories.map((category:any, index:any) => + handleCategoryChange(category)} style={[styles.categoryBtn, + selectedCategory === category ? styles.firstCategoryBtn : {}, + ]}> + + {category.name} + + + )} + + + + + Rating + + + {["All", "2", "3", "4", "5"].map((Rating, index) => ( + + handleSelectedRating(Rating)} + + + /> + ))} + + + + + + + + + + + + + + + + console.log("remove")} + backColor='#246BFD' + text="Apply" + textColor="white" + + + + + /> + + + + + + + + ); +} + +export default FilterPopup; + +const styles = StyleSheet.create({ + overlay: { + position: "absolute", + width: "100%", + height: "100%", + backgroundColor: 'rgba(80, 85, 94, 0.8)', + justifyContent: 'flex-end', + zIndex: 1000, + + }, + outer: { + width: "100%", + height: "45%", + zIndex:1000, + backgroundColor: 'white', + borderTopLeftRadius: 30, + borderTopRightRadius: 30, + shadowColor: '#000', + shadowOffset: { width: 0, height: -2 }, + shadowOpacity: 0.3, + shadowRadius: 10, + elevation: 5, + display: "flex", + flexDirection: "row", + justifyContent: "center", + }, + intro: { + width: "100%", + height: 40, + marginBottom:"5%", + marginTop:"5%", + display: "flex", + flexDirection: "row", + justifyContent: "center", + alignItems: 'center', + }, + introText: { + color: "#212121", + fontWeight: "bold", + fontSize:20 + }, + inner: { + width: "90%", + backgroundColor:"white" + }, + btn: { + height: 50, + width:100, + display: "flex", + justifyContent: "center", + alignItems: "center", + paddingHorizontal:20 + + }, + titleView: { + marginBottom:10 + + }, + rateView: { + + + }, + btnInnerView: { + display: "flex", + flexDirection: "row", + justifyContent: "center", + alignItems: "center", + width:"80%" + + }, + iconView: { + display: "flex", + flexDirection: "row", + justifyContent: "center", + alignItems: 'center', + + }, + rateTextView: { + + }, + rateText: { + + }, + title: { + color: "#212121", + fontWeight: "500", + fontSize:18 + + }, + scrollView: { + + }, + specialityView: { + + }, + displayComponent: { + + }, + btnView: { + display: "flex", + flexDirection: "row", + justifyContent: "space-between", + alignItems:'center' + }, + componentView: { + backgroundColor:"#FDFDFD", + marginBottom: "5%", + width: "100%", + height: 150, + borderRadius:20, + display: "flex", + flexDirection: 'row', + justifyContent: "center", + alignItems: "center", + zIndex:10000 + }, + horizontal: { + width: "100%", + borderWidth: 1, + borderColor:"#EEEEEE", + marginBottom: "6%", + backgroundColor:"#EEEEEE" + }, + categoryScroll: { + + }, + categoryBtnView: { + display:"flex", + flexDirection: "row", + alignItems: 'center', + marginBottom: "5%", + backgroundColor: "white", + }, + categoryBtn: { + borderWidth: 2, + borderColor: "#246BFD", + height: 40, + paddingHorizontal: 20, + paddingVertical:7, + borderRadius: 20, + display: "flex", + flexDirection: "row", + justifyContent: "center", + alignItems: "center", + marginRight: 8, + marginLeft:10 + }, + firstCategoryBtn: { + backgroundColor: "#246BFD" + }, + firstCategoryBtnText: { + color:"white" + }, + categoryBtnText: { + color: "#246BFD", + fontSize:16 + } + +}) \ No newline at end of file diff --git a/components/Ratebtn.tsx b/components/Ratebtn.tsx new file mode 100644 index 00000000..651b3125 --- /dev/null +++ b/components/Ratebtn.tsx @@ -0,0 +1,132 @@ +import React,{ReactElement, useState} from 'react'; +import { StyleSheet, Text, Image, View, TouchableHighlight, SafeAreaView, Button, Alert, Platform, StatusBar, Dimensions,TextInput, Pressable,ImageURISource} from 'react-native' +import Typography from '@/constants/Typography'; +import { SvgXml } from "react-native-svg" +import { whiteStar } from '@/assets/icons/whiteStar'; +import { blueStar } from '@/assets/icons/blueStar'; +interface RatebtnProps{ + text: string, + isSelected: boolean, + selectedAction:()=>void +} + + +function Ratebtn({text,isSelected,selectedAction}:RatebtnProps) { + return ( + + + + + + {text} + + + + ); +} + +export default Ratebtn; + +const styles = StyleSheet.create({ + categoryBtn: { + borderWidth: 2, + borderColor: "#246BFD", + height: 40, + paddingHorizontal: 20, + paddingVertical:7, + borderRadius: 20, + display: "flex", + flexDirection: "row", + justifyContent: "center", + alignItems: "center", + marginRight: 8, + marginLeft:10 + }, + btn: { + height: 40, + width:70, + display: "flex", + justifyContent: "center", + alignItems: "center", + paddingHorizontal: 2, + backgroundColor: "white", + borderWidth: 2, + borderColor: "#246BFD", + marginRight: 8, + marginLeft: 10, + borderRadius:20 + + }, + selectedbtn: { + height: 40, + width:70, + display: "flex", + justifyContent: "center", + alignItems: "center", + paddingHorizontal: 2, + backgroundColor: "#246BFD", + borderWidth: 2, + borderColor: "#246BFD", + marginRight: 8, + marginLeft: 10, + borderRadius:20 + + }, + selectedText: { + color:"white" + + }, + titleView: { + + }, + rateView: { + + + }, + btnInnerView: { + display: "flex", + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + width: "60%", + }, + iconView: { + display: "flex", + flexDirection: "row", + justifyContent: "center", + alignItems: 'center', + + }, + rateTextView: { + + }, + rateText: { + color:"#246BFD" + + }, + title: { + color: "#212121", + fontWeight: "bold", + fontSize: 18 + + }, + scrollView: { + + }, + specialityView: { + + }, + displayComponent: { + + }, + btnView: { + display: "flex", + flexDirection: "row", + justifyContent: "space-between", + alignItems: 'center' + }, + + categoryScroll: { + + } +}) \ No newline at end of file diff --git a/components/SearchComponent.tsx b/components/SearchComponent.tsx index 9e159ae2..b0d0dd93 100644 --- a/components/SearchComponent.tsx +++ b/components/SearchComponent.tsx @@ -9,9 +9,10 @@ import { router } from 'expo-router'; interface searchComponentProps{ - onSearchSubmit:(searchTerm:string)=>void + onSearchSubmit: (searchTerm: string) => void, + filterAction:()=>void } -function SearchComponent({onSearchSubmit}:searchComponentProps) { +function SearchComponent({onSearchSubmit,filterAction}:searchComponentProps) { const [value, setValue] = useState("") const handleSearchClick = () => { onSearchSubmit(value) @@ -39,7 +40,7 @@ function SearchComponent({onSearchSubmit}:searchComponentProps) { /> - +