Объявления: окно у игрока и редактор в админке

Окно — вариант E из макетов: заголовок в плашке-шапке, текст, точки очереди
и «Понятно», крестика нет. Очередь идёт от старого к новому; закрытое сразу
уходит из кэша, следующее открывается без ожидания сети. У повторно
показанного объявления под заголовком — красная пометка «обновлено».
AppShell показывает окно на любой странице и только когда пароль задан:
обязательное окно пароля всегда первое. Новые и изменённые объявления
приходят SSE-событием announcements, отложенное начало показа — перезапросом
раз в 5 минут.

Админка — вкладка «Объявления» с редактором R1: contenteditable и панель
(жирный, курсив, золотой и красный акцент, эмодзи, снятие оформления),
вставка и перетаскивание только простым текстом, счётчик символов, период
показа по МСК, переключатели «показывать новым игрокам» и «показать заново».
Предпросмотр — тем же окном, что у игрока. Список со статусом, счётчиком
«закрыли N из M» и действиями: изменить, снять с показа, дублировать,
удалить. Выделение текста в форме — полупрозрачный оранжевый вместо синего.

schema.d.ts пересобран из OpenAPI. #84

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-18 21:26:38 +03:00
co-authored by Claude Opus 5
parent a0a0e522ef
commit ab1fc3f00f
16 changed files with 1220 additions and 3 deletions
+2
View File
@@ -14,6 +14,7 @@ import { OverallStatsPage } from "../pages/OverallStatsPage";
import { PublicProfilePage } from "../pages/PublicProfilePage";
import { AdminAccountsPage } from "../pages/admin/AdminAccountsPage";
import { AdminAchievementsPage } from "../pages/admin/AdminAchievementsPage";
import { AdminAnnouncementsPage } from "../pages/admin/AdminAnnouncementsPage";
import { AdminFactionsPage } from "../pages/admin/AdminFactionsPage";
import { AdminLayout } from "../pages/admin/AdminLayout";
import { AdminLogsPage } from "../pages/admin/AdminLogsPage";
@@ -70,6 +71,7 @@ export const router = createBrowserRouter([
{ path: "factions", element: <AdminFactionsPage /> },
{ path: "achievements", element: <AdminAchievementsPage /> },
{ path: "logs", element: <AdminLogsPage /> },
{ path: "announcements", element: <AdminAnnouncementsPage /> },
],
},
{ path: "*", element: <Navigate to="/" replace /> },