"use client"; import { motion, useMotionValue, useTransform } from "framer-motion"; import { useState } from "react"; import { useI18n } from "@/lib/i18n"; import type { Activity } from "@/lib/schemas"; import { Button } from "@/components/ui"; import { ActivityHeader, FeedbackPanel, Hint, PromptCard, type ActivityComponentProps, } from "./shared"; type TrueFalseActivity = Extract; export function TrueFalse({ activity, onAnswered, onNext, isLast, nextLabel }: ActivityComponentProps) { const { t } = useI18n(); const [result, setResult] = useState(null); const x = useMotionValue(0); // The drag is elastic, so the card moves less than the pointer — these // ranges make each label reach full strength on a normal swipe. const trueOpacity = useTransform(x, [20, 70], [0, 1]); // Left drags go negative: at rest (0) this must be invisible, only fading // in as the card is dragged left. The old range was inverted, so the // "false ✕" label sat on the card permanently. const falseOpacity = useTransform(x, [-70, -20], [1, 0]); const answer = (value: boolean) => { if (result !== null) return; setResult(value === activity.answer); onAnswered(value === activity.answer, { userAnswer: value ? "true" : "false" }); }; return ( <> {result === null ? t("tf.hint") : t("tf.niceSwipe")}
{ if (info.offset.x > 90) answer(true); else if (info.offset.x < -90) answer(false); }} whileTap={{ cursor: "grabbing" }} className="touch-pan-y" > {t("tf.trueLabel")} {t("tf.falseLabel")}

“{activity.statement}”

{result === null ? (
) : ( {t("tf.statementIs.before")}{" "} {activity.answer ? t("tf.true") : t("tf.false")}. } /> )} ); }