feat: Route list page
This commit is contained in:
@@ -6,20 +6,94 @@ import {
|
||||
MenuItem,
|
||||
FormControl,
|
||||
InputLabel,
|
||||
Typography,
|
||||
Box,
|
||||
} from "@mui/material";
|
||||
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { ArrowLeft, Loader2, Save } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { toast } from "react-toastify";
|
||||
import { carrierStore } from "../../../shared/store/CarrierStore";
|
||||
import { articlesStore } from "../../../shared/store/ArticlesStore";
|
||||
import { Route, routeStore } from "../../../shared/store/RouteStore";
|
||||
|
||||
export const RouteCreatePage = observer(() => {
|
||||
const navigate = useNavigate();
|
||||
const [carrier, setCarrier] = useState<string>("");
|
||||
const [routeNumber, setRouteNumber] = useState("");
|
||||
const [direction, setDirection] = useState("");
|
||||
const [routeCoords, setRouteCoords] = useState("");
|
||||
const [govRouteNumber, setGovRouteNumber] = useState("");
|
||||
const [governorAppeal, setGovernorAppeal] = useState<string>("");
|
||||
const [direction, setDirection] = useState("backward");
|
||||
const [scaleMin, setScaleMin] = useState("");
|
||||
const [scaleMax, setScaleMax] = useState("");
|
||||
const [turn, setTurn] = useState("");
|
||||
const [centerLat, setCenterLat] = useState("");
|
||||
const [centerLng, setCenterLng] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
carrierStore.getCarriers();
|
||||
articlesStore.getArticleList();
|
||||
}, []);
|
||||
|
||||
const handleCreateRoute = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
// Преобразуем значения в нужные типы
|
||||
const carrier_id = Number(carrier);
|
||||
const governor_appeal = Number(governorAppeal);
|
||||
const scale_min = scaleMin ? Number(scaleMin) : undefined;
|
||||
const scale_max = scaleMax ? Number(scaleMax) : undefined;
|
||||
const rotate = turn ? Number(turn) : undefined;
|
||||
const center_latitude = centerLat ? Number(centerLat) : undefined;
|
||||
const center_longitude = centerLng ? Number(centerLng) : undefined;
|
||||
const route_direction = direction === "forward";
|
||||
// Координаты маршрута как массив массивов чисел
|
||||
const path = routeCoords
|
||||
.split("\n")
|
||||
.map((line) =>
|
||||
line
|
||||
.split(" ")
|
||||
.map((coord) => Number(coord.trim()))
|
||||
.filter((n) => !isNaN(n))
|
||||
)
|
||||
.filter((arr) => arr.length === 2);
|
||||
|
||||
// Собираем объект маршрута
|
||||
const newRoute: Partial<Route> = {
|
||||
carrier:
|
||||
carrierStore.carriers.data.find((c: any) => c.id === carrier_id)
|
||||
?.full_name || "",
|
||||
carrier_id,
|
||||
route_number: routeNumber,
|
||||
route_sys_number: govRouteNumber,
|
||||
governor_appeal,
|
||||
route_direction,
|
||||
scale_min,
|
||||
scale_max,
|
||||
rotate,
|
||||
center_latitude,
|
||||
center_longitude,
|
||||
path,
|
||||
};
|
||||
|
||||
// Отправка на сервер (пример, если есть routeStore.createRoute)
|
||||
let createdRoute: Route | null = null;
|
||||
|
||||
await routeStore.createRoute(newRoute);
|
||||
toast.success("Маршрут успешно создан");
|
||||
navigate(-1);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.error("Произошла ошибка при создании маршрута");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Paper className="w-full h-full p-3 flex flex-col gap-10">
|
||||
<div className="flex justify-between items-center">
|
||||
@@ -28,11 +102,31 @@ export const RouteCreatePage = observer(() => {
|
||||
onClick={() => navigate(-1)}
|
||||
>
|
||||
<ArrowLeft size={20} />
|
||||
Назад
|
||||
Маршруты / Создать
|
||||
</button>
|
||||
</div>
|
||||
<h1 className="text-2xl font-bold">Создание маршрута</h1>
|
||||
<div className="flex flex-col gap-10 w-full items-end">
|
||||
<Typography variant="h5" fontWeight={700}>
|
||||
Создать маршрут
|
||||
</Typography>
|
||||
<Box className="flex flex-col gap-6 w-full">
|
||||
<FormControl fullWidth required>
|
||||
<InputLabel>Выберите перевозчика</InputLabel>
|
||||
<Select
|
||||
value={carrier}
|
||||
label="Выберите перевозчика"
|
||||
onChange={(e) => setCarrier(e.target.value as string)}
|
||||
disabled={carrierStore.carriers.data.length === 0}
|
||||
>
|
||||
<MenuItem value="">Не выбрано</MenuItem>
|
||||
{carrierStore.carriers.data.map(
|
||||
(c: (typeof carrierStore.carriers.data)[number]) => (
|
||||
<MenuItem key={c.id} value={c.id}>
|
||||
{c.full_name}
|
||||
</MenuItem>
|
||||
)
|
||||
)}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<TextField
|
||||
className="w-full"
|
||||
label="Номер маршрута"
|
||||
@@ -40,38 +134,88 @@ export const RouteCreatePage = observer(() => {
|
||||
value={routeNumber}
|
||||
onChange={(e) => setRouteNumber(e.target.value)}
|
||||
/>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel>Направление</InputLabel>
|
||||
<TextField
|
||||
className="w-full"
|
||||
label="Координаты маршрута"
|
||||
multiline
|
||||
minRows={3}
|
||||
value={routeCoords}
|
||||
onChange={(e) => setRouteCoords(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
className="w-full"
|
||||
label="Номер маршрута в Говорящем Городе"
|
||||
required
|
||||
value={govRouteNumber}
|
||||
onChange={(e) => setGovRouteNumber(e.target.value)}
|
||||
/>
|
||||
<FormControl fullWidth required>
|
||||
<InputLabel>Обращение губернатора</InputLabel>
|
||||
<Select
|
||||
value={direction}
|
||||
label="Направление"
|
||||
onChange={(e) => setDirection(e.target.value)}
|
||||
required
|
||||
value={governorAppeal}
|
||||
label="Обращение губернатора"
|
||||
onChange={(e) => setGovernorAppeal(e.target.value as string)}
|
||||
disabled={articlesStore.articleList.ru.data.length === 0}
|
||||
>
|
||||
<MenuItem value="forward">Прямое</MenuItem>
|
||||
<MenuItem value="backward">Обратное</MenuItem>
|
||||
<MenuItem value="">Не выбрано</MenuItem>
|
||||
{articlesStore.articleList.ru.data.map(
|
||||
(a: (typeof articlesStore.articleList.ru.data)[number]) => (
|
||||
<MenuItem key={a.id} value={a.id}>
|
||||
{a.heading}
|
||||
</MenuItem>
|
||||
)
|
||||
)}
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
<FormControl fullWidth required>
|
||||
<InputLabel>Прямой/обратный маршрут</InputLabel>
|
||||
<Select
|
||||
value={direction}
|
||||
label="Прямой/обратный маршрут"
|
||||
onChange={(e) => setDirection(e.target.value)}
|
||||
>
|
||||
<MenuItem value="forward">Прямой</MenuItem>
|
||||
<MenuItem value="backward">Обратный</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
<TextField
|
||||
className="w-full"
|
||||
label="Масштаб (мин)"
|
||||
value={scaleMin}
|
||||
onChange={(e) => setScaleMin(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
className="w-full"
|
||||
label="Масштаб (макс)"
|
||||
value={scaleMax}
|
||||
onChange={(e) => setScaleMax(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
className="w-full"
|
||||
label="Поворот"
|
||||
value={turn}
|
||||
onChange={(e) => setTurn(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
className="w-full"
|
||||
label="Центр. широта"
|
||||
value={centerLat}
|
||||
onChange={(e) => setCenterLat(e.target.value)}
|
||||
/>
|
||||
<TextField
|
||||
className="w-full"
|
||||
label="Центр. долгота"
|
||||
value={centerLng}
|
||||
onChange={(e) => setCenterLng(e.target.value)}
|
||||
/>
|
||||
</Box>
|
||||
<div className="flex w-full justify-end">
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className="w-min flex gap-2 items-center"
|
||||
startIcon={<Save size={20} />}
|
||||
onClick={async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
// await createRoute(routeNumber, direction === "forward");
|
||||
setIsLoading(false);
|
||||
toast.success("Маршрут успешно создан");
|
||||
navigate(-1);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.error("Произошла ошибка");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}}
|
||||
onClick={handleCreateRoute}
|
||||
disabled={isLoading}
|
||||
>
|
||||
{isLoading ? (
|
||||
|
||||
Reference in New Issue
Block a user