"use client"; import { useState } from "react"; import { Loader2, Plus, AlertCircle, CheckCircle2 } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { cn } from "@/lib/utils"; import { parseChannelInput } from "@/lib/utils/channel-parser"; import { channelsApi, placementsApi } from "@/lib/api"; import type { Placement } from "@/lib/types/api"; interface AddChannelDialogProps { workspaceId: string; projectId: string; existingPlacements: Placement[]; onSuccess: () => void; children?: React.ReactNode; } export function AddChannelDialog({ workspaceId, projectId, existingPlacements, onSuccess, children, }: AddChannelDialogProps) { const [open, setOpen] = useState(false); const [inputValue, setInputValue] = useState(""); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); const existingUsernames = new Set( existingPlacements .map((p) => p.channel.username?.toLowerCase()) .filter(Boolean) ); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(null); setSuccess(false); const username = parseChannelInput(inputValue); if (!username) { setError("Не удалось распознать username из ссылки"); return; } if (existingUsernames.has(username.toLowerCase())) { setError("Этот канал уже добавлен в проект"); return; } try { setLoading(true); const username = parseChannelInput(inputValue); if (!username) { setError("Не удалось распознать username из ссылки"); return; } if (existingUsernames.has(username.toLowerCase())) { setError("Этот канал уже добавлен в проект"); return; } // Step 1: Find channel by username to get channel_id const channelsResponse = await channelsApi.list({ username }); const channel = channelsResponse.items.find( (c) => c.username?.toLowerCase() === username.toLowerCase() ); if (!channel) { setError("Канал не найден в каталоге"); return; } // Step 2: Create empty placement with channel_id await placementsApi.createBulk(workspaceId, projectId, { channels: [ { channel_id: channel.id, status: "Без статуса", }, ], }); setSuccess(true); setInputValue(""); // Close dialog after short delay setTimeout(() => { setOpen(false); setSuccess(false); onSuccess(); }, 1500); } catch (err: any) { console.error("Failed to add channel:", err); setError(err.detail || "Не удалось добавить канал"); } finally { setLoading(false); } }; const handleOpenChange = (isOpen: boolean) => { if (!isOpen) { setInputValue(""); setError(null); setSuccess(false); } setOpen(isOpen); }; const examples = [ "t.me/rian_ru", "@rian_ru", "telemetr.me/content/rian_ru", "tgstat.ru/channel/@rian_ru", ]; return ( {children} Добавить канал Введите ссылку или username канала для проверки и добавления в проект
setInputValue(e.target.value)} disabled={loading} autoComplete="off" />

Поддерживаются: t.me, telemetr.me, tgstat.ru, а также username с @

{error && (
{error}
)} {success && (
Канал успешно добавлен!
)}

Примеры:

{examples.map((example) => ( ))}
); }