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
143 lines
4.3 KiB
TypeScript
143 lines
4.3 KiB
TypeScript
import { Modal, Button } from 'react-bootstrap'
|
||
import { MapContainer, Marker, Popup, TileLayer } from 'react-leaflet'
|
||
import { CSSProperties, useState } from 'react'
|
||
|
||
import LineDot from './LineDot'
|
||
import { categoryNames } from '../assets/category'
|
||
import { useBook, useDispose, useRemoveAnnouncement } from '../hooks/api'
|
||
import { Announcement } from '../api/announcement/types'
|
||
import { iconItem } from '../utils/markerIcons'
|
||
import { useId } from '../hooks'
|
||
import SelectDisposalTrashbox from './SelectDisposalTrashbox'
|
||
import { LatLng } from 'leaflet'
|
||
|
||
type AnnouncementDetailsProps = {
|
||
close: () => void,
|
||
refresh: () => void,
|
||
announcement: Announcement,
|
||
}
|
||
|
||
const styles = {
|
||
container: {
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
} as CSSProperties,
|
||
map: {
|
||
width: '100%',
|
||
minHeight: 300,
|
||
} as CSSProperties,
|
||
}
|
||
|
||
const View = ({
|
||
announcement: { name, category, bestBy, description, lat, lng, address, metro },
|
||
}: { announcement: Announcement }) => (
|
||
<>
|
||
<h1>{name}</h1>
|
||
|
||
<span>{categoryNames[category]}</span>
|
||
<span className='m-2'>•</span>{/* dot */}
|
||
<span>Годен до {new Date(bestBy).toLocaleString('ru-RU')}</span>
|
||
|
||
<p className='mb-3'>{description}</p>
|
||
|
||
<MapContainer style={styles.map} center={[lat, lng]} zoom={16} >
|
||
<TileLayer
|
||
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||
url='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
|
||
/>
|
||
|
||
<Marker icon={iconItem} position={[lat, lng]}>
|
||
<Popup>
|
||
{address}
|
||
<br />
|
||
<LineDot station={metro} /> {metro}
|
||
</Popup>
|
||
</Marker>
|
||
</MapContainer>
|
||
</>
|
||
)
|
||
|
||
type ControlProps = {
|
||
closeRefresh: () => void,
|
||
announcement: Announcement,
|
||
showDispose: () => void
|
||
}
|
||
|
||
function Control({
|
||
closeRefresh,
|
||
announcement: { bookedBy, id, userId },
|
||
showDispose
|
||
}: ControlProps) {
|
||
const { handleBook, bookButton } = useBook()
|
||
|
||
const { handleRemove, removeButton } = useRemoveAnnouncement(closeRefresh)
|
||
|
||
const myId = useId()
|
||
|
||
return (
|
||
<>
|
||
<p>Забронировали {bookedBy} чел.</p>
|
||
{(myId === userId) ? (
|
||
<>
|
||
<Button variant='success' onClick={showDispose}>Утилизировать</Button>
|
||
<Button variant='success' onClick={() => void handleRemove(id)} {...removeButton} />
|
||
</>
|
||
) : (
|
||
<Button variant='success' onClick={() => void handleBook(id)} {...bookButton} />
|
||
)}
|
||
</>
|
||
)
|
||
}
|
||
|
||
function AnnouncementDetails({
|
||
close,
|
||
refresh,
|
||
announcement,
|
||
}: AnnouncementDetailsProps) {
|
||
const closeRefresh = () => {
|
||
close()
|
||
refresh()
|
||
}
|
||
|
||
const [disposeShow, setDisposeShow] = useState(false)
|
||
|
||
return (
|
||
<div
|
||
className='modal'
|
||
style={styles.container}
|
||
>
|
||
<Modal.Dialog centered className='modal-dialog'>
|
||
<Modal.Header closeButton onHide={close}>
|
||
<Modal.Title>
|
||
Подробнее
|
||
</Modal.Title>
|
||
</Modal.Header>
|
||
|
||
<Modal.Body>
|
||
<View announcement={announcement} />
|
||
</Modal.Body>
|
||
|
||
<Modal.Footer>
|
||
<Control closeRefresh={closeRefresh} showDispose={() => setDisposeShow(true)} announcement={announcement} />
|
||
</Modal.Footer>
|
||
</Modal.Dialog>
|
||
<Modal centered show={disposeShow} onHide={() => setDisposeShow(false)} style={{ zIndex: 100000 }}>
|
||
<Modal.Header closeButton>
|
||
<Modal.Title>
|
||
Утилизация
|
||
</Modal.Title>
|
||
</Modal.Header>
|
||
<SelectDisposalTrashbox
|
||
annId={announcement.id}
|
||
category={announcement.category}
|
||
address={new LatLng(announcement.lat, announcement.lng)}
|
||
closeRefresh={closeRefresh}
|
||
/>
|
||
</Modal>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default AnnouncementDetails
|