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

Add check declaration in the web banking #890

Merged
merged 17 commits into from
Sep 13, 2024
604 changes: 604 additions & 0 deletions clients/banking/src/components/CheckDeclarationWizard.tsx

Large diffs are not rendered by default.

50 changes: 50 additions & 0 deletions clients/banking/src/components/FoldableAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { LakeAlert } from "@swan-io/lake/src/components/LakeAlert";
import { LakeButton } from "@swan-io/lake/src/components/LakeButton";
import { ColorVariants } from "@swan-io/lake/src/constants/design";
import { useDisclosure } from "@swan-io/lake/src/hooks/useDisclosure";
import { ComponentProps, ReactNode } from "react";
import { match } from "ts-pattern";
import { t } from "../utils/i18n";

type FoldableAlertProps = {
variant: ComponentProps<typeof LakeAlert>["variant"];
title: string;
more: ReactNode;
openedAtStart?: boolean;
};

export const FoldableAlert = ({
variant,
title,
more,
openedAtStart = false,
}: FoldableAlertProps) => {
const [visible, { toggle }] = useDisclosure(openedAtStart);

return (
<LakeAlert
anchored={true}
variant={variant}
title={title}
callToAction={
<LakeButton
onPress={toggle}
mode="tertiary"
size="small"
color={match(variant)
.returnType<ColorVariants>()
.with("error", () => "negative")
.with("info", () => "shakespear")
.with("neutral", () => "gray")
.with("success", () => "positive")
.with("warning", () => "warning")
.exhaustive()}
>
{visible ? t("common.showLess") : t("common.showMore")}
</LakeButton>
}
>
{visible ? more : null}
</LakeAlert>
);
};
58 changes: 28 additions & 30 deletions clients/banking/src/components/MerchantProfileArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,36 +70,34 @@ export const AccountMerchantsProfileArea = ({
))
.with(
AsyncData.P.Done(Result.P.Ok({ merchantProfile: P.select(P.nonNullable) })),
merchantProfile => (
<>
{match(route)
.with({ name: "AccountMerchantsProfileSettings" }, () => (
<MerchantProfileSettings
merchantProfile={merchantProfile}
large={large}
merchantProfileCardVisible={merchantProfileCardVisible}
merchantProfileSepaDirectDebitCoreVisible={
merchantProfileSepaDirectDebitCoreVisible
}
merchantProfileSepaDirectDebitB2BVisible={
merchantProfileSepaDirectDebitB2BVisible
}
merchantProfileInternalDirectDebitCoreVisible={
merchantProfileInternalDirectDebitCoreVisible
}
merchantProfileInternalDirectDebitB2BVisible={
merchantProfileInternalDirectDebitB2BVisible
}
merchantProfileCheckVisible={merchantProfileCheckVisible}
onUpdate={() => {
refresh();
}}
/>
))
.with(P.nullish, () => <NotFoundPage />)
.exhaustive()}
</>
),
merchantProfile =>
match(route)
.with({ name: "AccountMerchantsProfileSettings" }, ({ params }) => (
<MerchantProfileSettings
params={params}
merchantProfile={merchantProfile}
large={large}
merchantProfileCardVisible={merchantProfileCardVisible}
merchantProfileSepaDirectDebitCoreVisible={
merchantProfileSepaDirectDebitCoreVisible
}
merchantProfileSepaDirectDebitB2BVisible={
merchantProfileSepaDirectDebitB2BVisible
}
merchantProfileInternalDirectDebitCoreVisible={
merchantProfileInternalDirectDebitCoreVisible
}
merchantProfileInternalDirectDebitB2BVisible={
merchantProfileInternalDirectDebitB2BVisible
}
merchantProfileCheckVisible={merchantProfileCheckVisible}
onUpdate={() => {
refresh();
}}
/>
))
.with(P.nullish, () => <NotFoundPage />)
.exhaustive(),
)
.exhaustive()
}
Expand Down
115 changes: 110 additions & 5 deletions clients/banking/src/components/MerchantProfileSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useMutation } from "@swan-io/graphql-client";
import { AutoWidthImage } from "@swan-io/lake/src/components/AutoWidthImage";
import { Box } from "@swan-io/lake/src/components/Box";
import { Fill } from "@swan-io/lake/src/components/Fill";
import { FullViewportLayer } from "@swan-io/lake/src/components/FullViewportLayer";
import { Grid } from "@swan-io/lake/src/components/Grid";
import { Icon } from "@swan-io/lake/src/components/Icon";
import { LakeAlert } from "@swan-io/lake/src/components/LakeAlert";
Expand All @@ -17,22 +18,32 @@ import { Space } from "@swan-io/lake/src/components/Space";
import { SwanLogo } from "@swan-io/lake/src/components/SwanLogo";
import { Tag } from "@swan-io/lake/src/components/Tag";
import { Tile } from "@swan-io/lake/src/components/Tile";
import { colors, negativeSpacings, radii, spacings } from "@swan-io/lake/src/constants/design";
import {
colors,
fonts,
negativeSpacings,
radii,
spacings,
} from "@swan-io/lake/src/constants/design";
import { showToast } from "@swan-io/lake/src/state/toasts";
import { identity } from "@swan-io/lake/src/utils/function";
import { filterRejectionsToResult } from "@swan-io/lake/src/utils/gql";
import { isNotNullish } from "@swan-io/lake/src/utils/nullish";
import { LakeModal } from "@swan-io/shared-business/src/components/LakeModal";
import { translateError } from "@swan-io/shared-business/src/utils/i18n";
import { ReactNode, useState } from "react";
import { StyleSheet, View } from "react-native";
import { StyleSheet, Text, View } from "react-native";
import { P, match } from "ts-pattern";
import {
MerchantPaymentMethodFragment,
MerchantPaymentMethodStatus,
MerchantProfileFragment,
RequestMerchantPaymentMethodsDocument,
} from "../graphql/partner";
import { t } from "../utils/i18n";
import { formatNestedMessage, t } from "../utils/i18n";
import { GetRouteParams, Router } from "../utils/routes";
import { useTgglFlag } from "../utils/tggl";
import { CheckDeclarationWizard } from "./CheckDeclarationWizard";
import {
MerchantProfilePaymentMethodCardRequestModal,
MerchantProfilePaymentMethodCheckRequestModal,
Expand All @@ -53,11 +64,11 @@ const styles = StyleSheet.create({
flexShrink: 1,
flexGrow: 1,
paddingHorizontal: spacings[24],
paddingTop: spacings[32],
paddingTop: spacings[4],
},
contentDesktop: {
paddingHorizontal: spacings[40],
paddingTop: spacings[40],
paddingTop: spacings[16],
},
merchantNameContainer: {
flex: 1,
Expand Down Expand Up @@ -96,10 +107,38 @@ const styles = StyleSheet.create({
marginTop: negativeSpacings[16],
marginRight: negativeSpacings[16],
},
stepDot: {
backgroundColor: colors.current[50],
borderWidth: 1,
borderColor: colors.current[100],
borderRadius: 12,
alignItems: "center",
justifyContent: "center",
width: 24,
height: 24,
},
stepDotText: {
fontFamily: fonts.primary,
color: colors.current[500],
textAlign: "center",
fontSize: 14,
lineHeight: 24,
},
});

const UNKNOWN_VALUE = <LakeText style={styles.unknownValue}>{t("common.unknown")}</LakeText>;

const Step = ({ number, children }: { number: number; children: ReactNode }) => (
<Box direction="row">
<View style={styles.stepDot}>
<Text style={styles.stepDotText}>{number}</Text>
</View>

<Space width={16} />
<LakeText>{children}</LakeText>
</Box>
);

const MerchantProfileSettingsPaymentMethodTile = ({
title,
description,
Expand Down Expand Up @@ -404,6 +443,7 @@ type Props = {
merchantProfileInternalDirectDebitCoreVisible: boolean;
merchantProfileInternalDirectDebitB2BVisible: boolean;
merchantProfileCheckVisible: boolean;
params: GetRouteParams<"AccountMerchantsProfileSettings">;
onUpdate: () => void;
};

Expand All @@ -416,8 +456,11 @@ export const MerchantProfileSettings = ({
merchantProfileInternalDirectDebitCoreVisible,
merchantProfileInternalDirectDebitB2BVisible,
merchantProfileCheckVisible,
params,
onUpdate,
}: Props) => {
const checkDeclarationEnabled = useTgglFlag("checks");

const [requestMerchantPaymentMethods] = useMutation(RequestMerchantPaymentMethodsDocument);
const [isEditModalOpen, setIsEditModalOpen] = useState(false);

Expand Down Expand Up @@ -475,6 +518,28 @@ export const MerchantProfileSettings = ({

return (
<ScrollView contentContainerStyle={[styles.content, large && styles.contentDesktop]}>
{Option.all([checkDeclarationEnabled, checkPaymentMethod.flatMap(identity)]).isSome() && (
<>
<Box direction="row" alignItems="center">
<LakeButton
icon="check-regular"
size="small"
color="current"
onPress={() => {
Router.push("AccountMerchantsProfileSettings", {
...params,
check: "declare",
});
}}
>
{t("merchantProfile.declareCheckButton")}
</LakeButton>
</Box>

<Space height={32} />
</>
)}

<LakeHeading level={2} variant="h4">
{t("merchantProfile.settings.information.title")}
</LakeHeading>
Expand Down Expand Up @@ -1087,6 +1152,46 @@ export const MerchantProfileSettings = ({
onCancel={() => setIsEditModalOpen(false)}
/>
</LakeModal>

<LakeModal
visible={params.check === "next"}
maxWidth={750}
icon="check-regular"
title={t("check.next.title")}
>
<LakeText>{t("check.next.description.intro")}</LakeText>
<Space height={24} />
<Step number={1}>{t("check.next.description.step1")}</Step>
<Space height={16} />

<Step number={2}>
{formatNestedMessage("check.next.description.step2", {
colored: text => (
<LakeText variant="smallMedium" color={colors.current[500]}>
{text}
</LakeText>
),
})}
</Step>

<Space height={40} />

<LakeButton
color="current"
onPress={() => {
Router.push("AccountMerchantsProfileSettings", {
...params,
check: undefined,
});
}}
>
{t("check.next.button")}
</LakeButton>
</LakeModal>

<FullViewportLayer visible={params.check === "declare"}>
<CheckDeclarationWizard merchantProfileId={merchantProfile.id} params={params} />
</FullViewportLayer>
</ScrollView>
);
};
4 changes: 2 additions & 2 deletions clients/banking/src/components/TransferBulkUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ export const TransferBulkUpload = ({ onSave }: Props) => {
color="gray"
icon="question-circle-regular"
onPress={() => setIsHelpModalOpen(true)}
ariaLabel={t("transfer.bulk.help.whatIsThis")}
ariaLabel={t("common.help.whatIsThis")}
>
{t("transfer.bulk.help.whatIsThis")}
{t("common.help.whatIsThis")}
</LakeButton>
}
render={() => (
Expand Down
27 changes: 27 additions & 0 deletions clients/banking/src/graphql/partner.gql
Original file line number Diff line number Diff line change
Expand Up @@ -2699,3 +2699,30 @@ mutation RequestMerchantProfileUpdate($input: RequestMerchantProfileUpdateInput!
}
}
}

fragment FnciInfo on FnciInfo {
colorCode
cpt1
cpt2
cpt3
holderEstablishment
}

mutation InitiateCheckMerchantPayment($input: InitiateCheckMerchantPaymentInput!) {
initiateCheckMerchantPayment(input: $input) {
__typename
... on InitiateCheckMerchantPaymentSuccessPayload {
fnciInfo {
...FnciInfo
}
}
... on CheckRejection {
fnciInfo {
...FnciInfo
}
}
... on Rejection {
message
}
}
}
Loading