From 7119e36b105b2c0046430c712573cb6955d93a98 Mon Sep 17 00:00:00 2001 From: Jason Sylvestre Date: Mon, 13 Oct 2025 13:48:35 -0700 Subject: [PATCH] We probably don't want to do this... But maybe... Sounds like some physical store support QR code scanning of chart strings --- Finjector.Web/ClientApp/package-lock.json | 10 +++++ Finjector.Web/ClientApp/package.json | 1 + .../src/components/Details/DetailsQrCode.tsx | 28 +++++++++++++ Finjector.Web/ClientApp/src/pages/Details.tsx | 2 + .../ClientApp/src/sass/_components.scss | 41 +++++++++++++++++++ 5 files changed, 82 insertions(+) create mode 100644 Finjector.Web/ClientApp/src/components/Details/DetailsQrCode.tsx diff --git a/Finjector.Web/ClientApp/package-lock.json b/Finjector.Web/ClientApp/package-lock.json index 4657bfbc..8cc56e12 100644 --- a/Finjector.Web/ClientApp/package-lock.json +++ b/Finjector.Web/ClientApp/package-lock.json @@ -25,6 +25,7 @@ "bootstrap": "^5.2.2", "http-proxy-middleware": "^2.0.6", "lodash": "^4.17.21", + "qrcode.react": "^4.2.0", "react": "^18.2.0", "react-bootstrap-typeahead": "^6.0.0", "react-dom": "^18.2.0", @@ -11479,6 +11480,15 @@ "optional": true, "peer": true }, + "node_modules/qrcode.react": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.2.0.tgz", + "integrity": "sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==", + "license": "ISC", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", diff --git a/Finjector.Web/ClientApp/package.json b/Finjector.Web/ClientApp/package.json index 25f8bd88..a8358647 100644 --- a/Finjector.Web/ClientApp/package.json +++ b/Finjector.Web/ClientApp/package.json @@ -21,6 +21,7 @@ "bootstrap": "^5.2.2", "http-proxy-middleware": "^2.0.6", "lodash": "^4.17.21", + "qrcode.react": "^4.2.0", "react": "^18.2.0", "react-bootstrap-typeahead": "^6.0.0", "react-dom": "^18.2.0", diff --git a/Finjector.Web/ClientApp/src/components/Details/DetailsQrCode.tsx b/Finjector.Web/ClientApp/src/components/Details/DetailsQrCode.tsx new file mode 100644 index 00000000..444621a0 --- /dev/null +++ b/Finjector.Web/ClientApp/src/components/Details/DetailsQrCode.tsx @@ -0,0 +1,28 @@ +import { QRCodeSVG } from "qrcode.react"; + +interface DetailsQrCodeProps { + chartSegmentString: string | undefined; +} + +const DetailsQrCode = ({ chartSegmentString }: DetailsQrCodeProps) => { + if (!chartSegmentString) { + return null; + } + + return ( +
+
+
Scan Chart String
+ +

{chartSegmentString}

+
+
+ ); +}; + +export default DetailsQrCode; diff --git a/Finjector.Web/ClientApp/src/pages/Details.tsx b/Finjector.Web/ClientApp/src/pages/Details.tsx index efd11094..b172b3fd 100644 --- a/Finjector.Web/ClientApp/src/pages/Details.tsx +++ b/Finjector.Web/ClientApp/src/pages/Details.tsx @@ -8,6 +8,7 @@ import PageTitle from "../components/Shared/Layout/PageTitle"; import DetailsAeErrors from "../components/Details/DetailsAeErrors"; import PageBody from "../components/Shared/Layout/PageBody"; import DetailsChartString from "../components/Details/DetailsChartString"; +import DetailsQrCode from "../components/Details/DetailsQrCode"; import { useFinQueryStatus } from "../util/error"; const Details = () => { @@ -56,6 +57,7 @@ const Details = () => { queryStatus={queryStatus} /> + diff --git a/Finjector.Web/ClientApp/src/sass/_components.scss b/Finjector.Web/ClientApp/src/sass/_components.scss index fb470d6d..b180506b 100644 --- a/Finjector.Web/ClientApp/src/sass/_components.scss +++ b/Finjector.Web/ClientApp/src/sass/_components.scss @@ -418,3 +418,44 @@ span.font-reg { .shade-hover-row:hover { background-color: #f5f5f5; /* Change this to the color you want */ } + +// QR Code +.qr-code-container { + display: flex; + justify-content: center; + margin-top: 2rem; + margin-bottom: 2rem; + padding: 1.5rem; + + .qr-code-wrapper { + text-align: center; + padding: 1.5rem; + background-color: #fff; + border-radius: 4px; + box-shadow: $box-shadow; + border: 1px solid $borders; + + h5 { + margin-bottom: 1rem; + color: $primary-font; + font-family: $sans-bold; + font-size: 1rem; + text-transform: uppercase; + letter-spacing: 0.025em; + } + + svg { + display: block; + margin: 0 auto 1rem; + } + + .qr-code-url { + margin-top: 0.75rem; + font-family: 'Courier New', monospace; + font-size: 0.85rem; + color: $secondary-font; + word-break: break-all; + max-width: 200px; + } + } +}