diff --git a/frontend/app.json b/frontend/app.json index 3b29eba..1612101 100644 --- a/frontend/app.json +++ b/frontend/app.json @@ -23,6 +23,9 @@ }, "web": { "favicon": "" - } + }, + "plugins": [ + "expo-image-picker" + ] } } diff --git a/frontend/components/Pages/ActionsPage/ActionCard.js b/frontend/components/Pages/ActionsPage/ActionCard.js index 76a8d98..688264e 100644 --- a/frontend/components/Pages/ActionsPage/ActionCard.js +++ b/frontend/components/Pages/ActionsPage/ActionCard.js @@ -2,9 +2,11 @@ import React from "react"; import { Text, Pressable } from "react-native"; import { Box, Heading, Image, Stack } from "native-base"; +import styles from './styles' + export default ActionCard = React.memo( ({ - navigation, + navigation = null, id, title, imgUrl, @@ -15,11 +17,11 @@ export default ActionCard = React.memo( return ( { - navigation.navigate("actiondetails", { action_id: id }); + navigation && navigation.navigate("actiondetails", { action_id: id }); }} {...props} > - + {imgUrl ? ( image ) : ( - + )} diff --git a/frontend/components/Pages/ActionsPage/styles.js b/frontend/components/Pages/ActionsPage/styles.js new file mode 100644 index 0000000..b4863f3 --- /dev/null +++ b/frontend/components/Pages/ActionsPage/styles.js @@ -0,0 +1,4 @@ +export default { + cardWidth: 280, + imageSize: 120, +} \ No newline at end of file diff --git a/frontend/components/Pages/ServiceProvidersPage/ServiceProviderCard.js b/frontend/components/Pages/ServiceProvidersPage/ServiceProviderCard.js index e7f3a9e..2331965 100644 --- a/frontend/components/Pages/ServiceProvidersPage/ServiceProviderCard.js +++ b/frontend/components/Pages/ServiceProvidersPage/ServiceProviderCard.js @@ -9,13 +9,13 @@ export default function ServiceProviderCard({ description, imageURI, onPress, - navigation, + navigation = null, ...props }) { return ( - navigation.navigate("serviceProviderDetails", { vendor_id: id }) + navigation && navigation.navigate("serviceProviderDetails", { vendor_id: id }) } > { + const [isOpen, setIsOpen] = useState(false); + + const onSelect = (id) => { + setIsOpen(false); + onChange(id) + } + + const renderAction = (id) => { + const action = data.find((i) => i.id === id); + return action.title; + } + + return ( + + setIsOpen(true)}> + + {value ? ( + {renderAction(value)} + ): ( + + + )} + + + + + ); +}; + +const SPInput = ({ data, onChange, value }) => { + const [isOpen, setIsOpen] = useState(false); + + const onSelect = (id) => { + setIsOpen(false); + onChange(id) + } + + const renderSP = (id) => { + const sp = data.find((i) => i.id === id); + return sp.name; + } + + return ( + + setIsOpen(true)}> + + {value ? ( + {renderSP(value)} + ): ( + + )} + + + + + ); +}; + +const validationSchema = Yup.object().shape({ + image: Yup.mixed().nullable(), + title: Yup.string().required("Title is required"), + description: Yup.string().required("Description is required"), + action: Yup.string().nullable(), + vendor: Yup.string().nullable(), +}); export default function AddTestimonial() { // TODO: waiting for dashboard/user context to be implemented + const { actions, vendors } = useContext(CommunityContext); return ( - - Add Testimonial Page - + + + console.log(values)} + > + {({ + handleChange, + handleBlur, + handleSubmit, + setFieldValue, + values, + errors, + touched, + }) => ( + + + + + + + {errors.title && touched.title ? ( + + {errors.title} + + ) : null} + + + + {errors.description && touched.description ? ( + + {errors.description} + + ) : null} + + Which action is this testimonial about? + + setFieldValue("action", value)} value={values.action}/> + + Who helped you complete this action? + + setFieldValue("vendor", value)} value={values.vendor}/> + + + + )} + + + ); } diff --git a/frontend/components/Pages/TestimonialsPage/ImageInput.js b/frontend/components/Pages/TestimonialsPage/ImageInput.js new file mode 100644 index 0000000..f35e7aa --- /dev/null +++ b/frontend/components/Pages/TestimonialsPage/ImageInput.js @@ -0,0 +1,154 @@ +import React from "react"; +import { TouchableWithoutFeedback } from "react-native"; + +import { + Actionsheet, + View, + Box, + Text, + Icon, + useDisclose, + Image, +} from "native-base"; +import FontAwesome from "@expo/vector-icons/FontAwesome"; +import * as ImagePicker from "expo-image-picker"; + +const ImageContainer = ({ uri, onDelete, onEdit }) => { + return ( + + image + + + + ); +} + +const ImageInput = ({ onChange, value = null }) => { + const { isOpen, onOpen, onClose } = useDisclose(); + const [status, requestPermission] = ImagePicker.useCameraPermissions(); + + const pickImage = async () => { + onClose(); + + let result = await ImagePicker.launchImageLibraryAsync({ + mediaTypes: ImagePicker.MediaTypeOptions.Images, + allowsEditing: false, + aspect: [4, 3], + quality: 1, + }); + + if (!result.canceled) { + onChange(result.assets[0].uri); + } + }; + + const takePhoto = async () => { + onClose(); + + if (!status.granted) { + await requestPermission(); + takePhoto(); + } else { + const result = await ImagePicker.launchCameraAsync({ + mediaTypes: ImagePicker.MediaTypeOptions.Images, + allowsEditing: true, + aspect: [4, 3], + quality: 1, + }); + + if (!result.canceled) { + onChange(result.assets[0].uri); + } + } + }; + + return ( + + + + {value ? ( + onChange("")} onEdit={onOpen} /> + ) : ( + + + Upload your own image here + + + {" "} + /{" "} + + + + )} + + + + + } + > + Upload from gallery + + } + > + Take a photo + + + + + ); +}; + +export default ImageInput; diff --git a/frontend/components/Pages/TestimonialsPage/ListResources.js b/frontend/components/Pages/TestimonialsPage/ListResources.js new file mode 100644 index 0000000..b080521 --- /dev/null +++ b/frontend/components/Pages/TestimonialsPage/ListResources.js @@ -0,0 +1,39 @@ +import React from "react"; +import { Modal, ScrollView, VStack, Button } from "native-base"; + +const ListResources = ({ + isOpen, + setIsOpen, + data, + onSelect, + title = "Resources", +}) => { + + return ( + setIsOpen(false)} size="xl"> + + + {title} + + + + {data.map((i, index) => { + return ( + + ); + })} + + + + + + ); +}; + +export default ListResources; diff --git a/frontend/components/Pages/TestimonialsPage/TestimonialsPage.js b/frontend/components/Pages/TestimonialsPage/TestimonialsPage.js index 1ef78ef..45d5d44 100644 --- a/frontend/components/Pages/TestimonialsPage/TestimonialsPage.js +++ b/frontend/components/Pages/TestimonialsPage/TestimonialsPage.js @@ -1,6 +1,7 @@ import React, { useContext } from "react"; -import { Container } from "native-base"; -import { View, ScrollView } from "react-native"; + +import { Box, Pressable, Container, View, ScrollView } from "native-base"; +import Ionicons from "react-native-vector-icons/Ionicons"; import Page from "../../Shared/Page"; import { TestimonialCard } from "./TestimonialsCard.js"; @@ -25,11 +26,11 @@ export default function TestimonialsPage({ navigation }) { {/* Button to create a new testimonial - waiting on dashboard/user context */} {/* */} - {/* navigation.navigate("addTestimonial")} position="absolute" bottom={5} right={5}> + navigation.navigate("addTestimonial")} position="absolute" bottom={5} right={5}> - */} + } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 1bbf50a..726ac86 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,6 +14,7 @@ "@react-navigation/native": "^6.1.7", "@react-navigation/native-stack": "^6.9.13", "expo": "^49.0.6", + "expo-image-picker": "~14.3.2", "expo-status-bar": "~1.6.0", "firebase": "^10.1.0", "formik": "^2.4.2", @@ -9769,6 +9770,25 @@ "expo": "*" } }, + "node_modules/expo-image-loader": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-4.3.0.tgz", + "integrity": "sha512-2kqJIO+oYM8J3GbvTUHLqTSpt1dLpOn/X0eB4U4RTuzz/faj8l/TyQELsMBLlGAkweNUuG9LqznbaBz+WuSFEw==", + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-image-picker": { + "version": "14.3.2", + "resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-14.3.2.tgz", + "integrity": "sha512-xr/YeQMIYheXecWP033F2SPwpBlBR5xVCx7YSfSCTH8Y9pw7Z886agqKGbS9QBVGlzJ5qecJktZ6ASSzeslDVg==", + "dependencies": { + "expo-image-loader": "~4.3.0" + }, + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-keep-awake": { "version": "12.3.0", "resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-12.3.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 6985c8f..3a34f5f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -31,7 +31,8 @@ "react-native-screens": "~3.22.0", "react-native-svg": "13.9.0", "victory-native": "^36.6.11", - "yup": "^1.2.0" + "yup": "^1.2.0", + "expo-image-picker": "~14.3.2" }, "overrides": { "semver": ">=7.5.2",