feat: add loader for saving route and description for stations

This commit is contained in:
2025-11-26 21:45:59 +03:00
parent 11133b6839
commit d6772b1e3a
3 changed files with 111 additions and 9 deletions

View File

@@ -1,4 +1,12 @@
import { Button, Stack, TextField, Typography, Slider } from "@mui/material"; import {
Button,
Stack,
TextField,
Typography,
Slider,
CircularProgress,
Box,
} from "@mui/material";
import { useMapData } from "./MapDataContext"; import { useMapData } from "./MapDataContext";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useTransform } from "./TransformContext"; import { useTransform } from "./TransformContext";
@@ -28,6 +36,7 @@ export function RightSidebar() {
const [isUserEditing, setIsUserEditing] = useState<boolean>(false); const [isUserEditing, setIsUserEditing] = useState<boolean>(false);
const [iconSize, setIconSize] = useState<number>(100); const [iconSize, setIconSize] = useState<number>(100);
const [fontSize, setFontSize] = useState<number>(100); const [fontSize, setFontSize] = useState<number>(100);
const [isSaving, setIsSaving] = useState<boolean>(false);
useEffect(() => { useEffect(() => {
if (originalRouteData) { if (originalRouteData) {
@@ -150,11 +159,19 @@ export function RightSidebar() {
newMinScale = 10; newMinScale = 10;
} }
if (newMinScale > 300) {
newMinScale = 297;
}
setMinScale(newMinScale); setMinScale(newMinScale);
if (maxScale - newMinScale < 2) { if (maxScale - newMinScale < 2) {
let newMaxScale = newMinScale + 2; let newMaxScale = newMinScale + 2;
if (newMaxScale > 300) {
newMaxScale = 300;
}
if (newMaxScale < 3) { if (newMaxScale < 3) {
newMaxScale = 3; newMaxScale = 3;
setMinScale(1); setMinScale(1);
@@ -443,18 +460,35 @@ export function RightSidebar() {
<Button <Button
variant="contained" variant="contained"
color="secondary" color="secondary"
sx={{ mt: 2 }} sx={{ mt: 2, position: "relative" }}
disabled={isSaving}
onClick={async () => { onClick={async () => {
setIsSaving(true);
try { try {
await saveChanges(); await saveChanges();
toast.success("Изменения сохранены"); toast.success("Изменения сохранены");
} catch (error) { } catch (error) {
console.error(error); console.error(error);
toast.error("Ошибка при сохранении изменений"); toast.error("Ошибка при сохранении изменений");
} finally {
setIsSaving(false);
} }
}} }}
> >
Сохранить изменения {isSaving ? (
<Box
sx={{
display: "flex",
alignItems: "center",
gap: 1,
}}
>
<CircularProgress size={20} sx={{ color: "inherit" }} />
<span>Сохранение...</span>
</Box>
) : (
"Сохранить изменения"
)}
</Button> </Button>
<svg <svg

View File

@@ -1382,13 +1382,78 @@ export const WebGLRouteMapPrototype = observer(() => {
skipNextAutoFitRef.current = false; skipNextAutoFitRef.current = false;
return; return;
} }
resetTransform();
const currentTransform = transformRef.current ?? lastTransformRef.current;
if (!currentTransform) {
resetTransform();
return;
}
const canvas = canvasRef.current;
if (!canvas || canvas.width === 0 || canvas.height === 0) {
resetTransform();
return;
}
const preservedScale = currentTransform.scale;
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const worldCenterX =
(centerX - currentTransform.translation.x) / preservedScale;
const worldCenterY =
(centerY - currentTransform.translation.y) / preservedScale;
const centerLat =
routeData?.center_latitude ?? originalRouteData?.center_latitude;
const centerLon =
routeData?.center_longitude ?? originalRouteData?.center_longitude;
if (Number.isFinite(centerLat) && Number.isFinite(centerLon)) {
const local = coordinatesToLocal(
centerLat as number,
centerLon as number
);
const baseX = local.x * UP_SCALE;
const baseY = local.y * UP_SCALE;
const cos = Math.cos(rotationAngle);
const sin = Math.sin(rotationAngle);
const rotatedX = baseX * cos - baseY * sin;
const rotatedY = baseX * sin + baseY * cos;
const updatedTransform: Transform = {
scale: preservedScale,
translation: {
x: centerX - rotatedX * preservedScale,
y: centerY - rotatedY * preservedScale,
},
};
transformRef.current = updatedTransform;
lastTransformRef.current = updatedTransform;
setTransformState(updatedTransform);
drawSceneRef.current();
} else {
const updatedTransform: Transform = {
scale: preservedScale,
translation: {
x: centerX - worldCenterX * preservedScale,
y: centerY - worldCenterY * preservedScale,
},
};
transformRef.current = updatedTransform;
lastTransformRef.current = updatedTransform;
setTransformState(updatedTransform);
drawSceneRef.current();
}
}, [ }, [
routeVertices,
stationVertices,
canvasSize.width,
canvasSize.height,
rotationAngle, rotationAngle,
routeData?.center_latitude,
routeData?.center_longitude,
originalRouteData?.center_latitude,
originalRouteData?.center_longitude,
resetTransform, resetTransform,
]); ]);

View File

@@ -275,7 +275,10 @@ export const InformationTab = observer(
{sight.common.id !== 0 && ( {sight.common.id !== 0 && (
<LinkedStations <LinkedStations
parentId={sight.common.id} parentId={sight.common.id}
fields={[{ label: "Название", data: "name" }]} fields={[
{ label: "Название", data: "name" },
{ label: "Описание", data: "description" },
]}
type="edit" type="edit"
/> />
)} )}