Improved StarRating indication of rated mark
This commit is contained in:
parent
9937708da5
commit
6478b45301
@ -25,10 +25,12 @@ const styles = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ViewProps = {
|
type ViewProps = {
|
||||||
|
myId: number,
|
||||||
announcement: Announcement,
|
announcement: Announcement,
|
||||||
}
|
}
|
||||||
|
|
||||||
const View = ({
|
const View = ({
|
||||||
|
myId,
|
||||||
announcement: { name, category, bestBy, description, lat, lng, address, metro, userId },
|
announcement: { name, category, bestBy, description, lat, lng, address, metro, userId },
|
||||||
}: ViewProps) => (
|
}: ViewProps) => (
|
||||||
<>
|
<>
|
||||||
@ -41,7 +43,7 @@ const View = ({
|
|||||||
<p className='mb-0'>{description}</p>
|
<p className='mb-0'>{description}</p>
|
||||||
|
|
||||||
<p className='mb-3'>
|
<p className='mb-3'>
|
||||||
Рейтинг пользователя: <StarRating dynamic userId={userId} />
|
Рейтинг пользователя: <StarRating dynamic={myId !== userId} userId={userId} />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<MapContainer style={styles.map} center={[lat, lng]} zoom={16} >
|
<MapContainer style={styles.map} center={[lat, lng]} zoom={16} >
|
||||||
@ -62,12 +64,14 @@ const View = ({
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ControlProps = {
|
type ControlProps = {
|
||||||
|
myId: number,
|
||||||
closeRefresh: () => void,
|
closeRefresh: () => void,
|
||||||
announcement: Announcement,
|
announcement: Announcement,
|
||||||
showDispose: () => void
|
showDispose: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
function Control({
|
function Control({
|
||||||
|
myId,
|
||||||
closeRefresh,
|
closeRefresh,
|
||||||
announcement: { bookedBy, id, userId },
|
announcement: { bookedBy, id, userId },
|
||||||
showDispose,
|
showDispose,
|
||||||
@ -76,8 +80,6 @@ function Control({
|
|||||||
|
|
||||||
const { handleRemove, removeButton } = useRemoveAnnouncement(closeRefresh)
|
const { handleRemove, removeButton } = useRemoveAnnouncement(closeRefresh)
|
||||||
|
|
||||||
const myId = useId()
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<p>Забронировали {bookedBy + (bookButton.disabled ? 1 : 0)} чел.</p>
|
<p>Забронировали {bookedBy + (bookButton.disabled ? 1 : 0)} чел.</p>
|
||||||
@ -111,6 +113,8 @@ function AnnouncementDetails({
|
|||||||
|
|
||||||
const [disposeShow, setDisposeShow] = useState(false)
|
const [disposeShow, setDisposeShow] = useState(false)
|
||||||
|
|
||||||
|
const myId = useId()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='modal'
|
className='modal'
|
||||||
@ -124,11 +128,16 @@ function AnnouncementDetails({
|
|||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
|
|
||||||
<Modal.Body>
|
<Modal.Body>
|
||||||
<View announcement={announcement} />
|
<View myId={myId} announcement={announcement} />
|
||||||
</Modal.Body>
|
</Modal.Body>
|
||||||
|
|
||||||
<Modal.Footer>
|
<Modal.Footer>
|
||||||
<Control closeRefresh={closeRefresh} showDispose={() => setDisposeShow(true)} announcement={announcement} />
|
<Control
|
||||||
|
myId={myId}
|
||||||
|
closeRefresh={closeRefresh}
|
||||||
|
showDispose={() => setDisposeShow(true)}
|
||||||
|
announcement={announcement}
|
||||||
|
/>
|
||||||
</Modal.Footer>
|
</Modal.Footer>
|
||||||
</Modal.Dialog>
|
</Modal.Dialog>
|
||||||
<Modal centered show={disposeShow} onHide={() => setDisposeShow(false)} style={{ zIndex: 100000 }}>
|
<Modal centered show={disposeShow} onHide={() => setDisposeShow(false)} style={{ zIndex: 100000 }}>
|
||||||
|
@ -8,18 +8,17 @@ import styles from '../styles/StarRating.module.css'
|
|||||||
type StarProps = {
|
type StarProps = {
|
||||||
filled: boolean,
|
filled: boolean,
|
||||||
selected: boolean,
|
selected: boolean,
|
||||||
setMyRate?: () => void,
|
selectRate?: () => void,
|
||||||
sendMyRate?: () => void,
|
sendMyRate?: () => void,
|
||||||
disabled: boolean
|
disabled: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
function Star({ filled, selected, setMyRate, sendMyRate, disabled }: StarProps) {
|
function Star({ filled, selected, selectRate, disabled }: StarProps) {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
className={`${styles.star} ${filled ? styles.starFilled : ''} ${selected ? styles.starSelected : ''}`}
|
className={`${styles.star} ${filled ? styles.starFilled : ''} ${selected ? styles.starSelected : ''}`}
|
||||||
onMouseEnter={setMyRate}
|
onMouseEnter={selectRate}
|
||||||
onFocus={setMyRate}
|
onFocus={selectRate}
|
||||||
onClick={sendMyRate}
|
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
>★</button> // star
|
>★</button> // star
|
||||||
)
|
)
|
||||||
@ -28,21 +27,23 @@ function Star({ filled, selected, setMyRate, sendMyRate, disabled }: StarProps)
|
|||||||
type StarRatingProps = {
|
type StarRatingProps = {
|
||||||
userId: number,
|
userId: number,
|
||||||
dynamic?: boolean,
|
dynamic?: boolean,
|
||||||
style?: React.CSSProperties,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function StarRating({ userId, dynamic = false }: StarRatingProps) {
|
function StarRating({ userId, dynamic = false }: StarRatingProps) {
|
||||||
const rating = useUserRating(userId)
|
const rating = useUserRating(userId)
|
||||||
|
|
||||||
|
const [selectedRate, setSelectedRate] = useState(0)
|
||||||
const [myRate, setMyRate] = useState(0)
|
const [myRate, setMyRate] = useState(0)
|
||||||
|
const rated = myRate > 0
|
||||||
|
|
||||||
const { doSendRate } = useSendRate()
|
const { doSendRate } = useSendRate()
|
||||||
|
|
||||||
async function sendMyRate() {
|
async function sendMyRate() {
|
||||||
const res = await doSendRate(myRate, userId)
|
const res = await doSendRate(selectedRate, userId)
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
rating.refetch()
|
rating.refetch()
|
||||||
|
setMyRate(selectedRate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,15 +60,30 @@ function StarRating({ userId, dynamic = false }: StarRatingProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className={styles.starContainer} onMouseLeave={() => setMyRate(0)}>
|
<span
|
||||||
|
className={styles.starContainer}
|
||||||
|
|
||||||
|
onClick={() => dynamic && !rated && void sendMyRate()}
|
||||||
|
|
||||||
|
onMouseEnter={() => rated && setSelectedRate(myRate)}
|
||||||
|
onMouseLeave={() => setSelectedRate(0)}
|
||||||
|
|
||||||
|
onFocus={() => rated && setSelectedRate(myRate)}
|
||||||
|
onBlur={() => setSelectedRate(0)}
|
||||||
|
|
||||||
|
onTouchStart={() => rated && setSelectedRate(myRate)}
|
||||||
|
onTouchEnd={() => setSelectedRate(0)}
|
||||||
|
|
||||||
|
title={`Пользователи: ${Math.round(rating.data)}\nВы: ${myRate}`}
|
||||||
|
tabIndex={0}
|
||||||
|
>
|
||||||
{...Array(5).fill(5).map((_, i) => (
|
{...Array(5).fill(5).map((_, i) => (
|
||||||
<Star
|
<Star
|
||||||
key={i}
|
key={i}
|
||||||
filled={i < Math.round(rating.data)}
|
filled={i < Math.round(rating.data)}
|
||||||
selected={i < myRate}
|
selected={i < selectedRate}
|
||||||
setMyRate={() => dynamic && setMyRate(i + 1)}
|
selectRate={() => dynamic && !rated && setSelectedRate(i + 1)}
|
||||||
sendMyRate={() => dynamic && void sendMyRate()}
|
disabled={!dynamic || rated}
|
||||||
disabled={!dynamic}
|
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</span >
|
</span >
|
||||||
|
Loading…
x
Reference in New Issue
Block a user