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
4 changes: 0 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@
"@hookform/resolvers": "3.9.1",
"@justaname.id/react": "0.3.180",
"@justaname.id/sdk": "0.2.177",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-slider": "^1.3.5",
"@reduxjs/toolkit": "^2.5.0",
"@reown/appkit": "1.6.9",
Expand Down Expand Up @@ -81,7 +79,6 @@
"siwe": "^2.3.2",
"tailwind-merge": "^1.14.0",
"tailwind-scrollbar": "^3.1.0",
"use-haptic": "^1.1.11",
"uuid": "^10.0.0",
"validator": "^13.12.0",
"vaul": "^1.1.2",
Expand Down Expand Up @@ -152,7 +149,6 @@
"^web-push$": "<rootDir>/src/utils/__mocks__/web-push.ts",
"^next/cache$": "<rootDir>/src/utils/__mocks__/next-cache.ts",
"^@zerodev/sdk(.*)$": "<rootDir>/src/utils/__mocks__/zerodev-sdk.ts",
"^@simplewebauthn/browser$": "<rootDir>/src/utils/__mocks__/simplewebauthn-browser.ts",
"^@/(.*)$": "<rootDir>/src/$1"
},
"setupFilesAfterEnv": [
Expand Down
248 changes: 29 additions & 219 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

87 changes: 4 additions & 83 deletions src/app/(mobile-ui)/home/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ import NoMoreJailModal from '@/components/Global/NoMoreJailModal'
import EarlyUserModal from '@/components/Global/EarlyUserModal'
import InvitesIcon from '@/components/Home/InvitesIcon'
import NavigationArrow from '@/components/Global/NavigationArrow'
import KycCompletedModal from '@/components/Home/KycCompletedModal'
import { updateUserById } from '@/app/actions/users'
import { useHaptic } from 'use-haptic'

const BALANCE_WARNING_THRESHOLD = parseInt(process.env.NEXT_PUBLIC_BALANCE_WARNING_THRESHOLD ?? '500')
const BALANCE_WARNING_EXPIRY = parseInt(process.env.NEXT_PUBLIC_BALANCE_WARNING_EXPIRY ?? '1814400') // 21 days in seconds
Expand All @@ -58,18 +55,15 @@ export default function Home() {
})
const { isConnected: isWagmiConnected } = useAccount()
const { disconnect: disconnectWagmi } = useDisconnect()
const { triggerHaptic } = useHaptic()

const { isFetchingUser, addAccount } = useAuth()
const { isUserKycApproved } = useKycStatus()
const username = user?.user.username

const [showIOSPWAInstallModal, setShowIOSPWAInstallModal] = useState(false)
const [showAddMoneyPromptModal, setShowAddMoneyPromptModal] = useState(false)
const [showBalanceWarningModal, setShowBalanceWarningModal] = useState(false)
// const [showReferralCampaignModal, setShowReferralCampaignModal] = useState(false)
const [isPostSignupActionModalVisible, setIsPostSignupActionModalVisible] = useState(false)
const [showKycModal, setShowKycModal] = useState(user?.user.showKycCompletedModal ?? false)

const userFullName = useMemo(() => {
if (!user) return
Expand Down Expand Up @@ -160,75 +154,12 @@ export default function Home() {
balanceInUsd > BALANCE_WARNING_THRESHOLD &&
!hasSeenBalanceWarning &&
!showIOSPWAInstallModal &&
!showAddMoneyPromptModal &&
!isPostSignupActionModalVisible
) {
setShowBalanceWarningModal(true)
}
}
}, [
balance,
isFetchingBalance,
showIOSPWAInstallModal,
showAddMoneyPromptModal,
isPostSignupActionModalVisible,
user,
])

// effect for showing add money prompt modal
useEffect(() => {
if (typeof window === 'undefined' || isFetchingBalance || !user || !address) return

// Don't show modal if balance is still loading (undefined)
if (balance === undefined) return

const hasSeenAddMoneyPromptThisSession = sessionStorage.getItem('hasSeenAddMoneyPromptThisSession')
const showNoMoreJailModal = sessionStorage.getItem('showNoMoreJailModal')

// determine if we should show the add money modal based on all conditions
// show if:
// 1. balance is zero.
// 2. user hasn't seen this prompt in the current session.
// 3. setup notifications modal is not visible (priority: setup modal > add money prompt)
// 4. the iOS PWA install modal is not currently active.
// 5. the balance warning modal is not currently active.
// 6. no other post-signup modal is active
const shouldShow =
balance === 0n &&
!hasSeenAddMoneyPromptThisSession &&
!showPermissionModal &&
!showIOSPWAInstallModal &&
!showBalanceWarningModal &&
!isPostSignupActionModalVisible &&
showNoMoreJailModal !== 'true' &&
!user?.showEarlyUserModal // Give Early User and No more jail modal precedence, showing two modals together isn't ideal and it messes up their functionality

if (shouldShow && !showAddMoneyPromptModal) {
// Only set state, don't set sessionStorage here to avoid race conditions
setShowAddMoneyPromptModal(true)
} else if (showAddMoneyPromptModal && showPermissionModal) {
// priority enforcement: hide add money modal if notification modal appears
// this handles race conditions where both modals try to show simultaneously
setShowAddMoneyPromptModal(false)
}
}, [
balance,
isFetchingBalance,
showPermissionModal,
showIOSPWAInstallModal,
showBalanceWarningModal,
isPostSignupActionModalVisible,
showAddMoneyPromptModal,
user,
address,
])

// Set sessionStorage flag when modal becomes visible to prevent showing again
useEffect(() => {
if (showAddMoneyPromptModal) {
sessionStorage.setItem('hasSeenAddMoneyPromptThisSession', 'true')
}
}, [showAddMoneyPromptModal])
}, [balance, isFetchingBalance, showIOSPWAInstallModal, isPostSignupActionModalVisible, user])

if (isLoading) {
return <PeanutLoading coverFullScreen />
Expand All @@ -239,7 +170,7 @@ export default function Home() {
<div className="h-full w-full space-y-6 p-5">
<div className="flex items-center justify-between gap-2">
<UserHeader username={username!} fullName={userFullName} isVerified={isUserKycApproved} />
<Link onClick={() => triggerHaptic()} href="/points" className="flex items-center gap-0">
<Link href="/points" className="flex items-center gap-0">
<InvitesIcon />
<span className="whitespace-nowrap pl-1 text-sm font-semibold md:text-base">Points</span>
<NavigationArrow size={16} className="fill-black" />
Expand Down Expand Up @@ -288,23 +219,13 @@ export default function Home() {
<IOSInstallPWAModal visible={showIOSPWAInstallModal} onClose={() => setShowIOSPWAInstallModal(false)} />

{/* Add Money Prompt Modal */}
<AddMoneyPromptModal visible={showAddMoneyPromptModal} onClose={() => setShowAddMoneyPromptModal(false)} />
{/* TODO @dev Disabling this, re-enable after properly fixing */}
{/* <AddMoneyPromptModal visible={showAddMoneyPromptModal} onClose={() => setShowAddMoneyPromptModal(false)} /> */}

<NoMoreJailModal />

<EarlyUserModal />

<KycCompletedModal
isOpen={showKycModal}
onClose={() => {
updateUserById({
userId: user?.user.userId,
showKycCompletedModal: false,
})
setShowKycModal(false)
}}
/>

{/* Balance Warning Modal */}
<BalanceWarningModal
visible={showBalanceWarningModal}
Expand Down

This file was deleted.

This file was deleted.

59 changes: 0 additions & 59 deletions src/app/(mobile-ui)/profile/identity-verification/layout.tsx

This file was deleted.

9 changes: 7 additions & 2 deletions src/app/(mobile-ui)/profile/identity-verification/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import RegionsVerification from '@/components/Profile/views/RegionsVerification.view'
import PageContainer from '@/components/0_Bruddle/PageContainer'
import IdentityVerificationView from '@/components/Profile/views/IdentityVerification.view'

export default function IdentityVerificationPage() {
return <RegionsVerification />
return (
<PageContainer>
<IdentityVerificationView />
</PageContainer>
)
}
24 changes: 15 additions & 9 deletions src/app/(mobile-ui)/qr-pay/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -433,14 +433,20 @@ export default function QRPayPage() {
})
.catch((error) => {
if (error.message.includes("provider can't decode it")) {
setWaitingForMerchantAmount(true)
if (EQrType.PIX === qrType) {
setErrorInitiatingPayment(
'We are currently experiencing issues with PIX payments due to an external provider. We are working to fix it as soon as possible'
)
} else {
setWaitingForMerchantAmount(true)
}
} else {
setErrorInitiatingPayment(error.message)
setWaitingForMerchantAmount(false)
}
})
.finally(() => setLoadingState('Idle'))
}, [paymentLock, qrCode, setLoadingState, paymentProcessor, shouldRetry])
}, [paymentLock, qrCode, setLoadingState, paymentProcessor, shouldRetry, qrType])

const merchantName = useMemo(() => {
if (paymentProcessor === 'SIMPLEFI') {
Expand Down Expand Up @@ -836,14 +842,14 @@ 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 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.'}
</p>
<Card className="relative z-10 flex w-full flex-col items-center gap-4 p-4">
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-secondary-1 p-3">
<Icon name="alert" className="h-full" />
</div>
<div className="h-[1px] bg-black"></div>
<p className="font-medium">
{' '}
{errorInitiatingPayment || 'An error occurred while getting the QR details.'}
</p>

<Button onClick={() => router.back()} variant="purple">
Go Back
Expand Down
3 changes: 0 additions & 3 deletions src/app/(mobile-ui)/withdraw/crypto/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import { captureMessage } from '@sentry/nextjs'
import type { Address } from 'viem'
import { Slider } from '@/components/Slider'
import { tokenSelectorContext } from '@/context'
import { useHaptic } from 'use-haptic'

export default function WithdrawCryptoPage() {
const router = useRouter()
Expand Down Expand Up @@ -65,7 +64,6 @@ export default function WithdrawCryptoPage() {
isPreparingTx,
reset: resetPaymentInitiator,
} = usePaymentInitiator()
const { triggerHaptic } = useHaptic()

// Helper to manage errors consistently
const setError = useCallback(
Expand Down Expand Up @@ -225,7 +223,6 @@ export default function WithdrawCryptoPage() {
const result = await initiatePayment(paymentPayload)

if (result.success && result.txHash) {
triggerHaptic()
setCurrentView('STATUS')
} else {
console.error('Withdrawal execution failed:', result.error)
Expand Down
4 changes: 2 additions & 2 deletions src/app/(mobile-ui)/withdraw/manteca/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default function MantecaWithdrawFlow() {
const queryClient = useQueryClient()
const { isUserBridgeKycApproved } = useKycStatus()
const { hasPendingTransactions } = usePendingTransactions()
const swapCurrency = searchParams.get('swap-currency') ?? 'false'

// Get method and country from URL parameters
const selectedMethodType = searchParams.get('method') // mercadopago, pix, bank-transfer, etc.
const countryFromUrl = searchParams.get('country') // argentina, brazil, etc.
Expand Down Expand Up @@ -431,7 +431,7 @@ export default function MantecaWithdrawFlow() {
walletBalance={
balance ? formatAmount(formatUnits(balance, PEANUT_WALLET_TOKEN_DECIMALS)) : undefined
}
isInitialInputUsd={swapCurrency !== 'true'}
isInitialInputUsd
/>
<Button
variant="purple"
Expand Down
4 changes: 0 additions & 4 deletions src/app/[...recipient]/client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import SupportCTA from '@/components/Global/SupportCTA'
import { BankRequestType, useDetermineBankRequestType } from '@/hooks/useDetermineBankRequestType'
import { PointsAction } from '@/services/services.types'
import { usePointsCalculation } from '@/hooks/usePointsCalculation'
import { useHaptic } from 'use-haptic'

export type PaymentFlow = 'request_pay' | 'external_wallet' | 'direct_pay' | 'withdraw'
interface Props {
Expand Down Expand Up @@ -73,7 +72,6 @@ export default function PaymentPage({ recipient, flow = 'request_pay' }: Props)
fulfillUsingManteca,
} = useRequestFulfillmentFlow()
const { requestType } = useDetermineBankRequestType(chargeDetails?.requestLink.recipientAccount.userId ?? '')
const { triggerHaptic } = useHaptic()

// Calculate points API call
// Points are ALWAYS calculated based on USD value (per PR.md: "1c in cost = 10 pts")
Expand Down Expand Up @@ -136,7 +134,6 @@ export default function PaymentPage({ recipient, flow = 'request_pay' }: Props)

// show STATUS view for any payment attempt (including failed ones)
if (latestPayment.status !== 'NEW') {
triggerHaptic()
dispatch(paymentActions.setView('STATUS'))
}
}
Expand Down Expand Up @@ -407,7 +404,6 @@ export default function PaymentPage({ recipient, flow = 'request_pay' }: Props)

// show status view only if fulfillment payment is successful
if (chargeDetails?.fulfillmentPayment?.status === 'SUCCESSFUL') {
triggerHaptic()
dispatch(paymentActions.setView('STATUS'))
}

Expand Down
5 changes: 5 additions & 0 deletions src/app/api/peanut/get-attachment-info/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import * as consts from '@/constants'
import { fetchWithSentry } from '@/utils'

export async function POST(request: NextRequest) {
//TODO: enable if we have attachments again, using /send-link instead of
//get-link-details
return new NextResponse(null, { status: 405 })
/*
try {
const { link } = await request.json()
const params = getRawParamsFromLink(link)
Expand Down Expand Up @@ -43,4 +47,5 @@ export async function POST(request: NextRequest) {
console.error('Failed to get attachment:', error)
return new NextResponse('Internal Server Error', { status: 500 })
}
*/
}
Loading
Loading