Skip to content

Commit

Permalink
don't work fully
Browse files Browse the repository at this point in the history
  • Loading branch information
levil664 committed Sep 7, 2023
1 parent 6bf96f3 commit 516bf53
Show file tree
Hide file tree
Showing 12 changed files with 4,238 additions and 32 deletions.
4 changes: 2 additions & 2 deletions apps/schools/domains/circle/components/addressForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import MapComponent from '@domains/circle/components/map'

const AddressForm = () => {
return (
<div>
<div className={styles.container}>
<Typography.Title level={1}>Добавление кружка</Typography.Title>
<Typography.Title level={3}>
<Typography.Title level={4}>
Выберите на карте расположение кружка, для этого: выберете город, найдите нужную улицу, дом и нажмите на
него
</Typography.Title>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.container {
width: 100%;
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
font-style: normal;
font-weight: 400;
line-height: 22px;

:global {
.ant-select-selector {
border-radius: 12px 0 0 12px !important;
}
}
}

.complexInputContainer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Select } from '@domains/common/components/select'
import { handleSubmitForm } from '../../handlers/circleCreate'
import { useCreateCircleMutation } from '../../redux/circleApi'
import { getVarsForAddressColumn } from '@domains/common/utils/geo'
import AddressForm from "@domains/circle/components/addressForm";

export const CreateCircleForm = () => {
const validators = useCreateCircleFormValidators()
Expand Down Expand Up @@ -138,6 +139,7 @@ export const CreateCircleForm = () => {
Родители смогут увидеть ваш кружок с помощью карты и узнать информацию о нём!
</Typography.Title>
</div>
<AddressForm/>
</Row>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
font-style: normal;
font-weight: 400;
line-height: 22px;

:global {
.ant-select-selector {
border-radius: 12px 0 0 12px !important;
}
}
}

.complexInputContainer {
Expand Down
17 changes: 17 additions & 0 deletions apps/schools/domains/circle/components/map/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useMemo } from 'react'
import { ValidatorsMap } from '@domains/common/redux/interfaces'
import { PleaseSelectOneOfOptionsMsg } from "@domains/user/components/auth/constants/message";

export const useAddressFormValidators = () => {
return useMemo<ValidatorsMap>(() => {
return {
city: [
{
required: true,
message: PleaseSelectOneOfOptionsMsg,
}
],
}
}, [this])
}

172 changes: 148 additions & 24 deletions apps/schools/domains/circle/components/map/index.tsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,171 @@
import React from 'react'
import { YMaps, Map, ZoomControl, Placemark } from '@pbe/react-yandex-maps'
import { Form } from 'antd'
import React, { Ref, useCallback, useEffect } from 'react'
import { YMaps, Map } from '@pbe/react-yandex-maps'
import { Form, Typography } from 'antd'
import styles from './styles/styles.module.scss'
import classnames from 'classnames'
import cities from '@public/cities.json'
import getConfig from 'next/config'
import { Input } from '@domains/common/components/input'
import { Select } from '@domains/common/components/select'


const points = [
{
coordinates: [56.841561, 60.615063],
content: 'Кружок1',
},
]

const MapComponent = () => {
const {
publicRuntimeConfig: {
YandexMapApiKey: { key: YandexApiKey },
},
} = getConfig()

const [form] = Form.useForm()
const ymaps = React.useRef(null)
const placemarkRef = React.useRef(null)
const mapRef = React.useRef<any>(null)
const setMapRef = useCallback((instance: Ref<any>) => {
mapRef.current = instance
}, [])
const [address, setAddress] = React.useState('')
const [mapState, setMapState] = React.useState({
center: [56.838926, 60.605702],
zoom: 10,
})

const createPlacemark = (coords) => {
return new ymaps.current.Placemark(
coords,
{
iconCaption: 'loading..',
},
{
preset: 'islands#violetDotIconWithCaption',
draggable: true,
},
)
}

const getAddress = (coords) => {
placemarkRef.current.properties.set('iconCaption', 'loading..')
ymaps.current.geocode(coords).then((res) => {
const firstGeoObject = res.geoObjects.get(0)

const accurateAddress = firstGeoObject.getAddressLine()

const newAddress = [
firstGeoObject.getLocalities().length
? firstGeoObject.getLocalities()
: firstGeoObject.getAdministrativeAreas(),
firstGeoObject.getThoroughfare() || firstGeoObject.getPremise(),
]
.filter(Boolean)
.join(', ')

setAddress(newAddress)

if ((accurateAddress.match(/,/g) || []).length === 3) {
const commaIndex = accurateAddress.indexOf(',')
const currentCity = accurateAddress.substring(commaIndex + 1, accurateAddress.indexOf(',', commaIndex + 1)).trim();
const newAddress = accurateAddress.substring(accurateAddress.indexOf(',', commaIndex + 1) + 1).trim();
form.setFieldValue('address', newAddress);
form.setFieldValue('city', currentCity);
} else {
const commaIndex = address.indexOf(',')
const currentCity = address.slice(0, commaIndex).trim()
const newAddress = address.slice(commaIndex + 1).trim()
form.setFieldValue('address', newAddress)
form.setFieldValue('city', currentCity)
}

placemarkRef.current.properties.set({
iconCaption: newAddress,
balloonContent: firstGeoObject.getAddressLine(),
})
})
}

const style: React.CSSProperties = {
position: 'relative',
width: '100%',
height: '600px',
}

const onMapClick = (e) => {
const coords = e.get('coords')

if (placemarkRef.current) {
placemarkRef.current.geometry.setCoordinates(coords)
} else {
placemarkRef.current = createPlacemark(coords)
mapRef.current.geoObjects.add(placemarkRef.current)
placemarkRef.current.events.add('dragend', function () {
getAddress(placemarkRef.current.geometry.getCoordinates())
})
}
getAddress(coords)
}

const handleCityChange = (e) => {
const selectedCity = cities.find(city => city.name === e);

if (selectedCity) {
setMapState({
center: selectedCity.coordinates,
zoom: 12,
});
form.setFieldValue('city', selectedCity.name);
} else {
console.error('Город не найден');
}
}

return (
<YMaps>
<YMaps query={{ apikey: YandexApiKey }}>
<div>
{/* Центр Екатеринбурга center: [56.8519, 60.6122], сейчас стоит Тургенева 4*/}
<Map style={style} defaultState={{ center: [56.841561, 60.615063], zoom: 15 }}>
<Form form={form} className={styles.form} colon={false} requiredMark={false} layout='vertical'>
<Form.Item required={true} className={styles.label}>
<Input required={true} placeholder='Введите название кружка' />
<Map
style={style}
modules={['Placemark', 'geocode', 'geoObject.addon.balloon']}
instanceRef={mapRef}
onLoad={(ymapsInstance) => (ymaps.current = ymapsInstance)}
onClick={onMapClick}
state={mapState}
>
<Form form={form} initialValues={{ address: address }} className={styles.form} layout='vertical'>
<Typography.Title level={1}>Адрес</Typography.Title>
<Typography.Title level={5}>
Добавьте на карте место, где будут проходить занятия
</Typography.Title>
<Form.Item
label={<span>Город</span>}
name={'city'}
initialValue={cities[290].name}
className={classnames(styles.label, styles.address)}
>
<Select
customType={'selectInput'}
placeholder='Выберите адрес кружка'
className={styles.select}
options={cities.map((city: any) => {
return {
value: city.name,
label: city.name,
}
})}
onChange={handleCityChange}
/>
</Form.Item>

<Form.Item
label={'Адрес'}
name={'address'}
className={classnames(styles.label, styles.room)}
initialValue={address}
>
<Input className={styles.input} disabled={true} value={address} />
</Form.Item>
</Form>
<ZoomControl options={{ size: 'small', position: { bottom: 100, right: 10 } }} />
{points.map((point, index) => (
<Placemark
geometry={point.coordinates}
key={index}
properties={{ iconCaption: point.content }}
/>
))}
</Map>
</div>
</YMaps>
)
}

export default MapComponent
export default MapComponent;
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
@import '@domains/common/components/styles/abstracts/_variables';
@import '@domains/common/components/styles/abstracts/_colors.scss';

.form {
position: absolute;
top: 30px;
left: 30px;
width: 300px;
height: 300px;
border: 1px solid rgba(0, 0, 0, 0.20);
background-color: white;
z-index: 1; /* Чтобы форма находилась выше карты */
width: 364px;
height: 350px;
padding: 30px;
border-radius: 16px;
background: $color-white;
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.15);
z-index: $z-foreground;
}

.label {
font-family: 'Roboto', sans-serif;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 22px;
}

.requiredMark {
color: $color-required-mark;
}

.select {
border-radius: 12px !important;
}
1 change: 1 addition & 0 deletions apps/schools/domains/common/components/input/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const Input: React.FC<CustomInputProps> = (props) => {
<BaseInput
className={classNames(defaultStyles.input, className)}
placeholder={placeholder}
disabled={disabled}
data-testid='input'
{...restProps}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
padding-top: 4px !important;
width: 100% !important;
height: 40px !important;
border-radius: 12px 0 0 12px !important;
border-radius: 12px !important;
}

.ant-select-selection-search-input {
Expand Down
2 changes: 2 additions & 0 deletions apps/schools/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ const withPlugins = require('next-compose-plugins')
const { getObjectFromEnv } = require('./env.config')

const HelpRequisites = getObjectFromEnv('HELP_REQUISITES')
const YandexMapApiKey = getObjectFromEnv('YANDEX_MAP_apiKey')

module.exports = withPlugins([], {
publicRuntimeConfig: {
HelpRequisites,
YandexMapApiKey,
},
})
Loading

0 comments on commit 516bf53

Please sign in to comment.