Update src/App.jsx
Browse files- src/App.jsx +26 -35
src/App.jsx
CHANGED
|
@@ -23,13 +23,11 @@ const CustomAlert = ({ message, onClose }) => {
|
|
| 23 |
|
| 24 |
// Main App component
|
| 25 |
const App = () => {
|
| 26 |
-
// console.log("App component is loading!"); // Keep this line for now, for debugging
|
| 27 |
-
|
| 28 |
const [activeTab, setActiveTab] = useState('generator');
|
| 29 |
const [content, setContent] = useState('');
|
| 30 |
const [errorLevel, setErrorLevel] = useState('L');
|
| 31 |
-
const [qrColor, setQrColor] = useState('#000000'); // Default QR color
|
| 32 |
-
const [decodedContent, setDecodedContent] = useState('');
|
| 33 |
const [selectedStyleIndex, setSelectedStyleIndex] = useState(0);
|
| 34 |
const [currentTheme, setCurrentTheme] = useState('dark'); // Default theme
|
| 35 |
const [isSummarizing, setIsSummarizing] = useState(false); // Loading state for summarization
|
|
@@ -39,8 +37,7 @@ const App = () => {
|
|
| 39 |
const [alertMessage, setAlertMessage] = useState(null); // State for custom alert message
|
| 40 |
|
| 41 |
const qrCanvasRef = useRef(null); // Ref for the main QR code canvas
|
| 42 |
-
// Use an array of refs for style preview canvases
|
| 43 |
-
const styleCanvasRefs = useRef(Array(12).fill(null));
|
| 44 |
|
| 45 |
// Define QR code styles (mimicking the Python app's styles)
|
| 46 |
const qrStyles = [
|
|
@@ -80,7 +77,6 @@ const App = () => {
|
|
| 80 |
cardBorder: 'border-white/10',
|
| 81 |
qrPreviewBorder: 'border-blue-500/50',
|
| 82 |
qrPreviewBg: 'bg-gradient-to-br from-gray-900/30 to-gray-800/30 backdrop-blur-md',
|
| 83 |
-
// Enhanced rainbow glow for header
|
| 84 |
headerGlow: 'from-purple-500 via-pink-500 to-yellow-500 animate-rainbow-glow'
|
| 85 |
},
|
| 86 |
light: {
|
|
@@ -136,7 +132,7 @@ const App = () => {
|
|
| 136 |
glassBorder: 'border-blue-800/20',
|
| 137 |
shadow: 'shadow-blue-600/20',
|
| 138 |
glow: 'shadow-lg shadow-blue-600/40',
|
| 139 |
-
buttonGlow: 'hover:shadow-xl hover:shadow-blue-500/50',
|
| 140 |
success: 'text-sky-400',
|
| 141 |
alert: 'text-red-400',
|
| 142 |
inputBg: 'bg-blue-950/30',
|
|
@@ -202,7 +198,7 @@ const App = () => {
|
|
| 202 |
glassBorder: 'border-orange-700/20',
|
| 203 |
shadow: 'shadow-orange-600/20',
|
| 204 |
glow: 'shadow-lg shadow-orange-600/40',
|
| 205 |
-
buttonGlow: 'hover:shadow-xl hover:shadow-orange-500/50',
|
| 206 |
success: 'text-lime-400',
|
| 207 |
alert: 'text-red-400',
|
| 208 |
inputBg: 'bg-orange-900/30',
|
|
@@ -241,28 +237,27 @@ const App = () => {
|
|
| 241 |
return;
|
| 242 |
}
|
| 243 |
|
| 244 |
-
|
| 245 |
-
|
| 246 |
-
|
| 247 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 248 |
}
|
| 249 |
-
|
| 250 |
-
QRCode.toCanvas(canvas, text, {
|
| 251 |
-
errorCorrectionLevel: errorLevel,
|
| 252 |
-
width: size,
|
| 253 |
-
color: {
|
| 254 |
-
dark: color, // Use the provided color directly
|
| 255 |
-
light: '#FFFFFF'
|
| 256 |
-
}
|
| 257 |
-
}, function (error) {
|
| 258 |
-
if (error) console.error("QR Code drawing error:", error);
|
| 259 |
-
});
|
| 260 |
}, []); // Dependencies are stable (QRCode)
|
| 261 |
|
| 262 |
// Effect to generate QR code on the main canvas (Generator Tab)
|
| 263 |
useEffect(() => {
|
| 264 |
-
// This effect will run whenever content, qrColor, errorLevel, or drawQrCode changes.
|
| 265 |
-
// drawQrCode is memoized, so it only changes if QRCode itself changes (unlikely after initial load).
|
| 266 |
drawQrCode(qrCanvasRef.current, content, qrColor, errorLevel);
|
| 267 |
}, [content, qrColor, errorLevel, drawQrCode]);
|
| 268 |
|
|
@@ -270,11 +265,9 @@ const App = () => {
|
|
| 270 |
useEffect(() => {
|
| 271 |
qrStyles.forEach((style, index) => {
|
| 272 |
const canvas = styleCanvasRefs.current[index];
|
| 273 |
-
// Draw a sample QR code for each style preview
|
| 274 |
-
// Pass the style's foreground color directly
|
| 275 |
drawQrCode(canvas, "Sample", style.fg, 'H', 80);
|
| 276 |
});
|
| 277 |
-
}, [qrStyles, drawQrCode]);
|
| 278 |
|
| 279 |
// Function to download the generated QR code
|
| 280 |
const downloadQrCode = () => {
|
|
@@ -451,7 +444,7 @@ const App = () => {
|
|
| 451 |
) : (
|
| 452 |
<i className="fas fa-magic mr-2"></i>
|
| 453 |
)}
|
| 454 |
-
✨ {isSummarizing ? '
|
| 455 |
</button>
|
| 456 |
<button
|
| 457 |
className={`w-full sm:w-1/2 py-3 px-6 rounded-xl font-bold text-lg bg-gradient-to-r ${currentThemeClasses.secondaryAccent} text-white shadow-lg ${currentThemeClasses.buttonGlow} transform hover:-translate-y-1 transition-all duration-300 ease-in-out flex items-center justify-center`}
|
|
@@ -509,11 +502,9 @@ const App = () => {
|
|
| 509 |
${currentThemeClasses.inputBg}`}
|
| 510 |
onClick={() => {
|
| 511 |
setSelectedStyleIndex(index);
|
| 512 |
-
//
|
| 513 |
-
setQrColor(style.fg);
|
| 514 |
}}
|
| 515 |
>
|
| 516 |
-
{/* Use a ref for each canvas in the map */}
|
| 517 |
<canvas ref={el => styleCanvasRefs.current[index] = el} width="80" height="80" className="rounded-lg"></canvas>
|
| 518 |
<span className={`mt-2 text-sm font-medium ${currentThemeClasses.labelColor} font-inter`}>{style.name}</span>
|
| 519 |
</div>
|
|
@@ -551,8 +542,9 @@ const App = () => {
|
|
| 551 |
<textarea
|
| 552 |
className={`w-full p-3 rounded-xl border ${currentThemeClasses.inputBorder} ${currentThemeClasses.inputBg} ${currentThemeClasses.text} focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all duration-300 font-inter`}
|
| 553 |
rows="8"
|
| 554 |
-
readOnly
|
| 555 |
value={decodedContent}
|
|
|
|
| 556 |
placeholder="Decoded content will appear here..."
|
| 557 |
></textarea>
|
| 558 |
|
|
@@ -612,7 +604,6 @@ const App = () => {
|
|
| 612 |
);
|
| 613 |
|
| 614 |
return (
|
| 615 |
-
// The main div for the application, no script or style tags here
|
| 616 |
<div className={`min-h-screen font-inter antialiased ${currentThemeClasses.bg} ${currentThemeClasses.text} transition-all duration-500 ease-in-out`}>
|
| 617 |
<div className="container mx-auto p-4 max-w-7xl">
|
| 618 |
<h1 className={`text-4xl lg:text-5xl font-extrabold text-center mb-8 bg-clip-text text-transparent bg-gradient-to-r ${currentThemeClasses.headerGlow} font-orbitron`}>
|
|
|
|
| 23 |
|
| 24 |
// Main App component
|
| 25 |
const App = () => {
|
|
|
|
|
|
|
| 26 |
const [activeTab, setActiveTab] = useState('generator');
|
| 27 |
const [content, setContent] = useState('');
|
| 28 |
const [errorLevel, setErrorLevel] = useState('L');
|
| 29 |
+
const [qrColor, setQrColor] = useState('#000000'); // Default QR color, will be updated by style selection
|
| 30 |
+
const [decodedContent, setDecodedContent] = useState(''); // Decoded content state
|
| 31 |
const [selectedStyleIndex, setSelectedStyleIndex] = useState(0);
|
| 32 |
const [currentTheme, setCurrentTheme] = useState('dark'); // Default theme
|
| 33 |
const [isSummarizing, setIsSummarizing] = useState(false); // Loading state for summarization
|
|
|
|
| 37 |
const [alertMessage, setAlertMessage] = useState(null); // State for custom alert message
|
| 38 |
|
| 39 |
const qrCanvasRef = useRef(null); // Ref for the main QR code canvas
|
| 40 |
+
const styleCanvasRefs = useRef(Array(12).fill(null)); // Use an array of refs for style preview canvases
|
|
|
|
| 41 |
|
| 42 |
// Define QR code styles (mimicking the Python app's styles)
|
| 43 |
const qrStyles = [
|
|
|
|
| 77 |
cardBorder: 'border-white/10',
|
| 78 |
qrPreviewBorder: 'border-blue-500/50',
|
| 79 |
qrPreviewBg: 'bg-gradient-to-br from-gray-900/30 to-gray-800/30 backdrop-blur-md',
|
|
|
|
| 80 |
headerGlow: 'from-purple-500 via-pink-500 to-yellow-500 animate-rainbow-glow'
|
| 81 |
},
|
| 82 |
light: {
|
|
|
|
| 132 |
glassBorder: 'border-blue-800/20',
|
| 133 |
shadow: 'shadow-blue-600/20',
|
| 134 |
glow: 'shadow-lg shadow-blue-600/40',
|
| 135 |
+
buttonGlow: 'hover:shadow-xl hover:hover:shadow-blue-500/50',
|
| 136 |
success: 'text-sky-400',
|
| 137 |
alert: 'text-red-400',
|
| 138 |
inputBg: 'bg-blue-950/30',
|
|
|
|
| 198 |
glassBorder: 'border-orange-700/20',
|
| 199 |
shadow: 'shadow-orange-600/20',
|
| 200 |
glow: 'shadow-lg shadow-orange-600/40',
|
| 201 |
+
buttonGlow: 'hover:shadow-xl hover:hover:shadow-orange-500/50',
|
| 202 |
success: 'text-lime-400',
|
| 203 |
alert: 'text-red-400',
|
| 204 |
inputBg: 'bg-orange-900/30',
|
|
|
|
| 237 |
return;
|
| 238 |
}
|
| 239 |
|
| 240 |
+
// Clear canvas before drawing new QR code
|
| 241 |
+
const context = canvas.getContext('2d');
|
| 242 |
+
context.clearRect(0, 0, canvas.width, canvas.height);
|
| 243 |
+
|
| 244 |
+
// Only draw if text content is not empty
|
| 245 |
+
if (text.trim() !== '') {
|
| 246 |
+
QRCode.toCanvas(canvas, text, {
|
| 247 |
+
errorCorrectionLevel: errorLevel,
|
| 248 |
+
width: size,
|
| 249 |
+
color: {
|
| 250 |
+
dark: color, // Use the provided color directly
|
| 251 |
+
light: '#FFFFFF'
|
| 252 |
+
}
|
| 253 |
+
}, function (error) {
|
| 254 |
+
if (error) console.error("QR Code drawing error:", error);
|
| 255 |
+
});
|
| 256 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 257 |
}, []); // Dependencies are stable (QRCode)
|
| 258 |
|
| 259 |
// Effect to generate QR code on the main canvas (Generator Tab)
|
| 260 |
useEffect(() => {
|
|
|
|
|
|
|
| 261 |
drawQrCode(qrCanvasRef.current, content, qrColor, errorLevel);
|
| 262 |
}, [content, qrColor, errorLevel, drawQrCode]);
|
| 263 |
|
|
|
|
| 265 |
useEffect(() => {
|
| 266 |
qrStyles.forEach((style, index) => {
|
| 267 |
const canvas = styleCanvasRefs.current[index];
|
|
|
|
|
|
|
| 268 |
drawQrCode(canvas, "Sample", style.fg, 'H', 80);
|
| 269 |
});
|
| 270 |
+
}, [qrStyles, drawQrCode]);
|
| 271 |
|
| 272 |
// Function to download the generated QR code
|
| 273 |
const downloadQrCode = () => {
|
|
|
|
| 444 |
) : (
|
| 445 |
<i className="fas fa-magic mr-2"></i>
|
| 446 |
)}
|
| 447 |
+
✨ {isSummarizing ? 'Summarize Content...' : 'Summarize Content'}
|
| 448 |
</button>
|
| 449 |
<button
|
| 450 |
className={`w-full sm:w-1/2 py-3 px-6 rounded-xl font-bold text-lg bg-gradient-to-r ${currentThemeClasses.secondaryAccent} text-white shadow-lg ${currentThemeClasses.buttonGlow} transform hover:-translate-y-1 transition-all duration-300 ease-in-out flex items-center justify-center`}
|
|
|
|
| 502 |
${currentThemeClasses.inputBg}`}
|
| 503 |
onClick={() => {
|
| 504 |
setSelectedStyleIndex(index);
|
| 505 |
+
setQrColor(style.fg); // Update color picker with selected style's color
|
|
|
|
| 506 |
}}
|
| 507 |
>
|
|
|
|
| 508 |
<canvas ref={el => styleCanvasRefs.current[index] = el} width="80" height="80" className="rounded-lg"></canvas>
|
| 509 |
<span className={`mt-2 text-sm font-medium ${currentThemeClasses.labelColor} font-inter`}>{style.name}</span>
|
| 510 |
</div>
|
|
|
|
| 542 |
<textarea
|
| 543 |
className={`w-full p-3 rounded-xl border ${currentThemeClasses.inputBorder} ${currentThemeClasses.inputBg} ${currentThemeClasses.text} focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all duration-300 font-inter`}
|
| 544 |
rows="8"
|
| 545 |
+
// Removed readOnly attribute to allow manual editing
|
| 546 |
value={decodedContent}
|
| 547 |
+
onChange={(e) => setDecodedContent(e.target.value)} // Added onChange handler for manual editing
|
| 548 |
placeholder="Decoded content will appear here..."
|
| 549 |
></textarea>
|
| 550 |
|
|
|
|
| 604 |
);
|
| 605 |
|
| 606 |
return (
|
|
|
|
| 607 |
<div className={`min-h-screen font-inter antialiased ${currentThemeClasses.bg} ${currentThemeClasses.text} transition-all duration-500 ease-in-out`}>
|
| 608 |
<div className="container mx-auto p-4 max-w-7xl">
|
| 609 |
<h1 className={`text-4xl lg:text-5xl font-extrabold text-center mb-8 bg-clip-text text-transparent bg-gradient-to-r ${currentThemeClasses.headerGlow} font-orbitron`}>
|