"use client"; import { useState, useTransition } from "react"; import { YoutubeVideo, DetectedObject, MarketplaceMatch } from "@/lib/db/schema"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle, CardFooter, CardDescription } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Play, Plus, CheckCircle2, XCircle, ArrowLeft, ChevronRight, Copy, ExternalLink, Video, Package, History, Save } from "lucide-react"; import Link from "next/link"; import { CrossVaultSuggestions } from "./cross-vault-suggestions"; import { VideoEmbed } from "@/features/vault/components/video-embed"; import { AnalysisHistory } from "./analysis-history"; import { triggerAIAnalysisAction, approveDetectionAction, rejectDetectionAction, completeVideoReviewAction, addManualProductAction } from "../actions/analysis"; import { toast } from "sonner"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, DialogFooter } from "@/components/ui/dialog"; type ExtendedVideo = YoutubeVideo & { channel?: { channelName: string }; detections: (DetectedObject & { marketplaceMatches: MarketplaceMatch[] })[]; }; export function AnalysisInterface({ video }: { video: ExtendedVideo }) { const [isPending, startTransition] = useTransition(); const [activeTab, setActiveTab] = useState("review"); const [isAddProductOpen, setIsAddProductOpen] = useState(false); const handleTriggerAI = async () => { startTransition(async () => { const result = await triggerAIAnalysisAction(video.id); if (result.success) { toast.success("AI Analysis triggered"); } else { toast.error("Failed to trigger analysis"); } }); }; const handleApprove = async (id: string) => { startTransition(async () => { await approveDetectionAction(id); toast.success("Product approved"); }); }; const handleReject = async (id: string) => { startTransition(async () => { await rejectDetectionAction(id); toast.success("Product rejected"); }); }; const handleComplete = async () => { startTransition(async () => { await completeVideoReviewAction(video.id); toast.success("Video review completed"); }); }; return (
Dashboard / Video Hub

{video.title}

{video.channel?.channelName}

{/* Left Side: Video Player & Overview */}
Review Objects Cross-Vault suggestions History

Detected Objects ({video.detections.length})

setIsAddProductOpen(false)} />
{video.detections.map((obj) => (
{obj.thumbnailUrl ? ( ) : ( )}

{obj.objectName}

{obj.moderationStatus}

Category: {obj.category}

{obj.marketplaceMatches?.[0] && (
{obj.marketplaceMatches[0].affiliateUrl}
)}
))}
{/* Right Side: Metadata & Status */}
Video Details

{video.platform}

{video.scanStatus.replace('_', ' ')}

Admin Instructions

1. Run AI Analysis if not already done.

2. Approve items that are correctly identified.

3. Add any missing products manually.

4. Use the Suggestions tab to reuse products from other creators who shared this video.

5. Mark as Done to notify the creator.

); } function AddProductDialog({ videoId, onSuccess }: { videoId: string, onSuccess: () => void }) { const [isPending, startTransition] = useTransition(); const [name, setName] = useState(""); const [category, setCategory] = useState("Apparel"); const [url, setUrl] = useState(""); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); startTransition(async () => { const result = await addManualProductAction(videoId, { objectName: name, category: category as any, affiliateUrl: url }); if (result.success) { toast.success("Product added manually"); onSuccess(); } else { toast.error("Failed to add product"); } }); }; return (
Add Manual Product
setName(e.target.value)} placeholder="e.g. Sony WH-1000XM4" required />
setCategory(e.target.value)} required />
setUrl(e.target.value)} placeholder="https://amazon.com/..." />
); }