216 lines
5.9 KiB
TypeScript
216 lines
5.9 KiB
TypeScript
import { Button } from "@mui/material";
|
||
import { useNavigate, useNavigationType } from "react-router";
|
||
import { MediaViewer } from "@widgets";
|
||
import { useMapData } from "./MapDataContext";
|
||
import { observer } from "mobx-react-lite";
|
||
import { useEffect, useState } from "react";
|
||
import { authInstance, isMediaIdEmpty } from "@shared";
|
||
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||
import LanguageSelector from "./web-gl/LanguageSelector";
|
||
|
||
type LeftSidebarProps = {
|
||
open: boolean;
|
||
onToggle: () => void;
|
||
};
|
||
|
||
export const LeftSidebar = observer(({ open, onToggle }: LeftSidebarProps) => {
|
||
const navigate = useNavigate();
|
||
const navigationType = useNavigationType();
|
||
const { routeData } = useMapData();
|
||
const [carrierLogo, setCarrierLogo] = useState<string | null>(null);
|
||
const [carrierSlogan, setCarrierSlogan] = useState<string | null>(null);
|
||
const [carrierShortName, setCarrierShortName] = useState<string | null>(null);
|
||
|
||
useEffect(() => {
|
||
async function fetchCarrierData() {
|
||
if (routeData?.carrier_id) {
|
||
const carrier = (
|
||
await authInstance.get(`/carrier/${routeData.carrier_id}`)
|
||
).data;
|
||
setCarrierLogo(carrier.logo);
|
||
setCarrierSlogan(carrier.slogan ?? null);
|
||
setCarrierShortName(carrier.short_name ?? null);
|
||
}
|
||
}
|
||
fetchCarrierData();
|
||
}, [routeData?.carrier_id]);
|
||
|
||
const handleBack = () => {
|
||
if (navigationType === "PUSH") {
|
||
navigate(-1);
|
||
} else {
|
||
navigate("/route");
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div
|
||
style={{
|
||
position: "relative",
|
||
width: 288,
|
||
height: "100%",
|
||
color: "#fff",
|
||
}}
|
||
>
|
||
{/* Кнопка назад — вне основного меню */}
|
||
<div style={{ padding: "12px 12px 0" }}>
|
||
<Button
|
||
onClick={handleBack}
|
||
variant="contained"
|
||
sx={{
|
||
backgroundColor: "#222",
|
||
color: "#fff",
|
||
borderRadius: 1.5,
|
||
px: 2,
|
||
py: 1,
|
||
"&:hover": { backgroundColor: "#2d2d2d" },
|
||
}}
|
||
fullWidth
|
||
startIcon={<ArrowBackIcon />}
|
||
>
|
||
Назад
|
||
</Button>
|
||
</div>
|
||
|
||
{/* Основное меню — повторяет .side-menu */}
|
||
<div
|
||
style={{
|
||
boxSizing: "border-box",
|
||
paddingTop: 46,
|
||
display: "flex",
|
||
flexDirection: "column",
|
||
alignItems: "center",
|
||
height: "calc(100% - 56px)",
|
||
position: "relative",
|
||
opacity: open ? 1 : 0,
|
||
transition: "opacity 0.25s ease",
|
||
pointerEvents: open ? "auto" : "none",
|
||
}}
|
||
>
|
||
{/* Герб — .side-menu-crest */}
|
||
<div
|
||
style={{
|
||
width: 170,
|
||
height: 170,
|
||
alignSelf: "flex-start",
|
||
marginLeft: 20,
|
||
backgroundColor: "rgba(255,255,255,0.15)",
|
||
borderRadius: 8,
|
||
display: "flex",
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
color: "rgba(255,255,255,0.5)",
|
||
fontSize: 14,
|
||
fontWeight: 500,
|
||
}}
|
||
>
|
||
Герб
|
||
</div>
|
||
|
||
{/* Слоган — .side-menu-label */}
|
||
{carrierSlogan && (
|
||
<div
|
||
style={{
|
||
marginTop: 10,
|
||
textAlign: "left",
|
||
fontSize: 15,
|
||
padding: "0 20px",
|
||
alignSelf: "flex-start",
|
||
fontWeight: 400,
|
||
lineHeight: "150%",
|
||
}}
|
||
>
|
||
{carrierSlogan}
|
||
</div>
|
||
)}
|
||
|
||
{/* Кнопки — .side-menu-buttons */}
|
||
<div style={{ width: 220, marginTop: 260 }}>
|
||
<div
|
||
style={{
|
||
backgroundColor: "#fff",
|
||
color: "#000",
|
||
textAlign: "center",
|
||
padding: "8px 16px",
|
||
marginBottom: 16,
|
||
borderRadius: 10,
|
||
}}
|
||
>
|
||
Достопримечательности
|
||
</div>
|
||
<div
|
||
style={{
|
||
backgroundColor: "#fff",
|
||
color: "#000",
|
||
textAlign: "center",
|
||
padding: "8px 16px",
|
||
marginBottom: 16,
|
||
borderRadius: 10,
|
||
}}
|
||
>
|
||
Остановки
|
||
</div>
|
||
</div>
|
||
|
||
{/* Нижняя секция — .side-menu-bottom-section */}
|
||
<div
|
||
style={{
|
||
position: "absolute",
|
||
bottom: 0,
|
||
left: 0,
|
||
width: "100%",
|
||
display: "flex",
|
||
flexDirection: "column",
|
||
}}
|
||
>
|
||
{/* .side-menu-carrier-block */}
|
||
<div style={{ padding: "0 20px" }}>
|
||
{carrierLogo && !isMediaIdEmpty(carrierLogo) && (
|
||
<div style={{ width: 170 }}>
|
||
<MediaViewer
|
||
media={{
|
||
id: carrierLogo,
|
||
media_type: 1,
|
||
filename: "carrier_logo",
|
||
}}
|
||
fullWidth
|
||
/>
|
||
</div>
|
||
)}
|
||
{carrierShortName && (
|
||
<div
|
||
style={{
|
||
marginTop: 4,
|
||
textAlign: "left",
|
||
fontSize: 16,
|
||
fontWeight: 700,
|
||
lineHeight: "150%",
|
||
color: "#fff",
|
||
}}
|
||
>
|
||
{carrierShortName}
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* .side-menu-bottom-photo */}
|
||
<img
|
||
src="/side-menu-photo.png"
|
||
alt=""
|
||
style={{
|
||
width: "288px",
|
||
marginTop: 32,
|
||
display: "block",
|
||
pointerEvents: "none",
|
||
}}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="absolute bottom-[20px] -right-[520px] z-10">
|
||
<LanguageSelector onBack={onToggle} isSidebarOpen={open} />
|
||
</div>
|
||
</div>
|
||
);
|
||
});
|