video-flow-b/components/ui/script-tab-content.tsx

131 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useCallback, useEffect, SetStateAction, forwardRef } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { FileText, Undo2, X, TriangleAlert } from 'lucide-react';
import { ScriptRenderer } from '@/components/script-renderer/ScriptRenderer';
import { useEditData } from '@/components/pages/work-flow/use-edit-data';
import FloatingGlassPanel from './FloatingGlassPanel';
interface ScriptTabContentProps {
setIsPauseWorkFlow: (isPauseWorkFlow: boolean) => void;
isPauseWorkFlow: boolean;
originalText?: string;
onApply: () => void;
setActiveTab: (tabId: string) => void;
}
export const ScriptTabContent = forwardRef<
{ switchBefore: (tabId: string) => boolean, saveBefore: () => void },
ScriptTabContentProps
>((props, ref) => {
const { setIsPauseWorkFlow, isPauseWorkFlow, originalText, onApply, setActiveTab } = props;
const { loading, scriptData, setAnyAttribute, applyScript } = useEditData('script', originalText);
const [isUpdate, setIsUpdate] = useState(false);
const [isRemindApplyUpdate, setIsRemindApplyUpdate] = useState(false);
const [nextToTabId, setNextToTabId] = useState<string>('');
useEffect(() => {
console.log('contentEditableRef---scriptTabContentIsChange', isUpdate);
}, [isUpdate]);
// 暴露方法给父组件
React.useImperativeHandle(ref, () => ({
switchBefore: (tabId: string) => {
setNextToTabId(tabId);
console.log('switchBefore', isUpdate);
if (isUpdate) {
setIsRemindApplyUpdate(true);
}
return isUpdate;
},
saveBefore: () => {
console.log('saveBefore');
if (isUpdate) {
onApply();
}
}
}));
const handleApply = () => {
onApply();
}
const handleCancel = () => {
setIsRemindApplyUpdate(false);
setActiveTab(nextToTabId);
}
// 如果loading 显示loading状态
if (loading) {
return (
<div className="flex flex-col items-center justify-center min-h-[400px] text-white/50">
<div className="w-12 h-12 mb-4 animate-spin rounded-full border-b-2 border-blue-600" />
<p>Loading...</p>
</div>
);
}
// 如果没有数据,显示空状态
if (!scriptData || scriptData.length === 0) {
return (
<div className="flex flex-col items-center justify-center min-h-[400px] text-white/50">
<FileText className="w-16 h-16 mb-4" />
<p>No script data</p>
</div>
);
}
return (
<div className="flex flex-col h-full">
<motion.div
className="relative w-full h-[90vh] backdrop-blur-xl rounded-2xl shadow-2xl overflow-hidden flex flex-col"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
>
<ScriptRenderer
data={scriptData}
setIsPauseWorkFlow={setIsPauseWorkFlow}
setAnyAttribute={setAnyAttribute}
isPauseWorkFlow={isPauseWorkFlow}
applyScript={applyScript}
mode='manual'
from='tab'
setIsUpdate={setIsUpdate}
/>
</motion.div>
<FloatingGlassPanel
open={isRemindApplyUpdate}
width='500px'
clickMaskClose={false}
>
<div className="flex flex-col items-center gap-4 text-white py-4">
<div className="flex items-center gap-3">
<TriangleAlert className="w-6 h-6 text-yellow-400" />
<p className="text-lg font-medium"></p>
</div>
<div className="flex gap-3 mt-2">
<button
onClick={() => handleApply()}
data-alt="confirm-replace-button"
className="px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded-md transition-colors duration-200 flex items-center gap-2"
>
<Undo2 className="w-4 h-4" />
Apply
</button>
<button
onClick={() => handleCancel()}
data-alt="ignore-button"
className="px-4 py-2 bg-gray-600 hover:bg-gray-700 rounded-md transition-colors duration-200 flex items-center gap-2"
>
<X className="w-4 h-4" />
Cancel
</button>
</div>
</div>
</FloatingGlassPanel>
</div>
);
});