feat: testing mode banner + snapshot storage fields fix

This commit is contained in:
2026-04-17 15:31:14 +03:00
parent d380b2570f
commit a3a4d2eb18
17 changed files with 228 additions and 29 deletions

View File

@@ -33,6 +33,7 @@ interface SightFramePreviewProps {
previewMedia: PreviewMediaData | null;
articles: Article[];
onArticleSelect: (index: number) => void;
previewFontSize?: number;
}
// Matches SightFrame.jsx renderCurrentMedia — same structure, same CSS classes
@@ -151,6 +152,7 @@ export function SightFramePreview({
previewMedia,
articles,
onArticleSelect,
previewFontSize,
}: SightFramePreviewProps) {
const token = localStorage.getItem("token") ?? "";
@@ -235,7 +237,12 @@ export function SightFramePreview({
{/* title: intro-title (300px, 40px centered) or regular (24px with border) */}
<div
className={`sfp-sight-frame-title${isIntro ? " sfp-intro-title" : ""}`}
style={{ lineHeight: isIntro ? undefined : titleLineHeight }}
style={{
lineHeight: isIntro ? undefined : titleLineHeight,
...(isIntro && previewFontSize != null
? { fontSize: `${previewFontSize}px` }
: {}),
}}
>
<p
style={{

View File

@@ -5,6 +5,8 @@ import {
Menu,
MenuItem,
TextField,
Slider,
Stack,
} from "@mui/material";
import {
authInstance,
@@ -45,6 +47,7 @@ export const RightWidgetTab = observer(
updateRightArticleInfo,
getRightArticles,
updateSight,
updateSightInfo,
unlinkPreviewMedia,
linkPreviewMedia,
unlinkRightArticle,
@@ -454,7 +457,40 @@ export const RightWidgetTab = observer(
</Box>
</Box>
<Box sx={{ flexShrink: 0, width: "550px" }}>
<Box sx={{ flexShrink: 0, width: "550px", display: "flex", flexDirection: "column", gap: 1 }}>
<Stack direction="row" spacing={2} alignItems="center">
<TextField
type="number"
label="Размер шрифта превью (px)"
size="small"
value={sight.common.preview_font_size ?? ""}
onChange={(e) => {
const raw = e.target.value;
if (raw === "") {
updateSightInfo(language, { preview_font_size: undefined }, true);
return;
}
const val = Math.max(1, Math.min(300, Math.round(Number(raw))));
if (Number.isFinite(val)) {
updateSightInfo(language, { preview_font_size: val }, true);
}
}}
slotProps={{ input: { min: 1, max: 300 } }}
sx={{ width: "200px" }}
/>
<Slider
value={sight.common.preview_font_size ?? 40}
min={1}
max={300}
step={1}
onChange={(_, newValue) => {
if (typeof newValue === "number") {
updateSightInfo(language, { preview_font_size: newValue }, true);
}
}}
sx={{ flexGrow: 1 }}
/>
</Stack>
<SightFramePreview
sightName={sight[language].name}
previewMedia={previewMedia}
@@ -463,6 +499,7 @@ export const RightWidgetTab = observer(
handleSelectArticle(idx);
setType("article");
}}
previewFontSize={sight.common.preview_font_size}
/>
</Box>
</Box>

View File

@@ -0,0 +1,43 @@
import { observer } from "mobx-react-lite";
import { testingModeStore, authStore } from "@shared";
import { useEffect } from "react";
export const TestingModeBanner = observer(() => {
const { isAuthenticated } = authStore;
useEffect(() => {
if (!isAuthenticated) {
testingModeStore.stopPolling();
return;
}
testingModeStore.startPolling();
return () => {
testingModeStore.stopPolling();
};
}, [isAuthenticated]);
if (!testingModeStore.isEnabled) return null;
return (
<div
style={{
position: "fixed",
bottom: 0,
left: 0,
right: 0,
zIndex: 2147483647,
backgroundColor: "#d32f2f",
color: "#fff",
textAlign: "center",
padding: "12px 16px",
fontWeight: 700,
fontSize: "14px",
letterSpacing: "0.05em",
boxShadow: "0 2px 8px rgba(0,0,0,0.4)",
pointerEvents: "none",
}}
>
ПРОВОДИТСЯ ТЕСТИРОВАНИЕ. ПРОСЬБА НЕ ВЗАИМОДЕЙСТВОВАТЬ С АДМИН-ПАНЕЛЬЮ
</div>
);
});

View File

@@ -20,3 +20,4 @@ export * from "./CreateButton";
export * from "./SaveWithoutCityAgree";
export * from "./CitySelector";
export * from "./modals";
export * from "./TestingModeBanner";