Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/kvartalnye #104

Merged
merged 12 commits into from
Nov 7, 2023
6 changes: 6 additions & 0 deletions components/Layers/Filters.config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { OknFilter } from 'components/Layers/OKN/Filter/Okn/OknFilter';
import { LinesFilter } from 'components/Layers/Lines/Filter/LinesFilter';
import { DTPFilter } from 'components/Layers/DTP/Filter/DTPFilter';
import { SOURCES_BY_TYPE } from 'constants/sources';
import { QuarterFilter } from 'components/Layers/Quarter/Filter/QuarterFilter';
import { FilterConfig, FilterType } from '../../types/Filters.types';

// @ts-ignore
Expand Down Expand Up @@ -52,4 +53,9 @@ export const FILTERS_CONFIG: FilterConfig = {
component: <LinesFilter />,
isVerified: true,
},
[FilterType.Quarter]: {
title: 'Квартальные',
component: <QuarterFilter />,
isVerified: true,
},
};
30 changes: 30 additions & 0 deletions components/Layers/Quarter/CardContent/CardContent.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.popup {
border-top-left-radius: inherit;
border-top-right-radius: inherit;
padding: 16px 8px 16px 16px;
}

.mainLink {
color: inherit;
font-size: inherit;
line-height: inherit;
}

.description {
margin-top: 8px;
position: relative;
svg {
position: relative;
top: 2px;
left: 2px;
path {
fill: #000;
}
}
a {
border-radius: 8px;
font-size: 16px;
width: 100%;
text-align: center;
}
}
69 changes: 69 additions & 0 deletions components/Layers/Quarter/CardContent/CardContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { QuarterObject } from 'components/Layers/Quarter/quarterObject';
import { Button, ButtonSize, ButtonType } from 'components/UI/Button/Button';
import { Header } from 'components/UI/Card/components/Header/Header';
import { Info } from 'components/UI/Card/components/Info/Info';
import { Section } from 'components/UI/Card/components/Section/Section';
import sectionStyles from 'components/UI/Card/components/Section/Section.module.css';
import { Sources } from 'components/UI/Card/components/Sources/Sources';
import { EditObjectButtonLink } from 'components/UI/EditObjectButtonLink/EditObjectButtonLink';
import { Icon } from 'components/UI/Icons';
import { IconType } from 'components/UI/Icons/Icons.types';
import styles from './CardContent.module.css';

type QuarterCardContentProps = {
placemark?: QuarterObject;
};

export function QuarterCardContent({ placemark }: QuarterCardContentProps) {
if (!placemark) return null;

return (
<div className={styles.popup}>
<Header title={placemark.quarterTitle} />

<div className={styles.description}>
{/* <a href={placemark.url} target="_blank" rel="noreferrer">
Посмотреть телефон и почту квартального&nbsp;
<Icon type={IconType.External} color="#000" />
</a> */}
<Button
size={ButtonSize.SMALL}
onClick={() => {}}
link={placemark.url}
type={ButtonType.YELLOW}
>
Посмотреть телефон и почту квартального&nbsp;
<Icon type={IconType.External} color="#000" />
</Button>
</div>

<Section>
<Info
nameColor="#9baac3"
infos={[
{
name: 'Район',
text: placemark.districtTitle,
},
// {
// name: 'Границы квартала',
// text: placemark.quarterDescription,
// },
]}
/>
</Section>

<Section>
<Sources sources={['ekb']} />
</Section>
<Section>
<div className={sectionStyles.block_inline}>
<EditObjectButtonLink
text="Дополнить или поправить"
address={placemark?.quarterTitle}
/>
</div>
</Section>
</div>
);
}
22 changes: 22 additions & 0 deletions components/Layers/Quarter/Filter/QuarterFilter.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.wrapper {
font-size: 16px;
line-height: 21px;

p {
margin: 16px 0 0 0;
&:first-child {
margin-top: 0;
}
}

ul {
list-style-type: '— ';
margin: 0;
padding: 0;
padding-left: 16px;
}

li {
padding: 0;
}
}
42 changes: 42 additions & 0 deletions components/Layers/Quarter/Filter/QuarterFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { setFilter } from 'state/features/dataLayers';
import { FilterType } from 'types/Filters.types';
import { Link } from 'components/UI/Card/components/Link/Link';
import styles from './QuarterFilter.module.css';

export function QuarterFilter() {
const dispatch = useDispatch();

useEffect(() => {
dispatch(
setFilter({
activeFilter: FilterType.Quarter,
activeFilterParams: {},
}),
);
});

return (
<div className={styles.wrapper}>
<p>
Квартальный 🙋 — это человек, который следит за&nbsp;порядком на придомовых
территориях, детских площадках, парковках, мусорках, объектах торговли и&nbsp;т. д.
</p>
<p>На что можно пожаловаться квартальному:</p>
<ul>
<li>общие вопросы благоустройства;</li>
<li>незаконная торговля, парковки и постройки;</li>
<li>вывески и незаконная реклама;</li>
<li>самовольные ограничения;</li>
<li>сломанные детские площадки.</li>
</ul>
<p>
<Link
href="https://екатеринбург.рф/справка/квартальные/"
text="Подробнее о квартальных"
/>
</p>
</div>
);
}
10 changes: 10 additions & 0 deletions components/Layers/Quarter/quarter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import quarterObjects from 'public/quarter_inspectors.json';
import { QuarterObject } from './quarterObject';

export const quarter = {
getObject(quarterTitle: string): Promise<QuarterObject> {
return Promise.resolve(
quarterObjects.features.find((f) => f.properties.quarterTitle === decodeURI(quarterTitle)).properties as unknown as QuarterObject,
);
},
};
6 changes: 6 additions & 0 deletions components/Layers/Quarter/quarterObject.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface QuarterObject {
districtTitle: string;
quarterTitle: string;
quarterDescription: string;
url: string;
}
6 changes: 6 additions & 0 deletions components/Layers/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { okn } from 'components/Layers/OKN/okn';

import { lines } from 'components/Layers/Lines/lines';
import { LinesCardContent } from 'components/Layers/Lines/CardContent/CardContent';
import { QuarterCardContent } from 'components/Layers/Quarter/CardContent/CardContent';
import { quarter } from 'components/Layers/Quarter/quarter';
import { DesignCodeCardContent } from './DesignCode/CardContent/CardContent';
import { DTPCardContent } from './DTP/CardContent/CardContent';
import { HousesCardContent } from './Houses/CardContent/CardContent';
Expand Down Expand Up @@ -39,4 +41,8 @@ export const MODEL_CONFIG = {
cardContent: LinesCardContent,
requests: { oneItemRequest: lines.getObject },
},
[MapItemType.Quarter]: {
cardContent: QuarterCardContent,
requests: { oneItemRequest: quarter.getObject },
},
} as const;
2 changes: 2 additions & 0 deletions components/Map/Map.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { OknSource } from './layers/OknSource';
import { DtpSource } from './layers/DtpSource';
import { LinesSource } from './layers/LinesSource';
import { DesignCodeSource } from './layers/DesignCodeSource';
import { QuarterSource } from './layers/QuarterSource';
import { MapContext } from './providers/MapProvider';

import 'maplibre-gl/dist/maplibre-gl.css';
Expand All @@ -23,6 +24,7 @@ function MapLayers() {
<DtpSource />
<LinesSource />
<DesignCodeSource />
<QuarterSource />
</>
);
}
Expand Down
73 changes: 73 additions & 0 deletions components/Map/layers/QuarterSource.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React, { useEffect } from 'react';
import { FillLayer, Layer, LineLayer, Source, useMap } from 'react-map-gl';
import { useSelector } from 'react-redux';
import { activeFilterSelector } from 'state/features/selectors';
import { FilterType } from 'types/Filters.types';
import { getLayerStyle } from 'components/Map/helpers/getFeatureState';
import { MapItemType } from 'types/map-item';
import { usePopup } from 'components/Map/providers/usePopup';
import useMapObjectState from '../providers/useMapObjectState';
import { colorLuminance } from '../helpers/colorLuminance';

const QUARTER_LAYER_ID = 'ekb-quarter-inspectors-layer';
const QUARTER_SOURCE_ID = 'ekb-quarter-inspectors-source';

export function QuarterSource() {
const ekbMap = useMap();
const { openPopup } = usePopup();
const activeFilter = useSelector(activeFilterSelector);

useMapObjectState(QUARTER_LAYER_ID);

useEffect(() => {
const map = ekbMap.current;

const handlePointClick = (e) => {
const item = e.target.queryRenderedFeatures(e.point)[0];

openPopup(decodeURI(item?.properties?.quarterTitle), MapItemType.Quarter);
};

map.on('click', QUARTER_LAYER_ID, handlePointClick);

return () => {
map.off('click', QUARTER_LAYER_ID, handlePointClick);
};
}, [ekbMap, openPopup]);

const layerStyle: FillLayer = {
type: 'fill',
id: QUARTER_LAYER_ID,
source: QUARTER_SOURCE_ID,
paint: {
'fill-color': getLayerStyle<string>({
initial: '#9AADCC',
hover: colorLuminance('#9AADCC', 0.2),
active: colorLuminance('#9AADCC', 0.4),
}),
'fill-opacity': 0.6,
},
};

const layerStrokeStyle: LineLayer = {
id: `${QUARTER_LAYER_ID}-outline`,
type: 'line',
source: QUARTER_SOURCE_ID,
paint: {
'line-color': '#000',
'line-opacity': 0.5,
'line-width': 1.5,
},
};

if (activeFilter !== FilterType.Quarter) {
return null;
}

return (
<Source type="geojson" data="./quarter_inspectors.json" id={QUARTER_SOURCE_ID} generateId>
<Layer {...layerStyle} />
<Layer {...layerStrokeStyle} />
</Source>
);
}
17 changes: 6 additions & 11 deletions components/UI/Button/Button.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,18 @@
font-size: 15px;
line-height: 1.33;
cursor: pointer;
transition: .15s ease;
}

.button:hover {
filter: contrast(0.75);
}

.button:active {
filter: contrast(0.65);
transition: all 0.15s ease;
}

.button_yellow {
background: #FFD400;
background: #ffd400;
color: black;
}

.button_yellow:hover {
background: #e1bb00;
}

.button_black {
background: black;
color: white;
Expand All @@ -34,7 +30,6 @@
padding: 12px 32px;
}


@media screen and (width >= 768px) {
.button {
font-size: 16px;
Expand Down
15 changes: 10 additions & 5 deletions components/UI/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react';
import classNames from 'classnames';
import styles from './Button.module.css';

Expand All @@ -23,22 +22,28 @@ const buttonStylesBySize: Record<ButtonSize, any> = {
};

type TButtonProps = {
text: string;
text?: string;
type: ButtonType;
size: ButtonSize;
onClick: VoidFunction;
link?: string;
children?: React.ReactNode;
};

export function Button({ text, type, size, onClick, link }: TButtonProps) {
export function Button({ text, type, size, onClick, link, children }: TButtonProps) {
const className = classNames(styles.button, buttonStylesByType[type], buttonStylesBySize[size]);

if (link) {
return (
<a className={className} href={link}>{text}</a>
<a className={className} href={link}>
{text || children}
</a>
);
}

return (
<button type="button" className={className} onClick={onClick}>{text}</button>
<button type="button" className={className} onClick={onClick}>
{text}
</button>
);
}
Loading
Loading