ppt-tool/frontend/components/ui/overlay-loader.tsx
Vadym Samoilenko e8295d6e71 Phase 4: Fix critical bugs, improve document parsing, add vision OCR
- Fix SSE stream 500: use async_session_maker inside StreamingResponse generator
  (Depends session closes when endpoint returns, before streaming starts)
- Fix template application: store template_name in prepare endpoint so worker
  uses the selected custom template instead of defaulting to "general"
- Fix OverlayLoader: replace loading.gif with HamsterLoader component
- Fix parse_mode default: change from "slides" to "layouts" to avoid 70+ layouts
- Update Gemini Flash model to gemini-3.1-flash-image-preview
- Improve DOCX parsing: python-docx for structured table extraction, OCR enabled
- Add vision-based image text extraction via Gemini for uploaded images
- Add LayoutParser integration for slide layout structure analysis
- Add Phase 4 MVP features: transfer ownership, URL input, follow-up questions,
  attachment-to-slide mapping, content router

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 14:07:00 +00:00

86 lines
No EOL
2.8 KiB
TypeScript

import { cn } from "@/lib/utils"
import { HamsterLoader } from "./hamster-loader"
import { ProgressBar } from "./progress-bar"
import { useEffect, useState } from "react"
interface OverlayLoaderProps {
text?: string
className?: string
show: boolean
showProgress?: boolean
duration?: number
extra_info?: string
onProgressComplete?: () => void
}
export const OverlayLoader = ({
text,
className,
show,
showProgress = false,
duration = 10,
onProgressComplete,
extra_info
}: OverlayLoaderProps) => {
const [isVisible, setIsVisible] = useState(false);
useEffect(() => {
if (show) {
setIsVisible(true);
} else {
setIsVisible(false);
}
}, [show]);
if (!show) return null;
return (
<div
style={{
zIndex: 1000
}}
className={cn(
"fixed inset-0 bg-black/70 z-50 flex items-center justify-center transition-opacity duration-300",
isVisible ? "opacity-100" : "opacity-0"
)}
>
<div
className={cn(
"flex flex-col items-center justify-center px-6 pt-0 pb-8 rounded-xl bg-[#030303] shadow-2xl",
"min-w-[280px] sm:min-w-[330px] border border-white/10 transition-all duration-400 ease-out",
isVisible ? "opacity-100 scale-100" : "opacity-0 scale-90",
className
)}
>
<div className="py-8">
<HamsterLoader size="lg" />
</div>
{showProgress ? (
<div className="w-full space-y-6 pt-4">
<ProgressBar
duration={duration}
onComplete={onProgressComplete}
/>
{text && (
<div className="space-y-1">
<p className="text-white text-base text-center font-semibold font-inter">
{text}
</p>
{extra_info && <p className="text-white/80 text-xs text-center font-semibold font-inter">{extra_info}</p>}
</div>
)}
</div>
) : (
<>
<p className="text-white text-base text-center font-semibold font-inter">
{text}
</p>
{extra_info && <p className="text-white/80 text-xs text-center font-semibold font-inter">{extra_info}</p>}
</>
)}
</div>
</div>
)
}