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

feat: [IOPID-2634] Implement Zendesk FAQ Banner in the accesso_a_io subCategories screen #6714

Merged
merged 10 commits into from
Feb 20, 2025
Merged
48 changes: 45 additions & 3 deletions ts/features/zendesk/screens/ZendeskChooseSubCategory.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import {
Banner,
ContentWrapper,
Divider,
IOVisualCostants,
ListItemNav
ListItemNav,
useIOToast,
VSpacer
} from "@pagopa/io-app-design-system";
import { FlatList, ListRenderItemInfo } from "react-native";
import { ZendeskSubCategory } from "../../../../definitions/content/ZendeskSubCategory";
Expand All @@ -21,6 +25,9 @@ import {
zendeskSupportFailure
} from "../store/actions";
import { zendeskSelectedCategorySelector } from "../store/reducers";
import { openWebUrl } from "../../../utils/url";
import { trackHelpCenterCtaTapped } from "../../../utils/analytics";
import { getOrFallback } from "../../../utils/object";

export type ZendeskChooseSubCategoryNavigationParams = {
assistanceType: ZendeskAssistanceType;
Expand All @@ -36,9 +43,13 @@ type Props = IOStackNavigationRouteProps<
* see {@link ZendeskChooseCategory} to check the previous category screen
*/
const ZendeskChooseSubCategory = (props: Props) => {
const { error } = useIOToast();
const selectedCategory = useIOSelector(zendeskSelectedCategorySelector);
const dispatch = useIODispatch();
const { assistanceType } = props.route.params;
const {
params: { assistanceType },
name: routeName
} = props.route;
const selectedSubcategory = (subcategory: ZendeskSubCategory) =>
dispatch(zendeskSelectedSubcategory(subcategory));
const zendeskWorkUnitFailure = (reason: string) =>
Expand All @@ -61,6 +72,8 @@ const ZendeskChooseSubCategory = (props: Props) => {
selectedCategory.zendeskSubCategories?.subCategories ?? [];
const subCategoriesId: string =
selectedCategory.zendeskSubCategories?.id ?? "";
const bannerEducational =
selectedCategory.zendeskSubCategories?.bannerEducational;

const locale = getFullLocale();

Expand Down Expand Up @@ -90,6 +103,35 @@ const ZendeskChooseSubCategory = (props: Props) => {
ignoreSafeAreaMargin={true}
testID={"ZendeskChooseCategory"}
>
{bannerEducational && (
<ContentWrapper>
<Banner
pictogramName="help"
size="big"
color="neutral"
title={getOrFallback(bannerEducational.title, locale, "it-IT")}
content={getOrFallback(bannerEducational.content, locale, "it-IT")}
action={getOrFallback(
bannerEducational.action.label,
locale,
"it-IT"
)}
onPress={() => {
const url = getOrFallback(
bannerEducational.action.href,
locale,
"it-IT"
);

trackHelpCenterCtaTapped(selectedCategory.value, url, routeName);
openWebUrl(url, () => {
error(I18n.t("global.jserror.title"));
});
}}
/>
<VSpacer size={8} />
</ContentWrapper>
)}
<FlatList
scrollEnabled={false}
contentContainerStyle={{
Expand All @@ -98,7 +140,7 @@ const ZendeskChooseSubCategory = (props: Props) => {
data={subCategories}
keyExtractor={c => c.value}
renderItem={renderItem}
ItemSeparatorComponent={() => <Divider />}
ItemSeparatorComponent={Divider}
/>
</IOScrollViewWithLargeHeader>
);
Expand Down
35 changes: 35 additions & 0 deletions ts/utils/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,38 @@ export const findFirstCaseInsensitive =
Object.entries,
A.findFirst(([k, _]) => k.toLowerCase() === key.toLowerCase())
);

/**
* This function aims to handle cases where it is uncertain whether a key exists in an object and provides a fallback value.
* @param obj The object from which to extract the value
* @param key The desired key
* @param fallback The fallback key
* @example
* // Example 1
* const obj = {
* it_IT: "it",
* en_EN: "en"
* };
* const key: "it_IT"|"en_EN"|"de_DE" = "de_DE";
* const result = getOrFallback(obj, key, "it_IT");
*
* console.log(result); // the result will fallback to "it"
*
* // Example 2
* const obj = {
* it_IT: "it",
* en_EN: "en",
* de_DE: "de"
* };
* const key: "it_IT"|"en_EN"|"de_DE" = "de_DE";
* const result = getOrFallback(obj, key, "it_IT");
*
* console.log(result); // the result will be "de"
*/
export function getOrFallback<
O extends object,
K1 extends keyof O,
K2 extends keyof O
>(obj: O, key: K1, fallback: K2) {
return obj[key] ?? obj[fallback];
}
Loading