diff --git a/app/dashboard/[workspaceId]/purchase-plans/[projectId]/page.tsx b/app/dashboard/[workspaceId]/purchase-plans/[projectId]/page.tsx index 6e9f56d..5838abe 100644 --- a/app/dashboard/[workspaceId]/purchase-plans/[projectId]/page.tsx +++ b/app/dashboard/[workspaceId]/purchase-plans/[projectId]/page.tsx @@ -32,6 +32,8 @@ import { Pencil, Send, Check, + ImageIcon, + MousePointerClick, } from "lucide-react"; import { DashboardHeader } from "@/components/layout/dashboard-header"; import { useWorkspace } from "@/components/providers/workspace-provider"; @@ -82,6 +84,8 @@ import { ColumnSelectorDialog } from "@/components/column-selector-dialog"; import { CreativeSelectDialog } from "@/components/creative-select-dialog"; import { PlacementStatusSelector } from "@/components/placement-status-selector"; import { PlacementPostStatusSelector } from "@/components/placement-post-status-selector"; +import { CostFormatSelector } from "@/components/cost-format-selector"; +import { FormatSelector } from "@/components/format-selector"; import { PlacementWizard } from "@/components/placement-wizard"; import { cn } from "@/lib/utils"; import { toast } from "sonner"; @@ -96,6 +100,7 @@ import type { PlacementType, CostType, UpdatePlacementInProjectRequest, + Creative, } from "@/lib/types/api"; import { ALL_COLUMNS, @@ -119,10 +124,11 @@ type PlacementInlineDraft = { cost_before_bargain?: { type: CostType; value: number } | null; placement_type?: PlacementType | null; format?: string | null; + originalFormat?: string | null; cpm?: number | null; }; -type EditableField = "status" | "post_status" | "placement_at" | "payment_at" | "cost" | "cost_before_bargain" | "format" | "comment" | "cost_format" | "cpm" | "creative_id" | "creative_name"; +type EditableField = "status" | "post_status" | "placement_at" | "payment_at" | "cost" | "cost_before" | "cost_before_bargain" | "format" | "comment" | "cost_format" | "cpm" | "creative_id" | "creative_name" | "placement_type"; const FIXED_COST_TYPE: CostType = "fixed"; @@ -225,6 +231,7 @@ interface ChannelGroupProps { onClearCreative?: (placementId: string) => void; onOpenCreativeSend?: (placement: PlacementWithStats) => void; onAddPlacement?: (channel: Placement["channel"]) => void; + creatives: Creative[]; } // ============================================================================ @@ -249,6 +256,7 @@ interface CellRendererProps { onOpenCreativeSelect?: (placement: PlacementWithStats) => void; onClearCreative?: (placementId: string) => void; onOpenCreativeSend?: (placement: PlacementWithStats) => void; + creatives: Creative[]; } function CellRenderer({ @@ -269,6 +277,7 @@ function CellRenderer({ onOpenCreativeSelect, onClearCreative, onOpenCreativeSend, + creatives, }: CellRendererProps) { const isEditing = editingCell?.placementId === placement.id; @@ -378,17 +387,37 @@ function CellRenderer({ case "creative": const viewCreativeId = placement.creative_id; const hasCreative = !!viewCreativeId; + const creative = hasCreative ? creatives.find((c) => c.id === viewCreativeId) : null; + const thumbnailUrl = creative?.media_items?.[0]?.s3_url; + const imagesCount = creative?.media_items?.length || 0; + const buttonsCount = creative?.buttons?.length || 0; + return (
- {placement.invite_link.slice(8, 20)}…
-
- ) : (
- —
- )}
-
+ {placement.invite_link.slice(8, 20)}…
+
+ ) : (
+ —
+ )}
+ + {truncatedText || 'Без текста'} +
+