digipin-reactjs
Version:
React hooks and components for integrating DIGIPIN (Indian Postal Digital PIN) geocoding into React apps. Includes hooks, prebuilt UI, and helpers for seamless integration.
143 lines (135 loc) • 6.68 kB
JavaScript
import { jsxs, jsx } from 'react/jsx-runtime';
import { useState, useCallback } from 'react';
import { getDigiPin, getLatLngFromDigiPin } from 'digipinjs';
function useDigiPin() {
const [input, setInput] = useState('');
const [result, setResult] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const search = useCallback(async (query) => {
setLoading(true);
setError(null);
try {
let res;
// If input looks like lat,lon, encode to DIGIPIN
const trimmed = query.trim();
if (/^-?\d+(\.\d+)?\s*,\s*-?\d+(\.\d+)?$/.test(trimmed)) {
const [latStr, lonStr] = trimmed.split(',');
const lat = Number(latStr.trim());
const lon = Number(lonStr.trim());
if (isNaN(lat) || isNaN(lon)) {
throw new Error('Invalid latitude or longitude');
}
if (lat < -90 || lat > 90) {
throw new Error('Latitude must be between -90 and 90');
}
if (lon < -180 || lon > 180) {
throw new Error('Longitude must be between -180 and 180');
}
res = getDigiPin(lat, lon);
}
else {
// Otherwise, decode as DIGIPIN
if (!trimmed) {
throw new Error('Input cannot be empty');
}
res = getLatLngFromDigiPin(trimmed);
}
setResult(res);
}
catch (e) {
setError(e.message || 'Unknown error');
setResult(null);
}
finally {
setLoading(false);
}
}, []);
return { input, setInput, result, loading, error, search };
}
const DigiPinInput = () => {
const { input, setInput, result, loading, error, search } = useDigiPin();
const handleSubmit = (e) => {
e.preventDefault();
search(input);
};
return (jsxs("form", { onSubmit: handleSubmit, children: [jsx("input", { type: "text", value: input, onChange: e => setInput(e.target.value), placeholder: "Enter DigiPin query" }), jsx("button", { type: "submit", disabled: loading, children: loading ? 'Searching...' : 'Search' }), error && jsx("div", { style: { color: 'red' }, children: error }), result && (jsx("pre", { children: JSON.stringify(result, null, 2) }))] }));
};
function useLatLonToDigiPin() {
const [lat, setLat] = useState('');
const [lon, setLon] = useState('');
const [digipinResult, setDigiPinResult] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const convert = useCallback(() => {
setLoading(true);
setError(null);
try {
const latNum = Number(lat.trim());
const lonNum = Number(lon.trim());
if (isNaN(latNum) || isNaN(lonNum)) {
throw new Error('Invalid latitude or longitude');
}
if (latNum < -90 || latNum > 90) {
throw new Error('Latitude must be between -90 and 90');
}
if (lonNum < -180 || lonNum > 180) {
throw new Error('Longitude must be between -180 and 180');
}
const result = getDigiPin(latNum, lonNum);
setDigiPinResult(result);
}
catch (e) {
setError(e.message || 'Unknown error');
setDigiPinResult(null);
}
finally {
setLoading(false);
}
}, [lat, lon]);
return { lat, setLat, lon, setLon, digipinResult, loading, error, convert };
}
function useDigiPinToLatLon() {
const [digipinInput, setDigiPinInput] = useState('');
const [latLonResult, setLatLonResult] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const convert = useCallback(() => {
setLoading(true);
setError(null);
try {
const input = digipinInput.trim();
if (!input) {
throw new Error('DIGIPIN cannot be empty');
}
const result = getLatLngFromDigiPin(input);
setLatLonResult({ lat: result.latitude, lon: result.longitude });
}
catch (e) {
setError(e.message || 'Unknown error');
setLatLonResult(null);
}
finally {
setLoading(false);
}
}, [digipinInput]);
return { digipinInput, setDigiPinInput, latLonResult, loading, error, convert };
}
const LatLonToDigiPinInput = () => {
const { lat, setLat, lon, setLon, digipinResult, loading, error, convert } = useLatLonToDigiPin();
const handleSubmit = (e) => {
e.preventDefault();
convert();
};
return (jsxs("form", { onSubmit: handleSubmit, style: { marginBottom: 24 }, children: [jsxs("div", { children: [jsx("input", { type: "text", value: lat, onChange: e => setLat(e.target.value), placeholder: "Latitude", style: { marginRight: 8 } }), jsx("input", { type: "text", value: lon, onChange: e => setLon(e.target.value), placeholder: "Longitude", style: { marginRight: 8 } }), jsx("button", { type: "submit", disabled: loading, children: loading ? 'Converting...' : 'Convert to DIGIPIN' })] }), error && jsx("div", { style: { color: 'red' }, children: error }), digipinResult && (jsxs("div", { style: { marginTop: 8 }, children: [jsx("strong", { children: "DIGIPIN:" }), " ", digipinResult] }))] }));
};
const DigiPinToLatLonInput = () => {
const { digipinInput, setDigiPinInput, latLonResult, loading, error, convert } = useDigiPinToLatLon();
const handleSubmit = (e) => {
e.preventDefault();
convert();
};
return (jsxs("form", { onSubmit: handleSubmit, style: { marginBottom: 24 }, children: [jsxs("div", { children: [jsx("input", { type: "text", value: digipinInput, onChange: e => setDigiPinInput(e.target.value), placeholder: "DIGIPIN", style: { marginRight: 8 } }), jsx("button", { type: "submit", disabled: loading, children: loading ? 'Converting...' : 'Convert to Lat/Lon' })] }), error && jsx("div", { style: { color: 'red' }, children: error }), latLonResult && (jsxs("div", { style: { marginTop: 8 }, children: [jsx("strong", { children: "Latitude:" }), " ", latLonResult.lat, " ", jsx("br", {}), jsx("strong", { children: "Longitude:" }), " ", latLonResult.lon] }))] }));
};
export { DigiPinInput, DigiPinToLatLonInput, LatLonToDigiPinInput, useDigiPin, useDigiPinToLatLon, useLatLonToDigiPin };
//# sourceMappingURL=index.mjs.map