Files
ForbiddenStarsApp/frontend/src/App.tsx
T
NotBigGhostandClaude Opus 5 8d4f7a95df Время: один пояс приложения из .env и на сервере, и на фронте
APP_TZ_OFFSET_HOURS влиял только на «дату игры», а фронт показывал время в
захардкоженных +3 — при другом значении дата и время партии противоречили друг
другу. Теперь /api/auth/config отдаёт tz_offset_hours, App.tsx выставляет его в
format.ts до первой отрисовки страниц, и в нём же показывается всё время и
вводятся даты объявлений (запасное значение +3, если конфиг недоступен). Пояс
устройства не учитывается — решение владельца. Валидатор ограничивает смещение
−12..14. #68

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqSoRj99iwVEH5U5fnZgsd
2026-09-19 03:05:30 +03:00

35 lines
1.3 KiB
TypeScript

import { QueryClientProvider } from "@tanstack/react-query";
import type { ReactNode } from "react";
import { RouterProvider } from "react-router-dom";
import { queryClient } from "./app/queryClient";
import { router } from "./app/router";
import { Spinner } from "./components/Spinner";
import { ToastProvider } from "./context/ToastContext";
import { setAppTzOffsetHours } from "./domain/format";
import { useAuthConfig } from "./hooks/auth";
/**
* Пояс приложения (APP_TZ_OFFSET_HOURS) приходит с сервера и нужен до первой отрисовки:
* функции format.ts читают его синхронно (#68). Пока конфиг грузится — спиннер; если он
* недоступен (нет сети), рендерим с запасным поясом, чтобы не запереть приложение.
*/
function AppTimeZone({ children }: { children: ReactNode }) {
const { data, isPending } = useAuthConfig();
if (data) setAppTzOffsetHours(data.tz_offset_hours);
if (isPending) return <Spinner />;
return <>{children}</>;
}
export function App() {
return (
<QueryClientProvider client={queryClient}>
<ToastProvider>
<AppTimeZone>
<RouterProvider router={router} />
</AppTimeZone>
</ToastProvider>
</QueryClientProvider>
);
}