import { AlertCircle, CheckCircle, Info, LogIn, Upload } from "lucide-react" import { useMemo, useState } from "react" import { useTranslation } from "react-i18next" import { Alert, AlertDescription } from "@/components/ui/alert" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Progress } from "@/components/ui/progress" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Textarea } from "@/components/ui/textarea" import { SOCIAL_NETWORKS } from "../constants/export-constants" import { useSocialExport } from "../hooks/use-social-export" import { ExportProgress, SocialExportSettings } from "../types/export-types" // Иконка YouTube const YouTubeIcon = () => ( ) // Иконка TikTok const TikTokIcon = () => ( ) // Иконка Telegram const TelegramIcon = () => ( ) // Иконка Vimeo const VimeoIcon = () => ( ) interface SocialExportTabProps { settings: SocialExportSettings onSettingsChange: (updates: Partial) => void onExport: (socialNetwork: string) => void onCancelExport: () => void onClose: () => void isRendering: boolean renderProgress: ExportProgress | null hasProject: boolean } export function SocialExportTab({ settings, onSettingsChange, onExport, onCancelExport, onClose, isRendering, renderProgress, hasProject, }: SocialExportTabProps) { const { t } = useTranslation() const { loginToSocialNetwork, logoutFromSocialNetwork, validateSocialExport, getOptimalSettings, getNetworkLimits } = useSocialExport() const [selectedNetwork, setSelectedNetwork] = useState(settings.socialNetwork || "youtube") const [loginStates, setLoginStates] = useState>({}) // Валидация в реальном времени const validation = useMemo(() => { return validateSocialExport(settings) }, [settings, validateSocialExport]) // Получаем лимиты для выбранной сети const networkLimits = useMemo(() => { return getNetworkLimits(selectedNetwork) }, [selectedNetwork, getNetworkLimits]) // Получаем оптимальные настройки const optimalSettings = useMemo(() => { return getOptimalSettings(selectedNetwork) }, [selectedNetwork, getOptimalSettings]) // Функция для получения статуса валидации const getValidationStatus = () => { if (validation.valid) { return (validation.warnings?.length ?? 0) > 0 || (validation.suggestions?.length ?? 0) > 0 ? "warning" : "success" } return "error" } // Функция для форматирования размера файла const formatFileSize = (bytes: number) => { const units = ["B", "KB", "MB", "GB"] let size = bytes let unitIndex = 0 while (size >= 1024 && unitIndex < units.length - 1) { size /= 1024 unitIndex++ } return `${Math.round(size * 10) / 10}${units[unitIndex]}` } // Функция для форматирования времени const formatDuration = (seconds: number) => { const hours = Math.floor(seconds / 3600) const minutes = Math.floor((seconds % 3600) / 60) const remainingSeconds = seconds % 60 if (hours > 0) { return `${hours}h ${minutes}m` } if (minutes > 0) { return `${minutes}m ${remainingSeconds}s` } return `${remainingSeconds}s` } // Обработчик входа в социальную сеть const handleLogin = async (networkId: string) => { try { const success = await loginToSocialNetwork(networkId) setLoginStates((prev) => ({ ...prev, [networkId]: success })) if (success) { onSettingsChange({ socialNetwork: networkId, isLoggedIn: true, }) } } catch (error) { console.error(`Login to ${networkId} failed:`, error) } } // Обработчик выхода из социальной сети const handleLogout = async (networkId: string) => { try { await logoutFromSocialNetwork(networkId) setLoginStates((prev) => ({ ...prev, [networkId]: false })) onSettingsChange({ isLoggedIn: false }) } catch (error) { console.error(`Logout from ${networkId} failed:`, error) } } // Обработчик экспорта в социальную сеть const handleSocialExport = async () => { if (!selectedNetwork) return try { // Сначала проверяем видео const validation = validateSocialExport(settings) if (!validation.valid) { console.warn("Video validation failed:", validation.error) // Показать ошибки валидации пользователю return } // Запускаем экспорт onExport(selectedNetwork) } catch (error) { console.error("Social export failed:", error) } } // Получение иконки для социальной сети const getSocialIcon = (networkId: string) => { switch (networkId) { case "youtube": return case "vimeo": return case "tiktok": return case "telegram": return default: return } } // Получение сети по ID const getNetworkById = (id: string) => SOCIAL_NETWORKS.find((n) => n.id === id) const selectedNetworkData = getNetworkById(selectedNetwork) return (
{/* Выбор социальной сети */}
{SOCIAL_NETWORKS.map((network) => { const isLoggedIn = loginStates[network.id] || false const isSelected = selectedNetwork === network.id return ( setSelectedNetwork(network.id)} >
{getSocialIcon(network.id)} {network.name}
{isLoggedIn &&
}
Max: {network.maxResolution} • {network.maxFps}fps {isSelected && (
{!isLoggedIn ? ( ) : (
{t("dialogs.export.loggedIn")}
)}
)}
) })}
{/* Валидация и лимиты сети */} {selectedNetworkData && networkLimits && (
{getSocialIcon(selectedNetwork)} {selectedNetworkData.name} Limits & Validation
{validation.valid ? ( ) : ( )} {validation.valid ? "Valid" : "Invalid"}
{/* Лимиты платформы */} {networkLimits && (
Max File Size
{(networkLimits.maxFileSize / (1024 * 1024 * 1024)).toFixed(1)}GB
Max Duration
{Math.round(networkLimits.maxDuration / 3600)}h
Max Resolution
{networkLimits.maxResolution}
Title Limit
{networkLimits.titleMaxLength} chars
)} {/* Ошибки валидации */} {!validation.valid && validation.errors && validation.errors.length > 0 && (
{validation.errors.map((error, index) => (
{error}
))}
)} {/* Предупреждения */} {validation.warnings && validation.warnings.length > 0 && (
{validation.warnings.map((warning, index) => (
{warning}
))}
)} {/* Предложения по оптимизации */} {validation.suggestions && validation.suggestions.length > 0 && (
Optimization suggestions:
{validation.suggestions.map((suggestion, index) => (
• {suggestion}
))}
)}
)} {/* Настройки выбранной сети */} {selectedNetworkData && ( {getSocialIcon(selectedNetwork)} {t("dialogs.export.uploadSettings", { platform: selectedNetworkData.name })} {/* Название видео */}
onSettingsChange({ title: e.target.value })} disabled={isRendering} className={ networkLimits && (settings.title || "").length > networkLimits.titleMaxLength ? "border-red-500 focus:border-red-500" : "" } />
{/* Описание */}