Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
</button>
</div>

<h1 class="text-5xl font-bold bg-gradient-to-r from-indigo-600 to-purple-600 bg-clip-text text-transparent mb-3">QR Code Generator v2.1.0</h1>
<h1 class="text-5xl font-bold bg-gradient-to-r from-indigo-600 to-purple-600 bg-clip-text text-transparent mb-3">QR Code Generator v2.2.0</h1>
<p class="text-gray-600 dark:text-gray-400" data-i18n="subtitle"></p>
<a href="https://github.com/j2teamnnl/qr-code-generator" target="_blank" class="inline-flex items-center gap-2 mt-3 text-sm text-gray-500 hover:text-indigo-600 transition">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
Expand Down
6 changes: 3 additions & 3 deletions js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ function setupEventListeners() {
const preview = document.getElementById('logoPreview');
if (preview) {
preview.classList.remove('hidden');
preview.innerHTML = '<p class="text-sm text-gray-500">⏳ Đang xử lý ảnh...</p>';
preview.innerHTML = `<p class="text-sm text-gray-500">${LanguageManager.translate('logo_processing')}</p>`;
}

try {
Expand All @@ -517,7 +517,7 @@ function setupEventListeners() {

if (preview) {
preview.classList.remove('hidden');
preview.innerHTML = '<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">✓ Ảnh đã được crop vuông:</p>';
preview.innerHTML = `<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">${LanguageManager.translate('logo_cropped')}</p>`;
preview.appendChild(img);
}

Expand All @@ -531,7 +531,7 @@ function setupEventListeners() {
ActivityLogger.log('Logo processing error', { error: error.message });
if (preview) {
preview.classList.remove('hidden');
preview.innerHTML = '<p class="text-sm text-red-500">❌ Lỗi xử lý ảnh</p>';
preview.innerHTML = `<p class="text-sm text-red-500">${LanguageManager.translate('logo_error')}</p>`;
}
}
});
Expand Down
51 changes: 38 additions & 13 deletions js/logger.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Activity Logger & Error Reporting System
import { LanguageManager } from './utils.js';

const ActivityLogger = {
logs: [],
Expand Down Expand Up @@ -126,10 +127,10 @@ const ActivityLogger = {
<div class="p-6 border-b border-gray-200 dark:border-gray-700">
<h2 class="text-2xl font-bold text-gray-800 dark:text-gray-100 flex items-center gap-3">
<span class="text-3xl">🐛</span>
<span>Báo Lỗi</span>
<span data-i18n-dynamic="error_report_title">${LanguageManager.translate('error_report_title')}</span>
</h2>
<p class="text-sm text-gray-600 dark:text-gray-400 mt-2">
Dưới đây là thông tin chi tiết về hoạt động của bạn. Hãy copy và gửi cho chúng tôi!
<p class="text-sm text-gray-600 dark:text-gray-400 mt-2" data-i18n-dynamic="error_report_desc">
${LanguageManager.translate('error_report_desc')}
</p>
</div>

Expand All @@ -150,13 +151,14 @@ const ActivityLogger = {
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
</svg>
Copy Báo Cáo
<span data-i18n-dynamic="error_report_copy">${LanguageManager.translate('error_report_copy')}</span>
</button>
<button
id="closeReportBtn"
class="px-6 py-3 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 font-semibold rounded-xl hover:bg-gray-300 dark:hover:bg-gray-600 transition-all"
data-i18n-dynamic="error_report_close"
>
Đóng
${LanguageManager.translate('error_report_close')}
</button>
</div>

Expand Down Expand Up @@ -188,6 +190,17 @@ const ActivityLogger = {

document.body.appendChild(modal);

// Update translations for dynamic content
const titleSpan = modal.querySelector('[data-i18n-dynamic="error_report_title"]');
const descP = modal.querySelector('[data-i18n-dynamic="error_report_desc"]');
const copySpan = modal.querySelector('[data-i18n-dynamic="error_report_copy"]');
const closeBtn = modal.querySelector('[data-i18n-dynamic="error_report_close"]');

if (titleSpan) titleSpan.textContent = LanguageManager.translate('error_report_title');
if (descP) descP.textContent = LanguageManager.translate('error_report_desc');
if (copySpan) copySpan.textContent = LanguageManager.translate('error_report_copy');
if (closeBtn) closeBtn.textContent = LanguageManager.translate('error_report_close');

// Event listeners
document.getElementById('copyReportBtn').addEventListener('click', () => {
const textarea = document.getElementById('errorReport');
Expand All @@ -197,7 +210,7 @@ const ActivityLogger = {
// Visual feedback
const btn = document.getElementById('copyReportBtn');
const originalText = btn.innerHTML;
btn.innerHTML = '<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg> Đã Copy!';
btn.innerHTML = `<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg> ${LanguageManager.translate('error_report_copied')}`;
setTimeout(() => {
btn.innerHTML = originalText;
}, 2000);
Expand All @@ -221,13 +234,25 @@ function createErrorReportButton() {
const button = document.createElement('button');
button.id = 'errorReportBtn';
button.className = 'fixed bottom-6 right-6 bg-gradient-to-r from-red-500 to-pink-600 hover:from-red-600 hover:to-pink-700 text-white font-bold p-4 rounded-full shadow-2xl transition-all transform hover:scale-110 z-40 flex items-center gap-2';
button.innerHTML = `
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
</svg>
<span class="hidden md:inline">Báo Lỗi</span>
`;
button.title = 'Báo lỗi hoặc gửi feedback';
const updateButtonText = () => {
button.innerHTML = `
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
</svg>
<span class="hidden md:inline">${LanguageManager.translate('error_report_button')}</span>
`;
button.title = LanguageManager.translate('error_report_button_title');
};
updateButtonText();

// Update button text when language changes
const originalUpdateUI = LanguageManager.updateUI;
LanguageManager.updateUI = function() {
originalUpdateUI.call(this);
if (document.getElementById('errorReportBtn')) {
updateButtonText();
}
};

button.addEventListener('click', () => {
ActivityLogger.log('Opened error report dialog');
Expand Down
9 changes: 5 additions & 4 deletions js/qr-generator.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// QR Code Generator & Styling
import { LanguageManager } from './utils.js';

const QRGenerator = {
canvas: null,
Expand Down Expand Up @@ -35,7 +36,7 @@ const QRGenerator = {
qrContainer.innerHTML = '';

if (!data) {
alert('Vui lòng nhập đầy đủ thông tin!');
alert(LanguageManager.translate('alert_please_fill'));
return;
}

Expand Down Expand Up @@ -84,7 +85,7 @@ const QRGenerator = {

document.getElementById('downloadSection').classList.remove('hidden');
} catch (error) {
alert('Dữ liệu quá dài! Vui lòng rút ngắn nội dung.');
alert(LanguageManager.translate('alert_data_too_long'));
console.error(error);
}
},
Expand Down Expand Up @@ -175,12 +176,12 @@ const QRGenerator = {
};
logo.onerror = () => {
console.error('Failed to load logo');
alert('Không thể tải logo. Vui lòng thử file khác.');
alert(LanguageManager.translate('alert_logo_load_failed'));
};
logo.src = URL.createObjectURL(croppedBlob);
}).catch((error) => {
console.error('Failed to crop image:', error);
alert('Không thể xử lý ảnh. Vui lòng thử file khác.');
alert(LanguageManager.translate('alert_image_process_failed'));
});
} else if (centerOption === 'text' && centerText) {
// SAFE SIZE: 18% of QR for text
Expand Down
40 changes: 40 additions & 0 deletions js/translations.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,26 @@ const translations = {
error_instagram_invalid: 'Vui lòng nhập username Instagram hoặc link profile',
error_telegram_invalid: 'Vui lòng nhập username Telegram',
error_spotify_invalid: 'Vui lòng nhập link Spotify hợp lệ',

// Alert messages
alert_please_fill: 'Vui lòng nhập đầy đủ thông tin!',
alert_data_too_long: 'Dữ liệu quá dài! Vui lòng rút ngắn nội dung.',
alert_logo_load_failed: 'Không thể tải logo. Vui lòng thử file khác.',
alert_image_process_failed: 'Không thể xử lý ảnh. Vui lòng thử file khác.',

// Logo processing messages
logo_processing: '⏳ Đang xử lý ảnh...',
logo_cropped: '✓ Ảnh đã được crop vuông:',
logo_error: '❌ Lỗi xử lý ảnh',

// Error report
error_report_title: 'Báo Lỗi',
error_report_desc: 'Dưới đây là thông tin chi tiết về hoạt động của bạn. Hãy copy và gửi cho chúng tôi!',
error_report_copy: 'Copy Báo Cáo',
error_report_close: 'Đóng',
error_report_copied: 'Đã Copy!',
error_report_button: 'Báo Lỗi',
error_report_button_title: 'Báo lỗi hoặc gửi feedback',
},
en: {
title: 'QR Code Generator',
Expand Down Expand Up @@ -149,6 +169,26 @@ const translations = {
error_instagram_invalid: 'Please enter Instagram username or profile link',
error_telegram_invalid: 'Please enter Telegram username',
error_spotify_invalid: 'Please enter valid Spotify link',

// Alert messages
alert_please_fill: 'Please fill in all required information!',
alert_data_too_long: 'Data is too long! Please shorten the content.',
alert_logo_load_failed: 'Failed to load logo. Please try another file.',
alert_image_process_failed: 'Failed to process image. Please try another file.',

// Logo processing messages
logo_processing: '⏳ Processing image...',
logo_cropped: '✓ Image cropped to square:',
logo_error: '❌ Image processing error',

// Error report
error_report_title: 'Error Report',
error_report_desc: 'Below is detailed information about your activity. Please copy and send it to us!',
error_report_copy: 'Copy Report',
error_report_close: 'Close',
error_report_copied: 'Copied!',
error_report_button: 'Report Error',
error_report_button_title: 'Report error or send feedback',
},
};

Expand Down
Loading