Added QR code viewer and fixed button behavior
This commit is contained in:
parent
1cbaccdf82
commit
64f473d214
|
@ -11,6 +11,11 @@ export enum ButtonType {
|
||||||
button = 'button',
|
button = 'button',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Button.defaultProps = {
|
||||||
|
loading: false,
|
||||||
|
type: ButtonType.button,
|
||||||
|
}
|
||||||
|
|
||||||
function Button(props: ButtonProps): JSX.Element {
|
function Button(props: ButtonProps): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -74,7 +74,7 @@ function Form(): JSX.Element {
|
||||||
navigator.userAgent.indexOf('CriOS') == -1 &&
|
navigator.userAgent.indexOf('CriOS') == -1 &&
|
||||||
navigator.userAgent.indexOf('FxiOS') == -1
|
navigator.userAgent.indexOf('FxiOS') == -1
|
||||||
)
|
)
|
||||||
}, []);
|
}, [isSafari]);
|
||||||
|
|
||||||
// Whether Safari is used or not
|
// Whether Safari is used or not
|
||||||
let [isShareDialogAvailable, setIsShareDialogAvailable] = useState<boolean>(false);
|
let [isShareDialogAvailable, setIsShareDialogAvailable] = useState<boolean>(false);
|
||||||
|
@ -82,7 +82,7 @@ function Form(): JSX.Element {
|
||||||
// Check if share dialog is available
|
// Check if share dialog is available
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsShareDialogAvailable(window.navigator && window.navigator.share !== undefined);
|
setIsShareDialogAvailable(window.navigator && window.navigator.share !== undefined);
|
||||||
}, []);
|
}, [isShareDialogAvailable]);
|
||||||
|
|
||||||
// Open share dialog
|
// Open share dialog
|
||||||
async function showShareDialog() {
|
async function showShareDialog() {
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
"pdfjs-dist": "^2.5.207",
|
"pdfjs-dist": "^2.5.207",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
|
"react-qr-code": "^2.0.3",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
"webpack": "^5.0.0",
|
"webpack": "^5.0.0",
|
||||||
"worker-loader": "^3.0.7"
|
"worker-loader": "^3.0.7"
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import {serverSideTranslations} from 'next-i18next/serverSideTranslations';
|
||||||
|
|
||||||
|
import React, {useEffect, useState} from "react";
|
||||||
|
import QRCode from "react-qr-code";
|
||||||
|
import Card from '../components/Card';
|
||||||
|
import Logo from "../components/Logo";
|
||||||
|
|
||||||
|
function Pass(): JSX.Element {
|
||||||
|
const [fragment, setFragment] = useState<string>(undefined);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const rawFragment = window.location.hash.substring(1);
|
||||||
|
const decodedFragment = Buffer.from(rawFragment, 'base64').toString();
|
||||||
|
setFragment(decodedFragment);
|
||||||
|
}, [fragment]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="py-6 flex flex-col space-y-5 items-center">
|
||||||
|
<Logo/>
|
||||||
|
<div className="flex flex-row items-center">
|
||||||
|
{
|
||||||
|
fragment &&
|
||||||
|
<Card content={
|
||||||
|
<div className="p-2 bg-white rounded-md">
|
||||||
|
<QRCode value={fragment} size={280} level="L" />
|
||||||
|
</div>
|
||||||
|
} />
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getStaticProps({ locale }) {
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
...(await serverSideTranslations(locale, ['common'])),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Pass;
|
|
@ -116,6 +116,11 @@ export class Payload {
|
||||||
|
|
||||||
const country = valueSets.countryCodes[countryCode].display;
|
const country = valueSets.countryCodes[countryCode].display;
|
||||||
|
|
||||||
|
// Encode raw data and get url
|
||||||
|
const encodedData = Buffer.from(body.rawData).toString('base64');
|
||||||
|
const url = window.location.protocol + "//" + window.location.host;
|
||||||
|
|
||||||
|
|
||||||
const generic: PassDictionary = {
|
const generic: PassDictionary = {
|
||||||
headerFields: [
|
headerFields: [
|
||||||
{
|
{
|
||||||
|
@ -134,6 +139,11 @@ export class Payload {
|
||||||
secondaryFields: [],
|
secondaryFields: [],
|
||||||
auxiliaryFields: [],
|
auxiliaryFields: [],
|
||||||
backFields: [
|
backFields: [
|
||||||
|
{
|
||||||
|
key: "enlarge",
|
||||||
|
label: "Enlarging the QR Code",
|
||||||
|
value: `Inside the Wallet app on iOS, press and hold or open the link below. This does not work when accessing the Wallet by double-clicking the side button.\n<a href='${url}/pass#${encodedData}'>Enlarge QR Code</a>`
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: "uvci",
|
key: "uvci",
|
||||||
label: "Unique Certificate Identifier (UVCI)",
|
label: "Unique Certificate Identifier (UVCI)",
|
||||||
|
@ -157,10 +167,27 @@ export class Payload {
|
||||||
this.img2x = dark ? Constants.img2xWhite : Constants.img2xBlack
|
this.img2x = dark ? Constants.img2xWhite : Constants.img2xBlack
|
||||||
this.dark = dark;
|
this.dark = dark;
|
||||||
|
|
||||||
this.generic = Payload.fillPassData(this.certificateType, generic, properties, valueSets, country, dateOfBirth);
|
this.generic = Payload.fillPassData(
|
||||||
|
this.certificateType,
|
||||||
|
generic,
|
||||||
|
properties,
|
||||||
|
valueSets,
|
||||||
|
country,
|
||||||
|
dateOfBirth,
|
||||||
|
url
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fillPassData(type: CertificateType, data: PassDictionary, properties: Object, valueSets: ValueSets, country: string, dateOfBirth: string): PassDictionary {
|
static fillPassData(
|
||||||
|
type: CertificateType,
|
||||||
|
data: PassDictionary,
|
||||||
|
properties: Object,
|
||||||
|
valueSets: ValueSets,
|
||||||
|
country: string,
|
||||||
|
dateOfBirth: string,
|
||||||
|
url: string
|
||||||
|
): PassDictionary {
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case CertificateType.Vaccination:
|
case CertificateType.Vaccination:
|
||||||
const dose = `${properties['dn']}/${properties['sd']}`;
|
const dose = `${properties['dn']}/${properties['sd']}`;
|
||||||
|
@ -353,7 +380,7 @@ export class Payload {
|
||||||
{
|
{
|
||||||
key: "credits",
|
key: "credits",
|
||||||
label: "",
|
label: "",
|
||||||
value: "Created with <a href='https://covidpass.marvinsextro.de'>CovidPass</a>"
|
value: `Created with <a href='${url}'>CovidPass</a>`
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
26
yarn.lock
26
yarn.lock
|
@ -1873,7 +1873,7 @@ lodash@^4.17.21:
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
|
||||||
loose-envify@^1.1.0:
|
loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||||
|
@ -2396,6 +2396,15 @@ process@0.11.10, process@^0.11.10:
|
||||||
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
||||||
integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
|
integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
|
||||||
|
|
||||||
|
prop-types@^15.7.2:
|
||||||
|
version "15.8.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.0.tgz#d237e624c45a9846e469f5f31117f970017ff588"
|
||||||
|
integrity sha512-fDGekdaHh65eI3lMi5OnErU6a8Ighg2KjcjQxO7m8VHyWjcPyj5kiOgV1LQDOOOgVy3+5FgjXvdSSX7B8/5/4g==
|
||||||
|
dependencies:
|
||||||
|
loose-envify "^1.4.0"
|
||||||
|
object-assign "^4.1.1"
|
||||||
|
react-is "^16.13.1"
|
||||||
|
|
||||||
public-encrypt@^4.0.0:
|
public-encrypt@^4.0.0:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
|
resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
|
||||||
|
@ -2433,6 +2442,11 @@ purgecss@^4.0.3:
|
||||||
postcss "^8.3.5"
|
postcss "^8.3.5"
|
||||||
postcss-selector-parser "^6.0.6"
|
postcss-selector-parser "^6.0.6"
|
||||||
|
|
||||||
|
qr.js@0.0.0:
|
||||||
|
version "0.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f"
|
||||||
|
integrity sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8=
|
||||||
|
|
||||||
querystring-es3@0.2.1, querystring-es3@^0.2.0:
|
querystring-es3@0.2.1, querystring-es3@^0.2.0:
|
||||||
version "0.2.1"
|
version "0.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
|
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
|
||||||
|
@ -2513,11 +2527,19 @@ react-is@17.0.2:
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
||||||
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
||||||
|
|
||||||
react-is@^16.7.0:
|
react-is@^16.13.1, react-is@^16.7.0:
|
||||||
version "16.13.1"
|
version "16.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
|
|
||||||
|
react-qr-code@^2.0.3:
|
||||||
|
version "2.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-qr-code/-/react-qr-code-2.0.3.tgz#cc80785e08f817d1ab066ca4035262f77d049648"
|
||||||
|
integrity sha512-6GDH0l53lksf2JgZwwcoS0D60a1OAal/GQRyNFkMBW19HjSqvtD5S20scmSQsKl+BgWM85Wd5DCcUYoHd+PZnQ==
|
||||||
|
dependencies:
|
||||||
|
prop-types "^15.7.2"
|
||||||
|
qr.js "0.0.0"
|
||||||
|
|
||||||
react-refresh@0.8.3:
|
react-refresh@0.8.3:
|
||||||
version "0.8.3"
|
version "0.8.3"
|
||||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
|
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
|
||||||
|
|
Loading…
Reference in New Issue