Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
5 changes: 2 additions & 3 deletions apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"dependencies": {
"@fontsource/roboto": "^5.0.8",
"@heroicons/react": "^2.1.3",
"@hookform/resolvers": "^3.4.2",
"@hookform/resolvers": "^4.1.3",
"@monerium/sdk": "^3.4.2",
"@pendulum-chain/api": "catalog:",
"@pendulum-chain/api-solang": "catalog:",
Expand Down Expand Up @@ -72,8 +72,7 @@
"wagmi": "catalog:",
"web3": "^4.16.0",
"xstate": "^5.20.1",
"yup": "^1.4.0",
"zod": "3",
"zod": "^4.3.6",
"zustand": "^5.0.2"
},
"devDependencies": {
Expand Down
38 changes: 38 additions & 0 deletions apps/frontend/src/assets/business-check-business-success.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions apps/frontend/src/assets/business-check-representative-success.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import BusinessCheck from "../../../assets/business-check-business.svg";
import BusinessCheckSuccess from "../../../assets/business-check-business-success.svg";
import { useAveniaKycActor, useAveniaKycSelector } from "../../../contexts/rampState";
import { AveniaKYBVerifyStep } from "./AveniaKYBVerifyStep";

Expand All @@ -15,6 +16,7 @@ export const AveniaKYBVerifyCompany = () => {
return (
<AveniaKYBVerifyStep
imageSrc={BusinessCheck}
imageSrcVerified={BusinessCheckSuccess}
isVerificationStarted={companyVerificationStarted ?? false}
onCancel={() => aveniaKycActor.send({ type: "GO_BACK" })}
onVerificationDone={() => aveniaKycActor.send({ type: "KYB_COMPANY_DONE" })}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import BusinessCheckRepresentative from "../../../assets/business-check-representative.svg";
import BusinessCheckRepresentativeSuccess from "../../../assets/business-check-representative-success.svg";
import { useAveniaKycActor, useAveniaKycSelector } from "../../../contexts/rampState";
import { AveniaKYBVerifyStep } from "./AveniaKYBVerifyStep";

Expand All @@ -15,6 +16,7 @@ export const AveniaKYBVerifyCompanyRepresentative = () => {
return (
<AveniaKYBVerifyStep
imageSrc={BusinessCheckRepresentative}
imageSrcVerified={BusinessCheckRepresentativeSuccess}
instructionsKey="components.aveniaKYB.aveniaKYBVerifyCompanyRepresentative.instructions"
isVerificationStarted={representativeVerificationStarted ?? false}
onCancel={() => aveniaKycActor.send({ type: "KYB_COMPANY_BACK" })}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { ArrowTopRightOnSquareIcon } from "@heroicons/react/24/solid";
import { ArrowTopRightOnSquareIcon, ShieldCheckIcon } from "@heroicons/react/24/solid";
import { Trans, useTranslation } from "react-i18next";
import { useQuote } from "../../../stores/quote/useQuoteStore";
import { cn } from "../../../helpers/cn";
import { SparkleButton } from "../../SparkleButton";
import { StepFooter } from "../../StepFooter";

interface AveniaKYBVerifyStepProps {
titleKey: string;
imageSrc: string;
imageSrcVerified?: string;
verificationUrl: string;
isVerificationStarted: boolean;
onCancel: () => void;
Expand All @@ -19,6 +21,7 @@ interface AveniaKYBVerifyStepProps {
export const AveniaKYBVerifyStep = ({
titleKey,
imageSrc,
imageSrcVerified,
verificationUrl,
isVerificationStarted,
onCancel,
Expand All @@ -35,12 +38,19 @@ export const AveniaKYBVerifyStep = ({
<div className="flex-1 pb-36">
<div className="mt-8 mb-4 flex w-full flex-col">
<div>
<h1 className="mt-2 mb-4 text-center font-bold text-2xl text-primary">{t(titleKey)}</h1>
<h1
className={cn(
"mt-2 mb-4 text-center font-bold text-2xl",
isVerificationStarted ? "text-success" : "text-primary"
)}
>
{t(titleKey)}
</h1>

<img
alt="Business Check"
className="mx-auto mt-16 w-[170px] transition-opacity duration-300 motion-reduce:transition-none"
src={imageSrc}
src={isVerificationStarted && imageSrcVerified ? imageSrcVerified : imageSrc}
/>

{!isVerificationStarted && (
Expand Down Expand Up @@ -79,15 +89,17 @@ export const AveniaKYBVerifyStep = ({
</div>

<StepFooter>
<div className="mt-8 flex gap-4">
<button className="btn-vortex-primary-inverse btn flex-1" onClick={onCancel}>
<div className="mt-8 grid grid-cols-2 gap-4">
<button className="btn-vortex-primary-inverse btn" onClick={onCancel}>
{t(cancelButtonKey)}
</button>

{isVerificationStarted ? (
<button className="btn-vortex-primary btn flex-1" onClick={onVerificationDone}>
{t("components.aveniaKYB.buttons.iHaveVerified")}
</button>
<SparkleButton
icon={<ShieldCheckIcon className="h-5 w-5" />}
label={t("components.aveniaKYB.buttons.iHaveVerified")}
onClick={onVerificationDone}
/>
) : (
<a
className="btn-vortex-primary btn flex flex-1 items-center justify-center gap-1"
Expand Down
19 changes: 13 additions & 6 deletions apps/frontend/src/components/Avenia/AveniaKYBFlow/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useAveniaKycSelector } from "../../../contexts/rampState";
import { MenuButtons } from "../../MenuButtons";
import { AveniaKYBVerificationStatus } from "./AveniaKYBVerificationStatus";
import { AveniaKYBVerifyCompany } from "./AveniaKYBVerifyCompany";
import { AveniaKYBVerifyCompanyRepresentative } from "./AveniaKYBVerifyCompanyRepresentative";
Expand All @@ -8,13 +9,19 @@ export const AveniaKYBFlow = () => {

if (!aveniaState) return null;

if (aveniaState.context.kybStep === "company") {
return <AveniaKYBVerifyCompany />;
} else if (aveniaState.context.kybStep === "representative") {
return <AveniaKYBVerifyCompanyRepresentative />;
let content;
if (aveniaState.context.kybStep === "representative") {
content = <AveniaKYBVerifyCompanyRepresentative />;
} else if (aveniaState.context.kybStep === "verification") {
return <AveniaKYBVerificationStatus />;
content = <AveniaKYBVerificationStatus />;
} else {
content = <AveniaKYBVerifyCompany />;
}

return <AveniaKYBVerifyCompany />;
return (
<div className="relative">
<MenuButtons />
{content}
</div>
);
};
35 changes: 17 additions & 18 deletions apps/frontend/src/components/Avenia/AveniaKYBForm.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { useAveniaKycActor, useAveniaKycSelector } from "../../contexts/rampState";
import { useKYCForm } from "../../hooks/brla/useKYCForm";
import { QuoteSummary } from "../QuoteSummary";
import { useKYBForm } from "../../hooks/brla/useKYBForm";
import { MenuButtons } from "../MenuButtons";
import { AveniaFieldProps, ExtendedAveniaFieldOptions } from "./AveniaField";
import { AveniaVerificationForm } from "./AveniaVerificationForm";

/**
* AveniaKYBForm - A simplified KYC form for companies (CNPJ)
* Only collects the company name
*/
export const AveniaKYBForm = () => {
const aveniaKycActor = useAveniaKycActor();
const aveniaState = useAveniaKycSelector();

const { t } = useTranslation();

const { kycForm } = useKYCForm({ cpfApiError: null, initialData: aveniaState?.context.kycFormData });

useEffect(() => {
if (aveniaState?.context.taxId) {
kycForm.setValue(ExtendedAveniaFieldOptions.TAX_ID, aveniaState.context.taxId);
const { kybForm } = useKYBForm({
initialData: {
fullName: aveniaState?.context.kycFormData?.fullName,
taxId: aveniaState?.context.taxId
}
}, [aveniaState?.context.taxId, kycForm]);
});

if (!aveniaState) return null;
if (!aveniaKycActor) return null;
Expand All @@ -41,7 +35,7 @@ export const AveniaKYBForm = () => {
},
{
id: ExtendedAveniaFieldOptions.TAX_ID,
index: 2,
index: 1,
label: "CNPJ",
placeholder: "",
readOnly: true,
Expand All @@ -52,10 +46,15 @@ export const AveniaKYBForm = () => {

return (
<div className="relative flex min-h-(--widget-min-height) grow flex-col">
<div className="flex flex-1 flex-col">
<AveniaVerificationForm aveniaKycActor={aveniaKycActor} fields={companyFormFields} form={kycForm} isCompany={true} />
</div>
<QuoteSummary />
<MenuButtons />
<AveniaVerificationForm
fields={companyFormFields}
form={kybForm}
isCompany={true}
onSubmit={data => {
aveniaKycActor.send({ formData: data, type: "FORM_SUBMIT" });
}}
/>
</div>
);
};
Loading
Loading