feat: Sight Page update

This commit is contained in:
2025-06-01 23:18:21 +03:00
parent 87386c6a73
commit a8777a974a
26 changed files with 3460 additions and 727 deletions

View File

@ -27,6 +27,8 @@ import { Info, ImagePlus } from "lucide-react";
import { observer } from "mobx-react-lite";
import { useEffect, useState } from "react";
import { toast } from "react-toastify";
// Мокап для всплывающей подсказки
export const InformationTab = observer(
@ -37,12 +39,10 @@ export const InformationTab = observer(
const [isPreviewMediaOpen, setIsPreviewMediaOpen] = useState(false);
const { language } = languageStore;
const { sight, updateSightInfo } = editSightStore;
const data = sight[language];
const common = sight.common;
const { sight, updateSightInfo, updateSight } = editSightStore;
const [, setCity] = useState<number>(common.city_id ?? 0);
const [, setCity] = useState<number>(sight.common.city_id ?? 0);
const [coordinates, setCoordinates] = useState<string>(`0 0`);
const token = localStorage.getItem("token");
@ -54,21 +54,13 @@ export const InformationTab = observer(
>(null);
const [isAddMediaOpen, setIsAddMediaOpen] = useState(false);
const handleMenuOpen = (
event: React.MouseEvent<HTMLElement>,
type: "thumbnail" | "watermark_lu" | "watermark_rd"
) => {
setMenuAnchorEl(event.currentTarget);
setActiveMenuType(type);
};
useEffect(() => {
// Показывать только при инициализации (не менять при ошибках пользователя)
if (common.latitude !== 0 || common.longitude !== 0) {
setCoordinates(`${common.latitude} ${common.longitude}`);
if (sight.common.latitude !== 0 || sight.common.longitude !== 0) {
setCoordinates(`${sight.common.latitude} ${sight.common.longitude}`);
}
// если координаты обнулились — оставить поле как есть
}, [common.latitude, common.longitude]);
}, [sight.common.latitude, sight.common.longitude]);
const handleMenuClose = () => {
setMenuAnchorEl(null);
@ -135,7 +127,7 @@ export const InformationTab = observer(
>
<TextField
label={`Название (${language.toUpperCase()})`}
value={data.name}
value={sight[language].name}
onChange={(e) => {
handleChange(language as Language, {
name: e.target.value,
@ -147,7 +139,7 @@ export const InformationTab = observer(
<TextField
label="Адрес"
value={data.address}
value={sight[language].address}
onChange={(e) => {
handleChange(language as Language, {
address: e.target.value,
@ -160,18 +152,15 @@ export const InformationTab = observer(
<Autocomplete
options={cities ?? []}
value={
cities.find((city) => city.id === common.city_id) ?? null
cities.find((city) => city.id === sight.common.city_id) ??
null
}
getOptionLabel={(option) => option.name}
onChange={(_, value) => {
setCity(value?.id ?? 0);
handleChange(
language as Language,
{
city_id: value?.id ?? 0,
},
true
);
handleChange(language as Language, {
city_id: value?.id ?? 0,
});
}}
renderInput={(params) => (
<TextField {...params} label="Город" />
@ -195,15 +184,23 @@ export const InformationTab = observer(
const isValidLon = !isNaN(lon);
if (isValidLat && isValidLon) {
handleChange(language as Language, {
latitude: lat,
longitude: lon,
});
handleChange(
language as Language,
{
latitude: lat,
longitude: lon,
},
true
);
} else {
handleChange(language as Language, {
latitude: 0,
longitude: 0,
});
handleChange(
language as Language,
{
latitude: 0,
longitude: 0,
},
true
);
}
}}
fullWidth
@ -251,17 +248,18 @@ export const InformationTab = observer(
</Box>
<Box
sx={{
width: 80,
height: 80,
position: "relative",
width: "200px",
height: "200px",
backgroundColor: "grey.200",
display: "flex",
alignItems: "center",
justifyContent: "center",
borderRadius: 1,
mb: 1,
cursor: common.thumbnail ? "pointer" : "default",
cursor: sight.common.thumbnail ? "pointer" : "default",
"&:hover": {
backgroundColor: common.thumbnail
backgroundColor: sight.common.thumbnail
? "red.300"
: "grey.200",
},
@ -270,29 +268,22 @@ export const InformationTab = observer(
setIsMediaModalOpen(true);
}}
>
{common.thumbnail ? (
{sight.common.thumbnail ? (
<img
src={`${import.meta.env.VITE_KRBL_MEDIA}${
common.thumbnail
sight.common.thumbnail
}/download?token=${token}`}
alt="Логотип"
style={{ maxWidth: "100%", maxHeight: "100%" }}
onClick={() => {
setIsPreviewMediaOpen(true);
setMediaId(common.thumbnail);
setMediaId(sight.common.thumbnail ?? "");
}}
/>
) : (
<ImagePlus size={24} color="grey" />
)}
</Box>
<Button
variant="outlined"
size="small"
onClick={(e) => handleMenuOpen(e, "thumbnail")}
>
Выбрать
</Button>
</Paper>
<Paper
elevation={2}
@ -324,49 +315,45 @@ export const InformationTab = observer(
</Box>
<Box
sx={{
width: 80,
height: 80,
position: "relative",
width: "200px",
height: "200px",
backgroundColor: "grey.200",
display: "flex",
alignItems: "center",
justifyContent: "center",
borderRadius: 1,
mb: 1,
cursor: common.watermark_lu ? "pointer" : "default",
cursor: sight.common.watermark_lu
? "pointer"
: "default",
"&:hover": {
backgroundColor: common.watermark_lu
backgroundColor: sight.common.watermark_lu
? "grey.300"
: "grey.200",
},
}}
onClick={() => {
setIsPreviewMediaOpen(true);
setMediaId(common.watermark_lu);
setMediaId(sight.common.watermark_lu ?? "");
}}
>
{common.watermark_lu ? (
{sight.common.watermark_lu ? (
<img
src={`${import.meta.env.VITE_KRBL_MEDIA}${
common.watermark_lu
sight.common.watermark_lu
}/download?token=${token}`}
alt="Знак л.в"
style={{ maxWidth: "100%", maxHeight: "100%" }}
onClick={() => {
setIsMediaModalOpen(true);
setMediaId(common.watermark_lu);
setMediaId(sight.common.watermark_lu ?? "");
}}
/>
) : (
<ImagePlus size={24} color="grey" />
)}
</Box>
<Button
variant="outlined"
size="small"
onClick={(e) => handleMenuOpen(e, "watermark_lu")}
>
Выбрать
</Button>
</Paper>
<Paper
@ -399,49 +386,45 @@ export const InformationTab = observer(
</Box>
<Box
sx={{
width: 80,
height: 80,
position: "relative",
width: "200px",
height: "200px",
backgroundColor: "grey.200",
display: "flex",
alignItems: "center",
justifyContent: "center",
borderRadius: 1,
mb: 1,
cursor: common.watermark_rd ? "pointer" : "default",
cursor: sight.common.watermark_rd
? "pointer"
: "default",
"&:hover": {
backgroundColor: common.watermark_rd
backgroundColor: sight.common.watermark_rd
? "grey.300"
: "grey.200",
},
}}
onClick={() => {
setIsMediaModalOpen(true);
setMediaId(common.watermark_rd);
setMediaId(sight.common.watermark_rd ?? "");
}}
>
{common.watermark_rd ? (
{sight.common.watermark_rd ? (
<img
src={`${import.meta.env.VITE_KRBL_MEDIA}${
common.watermark_rd
sight.common.watermark_rd
}/download?token=${token}`}
alt="Знак п.в"
style={{ maxWidth: "100%", maxHeight: "100%" }}
onClick={() => {
setIsPreviewMediaOpen(true);
setMediaId(common.watermark_rd);
setMediaId(sight.common.watermark_rd ?? "");
}}
/>
) : (
<ImagePlus size={24} color="grey" />
)}
</Box>
<Button
variant="outlined"
size="small"
onClick={(e) => handleMenuOpen(e, "watermark_rd")}
>
Выбрать
</Button>
</Paper>
</Box>
</Box>
@ -467,8 +450,9 @@ export const InformationTab = observer(
<Button
variant="contained"
color="success"
onClick={() => {
console.log(sight);
onClick={async () => {
await updateSight();
toast.success("Достопримечательность сохранена");
}}
>
Сохранить