'use client' import { noop } from 'es-toolkit/function' import { useCallback, useState } from 'react' import { useTranslation } from 'react-i18next' import Button from '@/app/components/base/button' import Input from '@/app/components/base/input' import { toast } from '@/app/components/base/ui/toast' import { emailRegex } from '@/config' import { useLocale } from '@/context/i18n' import { useWebAppStore } from '@/context/web-app-context' import Link from '@/next/link' import { useRouter, useSearchParams } from '@/next/navigation' import { webAppLogin } from '@/service/common' import { fetchAccessToken } from '@/service/share' import { setWebAppAccessToken, setWebAppPassport } from '@/service/webapp-auth' import { encryptPassword } from '@/utils/encryption' type MailAndPasswordAuthProps = { isEmailSetup: boolean } export default function MailAndPasswordAuth({ isEmailSetup }: MailAndPasswordAuthProps) { const { t } = useTranslation() const locale = useLocale() const router = useRouter() const searchParams = useSearchParams() const [showPassword, setShowPassword] = useState(false) const emailFromLink = decodeURIComponent(searchParams.get('email') || '') const [email, setEmail] = useState(emailFromLink) const [password, setPassword] = useState('') const [isLoading, setIsLoading] = useState(false) const redirectUrl = searchParams.get('redirect_url') const embeddedUserId = useWebAppStore(s => s.embeddedUserId) const getAppCodeFromRedirectUrl = useCallback(() => { if (!redirectUrl) return null const url = new URL(`${window.location.origin}${decodeURIComponent(redirectUrl)}`) const appCode = url.pathname.split('/').pop() if (!appCode) return null return appCode }, [redirectUrl]) const appCode = getAppCodeFromRedirectUrl() const handleEmailPasswordLogin = async () => { if (!email) { toast.error(t('error.emailEmpty', { ns: 'login' })) return } if (!emailRegex.test(email)) { toast.error(t('error.emailInValid', { ns: 'login' })) return } if (!password?.trim()) { toast.error(t('error.passwordEmpty', { ns: 'login' })) return } if (!redirectUrl || !appCode) { toast.error(t('error.redirectUrlMissing', { ns: 'login' })) return } try { setIsLoading(true) const loginData: Record = { email, password: encryptPassword(password), language: locale, remember_me: true, } const res = await webAppLogin({ url: '/login', body: loginData, }) if (res.result === 'success') { if (res?.data?.access_token) { setWebAppAccessToken(res.data.access_token) } const { access_token } = await fetchAccessToken({ appCode: appCode!, userId: embeddedUserId || undefined, }) setWebAppPassport(appCode!, access_token) router.replace(decodeURIComponent(redirectUrl)) } else { toast.error(res.data) } } catch (e: any) { if (e.code === 'authentication_failed') toast.error(e.message) } finally { setIsLoading(false) } } return (
setEmail(e.target.value)} id="email" type="email" autoComplete="email" placeholder={t('emailPlaceholder', { ns: 'login' }) || ''} tabIndex={1} />
setPassword(e.target.value)} id="password" onKeyDown={(e) => { if (e.key === 'Enter') handleEmailPasswordLogin() }} type={showPassword ? 'text' : 'password'} autoComplete="current-password" placeholder={t('passwordPlaceholder', { ns: 'login' }) || ''} tabIndex={2} />
) }