Files
WhiteNightsAdminPanel/src/pages/Carrier/CarrierCreatePage/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

268 lines
7.8 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 } from "react-router-dom";
import { toast } from "react-toastify";
import {
carrierStore,
cityStore,
mediaStore,
languageStore,
useSelectedCity,
} from "@shared";
import { useState, useEffect } from "react";
import { ImageUploadCard, LanguageSwitcher } from "@widgets";
import {
SelectMediaDialog,
UploadMediaDialog,
PreviewMediaDialog,
} from "@shared";
export const CarrierCreatePage = observer(() => {
const navigate = useNavigate();
const { createCarrierData, setCreateCarrierData } = carrierStore;
const { language } = languageStore;
const { selectedCityId } = useSelectedCity();
const [selectedMediaId, setSelectedMediaId] = useState<string | null>(null);
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 [activeMenuType, setActiveMenuType] = useState<
"thumbnail" | "watermark_lu" | "watermark_rd" | "image" | null
>(null);
useEffect(() => {
cityStore.getCities("ru");
mediaStore.getMedia();
languageStore.setLanguage("ru");
}, []);
useEffect(() => {
if (selectedCityId && !createCarrierData.city_id) {
setCreateCarrierData(
createCarrierData[language].full_name,
createCarrierData[language].short_name,
selectedCityId,
createCarrierData[language].slogan,
selectedMediaId || "",
language
);
}
}, [selectedCityId, createCarrierData.city_id]);
const handleCreate = async () => {
try {
setIsLoading(true);
await carrierStore.createCarrier();
toast.success("Перевозчик успешно создан");
navigate("/carrier");
} catch (error) {
toast.error("Ошибка при создании перевозчика");
} finally {
setIsLoading(false);
}
};
const handleMediaSelect = (media: {
id: string;
filename: string;
media_name?: string;
media_type: number;
}) => {
setSelectedMediaId(media.id);
setCreateCarrierData(
createCarrierData[language].full_name,
createCarrierData[language].short_name,
createCarrierData.city_id,
createCarrierData[language].slogan,
media.id,
language
);
};
const selectedMedia = selectedMediaId
? mediaStore.media.find((m) => m.id === selectedMediaId)
: 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 flex-col gap-10 w-full items-end">
<div className="flex gap-10 items-center mb-5 max-w-[80%] self-start">
<h1 className="text-3xl break-words">Создание перевозчика</h1>
</div>
<FormControl fullWidth>
<InputLabel>Город</InputLabel>
<Select
value={createCarrierData.city_id || ""}
label="Город"
required
onChange={(e) =>
setCreateCarrierData(
createCarrierData[language].full_name,
createCarrierData[language].short_name,
e.target.value as number,
createCarrierData[language].slogan,
selectedMediaId || "",
language
)
}
>
{cityStore.cities["ru"].data.map((city) => (
<MenuItem key={city.id} value={city.id}>
{city.name}
</MenuItem>
))}
</Select>
</FormControl>
<TextField
fullWidth
label="Полное название"
value={createCarrierData[language].full_name}
required
onChange={(e) =>
setCreateCarrierData(
e.target.value,
createCarrierData[language].short_name,
createCarrierData.city_id,
createCarrierData[language].slogan,
selectedMediaId || "",
language
)
}
/>
<TextField
fullWidth
label="Короткое название"
value={createCarrierData[language].short_name}
required
onChange={(e) =>
setCreateCarrierData(
createCarrierData[language].full_name,
e.target.value,
createCarrierData.city_id,
createCarrierData[language].slogan,
selectedMediaId || "",
language
)
}
/>
<TextField
fullWidth
label="Слоган"
value={createCarrierData[language].slogan}
onChange={(e) =>
setCreateCarrierData(
createCarrierData[language].full_name,
createCarrierData[language].short_name,
createCarrierData.city_id,
e.target.value,
selectedMediaId || "",
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={() => {
setSelectedMediaId(null);
setActiveMenuType(null);
setCreateCarrierData(
createCarrierData[language].full_name,
createCarrierData[language].short_name,
createCarrierData.city_id,
createCarrierData[language].slogan,
"",
language
);
}}
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={handleCreate}
disabled={
isLoading ||
!createCarrierData[language].full_name ||
!createCarrierData[language].short_name ||
!createCarrierData.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={createCarrierData[language].full_name}
contextType="carrier"
afterUpload={handleMediaSelect}
hardcodeType={activeMenuType}
/>
<PreviewMediaDialog
open={isPreviewMediaOpen}
onClose={() => setIsPreviewMediaOpen(false)}
mediaId={mediaId}
/>
</Paper>
);
});