Reviewed-on: #19 Reviewed-by: Микаэл Оганесян <15lu.akari@unprism.ru> Co-authored-by: fisenko <kkzemeow@gmail.com> Co-committed-by: fisenko <kkzemeow@gmail.com>
288 lines
8.4 KiB
TypeScript
288 lines
8.4 KiB
TypeScript
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>
|
||
);
|
||
});
|