LightningAddressInput.tsx raw
1 import { Button } from '@/components/ui/button'
2 import { Input } from '@/components/ui/input'
3 import { Label } from '@/components/ui/label'
4 import { createProfileDraftEvent } from '@/lib/draft-event'
5 import { isEmail } from '@/lib/utils'
6 import { useNostr } from '@/providers/NostrProvider'
7 import { Loader } from 'lucide-react'
8 import { useEffect, useState } from 'react'
9 import { useTranslation } from 'react-i18next'
10 import { toast } from 'sonner'
11
12 export default function LightningAddressInput() {
13 const { t } = useTranslation()
14 const { profile, profileEvent, publish, updateProfileEvent } = useNostr()
15 const [lightningAddress, setLightningAddress] = useState('')
16 const [hasChanged, setHasChanged] = useState(false)
17 const [saving, setSaving] = useState(false)
18
19 useEffect(() => {
20 if (profile) {
21 setLightningAddress(profile.lightningAddress || '')
22 }
23 }, [profile])
24
25 if (!profile || !profileEvent) {
26 return null
27 }
28
29 const handleSave = async () => {
30 setSaving(true)
31 const profileContent = profileEvent ? JSON.parse(profileEvent.content) : {}
32 if (lightningAddress.startsWith('lnurl')) {
33 profileContent.lud06 = lightningAddress
34 } else if (isEmail(lightningAddress)) {
35 profileContent.lud16 = lightningAddress
36 } else if (lightningAddress) {
37 toast.error(t('Invalid Lightning Address. Please enter a valid Lightning Address or LNURL.'))
38 setSaving(false)
39 return
40 } else {
41 delete profileContent.lud16
42 }
43
44 const profileDraftEvent = createProfileDraftEvent(
45 JSON.stringify(profileContent),
46 profileEvent?.tags
47 )
48 const newProfileEvent = await publish(profileDraftEvent)
49 await updateProfileEvent(newProfileEvent)
50 setSaving(false)
51 }
52
53 return (
54 <div className="w-full space-y-1">
55 <Label htmlFor="ln-address">{t('Lightning Address (or LNURL)')}</Label>
56 <div className="flex w-full items-center gap-2">
57 <Input
58 id="ln-address"
59 placeholder="xxxxxxxx@xxx.xxx"
60 value={lightningAddress}
61 onChange={(e) => {
62 setLightningAddress(e.target.value)
63 setHasChanged(true)
64 }}
65 />
66 <Button onClick={handleSave} disabled={saving || !hasChanged} className="w-20">
67 {saving ? <Loader className="animate-spin" /> : t('Save')}
68 </Button>
69 </div>
70 </div>
71 )
72 }
73