import { DataGrid, GridColDef, GridRenderCellParams } from "@mui/x-data-grid"; import { ruRU } from "@mui/x-data-grid/locales"; import { authStore, languageStore, cityStore, countryStore, SearchInput } from "@shared"; import { useEffect, useState, useMemo } from "react"; import { observer } from "mobx-react-lite"; import { Pencil, Trash2, Minus } from "lucide-react"; import { useNavigate } from "react-router-dom"; import { CreateButton, DeleteModal, LanguageSwitcher } from "@widgets"; import { toast } from "react-toastify"; import { Box, CircularProgress } from "@mui/material"; export const CityListPage = observer(() => { const { cities, getCities, deleteCity } = cityStore; const navigate = useNavigate(); const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [isBulkDeleteModalOpen, setIsBulkDeleteModalOpen] = useState(false); const [rowId, setRowId] = useState(null); const [ids, setIds] = useState([]); const [isLoading, setIsLoading] = useState(false); const [rows, setRows] = useState([]); const [paginationModel, setPaginationModel] = useState({ page: 0, pageSize: 50, }); const { language } = languageStore; const canWriteCities = authStore.canWrite("cities"); const [searchQuery, setSearchQuery] = useState(""); useEffect(() => { const fetchData = async () => { setIsLoading(true); await countryStore.getCountries("ru"); await countryStore.getCountries("en"); await countryStore.getCountries("zh"); await getCities(language); setIsLoading(false); }; fetchData(); }, [language]); useEffect(() => { let newRows = cities[language]?.data?.map((city) => ({ id: city.id, name: city.name, country: city.country_code, })); let newRows2: any[] = []; for (const city of newRows) { const name = countryStore.countries[language]?.data?.find( (country) => country.code === city.country )?.name; if (name) { newRows2.push(city); } } setRows(newRows2 || []); }, [cities, countryStore.countries, language, isLoading]); const filteredRows = useMemo(() => { const query = searchQuery.trim().toLowerCase(); if (!query) return rows; return rows.filter((row) => { const cityName = (row.name ?? "").toLowerCase(); const countryName = ( countryStore.countries[language]?.data?.find((c) => c.code === row.country)?.name ?? "" ).toLowerCase(); return cityName.includes(query) || countryName.includes(query); }); }, [rows, searchQuery, countryStore.countries, language]); const columns: GridColDef[] = [ { field: "country", headerName: "Страна", width: 150, renderCell: (params: GridRenderCellParams) => { return (
{params.value ? ( countryStore.countries[language]?.data?.find( (country) => country.code === params.value )?.name ) : ( )}
); }, }, { field: "name", headerName: "Название", flex: 1, renderCell: (params: GridRenderCellParams) => { return (
{params.value ? ( params.value ) : ( )}
); }, }, ...(authStore.canWrite("cities") ? [{ field: "actions", headerName: "Действия", align: "center" as const, headerAlign: "center" as const, width: 200, sortable: false, renderCell: (params: GridRenderCellParams) => (
), }] : []), ]; return ( <>

Города

{canWriteCities && ( )}
{canWriteCities && ids.length > 0 && (
)} { if (Array.isArray(newSelection)) { const selectedIds = newSelection.map( (id: string | number) => Number(id) ); setIds(selectedIds); } else if ( newSelection && typeof newSelection === "object" && "ids" in newSelection ) { const idsSet = newSelection.ids as Set; const selectedIds = Array.from(idsSet).map( (id: string | number) => Number(id) ); setIds(selectedIds); } else { setIds([]); } } : undefined } slots={{ noRowsOverlay: () => ( {isLoading ? : "Нет городов"} ), }} />
{ if (rowId) { await deleteCity(rowId.toString()); toast.success("Город успешно удален"); } setIsDeleteModalOpen(false); setRowId(null); }} onCancel={() => { setIsDeleteModalOpen(false); setRowId(null); }} /> { await Promise.all(ids.map((id) => deleteCity(id.toString()))); toast.success("Города успешно удалены"); getCities(language); setIsBulkDeleteModalOpen(false); setIds([]); }} onCancel={() => { setIsBulkDeleteModalOpen(false); }} /> ); });