Group Locations

This module helps manage geofenced group locations and determines user proximity to these areas.

Concept

Each group location is represented by a circular area (defined by a center point and a radius). A user is considered "inside" a location if their coordinates fall within that circular boundary.

Utility Functions

typescript

/** * Calculates the distance between two coordinates in meters */ export const calculateDistance = ( lat1: number, lon1: number, lat2: number, lon2: number ): number => { const R = 6371e3; // Earth's radius in meters const φ1 = (lat1 * Math.PI) / 180; const φ2 = (lat2 * Math.PI) / 180; const Δφ = ((lat2 - lat1) * Math.PI) / 180; const Δλ = ((lon2 - lon1) * Math.PI) / 180; const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ / 2) * Math.sin(Δλ / 2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); const distance = R * c; return distance; }; /** * Checks if a user is inside a location's circle */ export const isUserInsideLocation = ( userLat: number, userLon: number, locationLat: number, locationLon: number, radiusInMeters: number ): boolean => { const distance = calculateDistance(userLat, userLon, locationLat, locationLon); return distance <= radiusInMeters; };

Creating A Location

typescript

const handleCreateLocation = async () => { if (!coordinates || !locationName || !radius) return; setIsLoading(true); try { const { error } = await supabase.from("group_locations").insert({ group_id: groupId, latitude: coordinates.latitude.toString(), longitude: coordinates.longitude.toString(), name: locationName, radius: parseInt(radius), }); if (error) throw error; onClose(); } catch (error) { console.error("Error creating location:", error); } finally { setIsLoading(false); } };

Location Schema

typescript

export interface GroupLocations { id: string; group_id: string; latitude: string; longitude: string; updated_at: Date; created_at: Date; radius: number; name: string; }