diff --git a/components/dialog-create-placements.tsx b/components/dialog-create-placements.tsx index 94dbebb..7de55d7 100644 --- a/components/dialog-create-placements.tsx +++ b/components/dialog-create-placements.tsx @@ -6,7 +6,6 @@ import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; -import { Badge } from "@/components/ui/badge"; import { Dialog, DialogContent, @@ -27,6 +26,7 @@ import { cn } from "@/lib/utils"; import { parseChannelInput } from "@/lib/utils/channel-parser"; import { placementsApi, creativesApi, channelsApi } from "@/lib/api"; import type { Placement, Creative, Channel } from "@/lib/types/api"; +import { Badge } from "./ui/badge"; interface ChannelInput { username: string; @@ -64,41 +64,20 @@ export function CreatePlacementsDialog({ const [loading, setLoading] = useState(false); const [error, setError] = useState(null); - // Step 1: Channels const [newChannelInput, setNewChannelInput] = useState(""); const [selectedChannels, setSelectedChannels] = useState([]); const [existingChannels, setExistingChannels] = useState([]); const [projectChannels, setProjectChannels] = useState([]); - - // Step 2: Details const [creativeId, setCreativeId] = useState(prefilledCreativeId); const [format, setFormat] = useState(""); const [cost, setCost] = useState(""); const [placementDate, setPlacementDate] = useState(""); const [comment, setComment] = useState(""); - - // Step 3: Confirm const [creatives, setCreatives] = useState([]); const [creating, setCreating] = useState(false); const [createdCount, setCreatedCount] = useState(null); - const existingUsernames = new Set( - existingPlacements - .map((p) => p.channel.username?.toLowerCase()) - .filter(Boolean) - ); - - const getExistingChannelIdByUsername = (usernameLower: string): string | null => { - const matched = existingPlacements.find( - (p) => p.channel.username?.toLowerCase() === usernameLower - ); - return matched?.channel.id ?? null; - }; - const handleOpenChange = (isOpen: boolean) => { - if (!isOpen) { - resetForm(); - } setInternalOpen(isOpen); onOpenChange?.(isOpen); }; @@ -124,7 +103,26 @@ export function CreatePlacementsDialog({ setCreatedCount(null); }; - // Load creatives when dialog opens or when moving to step 2 + const existingUsernames = new Set( + existingPlacements + .map((p) => p.channel.username?.toLowerCase()) + .filter(Boolean) + ); + + const getExistingChannelIdByUsername = (usernameLower: string): string | null => { + const matched = existingPlacements.find( + (p) => p.channel.username?.toLowerCase() === usernameLower + ); + return matched?.channel.id ?? null; + }; + + useEffect(() => { + if (isOpen) { + loadCreatives(); + loadProjectChannels(); + } + }, [isOpen, workspaceId, projectId, prefilledCreativeId]); + const loadCreatives = async () => { try { const response = await creativesApi.list(workspaceId, { @@ -134,7 +132,6 @@ export function CreatePlacementsDialog({ }); setCreatives(response.items); - // Auto-select prefilled creative if set if (prefilledCreativeId && response.items.length > 0) { const prefilled = response.items.find((c) => c.id === prefilledCreativeId); if (prefilled) { @@ -146,7 +143,6 @@ export function CreatePlacementsDialog({ } }; - // Load project channels when opening dialog const loadProjectChannels = async () => { try { const projectPlacements = await placementsApi.getByProject(workspaceId, projectId); @@ -157,14 +153,6 @@ export function CreatePlacementsDialog({ } }; - // Load creatives and project channels when dialog opens - useEffect(() => { - if (isOpen) { - loadCreatives(); - loadProjectChannels(); - } - }, [isOpen, workspaceId, projectId, prefilledCreativeId]); - const addChannel = async () => { const username = parseChannelInput(newChannelInput); if (!username) { @@ -178,7 +166,6 @@ export function CreatePlacementsDialog({ return; } - // Check if channel exists in project channels const projectChannel = projectChannels.find((c) => c.username?.toLowerCase() === lowerUsername); if (projectChannel) { setSelectedChannels([...selectedChannels, { username, channelId: projectChannel.id }]); @@ -187,7 +174,6 @@ export function CreatePlacementsDialog({ return; } - // If channel already has placements in this project, reuse its channel_id. if (existingUsernames.has(lowerUsername)) { const existingChannelId = getExistingChannelIdByUsername(lowerUsername); if (!existingChannelId) { @@ -200,7 +186,6 @@ export function CreatePlacementsDialog({ return; } - // Channel doesn't exist in project yet. Create it globally via API to get channel_id. try { const createResponse = await channelsApi.create([{ username }]); const channelId = createResponse.results[0]?.channel.id; @@ -263,15 +248,13 @@ export function CreatePlacementsDialog({ }; const selectedCreative = creatives.find((c) => c.id === creativeId); - - // If open is controlled, don't render DialogTrigger const isControlled = controlledOpen !== undefined; return ( - {!isControlled && ( - {children} - )} + + {children} + Создать размещения @@ -297,7 +280,6 @@ export function CreatePlacementsDialog({ ) : ( <> - {/* Progress Steps */}
{[1, 2, 3].map((s) => (
- {/* Error */} {error && (
@@ -331,10 +312,8 @@ export function CreatePlacementsDialog({
)} - {/* Step 1: Channels */} {step === 1 && (
- {/* Add new channel */}
@@ -354,7 +333,6 @@ export function CreatePlacementsDialog({

- {/* Selected channels */} {selectedChannels.length > 0 && (
@@ -379,7 +357,6 @@ export function CreatePlacementsDialog({
)} - {/* Existing project channels */} {projectChannels.length > 0 && (
@@ -432,7 +409,6 @@ export function CreatePlacementsDialog({
)} - {/* Step 2: Details */} {step === 2 && (
@@ -479,21 +455,20 @@ export function CreatePlacementsDialog({ onChange={(e) => setPlacementDate(e.target.value)} />
-
-
- -