import React, { useState, useEffect, useRef } from 'react'; import { QrCode, Link, MessageSquare, User, Wifi, Download, Copy, Check } from 'lucide-react'; const TRANSLATIONS = { "de-DE": { "appTitle": "QR-Code Generator", "appDescription": "Erstelle QR-Codes für URLs, Text und Kontaktinformationen", "urlTab": "URL", "textTab": "Text", "contactTab": "Kontakt", "wifiTab": "WLAN", "enterUrl": "URL eingeben", "enterText": "Text eingeben", "contactInformation": "Kontaktinformationen", "wifiConfiguration": "WLAN-Konfiguration", "websiteUrl": "Website-URL", "urlPlaceholder": "beispiel.de oder https://beispiel.de", "urlHelp": "Geben Sie eine Website-URL ein. Falls Sie http:// weglassen, fügen wir automatisch https:// hinzu.", "textContent": "Textinhalt", "textPlaceholder": "Beliebigen Text eingeben um QR-Code zu erstellen...", "firstName": "Vorname", "firstNamePlaceholder": "Max", "lastName": "Nachname", "lastNamePlaceholder": "Mustermann", "phoneNumber": "Telefonnummer", "phonePlaceholder": "+49 (0) 123 456789", "emailAddress": "E-Mail-Adresse", "emailPlaceholder": "max.mustermann@beispiel.de", "organization": "Organisation", "organizationPlaceholder": "Firmenname", "website": "Website", "websitePlaceholder": "https://beispiel.de", "clearAllFields": "Alle Felder löschen", "networkName": "Netzwerkname (SSID)", "networkNamePlaceholder": "Mein WLAN-Netzwerk", "password": "Passwort", "passwordPlaceholder": "WLAN-Passwort", "securityType": "Sicherheitstyp", "hidden": "Verstecktes Netzwerk", "hiddenHelp": "Ankreuzen, falls dies ein verstecktes Netzwerk ist", "generatedQrCode": "Generierter QR-Code", "scanQrCode": "Scannen Sie diesen QR-Code mit Ihrem Gerät", "fillFormPrompt": "Füllen Sie das Formular aus, um Ihren QR-Code zu erstellen", "download": "Herunterladen", "copyData": "Daten kopieren", "copied": "Kopiert!", "qrCodeData": "QR-Code Daten:", "footerText": "QR-Codes sofort erstellen • Keine Datenspeicherung • Kostenlos", "qrCodeAlt": "Generierter QR-Code" }, "en-US": { "appTitle": "QR Code Generator", "appDescription": "Generate QR codes for URLs, text, and contact information", "urlTab": "URL", "textTab": "Text", "contactTab": "Contact", "wifiTab": "WiFi", "enterUrl": "Enter URL", "enterText": "Enter Text", "contactInformation": "Contact Information", "wifiConfiguration": "WiFi Configuration", "websiteUrl": "Website URL", "urlPlaceholder": "example.com or https://example.com", "urlHelp": "Enter a website URL. If you don't include http://, we'll add https:// automatically.", "textContent": "Text Content", "textPlaceholder": "Enter any text to generate QR code...", "firstName": "First Name", "firstNamePlaceholder": "John", "lastName": "Last Name", "lastNamePlaceholder": "Doe", "phoneNumber": "Phone Number", "phonePlaceholder": "+1 (555) 123-4567", "emailAddress": "Email Address", "emailPlaceholder": "john.doe@example.com", "organization": "Organization", "organizationPlaceholder": "Company Name", "website": "Website", "websitePlaceholder": "https://example.com", "clearAllFields": "Clear All Fields", "networkName": "Network Name (SSID)", "networkNamePlaceholder": "My WiFi Network", "password": "Password", "passwordPlaceholder": "WiFi password", "securityType": "Security Type", "hidden": "Hidden Network", "hiddenHelp": "Check if this is a hidden network", "generatedQrCode": "Generated QR Code", "scanQrCode": "Scan this QR code with your device", "fillFormPrompt": "Fill in the form to generate your QR code", "download": "Download", "copyData": "Copy Data", "copied": "Copied!", "qrCodeData": "QR Code Data:", "footerText": "Generate QR codes instantly • No data stored • Free to use", "qrCodeAlt": "Generated QR Code" }, "es-ES": { "appTitle": "Generador de Códigos QR", "appDescription": "Genera códigos QR para URLs, texto e información de contacto", "urlTab": "URL", "textTab": "Texto", "contactTab": "Contacto", "wifiTab": "WiFi", "enterUrl": "Ingresa URL", "enterText": "Ingresa Texto", "contactInformation": "Información de Contacto", "wifiConfiguration": "Configuración WiFi", "websiteUrl": "URL del Sitio Web", "urlPlaceholder": "ejemplo.com o https://ejemplo.com", "urlHelp": "Ingresa una URL de sitio web. Si no incluyes http://, agregaremos https:// automáticamente.", "textContent": "Contenido de Texto", "textPlaceholder": "Ingresa cualquier texto para generar código QR...", "firstName": "Nombre", "firstNamePlaceholder": "Juan", "lastName": "Apellido", "lastNamePlaceholder": "Pérez", "phoneNumber": "Número de Teléfono", "phonePlaceholder": "+1 (555) 123-4567", "emailAddress": "Dirección de Correo", "emailPlaceholder": "juan.perez@ejemplo.com", "organization": "Organización", "organizationPlaceholder": "Nombre de la Empresa", "website": "Sitio Web", "websitePlaceholder": "https://ejemplo.com", "clearAllFields": "Limpiar Todos los Campos", "networkName": "Nombre de Red (SSID)", "networkNamePlaceholder": "Mi Red WiFi", "password": "Contraseña", "passwordPlaceholder": "Contraseña WiFi", "securityType": "Tipo de Seguridad", "hidden": "Red Oculta", "hiddenHelp": "Marcar si esta es una red oculta", "generatedQrCode": "Código QR Generado", "scanQrCode": "Escanea este código QR con tu dispositivo", "fillFormPrompt": "Completa el formulario para generar tu código QR", "download": "Descargar", "copyData": "Copiar Datos", "copied": "¡Copiado!", "qrCodeData": "Datos del Código QR:", "footerText": "Genera códigos QR al instante • No se almacenan datos • Gratis", "qrCodeAlt": "Código QR Generado" } }; const appLocale = '{{APP_LOCALE}}'; const browserLocale = navigator.languages?.[0] || navigator.language || 'en-US'; const findMatchingLocale = (locale) => { if (TRANSLATIONS[locale]) return locale; const lang = locale.split('-')[0]; const match = Object.keys(TRANSLATIONS).find(key => key.startsWith(lang + '-')); return match || 'en-US'; }; const locale = (appLocale !== '{{APP_LOCALE}}') ? findMatchingLocale(appLocale) : findMatchingLocale(browserLocale); // Standardmäßig auf Deutsch setzen const defaultLocale = 'de-DE'; const t = (key) => TRANSLATIONS[locale]?.[key] || TRANSLATIONS[defaultLocale]?.[key] || TRANSLATIONS['en-US']?.[key] || key; const QRCodeGenerator = () => { const [activeTab, setActiveTab] = useState('url'); const [qrData, setQrData] = useState(''); const [copied, setCopied] = useState(false); const qrContainerRef = useRef(null); // Form states for different types const [urlInput, setUrlInput] = useState(''); const [textInput, setTextInput] = useState(''); const [contactInfo, setContactInfo] = useState({ firstName: '', lastName: '', phone: '', email: '', organization: '', url: '' }); const [wifiInfo, setWifiInfo] = useState({ ssid: '', password: '', security: 'WPA', hidden: false }); // QR Code generation using QRious library via CDN const generateQRCode = async (text) => { if (!text.trim()) { if (qrContainerRef.current) { qrContainerRef.current.innerHTML = ''; } return; } try { // Load QRious library dynamically if (!window.QRious) { const script = document.createElement('script'); script.src = 'https://cdnjs.cloudflare.com/ajax/libs/qrious/4.0.2/qrious.min.js'; script.onload = () => { createQR(text); }; document.head.appendChild(script); } else { createQR(text); } } catch (error) { console.error('Error loading QR library:', error); // Fallback to Google Charts API generateFallbackQR(text); } }; const createQR = (text) => { if (!qrContainerRef.current) return; try { // Clear previous QR code qrContainerRef.current.innerHTML = ''; // Create canvas element const canvas = document.createElement('canvas'); qrContainerRef.current.appendChild(canvas); // Generate QR code const qr = new window.QRious({ element: canvas, value: text, size: 300, background: 'white', foreground: 'black', level: 'M' }); // Style the canvas canvas.className = 'w-full h-auto rounded-xl shadow-lg bg-white'; canvas.style.maxWidth = '300px'; canvas.style.height = 'auto'; } catch (error) { console.error('Error creating QR code:', error); generateFallbackQR(text); } }; const generateFallbackQR = (text) => { if (!qrContainerRef.current) return; // Clear previous content qrContainerRef.current.innerHTML = ''; // Create img element for fallback const img = document.createElement('img'); const encodedData = encodeURIComponent(text); img.src = `https://chart.googleapis.com/chart?chs=300x300&cht=qr&chl=${encodedData}&choe=UTF-8`; img.alt = t('qrCodeAlt'); img.className = 'w-full h-auto rounded-xl shadow-lg bg-white p-4'; img.style.maxWidth = '300px'; img.style.height = 'auto'; // Add error handling for the fallback image img.onerror = () => { // If Google Charts also fails, try QR Server API img.src = `https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${encodedData}&format=png&margin=10`; }; qrContainerRef.current.appendChild(img); }; const formatUrl = (url) => { if (!url.trim()) return ''; // Add protocol if missing if (!url.startsWith('http://') && !url.startsWith('https://')) { return 'https://' + url; } return url; }; const generateVCard = (contact) => { const vcard = `BEGIN:VCARD VERSION:3.0 FN:${contact.firstName} ${contact.lastName} N:${contact.lastName};${contact.firstName};;; ORG:${contact.organization} TEL:${contact.phone} EMAIL:${contact.email} URL:${contact.url} END:VCARD`; return vcard; }; const generateWiFiQR = (wifi) => { // WiFi QR code format: WIFI:T:WPA;S:mynetwork;P:mypass;H:false;; const security = wifi.security || 'WPA'; const hidden = wifi.hidden ? 'true' : 'false'; return `WIFI:T:${security};S:${wifi.ssid};P:${wifi.password};H:${hidden};;`; }; useEffect(() => { let data = ''; switch (activeTab) { case 'url': data = formatUrl(urlInput); break; case 'text': data = textInput; break; case 'contact': if (contactInfo.firstName || contactInfo.lastName || contactInfo.phone || contactInfo.email) { data = generateVCard(contactInfo); } break; case 'wifi': if (wifiInfo.ssid) { data = generateWiFiQR(wifiInfo); } break; default: data = ''; } setQrData(data); generateQRCode(data); }, [activeTab, urlInput, textInput, contactInfo, wifiInfo]); const downloadQRCode = () => { if (!qrData) return; const canvas = qrContainerRef.current?.querySelector('canvas'); const img = qrContainerRef.current?.querySelector('img'); if (canvas) { // Download from canvas const link = document.createElement('a'); link.download = `qr-code-${activeTab}.png`; link.href = canvas.toDataURL(); link.click(); } else if (img) { // Download from image const link = document.createElement('a'); link.download = `qr-code-${activeTab}.png`; link.href = img.src; link.click(); } }; const copyToClipboard = async () => { if (qrData) { try { await navigator.clipboard.writeText(qrData); setCopied(true); setTimeout(() => setCopied(false), 2000); } catch (err) { console.error('Failed to copy text: ', err); } } }; const resetForm = () => { setUrlInput(''); setTextInput(''); setContactInfo({ firstName: '', lastName: '', phone: '', email: '', organization: '', url: '' }); setWifiInfo({ ssid: '', password: '', security: 'WPA', hidden: false }); setQrData(''); if (qrContainerRef.current) { qrContainerRef.current.innerHTML = ''; } }; const tabs = [ { id: 'url', label: t('urlTab'), icon: Link }, { id: 'text', label: t('textTab'), icon: MessageSquare }, { id: 'contact', label: t('contactTab'), icon: User }, { id: 'wifi', label: t('wifiTab'), icon: Wifi } ]; return (

{t('appTitle')}

{t('appDescription')}

{/* Tab Navigation */}
{/* Input Section */}

{activeTab === 'url' && t('enterUrl')} {activeTab === 'text' && t('enterText')} {activeTab === 'contact' && t('contactInformation')} {activeTab === 'wifi' && t('wifiConfiguration')}

{/* URL Input */} {activeTab === 'url' && (
setUrlInput(e.target.value)} placeholder={t('urlPlaceholder')} className="w-full px-4 py-3 border border-red-800 rounded-lg focus:ring-2 focus:ring-red-800 focus:border-transparent transition-all duration-200" />

{t('urlHelp')}

)} {/* WiFi Input */} {activeTab === 'wifi' && (
setWifiInfo({...wifiInfo, ssid: e.target.value})} placeholder={t('networkNamePlaceholder')} className="w-full px-4 py-3 border border-red-800 rounded-lg focus:ring-2 focus:ring-red-800 focus:border-transparent transition-all duration-200" />
setWifiInfo({...wifiInfo, password: e.target.value})} placeholder={t('passwordPlaceholder')} className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-purple-500 focus:border-transparent transition-all duration-200" />
setWifiInfo({...wifiInfo, hidden: e.target.checked})} className="w-4 h-4 text-red-800 bg-gray-100 border-red-800 rounded focus:ring-red-800 focus:ring-2" />

{t('hiddenHelp')}

)} {/* Text Input */} {activeTab === 'text' && (