Skip to content

Commit

Permalink
feat(IT Wallet): [SIW-1853] Ipatente routing with IT Wallet (#6521)
Browse files Browse the repository at this point in the history
## Short description
This PR enables a link between the iPatente service and IT Wallet adding
a custom route parsing the credentialType used by iPatente service.

## List of changes proposed in this pull request
- A new error screen was added when the user tries to navigate to the
credential without having that specific credential.
- Added the navigation routing when using a specific deep link related
to the iPatente service.

## How to test
Use this deep link to navigate into the credential (MDL only) and check
these results:
- Wallet not active -> Error screen that route you to activate the
wallet
- Wallet active but MDL not requested -> Screen that route you to
request the MDL
- Wallet active MDL active -> MDL details screen

Deep link to be used: `ioit://itw/presentation/credential-detail/MDL`

Screenshot:
![IMAGE 2024-12-11
15:08:36](https://github.com/user-attachments/assets/ac182db6-273c-4163-bec7-670be8bb2b4d)

---------

Co-authored-by: Federico Mastrini <[email protected]>
  • Loading branch information
ale-mazz and mastro993 authored Dec 11, 2024
1 parent 86043f0 commit cf6423f
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 7 deletions.
3 changes: 3 additions & 0 deletions locales/en/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3432,6 +3432,9 @@ features:
bodyBold: Documenti su IO
primaryAction: Inizia
secondaryAction: Non ora
credentialNotFound:
title: "Aggiungi il documento al Portafoglio"
subtitle: "Per usare i documenti su IO, prima aggiungili al Portafoglio. È facile e veloce."
unsupportedDevice:
text: Starting from 02.07.2024 your device may no longer be compatible with IO.
moreInfo: More info
Expand Down
3 changes: 3 additions & 0 deletions locales/it/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3432,6 +3432,9 @@ features:
bodyBold: Documenti su IO
primaryAction: Inizia
secondaryAction: Non ora
credentialNotFound:
title: "Aggiungi il documento al Portafoglio"
subtitle: "Per usare i documenti su IO, prima aggiungili al Portafoglio. È facile e veloce."
unsupportedDevice:
text: Starting from 02.07.2024 your device may no longer be compatible with IO.
moreInfo: More info
Expand Down
61 changes: 61 additions & 0 deletions ts/features/itwallet/common/components/ItwCredentialNotFound.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React, { useEffect } from "react";
import { OperationResultScreenContent } from "../../../../components/screens/OperationResultScreenContent";
import I18n from "../../../../i18n";
import { ItwCredentialIssuanceMachineContext } from "../../machine/provider";
import { useIONavigation } from "../../../../navigation/params/AppParamsList";
import { useItwDisableGestureNavigation } from "../hooks/useItwDisableGestureNavigation";
import { useAvoidHardwareBackButton } from "../../../../utils/useAvoidHardwareBackButton";

const ItwCredentialNotFound = ({
credentialType
}: {
credentialType: string;
}) => {
const machineRef = ItwCredentialIssuanceMachineContext.useActorRef();
const navigation = useIONavigation();

// Disable the back gesture navigation and the hardware back button
useItwDisableGestureNavigation();
useAvoidHardwareBackButton();

const navigateToCredential = () => {
machineRef.send({
type: "select-credential",
credentialType
});
};

const handleClose = () => {
navigation.pop();
};

// Since this component could be used on a screen where the header is visible, we hide it.
useEffect(() => {
navigation.setOptions({
headerShown: false
});
}, [navigation]);

return (
<OperationResultScreenContent
pictogram="cie"
title={I18n.t("features.itWallet.issuance.credentialNotFound.title")}
subtitle={I18n.t(
"features.itWallet.issuance.credentialNotFound.subtitle"
)}
isHeaderVisible={false}
action={{
label: I18n.t("global.buttons.continue"),
accessibilityLabel: I18n.t("global.buttons.continue"),
onPress: navigateToCredential
}}
secondaryAction={{
label: I18n.t("global.buttons.cancel"),
accessibilityLabel: I18n.t("global.buttons.cancel"),
onPress: handleClose
}}
/>
);
};

export default ItwCredentialNotFound;
4 changes: 2 additions & 2 deletions ts/features/itwallet/navigation/ItwStackNavigator.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
TransitionPresets,
createStackNavigator
createStackNavigator,
TransitionPresets
} from "@react-navigation/stack";
import * as React from "react";
import { Platform } from "react-native";
Expand Down
7 changes: 6 additions & 1 deletion ts/features/itwallet/navigation/useItwLinkingOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ export const useItwLinkingOptions = (): PathConfigMap<AppParamsList> => {
"credential/issuance",
[isItwValid
? ITW_ROUTES.DISCOVERY.ALREADY_ACTIVE_SCREEN
: ITW_ROUTES.DISCOVERY.INFO]: "discovery/info"
: ITW_ROUTES.DISCOVERY.INFO]: "discovery/info",
[isItwValid
? ITW_ROUTES.PRESENTATION.CREDENTIAL_DETAIL
: ITW_ROUTES.ISSUANCE.CREDENTIAL_ASYNC_FLOW_CONTINUATION]: {
path: "presentation/credential-detail/:credentialType"
}
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
trackCredentialDetail,
trackWalletCredentialShowFAC_SIMILE
} from "../../analytics";
import { ItwGenericErrorContent } from "../../common/components/ItwGenericErrorContent";
import { WellKnownClaim } from "../../common/utils/itwClaimsUtils";
import { StoredCredential } from "../../common/utils/itwTypesUtils";
import {
Expand All @@ -35,6 +34,7 @@ import {
ItwPresentationDetailsScreenBase
} from "../components/ItwPresentationDetailsScreenBase";
import { ItwCredentialTrustmark } from "../../trustmark/components/ItwCredentialTrustmark";
import ItwCredentialNotFound from "../../common/components/ItwCredentialNotFound";

export type ItwPresentationCredentialDetailNavigationParams = {
credentialType: string;
Expand All @@ -55,9 +55,8 @@ export const ItwPresentationCredentialDetailScreen = ({ route }: Props) => {
);

if (O.isNone(credentialOption)) {
// This is unlikely to happen, but we want to handle the case where the credential is not found
// because of inconsistencies in the state, and assert that the credential is O.some
return <ItwGenericErrorContent />;
// If the credential is not found, we render a screen that allows the user to request that credential.
return <ItwCredentialNotFound credentialType={credentialType} />;
}

return (
Expand Down

0 comments on commit cf6423f

Please sign in to comment.