Adding the skeleton QR code

This commit is contained in:
2026-03-14 00:24:58 -04:00
commit 6ce0fc0768
27 changed files with 7628 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
import React, { useState } from 'react';
import axios from 'axios';
import styles from '@styles/QRForm.module.scss';
const QRForm: React.FC = () => {
const [text, setText] = useState('');
const [size, setSize] = useState<'150' | '300' | '600'>('300');
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [imageUrl, setImageUrl] = useState<string | null>(null);
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setError(null);
setImageUrl(null);
if (!text.trim()) {
setError('Please enter a URL or text to encode.');
return;
}
setLoading(true);
try {
// Call a mock API to simulate server-side generation step.
// Using jsonplaceholder as a harmless mock endpoint.
await axios.post('https://jsonplaceholder.typicode.com/posts', {
payload: text,
size,
});
// Build a QR image URL using a public QR generator for preview purposes.
// In a real implementation the server would return the final image URL or binary data.
const generatedUrl = `https://api.qrserver.com/v1/create-qr-code/?size=${size}x${size}&data=${encodeURIComponent(
text
)}`;
setImageUrl(generatedUrl);
} catch (err) {
setError('Failed to generate QR code. Please try again.');
} finally {
setLoading(false);
}
};
return (
<div className={styles.qrFormBody}>
<form onSubmit={handleSubmit}>
<label className={styles.qrFormLabel}>Submit URL or text</label>
<input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="https://example.com or some text"
className={styles.qrFormInput}
/>
<label className={styles.qrFormLabel}>Image size</label>
<select
value={size}
onChange={(e) => setSize(e.target.value as '150' | '300' | '600')}
className={styles.qrFormSelect}
>
<option value="150">Small 150x150</option>
<option value="300">Medium 300x300</option>
<option value="600">Large 600x600</option>
</select>
{error && <div className={styles.qrError}>{error}</div>}
<button type="submit" disabled={loading} className={styles.qrFormButton}>
{loading ? 'Generating…' : 'Generate'}
</button>
</form>
</div>
);
};
export default QRForm;

View File

@@ -0,0 +1,42 @@
import React from 'react';
import styles from '@styles/QRImage.module.scss';
type Props = {
src?: string;
alt?: string;
filename?: string;
};
const QRImage = ({ src, alt = 'QR code', filename = 'qrcode.png' }: Props) => {
const imgRef = React.useRef<HTMLImageElement | null>(null);
const handleDownload = () => {
const img = imgRef.current;
if (!img || !img.src) {
return;
}
const link = document.createElement('a');
link.href = img.src;
link.download = filename;
document.body.appendChild(link);
link.click();
link.remove();
};
return (
<div className={styles.qrImageBody}>
<div className={styles.qrImageContainer}>
{src ? (
<img ref={imgRef} src={src} alt={alt} className={styles.qrImg} />
) : (
<span className={styles.qrSpan}>No image</span>
)}
</div>
<button type="button" onClick={handleDownload} className={styles.qrButton}>
Download
</button>
</div>
);
};
export default QRImage;

View File

@@ -0,0 +1,11 @@
import React from 'react';
import styles from '@styles/title.module.scss';
const Title: React.FC = () => (
<header className={styles.title}>
<h1>QRcode</h1>
<h2>generator</h2>
</header>
);
export default Title;