feat: platform update
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useParams, useRouter, useSearchParams } from "next/navigation";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import {
|
||||
Loader2,
|
||||
@@ -36,8 +37,6 @@ import { DashboardHeader } from "@/components/layout/dashboard-header";
|
||||
import { useWorkspace } from "@/components/providers/workspace-provider";
|
||||
import { demoAwarePlacementsApi } from "@/lib/demo";
|
||||
import { placementsApi, creativesApi } from "@/lib/api";
|
||||
import { AddChannelDialog } from "@/components/dialog-add-channel";
|
||||
import { CreatePlacementsDialog } from "@/components/dialog-create-placements";
|
||||
import { FiltersModal, PlacementFilters } from "@/components/filters-modal";
|
||||
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
@@ -82,6 +81,7 @@ 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 { PlacementWizard } from "@/components/placement-wizard";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type {
|
||||
Project,
|
||||
@@ -933,13 +933,13 @@ function ChannelGroup({
|
||||
{channel.username && (
|
||||
<div className="flex items-center gap-1 ml-2">
|
||||
<a
|
||||
href={`https://telemetr.me/channel/${channel.username}`}
|
||||
href={`https://telemetr.me/content/${channel.username}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center h-6 w-6 hover:opacity-75 transition-opacity"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<img src="/icons/telemetr.jpg" alt="TgStat" className="h-5 w-5 rounded" />
|
||||
<Image src="/icons/telemetr.jpg" width={20} height={20} alt="TgStat" className="h-5 w-5 rounded" />
|
||||
</a>
|
||||
<a
|
||||
href={`https://tgstat.ru/channel/@${channel.username}`}
|
||||
@@ -948,7 +948,7 @@ function ChannelGroup({
|
||||
className="flex items-center justify-center h-6 w-6 hover:opacity-75 transition-opacity"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<img src="/icons/tgstat.jpg" alt="TgStat" className="h-5 w-5 rounded" />
|
||||
<Image src="/icons/tgstat.jpg" width={20} height={20} alt="TgStat" className="h-5 w-5 rounded" />
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
@@ -1086,10 +1086,9 @@ export default function PurchasePlanDetailPage() {
|
||||
const [saveError, setSaveError] = useState<string | null>(null);
|
||||
const [editingCell, setEditingCell] = useState<EditingCell | null>(null);
|
||||
|
||||
// Create placements dialog
|
||||
// Placement wizard state
|
||||
const prefilledCreativeId = searchParams.get("creative_id");
|
||||
const [prefilledChannelIds, setPrefilledChannelIds] = useState<string[] | null>(null);
|
||||
const [showCreateDialog, setShowCreateDialog] = useState(false);
|
||||
const [showPlacementWizard, setShowPlacementWizard] = useState(false);
|
||||
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [statusFilter, setStatusFilter] = useState("all");
|
||||
@@ -1109,6 +1108,9 @@ export default function PurchasePlanDetailPage() {
|
||||
const [selectedPlacementForCreative, setSelectedPlacementForCreative] = useState<PlacementWithStats | null>(null);
|
||||
const [creatives, setCreatives] = useState<Array<{ id: string; name: string; thumbnail_url?: string | null }>>([]);
|
||||
|
||||
// Placement wizard
|
||||
const [wizardInitialCreative, setWizardInitialCreative] = useState<string | null>(null);
|
||||
|
||||
const loadCreatives = async () => {
|
||||
try {
|
||||
const response = await creativesApi.list(workspaceId, {
|
||||
@@ -1169,19 +1171,15 @@ export default function PurchasePlanDetailPage() {
|
||||
}
|
||||
}, [projects, projectId]);
|
||||
|
||||
// Auto-open create dialog if creative_id is provided
|
||||
// Handle URL params for placement wizard
|
||||
useEffect(() => {
|
||||
if (prefilledCreativeId && project) {
|
||||
setShowCreateDialog(true);
|
||||
const openPlacement = searchParams.get("openPlacement");
|
||||
if (openPlacement === "true") {
|
||||
const creativeId = searchParams.get("creative_id");
|
||||
setWizardInitialCreative(creativeId);
|
||||
setShowPlacementWizard(true);
|
||||
}
|
||||
}, [prefilledCreativeId, project]);
|
||||
|
||||
// Auto-open create dialog if channel_ids are provided
|
||||
useEffect(() => {
|
||||
if (prefilledChannelIds && project) {
|
||||
setShowCreateDialog(true);
|
||||
}
|
||||
}, [prefilledChannelIds, project]);
|
||||
}, [searchParams]);
|
||||
|
||||
useEffect(() => {
|
||||
loadPlacements();
|
||||
@@ -1700,32 +1698,10 @@ export default function PurchasePlanDetailPage() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<AddChannelDialog
|
||||
workspaceId={workspaceId}
|
||||
projectId={projectId}
|
||||
existingPlacements={placements}
|
||||
onSuccess={loadPlacements}
|
||||
>
|
||||
<Button variant="outline" disabled={isDemoMode}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Добавить канал
|
||||
</Button>
|
||||
</AddChannelDialog>
|
||||
<CreatePlacementsDialog
|
||||
workspaceId={workspaceId}
|
||||
projectId={projectId}
|
||||
existingPlacements={placements}
|
||||
prefilledCreativeId={prefilledCreativeId}
|
||||
prefilledChannelIds={prefilledChannelIds}
|
||||
open={showCreateDialog}
|
||||
onOpenChange={setShowCreateDialog}
|
||||
onSuccess={loadPlacements}
|
||||
>
|
||||
<Button disabled={isDemoMode}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Создать размещения
|
||||
</Button>
|
||||
</CreatePlacementsDialog>
|
||||
<Button disabled={isDemoMode} onClick={() => setShowPlacementWizard(true)}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
Добавить размещения
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1950,6 +1926,15 @@ export default function PurchasePlanDetailPage() {
|
||||
onClear={selectedPlacementForCreative ? () => handleClearCreative(selectedPlacementForCreative.id) : null}
|
||||
currentCreativeId={selectedPlacementForCreative?.creative_id}
|
||||
/>
|
||||
|
||||
<PlacementWizard
|
||||
open={showPlacementWizard}
|
||||
onOpenChange={setShowPlacementWizard}
|
||||
workspaceId={workspaceId}
|
||||
projectId={projectId}
|
||||
initialCreativeId={wizardInitialCreative}
|
||||
onSuccess={loadPlacements}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user