106 lines
3.1 KiB
TypeScript
106 lines
3.1 KiB
TypeScript
import React, { useEffect } from "react";
|
||
import {
|
||
FormControl,
|
||
Select,
|
||
MenuItem,
|
||
SelectChangeEvent,
|
||
Typography,
|
||
Box,
|
||
} from "@mui/material";
|
||
import { observer } from "mobx-react-lite";
|
||
import { authStore, cityStore, selectedCityStore, type City } from "@shared";
|
||
import { MapPin } from "lucide-react";
|
||
|
||
export const CitySelector: React.FC = observer(() => {
|
||
const { selectedCity, setSelectedCity, isLocked } = selectedCityStore;
|
||
const canLoadAllCities = authStore.isAdmin && authStore.canRead("cities");
|
||
|
||
useEffect(() => {
|
||
if (canLoadAllCities) {
|
||
cityStore.getCities("ru");
|
||
return;
|
||
}
|
||
authStore.fetchMeCities().catch(() => undefined);
|
||
}, [canLoadAllCities]);
|
||
|
||
const baseCities: City[] = canLoadAllCities
|
||
? cityStore.cities["ru"].data
|
||
: authStore.meCities["ru"].map((uc) => ({
|
||
id: uc.city_id,
|
||
name: uc.name,
|
||
country: "",
|
||
country_code: "",
|
||
arms: "",
|
||
}));
|
||
|
||
const currentCities: City[] = selectedCity?.id
|
||
? (() => {
|
||
const exists = baseCities.some((city) => city.id === selectedCity.id);
|
||
if (exists) {
|
||
return baseCities;
|
||
}
|
||
return [selectedCity, ...baseCities];
|
||
})()
|
||
: baseCities;
|
||
|
||
const handleCityChange = (event: SelectChangeEvent<string>) => {
|
||
const cityId = event.target.value;
|
||
if (cityId === "") {
|
||
setSelectedCity(null);
|
||
return;
|
||
}
|
||
|
||
const city = currentCities.find((c) => c.id === Number(cityId));
|
||
if (city) {
|
||
setSelectedCity(city);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<Box className="flex items-center gap-2">
|
||
<MapPin size={16} className={isLocked ? "text-gray-400" : "text-white"} />
|
||
<FormControl size="medium" sx={{ minWidth: 120 }}>
|
||
<Select
|
||
value={selectedCity?.id?.toString() || ""}
|
||
onChange={handleCityChange}
|
||
displayEmpty
|
||
disabled={isLocked}
|
||
sx={{
|
||
height: "40px",
|
||
color: "white",
|
||
"&.Mui-disabled": {
|
||
color: "rgba(255, 255, 255, 0.5)",
|
||
WebkitTextFillColor: "rgba(255, 255, 255, 0.5)",
|
||
},
|
||
"& .MuiOutlinedInput-notchedOutline": {
|
||
borderColor: isLocked
|
||
? "rgba(255, 255, 255, 0.1)"
|
||
: "rgba(255, 255, 255, 0.3)",
|
||
},
|
||
"&:hover .MuiOutlinedInput-notchedOutline": {
|
||
borderColor: isLocked
|
||
? "rgba(255, 255, 255, 0.1)"
|
||
: "rgba(255, 255, 255, 0.5)",
|
||
},
|
||
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
|
||
borderColor: "white",
|
||
},
|
||
"& .MuiSvgIcon-root": {
|
||
color: isLocked ? "rgba(255, 255, 255, 0.3)" : "white",
|
||
},
|
||
}}
|
||
>
|
||
<MenuItem value="">
|
||
<Typography variant="body2">Выберите город</Typography>
|
||
</MenuItem>
|
||
{currentCities.map((city) => (
|
||
<MenuItem key={city.id} value={city.id?.toString()}>
|
||
<Typography variant="body2">{city.name}</Typography>
|
||
</MenuItem>
|
||
))}
|
||
</Select>
|
||
</FormControl>
|
||
</Box>
|
||
);
|
||
});
|