| "use client"; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| import { useEffect } from "react"; |
|
|
| const REVIEW = process.env.NEXT_PUBLIC_REVIEW_MODE === "1"; |
|
|
| export function ContentProtection() { |
| useEffect(() => { |
| if (!REVIEW) return; |
| const stop = (e: Event) => e.preventDefault(); |
| document.addEventListener("contextmenu", stop); |
| document.addEventListener("dragstart", stop); |
| document.addEventListener("copy", stop); |
| document.addEventListener("cut", stop); |
| |
| const onKey = (e: KeyboardEvent) => { |
| const k = e.key.toLowerCase(); |
| const mod = e.ctrlKey || e.metaKey; |
| if ( |
| (mod && ["s", "p", "u", "c", "x"].includes(k)) || |
| k === "f12" || |
| (mod && e.shiftKey && ["i", "j", "c"].includes(k)) |
| ) { |
| e.preventDefault(); |
| e.stopPropagation(); |
| } |
| }; |
| document.addEventListener("keydown", onKey, true); |
| |
| const style = document.createElement("style"); |
| style.textContent = ` |
| img, video, audio, svg, canvas { -webkit-user-drag: none !important; user-select: none !important; -webkit-touch-callout: none !important; } |
| main, article, .protect-noselect { -webkit-user-select: none; -moz-user-select: none; user-select: none; } |
| input, textarea { user-select: text; } /* keep form fields usable */ |
| @media print { html, body { display: none !important; } } |
| `; |
| document.head.appendChild(style); |
| |
| return () => { |
| document.removeEventListener("contextmenu", stop); |
| document.removeEventListener("dragstart", stop); |
| document.removeEventListener("copy", stop); |
| document.removeEventListener("cut", stop); |
| document.removeEventListener("keydown", onKey, true); |
| style.remove(); |
| }; |
| }, []); |
|
|
| if (!REVIEW) return null; |
| const tag = process.env.NEXT_PUBLIC_REVIEW_TAG || "Confidential — Commission Review · do not distribute"; |
| return ( |
| <div aria-hidden="true" className="pointer-events-none fixed inset-0 z-[9999] select-none overflow-hidden"> |
| <div className="absolute inset-0 flex flex-wrap content-around justify-around opacity-[0.06]"> |
| {Array.from({ length: 40 }).map((_, i) => ( |
| <span key={i} className="m-8 -rotate-45 whitespace-nowrap text-xs font-semibold uppercase tracking-widest text-foreground"> |
| {tag} |
| </span> |
| ))} |
| </div> |
| </div> |
| ); |
| } |
|
|