Skip to content

Commit

Permalink
feat: pw onboarding
Browse files Browse the repository at this point in the history
  • Loading branch information
janrtvld committed Jan 14, 2025
1 parent ee74d80 commit 35d3b16
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 176 deletions.
23 changes: 16 additions & 7 deletions apps/easypid/src/features/menu/FunkeAboutScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,22 @@ import React from 'react'
import { TextBackButton } from 'packages/app'
import { Linking } from 'react-native'

import { useIsFunkeWallet } from '@easypid/hooks/useFeatureFlag'
import pj from '../../../package.json'

const TEXT_FUNKE = `This app was created by Animo Solutions in the context of the SPRIN-D Funke ‘EUDI Wallet Prototypes’. It
serves as a prototype for future wallet providers. All code is available under Apache 2.0.`

const TEXT_PARADYM =
'This app was created by Animo Solutions as a companion app for Paradym. All code is available under Apache 2.0.'

export function FunkeAboutScreen() {
const isFunkeWallet = useIsFunkeWallet()

const openContact = () => {
Linking.openURL('mailto:[email protected]?subject=Reach out from Funke EUDI Wallet')
Linking.openURL(
`mailto:[email protected]?subject=Reach out from ${isFunkeWallet ? 'Funke EUDI Wallet' : 'Paradym Wallet'}`
)
}

const openPrivacyPolicy = () => {
Expand All @@ -20,15 +31,13 @@ export function FunkeAboutScreen() {
<HeaderContainer title="About the wallet" />
<YStack fg={1} px="$4" gap="$4">
<YStack gap="$2">
<Paragraph color="$grey-700">
This app was created by Animo Solutions in the context of the SPRIN-D Funke ‘EUDI Wallet Prototypes’. It
serves as a prototype for future wallet providers. All code is available under Apache 2.0.
</Paragraph>
<Paragraph color="$grey-700">{isFunkeWallet ? TEXT_FUNKE : TEXT_PARADYM}</Paragraph>
<Paragraph>
For more information on the project visit sprind.org or reach out to{' '}
For more information, reach out to{' '}
<Paragraph fontWeight="$semiBold" color="$primary-500" onPress={openContact}>
[email protected]
</Paragraph>
.
</Paragraph>
</YStack>
<YStack gap="$2" fg={1} jc="space-between">
Expand All @@ -40,7 +49,7 @@ export function FunkeAboutScreen() {
onPress={openPrivacyPolicy}
/>
<Paragraph py="$4" mx="auto" variant="sub" fontSize={13} fontWeight="$medium">
EasyPID version: {pj.version}
Paradym Wallet version: {pj.version}
</Paragraph>
</YStack>
</YStack>
Expand Down
46 changes: 25 additions & 21 deletions apps/easypid/src/features/menu/FunkeMenuScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
} from '@package/ui'

import { usePidCredential } from '@easypid/hooks'
import { useFeatureFlag } from '@easypid/hooks/useFeatureFlag'
import { useWalletReset } from '@easypid/hooks/useWalletReset'
import { TextBackButton } from '@package/app'
import { Link } from 'expo-router'
Expand Down Expand Up @@ -53,28 +54,31 @@ export function FunkeMenuScreen() {
const { handleScroll, isScrolledByOffset, scrollEventThrottle } = useScrollViewPosition()
const onResetWallet = useWalletReset()
const { credential } = usePidCredential()
const hasEidCardFeatureFlag = useFeatureFlag('EID_CARD')

const idItem = credential ? (
<MenuItem
key="id"
item={{
href: `credentials/${credential.id}`,
icon: HeroIcons.IdentificationFilled,
title: 'Your digital ID',
}}
idx={0}
/>
) : (
<MenuItem
key="id"
item={{
href: '/pidSetup',
icon: HeroIcons.IdentificationFilled,
title: 'Setup digital ID',
}}
idx={0}
/>
)
const idItem = hasEidCardFeatureFlag ? (
credential ? (
<MenuItem
key="id"
item={{
href: `credentials/${credential.id}`,
icon: HeroIcons.IdentificationFilled,
title: 'Your digital ID',
}}
idx={0}
/>
) : (
<MenuItem
key="id"
item={{
href: '/pidSetup',
icon: HeroIcons.IdentificationFilled,
title: 'Setup digital ID',
}}
idx={0}
/>
)
) : null

return (
<FlexPage gap="$0" paddingHorizontal="$0">
Expand Down
99 changes: 5 additions & 94 deletions apps/easypid/src/features/onboarding/onboardingContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { sendCommand } from '@animo-id/expo-ausweis-sdk'
import type { SdJwtVcHeader } from '@credo-ts/core'
import { type AppAgent, initializeAppAgent, useSecureUnlock } from '@easypid/agent'
import { setWalletServiceProviderPin } from '@easypid/crypto/WalletServiceProviderClient'
import { useFeatureFlag } from '@easypid/hooks/useFeatureFlag'
import { ReceivePidUseCaseCFlow } from '@easypid/use-cases/ReceivePidUseCaseCFlow'
import type {
CardScanningErrorDetails,
Expand All @@ -14,7 +15,6 @@ import {
type OnboardingPage,
type OnboardingStep,
SIMULATOR_PIN,
pidSetupSteps,
} from '@easypid/utils/sharedPidSetup'
import {
BiometricAuthenticationCancelledError,
Expand All @@ -34,99 +34,9 @@ import { Linking, Platform } from 'react-native'
import type { PidSdJwtVcAttributes } from '../../hooks'
import { addReceivedActivity } from '../activity/activityRecord'
import { useHasFinishedOnboarding } from './hasFinishedOnboarding'
import { OnboardingBiometrics } from './screens/biometrics'
import { OnboardingIntroductionSteps } from './screens/introduction-steps'
import OnboardingPinEnter from './screens/pin'
import { OnboardingWalletExplanation } from './screens/wallet-explanation'
import OnboardingWelcome from './screens/welcome'
import { onboardingSteps } from './steps'
import { useShouldUseCloudHsm } from './useShouldUseCloudHsm'

export const onboardingSteps = [
{
step: 'welcome',
alternativeFlow: false,
progress: 0,
page: {
type: 'fullscreen',
},
Screen: OnboardingWelcome,
},
{
step: 'wallet-explanation',
alternativeFlow: false,
progress: 0.1,
page: {
animation: 'delayed',
type: 'content',
title: '',
},
Screen: OnboardingWalletExplanation,
},

{
step: 'introduction-steps',
alternativeFlow: false,
progress: 20,
page: {
animation: 'delayed',
type: 'content',
title: 'Set up your wallet',
subtitle: 'Before you can use the app, we will guide you through these steps.',
},
Screen: OnboardingIntroductionSteps,
},

{
step: 'pin',
alternativeFlow: false,
progress: 30,
page: {
type: 'content',
title: 'Choose a 6-digit PIN',
subtitle: 'This PIN secures your identity wallet. You enter it every time you share data.',
animationKey: 'pin',
},
Screen: OnboardingPinEnter,
},
{
step: 'pin-reenter',
alternativeFlow: false,
progress: 30,
page: {
type: 'content',
title: 'Repeat your PIN',
subtitle: 'This PIN secures your identity wallet. You enter it every time you share data.',
animationKey: 'pin',
},
Screen: OnboardingPinEnter,
},
{
step: 'biometrics',
alternativeFlow: false,
progress: 40,
page: {
type: 'content',
title: 'Set up biometrics',
subtitle:
'Activate the biometrics functionality of your phone to make sure only you can enter your wallet and share data.',
},
Screen: OnboardingBiometrics,
},
{
step: 'biometrics-disabled',
progress: 40,
alternativeFlow: true,
page: {
type: 'content',
title: 'You need to enable biometrics',
subtitle:
'To continue, make sure your device has biometric protection enabled, and that EasyPID is allowed to use biometrics.',
},
Screen: OnboardingBiometrics,
},
...pidSetupSteps,
] as const satisfies Array<OnboardingStep>

export type OnboardingContext = {
currentStep: OnboardingStep['step']
progress: number
Expand Down Expand Up @@ -166,6 +76,7 @@ export function OnboardingContextProvider({
showScanModal: true,
})
const [eidCardRequestedAccessRights, setEidCardRequestedAccessRights] = useState<string[]>()
const hasEidCardFeatureFlag = useFeatureFlag('EID_CARD')

const currentStep = onboardingSteps.find((step) => step.step === currentStepName)
if (!currentStep) throw new Error(`Invalid step ${currentStepName}`)
Expand Down Expand Up @@ -236,7 +147,7 @@ export function OnboardingContextProvider({
// Allows bypassing the eID card and use a simulator card
const isSimulatorPinCode = pin === SIMULATOR_PIN

if (isSimulatorPinCode) {
if (isSimulatorPinCode && hasEidCardFeatureFlag) {
toast.show('Simulator eID card activated', {
customData: {
preset: 'success',
Expand Down Expand Up @@ -677,7 +588,7 @@ export function OnboardingContextProvider({
} else if (currentStep.step === 'biometrics') {
screen = <currentStep.Screen goToNextStep={onEnableBiometrics} actionText="Activate Biometrics" />
} else if (currentStep.step === 'biometrics-disabled') {
screen = <currentStep.Screen goToNextStep={onEnableBiometricsDisabled} actionText="Go to settings" />
screen = <currentStep.Screen goToNextStep={onEnableBiometricsDisabled} actionText="Open settings" />
} else if (currentStep.step === 'data-protection') {
screen = <currentStep.Screen goToNextStep={onIdCardStart} />
} else if (currentStep.step === 'id-card-requested-attributes') {
Expand Down
63 changes: 20 additions & 43 deletions apps/easypid/src/features/onboarding/screens/welcome.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
import {
Blob,
Button,
FlexPage,
Heading,
HeroIcons,
IconContainer,
Image,
Paragraph,
Stack,
XStack,
YStack,
} from '@package/ui'
import { Blob, Button, FlexPage, Heading, Image, Paragraph, Stack, XStack, YStack } from '@package/ui'
import type React from 'react'
import { Alert } from 'react-native'

import appIcon from '../../../../assets/icon.png'

Expand All @@ -28,43 +15,33 @@ export default function OnboardingWelcome({ goToNextStep }: OnboardingWelcomePro
<YStack
transform={[{ translateX: -48 }]} // Half of the image width (96/2)
pos="absolute"
br="$6"
top="40%"
left="50%"
ov="hidden"
ai="center"
jc="center"
shadowOffset={{ width: 5, height: 5 }}
shadowColor="$grey-400"
shadowOpacity={0.5}
shadowRadius={24}
>
<Image height={96} width={96} src={appIcon} />
<Stack br="$7" ov="hidden">
<Image height={96} width={96} src={appIcon} />
</Stack>
</YStack>
</YStack>
<FlexPage safeArea="y" p={0} fg={1} jc="space-between" backgroundColor="$transparent">
<YStack px="$4" gap="$4" flex-1 justifyContent="space-between">
<YStack ai="flex-end">
<IconContainer
aria-label="Info"
icon={<HeroIcons.QuestionMarkCircle />}
onPress={() => {
Alert.alert(
'This is the EasyPID wallet',
'\nThis is your digital wallet. With it, you can store and share information about yourself.'
)
}}
/>
</YStack>
<Stack h="$11" />
<YStack gap="$4" jc="center" ai="center">
<Heading fontSize={32}>Paradym Wallet</Heading>
<Paragraph px="$2" ta="center">
This is your digital wallet. With it, you can store and share information about yourself.
</Paragraph>
</YStack>
<XStack gap="$2">
<Button.Solid flexGrow={1} onPress={goToNextStep}>
Get Started
</Button.Solid>
</XStack>
<FlexPage safeArea="y" fg={1} jc="space-between" backgroundColor="$transparent">
<Stack h="40%" />
<YStack gap="$4" ai="center">
<Heading fontSize={32}>Paradym Wallet</Heading>
<Paragraph px="$2" ta="center">
This is your digital wallet. With it, you can store and share information about yourself.
</Paragraph>
</YStack>
<XStack gap="$2">
<Button.Solid flexGrow={1} onPress={goToNextStep}>
Get Started
</Button.Solid>
</XStack>
</FlexPage>
</YStack>
)
Expand Down
Loading

0 comments on commit 35d3b16

Please sign in to comment.