-
-
-
-
- {(() => {
- switch (proofStep) {
- case QRcodeSteps.PROOF_GENERATION_STARTED:
- case QRcodeSteps.PROOF_GENERATED:
- return ;
- case QRcodeSteps.PROOF_GENERATION_FAILED:
- return (
- // @ts-expect-error Lottie typings don't match the default export shape
- {
- setProofStep(QRcodeSteps.WAITING_FOR_MOBILE);
- }}
- loop={false}
- />
- );
- case QRcodeSteps.PROOF_VERIFIED:
- return (
- // @ts-expect-error Lottie typings don't match the default export shape
- {
- setProofStep(QRcodeSteps.WAITING_FOR_MOBILE);
- }}
- loop={false}
- />
- );
- default:
- return (
-
- );
- }
- })()}
-
+ const qrValue =
+ type === 'websocket'
+ ? `${REDIRECT_URL}?sessionId=${sessionId}`
+ : getUniversalLink({
+ ...selfAppRef.current,
+ sessionId: sessionId,
+ });
+
+ return (
+
+
+ {showStatusText && }
);
-
- return
{renderProofStatus()}
;
};
// Also export other components/types that might be needed
diff --git a/sdk/qrcode/components/StatusBanner.tsx b/sdk/qrcode/components/StatusBanner.tsx
new file mode 100644
index 000000000..792d55e36
--- /dev/null
+++ b/sdk/qrcode/components/StatusBanner.tsx
@@ -0,0 +1,24 @@
+import React, { memo } from 'react';
+
+import selfLogo from '../assets/self-logo.svg';
+import { statusBannerLogoStyle, statusBannerStyle } from '../utils/styles.js';
+import { getStatusText, QRcodeSteps } from '../utils/utils.js';
+
+interface StatusBannerProps {
+ proofStep: number;
+ qrSize: number;
+}
+
+const StatusBanner = memo(({ proofStep, qrSize }: StatusBannerProps) => {
+ const showLogo =
+ proofStep === QRcodeSteps.DISCONNECTED || proofStep === QRcodeSteps.WAITING_FOR_MOBILE;
+
+ return (
+
+ {showLogo &&

}
+ {getStatusText(proofStep)}
+
+ );
+});
+
+export default StatusBanner;
diff --git a/sdk/qrcode/package.json b/sdk/qrcode/package.json
index e13096586..32f72ed3d 100644
--- a/sdk/qrcode/package.json
+++ b/sdk/qrcode/package.json
@@ -21,11 +21,6 @@
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.cjs"
},
- "./components/LED": {
- "types": "./dist/esm/components/LED.d.ts",
- "import": "./dist/esm/components/LED.js",
- "require": "./dist/cjs/components/LED.cjs"
- },
"./components/SelfQRcode": {
"types": "./dist/esm/components/SelfQRcode.d.ts",
"import": "./dist/esm/components/SelfQRcode.js",
diff --git a/sdk/qrcode/tsconfig.json b/sdk/qrcode/tsconfig.json
index 1eb0ffb47..c9cfed711 100644
--- a/sdk/qrcode/tsconfig.json
+++ b/sdk/qrcode/tsconfig.json
@@ -15,6 +15,8 @@
},
"include": [
"animations",
+ "assets",
+ "types",
"index.ts",
"components/**.tsx",
"utils/*.ts"
diff --git a/sdk/qrcode/tsup.config.ts b/sdk/qrcode/tsup.config.ts
index b49f53b95..c498b0e26 100644
--- a/sdk/qrcode/tsup.config.ts
+++ b/sdk/qrcode/tsup.config.ts
@@ -8,7 +8,6 @@ const __dirname = path.dirname(__filename);
const entries = {
index: 'index.ts',
- 'components/LED': 'components/LED.tsx',
'components/SelfQRcode': 'components/SelfQRcode.tsx',
'utils/utils': 'utils/utils.ts',
'utils/styles': 'utils/styles.ts',
@@ -28,6 +27,10 @@ export default defineConfig([
sourcemap: true,
target: 'es2020',
platform: 'neutral',
+ loader: {
+ '.svg': 'dataurl',
+ },
+ publicDir: path.resolve(__dirname, 'assets'),
external: [
/^react/,
/^react-dom/,
@@ -50,6 +53,10 @@ export default defineConfig([
sourcemap: true,
target: 'es2020',
platform: 'neutral',
+ loader: {
+ '.svg': 'dataurl',
+ },
+ publicDir: path.resolve(__dirname, 'assets'),
external: [
/^react/,
/^react-dom/,
diff --git a/sdk/qrcode/types/svg.d.ts b/sdk/qrcode/types/svg.d.ts
new file mode 100644
index 000000000..cdb2b1a9a
--- /dev/null
+++ b/sdk/qrcode/types/svg.d.ts
@@ -0,0 +1,4 @@
+declare module '*.svg' {
+ const content: string;
+ export default content;
+}
diff --git a/sdk/qrcode/utils/styles.ts b/sdk/qrcode/utils/styles.ts
index df025b1d3..142420f65 100644
--- a/sdk/qrcode/utils/styles.ts
+++ b/sdk/qrcode/utils/styles.ts
@@ -1,22 +1,68 @@
-const containerStyle: React.CSSProperties = {
- display: 'flex',
+import React from 'react';
+
+import { QRcodeSteps } from './utils.js';
+
+const getBorderColor = (step: number): string => {
+ switch (step) {
+ case QRcodeSteps.DISCONNECTED:
+ case QRcodeSteps.WAITING_FOR_MOBILE:
+ return '#E2E8F0';
+ case QRcodeSteps.MOBILE_CONNECTED:
+ case QRcodeSteps.PROOF_GENERATION_STARTED:
+ case QRcodeSteps.PROOF_GENERATED:
+ return '#3B82F6';
+ case QRcodeSteps.PROOF_GENERATION_FAILED:
+ return '#EF4444';
+ case QRcodeSteps.PROOF_VERIFIED:
+ return '#01BFFF';
+ default:
+ return '#E2E8F0';
+ }
+};
+
+export const qrAnimationOverlayStyle = (imageSize: number): React.CSSProperties => ({
+ position: 'absolute',
+ top: '50%',
+ left: '50%',
+ transform: 'translate(-50%, -50%)',
+ width: imageSize,
+ height: imageSize,
+ pointerEvents: 'none',
+});
+
+export const qrContainerStyle = (size: number): React.CSSProperties => ({
+ position: 'relative',
+ width: size,
+ height: size,
+});
+
+export const qrWrapperStyle = (step: number, showBorder: boolean = true): React.CSSProperties => ({
+ display: 'inline-flex',
flexDirection: 'column',
alignItems: 'center',
- width: '100%',
+ gap: '6px',
+ padding: '3px',
+ borderRadius: '10px',
+ border: showBorder ? `6px solid ${getBorderColor(step)}` : 'none',
+ backgroundColor: '#FFF',
+ transition: 'border-color 0.3s ease',
+});
+
+export const statusBannerLogoStyle: React.CSSProperties = {
+ width: 28,
+ height: 28,
+ marginRight: 8,
};
-const ledContainerStyle: React.CSSProperties = {
- marginBottom: '4px',
-};
-
-const qrContainerStyle = (size: number): React.CSSProperties => ({
- width: `${size}px`,
- height: `${size}px`,
+export const statusBannerStyle = (qrSize: number): React.CSSProperties => ({
+ backgroundColor: '#000',
+ color: '#fff',
+ borderRadius: '5px',
+ width: qrSize,
+ fontWeight: '700',
+ fontSize: '18px',
+ height: '50px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
});
-
-export { containerStyle };
-export { ledContainerStyle };
-export { qrContainerStyle };
diff --git a/sdk/qrcode/utils/utils.ts b/sdk/qrcode/utils/utils.ts
index 9ecbed5ea..c419ecc9c 100644
--- a/sdk/qrcode/utils/utils.ts
+++ b/sdk/qrcode/utils/utils.ts
@@ -1,3 +1,6 @@
+import { statusConnecting, statusError, statusFailed, statusSuccess } from '../animations/index.js';
+import selfLogoBlack from '../assets/self-logo-qr.svg';
+
export const QRcodeSteps = {
DISCONNECTED: 0,
WAITING_FOR_MOBILE: 1,
@@ -7,3 +10,47 @@ export const QRcodeSteps = {
PROOF_GENERATED: 5,
PROOF_VERIFIED: 6,
};
+
+export const getStatusAnimation = (proofStep: number) => {
+ switch (proofStep) {
+ case QRcodeSteps.MOBILE_CONNECTED:
+ case QRcodeSteps.PROOF_GENERATION_STARTED:
+ case QRcodeSteps.PROOF_GENERATED:
+ return statusConnecting;
+ case QRcodeSteps.PROOF_VERIFIED:
+ return statusSuccess;
+ case QRcodeSteps.PROOF_GENERATION_FAILED:
+ return statusFailed;
+ default:
+ return statusError;
+ }
+};
+
+export const getStatusIcon = (proofStep: number): string => {
+ switch (proofStep) {
+ case QRcodeSteps.DISCONNECTED:
+ case QRcodeSteps.WAITING_FOR_MOBILE:
+ return selfLogoBlack;
+ default:
+ return '';
+ }
+};
+
+export const getStatusText = (proofStep: number): string => {
+ switch (proofStep) {
+ case QRcodeSteps.DISCONNECTED:
+ case QRcodeSteps.WAITING_FOR_MOBILE:
+ return 'Prove your Self';
+ case QRcodeSteps.MOBILE_CONNECTED:
+ case QRcodeSteps.PROOF_GENERATION_STARTED:
+ return 'Connected to Self';
+ case QRcodeSteps.PROOF_GENERATED:
+ return 'Proof Generated';
+ case QRcodeSteps.PROOF_VERIFIED:
+ return 'Proof Successful';
+ case QRcodeSteps.PROOF_GENERATION_FAILED:
+ return 'Proof Failed';
+ default:
+ return 'An error occurred';
+ }
+};