@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"version": "0.0.1",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "hr-appeals-web",
|
||||||
|
"runtimeExecutable": "npm",
|
||||||
|
"runtimeArgs": ["run", "dev"],
|
||||||
|
"port": 3000
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -46,7 +46,8 @@ export const TEXTS = {
|
|||||||
required: 'Заполните поле',
|
required: 'Заполните поле',
|
||||||
selectRequired: 'Выберите значение',
|
selectRequired: 'Выберите значение',
|
||||||
tooShort: 'Слишком короткий ответ — опишите подробнее',
|
tooShort: 'Слишком короткий ответ — опишите подробнее',
|
||||||
hasErrors: 'Проверьте выделенные поля — что-то заполнено не полностью.'
|
hasErrors: 'Проверьте выделенные поля — что-то заполнено не полностью.',
|
||||||
|
submitFailed: 'Не удалось отправить обращение. Попробуйте ещё раз позже.'
|
||||||
},
|
},
|
||||||
|
|
||||||
thanks: {
|
thanks: {
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ export interface IFeedbackForm {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Состояние формы обращения: данные, валидация, отправка.
|
* Состояние формы обращения: данные, валидация, отправка.
|
||||||
* Бэкенда пока нет — submit только имитирует отправку (см. TODO ниже),
|
* Отправка идёт через nginx (/api/... -> hr-appeals-auth) — сервис сам
|
||||||
* поэтому вся логика синхронная и живёт здесь, без сервисного слоя.
|
* меняет её на app-only токен и создаёт элемент в списке SharePoint.
|
||||||
*/
|
*/
|
||||||
export function useFeedbackForm(): IFeedbackForm {
|
export function useFeedbackForm(): IFeedbackForm {
|
||||||
const [data, setData] = useState<IFeedbackData>(EMPTY_FEEDBACK);
|
const [data, setData] = useState<IFeedbackData>(EMPTY_FEEDBACK);
|
||||||
@@ -53,11 +53,24 @@ export function useFeedbackForm(): IFeedbackForm {
|
|||||||
setFormError('');
|
setFormError('');
|
||||||
setStatus('submitting');
|
setStatus('submitting');
|
||||||
|
|
||||||
// TODO: заменить на реальную отправку, когда определимся с бэкендом.
|
fetch('/api/feedback', {
|
||||||
// Сейчас это заглушка по договорённости: делаем только UI.
|
method: 'POST',
|
||||||
// eslint-disable-next-line no-console
|
headers: { 'Content-Type': 'application/json' },
|
||||||
console.info('Обращение (заглушка отправки):', data);
|
body: JSON.stringify(data)
|
||||||
|
})
|
||||||
|
.then(async (response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
const body = await response.json().catch(() => null);
|
||||||
|
throw new Error(body?.error ?? `Сервер вернул ${response.status}`);
|
||||||
|
}
|
||||||
setStatus('done');
|
setStatus('done');
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('Не удалось отправить обращение:', error);
|
||||||
|
setFormError(TEXTS.errors.submitFailed);
|
||||||
|
setStatus('idle');
|
||||||
|
});
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
const reset = useCallback((): void => {
|
const reset = useCallback((): void => {
|
||||||
|
|||||||
+10
-1
@@ -12,7 +12,16 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
port: 3000,
|
port: 3000,
|
||||||
open: true
|
open: true,
|
||||||
|
// Как nginx в проде (nginx.conf): /api/... идёт на hr-appeals-auth без
|
||||||
|
// префикса. Локально сервис запускаем на 3100 — порт 3000 занят самим vite.
|
||||||
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: 'http://localhost:3100',
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: (path) => path.replace(/^\/api/, '')
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
test: {
|
test: {
|
||||||
// globals: true — describe/it/expect доступны без импорта, как привычно по Jest.
|
// globals: true — describe/it/expect доступны без импорта, как привычно по Jest.
|
||||||
|
|||||||
Reference in New Issue
Block a user