+ {[1, 2, 3].map((s) => (
+
+
= s
+ ? "bg-primary text-primary-foreground"
+ : "bg-muted text-muted-foreground"
+ )}
+ >
+ {step > s ? : s}
+
+ {s < 3 && (
+
s ? "bg-primary" : "bg-muted"
+ )}
+ />
+ )}
+
+ ))}
+
+
+ {/* Step 1: Creative */}
+ {step === 1 && (
+
+
Выберите креатив
+
+ {creatives.filter(c => c.status === "active").map((creative) => (
+
+ ))}
+
+
+
+
+
+ )}
+
+ {/* Step 2: Channels */}
+ {step === 2 && (
+
+
Добавьте каналы
+
+ Введите каналы в любом формате, например:
+
+
+ t.me/username, @username, tgstat.ru/channel/@username, telemetr.me/content/username
+
+
+
+
+
+
+
+
+
+ )}
+
+ {/* Step 3: Details */}
+ {step === 3 && (
+
+
Детали размещения
+
+ {/* Summary of selected channels */}
+
+
Выбрано каналов: {validChannels.length}
+
+ {validChannels.slice(0, 5).map((c, i) => (
+
+ {c.normalized}
+
+ ))}
+ {validChannels.length > 5 && (
+ +{validChannels.length - 5} ещё
+ )}
+
+
+
+
+
+
+
+
+
+
+
+ date && setPlacementDate(date)}
+ locale={ru}
+ disabled={(date) => date < new Date()}
+ />
+
+
+
+
+
+
+ setCost(e.target.value)}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {error && (
+
+ {error}
+
+ )}
+
+
+
+
+
+
+ )}
+ >
+ )}
+
+
+ );
+}
diff --git a/lib/api/channels.ts b/lib/api/channels.ts
index d4a2931..613cf29 100644
--- a/lib/api/channels.ts
+++ b/lib/api/channels.ts
@@ -15,9 +15,10 @@ interface CreateChannelInput {
}
interface CreateChannelResult {
- channel: {
- id: string;
- };
+ index: number;
+ status: "created" | "updated" | "failed";
+ channel: Channel | null;
+ error?: string;
}
interface CreateChannelsResponse {
diff --git a/lib/utils/channel-parser.ts b/lib/utils/channel-parser.ts
index 70de419..0daae86 100644
--- a/lib/utils/channel-parser.ts
+++ b/lib/utils/channel-parser.ts
@@ -13,11 +13,11 @@ export function parseChannelInput(input: string): string | null {
// Patterns for different URL formats
const patterns: RegExp[] = [
- /telemetr\.me\/content\/([a-zA-Z0-9_]+)/, // telemetr.me/content/rian_ru
- /telemetr\.me\/([a-zA-Z0-9_]+)/, // telemetr.me/rian_ru (alternative)
- /t\.me\/([a-zA-Z0-9_]+)/, // t.me/rian_ru or https://t.me/rian_ru
- /tgstat\.ru\/channel\/@?([a-zA-Z0-9_]+)/, // tgstat.ru/channel/@rian_ru or tgstat.ru/channel/rian_ru
- /tg\.me\/([a-zA-Z0-9_]+)/, // tg.me/rian_ru
+ /telemetr\.me\/content\/([a-zA-Z0-9_]+)/, // telemetr.me/content/username
+ /telemetr\.me\/([a-zA-Z0-9_]+)/, // telemetr.me/username (alternative)
+ /t\.me\/([a-zA-Z0-9_]+)/, // t.me/username or https://t.me/username
+ /tgstat\.ru\/channel\/@?([a-zA-Z0-9_]+)/, // tgstat.ru/channel/@username or tgstat.ru/channel/username
+ /tg\.me\/([a-zA-Z0-9_]+)/, // tg.me/username
];
for (const pattern of patterns) {
diff --git a/lib/utils/constants.ts b/lib/utils/constants.ts
index 2b7a402..1fac184 100644
--- a/lib/utils/constants.ts
+++ b/lib/utils/constants.ts
@@ -56,13 +56,10 @@ export const buildRoute = {
// Creatives
creatives: (workspaceId: string) => `/dashboard/${workspaceId}/creatives`,
- creativeNew: (workspaceId: string) => `/dashboard/${workspaceId}/creatives/new`,
creativeDetail: (workspaceId: string, creativeId: string) =>
`/dashboard/${workspaceId}/creatives/${creativeId}`,
// Placements
- placements: (workspaceId: string) => `/dashboard/${workspaceId}/placements`,
- placementNew: (workspaceId: string) => `/dashboard/${workspaceId}/placements/new`,
placementDetail: (workspaceId: string, placementId: string) =>
`/dashboard/${workspaceId}/placements/${placementId}`,
diff --git a/public/icons/telegram.svg b/public/icons/telegram.svg
new file mode 100644
index 0000000..ce362fb
--- /dev/null
+++ b/public/icons/telegram.svg
@@ -0,0 +1 @@
+
\ No newline at end of file