2026-01-14 00:50:05 +01:00

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('')
}