Skip to content

Commit a061625

Browse files
committed
feat: display epc data for the scanned code
1 parent ca45458 commit a061625

File tree

6 files changed

+291
-15
lines changed

6 files changed

+291
-15
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"format:check": "prettier --check ."
1313
},
1414
"dependencies": {
15+
"@radix-ui/react-collapsible": "^1.1.1",
1516
"@radix-ui/react-icons": "^1.3.0",
1617
"@radix-ui/react-slot": "^1.1.0",
1718
"@yudiel/react-qr-scanner": "^2.0.8",

pnpm-lock.yaml

Lines changed: 159 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/App.tsx

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useState } from 'react';
22
import { IDetectedBarcode, Scanner } from '@yudiel/react-qr-scanner';
33
import QRCode from 'react-qr-code';
4+
import { Camera, ChevronDown, ChevronUp, RefreshCw } from 'lucide-react';
45
import {
56
Card,
67
CardContent,
@@ -10,24 +11,35 @@ import {
1011
} from '@/components/ui/card';
1112
import { Button } from '@/components/ui/button';
1213
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
13-
import { Camera, RefreshCw } from 'lucide-react';
14+
import {
15+
Collapsible,
16+
CollapsibleContent,
17+
CollapsibleTrigger,
18+
} from '@/components/ui/collapsible';
1419

15-
import { generateEpcQr, parseUpnQr } from './lib/qr';
20+
import {
21+
generateEpcQr,
22+
generateEpcQrString,
23+
parseUpnQr,
24+
type EpcQrData,
25+
} from './lib/qr';
26+
import { EpcQrDataDisplay } from './components/EpcQrDataDisplay';
1627

1728
function App() {
18-
const [code, setCode] = useState<string | null>(null);
29+
const [epcData, setEpcData] = useState<EpcQrData | null>(null);
1930
const [error, setError] = useState<string | null>(null);
2031
const [isScanning, setIsScanning] = useState(true);
32+
const [isOpen, setIsOpen] = useState(false);
2133

2234
const handleOnScan = (data: IDetectedBarcode[]) => {
2335
const [scanResult] = data;
2436
if (!scanResult || scanResult.format === 'unknown') return;
2537

2638
try {
27-
const upnQrCode = parseUpnQr(scanResult.rawValue);
28-
const epcQrCode = generateEpcQr(upnQrCode);
39+
const upnQrData = parseUpnQr(scanResult.rawValue);
40+
const epcQrData = generateEpcQr(upnQrData);
2941

30-
setCode(epcQrCode);
42+
setEpcData(epcQrData);
3143
setIsScanning(false);
3244
setError(null);
3345
} catch (error) {
@@ -38,9 +50,10 @@ function App() {
3850
};
3951

4052
const handleReset = () => {
41-
setCode(null);
53+
setEpcData(null);
4254
setError(null);
4355
setIsScanning(true);
56+
setIsOpen(false);
4457
};
4558

4659
return (
@@ -57,10 +70,32 @@ function App() {
5770
</div>
5871
) : (
5972
<div className="flex flex-col items-center">
60-
{code && <QRCode value={code} />}
73+
{epcData && <QRCode value={generateEpcQrString(epcData)} />}
6174
<Button onClick={handleReset} className="mt-4">
6275
<RefreshCw className="mr-2 h-4 w-4" /> Scan Another Code
6376
</Button>
77+
78+
{epcData && (
79+
<Collapsible
80+
open={isOpen}
81+
onOpenChange={setIsOpen}
82+
className="w-full mt-4"
83+
>
84+
<CollapsibleTrigger asChild>
85+
<Button variant="outline" className="w-full">
86+
{isOpen ? 'Hide' : 'Show'} EPC Data
87+
{isOpen ? (
88+
<ChevronUp className="ml-2 h-4 w-4" />
89+
) : (
90+
<ChevronDown className="ml-2 h-4 w-4" />
91+
)}
92+
</Button>
93+
</CollapsibleTrigger>
94+
<CollapsibleContent className="mt-2">
95+
<EpcQrDataDisplay data={epcData} />
96+
</CollapsibleContent>
97+
</Collapsible>
98+
)}
6499
</div>
65100
)}
66101

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Card, CardContent } from '@/components/ui/card';
2+
import { type EpcQrData } from '@/lib/qr';
3+
4+
const fieldNameMap: Record<keyof EpcQrData, string> = {
5+
serviceTag: 'Service Tag',
6+
version: 'Version',
7+
encoding: 'Character set',
8+
identification: 'Identification',
9+
bic: 'BIC',
10+
recipient: 'Name',
11+
iban: 'IBAN',
12+
amount: 'Amount',
13+
purposeCode: 'Purpose',
14+
reference: 'Reference',
15+
text: 'Text',
16+
info: 'Information',
17+
};
18+
19+
interface EpcQrDataDisplayProps {
20+
data: EpcQrData;
21+
}
22+
23+
export function EpcQrDataDisplay({ data }: EpcQrDataDisplayProps) {
24+
return (
25+
<Card>
26+
<CardContent className="pt-4">
27+
<dl className="space-y-2 text-sm">
28+
{(Object.keys(data) as Array<keyof EpcQrData>).map((key) => (
29+
<div key={key} className="flex">
30+
<dt className="font-semibold w-1/3">{fieldNameMap[key]}:</dt>
31+
<dd className="w-2/3">{data[key]}</dd>
32+
</div>
33+
))}
34+
</dl>
35+
</CardContent>
36+
</Card>
37+
);
38+
}

src/components/ui/collapsible.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
2+
3+
const Collapsible = CollapsiblePrimitive.Root;
4+
5+
const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
6+
7+
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
8+
9+
export { Collapsible, CollapsibleTrigger, CollapsibleContent };

0 commit comments

Comments
 (0)