Skip to content

Commit 962f4bc

Browse files
committed
react example update and SEO updated
1 parent 2f00f3b commit 962f4bc

7 files changed

Lines changed: 357 additions & 182 deletions

File tree

examples/react-demo/index.html

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,55 @@
44
<head>
55
<meta charset="UTF-8" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>QR Layout Designer | Professional QR Code Label Sticker Design Tool | ZPL & PDF</title>
78
<meta name="description"
8-
content="Free open-source QR code layout designer. Create, customize, and export professional QR code stickers and labels with a drag-and-drop interface." />
9+
content="The most advanced QR layout design tool for industrial labels and stickers. Create professional text + QR code designs, export to ZPL for thermal printers, or generate high-quality PDFs. No install required." />
910
<meta name="keywords"
10-
content="QR code generator, layout designer, sticker maker, label printing, ZPL, PDF, React QR component, embeddable UI" />
11-
11+
content="QR layout design, qr code label sticker, text + qr code design, zpl code printer, industrial label designer, barcode sticker maker, zebra printer layout tool, dynamic qr label" />
12+
<link rel="canonical" href="https://qr-layout-designer.netlify.app/" />
1213

14+
<!-- Open Graph / Facebook -->
1315
<meta property="og:type" content="website" />
14-
<meta property="og:title" content="QR Layout Designer | Free Open Source Sticker & Label Tool" />
16+
<meta property="og:url" content="https://qr-layout-designer.netlify.app/" />
17+
<meta property="og:title" content="QR Layout Designer | Professional QR Code Label Sticker Design Tool" />
1518
<meta property="og:description"
16-
content="Design and print QR code labels easily. Support for ZPL, PDF, and multiple UI frameworks." />
19+
content="Design, customize, and print QR code labels easily. Industry-standard ZPL and PDF export for thermal and laser printers." />
1720
<meta property="og:image"
1821
content="https://github.com/shashi089/qr-code-layout-generate-tool/raw/main/assets/layout_designer.png" />
1922

20-
23+
<!-- Twitter -->
2124
<meta property="twitter:card" content="summary_large_image" />
22-
<meta property="twitter:title" content="QR Layout Designer | Free Open Source Sticker & Label Tool" />
25+
<meta property="twitter:url" content="https://qr-layout-designer.netlify.app/" />
26+
<meta property="twitter:title" content="QR Layout Designer | QR Code Label Sticker Generator" />
2327
<meta property="twitter:description"
24-
content="Design and print QR code labels easily. Support for ZPL, PDF, and multiple UI frameworks." />
28+
content="Professional QR layout design tool for zpl code printers and sticker labels. Free, open-source, and web-based." />
2529
<meta property="twitter:image"
2630
content="https://github.com/shashi089/qr-code-layout-generate-tool/raw/main/assets/layout_designer.png" />
2731

28-
<title>QR Layout Designer | Free Open Source Sticker & Label Tool</title>
32+
<!-- JSON-LD Structured Data -->
33+
<script type="application/ld+json">
34+
{
35+
"@context": "https://schema.org",
36+
"@type": "SoftwareApplication",
37+
"name": "QR Layout Designer",
38+
"operatingSystem": "Web",
39+
"applicationCategory": "DesignApplication",
40+
"description": "Professional tool for QR layout design and QR code label sticker generation with ZPL/PDF support.",
41+
"softwareVersion": "1.0.0",
42+
"offers": {
43+
"@type": "Offer",
44+
"price": "0",
45+
"priceCurrency": "USD"
46+
},
47+
"featureList": [
48+
"Drag and drop QR layout design",
49+
"Text + QR code composition",
50+
"ZPL code export for thermal printers",
51+
"High-resolution PDF generation",
52+
"Industrial label templates"
53+
]
54+
}
55+
</script>
2956
</head>
3057

3158
<body>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
User-agent: *
2+
Allow: /
3+
4+
Sitemap: https://qr-layout-designer.netlify.app/sitemap.xml
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
3+
<url>
4+
<loc>https://qr-layout-designer.netlify.app/</loc>
5+
<lastmod>2026-03-17</lastmod>
6+
<changefreq>monthly</changefreq>
7+
<priority>1.0</priority>
8+
</url>
9+
</urlset>

examples/react-demo/src/App.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,12 @@
1212
top: 0;
1313
left: 0;
1414
z-index: 10;
15+
}
16+
17+
.scrollbar-hide::-webkit-scrollbar {
18+
display: none;
19+
}
20+
.scrollbar-hide {
21+
-ms-overflow-style: none;
22+
scrollbar-width: none;
1523
}

examples/react-demo/src/App.tsx

Lines changed: 115 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import 'qrlayout-ui/style.css';
55
import './App.css';
66
import { LabelList } from './features/labels/LabelList';
77
import { storage } from './services/storage';
8-
import { ArrowLeft, Tag, Users, Cpu, Home, Package } from 'lucide-react';
8+
import { ArrowLeft, Tag, Users, Cpu, Home, Package, Github } from 'lucide-react';
99
import { EmployeeMaster } from './features/employees/EmployeeMaster';
1010
import { MachineMaster } from './features/machines/MachineMaster';
1111
import { BinMaster } from './features/storage/BinMaster';
@@ -171,93 +171,129 @@ function App() {
171171
<>
172172
{/* Navigation Bar */}
173173
<div className="bg-white border-b border-gray-200 shadow-sm sticky top-0 z-40 backdrop-blur-lg bg-white/95">
174-
<div className="max-w-7xl mx-auto px-8">
175-
<div className="flex items-center justify-between py-4">
176-
{/* Logo/Brand */}
177-
<div className="flex items-center gap-3">
178-
<div className="p-2.5 bg-gradient-to-br from-blue-500 to-indigo-600 rounded-xl shadow-md">
179-
<svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
180-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm12 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1zM5 20h2a1 1 0 001-1v-2a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1z" />
181-
</svg>
174+
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
175+
<div className="flex flex-col lg:flex-row items-center justify-between py-4 gap-4">
176+
{/* Logo/Brand and Mobile Actions */}
177+
<div className="flex items-center justify-between w-full lg:w-auto gap-3">
178+
<div className="flex items-center gap-3">
179+
<div className="p-2 sm:p-2.5 bg-gradient-to-br from-blue-500 to-indigo-600 rounded-xl shadow-md shrink-0">
180+
<svg className="w-5 h-5 sm:w-6 sm:h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
181+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm12 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1zM5 20h2a1 1 0 001-1v-2a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1z" />
182+
</svg>
183+
</div>
184+
<div>
185+
<h1 className="text-lg sm:text-xl font-bold bg-gradient-to-r from-gray-900 to-gray-700 bg-clip-text text-transparent truncate max-w-[150px] sm:max-w-full">
186+
QR Layout Studio
187+
</h1>
188+
<div className="flex items-center gap-2">
189+
<p className="text-[10px] sm:text-xs text-gray-500 hidden sm:block">by</p>
190+
<a
191+
href="https://github.com/shashi089"
192+
target="_blank"
193+
rel="noopener noreferrer"
194+
className="text-[10px] sm:text-xs font-medium text-blue-600 hover:text-blue-700 transition-colors"
195+
>
196+
@shashi089
197+
</a>
198+
</div>
199+
</div>
182200
</div>
183-
<div>
184-
<h1 className="text-xl font-bold bg-gradient-to-r from-gray-900 to-gray-700 bg-clip-text text-transparent">
185-
QR Layout Studio (Demo)
186-
</h1>
187-
<p className="text-xs text-gray-500">Management Dashboard</p>
188-
</div>
189-
</div>
190201

191-
{/* Navigation Tabs */}
192-
<nav className="flex gap-2 bg-gray-100 p-1.5 rounded-xl">
193-
<button
194-
onClick={() => handleMainViewChange('home')}
195-
className={`flex items-center gap-2 px-4 py-2 font-semibold transition-all duration-200 rounded-lg cursor-pointer ${mainView === 'home'
196-
? 'bg-white text-blue-600 shadow-sm'
197-
: 'text-gray-600 hover:text-gray-900 hover:bg-white/50'
198-
}`}
199-
>
200-
<Home size={18} />
201-
<span className="hidden md:inline">Home</span>
202-
</button>
203-
<button
204-
onClick={() => handleMainViewChange('labels')}
205-
className={`flex items-center gap-2 px-4 py-2 font-semibold transition-all duration-200 rounded-lg cursor-pointer ${mainView === 'labels'
206-
? 'bg-white text-blue-600 shadow-sm'
207-
: 'text-gray-600 hover:text-gray-900 hover:bg-white/50'
208-
}`}
209-
>
210-
<Tag size={18} />
211-
<span>Labels</span>
212-
</button>
202+
{/* Mobile Clear Data Action */}
213203
<button
214-
onClick={() => handleMainViewChange('employees')}
215-
className={`flex items-center gap-2 px-5 py-2.5 font-semibold transition-all duration-200 rounded-lg cursor-pointer ${mainView === 'employees'
216-
? 'bg-white text-blue-600 shadow-md'
217-
: 'text-gray-600 hover:text-gray-900 hover:bg-white/50'
218-
}`}
204+
onClick={() => {
205+
if (confirm('Are you sure? This will delete all labels and employees.')) {
206+
storage.clearAll();
207+
setLabels([]);
208+
window.location.reload();
209+
}
210+
}}
211+
className="lg:hidden text-xs sm:text-sm text-red-600 hover:text-red-800 font-medium px-2 py-1.5 hover:bg-red-50 rounded-lg transition-colors cursor-pointer border border-red-100 whitespace-nowrap"
219212
>
220-
<Users size={18} />
221-
<span>Employees</span>
213+
Clear Data
222214
</button>
223-
<button
224-
onClick={() => handleMainViewChange('machines')}
225-
className={`flex items-center gap-2 px-4 py-2 font-semibold transition-all duration-200 rounded-lg cursor-pointer ${mainView === 'machines'
226-
? 'bg-white text-blue-600 shadow-sm'
227-
: 'text-gray-600 hover:text-gray-900 hover:bg-white/50'
228-
}`}
215+
</div>
216+
217+
{/* Navigation Tabs - Scrollable on mobile */}
218+
<div className="w-full lg:w-auto overflow-x-auto pb-1 lg:pb-0 scrollbar-hide -mx-4 px-4 lg:mx-0 lg:px-0">
219+
<nav className="flex gap-1.5 sm:gap-2 bg-gray-100 p-1 sm:p-1.5 rounded-xl w-max mx-auto lg:mx-0">
220+
<button
221+
onClick={() => handleMainViewChange('home')}
222+
className={`flex items-center gap-2 px-4 py-2 font-semibold transition-all duration-200 rounded-lg cursor-pointer ${mainView === 'home'
223+
? 'bg-white text-blue-600 shadow-sm'
224+
: 'text-gray-600 hover:text-gray-900 hover:bg-white/50'
225+
}`}
226+
>
227+
<Home size={18} />
228+
<span className="hidden md:inline">Home</span>
229+
</button>
230+
<button
231+
onClick={() => handleMainViewChange('labels')}
232+
className={`flex items-center gap-2 px-4 py-2 font-semibold transition-all duration-200 rounded-lg cursor-pointer ${mainView === 'labels'
233+
? 'bg-white text-blue-600 shadow-sm'
234+
: 'text-gray-600 hover:text-gray-900 hover:bg-white/50'
235+
}`}
236+
>
237+
<Tag size={18} />
238+
<span>Labels</span>
239+
</button>
240+
<button
241+
onClick={() => handleMainViewChange('employees')}
242+
className={`flex items-center gap-2 px-5 py-2.5 font-semibold transition-all duration-200 rounded-lg cursor-pointer ${mainView === 'employees'
243+
? 'bg-white text-blue-600 shadow-md'
244+
: 'text-gray-600 hover:text-gray-900 hover:bg-white/50'
245+
}`}
246+
>
247+
<Users size={18} />
248+
<span>Employees</span>
249+
</button>
250+
<button
251+
onClick={() => handleMainViewChange('machines')}
252+
className={`flex items-center gap-2 px-4 py-2 font-semibold transition-all duration-200 rounded-lg cursor-pointer ${mainView === 'machines'
253+
? 'bg-white text-blue-600 shadow-sm'
254+
: 'text-gray-600 hover:text-gray-900 hover:bg-white/50'
255+
}`}
256+
>
257+
<Cpu size={18} />
258+
<span className="hidden md:inline">Machines</span>
259+
</button>
260+
<button
261+
onClick={() => handleMainViewChange('storage')}
262+
className={`flex items-center gap-2 px-4 py-2 font-semibold transition-all duration-200 rounded-lg cursor-pointer ${mainView === 'storage'
263+
? 'bg-white text-blue-600 shadow-sm'
264+
: 'text-gray-600 hover:text-gray-900 hover:bg-white/50'
265+
}`}
266+
>
267+
<Package size={18} />
268+
<span className="hidden sm:inline">Storage</span>
269+
</button>
270+
</nav>
271+
</div>
272+
273+
{/* Desktop Actions */}
274+
<div className="hidden lg:flex items-center gap-3">
275+
<a
276+
href="https://github.com/shashi089/qr-code-layout-generate-tool"
277+
target="_blank"
278+
rel="noopener noreferrer"
279+
className="flex items-center gap-2 text-sm text-gray-600 hover:text-gray-900 font-medium px-3 py-1.5 hover:bg-gray-50 rounded-lg transition-colors border border-gray-200"
229280
>
230-
<Cpu size={18} />
231-
<span className="hidden md:inline">Machines</span>
232-
</button>
281+
<Github size={18} />
282+
<span>Source Code</span>
283+
</a>
233284
<button
234-
onClick={() => handleMainViewChange('storage')}
235-
className={`flex items-center gap-2 px-4 py-2 font-semibold transition-all duration-200 rounded-lg cursor-pointer ${mainView === 'storage'
236-
? 'bg-white text-blue-600 shadow-sm'
237-
: 'text-gray-600 hover:text-gray-900 hover:bg-white/50'
238-
}`}
285+
onClick={() => {
286+
if (confirm('Are you sure? This will delete all labels and employees.')) {
287+
storage.clearAll();
288+
setLabels([]);
289+
window.location.reload();
290+
}
291+
}}
292+
className="text-sm text-red-600 hover:text-red-800 font-medium px-3 py-1.5 hover:bg-red-50 rounded-lg transition-colors cursor-pointer border border-red-100 whitespace-nowrap"
239293
>
240-
<Package size={18} />
241-
<span className="hidden md:inline">Storage</span>
294+
Clear Data
242295
</button>
243-
</nav>
244-
245-
{/* Actions */}
246-
<button
247-
onClick={() => {
248-
if (confirm('Are you sure? This will delete all labels and employees.')) {
249-
storage.clearAll();
250-
setLabels([]);
251-
// Force reload to clear any other state if strictly needed,
252-
// or just clearing state is enough if EmployeeMaster fetches on mount.
253-
// For EmployeeMaster, we might need a way to trigger reload, but page refresh is simplest for "Reset"
254-
window.location.reload();
255-
}
256-
}}
257-
className="ml-4 text-sm text-red-600 hover:text-red-800 font-medium px-3 py-1.5 hover:bg-red-50 rounded-lg transition-colors cursor-pointer border border-red-100"
258-
>
259-
Clear Data
260-
</button>
296+
</div>
261297
</div>
262298
</div>
263299
</div>

0 commit comments

Comments
 (0)