porridger/front/src/pages/AddPage.tsx
dm1sh b7bbd937b4
Converted put(api/announcement) to use useSend
Added useSendButtonCaption hook
Related to #19
2023-07-17 12:18:54 +03:00

187 lines
8.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { CSSProperties, FormEventHandler, useState } from 'react'
import { Form, Button, Card } from 'react-bootstrap'
import { MapContainer, TileLayer } from 'react-leaflet'
import { latLng } from 'leaflet'
import { ClickHandler, LocationMarker, TrashboxMarkers } from '../components'
import { useAddAnnouncement, useTrashboxes } from '../hooks/api'
import { categories, categoryNames } from '../assets/category'
import { stations, lines, lineNames } from '../assets/metro'
import { fallbackError, gotError } from '../hooks/useFetch'
import { useOsmAddresses } from '../hooks/api'
const styles = {
modal: {
height: 'calc(100vh - 3rem)',
} as CSSProperties,
body: {
overflowY: 'auto',
} as CSSProperties,
map: {
width: '100%',
height: 400,
} as CSSProperties,
}
function AddPage() {
const [addressPosition, setAddressPosition] = useState(latLng(59.972, 30.3227))
const trashboxes = useTrashboxes(addressPosition)
const [selectedTrashbox, setSelectedTrashbox] = useState({ index: -1, category: '' })
const address = useOsmAddresses(addressPosition)
const { doSend, button } = useAddAnnouncement()
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())
void doSend(formData)
}
return (
<Card className='m-4' style={styles.modal}>
<Card.Body style={styles.body} >
<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='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
/>
<LocationMarker
address={fallbackError(address)}
position={addressPosition}
setPosition={setAddressPosition}
/>
<ClickHandler
setPosition={setAddressPosition}
/>
</MapContainer>
</div>
<p>Адрес: {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>
<Form.Group className='mb-3' controlId='trashbox'>
<Form.Label>Пункт сбора мусора</Form.Label>
<div className='mb-3'>
{trashboxes.loading
? (
<div style={styles.map}>
<p>Загрузка...</p>
</div>
) : (
gotError(trashboxes) ? (
<p
style={styles.map}
className='text-danger'
>{trashboxes.error}</p>
) : (
<MapContainer
scrollWheelZoom={false}
style={styles.map}
center={addressPosition}
zoom={13}
className=''
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
/>
<TrashboxMarkers
trashboxes={trashboxes.data}
selectTrashbox={setSelectedTrashbox}
/>
</MapContainer>
)
)
}
</div>
{!gotError(trashboxes) && selectedTrashbox.index > -1 ? (
<p>Выбран пункт сбора мусора на {
trashboxes.data[selectedTrashbox.index].Address
} с категорией {selectedTrashbox.category}</p>
) : (
<p>Выберите пунк сбора мусора и категорию</p>
)}
</Form.Group>
<Button variant='success' type='submit' {...button} />
</Form>
</Card.Body>
</Card>
)
}
export default AddPage