141 lines
5.1 KiB
TypeScript
141 lines
5.1 KiB
TypeScript
import { useState } from 'react'
|
|
import { CreateAccountModal } from '../CreateAccountModal'
|
|
import { RecoveryStep } from '../CreateAccountModalSteps'
|
|
import { UnlockAccountModal } from '../UnlockAccountModal'
|
|
import { Button, Card } from '../ui'
|
|
import { t } from '@/lib/i18n'
|
|
|
|
export function NoAccountView(): React.ReactElement {
|
|
const [showImportModal, setShowImportModal] = useState(false)
|
|
const [showRecoveryStep, setShowRecoveryStep] = useState(false)
|
|
const [showUnlockModal, setShowUnlockModal] = useState(false)
|
|
const [recoveryPhrase, setRecoveryPhrase] = useState<string[]>([])
|
|
const [npub, setNpub] = useState('')
|
|
const [generating, setGenerating] = useState(false)
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
const handleGenerate = (): void => {
|
|
void generateNoAccount({ setGenerating, setError, setRecoveryPhrase, setNpub, setShowRecoveryStep })
|
|
}
|
|
const handleRecoveryContinue = (): void => transitionToUnlock({ setShowRecoveryStep, setShowUnlockModal })
|
|
const handleUnlockSuccess = (): void => resetNoAccountAfterUnlock({ setShowUnlockModal, setRecoveryPhrase, setNpub })
|
|
const handleImportSuccess = (): void => {
|
|
setShowImportModal(false)
|
|
setShowUnlockModal(true)
|
|
}
|
|
|
|
return (
|
|
<NoAccountCard
|
|
error={error}
|
|
generating={generating}
|
|
onGenerate={handleGenerate}
|
|
onImport={() => setShowImportModal(true)}
|
|
modals={
|
|
<NoAccountModals
|
|
showImportModal={showImportModal}
|
|
onCloseImport={() => setShowImportModal(false)}
|
|
onImportSuccess={handleImportSuccess}
|
|
showRecoveryStep={showRecoveryStep}
|
|
recoveryPhrase={recoveryPhrase}
|
|
npub={npub}
|
|
onRecoveryContinue={handleRecoveryContinue}
|
|
showUnlockModal={showUnlockModal}
|
|
onUnlockSuccess={handleUnlockSuccess}
|
|
onCloseUnlock={() => setShowUnlockModal(false)}
|
|
/>
|
|
}
|
|
/>
|
|
)
|
|
}
|
|
|
|
function NoAccountActionButtons(params: { onGenerate: () => void; onImport: () => void }): React.ReactElement {
|
|
return (
|
|
<div className="flex flex-col gap-3 w-full max-w-xs">
|
|
<Button variant="primary" size="large" onClick={params.onGenerate}>
|
|
{t('account.create.generateButton')}
|
|
</Button>
|
|
<Button variant="secondary" size="large" onClick={params.onImport}>
|
|
{t('account.create.importButton')}
|
|
</Button>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function NoAccountCard(params: {
|
|
error: string | null
|
|
generating: boolean
|
|
onGenerate: () => void
|
|
onImport: () => void
|
|
modals: React.ReactElement
|
|
}): React.ReactElement {
|
|
return (
|
|
<Card variant="default" className="bg-cyber-dark/50">
|
|
<div className="flex flex-col items-center gap-4">
|
|
<p className="text-center text-cyber-accent mb-2">Créez un compte ou importez votre clé secrète pour commencer</p>
|
|
{params.error ? <p className="text-sm text-red-400">{params.error}</p> : null}
|
|
<NoAccountActionButtons onGenerate={params.onGenerate} onImport={params.onImport} />
|
|
{params.generating ? <p className="text-cyber-accent text-sm">Génération du compte...</p> : null}
|
|
{params.modals}
|
|
</div>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
function NoAccountModals(params: {
|
|
showImportModal: boolean
|
|
onImportSuccess: () => void
|
|
onCloseImport: () => void
|
|
showRecoveryStep: boolean
|
|
recoveryPhrase: string[]
|
|
npub: string
|
|
onRecoveryContinue: () => void
|
|
showUnlockModal: boolean
|
|
onUnlockSuccess: () => void
|
|
onCloseUnlock: () => void
|
|
}): React.ReactElement {
|
|
return (
|
|
<>
|
|
{params.showImportModal ? <CreateAccountModal onSuccess={params.onImportSuccess} onClose={params.onCloseImport} initialStep="import" /> : null}
|
|
{params.showRecoveryStep ? <RecoveryStep recoveryPhrase={params.recoveryPhrase} npub={params.npub} onContinue={params.onRecoveryContinue} /> : null}
|
|
{params.showUnlockModal ? <UnlockAccountModal onSuccess={params.onUnlockSuccess} onClose={params.onCloseUnlock} /> : null}
|
|
</>
|
|
)
|
|
}
|
|
|
|
async function generateNoAccount(params: {
|
|
setGenerating: (value: boolean) => void
|
|
setError: (value: string | null) => void
|
|
setRecoveryPhrase: (value: string[]) => void
|
|
setNpub: (value: string) => void
|
|
setShowRecoveryStep: (value: boolean) => void
|
|
}): Promise<void> {
|
|
params.setGenerating(true)
|
|
params.setError(null)
|
|
try {
|
|
const { nostrAuthService } = await import('@/lib/nostrAuth')
|
|
const result = await nostrAuthService.createAccount()
|
|
params.setRecoveryPhrase(result.recoveryPhrase)
|
|
params.setNpub(result.npub)
|
|
params.setShowRecoveryStep(true)
|
|
} catch (e) {
|
|
params.setError(e instanceof Error ? e.message : t('account.create.error.failed'))
|
|
} finally {
|
|
params.setGenerating(false)
|
|
}
|
|
}
|
|
|
|
function transitionToUnlock(params: { setShowRecoveryStep: (value: boolean) => void; setShowUnlockModal: (value: boolean) => void }): void {
|
|
params.setShowRecoveryStep(false)
|
|
params.setShowUnlockModal(true)
|
|
}
|
|
|
|
function resetNoAccountAfterUnlock(params: {
|
|
setShowUnlockModal: (value: boolean) => void
|
|
setRecoveryPhrase: (value: string[]) => void
|
|
setNpub: (value: string) => void
|
|
}): void {
|
|
params.setShowUnlockModal(false)
|
|
params.setRecoveryPhrase([])
|
|
params.setNpub('')
|
|
}
|