"use client"; import type { HTMLAttributes } from "react"; import { useEffect, useId, useRef, useState } from "react"; import { useI18n } from "@/translations/provider"; import Button from "./button"; const EXIT_ANIMATION_MS = 220; export type DismissReasonSheetProps = Omit< HTMLAttributes, "title" | "onSubmit" > & { closeOnOutside?: boolean; onClose?: () => void; onSubmit?: (value: string) => void; }; export function DismissReasonSheet({ closeOnOutside = true, onClose, onSubmit, className, ...props }: DismissReasonSheetProps) { const { dictionary: t } = useI18n(); const options = [ t["Not a good personal fit"], t["No mutual interest"], t["Different expectations"], t["No connection felt"], t["Location not suitable"], t["Other reasons"] ]; const groupId = useId(); const [isVisible, setIsVisible] = useState(true); const [isEntering, setIsEntering] = useState(true); const [isClosing, setIsClosing] = useState(false); const [selectedReasons, setSelectedReasons] = useState([]); const [reasonText, setReasonText] = useState(""); const textareaRef = useRef(null); useEffect(() => { const otherReason = options[options.length - 1]; if (selectedReasons.includes(otherReason)) { const timeoutId = setTimeout(() => { textareaRef.current?.scrollIntoView({ behavior: "smooth", block: "nearest", }); }, 100); return () => clearTimeout(timeoutId); } }, [selectedReasons, options]); const closeSheet = () => { if (isClosing) { return; } setIsClosing(true); }; useEffect(() => { const frameId = window.requestAnimationFrame(() => { setIsEntering(false); }); return () => { window.cancelAnimationFrame(frameId); }; }, []); useEffect(() => { if (!isVisible) { return; } const previousBodyOverflow = document.body.style.overflow; const previousHtmlOverflow = document.documentElement.style.overflow; document.body.style.overflow = "hidden"; document.documentElement.style.overflow = "hidden"; return () => { document.body.style.overflow = previousBodyOverflow; document.documentElement.style.overflow = previousHtmlOverflow; }; }, [isVisible]); useEffect(() => { if (!isClosing) { return; } const timeoutId = window.setTimeout(() => { setIsVisible(false); onClose?.(); }, EXIT_ANIMATION_MS); return () => { window.clearTimeout(timeoutId); }; }, [isClosing, onClose]); if (!isVisible) { return null; } return ( { if (closeOnOutside && event.target === event.currentTarget) { closeSheet(); } }} onKeyDown={(event) => { if ( closeOnOutside && event.target === event.currentTarget && (event.key === "Escape" || event.key === "Enter" || event.key === " ") ) { event.preventDefault(); closeSheet(); } }} > {t["Dismiss reasons"]} {t["Please provide the full reason for rejecting the submitted item"]} {t["Dismiss reasons"]} {options.map((option) => { const checked = selectedReasons.includes(option); const showTextArea = option === options[options.length - 1]; return ( { setSelectedReasons((prev) => prev.includes(option) ? prev.filter((r) => r !== option) : [...prev, option], ); }} > {checked ? ( ) : null} {option} {checked && showTextArea ? ( setReasonText(event.target.value) } /> ) : null} ); })} { const activeReasons = selectedReasons.map((r) => { if (r === options[options.length - 1]) { return reasonText ? `${r}: ${reasonText}` : r; } return r; }); onSubmit?.(activeReasons.join("\n")); closeSheet(); }} > {t["Decline"]} ); } export default DismissReasonSheet;
{t["Please provide the full reason for rejecting the submitted item"]}