-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(IT Wallet): [SIW-1036] Add eID detail screen (#5801)
> [!WARNING] > This PR depends on #5780 ## Short description This PR adds the credential detail screen for the eID. The screen can support other credential types as well, it would just need a bit more fine tuning. > [!Note] > In the detail screen claims are grouped into sections, but this information is not included in the credential itself. To work around this, a mapping claim-section has been hardcoded in app. Claims that can not be assigned to any section are displayed after all the others. > The **eID credential** used is also a **mock**. ## List of changes proposed in this pull request - Extracted `RenderPidAssuranceLevel` and `RenderReleaserName` into separate components for easier reuse - Added `ItwPresentationEidDetailScreen` component with related sub-components - Modified `ItwCredentialClaim` to support hidden claims and dates with icon and badge - Add utils in `itwClaimsUtils` to handle hardcoded claims configurations ## How to test Navigate to **Profile > IT Wallet > Credential detail (eID)**. You should be able to see the eID detail screen. ## Preview |iOS|Android| |---|--------| |<video src="https://github.com/pagopa/io-app/assets/52289599/03ab3b16-838f-4eb0-bbe4-006f1324692e">|<video src="https://github.com/pagopa/io-app/assets/52289599/7a7a7feb-f994-4669-9083-b398311d0086">| --------- Co-authored-by: Federico Mastrini <[email protected]> Co-authored-by: Damiano Plebani <[email protected]> Co-authored-by: Mario Perrotta <[email protected]>
- Loading branch information
1 parent
c0fe107
commit f6e0e19
Showing
21 changed files
with
1,742 additions
and
123 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 11 additions & 110 deletions
121
ts/features/itwallet/common/components/ItwCredentialClaimList.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,135 +1,36 @@ | ||
import { ListItemInfo } from "@pagopa/io-app-design-system"; | ||
import { SdJwt } from "@pagopa/io-react-native-wallet"; | ||
import React from "react"; | ||
import { Alert, View } from "react-native"; | ||
import I18n from "../../../../i18n"; | ||
import { useItwInfoBottomSheet } from "../hooks/useItwInfoBottomSheet"; | ||
import { View } from "react-native"; | ||
import { parseClaims, sortClaims } from "../utils/itwClaimsUtils"; | ||
import { CredentialType, mapAssuranceLevel } from "../utils/itwMocksUtils"; | ||
import { StoredCredential } from "../utils/itwTypesUtils"; | ||
import { ItwCredentialClaim } from "./ItwCredentialClaim"; | ||
import { ItwReleaserName } from "./ItwReleaserName"; | ||
import { ItwPidAssuranceLevel } from "./ItwPidAssuranceLevel"; | ||
|
||
/** | ||
* This component renders the list of claims for a credential. | ||
* It dinamically renders the list of claims passed as claims prop in the order they are passed. | ||
* @param data - the {@link StoredCredential} of the credential. | ||
*/ | ||
export const ItwCredentialClaimsList = ({ | ||
data: { | ||
parsedCredential, | ||
displayData, | ||
issuerConf, | ||
credential, | ||
credentialType | ||
} | ||
data, | ||
isPreview | ||
}: { | ||
data: StoredCredential; | ||
isPreview?: boolean; | ||
}) => { | ||
const claims = parseClaims(sortClaims(displayData.order, parsedCredential)); | ||
|
||
/** | ||
* Renders the releaser name with an info button that opens the bottom sheet. | ||
* This is not part of the claims list because it's not a claim. | ||
* Thus it's rendered separately. | ||
* @param releaserName - the releaser name. | ||
* @returns the list item with the releaser name. | ||
*/ | ||
const RenderReleaserName = () => { | ||
const releaserName = issuerConf.federation_entity.organization_name; | ||
const label = I18n.t( | ||
"features.itWallet.verifiableCredentials.claims.releasedBy" | ||
); | ||
const releasedByBottomSheet = useItwInfoBottomSheet({ | ||
title: | ||
releaserName ?? | ||
I18n.t("features.itWallet.generic.placeholders.organizationName"), | ||
content: [ | ||
{ | ||
title: I18n.t( | ||
"features.itWallet.issuance.credentialPreview.bottomSheet.about.title" | ||
), | ||
body: I18n.t( | ||
"features.itWallet.issuance.credentialPreview.bottomSheet.about.subtitle" | ||
) | ||
}, | ||
{ | ||
title: I18n.t( | ||
"features.itWallet.issuance.credentialPreview.bottomSheet.data.title" | ||
), | ||
body: I18n.t( | ||
"features.itWallet.issuance.credentialPreview.bottomSheet.data.subtitle" | ||
) | ||
} | ||
] | ||
}); | ||
const { parsedCredential, displayData } = data; | ||
|
||
return ( | ||
<> | ||
{releaserName ? ( | ||
<> | ||
<ListItemInfo | ||
endElement={{ | ||
type: "iconButton", | ||
componentProps: { | ||
icon: "info", | ||
accessibilityLabel: "test", | ||
onPress: () => releasedByBottomSheet.present() | ||
} | ||
}} | ||
label={label} | ||
value={releaserName} | ||
accessibilityLabel={`${label} ${releaserName}`} | ||
/> | ||
{releasedByBottomSheet.bottomSheet} | ||
</> | ||
) : null} | ||
</> | ||
); | ||
}; | ||
|
||
/** | ||
* Renders the PID assurance level with an info button that currenlt navigates to a not available screen. | ||
* If the credential is not a PID credential, it returns null. | ||
* This is not part of the claims list because it's not a claim. | ||
* Thus it's rendered separately. | ||
* @returns the list item with the PID assurance level. | ||
*/ | ||
const RenderPidAssuranceLevel = () => { | ||
if (credentialType === CredentialType.PID) { | ||
const { sdJwt } = SdJwt.decode(credential, SdJwt.SdJwt4VC); | ||
const assuranceLevel = mapAssuranceLevel( | ||
sdJwt.payload.verified_claims.verification.assurance_level | ||
); | ||
return ( | ||
<ListItemInfo | ||
label={I18n.t( | ||
"features.itWallet.verifiableCredentials.claims.securityLevel" | ||
)} | ||
value={assuranceLevel} | ||
endElement={{ | ||
type: "iconButton", | ||
componentProps: { | ||
icon: "info", | ||
onPress: () => Alert.alert("Not available"), | ||
accessibilityLabel: "" | ||
} | ||
}} | ||
/> | ||
); | ||
} else { | ||
return null; | ||
} | ||
}; | ||
const claims = parseClaims(sortClaims(displayData.order, parsedCredential)); | ||
|
||
return ( | ||
<> | ||
{claims.map((elem, index) => ( | ||
<View key={index}> | ||
<ItwCredentialClaim claim={elem} /> | ||
<ItwCredentialClaim claim={elem} isPreview={isPreview} /> | ||
</View> | ||
))} | ||
<RenderReleaserName /> | ||
<RenderPidAssuranceLevel /> | ||
<ItwReleaserName credential={data} /> | ||
<ItwPidAssuranceLevel credential={data} /> | ||
</> | ||
); | ||
}; |
54 changes: 54 additions & 0 deletions
54
ts/features/itwallet/common/components/ItwCredentialClaimsSection.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import React, { useState } from "react"; | ||
import { StyleSheet, View } from "react-native"; | ||
import { IconButton, H6 } from "@pagopa/io-app-design-system"; | ||
import I18n from "../../../../i18n"; | ||
import { ClaimDisplayFormat } from "../utils/itwClaimsUtils"; | ||
import { ItwCredentialClaim } from "./ItwCredentialClaim"; | ||
|
||
type Props = { | ||
title: string; | ||
claims: ReadonlyArray<ClaimDisplayFormat>; | ||
canHideValues?: boolean; | ||
}; | ||
|
||
export const ItwCredentialClaimsSection = ({ | ||
title, | ||
canHideValues, | ||
claims | ||
}: Props) => { | ||
const [valuesHidden, setValuesHidden] = useState(false); | ||
|
||
const renderHideValuesToggle = () => ( | ||
<IconButton | ||
testID="toggle-claim-visibility" | ||
icon={valuesHidden ? "eyeHide" : "eyeShow"} | ||
onPress={() => setValuesHidden(x => !x)} | ||
accessibilityLabel={I18n.t( | ||
valuesHidden | ||
? "features.itWallet.presentation.credentialDetails.actions.showClaimValues" | ||
: "features.itWallet.presentation.credentialDetails.actions.hideClaimValues" | ||
)} | ||
/> | ||
); | ||
|
||
return ( | ||
<View> | ||
<View style={styles.header}> | ||
<H6 color="grey-700">{title}</H6> | ||
{canHideValues && renderHideValuesToggle()} | ||
</View> | ||
<View> | ||
{claims.map(c => ( | ||
<ItwCredentialClaim key={c.id} claim={c} hidden={valuesHidden} /> | ||
))} | ||
</View> | ||
</View> | ||
); | ||
}; | ||
|
||
const styles = StyleSheet.create({ | ||
header: { | ||
justifyContent: "space-between", | ||
flexDirection: "row" | ||
} | ||
}); |
Oops, something went wrong.