Files
hr-appeals/src/features/feedback/FeedbackForm.tsx
T
gorbenko.pavel ebadf795e8
Tests / frontend-test (push) Successful in 3m40s
fix: убирает сворачиваемые секции формы
CollapseSection превращал заголовки "Кто обращается" / "Суть обращения" в
кнопки — по клику секция пряталась целиком, вместе с обязательными полями.
Легко было свернуть случайно и не заметить, что часть формы больше не видна
(и не отправляется). Заменены на обычные div с отступом: контент всегда
на экране, сворачивать нечего.

Один из двух известных факторов, из-за которых форма на мобильном "теряла"
часть контента (второй — фикс на 100dvh, отдельным коммитом): свёрнутая
секция резко уменьшала высоту страницы, из-за чего казалось, что скролл
пропал и форма "не двигается вниз".

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 10:43:18 +05:00

70 lines
2.8 KiB
TypeScript

import { Alert, Button, FormActions, FormCard, FormGrid, Toggle } from '@tnsu/ui-kit';
import { Field } from '../../components/Field/Field';
import { AppealSection } from './sections/AppealSection';
import { AuthorSection } from './sections/AuthorSection';
import { ThankYouScreen } from './ThankYouScreen';
import { TEXTS } from './texts';
import { useFeedbackForm } from './useFeedbackForm';
import styles from './FeedbackForm.module.scss';
/** Форма обращения в HR: сбор данных, валидация, экран благодарности. */
export const FeedbackForm: React.FC = () => {
const { data, errors, status, formError, set, submit, reset } = useFeedbackForm();
if (status === 'done') {
return <ThankYouScreen isAnonymous={data.isAnonymous} onNewAppeal={reset} />;
}
return (
// FormCard требует title, но заголовок страницы уже показан в PageShell
// (App.tsx) — второй здесь был бы дублем. Пустая строка убирает текст,
// а гэпа не оставляет: у ui-kit пустой title-блок не создаёт строки.
<FormCard title="">
{formError ? (
<div className={styles.notice}>
<Alert variant="err">{formError}</Alert>
</div>
) : null}
{/* Раньше секции лежали в CollapseSection и сворачивались по клику на
заголовок — можно было случайно спрятать обязательные поля и не
заметить это. Группа теперь просто div с отступом: поля всегда видны. */}
<div className={styles.group}>
<AuthorSection data={data} errors={errors} set={set} />
</div>
<div className={styles.group}>
<AppealSection data={data} errors={errors} set={set} />
</div>
{/* Спрашиваем в самом конце и только у именных обращений: у анонимного
ответа всё равно не будет, вопрос был бы бессмысленным. */}
{!data.isAnonymous ? (
<FormGrid>
<Field label={TEXTS.labels.wantsFeedback} full>
<Toggle
checked={data.wantsFeedback}
onChange={(v) => set('wantsFeedback', v)}
onLabel="Да"
/>
</Field>
</FormGrid>
) : null}
<FormActions>
<Button variant="ghost" type="button" onClick={reset}>
{TEXTS.actions.reset}
</Button>
<Button
variant="accent"
type="button"
onClick={submit}
disabled={status === 'submitting'}
>
{TEXTS.actions.submit}
</Button>
</FormActions>
</FormCard>
);
};