import { useState, type FormEvent } from 'react'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { guildQueryKey, updateGuild } from '@/api/guilds'; import { myGuildsQueryKey } from '@/api/users'; import type { Guild } from '@/api/types'; import { ErrorNotice } from '@/components/ui/ErrorNotice'; import { Field, TextAreaField } from '@/components/ui/Field'; import { Button } from '@/components/ui/primitives'; import { useUnsavedChanges } from '@/lib/unsavedChanges'; import { useSessionStore } from '@/stores/session'; import { SettingsSection } from '@/pages/settings/SettingsSection'; interface GuildGeneralSectionProps { guild: Guild; /** Владелец или участник с правами управления — иначе поля только для чтения. */ canEdit: boolean; } /** Общее в настройках сервера: имя и описание (PATCH /guilds/{id}). */ export function GuildGeneralSection({ guild, canEdit }: GuildGeneralSectionProps) { const { t } = useTranslation(); const queryClient = useQueryClient(); const [name, setName] = useState(guild.name); const [description, setDescription] = useState(guild.description); const [saved, setSaved] = useState(false); const save = useMutation({ mutationFn: () => updateGuild(guild.id, { name: name.trim(), description: description.trim() }), onSuccess: (updated) => { queryClient.setQueryData(guildQueryKey(guild.id), updated); // Рейка и сайдбар берут имя из снапшота — обновляем и его. useSessionStore.getState().renameGuild(guild.id, updated.name); void queryClient.invalidateQueries({ queryKey: guildQueryKey(guild.id) }); void queryClient.invalidateQueries({ queryKey: myGuildsQueryKey }); setSaved(true); }, }); const onSubmit = (event: FormEvent): void => { event.preventDefault(); if (!canEdit || name.trim() === '') { return; } setSaved(false); save.mutate(); }; // Незавершённая правка имени или описания: закрытие окна не должно её терять. useUnsavedChanges({ dirty: name !== guild.name || description !== guild.description, save: async () => { await save.mutateAsync(); }, }); return (
setName(event.target.value)} /> setDescription(event.target.value)} /> {canEdit ? null : (

{t('settings.servers.readOnlyHint')}

)} {save.isError ? : null} {saved && !save.isError ? (

{t('settings.servers.general.saved')}

) : null} {canEdit ? (
) : null}
); }