This commit is contained in:
2026-03-23 01:21:44 +03:00
parent b6a9cecba6
commit 442160ba38
16 changed files with 973 additions and 174 deletions

View File

@@ -5,7 +5,13 @@ import { editSightStore } from "@shared";
import { toast } from "react-toastify";
interface ImageUploadCardProps {
title: string;
imageKey?: "thumbnail" | "watermark_lu" | "watermark_rd" | "image";
imageKey?:
| "thumbnail"
| "icon"
| "alt_icon"
| "watermark_lu"
| "watermark_rd"
| "image";
imageUrl: string | null | undefined;
onImageClick: () => void;
onDeleteImageClick: () => void;

View File

@@ -9,6 +9,8 @@ import {
DialogTitle,
DialogContent,
DialogActions,
Checkbox,
FormControlLabel,
} from "@mui/material";
import {
BackButton,
@@ -54,12 +56,24 @@ export const CreateInformationTab = observer(
const [menuAnchorEl, setMenuAnchorEl] = useState<null | HTMLElement>(null);
const [activeMenuType, setActiveMenuType] = useState<
"thumbnail" | "watermark_lu" | "watermark_rd" | "video_preview" | null
| "thumbnail"
| "icon"
| "alt_icon"
| "watermark_lu"
| "watermark_rd"
| "video_preview"
| null
>(null);
const [isAddMediaOpen, setIsAddMediaOpen] = useState(false);
const [isVideoPreviewOpen, setIsVideoPreviewOpen] = useState(false);
const [hardcodeType, setHardcodeType] = useState<
"thumbnail" | "watermark_lu" | "watermark_rd" | "video_preview" | null
| "thumbnail"
| "icon"
| "alt_icon"
| "watermark_lu"
| "watermark_rd"
| "video_preview"
| null
>(null);
// НОВОЕ СОСТОЯНИЕ ДЛЯ ПРЕДУПРЕЖДАЮЩЕГО ОКНА
@@ -129,7 +143,13 @@ export const CreateInformationTab = observer(
media_name?: string;
media_type: number;
},
type: "thumbnail" | "watermark_lu" | "watermark_rd" | "video_preview"
type:
| "thumbnail"
| "icon"
| "alt_icon"
| "watermark_lu"
| "watermark_rd"
| "video_preview"
) => {
handleChange({
[type]: media.id,
@@ -284,6 +304,20 @@ export const CreateInformationTab = observer(
variant="outlined"
placeholder="Введите координаты в формате: широта долгота"
/>
<FormControlLabel
control={
<Checkbox
checked={!!sight.is_default_icon}
onChange={(e) =>
handleChange({
is_default_icon: e.target.checked,
})
}
/>
}
label="Использовать иконку по умолчанию"
/>
</Box>
<Box
@@ -295,11 +329,14 @@ export const CreateInformationTab = observer(
>
<Box
sx={{
display: "flex",
justifyContent: "space-around",
display: "grid",
width: "80%",
gap: 2,
flexDirection: { xs: "column", sm: "row" },
gridTemplateColumns: {
xs: "1fr",
sm: "repeat(2, minmax(0, 1fr))",
md: "repeat(4, minmax(0, 1fr))",
},
}}
>
<ImageUploadCard
@@ -330,6 +367,66 @@ export const CreateInformationTab = observer(
}}
/>
{!sight.is_default_icon && (
<>
<ImageUploadCard
title="Иконка (на карте)"
imageKey="icon"
imageUrl={isMediaIdEmpty(sight.icon) ? null : sight.icon}
onImageClick={() => {
setIsPreviewMediaOpen(true);
setMediaId(sight.icon ?? "");
}}
onDeleteImageClick={() => {
handleChange({
icon: null,
});
setActiveMenuType(null);
}}
onSelectFileClick={() => {
setActiveMenuType("icon");
setIsAddMediaOpen(true);
}}
setUploadMediaOpen={() => {
setIsUploadMediaOpen(true);
setActiveMenuType("icon");
setHardcodeType("icon");
}}
setHardcodeType={() => {
setHardcodeType("icon");
}}
/>
<ImageUploadCard
title="Иконка (при выборе)"
imageKey="alt_icon"
imageUrl={isMediaIdEmpty(sight.alt_icon) ? null : sight.alt_icon}
onImageClick={() => {
setIsPreviewMediaOpen(true);
setMediaId(sight.alt_icon ?? "");
}}
onDeleteImageClick={() => {
handleChange({
alt_icon: null,
});
setActiveMenuType(null);
}}
onSelectFileClick={() => {
setActiveMenuType("alt_icon");
setIsAddMediaOpen(true);
}}
setUploadMediaOpen={() => {
setIsUploadMediaOpen(true);
setActiveMenuType("alt_icon");
setHardcodeType("alt_icon");
}}
setHardcodeType={() => {
setHardcodeType("alt_icon");
}}
/>
</>
)}
<ImageUploadCard
title="Водяной знак (левый верхний)"
imageKey="watermark_lu"

View File

@@ -9,6 +9,8 @@ import {
DialogTitle,
DialogContent,
DialogActions,
Checkbox,
FormControlLabel,
} from "@mui/material";
import {
BackButton,
@@ -56,12 +58,24 @@ export const InformationTab = observer(
const [menuAnchorEl, setMenuAnchorEl] = useState<null | HTMLElement>(null);
const [activeMenuType, setActiveMenuType] = useState<
"thumbnail" | "watermark_lu" | "watermark_rd" | "video_preview" | null
| "thumbnail"
| "icon"
| "alt_icon"
| "watermark_lu"
| "watermark_rd"
| "video_preview"
| null
>(null);
const [isAddMediaOpen, setIsAddMediaOpen] = useState(false);
const [isVideoPreviewOpen, setIsVideoPreviewOpen] = useState(false);
const [hardcodeType, setHardcodeType] = useState<
"thumbnail" | "watermark_lu" | "watermark_rd" | "video_preview" | null
| "thumbnail"
| "icon"
| "alt_icon"
| "watermark_lu"
| "watermark_rd"
| "video_preview"
| null
>(null);
const canReadCities = authStore.canRead("cities");
@@ -121,7 +135,13 @@ export const InformationTab = observer(
media_name?: string;
media_type: number;
},
type: "thumbnail" | "watermark_lu" | "watermark_rd" | "video_preview"
type:
| "thumbnail"
| "icon"
| "alt_icon"
| "watermark_lu"
| "watermark_rd"
| "video_preview"
) => {
handleChange(
language as Language,
@@ -295,6 +315,24 @@ export const InformationTab = observer(
variant="outlined"
placeholder="Введите координаты в формате: широта долгота (можно использовать запятые или пробелы)"
/>
<FormControlLabel
control={
<Checkbox
checked={!!sight.common.is_default_icon}
onChange={(e) =>
handleChange(
language as Language,
{
is_default_icon: e.target.checked,
},
true
)
}
/>
}
label="Использовать иконку по умолчанию"
/>
</Box>
<Box sx={{ width: "80%" }}>
@@ -319,11 +357,14 @@ export const InformationTab = observer(
>
<Box
sx={{
display: "flex",
justifyContent: "space-around",
display: "grid",
width: "80%",
gap: 2,
flexDirection: { xs: "column", sm: "row" },
gridTemplateColumns: {
xs: "1fr",
sm: "repeat(2, minmax(0, 1fr))",
md: "repeat(4, minmax(0, 1fr))",
},
}}
>
<ImageUploadCard
@@ -357,6 +398,72 @@ export const InformationTab = observer(
setHardcodeType("thumbnail");
}}
/>
{!sight.common.is_default_icon && (
<>
<ImageUploadCard
title="Иконка (на карте)"
imageKey="icon"
imageUrl={isMediaIdEmpty(sight.common.icon) ? null : sight.common.icon}
onImageClick={() => {
setIsPreviewMediaOpen(true);
setMediaId(sight.common.icon ?? "");
}}
onDeleteImageClick={() => {
handleChange(
language as Language,
{
icon: null,
},
true
);
setActiveMenuType(null);
}}
onSelectFileClick={() => {
setActiveMenuType("icon");
setIsAddMediaOpen(true);
}}
setUploadMediaOpen={() => {
setIsUploadMediaOpen(true);
setActiveMenuType("icon");
setHardcodeType("icon");
}}
setHardcodeType={() => {
setHardcodeType("icon");
}}
/>
<ImageUploadCard
title="Иконка (при выборе)"
imageKey="alt_icon"
imageUrl={isMediaIdEmpty(sight.common.alt_icon) ? null : sight.common.alt_icon}
onImageClick={() => {
setIsPreviewMediaOpen(true);
setMediaId(sight.common.alt_icon ?? "");
}}
onDeleteImageClick={() => {
handleChange(
language as Language,
{
alt_icon: null,
},
true
);
setActiveMenuType(null);
}}
onSelectFileClick={() => {
setActiveMenuType("alt_icon");
setIsAddMediaOpen(true);
}}
setUploadMediaOpen={() => {
setIsUploadMediaOpen(true);
setActiveMenuType("alt_icon");
setHardcodeType("alt_icon");
}}
setHardcodeType={() => {
setHardcodeType("alt_icon");
}}
/>
</>
)}
<ImageUploadCard
title="Водяной знак (левый верхний)"
imageKey="watermark_lu"

View File

@@ -34,7 +34,7 @@ export const VideoPreviewCard: React.FC<VideoPreviewCardProps> = ({
};
const handleFileInputChange = async (
event: React.ChangeEvent<HTMLInputElement>
event: React.ChangeEvent<HTMLInputElement>,
) => {
const file = event.target.files?.[0];
if (file) {
@@ -87,7 +87,7 @@ export const VideoPreviewCard: React.FC<VideoPreviewCardProps> = ({
gap: 1,
flex: 1,
minWidth: 150,
width: "min-content",
width: "100%",
mx: "auto",
}}
className={className}