mirror of https://github.com/kortix-ai/suna.git
158 lines
8.0 KiB
TypeScript
158 lines
8.0 KiB
TypeScript
import React from 'react';
|
|
import { Skeleton } from '@/components/ui/skeleton';
|
|
import { ChatInput } from '@/components/thread/chat-input/chat-input';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
interface ThreadSkeletonProps {
|
|
isSidePanelOpen?: boolean;
|
|
showHeader?: boolean;
|
|
messageCount?: number;
|
|
}
|
|
|
|
export function ThreadSkeleton({
|
|
isSidePanelOpen = false,
|
|
showHeader = true,
|
|
messageCount = 3,
|
|
}: ThreadSkeletonProps) {
|
|
// Mock handlers for the ChatInput component
|
|
const handleSubmit = (message: string) => {
|
|
// No-op for skeleton
|
|
console.log('Skeleton submit:', message);
|
|
};
|
|
|
|
const handleChange = (value: string) => {
|
|
// No-op for skeleton
|
|
console.log('Skeleton change:', value);
|
|
};
|
|
|
|
return (
|
|
<div className="flex h-screen">
|
|
<div
|
|
className={`flex flex-col flex-1 overflow-hidden transition-all duration-200 ease-in-out`}
|
|
>
|
|
{/* Skeleton Header */}
|
|
{showHeader && (
|
|
<div className="border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
|
<div className="flex h-14 items-center gap-4 px-4">
|
|
<div className="flex-1">
|
|
<div className="flex items-center gap-2">
|
|
<Skeleton className="h-6 w-6 rounded-full" />
|
|
<Skeleton className="h-5 w-40" />
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<Skeleton className="h-8 w-8 rounded-full" />
|
|
<Skeleton className="h-8 w-8 rounded-full" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Skeleton Chat Messages */}
|
|
<div className="flex-1 overflow-y-auto px-6 py-4 pb-72">
|
|
<div className="mx-auto max-w-3xl space-y-6">
|
|
{/* Generate multiple message skeletons based on messageCount */}
|
|
{Array.from({ length: messageCount }).map((_, index) => (
|
|
<React.Fragment key={index}>
|
|
{/* User message - every other message */}
|
|
{index % 2 === 0 ? (
|
|
<div className="flex justify-end">
|
|
<div className="max-w-[85%] rounded-lg bg-primary/10 px-4 py-3">
|
|
<div className="space-y-2">
|
|
<Skeleton className="h-4 w-48" />
|
|
<Skeleton className="h-4 w-32" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
/* Assistant response with tool usage */
|
|
<div>
|
|
<div className="flex items-start gap-3">
|
|
<Skeleton className="flex-shrink-0 w-5 h-5 mt-2 rounded-full" />
|
|
<div className="flex-1 space-y-2">
|
|
<div className="max-w-[90%] w-full rounded-lg bg-muted px-4 py-3">
|
|
<div className="space-y-3">
|
|
<div>
|
|
<Skeleton className="h-4 w-full max-w-[360px] mb-2" />
|
|
<Skeleton className="h-4 w-full max-w-[320px] mb-2" />
|
|
<Skeleton className="h-4 w-full max-w-[290px]" />
|
|
</div>
|
|
|
|
{/* Tool call button skeleton */}
|
|
{index % 3 === 1 && (
|
|
<div className="py-1">
|
|
<Skeleton className="h-6 w-32 rounded-md" />
|
|
</div>
|
|
)}
|
|
|
|
{index % 3 === 1 && (
|
|
<div>
|
|
<Skeleton className="h-4 w-full max-w-[340px] mb-2" />
|
|
<Skeleton className="h-4 w-full max-w-[280px]" />
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</React.Fragment>
|
|
))}
|
|
|
|
{/* Assistant thinking state */}
|
|
<div>
|
|
<div className="flex items-start gap-3">
|
|
<Skeleton className="flex-shrink-0 w-5 h-5 mt-2 rounded-full" />
|
|
<div className="flex-1 space-y-2">
|
|
<div className="flex items-center gap-1.5 py-1">
|
|
<div className="h-1.5 w-1.5 rounded-full bg-gray-400/50 animate-pulse" />
|
|
<div className="h-1.5 w-1.5 rounded-full bg-gray-400/50 animate-pulse delay-150" />
|
|
<div className="h-1.5 w-1.5 rounded-full bg-gray-400/50 animate-pulse delay-300" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* ChatInput - Inside the left div, positioned at bottom with exact same styling */}
|
|
<div
|
|
className={cn(
|
|
"bg-gradient-to-t from-background via-background/90 to-transparent px-0 pt-8 transition-all duration-200 ease-in-out"
|
|
)}
|
|
>
|
|
<div className={cn(
|
|
"mx-auto",
|
|
"max-w-3xl"
|
|
)}>
|
|
<ChatInput
|
|
onSubmit={handleSubmit}
|
|
onChange={handleChange}
|
|
placeholder="Describe what you need help with..."
|
|
loading={false}
|
|
disabled={true}
|
|
isAgentRunning={false}
|
|
value=""
|
|
hideAttachments={false}
|
|
isLoggedIn={true}
|
|
hideAgentSelection={true}
|
|
defaultShowSnackbar={false}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Side Panel - Always visible in skeleton with exact responsive widths */}
|
|
<div className="hidden sm:block">
|
|
<div className="h-screen w-[90%] sm:w-[450px] md:w-[500px] lg:w-[550px] xl:w-[650px] border-l">
|
|
<div className="p-4">
|
|
<Skeleton className="h-8 w-32 mb-4" />
|
|
<Skeleton className="h-20 w-full rounded-md mb-4" />
|
|
<Skeleton className="h-40 w-full rounded-md" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
} |