QR Type: Email, SMS, and Phone
Relevant source files
The following files were used as context for generating this wiki page:The QR-Tool application supports the generation of QR codes for initiating communication actions directly from a scanning device. This includes composing an email, sending an SMS message, or making a phone call. The functionality is implemented by encoding data into standard URI (Uniform Resource Identifier) schemes: mailto:, sms:, and tel:.
This system ensures that user-provided data is correctly formatted and validated before being encoded into the final QR code, providing a reliable user experience. The core logic resides within the main App component, which handles state management, UI rendering, validation, and content generation.
Sources: README.md, src/App.jsx:20-27
Data Flow and State Management
User interactions for Email, SMS, and Phone QR types follow a standard data flow within the App component. User input is captured, validated, and used to generate the final QR content string.
This diagram illustrates the flow from user input to the final QR code generation.
State Object
The data for all QR types is stored in a single state object, qrData. The fields relevant to these communication types are detailed below.
| Field | Data Type | Description | Relevant QR Types |
|---|---|---|---|
email | string | The recipient's email address. | |
subject | string | The pre-filled subject line of the email. | |
body | string | The pre-filled body content of the email. | |
phone | string | The recipient's phone number. | SMS, Phone |
message | string | The pre-filled body of the SMS message. | SMS |
Sources: src/App.jsx:324-345
Content Generation
The core of the functionality is the generateQRContent function, which takes the qrType and qrData object to produce the final string for QR encoding.
Sources: src/App.jsx:54-122, src/App.test.js:19-86
Email (mailto:)
For the EMAIL type, the function constructs a mailto: URI. The subject and body are encoded using encodeURIComponent to ensure special characters are handled correctly.
// file: src/App.jsx:101-104
case QR_TYPES.EMAIL:
return `mailto:${data.email || ''}?subject=${encodeURIComponent(
data.subject || '',
)}&body=${encodeURIComponent(data.body || '')}`;
Sources: src/App.jsx:101-104, src/App.test.js:238-292
SMS (sms:)
For the SMS type, it generates an sms: URI. It includes special logic to handle differences in how iOS and other operating systems parse the URI, using & as a separator for iOS and ? for others. If no message is provided, it generates a URI with only the phone number.
// file: src/App.jsx:105-112
case QR_TYPES.SMS: {
const phone = data.phone || '';
const message = data.message || '';
if (!message) return `sms:${phone}`;
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
const sep = isIOS ? '&' : '?';
return `sms:${phone}${sep}body=${encodeURIComponent(message)}`;
}
Sources: src/App.jsx:105-112, src/App.test.js:294-313
Phone (tel:)
The TEL type is the simplest, creating a tel: URI with the provided phone number.
// file: src/App.jsx:113-114
case QR_TYPES.TEL:
return `tel:${data.phone || ''}`;
Sources: src/App.jsx:113-114, src/App.test.js:315-325
URI Generation Summary
| QR Type | URI Scheme | Example Output |
|---|---|---|
mailto: | mailto:a@b.com?subject=Hello&body=Test%20email | |
| SMS | sms: | sms:+12345?body=Hello%20there |
| Phone | tel: | tel:+12345 |
Sources: src/App.test.js:238-325
Input Validation
To ensure the generated QR codes are functional, user inputs for email addresses and phone numbers are validated. This logic is triggered by a useEffect hook that observes changes to qrData.
This sequence diagram shows the validation process.
Validation Functions
The validation logic is encapsulated in helper functions within src/utils/qr-helpers.js.
| Function | Description | Source File |
|---|---|---|
isValidEmail(email) | Checks if the string is a valid email format using a regex. Returns true if empty. | src/utils/qr-helpers.js |
isValidPhone(phone) | Checks if the string contains only valid phone characters (\d, \s, +, -, ()). Returns true if empty. | src/utils/qr-helpers.js |
These functions are tested in tests/qr-helpers.test.js to confirm their behavior with valid and invalid inputs.
Sources: src/utils/qr-helpers.js:50-65, tests/qr-helpers.test.js:77-96
Implementation in App.jsx
The validation is applied within a useEffect hook. If an input is invalid, an error message is added to the validationErrors state object, which is then used to render an error message in the UI.
// file: src/App.jsx:350-353
if (qrType === QR_TYPES.EMAIL) {
if (qrData.email && !isValidEmail(qrData.email)) e.email = 'Email không hợp lệ';
}
if (qrType === QR_TYPES.SMS || qrType === QR_TYPES.TEL) {
if (qrData.phone && !isValidPhone(qrData.phone)) e.phone = 'Số điện thoại không hợp lệ';
}
Sources: src/App.jsx:347, 350-353
Testing
The project includes comprehensive unit tests for the content generation logic using vitest. The tests in src/App.test.js cover various scenarios, including:
- Correct generation of
mailto:,sms:, andtel:URIs. - Proper URL encoding of special characters in email subjects and bodies.
- Handling of empty fields.
// file: src/App.test.js:246-254
it('should handle special characters in email body', () => {
const data = {
email: 'test@test.com',
subject: 'Test & Demo',
body: 'Hello! How are you?',
};
const result = generateQRContent(QR_TYPES.EMAIL, data);
expect(result).toContain('subject=Test%20%26%20Demo');
expect(result).toContain('body=Hello!%20How%20are%20you%3F');
});
Sources: src/App.test.js:238-325