From 72ab6e817f71886c8447fd8756b81383d324df53 Mon Sep 17 00:00:00 2001 From: dev-rathore Date: Mon, 25 Nov 2024 17:52:09 +0530 Subject: [PATCH 1/3] initial implementation --- app/(modal)/create-collaboration.tsx | 26 ++++++++--- components/brand/CreateBrand.tsx | 9 ---- .../collaboration/CollaborationHeader.tsx | 7 +-- .../OverviewTabContent.tsx | 7 ++- .../collaboration-details/index.tsx | 12 +++--- .../CreateCollaborationMap.tsx | 43 ++++++++++++++++++- 6 files changed, 73 insertions(+), 31 deletions(-) delete mode 100644 components/brand/CreateBrand.tsx diff --git a/app/(modal)/create-collaboration.tsx b/app/(modal)/create-collaboration.tsx index dacf68ad..e3ca13d3 100644 --- a/app/(modal)/create-collaboration.tsx +++ b/app/(modal)/create-collaboration.tsx @@ -43,6 +43,7 @@ const CreateCollaborationScreen = () => { }, ]); const [location, setLocation] = useState("Remote"); + const [formattedAddress, setFormattedAddress] = useState(""); const [links, setLinks] = useState([]); const [screen, setScreen] = useState(1); const theme = useTheme(); @@ -89,6 +90,10 @@ const CreateCollaborationScreen = () => { setIsModalVisible(false); }; + const onFormattedAddressChange = (address: string) => { + setFormattedAddress(address); + } + const submitCollaboration = async () => { try { if (!AuthApp.currentUser) { @@ -111,6 +116,18 @@ const CreateCollaborationScreen = () => { } const collabRef = collection(FirestoreDB, "collaborations"); + + let locationAddress = {}; + if (location === "Physical" && mapRegion.latitude && mapRegion.longitude) { + locationAddress = { + name: formattedAddress, + latlong: { + lat: mapRegion.latitude, + long: mapRegion.longitude, + }, + }; + } + await addDoc(collabRef, { name: collaborationName, brandId: selectedBrand ? selectedBrand.id : "", @@ -127,13 +144,7 @@ const CreateCollaborationScreen = () => { platform: platform[0].value, location: { type: location, - ...(location === "Physical" && { - name: "locationName", // TODO: Add location name using geocoding API - latlong: { - lat: mapRegion.latitude, - long: mapRegion.longitude, - }, - }), + ...locationAddress, }, externalLinks: links, status: "active", @@ -371,6 +382,7 @@ const CreateCollaborationScreen = () => { setMapRegion(region)} + onFormattedAddressChange={onFormattedAddressChange} /> ) } diff --git a/components/brand/CreateBrand.tsx b/components/brand/CreateBrand.tsx deleted file mode 100644 index 1c504955..00000000 --- a/components/brand/CreateBrand.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { View } from "../theme/Themed" - -const CreateBrand = () => { - return ( - - ); -}; - -export default CreateBrand; diff --git a/components/collaboration/CollaborationHeader.tsx b/components/collaboration/CollaborationHeader.tsx index d35a9dcd..05da1f08 100644 --- a/components/collaboration/CollaborationHeader.tsx +++ b/components/collaboration/CollaborationHeader.tsx @@ -5,9 +5,10 @@ import Tag from '../ui/tag'; import { Text, View } from '../theme/Themed'; import { useTheme } from '@react-navigation/native'; import { stylesFn } from '@/styles/collaboration-details/CollaborationHeader.styles'; +import { CollaborationDetail } from './collaboration-details'; interface ColloborationHeaderProps { - collaboration: any; + collaboration: CollaborationDetail; } const CollaborationHeader: React.FC = ({ @@ -41,12 +42,12 @@ const CollaborationHeader: React.FC = ({ - {collaboration.appliedCount} Applied + {collaboration.promotionType} - {collaboration.brandViewed} Reviewed + {collaboration.collaborationType} = ({ collaboration, - logo, }) => { const theme = useTheme(); const styles = stylesFn(theme); @@ -39,7 +38,7 @@ const OverviewTabContent: React.FC = ({ = ({ pageID }) => { - const [collaboration, setCollaboration] = useState( + const [collaboration, setCollaboration] = useState( undefined ); const [loading, setLoading] = useState(true); @@ -43,6 +44,7 @@ const CollaborationDetails: React.FC = ({ setCollaboration({ ...data, + logo: brandData?.image || "", brandName: brandData?.name || "Unknown Brand", paymentVerified: brandData?.paymentMethodVerified || false, brandDescription: brandData?.description || "", @@ -60,9 +62,7 @@ const CollaborationDetails: React.FC = ({ title: "Overview", component: ( ), }, diff --git a/components/collaboration/create-collaboration/CreateCollaborationMap.tsx b/components/collaboration/create-collaboration/CreateCollaborationMap.tsx index 776a9ef5..38a33dcb 100644 --- a/components/collaboration/create-collaboration/CreateCollaborationMap.tsx +++ b/components/collaboration/create-collaboration/CreateCollaborationMap.tsx @@ -11,11 +11,13 @@ import { useTheme } from "@react-navigation/native"; interface CreateCollaborationMapProps { mapRegion: any; onMapRegionChange: (region: any) => void; + onFormattedAddressChange?: (address: string) => void; } const CreateCollaborationMap: React.FC = ({ mapRegion, onMapRegionChange, + onFormattedAddressChange, }) => { const [nativeMapRegion, setNativeMapRegion] = useState(mapRegion); @@ -24,20 +26,57 @@ const CreateCollaborationMap: React.FC = ({ const theme = useTheme(); const styles = stylesFn(theme); - const onLocationChange = ( + const fetchMapRegionAddress = async ( + lat: number, + lng: number + ) => { + if (!lat || !lng) { + return; + } + + const response = await fetch( + `https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${process.env.EXPO_PUBLIC_GOOGLE_MAPS_API_KEY}` + ); + + const result = await response.json(); + + const address = result?.results?.[0]?.formatted_address || result?.plus_code?.compound_code || 'Address'; + + return address; + }; + + const onLocationChange = async ( location: { latitude: number; longitude: number }, ) => { setWebMapRegion({ latitude: location.latitude, longitude: location.longitude, }); + + const address = await fetchMapRegionAddress( + location.latitude, + location.longitude + ); + + if (onFormattedAddressChange) { + onFormattedAddressChange(address as string); + } }; - const onMapLocationChange = (region: any) => { + const onMapLocationChange = async (region: any) => { onMapRegionChange({ latitude: region.latitude, longitude: region.longitude, }); + + const address = await fetchMapRegionAddress( + region.latitude, + region.longitude + ); + + if (onFormattedAddressChange) { + onFormattedAddressChange(address as string); + } } useEffect(() => { From 1d8e3cbf4377926d595df687b1ebe2426585ba74 Mon Sep 17 00:00:00 2001 From: dev-rathore Date: Tue, 26 Nov 2024 21:43:03 +0530 Subject: [PATCH 2/3] updateBytes function added --- app/(onboarding)/onboarding-your-brand.tsx | 19 ++++++++++++- .../collaboration/CollaborationHeader.tsx | 28 ++++++++++++------- components/menu/index.tsx | 17 ++--------- .../firebase-storage-context.provider.tsx | 17 ++++++++++- 4 files changed, 55 insertions(+), 26 deletions(-) diff --git a/app/(onboarding)/onboarding-your-brand.tsx b/app/(onboarding)/onboarding-your-brand.tsx index 014fc355..5c5d364b 100644 --- a/app/(onboarding)/onboarding-your-brand.tsx +++ b/app/(onboarding)/onboarding-your-brand.tsx @@ -19,6 +19,7 @@ import { addDoc, collection, doc, setDoc } from "firebase/firestore"; import { FirestoreDB } from "@/utils/firestore"; import Toaster from "@/shared-uis/components/toaster/Toaster"; import Colors from "@/constants/Colors"; +import { useFirebaseStorageContext } from "@/contexts"; const OnboardingScreen = () => { const [brandName, setBrandName] = useState(""); @@ -29,11 +30,15 @@ const OnboardingScreen = () => { const [filteredRoles, setFilteredRoles] = useState([]); const [filteredIndustries, setFilteredIndustries] = useState([]); const [activeDropdown, setActiveDropdown] = useState(null); + const [isSubmitting, setIsSubmitting] = useState(false); const theme = useTheme(); const styles = fnStyles(theme); const { firstBrand, } = useLocalSearchParams(); + const { + uploadImageBytes, + } = useFirebaseStorageContext(); const pickImage = async () => { let result = await ImagePicker.launchImageLibraryAsync({ @@ -42,6 +47,7 @@ const OnboardingScreen = () => { aspect: [4, 3], quality: 1, }); + if (!result.canceled) { setImage(result.assets[0].uri); } @@ -67,17 +73,26 @@ const OnboardingScreen = () => { const handleSubmit = async () => { try { + setIsSubmitting(true); const user = AuthApp.currentUser; if (!brandName || !role || !industry || !website) { Toaster.error("Please fill in all fields."); + setIsSubmitting(false); return; } + + let imageUrl = ""; + if (image) { + const blob = await fetch(image).then((res) => res.blob()); + imageUrl = await uploadImageBytes(blob, `brands/${brandName}-${Date.now()}`); + } + if (user) { const colRef = collection(FirestoreDB, "brands"); let brandData = { name: brandName, - image: "", + image: imageUrl, profile: { industry, website, @@ -99,6 +114,7 @@ const OnboardingScreen = () => { role, }); + setIsSubmitting(false); router.navigate({ pathname: "/(onboarding)/onboarding-brand-preference", params: { brandId: docRef.id }, @@ -238,6 +254,7 @@ const OnboardingScreen = () => { />