Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions locales/de/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -3759,6 +3759,12 @@
}
}
}
},
"tour": {
"next": "Weiter",
"back": "Zurück",
"skip": "Überspringen",
"done": "Fertig"
}
},
"support": {
Expand Down
6 changes: 6 additions & 0 deletions locales/en/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -5476,6 +5476,12 @@
"cta": "Attiva notifiche push",
"toast": "Hai attivato le notifiche push"
}
},
"tour": {
"next": "Next",
"back": "Back",
"skip": "Skip",
"done": "Done"
}
},
"support": {
Expand Down
8 changes: 7 additions & 1 deletion locales/it/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -5966,6 +5966,12 @@
"cta": "Attiva notifiche push",
"toast": "Hai attivato le notifiche push"
}
},
"tour": {
"next": "Avanti",
"back": "Indietro",
"skip": "Salta",
"done": "Fine"
}
},
"support": {
Expand Down Expand Up @@ -6837,7 +6843,7 @@
}
},
"whatsNew": {
"title": "Abbiamo migliorato laccesso a IO!",
"title": "Abbiamo migliorato l'accesso a IO!",
"subtitle": "Ora puoi accedere all'app utilizzando il tuo SPID o la tua CIE solo una volta all'anno. Ti basterà poi utilizzare il tuo codice di sblocco o il biometrico per entrare."
}
},
Expand Down
25 changes: 14 additions & 11 deletions ts/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
import { isDevEnv } from "./utils/environment";
import { StatusMessages } from "./components/StatusMessages/StatusMessages";
import { AppFeedbackProvider } from "./features/appReviews/components/AppFeedbackProvider";
import { TourProvider } from "./features/tour/components/TourProvider";
import { IOAlertVisibleContextProvider } from "./components/StatusMessages/IOAlertVisibleContext";
import { getEnv } from "./features/itwallet/common/utils/environment";

Expand Down Expand Up @@ -161,17 +162,19 @@ const App = (): JSX.Element => (
<ToastProvider>
<Provider store={store}>
<PersistGate loading={undefined} persistor={persistor}>
<IOAlertVisibleContextProvider>
<BottomSheetModalProvider>
<LightModalProvider>
<AppFeedbackProvider>
<StatusMessages>
<RootContainer store={store} />
</StatusMessages>
</AppFeedbackProvider>
</LightModalProvider>
</BottomSheetModalProvider>
</IOAlertVisibleContextProvider>
<TourProvider>
<IOAlertVisibleContextProvider>
<BottomSheetModalProvider>
<LightModalProvider>
<AppFeedbackProvider>
<StatusMessages>
<RootContainer store={store} />
</StatusMessages>
</AppFeedbackProvider>
</LightModalProvider>
</BottomSheetModalProvider>
</IOAlertVisibleContextProvider>
</TourProvider>
</PersistGate>
</Provider>
</ToastProvider>
Expand Down
4 changes: 4 additions & 0 deletions ts/components/ui/IOScrollViewWithLargeHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { useNavigation } from "@react-navigation/native";
import { ComponentProps, forwardRef, ReactNode, useState } from "react";

import { LayoutChangeEvent, View } from "react-native";
import Animated, { AnimatedRef } from "react-native-reanimated";
import I18n from "i18next";
import {
BackProps,
Expand Down Expand Up @@ -48,6 +49,7 @@ type Props = WithTestID<
ignoreAccessibilityCheck?: ComponentProps<
typeof HeaderSecondLevel
>["ignoreAccessibilityCheck"];
animatedRef?: AnimatedRef<Animated.ScrollView>;
topElement?: ReactNode;
alwaysBounceVertical?: boolean;
} & SupportRequestParams
Expand Down Expand Up @@ -76,6 +78,7 @@ export const IOScrollViewWithLargeHeader = forwardRef<View, Props>(
excludeEndContentMargin,
testID,
ignoreAccessibilityCheck = false,
animatedRef,
topElement = undefined,
alwaysBounceVertical
},
Expand Down Expand Up @@ -116,6 +119,7 @@ export const IOScrollViewWithLargeHeader = forwardRef<View, Props>(
return (
<IOScrollView
actions={actions}
animatedRef={animatedRef}
headerConfig={headerProps}
snapOffset={titleHeight}
includeContentMargins={false}
Expand Down
5 changes: 4 additions & 1 deletion ts/features/common/store/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ import {
backgroundLinkingReducer
} from "../../../linking/reducers";
import cdcReducer, { CdcState } from "../../../bonus/cdc/common/store/reducers";
import tourReducer, { TourState } from "../../../tour/store/reducers";

type LoginFeaturesState = {
testLogin: TestLoginState;
Expand Down Expand Up @@ -113,6 +114,7 @@ export type FeaturesState = {
connectivityStatus: ConnectivityState;
backgroundLinking: BackgroundLinkingState;
cdc: CdcState;
tour: TourState & PersistPartial;
};

export type PersistedFeaturesState = FeaturesState & PersistPartial;
Expand Down Expand Up @@ -145,7 +147,8 @@ const rootReducer = combineReducers<FeaturesState, Action>({
utmLink: utmLinkReducer,
connectivityStatus: connectivityStateReducer,
backgroundLinking: backgroundLinkingReducer,
cdc: cdcReducer
cdc: cdcReducer,
tour: tourReducer
});

const CURRENT_REDUX_FEATURES_STORE_VERSION = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { CieIasAndMrtdPlaygroundMrtdScreen } from "../../devMode/playgrounds/Cie
import { IdPayCodePlayGround } from "../../devMode/playgrounds/IdPayCodePlayground";
import IdPayOnboardingPlayground from "../../devMode/playgrounds/IdPayOnboardingPlayground";
import { IOMarkdownPlayground } from "../../devMode/playgrounds/IOMarkdownPlayground";
import { GuidedTourPlayground } from "../../devMode/playgrounds/GuidedTourPlayground";
import { NfcPlayground } from "../../devMode/playgrounds/NfcPlayground";
import AppearancePreferenceScreen from "../../preferences/screens/AppearancePreferenceScreen";
import CalendarsPreferencesScreen from "../../preferences/screens/CalendarsPreferencesScreen";
Expand Down Expand Up @@ -227,6 +228,10 @@ const SettingsStackNavigator = () => (
name={SETTINGS_ROUTES.NFC_PLAYGROUND}
component={NfcPlayground}
/>
<Stack.Screen
name={SETTINGS_ROUTES.GUIDED_TOUR_PLAYGROUND}
component={GuidedTourPlayground}
/>

<Stack.Screen
name={SETTINGS_ROUTES.AUTHENTICATION}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export type SettingsParamsList = {
[SETTINGS_ROUTES.CIE_IAS_AND_MRTD_PLAYGROUND_INTERNAL_AUTH_AND_MRTD]: undefined;
[SETTINGS_ROUTES.CIE_IAS_AND_MRTD_PLAYGROUND_INTERNAL_AUTH_AND_MRTD_RESULTS]: CieIasAndMrtdResultNavParams;
[SETTINGS_ROUTES.NFC_PLAYGROUND]: undefined;
[SETTINGS_ROUTES.GUIDED_TOUR_PLAYGROUND]: undefined;
[SETTINGS_ROUTES.SETTINGS_MAIN]: undefined;
[SETTINGS_ROUTES.AUTHENTICATION]: NavigatorScreenParams<AuthenticationParamsList>;
};
1 change: 1 addition & 0 deletions ts/features/settings/common/navigation/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,6 @@ export const SETTINGS_ROUTES = {
CIE_IAS_AND_MRTD_PLAYGROUND_INTERNAL_AUTH_RESULTS:
"CIE_IAS_AND_MRTD_PLAYGROUND_INTERNAL_AUTH_RESULTS",
NFC_PLAYGROUND: "NFC_PLAYGROUND",
GUIDED_TOUR_PLAYGROUND: "GUIDED_TOUR_PLAYGROUND",
AUTHENTICATION: "AUTHENTICATION"
} as const;
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,13 @@ const PlaygroundsSection = () => {
screen: SETTINGS_ROUTES.NFC_PLAYGROUND
})
},
{
value: "Guided Tour",
onPress: () =>
navigation.navigate(SETTINGS_ROUTES.PROFILE_NAVIGATOR, {
screen: SETTINGS_ROUTES.GUIDED_TOUR_PLAYGROUND
})
},
{
value: I18n.t(
"profile.main.loginEnvironment.activeSession.playground.title"
Expand Down
176 changes: 176 additions & 0 deletions ts/features/settings/devMode/playgrounds/GuidedTourPlayground.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import {
Body,
H6,
IOButton,
IOColors,
VSpacer
} from "@pagopa/io-app-design-system";
import { useEffect } from "react";
import { StyleSheet, View } from "react-native";
import Animated, {
useAnimatedRef,
useScrollViewOffset
} from "react-native-reanimated";
import { useHeaderHeight } from "@react-navigation/elements";
import { IOScrollViewWithLargeHeader } from "../../../../components/ui/IOScrollViewWithLargeHeader";
import { useIODispatch, useIOSelector } from "../../../../store/hooks";
import { GuidedTour } from "../../../tour/components/GuidedTour";
import { useTourContext } from "../../../tour/components/TourProvider";
import {
resetTourCompletedAction,
startTourAction
} from "../../../tour/store/actions";
import { isTourCompletedSelector } from "../../../tour/store/selectors";

const PLAYGROUND_GROUP_ID = "playground";

export const GuidedTourPlayground = () => {
const dispatch = useIODispatch();
const { registerScrollRef, unregisterScrollRef } = useTourContext();
const isCompleted = useIOSelector(
isTourCompletedSelector(PLAYGROUND_GROUP_ID)
);

const scrollRef = useAnimatedRef<Animated.ScrollView>();
const scrollY = useScrollViewOffset(scrollRef);
const headerHeight = useHeaderHeight();

useEffect(() => {
registerScrollRef(PLAYGROUND_GROUP_ID, scrollRef, scrollY, headerHeight);
return () => {
unregisterScrollRef(PLAYGROUND_GROUP_ID);
};
}, [
registerScrollRef,
unregisterScrollRef,
scrollRef,
scrollY,
headerHeight
]);

return (
<IOScrollViewWithLargeHeader
title={{ label: "Guided Tour Playground" }}
animatedRef={scrollRef}
includeContentMargins
>
<IOButton
variant="solid"
label="Start Tour"
onPress={() =>
dispatch(startTourAction({ groupId: PLAYGROUND_GROUP_ID }))
}
/>
<VSpacer size={8} />
<IOButton
variant="solid"
color="danger"
label="Reset Completed State"
onPress={() =>
dispatch(resetTourCompletedAction({ groupId: PLAYGROUND_GROUP_ID }))
}
/>
<VSpacer size={8} />
<Body>{`Tour completed: ${isCompleted}`}</Body>

<VSpacer size={32} />

<GuidedTour
groupId={PLAYGROUND_GROUP_ID}
index={0}
title="Welcome Card"
description="This is the first item in the tour. It shows a welcome message."
>
<View style={styles.card}>
<H6>Welcome Card</H6>
<VSpacer size={4} />
<Body>This is a sample card component.</Body>
</View>
</GuidedTour>

<VSpacer size={24} />

<GuidedTour
groupId={PLAYGROUND_GROUP_ID}
index={1}
title="Action Button"
description="This button performs an important action."
>
<IOButton
variant="solid"
color="primary"
label="Sample Action"
onPress={() => undefined}
/>
</GuidedTour>

<VSpacer size={24} />

<GuidedTour
groupId={PLAYGROUND_GROUP_ID}
index={2}
title="Info Section"
description="This section contains useful information about the feature."
>
<View style={styles.infoBox}>
<Body weight="Semibold">Info Section</Body>
<VSpacer size={4} />
<Body>Some helpful text that explains what this section does.</Body>
</View>
</GuidedTour>

{/* Spacer to push items below the fold */}
<VSpacer size={48} />
<View style={styles.filler} />
<VSpacer size={48} />

<GuidedTour
groupId={PLAYGROUND_GROUP_ID}
index={3}
title="Below the Fold"
description="This item is below the fold. The tour should auto-scroll to reveal it."
>
<View style={styles.card}>
<H6>Below the Fold Card</H6>
<VSpacer size={4} />
<Body>You need to scroll to see this card.</Body>
</View>
</GuidedTour>

<VSpacer size={24} />

<GuidedTour
groupId={PLAYGROUND_GROUP_ID}
index={4}
title="Bottom Item"
description="This is the last item, far down the page."
>
<View style={styles.infoBox}>
<Body weight="Semibold">Bottom Item</Body>
<VSpacer size={4} />
<Body>The very last tour stop at the bottom of the page.</Body>
</View>
</GuidedTour>

<VSpacer size={48} />
</IOScrollViewWithLargeHeader>
);
};

const styles = StyleSheet.create({
card: {
backgroundColor: IOColors["grey-50"],
borderRadius: 8,
padding: 16
},
filler: {
height: 600,
backgroundColor: IOColors["grey-100"],
borderRadius: 8
},
infoBox: {
backgroundColor: IOColors["grey-50"],
borderRadius: 8,
padding: 16
}
});
Loading