'use client' import { useState } from 'react' import Header from '@/components/Header' import { RefreshCw, Loader2, Play, Download, Eye, MessageCircle, Heart, Share2, ExternalLink, AlertTriangle } from 'lucide-react' import { useSettings } from '@/lib/context/SettingsContext' import { analyzeMediaWithAI } from '@/lib/api/opencode' import { generateVideo, waitForTaskCompletion } from '@/lib/api/api34ai' interface TikTokVideo { id: string url: string thumbnail: string caption: string playCount: number likeCount: number commentCount: number shareCount: number authorName: string authorAvatar: string videoUrl?: string } const demoVideos: TikTokVideo[] = [ { id: '1', url: 'https://www.tiktok.com/@user1/video/123', thumbnail: 'https://picsum.photos/seed/tiktok1/360/640', caption: 'Thử thách 24 giờ chỉ ăn một món! 🍜 #foodchallenge #vietnam', playCount: 2500000, likeCount: 450000, commentCount: 12000, shareCount: 25000, authorName: 'foodie.vn', authorAvatar: 'https://api.dicebear.com/7.x/initials/svg?seed=foodie', }, { id: '2', url: 'https://www.tiktok.com/@user2/video/456', thumbnail: 'https://picsum.photos/seed/tiktok2/360/640', caption: 'Mua đồ công nghệ giá rẻ ở đâu? 🛒 #tech #shopping', playCount: 1800000, likeCount: 320000, commentCount: 8000, shareCount: 18000, authorName: 'techreview.vn', authorAvatar: 'https://api.dicebear.com/7.x/initials/svg?seed=tech', }, { id: '3', url: 'https://www.tiktok.com/@user3/video/789', thumbnail: 'https://picsum.photos/seed/tiktok3/360/640', caption: 'Hướng dẫn make-up tự nhiên cho người mới 💄 #beauty #tutorial', playCount: 3200000, likeCount: 680000, commentCount: 15000, shareCount: 42000, authorName: 'beautyqueen', authorAvatar: 'https://api.dicebear.com/7.x/initials/svg?seed=beauty', }, { id: '4', url: 'https://www.tiktok.com/@user4/video/101', thumbnail: 'https://picsum.photos/seed/tiktok4/360/640', caption: 'Phong cách thời trang mùa hè 2024 👗 #fashion #style', playCount: 2100000, likeCount: 390000, commentCount: 9500, shareCount: 21000, authorName: 'fashionista.vn', authorAvatar: 'https://api.dicebear.com/7.x/initials/svg?seed=fashion', }, { id: '5', url: 'https://www.tiktok.com/@user5/video/112', thumbnail: 'https://picsum.photos/seed/tiktok5/360/640', caption: 'Bí quyết tập gym tại nhà cho người bận rộn 💪 #fitness #workout', playCount: 1500000, likeCount: 280000, commentCount: 6000, shareCount: 12000, authorName: 'fitlife.vn', authorAvatar: 'https://api.dicebear.com/7.x/initials/svg?seed=fitness', }, { id: '6', url: 'https://www.tiktok.com/@user6/video/131', thumbnail: 'https://picsum.photos/seed/tiktok6/360/640', caption: 'Du lịch Việt Nam - Đà Lạt mùa hoa lavender 🌸 #travel #dalat', playCount: 2800000, likeCount: 520000, commentCount: 11000, shareCount: 28000, authorName: 'travelblog.vn', authorAvatar: 'https://api.dicebear.com/7.x/initials/svg?seed=travel', }, ] function formatNumber(num: number): string { if (num >= 1000000) return (num / 1000000).toFixed(1) + 'M' if (num >= 1000) return (num / 1000).toFixed(1) + 'K' return num.toString() } export default function TrendingPage() { const { settings, isMounted } = useSettings() const [videos, setVideos] = useState([]) const [isLoading, setIsLoading] = useState(false) const [analyzingId, setAnalyzingId] = useState(null) const [generatingId, setGeneratingId] = useState(null) const [analysisResult, setAnalysisResult] = useState(null) const [generatedVideo, setGeneratedVideo] = useState(null) const [selectedVideo, setSelectedVideo] = useState(null) const [error, setError] = useState(null) if (!isMounted) { return (
Loading...
) } const handleFetchTrending = async () => { setIsLoading(true) setError(null) try { const response = await fetch('/api/tiktok', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ region: 'VN' }) }) const result = await response.json() if (result.error) { throw new Error(result.error) } if (!result.videos || result.videos.length === 0) { setVideos(demoVideos) return } const formattedVideos: TikTokVideo[] = result.videos.map((item: any) => ({ id: item.id || item.video?.id, url: item.url || '', thumbnail: item.thumbnail || '', caption: item.caption || '', playCount: item.playCount || 0, likeCount: item.likeCount || 0, commentCount: item.commentCount || 0, shareCount: item.shareCount || 0, authorName: item.authorName || 'Unknown', authorAvatar: item.authorAvatar || '', })) setVideos(formattedVideos) } catch (e: any) { setError(e.message || 'Failed to fetch trending. Using demo data.') setVideos(demoVideos) } finally { setIsLoading(false) } } const handleAnalyze = async (video: TikTokVideo) => { if (!settings.opencodeApiKey) { setError('Please configure OpenCode API key in Settings') return } setAnalyzingId(video.id) setError(null) setSelectedVideo(video) try { const result = await analyzeMediaWithAI( settings.opencodeApiKey, settings.opencodeModel, 'video', video.thumbnail ) setAnalysisResult(result) } catch (e: any) { setError(e.message || 'Failed to analyze video') } finally { setAnalyzingId(null) } } const handleRecreate = async () => { if (!analysisResult || !settings.api34aiKey) return setIsLoading(true) setError(null) try { const videoResult = await generateVideo( settings.api34aiKey, { prompt: analysisResult.script, model: settings.videoModel || 'veo3.1', duration: settings.defaultDuration, ratio: settings.defaultAspectRatio, resolution: '720p', quality: 'fast' } ) const videoUrl = await waitForTaskCompletion( settings.api34aiKey, videoResult.task_id ) setGeneratedVideo(videoUrl) } catch (e: any) { setError(e.message || 'Failed to generate video') } finally { setIsLoading(false) } } const downloadVideo = async () => { if (!generatedVideo) return try { const response = await fetch(generatedVideo) const blob = await response.blob() const url = window.URL.createObjectURL(blob) const link = document.createElement('a') link.href = url link.download = `recreated-${Date.now()}.mp4` link.click() window.URL.revokeObjectURL(url) } catch (e) { console.error('Download failed:', e) } } return (

TikTok Trending - Vietnam

Browse trending TikTok videos, analyze and recreate them

Region: 🇻🇳 Vietnam
{error && (
{error}
)} {videos.length > 0 ? (
{videos.map((video) => (
{video.caption}

{video.caption}

{video.authorName} @{video.authorName}
{formatNumber(video.playCount)}
{formatNumber(video.likeCount)}
{formatNumber(video.commentCount)}
{formatNumber(video.shareCount)}
))}
) : (

No trending videos loaded. Click "Refresh Trending" to fetch.

)} {selectedVideo && analysisResult && (

AI Analysis

Content Summary

{analysisResult.contentSummary}

Script

{analysisResult.script}

Keyframes

{analysisResult.keyframes?.map((kf: any, i: number) => (
{kf.time} {kf.description}
))}
{generatedVideo ? (
) : ( )}
)}
) }