import {
Button,
Paper,
TextField,
Select,
MenuItem,
FormControl,
InputLabel,
Box,
} from "@mui/material";
import { observer } from "mobx-react-lite";
import { ArrowLeft, Save } from "lucide-react";
import { Loader2 } from "lucide-react";
import { useNavigate, useParams } from "react-router-dom";
import { toast } from "react-toastify";
import {
carrierStore,
cityStore,
authStore,
mediaStore,
languageStore,
isMediaIdEmpty,
LoadingSpinner,
} from "@shared";
import { useState, useEffect } from "react";
import { ImageUploadCard, LanguageSwitcher, DeleteModal } from "@widgets";
import {
SelectMediaDialog,
PreviewMediaDialog,
UploadMediaDialog,
} from "@shared";
type ColorFields = { main_color: string; left_color: string; right_color: string };
const colorFields = (data: ColorFields) => ({
main_color: data.main_color,
left_color: data.left_color,
right_color: data.right_color,
});
const ColorPickerField = ({
label,
value,
onChange,
}: {
label: string;
value: string;
onChange: (val: string) => void;
}) => (
);
export const CarrierEditPage = observer(() => {
const navigate = useNavigate();
const { id } = useParams();
const { getCarrier, setEditCarrierData, editCarrierData } = carrierStore;
const { language } = languageStore;
const canReadCities = authStore.canRead("cities");
const [isLoading, setIsLoading] = useState(false);
const [isLoadingData, setIsLoadingData] = useState(true);
const [isSelectMediaOpen, setIsSelectMediaOpen] = useState(false);
const [isUploadMediaOpen, setIsUploadMediaOpen] = useState(false);
const [isPreviewMediaOpen, setIsPreviewMediaOpen] = useState(false);
const [mediaId, setMediaId] = useState("");
const [isDeleteLogoModalOpen, setIsDeleteLogoModalOpen] = useState(false);
const [initialCityName, setInitialCityName] = useState("");
const [activeMenuType, setActiveMenuType] = useState<
"thumbnail" | "watermark_lu" | "watermark_rd" | "image" | null
>(null);
useEffect(() => {
(async () => {
if (!id) {
setIsLoadingData(false);
return;
}
setIsLoadingData(true);
try {
if (!authStore.me) {
await authStore.getMeAction().catch(() => undefined);
}
if (authStore.canRead("cities")) {
await cityStore.getCities("ru");
} else {
await authStore.fetchMeCities().catch(() => undefined);
}
const carrierData = await getCarrier(Number(id));
if (carrierData) {
const colors = {
main_color: carrierData.ru?.main_color || "",
left_color: carrierData.ru?.left_color || "",
right_color: carrierData.ru?.right_color || "",
};
setEditCarrierData(
carrierData.ru?.full_name || "",
carrierData.ru?.short_name || "",
carrierData.ru?.city_id || 0,
carrierData.ru?.slogan || "",
carrierData.ru?.logo || "",
"ru",
colors
);
setEditCarrierData(
carrierData.en?.full_name || "",
carrierData.en?.short_name || "",
carrierData.en?.city_id || 0,
carrierData.en?.slogan || "",
carrierData.en?.logo || "",
"en"
);
setEditCarrierData(
carrierData.zh?.full_name || "",
carrierData.zh?.short_name || "",
carrierData.zh?.city_id || 0,
carrierData.zh?.slogan || "",
carrierData.zh?.logo || "",
"zh"
);
setInitialCityName(carrierData.ru?.city || "");
}
await mediaStore.getMedia();
} finally {
setIsLoadingData(false);
}
})();
languageStore.setLanguage("ru");
}, [id]);
const handleEdit = async () => {
try {
setIsLoading(true);
await carrierStore.editCarrier(Number(id));
toast.success("Перевозчик успешно обновлен");
navigate("/carrier");
} catch (error) {
toast.error("Ошибка при обновлении перевозчика");
} finally {
setIsLoading(false);
}
};
const handleMediaSelect = (media: {
id: string;
filename: string;
media_name?: string;
media_type: number;
}) => {
setEditCarrierData(
editCarrierData[language].full_name,
editCarrierData[language].short_name,
editCarrierData.city_id,
editCarrierData[language].slogan,
media.id,
language
);
};
const selectedMedia =
editCarrierData.logo && !isMediaIdEmpty(editCarrierData.logo)
? mediaStore.media.find((m) => m.id === editCarrierData.logo)
: null;
const effectiveLogoUrl = isMediaIdEmpty(editCarrierData.logo)
? null
: (selectedMedia?.id ?? editCarrierData.logo);
const baseCities = canReadCities
? cityStore.cities["ru"].data
: authStore.meCities["ru"].map((city) => ({
id: city.city_id,
name: city.name,
country: "",
country_code: "",
arms: "",
}));
const availableCities =
editCarrierData.city_id &&
!baseCities.some((city) => city.id === editCarrierData.city_id)
? [
{
id: editCarrierData.city_id,
name: initialCityName || `Город ${editCarrierData.city_id}`,
country: "",
country_code: "",
arms: "",
},
...baseCities,
]
: baseCities;
if (isLoadingData) {
return (
);
}
return (
{editCarrierData.ru.full_name}
Город
setEditCarrierData(
e.target.value,
editCarrierData[language].short_name,
editCarrierData.city_id,
editCarrierData[language].slogan,
editCarrierData.logo,
language
)
}
/>
setEditCarrierData(
editCarrierData[language].full_name,
e.target.value,
editCarrierData.city_id,
editCarrierData[language].slogan,
editCarrierData.logo,
language
)
}
/>
setEditCarrierData(
editCarrierData[language].full_name,
editCarrierData[language].short_name,
editCarrierData.city_id,
e.target.value,
editCarrierData.logo,
language
)
}
/>
setEditCarrierData(
editCarrierData[language].full_name,
editCarrierData[language].short_name,
editCarrierData.city_id,
editCarrierData[language].slogan,
editCarrierData.logo,
language,
{ ...colorFields(editCarrierData), main_color: val }
)
}
/>
Используется в: виджет маршрута, виджет обращений, значки на карте, скопление достопримечательностей на карте, информационный виджет
setEditCarrierData(
editCarrierData[language].full_name,
editCarrierData[language].short_name,
editCarrierData.city_id,
editCarrierData[language].slogan,
editCarrierData.logo,
language,
{ ...colorFields(editCarrierData), left_color: val }
)
}
/>
Используется в: боковое меню, левый виджет достопримечательности
setEditCarrierData(
editCarrierData[language].full_name,
editCarrierData[language].short_name,
editCarrierData.city_id,
editCarrierData[language].slogan,
editCarrierData.logo,
language,
{ ...colorFields(editCarrierData), right_color: val }
)
}
/>
Используется в: список достопримечательностей, страница достопримечательности
{
setIsPreviewMediaOpen(true);
setMediaId(effectiveLogoUrl ?? "");
}}
onDeleteImageClick={() => {
setIsDeleteLogoModalOpen(true);
}}
onSelectFileClick={() => {
setActiveMenuType("image");
setIsSelectMediaOpen(true);
}}
setUploadMediaOpen={() => {
setIsUploadMediaOpen(true);
setActiveMenuType("image");
}}
/>
}
onClick={handleEdit}
disabled={
isLoading ||
!editCarrierData[language].full_name ||
!editCarrierData.city_id
}
>
{isLoading ? (
) : (
"Сохранить"
)}
setIsSelectMediaOpen(false)}
onSelectMedia={handleMediaSelect}
mediaType={1}
/>
setIsUploadMediaOpen(false)}
contextObjectName={editCarrierData[language].full_name}
contextType="carrier"
afterUpload={handleMediaSelect}
hardcodeType={activeMenuType}
/>
setIsPreviewMediaOpen(false)}
mediaId={mediaId}
/>
{
setEditCarrierData(
editCarrierData[language].full_name,
editCarrierData[language].short_name,
editCarrierData.city_id,
editCarrierData[language].slogan,
"",
language
);
setIsDeleteLogoModalOpen(false);
}}
onCancel={() => setIsDeleteLogoModalOpen(false)}
edit
/>
);
});