You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
filepizza/src/components/ReportTermsViolationButton.tsx

143 lines
5.0 KiB
TypeScript

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

'use client'
import { JSX } from 'react'
import { useWebRTCPeer } from './WebRTCProvider'
import { useCallback, useState } from 'react'
import { useMutation } from '@tanstack/react-query'
import CancelButton from './CancelButton'
export default function ReportTermsViolationButton({
uploaderPeerID,
slug,
}: {
uploaderPeerID: string
slug: string
}): JSX.Element {
const { peer } = useWebRTCPeer()
const [showModal, setShowModal] = useState(false)
const [isReporting, setIsReporting] = useState(false)
const reportMutation = useMutation({
mutationFn: async () => {
const response = await fetch(`/api/destroy`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ slug }),
})
if (!response.ok) {
throw new Error('Failed to report violation')
}
return response.json()
},
})
const handleReport = useCallback(() => {
try {
// Destroy the channel so no further downloads can be made.
setIsReporting(true)
reportMutation.mutate()
// Send a report message to the uploader to hard-redirect them to the reported page.
// The uploader will broadcast a report message to all connections, which will hard-redirect all downloaders to the reported page.
const conn = peer.connect(uploaderPeerID, {
metadata: { type: 'report' },
})
// Set a timeout to redirect after 2 seconds even if connection doesn't open
const timeout = setTimeout(() => {
conn.close()
window.location.href = '/reported'
}, 2000)
conn.on('open', () => {
clearTimeout(timeout)
conn.close()
window.location.href = '/reported'
})
} catch (error) {
console.error('Failed to report violation', error)
setIsReporting(false)
}
}, [peer, uploaderPeerID])
return (
<>
<div className="flex justify-center">
<button
onClick={() => setShowModal(true)}
className="text-sm text-red-600 dark:text-red-400 hover:underline transition-colors duration-200"
aria-label="Report terms violation"
>
Report suspicious pizza delivery
</button>
</div>
{showModal && (
<div
className="fixed inset-0 bg-black/50 flex items-center justify-center p-4 z-50"
role="dialog"
aria-modal="true"
aria-labelledby="modal-title"
onClick={() => setShowModal(false)}
>
<div
className="bg-stone-50 dark:bg-stone-900 border border-stone-200 dark:border-stone-700 rounded-lg p-8 max-w-md w-full shadow-lg"
onClick={(e) => e.stopPropagation()}
>
<h2
id="modal-title"
className="text-xl font-bold mb-4 text-stone-900 dark:text-stone-50"
>
Found a suspicious delivery?
</h2>
<div className="space-y-4 text-stone-700 dark:text-stone-300">
<p>
Before reporting this delivery, please note our FilePizza terms:
</p>
<ul className="list-none space-y-3">
<li className="flex items-start gap-3 px-4 py-2 rounded-lg bg-stone-100 dark:bg-stone-800">
<span className="text-base"></span>
<span className="text-sm">
Only upload files you have the right to share
</span>
</li>
<li className="flex items-start gap-3 px-4 py-2 rounded-lg bg-stone-100 dark:bg-stone-800">
<span className="text-base">🔒</span>
<span className="text-sm">
Share download links only with known recipients
</span>
</li>
<li className="flex items-start gap-3 px-4 py-2 rounded-lg bg-stone-100 dark:bg-stone-800">
<span className="text-base"></span>
<span className="text-sm">
No illegal or harmful content allowed
</span>
</li>
</ul>
<p>
If you've spotted a violation of these terms, click Report to
halt its delivery.
</p>
</div>
<div className="mt-6 flex justify-end space-x-4">
<CancelButton onClick={() => setShowModal(false)} />
<button
disabled={isReporting}
onClick={handleReport}
className={`px-4 py-2 bg-linear-to-b from-red-500 to-red-600 text-white rounded-md border border-red-600 shadow-sm text-shadow disabled:opacity-50 disabled:cursor-not-allowed enabled:hover:from-red-500 enabled:hover:to-red-700 enabled:hover:shadow-md transition-all duration-200`}
aria-label="Confirm report"
>
{isReporting ? 'Reporting...' : 'Report'}
</button>
</div>
</div>
</div>
)}
</>
)
}