From a6fc0b5448bd0d135d7ba9a312f1555b39022a33 Mon Sep 17 00:00:00 2001 From: Taltos-ch Date: Mon, 17 Feb 2025 07:46:21 +0100 Subject: [PATCH] added Contact QR Code Generator --- components.d.ts | 1 + src/tools/index.ts | 1 + .../contact-info-qr-code-generator.ts | 49 ------ .../contact-info-qr-code-generator.vue | 160 ------------------ src/tools/qr-contact-info-generator/index.ts | 16 +- .../qr-contact-info-generator.ts | 56 ++++++ .../qr-contact-info-generator.vue | 77 +++++++++ 7 files changed, 147 insertions(+), 213 deletions(-) delete mode 100644 src/tools/qr-contact-info-generator/contact-info-qr-code-generator.ts delete mode 100644 src/tools/qr-contact-info-generator/contact-info-qr-code-generator.vue create mode 100644 src/tools/qr-contact-info-generator/qr-contact-info-generator.ts create mode 100644 src/tools/qr-contact-info-generator/qr-contact-info-generator.vue diff --git a/components.d.ts b/components.d.ts index 3e65c3cc..b87945f8 100644 --- a/components.d.ts +++ b/components.d.ts @@ -151,6 +151,7 @@ declare module '@vue/runtime-core' { PercentageCalculator: typeof import('./src/tools/percentage-calculator/percentage-calculator.vue')['default'] PhoneParserAndFormatter: typeof import('./src/tools/phone-parser-and-formatter/phone-parser-and-formatter.vue')['default'] QrCodeGenerator: typeof import('./src/tools/qr-code-generator/qr-code-generator.vue')['default'] + ContactQRCodeGenerator: typeof import('./src/tools/qr-contact-info-generator/qr-contact-info-generator.vue')['default'] RandomPortGenerator: typeof import('./src/tools/random-port-generator/random-port-generator.vue')['default'] RegexMemo: typeof import('./src/tools/regex-memo/regex-memo.vue')['default'] 'RegexMemo.content': typeof import('./src/tools/regex-memo/regex-memo.content.md')['default'] diff --git a/src/tools/index.ts b/src/tools/index.ts index 388cfaf4..c4be5a1e 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -1,6 +1,7 @@ import { tool as base64FileConverter } from './base64-file-converter'; import { tool as base64StringConverter } from './base64-string-converter'; import { tool as basicAuthGenerator } from './basic-auth-generator'; +import { tool as qrContactInfoGenerator } from './qr-contact-info-generator'; import { tool as emailNormalizer } from './email-normalizer'; import { tool as asciiTextDrawer } from './ascii-text-drawer'; diff --git a/src/tools/qr-contact-info-generator/contact-info-qr-code-generator.ts b/src/tools/qr-contact-info-generator/contact-info-qr-code-generator.ts deleted file mode 100644 index 1b17d371..00000000 --- a/src/tools/qr-contact-info-generator/contact-info-qr-code-generator.ts +++ /dev/null @@ -1,49 +0,0 @@ -import QRCode from 'qrcode'; - -interface ContactInfo { - firstName: string; - lastName: string; - role: string; - phoneNumber: string; - email: string; - companyName: string; - companyWebsite: string; - companyAddress: string; -} - -const generateContactInfoQRCode = (contactInfo: ContactInfo): void => { - const vCard = ` -BEGIN:VCARD -VERSION:3.0 -N:${contactInfo.lastName};${contactInfo.firstName} -FN:${contactInfo.firstName} ${contactInfo.lastName} -ORG:${contactInfo.companyName} -TITLE:${contactInfo.role} -TEL;TYPE=WORK,VOICE:${contactInfo.phoneNumber} -EMAIL;TYPE=PREF,INTERNET:${contactInfo.email} -URL:${contactInfo.companyWebsite} -ADR;TYPE=WORK,PREF:;;${contactInfo.companyAddress} -END:VCARD - `; - - QRCode.toDataURL(vCard, { errorCorrectionLevel: 'H' }, (err: Error | null, url: string) => { - if (err) { - console.error(err); - return; - } - console.log(url); - }); -}; - -const contactInfo: ContactInfo = { - firstName: 'John', - lastName: 'Doe', - role: 'Software Engineer', - phoneNumber: '+1234567890', - email: 'john.doe@example.com', - companyName: 'Example Inc.', - companyWebsite: 'https://www.example.com', - companyAddress: '123 Example Street, City, Country' -}; - -generateContactInfoQRCode(contactInfo); \ No newline at end of file diff --git a/src/tools/qr-contact-info-generator/contact-info-qr-code-generator.vue b/src/tools/qr-contact-info-generator/contact-info-qr-code-generator.vue deleted file mode 100644 index 46eb10d9..00000000 --- a/src/tools/qr-contact-info-generator/contact-info-qr-code-generator.vue +++ /dev/null @@ -1,160 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/tools/qr-contact-info-generator/index.ts b/src/tools/qr-contact-info-generator/index.ts index fd467b19..ce087fad 100644 --- a/src/tools/qr-contact-info-generator/index.ts +++ b/src/tools/qr-contact-info-generator/index.ts @@ -1,5 +1,13 @@ -import ContactInfoQRCodeGenerator from './contact-info-qr-code-generator.vue'; +import { Qrcode } from '@vicons/tabler'; +import { defineTool } from '../tool'; +import { translate } from '@/plugins/i18n.plugin'; -export { - ContactInfoQRCodeGenerator, -}; \ No newline at end of file +export const tool = defineTool({ + name: translate('tools.qr-contact-info-generator.title'), + path: '/qr-contact-info-generator', + description: translate('tools.qr-contact-info-generator.description'), + keywords: ['qr', 'contact', 'info', 'generator'], + component: () => import('./qr-contact-info-generator.vue'), + icon: Qrcode, + createdAt: new Date('2025-02-17'), +}); \ No newline at end of file diff --git a/src/tools/qr-contact-info-generator/qr-contact-info-generator.ts b/src/tools/qr-contact-info-generator/qr-contact-info-generator.ts new file mode 100644 index 00000000..9ce894e4 --- /dev/null +++ b/src/tools/qr-contact-info-generator/qr-contact-info-generator.ts @@ -0,0 +1,56 @@ +import { type MaybeRef, get } from '@vueuse/core'; +import QRCode, { type QRCodeErrorCorrectionLevel, type QRCodeToDataURLOptions } from 'qrcode'; +import { isRef, ref, watch } from 'vue'; + +interface ContactInfo { + firstName: string; + lastName: string; + jobRole: string; + phoneNumber: string; + emailAddress: string; + companyName: string; + companyWebsite: string; + companyAddress: string; +} + +interface QRCodeOptions { + foregroundColor?: string; + backgroundColor?: string; +} + +export function generateContactQRCode(contact: MaybeRef, options: MaybeRef = {}): Promise { + const vCard = ref(` +BEGIN:VCARD +VERSION:3.0 +FN:${get(contact).firstName} ${get(contact).lastName} +ORG:${get(contact).companyName} +TITLE:${get(contact).jobRole} +TEL:${get(contact).phoneNumber} +EMAIL:${get(contact).emailAddress} +URL:${get(contact).companyWebsite} +ADR:${get(contact).companyAddress} +END:VCARD + `); + + const qrOptions: QRCodeToDataURLOptions = { + errorCorrectionLevel: 'H' as QRCodeErrorCorrectionLevel, + type: 'image/png', + margin: 1, + color: { + dark: get(options).foregroundColor || '#000000ff', + light: get(options).backgroundColor || '#ffffffff', + }, + }; + + const qrCodeDataUrl = ref(''); + + watch( + [vCard, options].filter(isRef), + async () => { + qrCodeDataUrl.value = await QRCode.toDataURL(get(vCard), qrOptions); + }, + { immediate: true }, + ); + + return qrCodeDataUrl.value; +} \ No newline at end of file diff --git a/src/tools/qr-contact-info-generator/qr-contact-info-generator.vue b/src/tools/qr-contact-info-generator/qr-contact-info-generator.vue new file mode 100644 index 00000000..b61dfe61 --- /dev/null +++ b/src/tools/qr-contact-info-generator/qr-contact-info-generator.vue @@ -0,0 +1,77 @@ + + + + + \ No newline at end of file