feat: add header channel selector & adding channel modal menu
This commit is contained in:
@@ -52,31 +52,35 @@ import {
|
||||
Clock,
|
||||
Archive,
|
||||
} from "lucide-react";
|
||||
import type { Purchase, TargetChannel } from "@/lib/types/api";
|
||||
import type { Purchase } from "@/lib/types/api";
|
||||
import { Alert, AlertDescription } from "@/components/ui/alert";
|
||||
import { useTargetChannel } from "@/components/providers/target-channel-provider";
|
||||
|
||||
export default function PurchasesPage() {
|
||||
const { selectedChannel } = useTargetChannel();
|
||||
const [purchases, setPurchases] = useState<Purchase[]>([]);
|
||||
const [channels, setChannels] = useState<TargetChannel[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [filterChannel, setFilterChannel] = useState<string>("all");
|
||||
const [filterStatus, setFilterStatus] = useState<string>("all");
|
||||
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
}, []);
|
||||
if (selectedChannel) {
|
||||
loadData();
|
||||
} else {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [selectedChannel]);
|
||||
|
||||
const loadData = async () => {
|
||||
if (!selectedChannel) return;
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
const [purchasesRes, channelsRes] = await Promise.all([
|
||||
purchasesApi.list(),
|
||||
channelsApi.list(),
|
||||
]);
|
||||
const purchasesRes = await purchasesApi.list({
|
||||
target_channel_id: selectedChannel.id,
|
||||
});
|
||||
setPurchases(purchasesRes.placements);
|
||||
setChannels(channelsRes.target_channels);
|
||||
} catch (err: any) {
|
||||
setError(err?.error?.message || "Ошибка загрузки данных");
|
||||
} finally {
|
||||
@@ -90,15 +94,8 @@ export default function PurchasesPage() {
|
||||
purchase.external_channel_title
|
||||
.toLowerCase()
|
||||
.includes(searchQuery.toLowerCase()) ||
|
||||
purchase.target_channel_title
|
||||
.toLowerCase()
|
||||
.includes(searchQuery.toLowerCase()) ||
|
||||
purchase.creative_name.toLowerCase().includes(searchQuery.toLowerCase());
|
||||
|
||||
// Фильтр по каналу
|
||||
const matchesChannel =
|
||||
filterChannel === "all" || purchase.target_channel_id === filterChannel;
|
||||
|
||||
// Фильтр по статусу
|
||||
let matchesStatus = true;
|
||||
if (filterStatus === "archived") {
|
||||
@@ -107,7 +104,7 @@ export default function PurchasesPage() {
|
||||
matchesStatus = purchase.status === "active";
|
||||
}
|
||||
|
||||
return matchesSearch && matchesChannel && matchesStatus;
|
||||
return matchesSearch && matchesStatus;
|
||||
});
|
||||
|
||||
// Статистика
|
||||
@@ -215,20 +212,6 @@ export default function PurchasesPage() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Select value={filterChannel} onValueChange={setFilterChannel}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Целевой канал" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="all">Все каналы</SelectItem>
|
||||
{channels.map((channel) => (
|
||||
<SelectItem key={channel.id} value={channel.id}>
|
||||
{channel.title}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<Select value={filterStatus} onValueChange={setFilterStatus}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Статус" />
|
||||
@@ -264,16 +247,12 @@ export default function PurchasesPage() {
|
||||
<div className="text-center py-12">
|
||||
<ShoppingCart className="h-12 w-12 text-muted-foreground mx-auto mb-4" />
|
||||
<p className="text-lg font-medium text-muted-foreground">
|
||||
{searchQuery ||
|
||||
filterChannel !== "all" ||
|
||||
filterStatus !== "all"
|
||||
{searchQuery || filterStatus !== "all"
|
||||
? "Закупы не найдены"
|
||||
: "Нет закупов"}
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
{searchQuery ||
|
||||
filterChannel !== "all" ||
|
||||
filterStatus !== "all"
|
||||
{searchQuery || filterStatus !== "all"
|
||||
? "Попробуйте изменить фильтры"
|
||||
: "Создайте первый закуп"}
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user