"use client"; import { useEffect, useId, useMemo, useRef, useState } from "react"; import { useI18n } from "@/translations/provider"; import SwipeButton from "./swipe-button"; const EXIT_ANIMATION_MS = 220; export type FemaleOutcomeSheetProps = { closeOnOutside?: boolean; onClose?: () => void; onSubmit?: (status: "success" | "failure", reason?: string) => void; }; export function FemaleOutcomeSheet({ closeOnOutside = true, onClose, onSubmit, }: FemaleOutcomeSheetProps) { const { dictionary: t } = useI18n(); const groupId = useId(); const [isVisible, setIsVisible] = useState(true); const [isEntering, setIsEntering] = useState(true); const [isClosing, setIsClosing] = useState(false); // Outcome selection state: "ongoing" (Option A) or "canceled" (Option B) const [outcome, setOutcome] = useState<"ongoing" | "canceled">("ongoing"); // Rejection/Cancellation reason states const reasons = useMemo( () => [ t["Not a good personal fit"], t["No mutual interest"], t["Different expectations"], t["No connection felt"], t["Location not suitable"], t["Other reasons"], ], [t], ); const [selectedReasons, setSelectedReasons] = useState([]); const [reasonText, setReasonText] = useState(""); const textareaRef = useRef(null); useEffect(() => { const otherReason = reasons[reasons.length - 1]; if (selectedReasons.includes(otherReason)) { const timeoutId = setTimeout(() => { textareaRef.current?.scrollIntoView({ behavior: "smooth", block: "nearest", }); }, 100); return () => clearTimeout(timeoutId); } }, [selectedReasons, reasons]); 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; } const isCanceledSwipeDisabled = selectedReasons.length === 0 || (selectedReasons.includes(reasons[reasons.length - 1]) && reasonText.trim() === ""); 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["What was the outcome of your contact?"]}

{ t[ "We hope the acquaintance process is going well. Please let us know if you want to continue the acquaintance process or if the match has been canceled." ] }

{t["What was the outcome of your contact?"]}
{/* Option A: Ongoing acquaintance */} {/* Option B: Canceled */} {/* Reasons List (if Canceled is chosen) */} {outcome === "canceled" ? (

{t["Please select the reason for cancellation:"]}

{reasons.map((option) => { const isReasonChecked = selectedReasons.includes(option); const isOtherReason = option === reasons[reasons.length - 1]; return (
{isReasonChecked && isOtherReason ? (