forked from polka_billy/porridger
Added ann details button Added modal shown on its click Moved trashbox selection there Added trashboxes mock while testing in restricted area
144 lines
6.0 KiB
TypeScript
144 lines
6.0 KiB
TypeScript
import { CSSProperties, FormEventHandler, useEffect, useState } from 'react'
|
||
import { Form, Button } from 'react-bootstrap'
|
||
import { MapContainer, TileLayer } from 'react-leaflet'
|
||
import { latLng } from 'leaflet'
|
||
import { useNavigate } from 'react-router-dom'
|
||
|
||
import { ClickHandler, LocationMarker } from '../components'
|
||
import { useAddAnnouncement } from '../hooks/api'
|
||
import { categories, categoryNames } from '../assets/category'
|
||
import { stations, lines, lineNames } from '../assets/metro'
|
||
import { fallbackError, gotResponse } from '../hooks/useFetch'
|
||
import { useOsmAddresses } from '../hooks/api'
|
||
import CardLayout from '../components/CardLayout'
|
||
|
||
const styles = {
|
||
map: {
|
||
width: '100%',
|
||
height: 400,
|
||
} as CSSProperties,
|
||
}
|
||
|
||
function AddPage() {
|
||
const [addressPosition, setAddressPosition] = useState(latLng(59.972, 30.3227))
|
||
|
||
const address = useOsmAddresses(addressPosition)
|
||
|
||
const { handleAdd, addButton } = useAddAnnouncement()
|
||
|
||
const navigate = useNavigate()
|
||
|
||
const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => {
|
||
event.preventDefault()
|
||
event.stopPropagation()
|
||
|
||
const formData = new FormData(event.currentTarget)
|
||
|
||
formData.append('latitude', addressPosition.lat.toString())
|
||
formData.append('longtitude', addressPosition.lng.toString())
|
||
formData.append('address', address.data || '') // if address.error
|
||
formData.set('bestBy', new Date((formData.get('bestBy') as number | null) || 0).getTime().toString())
|
||
|
||
handleAdd(formData)
|
||
}
|
||
|
||
useEffect(() => {
|
||
if (addButton.children === 'Опубликовано') {
|
||
navigate('/')
|
||
}
|
||
}, [addButton.children, navigate])
|
||
|
||
return (
|
||
<CardLayout text='Опубликовать объявление'>
|
||
<Form onSubmit={handleSubmit}>
|
||
<Form.Group className='mb-3' controlId='name'>
|
||
<Form.Label>Заголовок объявления</Form.Label>
|
||
<Form.Control type='text' required name='name' />
|
||
</Form.Group>
|
||
|
||
<Form.Group className='mb-3' controlId='category'>
|
||
<Form.Label>Категория</Form.Label>
|
||
<Form.Select required name='category'>
|
||
<option value='' hidden>
|
||
Выберите категорию
|
||
</option>
|
||
{categories.map(category =>
|
||
<option key={category} value={category}>{categoryNames[category]}</option>
|
||
)}
|
||
</Form.Select>
|
||
</Form.Group>
|
||
|
||
<Form.Group className='mb-3' controlId='bestBy'>
|
||
<Form.Label>Срок годности</Form.Label>
|
||
<Form.Control type='date' required name='bestBy' />
|
||
</Form.Group>
|
||
|
||
<Form.Group className='mb-3' controlId='address'>
|
||
<Form.Label>Адрес выдачи</Form.Label>
|
||
<div className='mb-3'>
|
||
<MapContainer
|
||
scrollWheelZoom={false}
|
||
style={styles.map}
|
||
center={addressPosition}
|
||
zoom={13}
|
||
>
|
||
<TileLayer
|
||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||
url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
|
||
/>
|
||
{gotResponse(address) && <LocationMarker
|
||
address={fallbackError(address)}
|
||
position={addressPosition}
|
||
setPosition={setAddressPosition}
|
||
/>}
|
||
|
||
<ClickHandler
|
||
setPosition={setAddressPosition}
|
||
/>
|
||
</MapContainer>
|
||
</div>
|
||
<p>Адрес: {gotResponse(address) ? fallbackError(address) : 'Загрузка...'}</p>
|
||
</Form.Group>
|
||
|
||
<Form.Group className='mb-3' controlId='description'>
|
||
<Form.Label>Описание</Form.Label>
|
||
<Form.Control as='textarea' name='description' rows={3} placeholder='Укажите свои контакты, а так же, когда вам будет удобно передать продукт' />
|
||
</Form.Group>
|
||
|
||
<Form.Group className='mb-3' controlId='src'>
|
||
<Form.Label>Иллюстрация (фото или видео)</Form.Label>
|
||
<Form.Control
|
||
type='file'
|
||
name='src'
|
||
accept='video/mp4,video/mkv, video/x-m4v,video/*, image/*'
|
||
capture='environment'
|
||
/>
|
||
</Form.Group>
|
||
|
||
<Form.Group className='mb-3' controlId='metro'>
|
||
<Form.Label>
|
||
Станция метро
|
||
</Form.Label>
|
||
<Form.Select name='metro'>
|
||
<option value=''>
|
||
Укажите ближайщую станцию метро
|
||
</option>
|
||
{lines.map(
|
||
line =>
|
||
<optgroup key={line} label={lineNames[line]}>
|
||
{Array.from(stations[line]).map(metro =>
|
||
<option key={metro} value={metro}>{metro}</option>
|
||
)}
|
||
</optgroup>
|
||
)}
|
||
</Form.Select>
|
||
</Form.Group>
|
||
|
||
<Button variant='success' type='submit' {...addButton} />
|
||
</Form>
|
||
</CardLayout>
|
||
)
|
||
}
|
||
|
||
export default AddPage
|