'use client' import { useCallback, useState } from 'react' import { useContext } from 'use-context-selector' import { useTranslation } from 'react-i18next' import useSWR from 'swr' import { useSearchParams } from 'next/navigation' import cn from 'classnames' import Link from 'next/link' import { CheckCircleIcon } from '@heroicons/react/24/solid' import style from './style.module.css' import Button from '@/app/components/base/button' import { SimpleSelect } from '@/app/components/base/select' import { timezones } from '@/utils/timezone' import { LanguagesSupported, languages } from '@/i18n/language' import { activateMember, invitationCheck } from '@/service/common' import Toast from '@/app/components/base/toast' import Loading from '@/app/components/base/loading' import I18n from '@/context/i18n' const validPassword = /^(?=.*[a-zA-Z])(?=.*\d).{8,}$/ const ActivateForm = () => { const { t } = useTranslation() const { locale, setLocaleOnClient } = useContext(I18n) const searchParams = useSearchParams() const workspaceID = searchParams.get('workspace_id') const email = searchParams.get('email') const token = searchParams.get('token') const checkParams = { url: '/activate/check', params: { ...workspaceID && { workspace_id: workspaceID }, ...email && { email }, token, }, } const { data: checkRes, mutate: recheck } = useSWR(checkParams, invitationCheck, { revalidateOnFocus: false, }) const [name, setName] = useState('') const [password, setPassword] = useState('') const [timezone, setTimezone] = useState('Asia/Shanghai') const [language, setLanguage] = useState(locale) const [showSuccess, setShowSuccess] = useState(false) const defaultLanguage = useCallback(() => (window.navigator.language.startsWith('zh') ? LanguagesSupported[1] : LanguagesSupported[0]) || LanguagesSupported[0], []) const showErrorMessage = useCallback((message: string) => { Toast.notify({ type: 'error', message, }) }, []) const valid = useCallback(() => { if (!name.trim()) { showErrorMessage(t('login.error.nameEmpty')) return false } if (!password.trim()) { showErrorMessage(t('login.error.passwordEmpty')) return false } if (!validPassword.test(password)) showErrorMessage(t('login.error.passwordInvalid')) return true }, [name, password, showErrorMessage, t]) const handleActivate = useCallback(async () => { if (!valid()) return try { await activateMember({ url: '/activate', body: { workspace_id: workspaceID, email, token, name, password, interface_language: language, timezone, }, }) setLocaleOnClient(language.startsWith('en') ? 'en' : 'zh-Hans', false) setShowSuccess(true) } catch { recheck() } }, [email, language, name, password, recheck, setLocaleOnClient, timezone, token, valid, workspaceID]) return (
{!checkRes && } {checkRes && !checkRes.is_valid && (
🤷‍♂️

{t('login.invalid')}

)} {checkRes && checkRes.is_valid && !showSuccess && (

{`${t('login.join')} ${checkRes.workspace_name}`}

{`${t('login.joinTipStart')} ${checkRes.workspace_name} ${t('login.joinTipEnd')}`}

{/* username */}
setName(e.target.value)} placeholder={t('login.namePlaceholder') || ''} className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder-gray-400 caret-primary-600 sm:text-sm pr-10'} />
{/* password */}
setPassword(e.target.value)} placeholder={t('login.passwordPlaceholder') || ''} className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder-gray-400 caret-primary-600 sm:text-sm pr-10'} />
{t('login.error.passwordInvalid')}
{/* language */}
{ setLanguage(item.value as string) }} />
{/* timezone */}
{ setTimezone(item.value as string) }} />
{t('login.license.tip')}   {t('login.license.link')}
)} {checkRes && checkRes.is_valid && showSuccess && (

{`${t('login.activatedTipStart')} ${checkRes.workspace_name} ${t('login.activatedTipEnd')}`}

)}
) } export default ActivateForm