Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(IT Wallet): [SIW-1933] Handle Trustmark QR code generation failures #6558

Merged
merged 19 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions locales/de/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ inbox:
enableButton: "Posteingang aktivieren"
disableButton: "Posteingang deaktivieren"
enableCallToActionDescription: "Aktiviere den Posteingang, um Mitteilungen anzusehen"
settings:
informativeBanner:
settings:
informativeBanner:
content: "Suchst du dein Profil? Wir haben es verschoben, es befindet sich jetzt in der oberen rechten Ecke!"
action: "Geh zu den Einstellungen"
profile:
Expand Down Expand Up @@ -443,7 +443,7 @@ profile:
body: "Wenn du dies bestätigst, können wir dir nicht gezielt helfen, da uns möglicherweise die notwendigen Daten zur Lösung des Problems fehlen."
whyBottomSheet:
title: "Warum wir Daten erfassen"
body: "Wir sammeln keine Daten für Marketingzwecke. \n\nWir verwenden Tools, die es uns ermöglichen, Daten darüber aufzuzeichnen, wie du die App nutzt, um **dir einen besseren Service zu bieten** und **dich bei Bedarf zu unterstützen**."
body: "Wir sammeln keine Daten für Marketingzwecke. \n\nWir verwenden Tools, die es uns ermöglichen, Daten darüber aufzuzeichnen, wie du die App nutzt, um **dir einen besseren Service zu bieten** und **dich bei Bedarf zu unterstützen**."
securityBottomSheet:
title: "Was ist eine Pseudonymisierung?"
body: "Sie ist die Verarbeitung personenbezogener Daten in einer Weise, dass die personenbezogener Daten ohne Hinzuziehung zusätzlicher Informationen nicht mehr einer bestimmten betroffenen Person zugeordnet werden können, sofern diese zusätzlichen Informationen gesondert aufbewahrt werden und technischen und organisatorischen Maßnahmen unterliegen, die gewährleisten, dass diese personenbezogener Daten nicht einer identifizierten oder identifizierbaren natürlichen Person zugewiesen werden können."
Expand Down Expand Up @@ -2711,9 +2711,9 @@ features:
delete:
successful: "Die Quittung wurde ausgeblendet"
failed: "Es ist ein Fehler aufgetreten, bitte versuche es erneut"
hideBanner:
hideBanner:
title: "Möchtest du diese Quittung aus deiner Liste ausblenden?"
content: "Dieser Vorgang ist unwiderruflich. Die Quittung wird nicht mehr in deiner Quittungsliste angezeigt."
content: "Dieser Vorgang ist unwiderruflich. Die Quittung wird nicht mehr in deiner Quittungsliste angezeigt."
accept: "Ja, ausblenden"
details:
totalFeeUnknown: "Der Gesamtbetrag enthält keine Provisionskosten: du findest diese in dem Dokument, das du von {{pspName}} erhalten hast."
Expand All @@ -2731,7 +2731,7 @@ features:
empty:
title: "Keine Quittung gefunden"
subtitle: "Wenn du eine Quittung für eine pagoPA-Zahlungsmitteilung suchst, die du in der Vergangenheit bezahlt hast, wende dich an den Gläubiger."
emptyPayer:
emptyPayer:
title: "Hier findest du Quittungen für Zahlungen, die mit der App getätigt wurden."
details:
payPal:
Expand Down Expand Up @@ -3023,13 +3023,12 @@ features:
content: "Dies ist ein notwendiger Sicherheitsschritt, um das Dokument '{{credentialName}}' in IO weiter zu verwenden."
primaryAction: "Start"
ctas:
trustmark: "Echtheitszertifikat anzeigen"
openPdf: "Dokument anzeigen"
shareButton: "Speichern oder freigeben"
fiscalCode: "Deine Steuernummer"
trustmark:
cta: "Echtheitszertifikat anzeigen"
description: "Zeige den QR-Code vor, um die Echtheit des Dokuments zu bestätigen, wenn du dazu aufgefordert wirst."
expiration: "Der QR-Code erneuert sich in"
qrCode: "QR-Code zur Authentizität von Dokumenten"
walletRevocation:
cta: "Dokumente in IO deaktivieren"
Expand All @@ -3053,7 +3052,7 @@ features:
cta: "Mehr erfahren"
closeButton: "Schließen"
closeButtonAlt: "Verstanden"
revokedByWalletProvider:
revokedByWalletProvider:
title: "Dokumente in IO wurde deaktiviert"
content: "Um die Voraussetzungen für die weitere Nutzung der Funktionen auf deinem Gerät zu prüfen, tippe auf 'Mehr erfahren'."
newWalletInstanceCreated:
Expand Down
25 changes: 20 additions & 5 deletions locales/en/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ date:
meridian:
- "am"
- "pm"
time:
minutes:
zero: "0 minutes"
one: "1 minute"
other: "{{count}} minutes"
seconds:
zero: "0 seconds"
one: "1 second"
other: "{{count}} seconds"
global:
why: "Perché?"
you: "YOU"
Expand Down Expand Up @@ -3240,7 +3249,7 @@ features:
empty:
title: Nessuna ricevuta trovata
subtitle: Se stai cercando la ricevuta di un avviso pagoPA che hai pagato in passato, rivolgiti all’ente creditore.
emptyPayer:
emptyPayer:
title: Qui vedrai le ricevute dei pagamenti fatti in app
details:
payPal:
Expand Down Expand Up @@ -3536,18 +3545,24 @@ features:
content: È un passaggio di sicurezza necessario per continuare ad usare la tua {{credentialName}} su IO.
primaryAction: Inizia
ctas:
openPdf: "Show document"
trustmark: Mostra certificato di autenticità
openPdf: Show document
shareButton: Save or share
fiscalCode: Your Fiscal Code
statusAttestationUnknown:
title: Non siamo riusciti a caricare {{credentialName}}
content: Chiudi e riapri l'app per riprovare.
primaryAction: Ho capito
trustmark:
cta: Mostra certificato di autenticità
description: Mostra il QR Code per attestare l’autenticità del documento quando ti viene richiesto.
expiration: Il QR Code si rinnova tra
qrCode: QR code autenticità credenziale
timer:
expiresIn: Il QR Code si rinnova tra **{{time}}**
expired: Il QR Code è scaduto
failure:
description: Abbiamo avuto un problema nel generare il nuovo QR Code.
action: Riprova
toast: "Puoi riprovare tra {{time}}"
walletRevocation:
cta: Disattiva Documenti su IO
confirmScreen:
Expand All @@ -3570,7 +3585,7 @@ features:
cta: Scopri di più
closeButton: Chiudi
closeButtonAlt: Ho capito
revokedByWalletProvider:
revokedByWalletProvider:
title: Documenti su IO è stata disattivata
content: Per verificare i requisiti richiesti per continuare a usare la funzionalità sul tuo dispositivo, premi "Scopri di più".
newWalletInstanceCreated:
Expand Down
23 changes: 19 additions & 4 deletions locales/it/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ date:
meridian:
- "am"
- "pm"
time:
minutes:
zero: "0 minuti"
one: "1 minuto"
other: "{{count}} minuti"
seconds:
zero: "0 secondi"
one: "1 secondo"
other: "{{count}} secondi"
global:
why: "Perché?"
you: "TU"
Expand Down Expand Up @@ -3240,7 +3249,7 @@ features:
empty:
title: Nessuna ricevuta trovata
subtitle: Se stai cercando la ricevuta di un avviso pagoPA che hai pagato in passato, rivolgiti all’ente creditore.
emptyPayer:
emptyPayer:
title: Qui vedrai le ricevute dei pagamenti fatti in app
details:
payPal:
Expand Down Expand Up @@ -3536,6 +3545,7 @@ features:
content: È un passaggio di sicurezza necessario per continuare ad usare la tua {{credentialName}} su IO.
primaryAction: Inizia
ctas:
trustmark: Mostra certificato di autenticità
openPdf: "Mostra documento"
shareButton: Salva o condividi
fiscalCode: Il tuo Codice Fiscale
Expand All @@ -3544,10 +3554,15 @@ features:
content: Chiudi e riapri l'app per riprovare.
primaryAction: Ho capito
trustmark:
cta: Mostra certificato di autenticità
description: Mostra il QR Code per attestare l’autenticità del documento quando ti viene richiesto.
expiration: Il QR Code si rinnova tra
qrCode: QR code autenticità credenziale
timer:
expiresIn: Il QR Code si rinnova tra **{{time}}**
expired: Il QR Code è scaduto
failure:
description: Abbiamo avuto un problema nel generare il nuovo QR Code.
action: Riprova
toast: "Puoi riprovare tra {{time}}"
walletRevocation:
cta: Disattiva Documenti su IO
confirmScreen:
Expand All @@ -3570,7 +3585,7 @@ features:
cta: Scopri di più
closeButton: Chiudi
closeButtonAlt: Ho capito
revokedByWalletProvider:
revokedByWalletProvider:
title: Documenti su IO è stata disattivata
content: Per verificare i requisiti richiesti per continuare a usare la funzionalità sul tuo dispositivo, premi "Scopri di più".
newWalletInstanceCreated:
Expand Down
6 changes: 5 additions & 1 deletion ts/components/QrCodeImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export type QrCodeImageProps = {
correctionLevel?: QRCodeProps["ecl"];
// Accessibility
accessibilityLabel?: string;
// Callback to handle the error if the QR Code generation fails
onError?: (error: Error) => void;
};

const defaultAccessibilityLabel = "QR Code";
Expand All @@ -27,7 +29,8 @@ const QrCodeImage = ({
size = 200,
backgroundColor,
correctionLevel = "H",
accessibilityLabel = defaultAccessibilityLabel
accessibilityLabel = defaultAccessibilityLabel,
onError
}: QrCodeImageProps) => {
const { width } = useWindowDimensions();
const realSize = React.useMemo<number>(() => {
Expand All @@ -49,6 +52,7 @@ const QrCodeImage = ({
size={realSize}
ecl={correctionLevel}
backgroundColor={backgroundColor}
onError={onError}
/>
</View>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,9 @@ export const ItwCredentialTrustmark = ({
onPress={onPressWithTrackEvent}
testID={testID}
accessible={true}
accessibilityLabel={I18n.t("features.itWallet.trustmark.cta")}
accessibilityLabel={I18n.t(
"features.itWallet.presentation.ctas.trustmark"
)}
accessibilityRole="button"
onPressIn={onPressIn}
onPressOut={onPressOut}
Expand All @@ -321,7 +323,9 @@ export const ItwCredentialTrustmark = ({
<View style={styles.buttonInnerBorder} />
<View style={styles.content}>
<Caption>
{I18n.t("features.itWallet.trustmark.cta").toUpperCase()}
{I18n.t(
"features.itWallet.presentation.ctas.trustmark"
).toUpperCase()}
</Caption>
{!enableIridescence && (
<Image
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Body, HSpacer, Icon, IOStyles } from "@pagopa/io-app-design-system";
import { format } from "date-fns";
import React, { useMemo } from "react";
import { View } from "react-native";
import Placeholder from "rn-placeholder";
import { useDebugInfo } from "../../../../hooks/useDebugInfo";
import I18n from "../../../../i18n";
import { ItwTrustmarkMachineContext } from "../machine/provider";
import { selectExpirationSeconds, selectFailure } from "../machine/selectors";
import IOMarkdown from "../../../../components/IOMarkdown";

/**
* Timer that shows the remaining time before the trustmark expires
*/
const ItwTrustmarkExpirationTimer = () => {
const expirationSeconds = ItwTrustmarkMachineContext.useSelector(
selectExpirationSeconds
);
const failure = ItwTrustmarkMachineContext.useSelector(selectFailure);

useDebugInfo({ expirationSeconds, failure });

const content = useMemo(() => {
if (failure) {
return <Body>{I18n.t("features.itWallet.trustmark.timer.expired")}</Body>;
}

if (expirationSeconds === undefined) {
return (
<Placeholder.Box height={18} width={200} animate="fade" radius={4} />
);
}

return (
<IOMarkdown
content={I18n.t("features.itWallet.trustmark.timer.expiresIn", {
time: format(new Date(expirationSeconds * 1000), "mm:ss")
})}
/>
);
}, [failure, expirationSeconds]);

return (
<View style={[IOStyles.row, IOStyles.alignCenter]}>
<Icon name="history" size={24} color="grey-300" />
<HSpacer size={24} />
{content}
</View>
);
};

export { ItwTrustmarkExpirationTimer };
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {
Body,
ButtonLink,
Icon,
IOColors,
IOVisualCostants
} from "@pagopa/io-app-design-system";
import React, { useCallback, useMemo } from "react";
import { StyleSheet, View } from "react-native";
import { QrCodeImage } from "../../../../components/QrCodeImage";
import { useDebugInfo } from "../../../../hooks/useDebugInfo";
import I18n from "../../../../i18n";
import { ItwTrustmarkMachineContext } from "../machine/provider";
import { selectFailure, selectTrustmarkUrl } from "../machine/selectors";

/**
* Component that renders the QR code of the trustmark
*/
const ItwTrustmarkQrCode = () => {
const machineRef = ItwTrustmarkMachineContext.useActorRef();
const trustmarkUrl =
ItwTrustmarkMachineContext.useSelector(selectTrustmarkUrl);
const failure = ItwTrustmarkMachineContext.useSelector(selectFailure);

useDebugInfo({ trustmarkUrl, failure });

const handleOnRetry = useCallback(() => {
machineRef.send({ type: "retry" });
}, [machineRef]);

const content = useMemo(() => {
if (failure) {
return (
<View style={styles.alert}>
<Icon name="noticeFilled" size={24} color="grey-700" />
<Body textStyle={{ textAlign: "center" }}>
{I18n.t("features.itWallet.trustmark.failure.description")}
</Body>
<View>
<ButtonLink
label={I18n.t("features.itWallet.trustmark.failure.action")}
onPress={handleOnRetry}
/>
</View>
</View>
);
}

return (
<QrCodeImage
size={"92%"}
value={trustmarkUrl}
correctionLevel="L"
accessibilityLabel={I18n.t("features.itWallet.trustmark.qrCode")}
/>
);
}, [failure, trustmarkUrl, handleOnRetry]);

return <View style={styles.container}>{content}</View>;
};

const styles = StyleSheet.create({
container: {
marginHorizontal: -IOVisualCostants.appMarginDefault,
alignItems: "center"
},
alert: {
backgroundColor: IOColors["grey-50"],
width: "92%",
alignItems: "center",
justifyContent: "center",
aspectRatio: 1,
padding: 16,
borderRadius: 16,
gap: 8
}
});

export { ItwTrustmarkQrCode };
Loading
Loading