package screens import ( "context" "fmt" "github.com/NicoNex/echotron/v3" "github.com/TelegramExchange/tgex-backend/tg_bot/bot" "github.com/rs/zerolog/log" ) type Placements struct { WorkspaceID string ProjectID string ProjectTitle string ProjectTelegramID int64 ProjectUsername string ProjectStatus string BackState bot.State } func (s *Placements) Enter(b *bot.Bot, mode bot.RenderMode) { jwt := b.Session.JWT if jwt == "" { log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации. Попробуйте /start", Keyboard()) return } s.renderPurchases(b, mode, jwt) } func (s *Placements) renderPurchases(b *bot.Bot, mode bot.RenderMode, jwt string) { resp, err := b.Backend.GetPlacements( context.Background(), jwt, s.WorkspaceID, s.ProjectID, ) if err != nil { log.Error().Err(err).Msg("Failed to get placements") b.SendNew("❌ Не удалось загрузить размещения", Keyboard()) return } text := "Размещения\n\n" var buttons [][]echotron.InlineKeyboardButton if len(resp.Placements) == 0 { text += `Список размещений пуст. Размещение — это план публикации рекламы в канале: ‣ Выбор креатива ‣ Канал размещения ‣ Стоимость и формат ‣ Статус выполнения Создайте первое размещение` } else { text += "Управление размещениями для проекта.\n\n" text += "Выберите размещение для деталей:\n\n" for i, placement := range resp.Placements { statusSymbol := "●" if placement.Status == "archived" { statusSymbol = "■" } channelName := "Без названия" if placement.Channel.Title != nil && *placement.Channel.Title != "" { channelName = *placement.Channel.Title } else if placement.Channel.Username != nil && *placement.Channel.Username != "" { channelName = "@" + *placement.Channel.Username } buttonText := fmt.Sprintf("%s #%d %s", statusSymbol, i+1, channelName) buttons = append(buttons, Row( Button(buttonText, fmt.Sprintf("placement:%s", placement.ID)), )) } } // Кнопка создания нового размещения buttons = append(buttons, Row( Button("+ Создать размещение", "add_purchase"), )) // Кнопка назад buttons = append(buttons, Row( Button("← Назад", "back"), )) keyboard := Keyboard(buttons...) b.Render(text, keyboard, mode) messageID := b.LastMessageID updateProjectHeaderMedia(b, messageID, text, keyboard, s.ProjectTelegramID, s.ProjectTitle, s.ProjectUsername, s.ProjectStatus) } func (s *Placements) HandleCallback(b *bot.Bot, u *echotron.Update) { if u.CallbackQuery == nil || u.CallbackQuery.Data == "" { return } data := u.CallbackQuery.Data switch data { case "back": if s.BackState != nil { b.SetState(s.BackState, bot.EditMessage) } case "add_purchase": b.SetState(&AddPurchase{ WorkspaceID: s.WorkspaceID, ProjectID: s.ProjectID, ProjectTitle: s.ProjectTitle, ProjectTelegramID: s.ProjectTelegramID, ProjectUsername: s.ProjectUsername, ProjectStatus: s.ProjectStatus, ActivePicker: "", BackState: s, }, bot.EditMessage) default: // Проверяем, не нажали ли на конкретное размещение if len(data) > 10 && data[:10] == "placement:" { placementID := data[10:] b.SetState(&PlacementDetails{ WorkspaceID: s.WorkspaceID, ProjectID: s.ProjectID, PlacementID: placementID, BackState: s, }, bot.EditMessage) } else { s.Enter(b, bot.NewMessage) } } } func (s *Placements) HandleMessage(_ *bot.Bot, _ *echotron.Update) { return } func (s *Placements) Handle(_ *bot.Bot, _ *echotron.Update) { return } func (s *Placements) Exit() {}