import { useEffect, useState, type FormEvent } from 'react'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { updateProfile, currentUserQueryKey, type UpdateProfileInput } from '@/api/users'; import { ErrorNotice, LoadingNotice } from '@/components/ui/ErrorNotice'; import { Field, SelectField, TextAreaField } from '@/components/ui/Field'; import { Button, Card } from '@/components/ui/primitives'; import { supportedLanguages, type SupportedLanguage } from '@/i18n'; import { useCurrentUser } from '@/lib/hooks'; import { useSessionStore } from '@/stores/session'; import { userStatuses } from '@/api/types'; /** Профиль: отображаемое имя, «о себе», своё состояние, статус и язык. */ export default function ProfileSettingsPage() { const { t, i18n } = useTranslation(); const queryClient = useQueryClient(); const currentUser = useCurrentUser(); const [displayName, setDisplayName] = useState(''); const [bio, setBio] = useState(''); const [customStatus, setCustomStatus] = useState(''); const [customEmoji, setCustomEmoji] = useState(''); const [status, setStatus] = useState('online'); const [locale, setLocale] = useState('ru'); const [saved, setSaved] = useState(false); const user = currentUser.data; useEffect(() => { if (user === undefined) { return; } setDisplayName(user.display_name); setBio(user.bio); setCustomStatus(user.custom_status); setCustomEmoji(user.custom_status_emoji); setStatus(user.status); setLocale(user.locale === 'en' ? 'en' : 'ru'); }, [user]); const save = useMutation({ mutationFn: (input: UpdateProfileInput) => updateProfile(input), onSuccess: (updated) => { queryClient.setQueryData(currentUserQueryKey, updated); useSessionStore.getState().patchUser(updated); setSaved(true); if (updated.locale === 'en' || updated.locale === 'ru') { window.localStorage.setItem('glchat.language', updated.locale); void i18n.changeLanguage(updated.locale); } }, }); const onSubmit = (event: FormEvent): void => { event.preventDefault(); setSaved(false); save.mutate({ display_name: displayName.trim(), bio: bio.trim(), custom_status: customStatus.trim(), custom_status_emoji: customEmoji.trim(), status, locale, }); }; if (currentUser.isPending) { return ( ); } if (currentUser.isError || user === undefined) { return ( void currentUser.refetch()} /> ); } return (

{t('settings.profile.title')}

{t('settings.profile.description')}

setDisplayName(event.target.value)} /> setBio(event.target.value)} />
setCustomStatus(event.target.value)} /> setCustomEmoji(event.target.value)} />
({ value, label: t(`user.status.${value}`), }))} /> setLocale(value === 'en' ? 'en' : 'ru')} options={supportedLanguages.map((language) => ({ value: language, label: t(`language.${language}`), }))} />
{t('settings.profile.username')}
{user.username}
{t('settings.profile.userId')}
{user.id}
{t('settings.profile.badges')}
{user.badges.length === 0 ? t('settings.profile.noBadges') : user.badges.join(', ')}
{save.isError ? : null} {saved && !save.isError ? (

{t('settings.profile.saved')}

) : null}
); }