feat: add static vs dynamic QR code toggle to the create page

This commit is contained in:
Mohan Ki
2026-07-27 17:17:36 +05:30
parent 9aaf94625a
commit 36c726f713
+68 -19
View File
@@ -11,6 +11,7 @@ export default function CreateQRPage() {
const router = useRouter();
const [destinationUrl, setDestinationUrl] = useState('https://ck-qr.com');
const [qrName, setQrName] = useState('');
const [qrType, setQrType] = useState<'dynamic' | 'static'>('dynamic');
const [customSlug, setCustomSlug] = useState('');
const [randomSlug, setRandomSlug] = useState('');
const [isGenerating, setIsGenerating] = useState(false);
@@ -49,9 +50,22 @@ export default function CreateQRPage() {
React.useEffect(() => {
const generated = Math.random().toString(36).substring(2, 8);
setRandomSlug(generated);
setQrOptions(prev => ({ ...prev, data: `${baseUrl}/l/${generated}` }));
if (qrType === 'dynamic') {
setQrOptions(prev => ({ ...prev, data: `${baseUrl}/l/${generated}` }));
} else {
setQrOptions(prev => ({ ...prev, data: destinationUrl }));
}
}, [baseUrl]);
// Keep QR data in sync with type and destinationUrl
React.useEffect(() => {
if (qrType === 'static') {
setQrOptions(prev => ({ ...prev, data: destinationUrl }));
} else {
setQrOptions(prev => ({ ...prev, data: `${baseUrl}/l/${customSlug || randomSlug}` }));
}
}, [qrType, destinationUrl]);
// Keep QR data in sync with custom slug
const handleSlugChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const val = e.target.value.replace(/[^a-zA-Z0-9-_]/g, '');
@@ -65,8 +79,8 @@ export default function CreateQRPage() {
// Generate Dynamic QR via API
const response = await api.post('/qr/generate', {
name: qrName,
customSlug: customSlug || randomSlug, // Pass the previewed slug so the backend uses it!
type: 'dynamic',
customSlug: qrType === 'dynamic' ? (customSlug || randomSlug) : undefined, // Pass the previewed slug so the backend uses it!
type: qrType,
dataType: 'URL',
destinationUrl: destinationUrl,
designData: qrOptions
@@ -134,6 +148,34 @@ export default function CreateQRPage() {
<h2 className="text-xl font-bold text-gray-800 border-b pb-4 mb-6">QR Content</h2>
<div className="flex flex-col gap-6">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">QR Type</label>
<div className="flex gap-4">
<label className="flex items-center gap-2 cursor-pointer">
<input
type="radio"
name="qrType"
value="dynamic"
checked={qrType === 'dynamic'}
onChange={() => setQrType('dynamic')}
className="text-indigo-600 focus:ring-indigo-500"
/>
<span className="text-gray-900 font-medium">Dynamic (Trackable & Editable)</span>
</label>
<label className="flex items-center gap-2 cursor-pointer">
<input
type="radio"
name="qrType"
value="static"
checked={qrType === 'static'}
onChange={() => setQrType('static')}
className="text-indigo-600 focus:ring-indigo-500"
/>
<span className="text-gray-900 font-medium">Static (Permanent)</span>
</label>
</div>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Internal Name</label>
<input
@@ -154,25 +196,32 @@ export default function CreateQRPage() {
placeholder="https://your-website.com"
className="w-full border-gray-300 rounded-lg shadow-sm p-3 border focus:ring-indigo-500 focus:border-indigo-500 text-gray-900 bg-white"
/>
<p className="text-xs text-gray-500 mt-2">This is a dynamic QR. You can change this URL later without reprinting the code.</p>
{qrType === 'dynamic' && (
<p className="text-xs text-gray-500 mt-2">This is a dynamic QR. You can change this URL later without reprinting the code.</p>
)}
{qrType === 'static' && (
<p className="text-xs text-gray-500 mt-2">This URL is embedded directly into the code and cannot be changed later.</p>
)}
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Custom Short Link (Optional)</label>
<div className="flex flex-col sm:flex-row shadow-sm rounded-lg overflow-hidden border border-gray-300 focus-within:ring-2 focus-within:ring-indigo-500">
<span className="inline-flex items-center px-4 bg-gray-50 text-gray-500 border-r border-gray-300 text-sm whitespace-nowrap">
{(process.env.NEXT_PUBLIC_APP_URL || 'https://qr.houseofwebsites.ai').replace(/^https?:\/\//, '')}/l/
</span>
<input
type="text"
value={customSlug}
onChange={handleSlugChange}
placeholder={randomSlug || "my-promo"}
className="flex-1 w-full p-3 focus:outline-none text-gray-900 bg-white"
/>
{qrType === 'dynamic' && (
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">Custom Short Link (Optional)</label>
<div className="flex flex-col sm:flex-row shadow-sm rounded-lg overflow-hidden border border-gray-300 focus-within:ring-2 focus-within:ring-indigo-500">
<span className="inline-flex items-center px-4 bg-gray-50 text-gray-500 border-r border-gray-300 text-sm whitespace-nowrap">
{(process.env.NEXT_PUBLIC_APP_URL || 'https://qr.houseofwebsites.ai').replace(/^https?:\/\//, '')}/l/
</span>
<input
type="text"
value={customSlug}
onChange={handleSlugChange}
placeholder={randomSlug || "my-promo"}
className="flex-1 w-full p-3 focus:outline-none text-gray-900 bg-white"
/>
</div>
<p className="text-xs text-gray-500 mt-2">Leave blank to auto-generate a random link.</p>
</div>
<p className="text-xs text-gray-500 mt-2">Leave blank to auto-generate a random link.</p>
</div>
)}
</div>
</div>