report button
This commit is contained in:
@@ -0,0 +1,65 @@
|
|||||||
|
import { useState, useEffect, useRef, useCallback } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { IconFlagFilled } from '@tabler/icons-react'
|
||||||
|
import Select from './Select'
|
||||||
|
import * as api from '../../api'
|
||||||
|
import Tooltip from './Tooltip'
|
||||||
|
|
||||||
|
export default function ReportButton({ contentType, contentId }: { contentType: string; contentId: string }) {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const wrapRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
|
const REASONS = [
|
||||||
|
{ value: '', label: t('report.selectReason') },
|
||||||
|
{ value: 'offensive', label: t('report.offensive') },
|
||||||
|
{ value: 'spam', label: t('report.spam') },
|
||||||
|
{ value: 'broken', label: t('report.broken') },
|
||||||
|
{ value: 'other', label: t('report.other') },
|
||||||
|
]
|
||||||
|
const [reported, setReported] = useState(false)
|
||||||
|
const [showForm, setShowForm] = useState(false)
|
||||||
|
const [reason, setReason] = useState<string | number>('')
|
||||||
|
|
||||||
|
const close = useCallback(() => setShowForm(false), [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!showForm) return
|
||||||
|
const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') close() }
|
||||||
|
const onClick = (e: MouseEvent) => {
|
||||||
|
const target = e.target
|
||||||
|
if (wrapRef.current && (!(target instanceof Node) || !wrapRef.current.contains(target))) close()
|
||||||
|
}
|
||||||
|
document.addEventListener('keydown', onKey)
|
||||||
|
document.addEventListener('mousedown', onClick)
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('keydown', onKey)
|
||||||
|
document.removeEventListener('mousedown', onClick)
|
||||||
|
}
|
||||||
|
}, [showForm, close])
|
||||||
|
|
||||||
|
const submit = async () => {
|
||||||
|
try {
|
||||||
|
await api.submitReport(contentType, contentId, String(reason) || 'No reason given')
|
||||||
|
setReported(true)
|
||||||
|
setShowForm(false)
|
||||||
|
} catch { /* ignored */ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reported) return <span className="report-done">{t('common.reported')}</span>
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="report-wrap" ref={wrapRef}>
|
||||||
|
<Tooltip text={t('common.report')}>
|
||||||
|
<button className="report-btn" onClick={(e) => { e.stopPropagation(); setShowForm(!showForm) }}>
|
||||||
|
<IconFlagFilled size={10} />
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
{showForm && (
|
||||||
|
<div className="report-form" onClick={e => e.stopPropagation()}>
|
||||||
|
<Select value={reason} options={REASONS} onChange={setReason} className="report-select" />
|
||||||
|
<button className="btn btn-sm" onClick={submit}>{t('common.submit')}</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user