import { useCallback, useEffect, useRef, useState } from 'react'; import { Box, Button, Card, Flex, Select, Spinner, Stack, Tab, TabList, TabPanel, Text, TextInput, } from '@sanity/ui'; import { LaunchIcon, ResetIcon, SearchIcon } from '@sanity/icons'; import { useClient } from 'sanity'; import { useLamina } from '../lib/LaminaContext.js'; import { getDocumentContext } from '../lib/documentContext.js'; import { useSanityAssets } from '../lib/useSanityAssets.js'; import { AssetPickerGrid } from '../components/AssetPickerGrid.js'; import type { AssetTypeFilter } from '../types.js'; const LAMINA_ORIGIN = 'https://app.uselamina.ai'; interface LaminaMessage { type: 'lamina:asset-ready' | 'lamina:editor-close' | 'lamina:embed-ready'; url?: string; runId?: string; mediaType?: 'image' | 'video'; brief?: string; filename?: string; } function isLaminaMessage(data: unknown): data is LaminaMessage { return ( typeof data === 'object' && data !== null && 'type' in data && typeof (data as LaminaMessage).type === 'string' && (data as LaminaMessage).type.startsWith('lamina:') ); } interface HistoryEntry { _id: string; _type: string; _createdAt: string; url: string; originalFilename: string | null; mimeType: string | null; description: string | null; source: { name: string; id: string; url?: string } | null; } function formatDate(dateStr: string): string { const d = new Date(dateStr); const now = new Date(); const diffMs = now.getTime() - d.getTime(); const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); if (diffDays === 0) return 'Today'; if (diffDays === 1) return 'Yesterday'; if (diffDays < 7) return `${diffDays} days ago`; return d.toLocaleDateString(); } function GenerationHistory() { const sanityClient = useClient({ apiVersion: '2024-01-01' }); const [entries, setEntries] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { let cancelled = false; (async () => { setLoading(true); setError(null); try { const result = await sanityClient.fetch( `*[_type in ["sanity.imageAsset", "sanity.fileAsset"] && source.name == "lamina"] | order(_createdAt desc) [0...50] { _id, _type, _createdAt, url, originalFilename, mimeType, description, source }`, ); if (!cancelled) setEntries(result ?? []); } catch (err) { if (!cancelled) setError(err instanceof Error ? err.message : 'Failed to load history'); } finally { if (!cancelled) setLoading(false); } })(); return () => { cancelled = true; }; }, [sanityClient]); if (loading) { return ( ); } if (error) { return ( {error} ); } if (entries.length === 0) { return ( No generation history yet ); } // Group by date const groups: Array<{ label: string; items: HistoryEntry[] }> = []; let currentLabel = ''; for (const entry of entries) { const label = formatDate(entry._createdAt); if (label !== currentLabel) { groups.push({ label, items: [entry] }); currentLabel = label; } else { groups[groups.length - 1].items.push(entry); } } return ( Recent generations {groups.map((group) => ( {group.label} {group.items.map((entry) => { const isImage = entry._type === 'sanity.imageAsset'; return ( {isImage ? ( ) : ( {entry.mimeType?.split('/')[1]?.toUpperCase() || 'FILE'} )} {entry.description ? ( {entry.description} ) : ( {entry.originalFilename || entry._id} )} {new Date(entry._createdAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} {entry.mimeType ? ` · ${entry.mimeType}` : ''} {entry.source?.url ? (