UNPKG

sid-address-verification-react-native

Version:
361 lines (360 loc) 13.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _jsxRuntime = require("react/jsx-runtime"); var _react = _interopRequireWildcard(require("react")); var _reactNative = require("react-native"); var _ApiService = require("../services/ApiService"); var _LocationService = require("../services/LocationService"); var _permissions = require("../utils/permissions"); var _helper_functions = require("../utils/helper_functions"); var _GooglePlacesService = _interopRequireDefault(require("../services/GooglePlacesService")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } const AddressVerificationField = ({ config, onAddressSelected, onLocationUpdate, onError, chooseAddressType, addressTypes, onAddressTypeChange, placeholder = 'Enter your address', showSubmitButton = true, style // googlePlacesApiKey, // Add this prop to pass the API key }) => { const [query, setQuery] = (0, _react.useState)(config.initialAddressText || ''); const [suggestions, setSuggestions] = (0, _react.useState)([]); const [selectedAddress, setSelectedAddress] = (0, _react.useState)(null); const [selectedType, setSelectedType] = (0, _react.useState)(null); const [loading, setLoading] = (0, _react.useState)(true); const [loadingSuggestions, setLoadingSuggestions] = (0, _react.useState)(false); const [pollingInterval, setPollingInterval] = (0, _react.useState)(15); const [sessionTimeout, setSessionTimeout] = (0, _react.useState)(60); const [sessionToken] = (0, _react.useState)(() => (0, _helper_functions.generateSessionToken)()); const [googlePlacesService] = (0, _react.useState)(() => new _GooglePlacesService.default(_helper_functions.GOOGLE_PLACES_KEY || '')); // Debounced search function const debouncedSearch = (0, _react.useCallback)((0, _helper_functions.debounce)(async searchQuery => { if (searchQuery.trim().length > 2) { setLoadingSuggestions(true); try { const predictions = await googlePlacesService.getAutocompletePredictions(searchQuery, sessionToken); console.log('predictions', predictions); if (Array.isArray(predictions)) { setSuggestions(predictions); } else { console.warn('GooglePlacesService returned non-array predictions:', predictions); setSuggestions([]); // fallback to empty } } catch (error) { console.error('Error fetching suggestions:', error); onError?.(`Failed to fetch suggestions: ${error}`); setSuggestions([]); } finally { setLoadingSuggestions(false); } } else { setSuggestions([]); } }, 300), [googlePlacesService, sessionToken, onError]); // Initialize API service and fetch config (0, _react.useEffect)(() => { const initializeService = async () => { try { // Validate Google Places API key // if (!googlePlacesApiKey) { // throw new Error('Google Places API key is required'); // } _ApiService.ApiService.getInstance().configure(config.apiKey, config.customerID); const configData = await _ApiService.ApiService.getInstance().fetchAddressVerificationConfig(); setPollingInterval(configData.geotaggingPollingInterval || 15); setSessionTimeout(configData.geotaggingSessionTimeout || 60); } catch (error) { console.error('Error initializing service:', error); onError?.(`Failed to initialize: ${error}`); } finally { setLoading(false); } }; initializeService(); }, [config.apiKey, config.customerID, onError]); // Trigger search when query changes (0, _react.useEffect)(() => { debouncedSearch(query); }, [query, debouncedSearch]); const handleSuggestionSelect = (0, _react.useCallback)(async suggestion => { try { setLoadingSuggestions(true); const placeDetails = await googlePlacesService.getPlaceDetails(suggestion.place_id, sessionToken); setSelectedAddress(placeDetails); setQuery(placeDetails.address); setSuggestions([]); onAddressSelected(placeDetails); } catch (error) { console.error('Error selecting address:', error); onError?.(`Failed to select address: ${error}`); _reactNative.Alert.alert('Error', 'Failed to get address details. Please try again.'); } finally { setLoadingSuggestions(false); } }, [onAddressSelected, onError, googlePlacesService, sessionToken]); const handleSubmit = (0, _react.useCallback)(async () => { if (!selectedAddress) { _reactNative.Alert.alert('Error', 'Please select an address first'); return; } if (config.verifyLocation) { try { const permissionResult = await (0, _permissions.requestLocationPermission)(); if (!permissionResult.granted) { _reactNative.Alert.alert('Permission Required', 'Location permission is required for address verification'); return; } // Start location tracking const locationService = _LocationService.LocationService.getInstance(); locationService.startLocationTracking(config.locationFetchIntervalSeconds || pollingInterval, config.locationFetchDurationSeconds || sessionTimeout, onLocationUpdate); _reactNative.Alert.alert('Success', 'Address verification started. Location tracking is now active.'); } catch (error) { console.error('Error starting location verification:', error); onError?.(`Failed to start location verification: ${error}`); } } else { _reactNative.Alert.alert('Success', 'Address selected successfully'); } }, [selectedAddress, config, pollingInterval, sessionTimeout, onLocationUpdate, onError]); const handleClearAddress = (0, _react.useCallback)(() => { setSelectedAddress(null); setQuery(''); setSuggestions([]); }, []); if (loading) { return (0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.container, style], children: [(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, { size: "large", color: "#0000ff" }), (0, _jsxRuntime.jsx)(_reactNative.Text, { style: styles.loadingText, children: "Loading configuration..." })] }); } return (0, _jsxRuntime.jsxs)(_reactNative.View, { style: [styles.container, style], children: [(0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.inputContainer, children: [chooseAddressType && addressTypes?.length > 0 && (0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.addressTypeContainer, children: addressTypes.map(type => (0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { style: [styles.addressTypeButton, selectedType === type && styles.addressTypeButtonSelected], onPress: () => { setSelectedType(type); onAddressTypeChange?.(type); }, children: (0, _jsxRuntime.jsx)(_reactNative.Text, { style: [styles.addressTypeText, selectedType === type && styles.addressTypeTextSelected], children: type }) }, type)) }), (0, _jsxRuntime.jsx)(_reactNative.TextInput, { style: styles.textInput, value: query, onChangeText: setQuery, placeholder: placeholder, placeholderTextColor: "#999", autoComplete: "street-address", autoCorrect: false, keyboardAppearance: "light" }), selectedAddress && (0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { style: styles.clearButton, onPress: handleClearAddress, children: (0, _jsxRuntime.jsx)(_reactNative.Text, { style: styles.clearButtonText, children: "\u2715" }) })] }), loadingSuggestions && (0, _jsxRuntime.jsx)(_reactNative.View, { style: styles.loadingContainer, children: (0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, { size: "small", color: "#0000ff" }) }), suggestions.length > 0 && (0, _jsxRuntime.jsx)(_reactNative.FlatList, { data: suggestions, keyExtractor: item => item.place_id, renderItem: ({ item }) => (0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, { style: styles.suggestionItem, onPress: () => handleSuggestionSelect(item), children: [(0, _jsxRuntime.jsx)(_reactNative.Text, { style: styles.suggestionMain, children: item.structured_formatting.main_text }), (0, _jsxRuntime.jsx)(_reactNative.Text, { style: styles.suggestionSecondary, children: item.structured_formatting.secondary_text })] }), style: styles.suggestionsList, nestedScrollEnabled: true, keyboardShouldPersistTaps: "handled" }), showSubmitButton && (0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, { style: [styles.submitButton, !selectedAddress && styles.submitButtonDisabled], onPress: handleSubmit, disabled: !selectedAddress, children: (0, _jsxRuntime.jsx)(_reactNative.Text, { style: styles.submitButtonText, children: config.verifyLocation ? 'Verify Address' : 'Submit Address' }) }), selectedAddress && (0, _jsxRuntime.jsxs)(_reactNative.View, { style: styles.selectedAddressContainer, children: [(0, _jsxRuntime.jsx)(_reactNative.Text, { style: styles.selectedAddressLabel, children: "Selected Address:" }), (0, _jsxRuntime.jsx)(_reactNative.Text, { style: styles.selectedAddressText, children: selectedAddress.address }), (0, _jsxRuntime.jsxs)(_reactNative.Text, { style: styles.coordinatesText, children: ["Coordinates: ", selectedAddress.latitude.toFixed(6), ",", ' ', selectedAddress.longitude.toFixed(6)] })] })] }); }; const styles = _reactNative.StyleSheet.create({ container: { padding: 16 }, inputContainer: { position: 'relative' }, textInput: { borderWidth: 1, borderColor: '#ccc', borderRadius: 8, padding: 12, paddingRight: 40, // Make room for clear button fontSize: 16, backgroundColor: '#fff', color: '#000' }, clearButton: { position: 'absolute', right: 12, top: 12, width: 24, height: 24, justifyContent: 'center', alignItems: 'center', backgroundColor: '#f0f0f0', borderRadius: 12 }, clearButtonText: { fontSize: 14, color: '#666', fontWeight: 'bold' }, loadingContainer: { padding: 8, alignItems: 'center' }, loadingText: { marginTop: 8, fontSize: 16, color: '#666' }, suggestionsList: { maxHeight: 200, borderWidth: 1, borderColor: '#ccc', borderTopWidth: 0, backgroundColor: '#fff', borderBottomLeftRadius: 8, borderBottomRightRadius: 8 }, suggestionItem: { padding: 12, borderBottomWidth: 1, borderBottomColor: '#eee' }, suggestionMain: { fontSize: 16, fontWeight: '600', color: '#333' }, addressTypeContainer: { flexDirection: 'row', flexWrap: 'wrap', marginBottom: 12, gap: 8 }, addressTypeButton: { paddingVertical: 6, paddingHorizontal: 12, borderRadius: 16, borderWidth: 1, borderColor: '#ccc', backgroundColor: '#f0f0f0' }, addressTypeButtonSelected: { backgroundColor: '#007AFF', borderColor: '#007AFF' }, addressTypeText: { color: '#333', fontSize: 14 }, addressTypeTextSelected: { color: '#fff', fontWeight: '600' }, suggestionSecondary: { fontSize: 14, color: '#666', marginTop: 2 }, submitButton: { backgroundColor: '#007AFF', padding: 12, borderRadius: 8, alignItems: 'center', marginTop: 16 }, submitButtonDisabled: { backgroundColor: '#ccc' }, submitButtonText: { color: '#fff', fontSize: 16, fontWeight: '600' }, selectedAddressContainer: { marginTop: 16, padding: 12, backgroundColor: '#f8f8f8', borderRadius: 8, borderLeftWidth: 4, borderLeftColor: '#007AFF' }, selectedAddressLabel: { fontSize: 14, fontWeight: '600', marginBottom: 4, color: '#333' }, selectedAddressText: { fontSize: 16, marginBottom: 4, color: '#333' }, coordinatesText: { fontSize: 14, color: '#666' } }); var _default = exports.default = AddressVerificationField; //# sourceMappingURL=AddressVerificationField.js.map