/* Copyright (C) 2025 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { Modal, Button, Typography, Checkbox, Input, Space, } from '@douyinfe/semi-ui'; import { IconAlertTriangle } from '@douyinfe/semi-icons'; import { useIsMobile } from '../../../hooks/common/useIsMobile'; import MarkdownRenderer from '../markdown/MarkdownRenderer'; const { Text } = Typography; const RiskMarkdownBlock = React.memo(function RiskMarkdownBlock({ markdownContent, }) { if (!markdownContent) { return null; } return (
); }); const RiskAcknowledgementModal = React.memo(function RiskAcknowledgementModal({ visible, title, markdownContent = '', detailTitle = '', detailItems = [], checklist = [], inputPrompt = '', requiredText = '', inputPlaceholder = '', mismatchText = '', cancelText = '', confirmText = '', onCancel, onConfirm, }) { const isMobile = useIsMobile(); const [checkedItems, setCheckedItems] = useState([]); const [typedText, setTypedText] = useState(''); useEffect(() => { if (!visible) return; setCheckedItems(Array(checklist.length).fill(false)); setTypedText(''); }, [visible, checklist.length]); const allChecked = useMemo(() => { if (checklist.length === 0) return true; return checkedItems.length === checklist.length && checkedItems.every(Boolean); }, [checkedItems, checklist.length]); const typedMatched = useMemo(() => { if (!requiredText) return true; return typedText.trim() === requiredText.trim(); }, [typedText, requiredText]); const detailText = useMemo(() => detailItems.join(', '), [detailItems]); const canConfirm = allChecked && typedMatched; const handleChecklistChange = useCallback((index, checked) => { setCheckedItems((previous) => { const next = [...previous]; next[index] = checked; return next; }); }, []); return ( {title} } width={isMobile ? '100%' : 860} centered maskClosable={false} closeOnEsc={false} onCancel={onCancel} bodyStyle={{ maxHeight: isMobile ? '70vh' : '72vh', overflowY: 'auto', padding: isMobile ? '12px 16px' : '18px 22px', }} footer={ } >
{detailItems.length > 0 ? (
{detailTitle ? {detailTitle} : null}
{detailText}
) : null} {checklist.length > 0 ? (
{checklist.map((item, index) => ( { handleChecklistChange(index, event.target.checked); }} > {item} ))}
) : null} {requiredText ? (
{inputPrompt ? {inputPrompt} : null}
{requiredText}
event.preventDefault()} onCut={(event) => event.preventDefault()} onPaste={(event) => event.preventDefault()} onDrop={(event) => event.preventDefault()} /> {!typedMatched && typedText ? ( {mismatchText} ) : null}
) : null}
); }); export default RiskAcknowledgementModal;