porridger/front/src/components/AnnouncementDetails.tsx
dm1sh d9925647c6
Refactored Rating component
Separated annDetails, added to userPage, made actually operating
2023-08-08 19:26:37 +03:00

152 lines
4.5 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 { LatLng } from 'leaflet'
import LineDot from './LineDot'
import { categoryNames } from '../assets/category'
import { useBook, useRemoveAnnouncement } from '../hooks/api'
import { Announcement } from '../api/announcement/types'
import { iconItem } from '../utils/markerIcons'
import { useId } from '../hooks'
import SelectDisposalTrashbox from './SelectDisposalTrashbox'
import StarRating from './StarRating'
const styles = {
container: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
} as CSSProperties,
map: {
width: '100%',
minHeight: 300,
} as CSSProperties,
}
type ViewProps = {
announcement: Announcement,
}
const View = ({
announcement: { name, category, bestBy, description, lat, lng, address, metro, userId },
}: ViewProps) => (
<>
<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-0'>{description}</p>
<p className='mb-3'>
Рейтинг пользователя: <StarRating dynamic userId={userId} />
</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 + (bookButton.disabled ? 1 : 0)} чел.</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} />
)}
</>
)
}
type AnnouncementDetailsProps = {
close: () => void,
refresh: () => void,
announcement: Announcement,
}
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