From c33d7b40bcb9c19d2f6427ec201865b5e9d0bfa3 Mon Sep 17 00:00:00 2001 From: katyhonguyen Date: Sun, 22 Dec 2024 23:12:15 -0800 Subject: [PATCH] filter styling --- package-lock.json | 74 ++++++++ package.json | 1 + src/components/Checkbox/Checkbox.tsx | 35 ++++ src/components/Checkbox/styles.ts | 24 +++ src/components/TreeFilter/TreeFilter.tsx | 219 +++++++++++++++++++---- src/components/TreeFilter/styles.ts | 62 ++++--- src/icons/CallBig.tsx | 10 +- src/navigation/AppNavigator.tsx | 26 +-- src/screens/Directory/Directory.tsx | 4 +- src/screens/Login/styles.ts | 53 ------ 10 files changed, 370 insertions(+), 138 deletions(-) create mode 100644 src/components/Checkbox/Checkbox.tsx create mode 100644 src/components/Checkbox/styles.ts delete mode 100644 src/screens/Login/styles.ts diff --git a/package-lock.json b/package-lock.json index 8ad68cb..3513b58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,6 +47,7 @@ "react-native-element-dropdown": "^2.12.2", "react-native-elements": "^3.4.3", "react-native-gesture-handler": "~2.20.2", + "react-native-paper": "^5.12.5", "react-native-reanimated": "~3.16.1", "react-native-safe-area-context": "^4.12.0", "react-native-screens": "~4.1.0", @@ -2382,6 +2383,28 @@ "node": ">=6.9.0" } }, + "node_modules/@callstack/react-theme-provider": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@callstack/react-theme-provider/-/react-theme-provider-3.0.9.tgz", + "integrity": "sha512-tTQ0uDSCL0ypeMa8T/E9wAZRGKWj8kXP7+6RYgPTfOPs9N07C9xM8P02GJ3feETap4Ux5S69D9nteq9mEj86NA==", + "license": "MIT", + "dependencies": { + "deepmerge": "^3.2.0", + "hoist-non-react-statics": "^3.3.0" + }, + "peerDependencies": { + "react": ">=16.3.0" + } + }, + "node_modules/@callstack/react-theme-provider/node_modules/deepmerge": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@egjs/hammerjs": { "version": "2.0.17", "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", @@ -17526,6 +17549,57 @@ "react-native": "*" } }, + "node_modules/react-native-paper": { + "version": "5.12.5", + "resolved": "https://registry.npmjs.org/react-native-paper/-/react-native-paper-5.12.5.tgz", + "integrity": "sha512-Qpqd1g9PClmjGj/Dkr1htAwt8cTZ3SCHVmhttxRuG/QML7KzHm5ArLNgR7vz5dW1EwJqTmyl/3gd6gnrtw90mw==", + "license": "MIT", + "dependencies": { + "@callstack/react-theme-provider": "^3.0.9", + "color": "^3.1.2", + "use-latest-callback": "^0.1.5" + }, + "peerDependencies": { + "react": "*", + "react-native": "*", + "react-native-safe-area-context": "*", + "react-native-vector-icons": "*" + } + }, + "node_modules/react-native-paper/node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/react-native-paper/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/react-native-paper/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/react-native-paper/node_modules/use-latest-callback": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.11.tgz", + "integrity": "sha512-8nhb73STSD/z3GTHklvNjL8F9wMOo0bj0AFnulpIYuFTm6aQlT3ZcNbXF2YurKImIY8+kpSFSDHZZyQmurGrhw==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8" + } + }, "node_modules/react-native-ratings": { "version": "8.0.4", "resolved": "https://registry.npmjs.org/react-native-ratings/-/react-native-ratings-8.0.4.tgz", diff --git a/package.json b/package.json index a8de631..ce3ed18 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "react-native-element-dropdown": "^2.12.2", "react-native-elements": "^3.4.3", "react-native-gesture-handler": "~2.20.2", + "react-native-paper": "^5.12.5", "react-native-reanimated": "~3.16.1", "react-native-safe-area-context": "^4.12.0", "react-native-screens": "~4.1.0", diff --git a/src/components/Checkbox/Checkbox.tsx b/src/components/Checkbox/Checkbox.tsx new file mode 100644 index 0000000..c90b4c0 --- /dev/null +++ b/src/components/Checkbox/Checkbox.tsx @@ -0,0 +1,35 @@ +import React, { useState } from 'react'; +import { Text, View } from 'react-native'; +import { Checkbox } from 'react-native-paper'; +import colors from '@/styles/colors'; +import { styles } from './styles'; + +interface CheckboxComponentProps { + checked: boolean; + onToggle: () => void; + label: string; +} + +const CheckboxComponent: React.FC = ({ + checked, + label, +}) => { + const [isChecked, setChecked] = useState(checked); + return ( + + + { + setChecked(!isChecked); + }} + color={colors.primary} + uncheckedColor={colors.gray5} + /> + + {label} + + ); +}; + +export default CheckboxComponent; diff --git a/src/components/Checkbox/styles.ts b/src/components/Checkbox/styles.ts new file mode 100644 index 0000000..2bfc98e --- /dev/null +++ b/src/components/Checkbox/styles.ts @@ -0,0 +1,24 @@ +import { StyleSheet } from 'react-native'; +import colors from '@/styles/colors'; +import typography from '@/styles/typography'; + +export const styles = StyleSheet.create({ + checkboxContainer: { + flexDirection: 'row', + alignItems: 'center', + }, + checkboxWrapper: { + width: 20, + height: 20, + backgroundColor: colors.gray5, + borderRadius: 5, + justifyContent: 'center', + alignItems: 'center', + marginRight: 10, + }, + checkboxLabel: { + marginLeft: 10, + ...typography.normalRegular, + color: colors.gray3, + }, +}); diff --git a/src/components/TreeFilter/TreeFilter.tsx b/src/components/TreeFilter/TreeFilter.tsx index 4e88d27..4712f3c 100644 --- a/src/components/TreeFilter/TreeFilter.tsx +++ b/src/components/TreeFilter/TreeFilter.tsx @@ -1,6 +1,7 @@ import React, { useState } from 'react'; -import { Modal, Text, TouchableOpacity, View } from 'react-native'; -import CheckBox from '@react-native-community/checkbox'; +import { Modal, ScrollView, Text, TouchableOpacity, View } from 'react-native'; +import CheckboxComponent from '@/components/Checkbox/Checkbox'; +import Dropdown from '@/components/Dropdown/Dropdown'; import { styles } from './styles'; type TreeFilterModalProps = { @@ -8,26 +9,96 @@ type TreeFilterModalProps = { onClose: () => void; }; -// type SelectedHeightFilters = { -// [key: string]: boolean; -// }; - const TreeFilterModal: React.FC = ({ visible, onClose, }) => { - // const [selectedHeightFilters, setSelectedHeightFilters] = useState({ - // small: false, - // medium: false, - // large: false, - // }); - - // const handleCheckboxChange = (filter: string) => { - // setSelectedHeightFilters(prevState => ({ - // ...prevState, - // [filter]: !prevState[filter], - // })); - // }; + // Individual filter states + const [heightChecks, setHeightChecks] = useState({ + small: false, + medium: false, + large: false, + }); + + const [fruitChecks, setFruitChecks] = useState({ + wet: false, + dry: false, + }); + + const [waterChecks, setWaterChecks] = useState({ + less: false, + moderate: false, + more: false, + }); + + const [otherChecks, setOtherChecks] = useState({ + native: false, + evergreen: false, + powerline: false, + lowroot: false, + }); + + const [treeShape, setTreeShape] = useState(''); + + const handleHeightChange = (key: keyof typeof heightChecks) => { + setHeightChecks(prev => ({ + ...prev, + [key]: !prev[key], + })); + }; + + const handleFruitChange = (key: keyof typeof fruitChecks) => { + setFruitChecks(prev => ({ + ...prev, + [key]: !prev[key], + })); + }; + + const handleWaterChange = (key: keyof typeof waterChecks) => { + setWaterChecks(prev => ({ + ...prev, + [key]: !prev[key], + })); + }; + + const handleOtherChange = (key: keyof typeof otherChecks) => { + setOtherChecks(prev => ({ + ...prev, + [key]: !prev[key], + })); + }; + + const resetFilters = () => { + setHeightChecks({ + small: false, + medium: false, + large: false, + }); + setFruitChecks({ + wet: false, + dry: false, + }); + setWaterChecks({ + less: false, + moderate: false, + more: false, + }); + setOtherChecks({ + native: false, + evergreen: false, + powerline: false, + lowroot: false, + }); + setTreeShape(''); + }; + + const treeShapeOptions = [ + 'Columnar', + 'Conical', + 'Irregular', + 'Palm', + 'Rounded', + ]; return ( = ({ visible={visible} onRequestClose={onClose} > - - + + - Filter + Filter Trees + + Reset + - {/* - - handleCheckboxChange('small')} + + {/* Height */} + + Height + handleHeightChange('small')} + label="Small" + /> + handleHeightChange('medium')} + label="Medium" + /> + handleHeightChange('large')} + label="Large" /> - Small(< 40’) - - handleCheckboxChange('medium')} + {/* Tree Shape */} + + Tree Shape + - Medium (40 - 60’) - - handleCheckboxChange('large')} + {/* Fruit Type */} + + Fruit Type + handleFruitChange('wet')} + label="Wet Fruit" + /> + handleFruitChange('dry')} + label="Dry Fruit" /> - Large(60’ +) - */} + + + {/* Water Amount */} + + Water Amount + handleWaterChange('less')} + label="Less" + /> + handleWaterChange('moderate')} + label="Moderate" + /> + handleWaterChange('more')} + label="More" + /> + + + {/* Other Properties */} + + Other Properties + handleOtherChange('native')} + label="California Native" + /> + handleOtherChange('evergreen')} + label="Evergreen" + /> + handleOtherChange('powerline')} + label="Powerline Friendly" + /> + + handleOtherChange('lowroot')} + label="Low root damage" + /> + + + {/* Complete Button */} Complete diff --git a/src/components/TreeFilter/styles.ts b/src/components/TreeFilter/styles.ts index 8dbe53a..f4b48e7 100644 --- a/src/components/TreeFilter/styles.ts +++ b/src/components/TreeFilter/styles.ts @@ -5,39 +5,62 @@ import typography from '@/styles/typography'; const { width, height } = Dimensions.get('window'); export const styles = StyleSheet.create({ - filterContainer: { + filterBackground: { flex: 1, justifyContent: 'flex-end', alignItems: 'center', backgroundColor: 'rgba(0, 0, 0, 0.5)', }, - filterContent: { + filterContainer: { width: '100%', height: height * 0.8, backgroundColor: colors.white, - padding: 40, + paddingHorizontal: 40, + paddingBottom: 20, borderTopLeftRadius: 44, borderTopRightRadius: 44, - alignItems: 'flex-start', }, - filterHeading: {}, + filterProperties: { + marginBottom: 23, + gap: 10, + }, + + filterHeading: { + paddingTop: 40, + paddingBottom: 40, + flexDirection: 'row', + justifyContent: 'space-between', + }, filterHeadingText: { ...typography.heading5, color: colors.primary, - marginBottom: 10, }, - filterText: { - ...typography.normalRegular, - color: colors.gray4, + filterSubHeadingText: { + ...typography.mediumBold, + color: colors.gray2, + borderBottomWidth: 1, + borderBottomColor: colors.gray5, + paddingBottom: 5, }, - resetButton: {}, + resetButton: { + width: 86, + height: 34, + paddingVertical: 4, + paddingHorizontal: 8, + backgroundColor: colors.gray5, + borderRadius: 5, + alignItems: 'center', + }, - resetText: {}, + resetText: { + ...typography.mediumBold, + color: colors.gray3, + }, completeButton: { backgroundColor: colors.primary, @@ -48,26 +71,11 @@ export const styles = StyleSheet.create({ alignItems: 'center', justifyContent: 'center', padding: 5, + paddingBottom: 10, }, completeButtonText: { ...typography.mediumBold, color: colors.white, }, - - checkboxContainer: { - marginVertical: 20, - width: '100%', - }, - - checkboxRow: { - flexDirection: 'row', - alignItems: 'center', - marginVertical: 8, - }, - - checkboxLabel: { - ...typography.normalRegular, - marginLeft: 8, - }, }); diff --git a/src/icons/CallBig.tsx b/src/icons/CallBig.tsx index cc6f586..6cd3b71 100644 --- a/src/icons/CallBig.tsx +++ b/src/icons/CallBig.tsx @@ -1,18 +1,18 @@ -import type { SVGProps } from 'react'; import * as React from 'react'; +import Svg, { Path } from 'react-native-svg'; -const SvgCallBig = (props: SVGProps) => ( - ( + - - + ); export default SvgCallBig; diff --git a/src/navigation/AppNavigator.tsx b/src/navigation/AppNavigator.tsx index 7ef7203..547bdec 100644 --- a/src/navigation/AppNavigator.tsx +++ b/src/navigation/AppNavigator.tsx @@ -9,7 +9,7 @@ import SvgHomeSelected from '@/icons/HomeSelected'; import SvgHomeUnselected from '@/icons/HomeUnselected'; import ContactScreen from '@/screens/Contact/Contact'; import DirectoryScreen from '@/screens/Directory/Directory'; -import LoginScreen from '@/screens/Login/Login'; +// import LoginScreen from '@/screens/login/Login'; import SpeciesInfoScreen from '@/screens/SpeciesInfo/SpeciesInfo'; import TreeInfoScreen from '@/screens/TreeInfo/TreeInfo'; import TreeSearchScreen from '@/screens/TreeSearch/TreeSearch'; @@ -28,17 +28,17 @@ const ContactStack = createNativeStackNavigator(); const BottomTab = createBottomTabNavigator(); const RootStack = createNativeStackNavigator(); -// Login Stack Navigator -function LoginStackNavigator() { - return ( - - - - ); -} +// // Login Stack Navigator +// function LoginStackNavigator() { +// return ( +// +// +// +// ); +// } // Home Stack Navigator function HomeStackNavigator() { @@ -120,7 +120,7 @@ export default function AppNavigator() { initialRouteName="LoginStack" screenOptions={{ headerShown: false }} > - + {/* */} )} diff --git a/src/screens/Directory/Directory.tsx b/src/screens/Directory/Directory.tsx index 8cc162e..5cb9184 100644 --- a/src/screens/Directory/Directory.tsx +++ b/src/screens/Directory/Directory.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { ScrollView, Text, TouchableOpacity, View } from 'react-native'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; import BackArrow from '@/icons/BackArrow'; -import Call from '@/icons/Call'; +import CallBig from '@/icons/CallBig'; import { ContactStackParamList } from '@/types/navigation'; import { styles } from './styles'; @@ -23,7 +23,7 @@ export default function Directory({ navigation }: DirectoryScreenProps) { - + Directory diff --git a/src/screens/Login/styles.ts b/src/screens/Login/styles.ts deleted file mode 100644 index 1d9bec4..0000000 --- a/src/screens/Login/styles.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { StyleSheet } from 'react-native'; -import colors from '@/styles/colors'; -import typography from '@/styles/typography'; - -export const styles = StyleSheet.create({ - loginContainer: { - padding: 40, - flex: 1, - justifyContent: 'center', - }, - - loginText: { - ...typography.heading3, - color: colors.primary, - }, - - logoContainer: { - alignItems: 'center', - paddingTop: 20, - paddingBottom: 70, - }, - - logo: { - height: 200, - marginTop: 20, - marginBottom: 70, - }, - - button: { - backgroundColor: '#446127', - padding: 15, - borderRadius: 5, - alignItems: 'center', - marginBottom: 10, - }, - - buttonText: { - ...typography.largeBold, - color: colors.white, - }, - - adminLoginContainer: { - flex: 0, - flexDirection: 'row', - justifyContent: 'flex-end', - paddingTop: 10, - }, - - adminLoginText: { - ...typography.smallBold, - color: colors.gray3, - }, -});