Skip to content

Commit

Permalink
fix(unlock-app): Improve migration checkout experience (#15084)
Browse files Browse the repository at this point in the history
* update connectpage

* allow user to sign out

* update migration feedback

* update connectpage

* cleanup

* cleanup

* more cleanup
  • Loading branch information
0xTxbi authored Nov 14, 2024
1 parent c4ebea9 commit 0ee9043
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 41 deletions.
25 changes: 20 additions & 5 deletions unlock-app/src/components/interface/checkout/main/ConnectPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,21 @@ interface ConnectPageProps {
showPrivyModal: boolean
}

export const ConnectPage = ({ style, showPrivyModal }: ConnectPageProps) => {
export const ConnectPage = ({
style,
checkoutService,
showPrivyModal,
}: ConnectPageProps) => {
const [showLegacyMessage, setShowLegacyMessage] = useState(false)
const [showMigrationSteps, setShowMigrationSteps] = useState(false)
const { user } = usePrivy()
const { user, logout: privyLogout } = usePrivy()

const handleSignOut = async () => {
await privyLogout()
setShowMigrationSteps(false)
setShowLegacyMessage(false)
checkoutService?.send({ type: 'SELECT' })
}

useEffect(() => {
// check if the user has a legacy account
Expand All @@ -31,7 +42,12 @@ export const ConnectPage = ({ style, showPrivyModal }: ConnectPageProps) => {
}, [user?.email?.address, user?.wallet?.address, user])

if (showMigrationSteps) {
return <MigrateUserCheckout userEmail={user?.email?.address || ''} />
return (
<MigrateUserCheckout
userEmail={user?.email?.address || ''}
onSignOut={handleSignOut}
/>
)
}

if (showLegacyMessage) {
Expand All @@ -43,8 +59,7 @@ export const ConnectPage = ({ style, showPrivyModal }: ConnectPageProps) => {
<h2 className="text-xl font-bold">Legacy Account Detected</h2>
<p>
We&apos;ve detected that you have an existing Unlock account that
needs to be migrated. Please visit the migration page to complete the
migration process.
needs to be migrated. Please proceed to migrate your account.
</p>

<div className="flex justify-center">
Expand Down
26 changes: 20 additions & 6 deletions unlock-app/src/components/legacy-auth/MigrateUserCheckout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@ import { SignInWithPassword } from './SignInWithPassword'
import { SignInWithCode } from './SignInWithCode'
import { SignInWithGoogle } from './SignInWithGoogle'

export const MigrateUserCheckout = ({ userEmail }: { userEmail: string }) => {
interface MigrateUserCheckoutProps {
userEmail: string
onSignOut: () => Promise<void>
}

export const MigrateUserCheckout = ({
userEmail,
onSignOut,
}: MigrateUserCheckoutProps) => {
const [walletPk, setWalletPk] = useState<string | null>(null)
const [userAccountType, setUserAccountType] = useState<UserAccountType[]>([])

console.log('walletPk', walletPk)

// Mutation to handle the user account type
const checkUserAccountType = useMutation({
mutationFn: async (email: string) => {
Expand Down Expand Up @@ -69,9 +75,17 @@ export const MigrateUserCheckout = ({ userEmail }: { userEmail: string }) => {

return (
<div className="px-4 space-y-16 mt-4">
<h3 className="text-sm text-center">
migrating <span className="font-bold text-md">{userEmail}</span>
</h3>
<div>
<h3 className="text-sm text-center">
Migrating <span className="font-bold text-md">{userEmail}</span>
</h3>
<p
onClick={onSignOut}
className="text-sm text-center text-brand-ui-primary underline cursor-pointer"
>
Sign out
</p>
</div>

{!walletPk && (
<div className="space-y-2">
Expand Down
94 changes: 64 additions & 30 deletions unlock-app/src/components/legacy-auth/MigrationFeedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { Button } from '@unlock-protocol/ui'
import { usePrivy } from '@privy-io/react-auth'
import { useState } from 'react'
import { useState, useEffect } from 'react'
import Link from 'next/link'
import { onSignedInWithPrivy } from '~/config/PrivyProvider'
import { FaCheckCircle as CheckIcon } from 'react-icons/fa'
Expand All @@ -21,39 +21,60 @@ export default function MigrationFeedback({
const { importWallet, user } = usePrivy()
const [isImporting, setIsImporting] = useState(false)
const [isImported, setIsImported] = useState(false)
const [importError, setImportError] = useState<string | null>(null)
const [authError, setAuthError] = useState<string | null>(null)
const [hasImported, setHasImported] = useState(false)

const handleImport = async () => {
setIsImporting(true)
setImportError(null)
setAuthError(null)
onMigrationStart?.()
try {
// First attempt the wallet import
// Attempt the wallet import
const importResult = await importWallet({ privateKey: walletPk })

if (!importResult) {
ToastHelper.error(
'Failed to import wallet. Please ensure your private key is correct and try again.'
)
throw new Error(
'Failed to import wallet. Please ensure your private key is correct and try again.'
)
}

// Only proceed with dashboard authentication if wallet import was successful
try {
if (user) {
setHasImported(true)
// The user state will be updated asynchronously, handled by useEffect
} catch (error: any) {
console.error('Failed to import wallet:', error)
setImportError(
error.message || 'Failed to import wallet. Please try again.'
)
} finally {
setIsImporting(false)
}
}

useEffect(() => {
const authenticateUser = async () => {
if (user && hasImported) {
try {
await onSignedInWithPrivy(user)
setIsImported(true)
} catch (authError: any) {
console.error(
'Failed to fully authenticate with dashboard:',
authError
)
setAuthError(
'Wallet imported successfully, but authentication failed. Please try signing in again to use the dashboard.'
)
}
} catch (authError) {
console.error('Failed to fully authenticate with dashboard:', authError)
ToastHelper.error(
'Wallet imported successfully, but authentication failed. Please try signing in again to use the dashboard.'
)
}
} catch (importError) {
console.error('Failed to import wallet:', importError)
ToastHelper.error('Failed to import wallet. Please try again.')
} finally {
setIsImporting(false)
}
}

authenticateUser()
}, [user, hasImported])

const isCheckoutMode = mode === 'checkout'
const baseTextClasses = 'text-gray-700'
Expand All @@ -65,21 +86,34 @@ export default function MigrationFeedback({
<div className="space-y-5">
{!isImported ? (
<>
<p
className={`${isCheckoutMode ? 'text-center' : ''} ${baseTextClasses}`}
>
Your wallet will now be managed securely by Privy, making it easier
to access your assets across devices. Click below to proceed with
the migration.
</p>
{!hasImported && (
<>
<p
className={`${isCheckoutMode ? 'text-center' : ''} ${baseTextClasses}`}
>
Your wallet will now be managed securely by Privy, making it
easier to access your assets across devices. Click below to
proceed with the migration.
</p>

{importError && <div className="text-red-500">{importError}</div>}

<Button
onClick={handleImport}
disabled={isImporting}
className="w-full"
>
{isImporting ? 'Importing Wallet...' : 'Start Migration'}
</Button>
<Button
onClick={handleImport}
disabled={isImporting}
className="w-full"
>
{isImporting ? 'Importing Wallet...' : 'Start Migration'}
</Button>
</>
)}

{hasImported && !isImported && (
<>
{authError && <div className="text-red-500">{authError}</div>}
{isImporting && <div>Authenticating...</div>}
</>
)}
</>
) : (
<>
Expand Down

0 comments on commit 0ee9043

Please sign in to comment.