Added users rating in announcement details

This commit is contained in:
2023-08-07 14:08:51 +03:00
parent b93ab9794d
commit d2a3393a11
11 changed files with 231 additions and 5 deletions

View File

@ -1,15 +1,16 @@
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 Rating from './Rating'
import { categoryNames } from '../assets/category'
import { useBook, useDispose, useRemoveAnnouncement } from '../hooks/api'
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 { LatLng } from 'leaflet'
type AnnouncementDetailsProps = {
close: () => void,
@ -30,7 +31,7 @@ const styles = {
}
const View = ({
announcement: { name, category, bestBy, description, lat, lng, address, metro },
announcement: { name, category, bestBy, description, lat, lng, address, metro, userId },
}: { announcement: Announcement }) => (
<>
<h1>{name}</h1>
@ -39,7 +40,9 @@ const View = ({
<span className='m-2'>&#x2022;</span>{/* dot */}
<span>Годен до {new Date(bestBy).toLocaleString('ru-RU')}</span>
<p className='mb-3'>{description}</p>
<p className='mb-0'>{description}</p>
<Rating userId={userId} className='mb-3' />
<MapContainer style={styles.map} center={[lat, lng]} zoom={16} >
<TileLayer
@ -67,7 +70,7 @@ type ControlProps = {
function Control({
closeRefresh,
announcement: { bookedBy, id, userId },
showDispose
showDispose,
}: ControlProps) {
const { handleBook, bookButton } = useBook()

View File

@ -0,0 +1,78 @@
import { useState } from 'react'
import { gotError, gotResponse } from '../hooks/useFetch'
import { useUserRating, useSendRate } from '../hooks/api'
import styles from '../styles/Rating.module.css'
type StarProps = {
filled: boolean,
selected: boolean,
setMyRate: () => void,
sendMyRate: () => void,
}
function Star({ filled, selected, setMyRate, sendMyRate }: StarProps) {
return (
<button
className={`${styles.star} ${filled ? styles.starFilled : ''} ${selected ? styles.starSelected : ''}`}
onMouseEnter={setMyRate}
onFocus={setMyRate}
onClick={sendMyRate}
>&#9733;</button>
)
}
type RatingProps = {
userId: number,
className: string | undefined,
}
function Rating({ userId, className }: RatingProps) {
const rating = useUserRating(userId)
const [myRate, setMyRate] = useState(0)
const { doSendRate } = useSendRate()
async function sendMyRate() {
const res = await doSendRate(myRate)
if (res) {
rating.refetch()
}
}
return (
<p className={className}>
Рейтинг пользователя:{' '}
{gotResponse(rating) ? (
gotError(rating) ? (
<span className='text-danger'>{rating.error}</span>
) : (
<span
className={styles.starContainer}
onMouseLeave={() => setMyRate(0)}
>
{...Array(5).fill(5).map(
(_, i) =>
<Star
key={i}
filled={i < rating.data}
selected={i < myRate}
setMyRate={() => setMyRate(i + 1)}
sendMyRate={() => void sendMyRate()}
/>
)}
</span>
)
) : (
<span>Загрузка...</span>
)
}
</p>
)
}
export default Rating

View File

@ -14,3 +14,4 @@ export { default as Points } from './Points'
export { default as SignOut } from './SignOut'
export { default as Poetry } from './Poetry'
export { default as SelectDisposalTrashbox } from './SelectDisposalTrashbox'
export { default as Rating } from './Rating'