add saving
This commit is contained in:
parent
7ccd6e80ca
commit
d1207f0541
@ -10,6 +10,7 @@ import { Input } from '@/components/ui/input'
|
|||||||
import { Label } from '@/components/ui/label'
|
import { Label } from '@/components/ui/label'
|
||||||
import { Textarea } from '@/components/ui/textarea'
|
import { Textarea } from '@/components/ui/textarea'
|
||||||
import { LoadingSpinner } from '@/components/ui/loading-spinner'
|
import { LoadingSpinner } from '@/components/ui/loading-spinner'
|
||||||
|
import { FullScreenLoading } from '@/components/ui/full-screen-loading'
|
||||||
import { VersionTimeline, VersionTimelineRef } from '@/components/studio/VersionTimeline'
|
import { VersionTimeline, VersionTimelineRef } from '@/components/studio/VersionTimeline'
|
||||||
import {
|
import {
|
||||||
Play,
|
Play,
|
||||||
@ -70,6 +71,10 @@ export default function PromptPage({ params }: PromptPageProps) {
|
|||||||
const [originalTitle, setOriginalTitle] = useState('')
|
const [originalTitle, setOriginalTitle] = useState('')
|
||||||
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false)
|
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false)
|
||||||
const [isDuplicating, setIsDuplicating] = useState(false)
|
const [isDuplicating, setIsDuplicating] = useState(false)
|
||||||
|
const [fullScreenLoading, setFullScreenLoading] = useState({
|
||||||
|
isVisible: false,
|
||||||
|
message: ''
|
||||||
|
})
|
||||||
const versionTimelineRef = useRef<VersionTimelineRef>(null)
|
const versionTimelineRef = useRef<VersionTimelineRef>(null)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -163,6 +168,11 @@ export default function PromptPage({ params }: PromptPageProps) {
|
|||||||
if (!user || !promptId) return
|
if (!user || !promptId) return
|
||||||
|
|
||||||
setIsSaving(true)
|
setIsSaving(true)
|
||||||
|
setFullScreenLoading({
|
||||||
|
isVisible: true,
|
||||||
|
message: '正在保存提示词...'
|
||||||
|
})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/prompts/${promptId}`, {
|
const response = await fetch(`/api/prompts/${promptId}`, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
@ -198,6 +208,10 @@ export default function PromptPage({ params }: PromptPageProps) {
|
|||||||
console.error('Failed to save prompt:', error)
|
console.error('Failed to save prompt:', error)
|
||||||
} finally {
|
} finally {
|
||||||
setIsSaving(false)
|
setIsSaving(false)
|
||||||
|
setFullScreenLoading({
|
||||||
|
isVisible: false,
|
||||||
|
message: ''
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,6 +263,11 @@ export default function PromptPage({ params }: PromptPageProps) {
|
|||||||
if (!user || !prompt) return
|
if (!user || !prompt) return
|
||||||
|
|
||||||
setIsDuplicating(true)
|
setIsDuplicating(true)
|
||||||
|
setFullScreenLoading({
|
||||||
|
isVisible: true,
|
||||||
|
message: '正在复制提示词...'
|
||||||
|
})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 创建新的prompt,使用当前显示的内容
|
// 创建新的prompt,使用当前显示的内容
|
||||||
const duplicatedPrompt = {
|
const duplicatedPrompt = {
|
||||||
@ -267,13 +286,30 @@ export default function PromptPage({ params }: PromptPageProps) {
|
|||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const newPrompt = await response.json()
|
const newPrompt = await response.json()
|
||||||
// 跳转到新创建的prompt页面
|
|
||||||
router.push(`/studio/${newPrompt.id}`)
|
// 先隐藏加载遮罩,然后跳转
|
||||||
|
setFullScreenLoading({
|
||||||
|
isVisible: false,
|
||||||
|
message: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 延迟跳转以确保遮罩动画完成
|
||||||
|
setTimeout(() => {
|
||||||
|
router.push(`/studio/${newPrompt.id}`)
|
||||||
|
}, 300)
|
||||||
} else {
|
} else {
|
||||||
console.error('Failed to duplicate prompt')
|
console.error('Failed to duplicate prompt')
|
||||||
|
setFullScreenLoading({
|
||||||
|
isVisible: false,
|
||||||
|
message: ''
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error duplicating prompt:', error)
|
console.error('Error duplicating prompt:', error)
|
||||||
|
setFullScreenLoading({
|
||||||
|
isVisible: false,
|
||||||
|
message: ''
|
||||||
|
})
|
||||||
} finally {
|
} finally {
|
||||||
setIsDuplicating(false)
|
setIsDuplicating(false)
|
||||||
}
|
}
|
||||||
@ -553,6 +589,12 @@ export default function PromptPage({ params }: PromptPageProps) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Full Screen Loading */}
|
||||||
|
<FullScreenLoading
|
||||||
|
isVisible={fullScreenLoading.isVisible}
|
||||||
|
message={fullScreenLoading.message}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
66
src/components/ui/full-screen-loading.tsx
Normal file
66
src/components/ui/full-screen-loading.tsx
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
import { LoadingSpinner } from './loading-spinner'
|
||||||
|
import { cn } from '@/lib/utils'
|
||||||
|
|
||||||
|
interface FullScreenLoadingProps {
|
||||||
|
isVisible: boolean
|
||||||
|
message?: string
|
||||||
|
onComplete?: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FullScreenLoading({
|
||||||
|
isVisible,
|
||||||
|
message = '正在处理中...',
|
||||||
|
onComplete
|
||||||
|
}: FullScreenLoadingProps) {
|
||||||
|
// 禁止页面滚动
|
||||||
|
useEffect(() => {
|
||||||
|
if (isVisible) {
|
||||||
|
document.body.style.overflow = 'hidden'
|
||||||
|
} else {
|
||||||
|
document.body.style.overflow = 'unset'
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.body.style.overflow = 'unset'
|
||||||
|
}
|
||||||
|
}, [isVisible])
|
||||||
|
|
||||||
|
// 自动调用完成回调
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isVisible && onComplete) {
|
||||||
|
const timer = setTimeout(onComplete, 300) // 等待退出动画完成
|
||||||
|
return () => clearTimeout(timer)
|
||||||
|
}
|
||||||
|
}, [isVisible, onComplete])
|
||||||
|
|
||||||
|
if (!isVisible) return null
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={cn(
|
||||||
|
"fixed inset-0 z-[9999] flex items-center justify-center",
|
||||||
|
"bg-black/50 backdrop-blur-sm",
|
||||||
|
"animate-in fade-in duration-200"
|
||||||
|
)}>
|
||||||
|
<div className={cn(
|
||||||
|
"bg-background rounded-lg border border-border shadow-2xl",
|
||||||
|
"p-8 mx-4 max-w-sm w-full",
|
||||||
|
"animate-in zoom-in-95 duration-200"
|
||||||
|
)}>
|
||||||
|
<div className="flex flex-col items-center space-y-4">
|
||||||
|
<LoadingSpinner size="lg" />
|
||||||
|
<div className="text-center">
|
||||||
|
<p className="text-foreground font-medium">{message}</p>
|
||||||
|
<p className="text-sm text-muted-foreground mt-1">
|
||||||
|
请稍候...
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FullScreenLoading
|
Loading…
Reference in New Issue
Block a user