Restructured the repository into a monorepo to better organize application code and maintenance scripts. ## Workspace Structure - web-app: Next.js application (all app code moved from root) - housekeeping: Database backup and maintenance scripts ## Key Changes - Moved all application code to web-app/ using git mv - Moved database scripts to housekeeping/ workspace - Updated Dockerfile for monorepo build process - Updated docker-compose files (volume paths: ./web-app/etc/hosts/) - Updated .gitignore for workspace-level node_modules - Updated documentation (README.md, CLAUDE.md, CHANGELOG.md) ## Migration Impact - Root package.json now manages workspaces - Build commands delegate to web-app workspace - All file history preserved via git mv - Docker build process updated for workspace structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
77 lines
2.4 KiB
TypeScript
77 lines
2.4 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useEffect, FC } from 'react';
|
|
import { writeBarcode, prepareZXingModule, type WriterOptions } from 'zxing-wasm/writer';
|
|
|
|
// Configure WASM file location for writer
|
|
prepareZXingModule({
|
|
overrides: {
|
|
locateFile: (path, prefix) => {
|
|
if (path.endsWith('.wasm')) {
|
|
return window.location.origin + '/zxing_writer.wasm';
|
|
}
|
|
return prefix + path;
|
|
}
|
|
}
|
|
});
|
|
|
|
export const Pdf417BarcodeWasm: FC<{ hub3aText: string, className?: string }> = ({ hub3aText, className }) => {
|
|
const [barcodeDataUrl, setBarcodeDataUrl] = useState<string | undefined>(undefined);
|
|
const [error, setError] = useState<string | undefined>(undefined);
|
|
|
|
useEffect(() => {
|
|
const generateBarcode = async () => {
|
|
try {
|
|
setError(undefined);
|
|
setBarcodeDataUrl(undefined);
|
|
|
|
const writerOptions: WriterOptions = {
|
|
format: 'PDF417',
|
|
ecLevel: "5",
|
|
scale: 2,
|
|
};
|
|
|
|
const result = await writeBarcode(hub3aText, writerOptions);
|
|
|
|
// Convert PNG blob to data URL
|
|
const reader = new FileReader();
|
|
reader.onloadend = () => {
|
|
setBarcodeDataUrl(reader.result as string);
|
|
};
|
|
reader.readAsDataURL(result.image as Blob);
|
|
|
|
} catch (err) {
|
|
console.error('Failed to generate PDF417 barcode:', err);
|
|
setError('Failed to generate barcode');
|
|
}
|
|
};
|
|
|
|
if (hub3aText) {
|
|
generateBarcode();
|
|
}
|
|
}, [hub3aText]);
|
|
|
|
// Show error state
|
|
if (error) {
|
|
return (
|
|
<div style={{ width: "350px", height: "92px" }} className="flex items-center justify-center">
|
|
<span className="text-error text-sm">{error}</span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Don't render until barcode is generated (prevents hydration mismatch)
|
|
if (!barcodeDataUrl) {
|
|
return (
|
|
<div style={{ width: "350px", height: "92px" }} className="flex items-center justify-center">
|
|
<span className="loading loading-spinner loading-lg"></span>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
// eslint-disable-next-line @next/next/no-img-element
|
|
<img src={barcodeDataUrl} alt="PDF417 Barcode" className={className} />
|
|
);
|
|
}
|