diff --git a/locales/en/index.yml b/locales/en/index.yml
index f141b4dcb7c..fe440eb1bec 100644
--- a/locales/en/index.yml
+++ b/locales/en/index.yml
@@ -3432,6 +3432,8 @@ features:
success:
title: "Done!"
subtitle: "Go back to the {{organizationName}} website to continue."
+ qrCodeScreen:
+ loading: "Wait a few seconds for the verification request..."
missingFeatureScreen:
headerTitle: "Screen not available"
title: "This screen will be available soon."
diff --git a/locales/it/index.yml b/locales/it/index.yml
index afc6d92d562..aff0d0d8c6c 100644
--- a/locales/it/index.yml
+++ b/locales/it/index.yml
@@ -3433,6 +3433,8 @@ features:
success:
title: "Fatto!"
subtitle: "Torna sul sito di {{organizationName}} per continuare."
+ qrCodeScreen:
+ loading: "Attendi qualche secondo la richiesta di verifica..."
missingFeatureScreen:
headerTitle: "Schermata non disponibile"
title: "Questa schermata sarĂ presto disponibile"
diff --git a/ts/features/it-wallet/navigation/ItwParamsList.ts b/ts/features/it-wallet/navigation/ItwParamsList.ts
index aa64758025d..e26917245ff 100644
--- a/ts/features/it-wallet/navigation/ItwParamsList.ts
+++ b/ts/features/it-wallet/navigation/ItwParamsList.ts
@@ -46,6 +46,9 @@ export type ItwParamsList = {
[ITW_ROUTES.PRESENTATION.CREDENTIAL.REMOTE.DATA]: undefined;
[ITW_ROUTES.PRESENTATION.CREDENTIAL.REMOTE.RESULT]: undefined;
+ // PRESENTATION PROXIMITY
+ [ITW_ROUTES.PRESENTATION.PROXIMITY.QRCODE]: undefined;
+
// GENERIC
[ITW_ROUTES.GENERIC.NOT_AVAILABLE]: undefined;
};
diff --git a/ts/features/it-wallet/navigation/ItwRoutes.ts b/ts/features/it-wallet/navigation/ItwRoutes.ts
index 04f5571294e..1b90e9b1c0a 100644
--- a/ts/features/it-wallet/navigation/ItwRoutes.ts
+++ b/ts/features/it-wallet/navigation/ItwRoutes.ts
@@ -40,6 +40,9 @@ export const ITW_ROUTES = {
DATA: "ITW_PRESENTATION_CREDENTIAL_DATA",
RESULT: "ITW_PRESETATION_CREDENTIAL_RESULT"
} as const
+ } as const,
+ PROXIMITY: {
+ QRCODE: "ITW_PRESENTATION_CROSS_DEVICE_QRCODE"
} as const
} as const,
GENERIC: {
diff --git a/ts/features/it-wallet/navigation/ItwStackNavigator.tsx b/ts/features/it-wallet/navigation/ItwStackNavigator.tsx
index 46976494a9e..d0034ac740f 100644
--- a/ts/features/it-wallet/navigation/ItwStackNavigator.tsx
+++ b/ts/features/it-wallet/navigation/ItwStackNavigator.tsx
@@ -25,6 +25,7 @@ import ItwCredentialsChecksScreen from "../screens/issuing/credential/ItwCredent
import ItwCredentialCatalogScreen from "../screens/issuing/credential/ItwCredentialCatalogScreen";
import ItwPrCredentialDetailsScreen from "../screens/presentation/ItwPrCredentialDetails";
import ItwPrPidDataScreen from "../screens/presentation/remote/pid/ItwPrPidDataScreen";
+import ItwPrProximityQrCodeScreen from "../screens/presentation/ItwPrProximityQrCodeScreen";
import { ItwParamsList } from "./ItwParamsList";
import { ITW_ROUTES } from "./ItwRoutes";
@@ -137,6 +138,12 @@ export const ItwStackNavigator = () => (
component={ItwPrCredentialResultScreen}
/>
+ {/* PRESENTATION PROXIMITY */}
+
+
{/* GENERIC */}
{
accessibilityLabel: I18n.t(
"features.itWallet.presentation.credentialDetails.buttons.qrCode"
),
- onPress: () => navigation.navigate(ITW_ROUTES.GENERIC.NOT_AVAILABLE)
+ onPress: () =>
+ navigation.navigate(ITW_ROUTES.PRESENTATION.PROXIMITY.QRCODE)
}
};
diff --git a/ts/features/it-wallet/screens/presentation/ItwPrPidDetails.tsx b/ts/features/it-wallet/screens/presentation/ItwPrPidDetails.tsx
index 5653a8fbc93..d2ec9e14cf2 100644
--- a/ts/features/it-wallet/screens/presentation/ItwPrPidDetails.tsx
+++ b/ts/features/it-wallet/screens/presentation/ItwPrPidDetails.tsx
@@ -51,7 +51,8 @@ const ItwPrPidDetails = () => {
),
icon: "qrCode",
iconPosition: "end",
- onPress: () => navigation.navigate(ITW_ROUTES.GENERIC.NOT_AVAILABLE)
+ onPress: () =>
+ navigation.navigate(ITW_ROUTES.PRESENTATION.PROXIMITY.QRCODE)
}
};
diff --git a/ts/features/it-wallet/screens/presentation/ItwPrProximityQrCodeScreen.tsx b/ts/features/it-wallet/screens/presentation/ItwPrProximityQrCodeScreen.tsx
new file mode 100644
index 00000000000..d9d9d41150e
--- /dev/null
+++ b/ts/features/it-wallet/screens/presentation/ItwPrProximityQrCodeScreen.tsx
@@ -0,0 +1,103 @@
+import * as React from "react";
+import { Image, SafeAreaView, View } from "react-native";
+import RNQRGenerator from "rn-qr-generator";
+import { IOStyles, LabelSmall, VSpacer } from "@pagopa/io-app-design-system";
+import { useNavigation } from "@react-navigation/native";
+import ItwLoadingSpinner from "../../components/ItwLoadingSpinner";
+import { useOnFirstRender } from "../../../../utils/hooks/useOnFirstRender";
+import { IOStackNavigationProp } from "../../../../navigation/params/AppParamsList";
+import { ItwParamsList } from "../../navigation/ItwParamsList";
+import I18n from "../../../../i18n";
+import BaseScreenComponent from "../../../../components/screens/BaseScreenComponent";
+import ItwKoView from "../../components/ItwKoView";
+import { getItwGenericMappedError } from "../../utils/errors/itwErrorsMapping";
+
+// A mocked QR code to be used in the proximity flow
+// TODO: remove this mocked QR code after the proximity flow is implemented [SIW-688]
+const mockedQrCode =
+ "mdoc:owBjMS4wAYIB2BhYS6QBAiABIVggUCnUgO0nCmTWOkqZLpQJh1uO2Q0YCTbYtUowBJU6ltEiWCBPkYpJZpEY4emfmR_2eFS5XQN68wihmgEoiMVEf8M3_gKBgwIBowD0AfULUJr9sL_rAkZCk114baNK4rY";
+
+/**
+ * A screen that shows a QR code to be scanned by the other device
+ * in order to start the proximity flow.
+ */
+const ItwPrProximityQrCodeScreen = () => {
+ const [qrCodeUri, setQrCodeUri] = React.useState("");
+ const [isLoading, setIsLoading] = React.useState(false);
+ const [isError, setIsError] = React.useState(false);
+ const navigation = useNavigation>();
+ useOnFirstRender(() => {
+ RNQRGenerator.generate({
+ value: mockedQrCode,
+ height: 300,
+ width: 300,
+ correctionLevel: "H"
+ })
+ .then(({ uri }) => {
+ setQrCodeUri(uri);
+ setIsLoading(true);
+ })
+ .catch(_ => {
+ setIsError(true);
+ });
+ });
+
+ /**
+ * This component is used to display a loading spinner and a text.
+ * It is used during proximity flow. After proximity integration [SIW-688] this
+ * component could show a message to the user related to the several steps
+ * of the proximity flow.
+ * @returns a loading component which displays a loading spinner and a text.
+ */
+ const LoadingComponent = () => (
+
+
+
+
+ {I18n.t("features.itWallet.presentation.qrCodeScreen.loading")}
+
+
+ );
+
+ /**
+ * Error view component which currently displays a generic error.
+ */
+ const ErrorView = () => {
+ const mappedError = getItwGenericMappedError(() => navigation.goBack());
+ return ;
+ };
+
+ if (isError) {
+ return ;
+ }
+
+ return (
+
+
+
+ {qrCodeUri !== "" && (
+ <>
+
+ {"Il tuo codice QR personale"}
+
+
+
+
+ {isLoading && }
+ >
+ )}
+
+
+
+ );
+};
+
+export default ItwPrProximityQrCodeScreen;