Repository navigation
Feedbacks Resolved #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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<any[]>([]); | ||
| const [filteredIndustries, setFilteredIndustries] = useState<string[]>([]); | ||
| const [activeDropdown, setActiveDropdown] = useState<any>(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); | ||
| } | ||
|
Comment on lines
+50
to
53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Enhance image validation and error handling The image picker implementation should include size and format validation to prevent issues during upload. if (!result.canceled) {
+ const { uri, fileSize, type } = result.assets[0];
+ const MAX_SIZE = 5 * 1024 * 1024; // 5MB
+ if (fileSize > MAX_SIZE) {
+ Toaster.error("Image size should be less than 5MB");
+ return;
+ }
+ if (!type?.startsWith('image/')) {
+ Toaster.error("Invalid file format");
+ return;
+ }
- setImage(result.assets[0].uri);
+ setImage(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()}`); | ||
| } | ||
|
|
||
|
Comment on lines
+76
to
+89
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve form submission robustness and error handling The current implementation has several potential issues that should be addressed:
+ const [uploadError, setUploadError] = useState<Error | null>(null);
+ useEffect(() => {
+ return () => {
+ // Cleanup effect for component unmount
+ if (isSubmitting) {
+ // Cancel ongoing uploads if necessary
+ }
+ };
+ }, [isSubmitting]);
const handleSubmit = async () => {
try {
setIsSubmitting(true);
+ setUploadError(null);
const user = AuthApp.currentUser;
if (!brandName || !role || !industry || !website) {
Toaster.error("Please fill in all fields.");
setIsSubmitting(false);
return;
}
let imageUrl = "";
if (image) {
+ try {
const blob = await fetch(image).then((res) => res.blob());
+ if (!(blob instanceof Blob)) {
+ throw new Error('Invalid image format');
+ }
imageUrl = await uploadImageBytes(blob, `brands/${brandName}-${Date.now()}`);
+ } catch (error) {
+ // If image upload fails, cleanup and show error
+ setUploadError(error as Error);
+ setIsSubmitting(false);
+ Toaster.error("Failed to upload image");
+ return;
+ }
}
|
||
| 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 = () => { | |
| /> | ||
|
|
||
| <Button | ||
| loading={isSubmitting} | ||
| mode="contained" | ||
| onPress={handleSubmit} | ||
| > | ||
|
|
||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ import { collection, doc, getDoc, getDocs } from "firebase/firestore"; | |
| import BottomSheetActions from "@/components/BottomSheetActions"; | ||
| import EmptyState from "@/components/ui/empty-state"; | ||
| import Colors from "@/constants/Colors"; | ||
| import { processRawAttachment } from "@/utils/attachments"; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Type safety improvements needed for attachment processing The
🔗 Analysis chainVerify types for attachment processing The new import for 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Check the type definitions in the attachments utility
ast-grep --pattern 'export function processRawAttachment($_) {
$$$
}'
# Look for any existing type definitions for attachments
rg -t typescript "type.*Attachment"
Length of output: 146 Script: #!/bin/bash
# Look for processRawAttachment function definition
rg -l "processRawAttachment"
# Once we find the file, let's examine its contents
rg -A 10 "processRawAttachment"
# Look for type definitions with a broader search
rg "type.*ttachment|interface.*ttachment"
Length of output: 3491 Script: #!/bin/bash
# Let's check for MediaItem type definition since processRawAttachment returns it
rg -A 5 "type MediaItem|interface MediaItem"
# Also check the file where MediaItem might be imported from
rg -l "MediaItem"
Length of output: 602 |
||
|
|
||
| const ApplicationsTabContent = (props: any) => { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add proper TypeScript interfaces for improved type safety The component uses interface ApplicationsTabContentProps {
pageID: string;
collaboration: CollaborationDetail;
}
interface Influencer {
id: string;
profileImage: string;
name: string;
handle: string;
attachments: Attachment[];
backend?: {
followers: number;
reach: number;
rating: number;
};
}
interface SelectedApplication {
applicationID: string;
collaborationID: string;
influencerID: string;
}Then update the component: -const ApplicationsTabContent = (props: any) => {
+const ApplicationsTabContent: React.FC<ApplicationsTabContentProps> = (props) => {
- const [influencers, setInfluencers] = useState<any>([]);
+ const [influencers, setInfluencers] = useState<Influencer[]>([]);
- const [selectedApplication, setSelectedApplication] = useState<any>(null);
+ const [selectedApplication, setSelectedApplication] = useState<SelectedApplication | null>(null);Also applies to: 19-22 |
||
| const theme = useTheme(); | ||
|
|
@@ -96,7 +97,7 @@ const ApplicationsTabContent = (props: any) => { | |
| profilePic: item.profileImage, | ||
| name: item.name, | ||
| handle: item.handle || "@handle", | ||
| media: item.attachments, | ||
| media: item.attachments.map((media: any) => processRawAttachment(media)), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add type safety and error handling for attachment processing While processing attachments is good, there are several improvements needed:
-media: item.attachments.map((media: any) => processRawAttachment(media)),
+media: item.attachments.map((media: Attachment) => {
+ try {
+ return processRawAttachment(media);
+ } catch (error) {
+ console.error('Failed to process attachment:', error);
+ return null;
+ }
+}).filter(Boolean),
|
||
| followers: item.backend ? item.backend.followers : 1000, | ||
| reach: item.backend ? item.backend.reach : 10000, | ||
| rating: item.backend ? item.backend.rating : 4.5, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,10 +11,11 @@ import OverviewTabContent from "./OverviewTabContent"; | |
| import SettingsTabContent from "./SettingsTabContent"; | ||
| import CollaborationHeader from "../CollaborationHeader"; | ||
|
|
||
| interface Collaboration extends ICollaboration { | ||
| export interface CollaborationDetail extends ICollaboration { | ||
| brandDescription: string; | ||
| brandName: string; | ||
| logo: string; | ||
| paymentVerified: boolean; | ||
| brandDescription: string; | ||
| } | ||
|
Comment on lines
+14
to
19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Interface inconsistency detected - The verification revealed that the old
🔗 Analysis chainInterface changes look good, verify usage across codebase The renaming of Let's verify the interface usage across the codebase: 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Description: Check for any remaining references to the old interface name and verify new interface adoption
# Search for old interface references
echo "Checking for old Collaboration interface references..."
rg "interface Collaboration extends ICollaboration"
# Search for new interface usage
echo "Checking CollaborationDetail usage..."
rg "CollaborationDetail"
Length of output: 2217 |
||
|
|
||
| interface CollaborationDetailsProps { | ||
|
|
@@ -24,7 +25,7 @@ interface CollaborationDetailsProps { | |
| const CollaborationDetails: React.FC<CollaborationDetailsProps> = ({ | ||
| pageID | ||
| }) => { | ||
| const [collaboration, setCollaboration] = useState<Collaboration | undefined>( | ||
| const [collaboration, setCollaboration] = useState<CollaborationDetail | undefined>( | ||
| undefined | ||
| ); | ||
| const [loading, setLoading] = useState(true); | ||
|
|
@@ -43,6 +44,7 @@ const CollaborationDetails: React.FC<CollaborationDetailsProps> = ({ | |
|
|
||
| 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<CollaborationDetailsProps> = ({ | |
| title: "Overview", | ||
| component: ( | ||
| <OverviewTabContent | ||
| collaboration={collaboration as Collaboration} | ||
| // logo={collaboration?.logo} | ||
| logo={""} | ||
| collaboration={collaboration as CollaborationDetail} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Improve type safety in prop passing The current type assertion using Here's a suggested improvement: - collaboration={collaboration as CollaborationDetail}
+ collaboration={collaboration ?? undefined}
|
||
| /> | ||
| ), | ||
| }, | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -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<CreateCollaborationMapProps> = ({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mapRegion, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onMapRegionChange, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onFormattedAddressChange, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [nativeMapRegion, setNativeMapRegion] = useState(mapRegion); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -24,20 +26,57 @@ const CreateCollaborationMap: React.FC<CreateCollaborationMapProps> = ({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+29
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider improving error handling and security. Several improvements could enhance the robustness of this function:
Here's a suggested improvement: const fetchMapRegionAddress = async (
- lat: number,
- lng: number
+ lat: number | undefined,
+ lng: number | undefined
): Promise<string> => {
if (!lat || !lng) {
- return;
+ return 'Address';
}
+ try {
const response = await fetch(
`https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lng}&key=${process.env.EXPO_PUBLIC_GOOGLE_MAPS_API_KEY}`
);
+ if (!response.ok) {
+ throw new Error('Geocoding API request failed');
+ }
const result = await response.json();
const address = result?.results?.[0]?.formatted_address || result?.plus_code?.compound_code || 'Address';
return address;
+ } catch (error) {
+ console.error('Error fetching address:', error);
+ return 'Address';
+ }
};Consider implementing a backend proxy for geocoding:
📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 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(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add coordinate range validation
While the location handling is structured well, consider adding validation for coordinate ranges to ensure they are within valid bounds (-90 to 90 for latitude, -180 to 180 for longitude).
let locationAddress = {}; if (location === "Physical" && mapRegion.latitude && mapRegion.longitude) { + const isValidLatitude = mapRegion.latitude >= -90 && mapRegion.latitude <= 90; + const isValidLongitude = mapRegion.longitude >= -180 && mapRegion.longitude <= 180; + if (!isValidLatitude || !isValidLongitude) { + Toaster.error("Invalid coordinates"); + return; + } locationAddress = { name: formattedAddress, latlong: { lat: mapRegion.latitude, long: mapRegion.longitude, }, }; }