QR Type: Location
Relevant source files
The following files were used as context for generating this wiki page: - [src/App.jsx](https://github.com/vophuthinh/QR-Tool/blob/HEAD/src/App.jsx) - [src/utils/qr-helpers.js](https://github.com/vophuthinh/QR-Tool/blob/HEAD/src/utils/qr-helpers.js) - [src/App.test.js](https://github.com/vophuthinh/QR-Tool/blob/HEAD/src/App.test.js) - [tests/qr-helpers.test.js](https://github.com/vophuthinh/QR-Tool/blob/HEAD/tests/qr-helpers.test.js) - [README.md](https://github.com/vophuthinh/QR-Tool/blob/HEAD/README.md) - [SECURITY_AUDIT_REPORT.md](https://github.com/vophuthinh/QR-Tool/blob/HEAD/SECURITY_AUDIT_REPORT.md)The Location QR type, identified internally as geo, enables users to generate a QR code containing GPS coordinates. When scanned, this QR code typically prompts a mapping application on the scanning device to open and display the specified location. The feature supports latitude, longitude, and an optional descriptive label.
This functionality is one of several QR types offered by the application, alongside URL, Text, Wi-Fi, and others.
Sources: README.md, src/App.jsx:33
Architecture and Data Flow
The process for generating a Location QR code is managed within the main App component. It involves user input, state management, validation, and content formatting before the final QR code is rendered.
The following diagram illustrates the data flow from user interaction to the final rendered QR code.
This diagram shows the flow of data for the Location QR type, starting from user input in the UI, through state updates, validation, and content generation, to the final rendering of the QR image.
Sources: src/App.jsx:319-328, 1024-1049, src/utils/qr-helpers.js:63-73
State Management
The data for the Location QR type is stored in the qrData state object within the App component.
| Key | Type | Description | Default Value |
|---|---|---|---|
lat | string | The latitude of the location. | '' |
lng | string | The longitude of the location. | '' |
label | string | An optional text label for the location. | '' |
These state fields are updated via the updateQrData function whenever the user types into the corresponding input fields in the UI.
Sources: src/App.jsx:304-318, 320
User Interface
The UI for the Location QR type is conditionally rendered within App.jsx when qrType is equal to QR_TYPES.GEO. It consists of three main input fields.
// src/App.jsx:1024-1049
{qrType === QR_TYPES.GEO && (
<>
<div className="grid grid-cols-2 gap-2">
<div>
<Label htmlFor="lat">📍 Vĩ độ (Lat)</Label>
<Input
id="lat"
placeholder="21.0285"
value={qrData.lat}
onChange={(e) => updateQrData('lat', e.target.value)}
error={validationErrors.geo}
/>
</div>
<div>
<Label htmlFor="lng">📍 Kinh độ (Lng)</Label>
<Input
id="lng"
placeholder="105.8542"
value={qrData.lng}
onChange={(e) => updateQrData('lng', e.target.value)}
error={validationErrors.geo}
/>
</div>
</div>
{validationErrors.geo && (
<p className="text-xs text-rose-600 dark:text-rose-400 font-medium">
⚠️ {validationErrors.geo}
</p>
)}
<div>
<Label htmlFor="geo-label">🏷️ Nhãn địa điểm</Label>
<Input
id="geo-label"
placeholder="Hà Nội, Việt Nam"
value={qrData.label}
onChange={(e) => updateQrData('label', e.target.value)}
/>
</div>
</>
)}
- Two
Inputcomponents are used for latitude and longitude, arranged in a two-column grid. - A single
Inputis used for the optional location label. - An error message is displayed below the coordinate inputs if validation fails.
Sources: src/App.jsx:1024-1049
Input Validation
Input validation for the coordinates is performed in a React.useEffect hook that runs whenever qrData changes. It utilizes the isValidLatLng helper function.
Validation Logic
The core validation logic resides in isValidLatLng from qr-helpers.js.
// src/utils/qr-helpers.js:63-73
export function isValidLatLng(lat, lng) {
if (!lat && !lng) return true;
const la = parseFloat(lat),
ln = parseFloat(lng);
if (isNaN(la) || isNaN(ln)) return false;
return la >= -90 && la <= 90 && ln >= -180 && ln <= 180;
}
The validation rules are as follows:
- If both
latandlngare empty, the input is considered valid. - Both values must be parseable as floating-point numbers.
- Latitude must be between -90 and 90, inclusive.
- Longitude must be between -180 and 180, inclusive.
Sources: src/utils/qr-helpers.js:63-73, tests/qr-helpers.test.js:80-88, SECURITY_AUDIT_REPORT.md
Integration in App.jsx
The App component uses this function to update the validationErrors state, which in turn displays an error message in the UI.
// src/App.jsx:342-344
React.useEffect(() => {
// ... other validations
if (qrType === QR_TYPES.GEO) {
if (!isValidLatLng(qrData.lat, qrData.lng)) e.geo = 'Tọa độ không hợp lệ (Lat: -90..90, Lng: -180..180)';
}
setValidationErrors(e);
}, [qrType, qrData]);
Sources: src/App.jsx:322-346
QR Content Generation
The final string to be encoded in the QR code is generated by the generateQRContent function. For the GEO type, it constructs a standard geo: URI.
generateQRContent Implementation
// src/App.jsx:144-149
case QR_TYPES.GEO: {
const lat = data.lat ? data.lat.toString() : '0';
const lng = data.lng ? data.lng.toString() : '0';
const label = data.label ? `(${data.label})` : '';
return `geo:0,0?q=${lat},${lng}${label}`;
}
- If
latorlngare empty, they default to'0'. - If a
labelexists, it is enclosed in parentheses. - The final format is
geo:0,0?q=LAT,LNG(LABEL). Thegeo:0,0?q=part is a common format to ensure compatibility with various scanner apps, where theqparameter specifies the search query.
Sources: src/App.jsx:144-149
Test Cases
The behavior is confirmed by unit tests in App.test.js.
// src/App.test.js:345-372
describe('GEO type', () => {
it('should generate geo coordinates with label', () => {
const data = {
lat: '21.0285',
lng: '105.8542',
label: 'Hanoi, Vietnam',
};
const result = generateQRContent(QR_TYPES.GEO, data);
expect(result).toBe('geo:0,0?q=21.0285,105.8542(Hanoi, Vietnam)');
});
it('should handle coordinates without label', () => {
const data = {
lat: '10.762622',
lng: '106.660172',
label: '',
};
const result = generateQRContent(QR_TYPES.GEO, data);
expect(result).toBe('geo:0,0?q=10.762622,106.660172');
});
it('should default to 0,0 when empty', () => {
const data = {
lat: '',
lng: '',
label: '',
};
const result = generateQRContent(QR_TYPES.GEO, data);
expect(result).toBe('geo:0,0?q=0,0');
});
});
Sources: src/App.test.js:345-372
Summary
The Location QR feature provides a straightforward way to encode geographic coordinates. It leverages React state management for user input, performs robust validation on latitude and longitude values, and formats the data into a standardized geo: URI scheme. This ensures that the generated QR codes are widely compatible with mobile device mapping applications.