porridger/front/src/components/AnnouncementDetails.tsx
dm1sh b93ab9794d
Added announcement disposal:
Added ann details button
Added modal shown on its click
Moved trashbox selection there
Added trashboxes mock while testing in restricted area
2023-08-01 18:23:56 +03:00

143 lines
4.3 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 { 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'>&#x2022;</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='&copy; <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