Files
WhiteNightsAdminPanel/src/pages/Carrier/CarrierEditPage/index.tsx
fisenko 03fd04a420 #18 Корректировки 01.11.25 (#19)
Reviewed-on: #19
Reviewed-by: Микаэл Оганесян <15lu.akari@unprism.ru>
Co-authored-by: fisenko <kkzemeow@gmail.com>
Co-committed-by: fisenko <kkzemeow@gmail.com>
2025-11-07 07:16:29 +00:00

288 lines
8.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
Button,
Paper,
TextField,
Select,
MenuItem,
FormControl,
InputLabel,
} 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, mediaStore, languageStore } from "@shared";
import { useState, useEffect } from "react";
import { ImageUploadCard, LanguageSwitcher, DeleteModal } from "@widgets";
import {
SelectMediaDialog,
PreviewMediaDialog,
UploadMediaDialog,
} from "@shared";
export const CarrierEditPage = observer(() => {
const navigate = useNavigate();
const { id } = useParams();
const { getCarrier, setEditCarrierData, editCarrierData } = carrierStore;
const { language } = languageStore;
const [isLoading, setIsLoading] = useState(false);
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 [activeMenuType, setActiveMenuType] = useState<
"thumbnail" | "watermark_lu" | "watermark_rd" | "image" | null
>(null);
useEffect(() => {
(async () => {
await cityStore.getCities("ru");
await cityStore.getCities("en");
await cityStore.getCities("zh");
const carrierData = await getCarrier(Number(id));
if (carrierData) {
setEditCarrierData(
carrierData.ru?.full_name || "",
carrierData.ru?.short_name || "",
carrierData.ru?.city_id || 0,
carrierData.ru?.slogan || "",
carrierData.ru?.logo || "",
"ru"
);
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"
);
}
mediaStore.getMedia();
})();
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
? mediaStore.media.find((m) => m.id === editCarrierData.logo)
: null;
return (
<Paper className="w-full h-full p-3 flex flex-col gap-10">
<LanguageSwitcher />
<div className="flex items-center gap-4">
<button
className="flex items-center gap-2"
onClick={() => navigate(-1)}
>
<ArrowLeft size={20} />
Назад
</button>
</div>
<div className="flex gap-10 items-center mb-5 max-w-[80%] self-start">
<h1 className="text-3xl break-words">{editCarrierData.ru.full_name}</h1>
</div>
<div className="flex flex-col gap-10 w-full items-end">
<FormControl fullWidth>
<InputLabel>Город</InputLabel>
<Select
value={editCarrierData.city_id || ""}
label="Город"
required
onChange={(e) =>
setEditCarrierData(
editCarrierData[language].full_name,
editCarrierData[language].short_name,
Number(e.target.value),
editCarrierData[language].slogan,
editCarrierData.logo,
language
)
}
>
{cityStore.cities["ru"].data?.map((city) => (
<MenuItem key={city.id} value={city.id}>
{city.name}
</MenuItem>
))}
</Select>
</FormControl>
<TextField
fullWidth
label="Полное название"
value={editCarrierData[language].full_name}
required
onChange={(e) =>
setEditCarrierData(
e.target.value,
editCarrierData[language].short_name,
editCarrierData.city_id,
editCarrierData[language].slogan,
editCarrierData.logo,
language
)
}
/>
<TextField
fullWidth
label="Короткое название"
value={editCarrierData[language].short_name}
required
onChange={(e) =>
setEditCarrierData(
editCarrierData[language].full_name,
e.target.value,
editCarrierData.city_id,
editCarrierData[language].slogan,
editCarrierData.logo,
language
)
}
/>
<TextField
fullWidth
label="Слоган"
value={editCarrierData[language].slogan}
onChange={(e) =>
setEditCarrierData(
editCarrierData[language].full_name,
editCarrierData[language].short_name,
editCarrierData.city_id,
e.target.value,
editCarrierData.logo,
language
)
}
/>
<div className="w-full flex flex-col gap-4 max-w-[300px] mx-auto">
<ImageUploadCard
title="Логотип перевозчика"
imageKey="thumbnail"
imageUrl={selectedMedia?.id}
onImageClick={() => {
setIsPreviewMediaOpen(true);
setMediaId(selectedMedia?.id ?? "");
}}
onDeleteImageClick={() => {
setIsDeleteLogoModalOpen(true);
}}
onSelectFileClick={() => {
setActiveMenuType("image");
setIsSelectMediaOpen(true);
}}
setUploadMediaOpen={() => {
setIsUploadMediaOpen(true);
setActiveMenuType("image");
}}
/>
</div>
<Button
variant="contained"
className="w-min flex gap-2 items-center"
startIcon={<Save size={20} />}
onClick={handleEdit}
disabled={
isLoading ||
!editCarrierData[language].full_name ||
!editCarrierData.city_id
}
>
{isLoading ? (
<Loader2 size={20} className="animate-spin" />
) : (
"Сохранить"
)}
</Button>
</div>
<SelectMediaDialog
open={isSelectMediaOpen}
onClose={() => setIsSelectMediaOpen(false)}
onSelectMedia={handleMediaSelect}
mediaType={1}
/>
<UploadMediaDialog
open={isUploadMediaOpen}
onClose={() => setIsUploadMediaOpen(false)}
contextObjectName={editCarrierData[language].full_name}
contextType="carrier"
afterUpload={handleMediaSelect}
hardcodeType={activeMenuType}
/>
<PreviewMediaDialog
open={isPreviewMediaOpen}
onClose={() => setIsPreviewMediaOpen(false)}
mediaId={mediaId}
/>
<DeleteModal
open={isDeleteLogoModalOpen}
onDelete={() => {
setEditCarrierData(
editCarrierData[language].full_name,
editCarrierData[language].short_name,
editCarrierData.city_id,
editCarrierData[language].slogan,
"",
language
);
setIsDeleteLogoModalOpen(false);
}}
onCancel={() => setIsDeleteLogoModalOpen(false)}
edit
/>
</Paper>
);
});