Skip to content
Merged
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
31 changes: 14 additions & 17 deletions src/app/(mobile-ui)/qr-pay/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import { useSearchParams, useRouter } from 'next/navigation'
import { useState, useCallback, useMemo, useEffect, useContext } from 'react'
import { Card } from '@/components/0_Bruddle/Card'
import { PeanutDoesntStoreAnyPersonalInformation } from '@/components/Kyc/KycVerificationInProgressModal'
import Card from '@/components/Global/Card'
import { Button } from '@/components/0_Bruddle/Button'
import { Icon } from '@/components/Global/Icons/Icon'
import { mantecaApi } from '@/services/manteca'
Expand Down Expand Up @@ -216,18 +217,18 @@ export default function QRPayPage() {
if (!!errorInitiatingPayment) {
return (
<div className="my-auto flex h-full flex-col justify-center space-y-4">
<Card className="shadow-4">
<Card.Header>
<Card.Title>Unable to get QR details</Card.Title>
<Card.Description>
<Card className="shadow-4 space-y-2">
<div className="space-y-2">
<h1 className="text-3xl font-extrabold">Unable to get QR details</h1>
<p className="text-lg">
{errorInitiatingPayment || 'An error occurred while getting the QR details.'}
</Card.Description>
</Card.Header>
<Card.Content>
<Button onClick={() => router.back()} variant="purple">
Go Back
</Button>
</Card.Content>
</p>
</div>
<div className="h-[1px] bg-black"></div>

<Button onClick={() => router.back()} variant="purple">
Go Back
</Button>
</Card>
</div>
)
Expand Down Expand Up @@ -273,11 +274,7 @@ export default function QRPayPage() {
icon: 'check-circle',
},
]}
footer={
<p className="flex items-center justify-center gap-1 text-xs text-gray-400">
<Icon name="info" className="size-3" /> Peanut doesn't store any personal information
</p>
}
footer={<PeanutDoesntStoreAnyPersonalInformation />}
/>
</div>
)
Expand Down
7 changes: 3 additions & 4 deletions src/app/[...recipient]/client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export default function PaymentPage({ recipient, flow = 'request_pay' }: Props)
const { isDrawerOpen, selectedTransaction, openTransactionDetails } = useTransactionDetailsDrawer()
const [isLinkCancelling, setisLinkCancelling] = useState(false)
const {
showExternalWalletFulfilMethods,
showExternalWalletFulfillMethods,
showRequestFulfilmentBankFlowManager,
setShowRequestFulfilmentBankFlowManager,
setFlowStep: setRequestFulfilmentBankFlowStep,
Expand Down Expand Up @@ -394,8 +394,7 @@ export default function PaymentPage({ recipient, flow = 'request_pay' }: Props)
}, [transactionForDrawer, currentView, dispatch, openTransactionDetails, isExternalWalletFlow, chargeId])

const showActionList =
flow !== 'direct_pay' || // Always show for non-direct-pay flows
(flow === 'direct_pay' && !user) || // Show for direct-pay when user is not logged in
(flow !== 'direct_pay' || (flow === 'direct_pay' && !user)) && // Show for direct-pay when user is not logged in
!fulfillUsingManteca // Show when not fulfilling using Manteca
// Send to bank step if its mentioned in the URL and guest KYC is not needed
useEffect(() => {
Expand Down Expand Up @@ -433,7 +432,7 @@ export default function PaymentPage({ recipient, flow = 'request_pay' }: Props)
}

// render external wallet fulfilment methods
if (showExternalWalletFulfilMethods) {
if (showExternalWalletFulfillMethods) {
return <ExternalWalletFulfilManager parsedPaymentData={parsedPaymentData as ParsedURL} />
}

Expand Down
9 changes: 7 additions & 2 deletions src/components/Claim/Link/Initial.view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export const InitialClaimLinkView = (props: IClaimScreenProps) => {
setClaimToExternalWallet,
resetFlow: resetClaimBankFlow,
claimToMercadoPago,
setClaimToMercadoPago,
} = useClaimBankFlow()
const { setLoadingState, isLoading } = useContext(loadingStateContext)
const {
Expand Down Expand Up @@ -632,9 +633,13 @@ export const InitialClaimLinkView = (props: IClaimScreenProps) => {

useEffect(() => {
const stepFromURL = searchParams.get('step')
if (user && claimLinkData.status !== 'CLAIMED' && stepFromURL === 'claim' && isPeanutWallet) {
if (user && claimLinkData.status !== 'CLAIMED') {
removeParamStep()
handleClaimLink(false, true)
if (stepFromURL === 'claim' && isPeanutWallet) {
handleClaimLink(false, true)
} else if (stepFromURL === 'regional-claim') {
setClaimToMercadoPago(true)
}
}
}, [user, searchParams, isPeanutWallet])

Expand Down
57 changes: 52 additions & 5 deletions src/components/Claim/Link/MantecaFlowManager.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
'use client'

import { MERCADO_PAGO } from '@/assets'
import { MERCADO_PAGO, PIX } from '@/assets'
import NavHeader from '@/components/Global/NavHeader'
import PeanutActionDetailsCard from '@/components/Global/PeanutActionDetailsCard'
import { useClaimBankFlow } from '@/context/ClaimBankFlowContext'
import { ClaimLinkData } from '@/services/sendLinks'
import { FC, useState } from 'react'
import { FC, useEffect, useState } from 'react'
import MantecaDetailsStep from './views/MantecaDetailsStep.view'
import { MercadoPagoStep } from '@/types/manteca.types'
import MantecaReviewStep from './views/MantecaReviewStep'
import { Button } from '@/components/0_Bruddle'
import { useRouter } from 'next/navigation'
import useKycStatus from '@/hooks/useKycStatus'
import { InitiateMantecaKYCModal } from '@/components/Kyc/InitiateMantecaKYCModal'
import { useAuth } from '@/context/authContext'
import { CountryData } from '@/components/AddMoney/consts'

interface MantecaFlowManagerProps {
claimLinkData: ClaimLinkData
Expand All @@ -19,12 +23,39 @@ interface MantecaFlowManagerProps {
}

const MantecaFlowManager: FC<MantecaFlowManagerProps> = ({ claimLinkData, amount, attachment }) => {
const { setClaimToMercadoPago } = useClaimBankFlow()
const { setClaimToMercadoPago, selectedCountry, regionalMethodType } = useClaimBankFlow()
const [currentStep, setCurrentStep] = useState<MercadoPagoStep>(MercadoPagoStep.DETAILS)
const router = useRouter()
const [destinationAddress, setDestinationAddress] = useState('')
const [isKYCModalOpen, setIsKYCModalOpen] = useState(false)
const argentinaCountryData = {
id: 'AR',
type: 'country',
title: 'Argentina',
currency: 'ARS',
path: 'argentina',
iso2: 'AR',
iso3: 'ARG',
} as CountryData

const { isUserMantecaKycApproved } = useKycStatus()
const { fetchUser } = useAuth()

const isSuccess = currentStep === MercadoPagoStep.SUCCESS
const selectedCurrency = selectedCountry?.currency || 'ARS'
const regionalMethodLogo = regionalMethodType === 'mercadopago' ? MERCADO_PAGO : PIX
const logo = selectedCountry?.id ? undefined : regionalMethodLogo

const handleKycCancel = () => {
setIsKYCModalOpen(false)
onPrev()
}

useEffect(() => {
if (!isUserMantecaKycApproved) {
setIsKYCModalOpen(true)
}
}, [isUserMantecaKycApproved])

const renderStepDetails = () => {
if (currentStep === MercadoPagoStep.DETAILS) {
Expand All @@ -43,6 +74,7 @@ const MantecaFlowManager: FC<MantecaFlowManagerProps> = ({ claimLinkData, amount
claimLink={claimLinkData.link}
destinationAddress={destinationAddress}
amount={amount}
currency={selectedCurrency}
/>
)
}
Expand Down Expand Up @@ -83,15 +115,30 @@ const MantecaFlowManager: FC<MantecaFlowManagerProps> = ({ claimLinkData, amount
avatarSize="medium"
transactionType="REGIONAL_METHOD_CLAIM"
recipientType="USERNAME"
recipientName={isSuccess ? 'You’ll receive' : 'Receive in Mercado Pago'}
recipientName={isSuccess ? 'You’ll receive' : 'Receive in ' + regionalMethodType}
amount={amount}
tokenSymbol={claimLinkData.tokenSymbol}
message={attachment.message}
fileUrl={attachment.attachmentUrl}
logo={isSuccess ? undefined : MERCADO_PAGO}
logo={isSuccess ? undefined : logo}
countryCodeForFlag={selectedCountry?.id?.toLowerCase()}
/>

{renderStepDetails()}

{isKYCModalOpen && (
<InitiateMantecaKYCModal
isOpen={isKYCModalOpen}
onClose={handleKycCancel}
onManualClose={handleKycCancel}
onKycSuccess={() => {
// close the modal and let the user continue with amount input
setIsKYCModalOpen(false)
fetchUser()
}}
country={selectedCountry || argentinaCountryData}
/>
)}
</div>
</div>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const MantecaDetailsStep: FC<MantecaDetailsStepProps> = ({

return (
<>
<p className="font-bold">Enter Mercado Pago account details</p>
<p className="font-bold">Enter account details</p>

<BaseInput
value={destinationAddress}
Expand Down
15 changes: 11 additions & 4 deletions src/components/Claim/Link/views/MantecaReviewStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,19 @@ interface MantecaReviewStepProps {
claimLink: string
destinationAddress: string
amount: string
currency: string
}

const MantecaReviewStep: FC<MantecaReviewStepProps> = ({ setCurrentStep, claimLink, destinationAddress, amount }) => {
const MantecaReviewStep: FC<MantecaReviewStepProps> = ({
setCurrentStep,
claimLink,
destinationAddress,
amount,
currency,
}) => {
const [isSubmitting, setIsSubmitting] = useState(false)
const [error, setError] = useState<string | null>(null)
const { price, isLoading } = useCurrency('ARS') // TODO: change to the currency of the selected Method
const { price, isLoading } = useCurrency(currency)

const detailsCardRows: MantecaCardRow[] = [
{
Expand All @@ -31,7 +38,7 @@ const MantecaReviewStep: FC<MantecaReviewStepProps> = ({ setCurrentStep, claimLi
{
key: 'exchangeRate',
label: 'Exchange Rate',
value: `1 USD = ${price?.buy} ARS`,
value: `1 USD = ${price?.buy} ${currency}`,
},
{
key: 'fee',
Expand All @@ -55,7 +62,7 @@ const MantecaReviewStep: FC<MantecaReviewStepProps> = ({ setCurrentStep, claimLi
amount: amount.replace(/,/g, ''),
destinationAddress,
txHash,
currency: 'ARS', // TODO: source-selected currency
currency,
})
if (withdrawError || !data) {
setError(withdrawError || 'Something went wrong. Please contact Support')
Expand Down
2 changes: 1 addition & 1 deletion src/components/Claim/useClaimLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const useClaimLink = () => {
}
}

const addParamStep = (step: 'bank' | 'claim') => {
const addParamStep = (step: 'bank' | 'claim' | 'regional-claim' | 'regional-req-fulfill') => {
const params = new URLSearchParams(searchParams)
params.set('step', step)

Expand Down
49 changes: 46 additions & 3 deletions src/components/Common/ActionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import { GuestVerificationModal } from '../Global/GuestVerificationModal'
import ActionListDaimoPayButton from './ActionListDaimoPayButton'
import { ACTION_METHODS, PaymentMethod } from '@/constants/actionlist.consts'
import useClaimLink from '../Claim/useClaimLink'
import { useAuth } from '@/context/authContext'
import { useGeoLocaion } from '@/hooks/useGeoLocaion'
import Loading from '../Global/Loading'

interface IActionListProps {
flow: 'claim' | 'request'
Expand All @@ -47,6 +50,7 @@ export default function ActionList({ claimLinkData, isLoggedIn, flow, requestLin
setFlowStep: setClaimBankFlowStep,
setShowVerificationModal,
setClaimToMercadoPago,
setRegionalMethodType,
} = useClaimBankFlow()
const [showMinAmountError, setShowMinAmountError] = useState(false)
const { claimType } = useDetermineBankClaimType(claimLinkData?.sender?.userId ?? '')
Expand All @@ -58,11 +62,15 @@ export default function ActionList({ claimLinkData, isLoggedIn, flow, requestLin
const { addParamStep } = useClaimLink()
const {
setShowRequestFulfilmentBankFlowManager,
setShowExternalWalletFulfilMethods,
setShowExternalWalletFulfillMethods,
setFlowStep: setRequestFulfilmentBankFlowStep,
setFulfillUsingManteca,
setRegionalMethodType: setRequestFulfillmentRegionalMethodType,
} = useRequestFulfillmentFlow()
const [isGuestVerificationModalOpen, setIsGuestVerificationModalOpen] = useState(false)
const { user } = useAuth()

const { countryCode: userGeoLocationCountryCode, isLoading: isGeoLoading } = useGeoLocaion()

const handleMethodClick = async (method: PaymentMethod) => {
if (flow === 'claim' && claimLinkData) {
Expand All @@ -87,6 +95,13 @@ export default function ActionList({ claimLinkData, isLoggedIn, flow, requestLin
}
break
case 'mercadopago':
case 'pix':
if (!user) {
addParamStep('regional-claim')
setShowVerificationModal(true)
return
}
setRegionalMethodType(method.id)
setClaimToMercadoPago(true)
break
case 'exchange-or-wallet':
Expand All @@ -110,15 +125,35 @@ export default function ActionList({ claimLinkData, isLoggedIn, flow, requestLin
}
break
case 'mercadopago':
case 'pix':
if (!user) {
addParamStep('regional-req-fulfill')
setIsGuestVerificationModalOpen(true)
return
}
setRequestFulfillmentRegionalMethodType(method.id)
setFulfillUsingManteca(true)
break
case 'exchange-or-wallet':
setShowExternalWalletFulfilMethods(true)
setShowExternalWalletFulfillMethods(true)
break
}
}
}

const geolocatedMethods = useMemo(() => {
// show pix in brazil and mercado pago in other countries
return ACTION_METHODS.filter((method) => {
if (userGeoLocationCountryCode === 'BR' && method.id === 'mercadopago') {
return false
}
if (userGeoLocationCountryCode !== 'BR' && method.id === 'pix') {
return false
}
return true
})
}, [userGeoLocationCountryCode])

const requiresVerification = useMemo(() => {
if (flow === 'claim') {
return claimType === BankClaimType.GuestKycNeeded || claimType === BankClaimType.ReceiverKycNeeded
Expand All @@ -130,7 +165,7 @@ export default function ActionList({ claimLinkData, isLoggedIn, flow, requestLin
}, [claimType, requestType, flow])

const sortedActionMethods = useMemo(() => {
return [...ACTION_METHODS].sort((a, b) => {
return [...geolocatedMethods].sort((a, b) => {
const aIsUnavailable = a.soon || (a.id === 'bank' && requiresVerification)
const bIsUnavailable = b.soon || (b.id === 'bank' && requiresVerification)

Expand All @@ -141,6 +176,14 @@ export default function ActionList({ claimLinkData, isLoggedIn, flow, requestLin
})
}, [requiresVerification])

if (isGeoLoading) {
return (
<div className="flex w-full items-center justify-center py-8">
<Loading />
</div>
)
}

return (
<div className="space-y-2">
{!isLoggedIn && (
Expand Down
4 changes: 2 additions & 2 deletions src/components/Common/CountryList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ export const CountryList = ({
// support all bridge and manteca supported countries
isSupported = isBridgeSupportedCountry || isMantecaSupportedCountry
} else if (viewMode === 'claim-request') {
// support all countries
isSupported = isBridgeSupportedCountry
// support all bridge and manteca supported countries
isSupported = isBridgeSupportedCountry || isMantecaSupportedCountry
} else {
// support all countries
isSupported = true
Expand Down
Loading
Loading