Step2UserVerification.tsx (5584B)
1 import { useIntl } from "react-intl"; 2 import { useEffect, useState } from "react"; 3 import { AccountInfo, Profile, getProfile, getPurpleAccountInfo } from "@/utils/PurpleUtils"; 4 import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/Tabs"; 5 import { StepHeader } from "./StepHeader"; 6 import { LNCheckout } from "./Types"; 7 import { Step2OTPVerification } from "./Step2OTPVerification"; 8 import { Step2DamusIOSVerification } from "./Step2DamusIOSVerification"; 9 import { NostrProfile } from "@/components/NostrProfile"; 10 import { Sparkles } from "lucide-react"; 11 import { AccountExistsNoteIfAccountExists } from "./AccountExistsNote"; 12 13 export interface Step2UserVerificationProps { 14 lnCheckout: LNCheckout | null 15 setLNCheckout: (checkout: LNCheckout) => void 16 selectedAuthMethod: string | "nostr-dm" | "damus-ios" 17 setSelectedAuthMethod: (method: string) => void 18 setError: (error: string) => void 19 } 20 21 export function Step2UserVerification(props: Step2UserVerificationProps) { 22 const intl = useIntl() 23 const [pubkey, setPubkey] = useState<string | null>(null) 24 const [profile, setProfile] = useState<Profile | undefined | null>(undefined) // The profile info fetched from the Damus relay 25 const [existingAccountInfo, setExistingAccountInfo] = useState<AccountInfo | null | undefined>(undefined) // The account info fetched from the server 26 27 const step1Done = props.lnCheckout?.product_template_name != null 28 const step2Done = props.lnCheckout?.verified_pubkey != null 29 30 // MARK: - Functions 31 32 const fetchProfile = async () => { 33 if (!pubkey) { 34 return 35 } 36 try { 37 const profile = await getProfile(pubkey) 38 setProfile(profile) 39 } 40 catch (e) { 41 console.error(e) 42 props.setError("Failed to get profile info from the relay. Please wait a few minutes and refresh the page. If the problem persists, please contact support.") 43 } 44 } 45 46 const fetchAccountInfo = async () => { 47 if (!pubkey) { 48 setExistingAccountInfo(undefined) 49 return 50 } 51 try { 52 const accountInfo = await getPurpleAccountInfo(pubkey) 53 setExistingAccountInfo(accountInfo) 54 } 55 catch (e) { 56 console.error(e) 57 props.setError("Failed to get account info from our servers. Please wait a few minutes and refresh the page. If the problem persists, please contact support.") 58 } 59 } 60 61 // MARK: - Effects and hooks 62 63 // Load the profile when the pubkey changes 64 useEffect(() => { 65 if (pubkey) { 66 fetchProfile() 67 fetchAccountInfo() 68 } 69 }, [pubkey]) 70 71 // Reset pubkey if user switches tabs 72 useEffect(() => { 73 setPubkey(null) 74 setProfile(null) 75 }, [props.selectedAuthMethod]) 76 77 useEffect(() => { 78 if (props.lnCheckout?.verified_pubkey) { 79 setPubkey(props.lnCheckout.verified_pubkey) 80 } 81 }, [props.lnCheckout]) 82 83 // MARK: - Render 84 85 return (<> 86 <StepHeader 87 stepNumber={2} 88 title={intl.formatMessage({ id: "purple.checkout.step-2", defaultMessage: "Verify your npub" })} 89 done={step2Done} 90 active={step1Done} 91 /> 92 {props.lnCheckout && !step2Done && 93 <Tabs defaultValue="nostr-dm" className="w-full flex flex-col items-center mb-6" value={props.selectedAuthMethod} onValueChange={(newValue: string) => { props.setSelectedAuthMethod(newValue) } }> 94 <TabsList className="mx-auto"> 95 <TabsTrigger value="nostr-dm" disabled={step2Done}>via Nostr DMs</TabsTrigger> 96 <TabsTrigger value="damus-ios" disabled={step2Done}>via Damus iOS</TabsTrigger> 97 </TabsList> 98 <TabsContent value="nostr-dm"> 99 <Step2OTPVerification 100 lnCheckout={props.lnCheckout} 101 setLNCheckout={props.setLNCheckout} 102 pubkey={pubkey} 103 setPubkey={setPubkey} 104 profile={profile} 105 setProfile={setProfile} 106 existingAccountInfo={existingAccountInfo} 107 setError={props.setError} 108 /> 109 </TabsContent> 110 <TabsContent value="damus-ios"> 111 <Step2DamusIOSVerification 112 lnCheckout={props.lnCheckout} 113 setLNCheckout={props.setLNCheckout} 114 pubkey={pubkey} 115 setPubkey={setPubkey} 116 profile={profile} 117 setProfile={setProfile} 118 setError={props.setError} 119 /> 120 </TabsContent> 121 </Tabs> 122 } 123 {step2Done && pubkey && (profile !== undefined) && <> 124 <NostrProfile 125 pubkey={pubkey} 126 profile={profile} 127 profileHeader={<> 128 <div className="text-purple-200/50 font-normal text-sm"> 129 {existingAccountInfo === null || existingAccountInfo === undefined ? <> 130 {props.lnCheckout?.verified_pubkey && !props.lnCheckout?.invoice?.paid && intl.formatMessage({ id: "purple.checkout.purchasing-for", defaultMessage: "Verified. Purchasing Damus Purple for:" })} 131 {props.lnCheckout?.invoice?.paid && intl.formatMessage({ id: "purple.checkout.purchased-for", defaultMessage: "Purchased Damus Purple for:" })} 132 </> : <> 133 {props.lnCheckout?.verified_pubkey && !props.lnCheckout?.invoice?.paid && intl.formatMessage({ id: "purple.checkout.renewing-for", defaultMessage: "Verified. Renewing Damus Purple for:" })} 134 {props.lnCheckout?.invoice?.paid && intl.formatMessage({ id: "purple.checkout.renewed-for", defaultMessage: "Renewed Damus Purple for:" })} 135 </>} 136 </div> 137 </>} 138 profileFooter={<> 139 <AccountExistsNoteIfAccountExists existingAccountInfo={existingAccountInfo}/> 140 </>} 141 /> 142 </>} 143 </>) 144 }