"use client"; // ============================================================================ // Creatives List Page // ============================================================================ import React, { useEffect, useState } from "react"; import Link from "next/link"; import { DashboardHeader } from "@/components/layout/dashboard-header"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { creativesApi } from "@/lib/api"; import { formatNumber, formatMetric, truncate, formatDate, } from "@/lib/utils/format"; import { Folder, Loader2, AlertCircle, Plus, Eye, Pencil, Archive, Trash2, } from "lucide-react"; import type { Creative } from "@/lib/types/api"; import { Alert, AlertDescription } from "@/components/ui/alert"; export default function CreativesPage() { const [creatives, setCreatives] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [activeTab, setActiveTab] = useState<"all" | "active" | "archived">( "active" ); useEffect(() => { loadCreatives(); }, []); const loadCreatives = async () => { try { setLoading(true); const response = await creativesApi.list(); setCreatives(response.creatives); } catch (err: any) { setError(err?.error?.message || "Ошибка загрузки креативов"); } finally { setLoading(false); } }; const handleArchive = async ( id: string, currentStatus: "active" | "archived" ) => { try { const newStatus = currentStatus === "active" ? "archived" : "active"; await creativesApi.update(id, { status: newStatus }); loadCreatives(); } catch (err: any) { alert(err?.error?.message || "Ошибка обновления креатива"); } }; const handleDelete = async (id: string, name: string) => { if (!confirm(`Удалить креатив "${name}"?`)) return; try { await creativesApi.delete(id); loadCreatives(); } catch (err: any) { alert(err?.error?.message || "Ошибка удаления креатива"); } }; const filteredCreatives = creatives.filter((creative) => { if (activeTab === "active") return creative.status === "active"; if (activeTab === "archived") return creative.status === "archived"; return true; }); return ( <>

Креативы

Шаблоны рекламных сообщений

{error && ( {error} )} setActiveTab(v as any)} className="w-full" > Активные ({creatives.filter((c) => c.status === "active").length}) Архив ({creatives.filter((c) => c.status === "archived").length}) Все ({creatives.length}) {loading ? (
) : filteredCreatives.length === 0 ? (

{activeTab === "all" && "Нет креативов"} {activeTab === "active" && "Нет активных креативов"} {activeTab === "archived" && "Нет архивных креативов"}

Создайте первый креатив для рекламных сообщений

{activeTab === "active" && ( )}
) : (
{filteredCreatives.map((creative) => (
{creative.name} {creative.status === "archived" && ( Архив )}
{creative.target_channel_title}

{creative.text}

{formatNumber(creative.placements_count)}
Размещений
{formatDate(creative.created_at)}
Создан
))}
)}
); }