import { DataGrid, GridColDef, GridRenderCellParams } from "@mui/x-data-grid"; import { ruRU } from "@mui/x-data-grid/locales"; import { authStore, cityStore, languageStore, sightsStore, selectedCityStore, 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 { Box, CircularProgress } from "@mui/material"; export const SightListPage = observer(() => { const { sights, getSights, deleteListSight } = sightsStore; 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 [paginationModel, setPaginationModel] = useState({ page: 0, pageSize: 50, }); const { language } = languageStore; const canReadCities = authStore.canRead("cities"); const [searchQuery, setSearchQuery] = useState(""); useEffect(() => { const fetchSights = async () => { setIsLoading(true); if (!authStore.me) { await authStore.getMeAction().catch(() => undefined); } if (authStore.canRead("cities")) { await cityStore.getCities(language); } else { await authStore.fetchMeCities().catch(() => undefined); } await getSights(); setIsLoading(false); }; fetchSights(); }, [language]); const columns: GridColDef[] = [ { field: "name", headerName: "Название", flex: 1, renderCell: (params: GridRenderCellParams) => { return (
{params.value ? ( params.value ) : ( )}
); }, }, { field: "short_name", headerName: "Сокращенное название", flex: 1, renderCell: (params: GridRenderCellParams) => { return (
{params.value ? ( params.value ) : ( )}
); }, }, { field: "city_id", headerName: "Город", flex: 1, renderCell: (params: GridRenderCellParams) => { const lang = language as "ru" | "en" | "zh"; const cityName = canReadCities ? cityStore.cities[lang]?.data.find((c) => c.id === params.value)?.name : authStore.meCities[lang]?.find((c) => c.city_id === params.value)?.name; return (
{cityName ?? }
); }, }, ...(authStore.canWrite("sights") ? [{ field: "actions", headerName: "Действия", align: "center" as const, headerAlign: "center" as const, sortable: false, renderCell: (params: GridRenderCellParams) => (
), }] : []), ]; const filteredSights = useMemo(() => { const { selectedCityId } = selectedCityStore; const allowedCityIds = canReadCities ? null : authStore.meCities["ru"].map((c) => c.city_id); return sights.filter((sight: any) => { if (allowedCityIds && !allowedCityIds.includes(sight.city_id)) { return false; } if (selectedCityId && sight.city_id !== selectedCityId) { return false; } return true; }); }, [sights, selectedCityStore.selectedCityId, canReadCities, authStore.meCities]); const query = searchQuery.trim().toLowerCase(); const rows = filteredSights .filter((sight: any) => !query || (sight.name ?? "").toLowerCase().includes(query) || (sight.short_name ?? "").toLowerCase().includes(query)) .map((sight: any) => ({ id: sight.id, name: sight.name, short_name: sight.short_name, city_id: sight.city_id, })); const canWriteSights = authStore.canWrite("sights"); return ( <>

Достопримечательности

{canWriteSights && ( )}
{canWriteSights && ids.length > 0 && (
)} canWriteSights && navigate(`/sight/${params.row.id}/edit`)} checkboxSelection={canWriteSights} disableRowSelectionExcludeModel loading={isLoading} paginationModel={paginationModel} onPaginationModelChange={setPaginationModel} pageSizeOptions={[50]} localeText={ruRU.components.MuiDataGrid.defaultProps.localeText} onRowSelectionModelChange={ canWriteSights ? (newSelection: any) => { if (Array.isArray(newSelection)) { const selectedIds = newSelection.map(Number); setIds(selectedIds); } else if ( newSelection && typeof newSelection === "object" && "ids" in newSelection ) { const idsSet = newSelection.ids as Set; const selectedIds = Array.from(idsSet).map(Number); setIds(selectedIds); } else { setIds([]); } } : undefined } slots={{ noRowsOverlay: () => ( {isLoading ? ( ) : ( "Нет достопримечательностей" )} ), }} />
{ if (rowId) { await deleteListSight(Number(rowId)); } setIsDeleteModalOpen(false); setRowId(null); }} onCancel={() => { setIsDeleteModalOpen(false); setRowId(null); }} /> { await Promise.all(ids.map((id) => deleteListSight(id))); getSights(); setIsBulkDeleteModalOpen(false); setIds([]); }} onCancel={() => { setIsBulkDeleteModalOpen(false); }} /> ); });