104 lines
3.8 KiB
TypeScript
104 lines
3.8 KiB
TypeScript
import { Accordion, ActionIcon, Collapse, ColorSwatch, Flex, MantineStyleProp, ScrollAreaAutosize, Stack, Text, useMantineColorScheme } from '@mantine/core'
|
||
import useSWR from 'swr'
|
||
import { fetcher } from '../../../http/axiosInstance'
|
||
import { BASE_URL } from '../../../constants'
|
||
import { useDisclosure } from '@mantine/hooks'
|
||
import { IconChevronDown } from '@tabler/icons-react'
|
||
|
||
const MapLegend = ({
|
||
selectedDistrict,
|
||
selectedYear,
|
||
style
|
||
}: {
|
||
selectedDistrict: number | null,
|
||
selectedYear: number | null,
|
||
style: MantineStyleProp
|
||
}) => {
|
||
const { colorScheme } = useMantineColorScheme()
|
||
|
||
const { data: existingObjectsList } = useSWR(
|
||
selectedYear && selectedDistrict ? `/general/objects/list?year=${selectedYear}&city_id=${selectedDistrict}&planning=0` : null,
|
||
(url) => fetcher(url, BASE_URL.ems),
|
||
{
|
||
revalidateOnFocus: false
|
||
}
|
||
)
|
||
|
||
const { data: planningObjectsList } = useSWR(
|
||
selectedYear && selectedDistrict ? `/general/objects/list?year=${selectedYear}&city_id=${selectedDistrict}&planning=1` : null,
|
||
(url) => fetcher(url, BASE_URL.ems),
|
||
{
|
||
revalidateOnFocus: false
|
||
}
|
||
)
|
||
|
||
const [opened, { toggle }] = useDisclosure(false)
|
||
|
||
return (
|
||
<ScrollAreaAutosize maw='300px' w='100%' fz='xs' mt='auto' style={{ ...style, zIndex: 1, backdropFilter: 'blur(8px)', backgroundColor: colorScheme === 'light' ? '#FFFFFFAA' : '#000000AA', borderRadius: '4px' }}>
|
||
<Stack gap='sm' p='sm'>
|
||
<Flex align='center'>
|
||
<Text fz='xs'>
|
||
Легенда
|
||
</Text>
|
||
|
||
<ActionIcon ml='auto' variant='subtle' onClick={toggle} >
|
||
<IconChevronDown style={{ transform: opened ? 'rotate(0deg)' : 'rotate(180deg)' }} />
|
||
</ActionIcon>
|
||
</Flex>
|
||
|
||
<Collapse in={opened}>
|
||
<Accordion defaultValue={['existing', 'planning']} multiple>
|
||
<Accordion.Item value='existing' key='existing'>
|
||
<Accordion.Control>Существующие</Accordion.Control>
|
||
<Accordion.Panel>
|
||
{existingObjectsList && <LegendGroup objectsList={existingObjectsList} border='solid' />}
|
||
</Accordion.Panel>
|
||
</Accordion.Item>
|
||
|
||
<Accordion.Item value='planning' key='planning'>
|
||
<Accordion.Control>Планируемые</Accordion.Control>
|
||
<Accordion.Panel>
|
||
{planningObjectsList && <LegendGroup objectsList={planningObjectsList} border='dotted' />}
|
||
</Accordion.Panel>
|
||
</Accordion.Item>
|
||
</Accordion>
|
||
</Collapse>
|
||
</Stack>
|
||
</ScrollAreaAutosize>
|
||
)
|
||
}
|
||
|
||
const LegendGroup = ({
|
||
objectsList,
|
||
border
|
||
}: {
|
||
objectsList: { id: number, name: string, count: number, r: number | null, g: number | null, b: number | null }[],
|
||
border: 'solid' | 'dotted'
|
||
}) => {
|
||
|
||
const borderStyle = () => {
|
||
switch (border) {
|
||
case 'solid':
|
||
return '2px solid black'
|
||
case 'dotted':
|
||
return '2px dotted black'
|
||
default:
|
||
return 'none'
|
||
}
|
||
}
|
||
|
||
return (
|
||
<Stack gap={4}>
|
||
{objectsList.map(object => (
|
||
<Flex gap='xs' align='center' key={object.id}>
|
||
<ColorSwatch style={{ border: borderStyle() }} radius={0} size={16} color={`rgb(${object.r},${object.g},${object.b})`} />
|
||
-
|
||
<Text fz='xs'>{object.name}</Text>
|
||
</Flex>
|
||
))}
|
||
</Stack>
|
||
)
|
||
}
|
||
|
||
export default MapLegend |