package screens import ( "context" "fmt" "strings" "example.com/m/bot" "github.com/NicoNex/echotron/v3" "github.com/rs/zerolog/log" ) const creativesForPlacementPerPage = 6 type SelectCreativeForPlacement struct { WorkspaceID string ProjectID string CurrentPage int AddPlacementState *AddPlacement } func (s *SelectCreativeForPlacement) Enter(b *bot.Bot, mode bot.RenderMode) { jwt, err := s.ensureJWT(b) if err != nil { log.Error().Err(err).Msg("Failed to get JWT") b.SendNew("❌ Ошибка авторизации. Попробуйте /start", bot.Keyboard()) return } s.renderCreatives(b, mode, jwt) } func (s *SelectCreativeForPlacement) renderCreatives(b *bot.Bot, mode bot.RenderMode, jwt string) { page, err := b.Backend.GetCreatives( context.Background(), jwt, s.WorkspaceID, &s.ProjectID, false, // includeArchived s.CurrentPage+1, creativesForPlacementPerPage, ) if err != nil { log.Error().Err(err).Msg("Failed to get creatives") b.SendNew("❌ Не удалось загрузить креативы", bot.Keyboard()) return } text := "Выбор креатива\n\n" var buttons [][]echotron.InlineKeyboardButton if len(page.Items) == 0 { text += "У выбранного проекта пока нет креативов.\n\nСоздайте креатив через меню проекта." } else { text += fmt.Sprintf("Выберите креатив (стр. %d из %d):", s.CurrentPage+1, page.Pages) // Креативы по 2 в ряду for i := 0; i < len(page.Items); i += 2 { var row []echotron.InlineKeyboardButton // Первый креатив в ряду creative := page.Items[i] row = append(row, bot.Button(creative.Name, fmt.Sprintf("select:%s", creative.ID))) // Второй креатив в ряду (если есть) if i+1 < len(page.Items) { creative = page.Items[i+1] row = append(row, bot.Button(creative.Name, fmt.Sprintf("select:%s", creative.ID))) } else { row = append(row, bot.Button(" ", "empty")) } buttons = append(buttons, row) } // Кнопки пагинации var navRow []echotron.InlineKeyboardButton if s.CurrentPage > 0 { navRow = append(navRow, bot.Button("←", "prev")) } else { navRow = append(navRow, bot.Button("·", "empty")) } pageButton := bot.Button(fmt.Sprintf("• %d/%d •", s.CurrentPage+1, page.Pages), "page_info") navRow = append(navRow, pageButton) if s.CurrentPage+1 < page.Pages { navRow = append(navRow, bot.Button("→", "next")) } else { navRow = append(navRow, bot.Button("·", "empty")) } buttons = append(buttons, navRow) } // Опция пропустить выбор креатива (креатив опционален) buttons = append(buttons, bot.Row(bot.Button("Без креатива", "skip"))) // Кнопка возврата buttons = append(buttons, bot.Row(bot.Button("« Назад", "back"))) keyboard := bot.Keyboard(buttons...) b.Render(text, keyboard, mode) } func (s *SelectCreativeForPlacement) ensureJWT(b *bot.Bot) (string, error) { if b.Session.JWT != "" { return b.Session.JWT, nil } jwt, err := b.Backend.GetJWTByTelegramID(context.Background(), b.ChatID) if err != nil { return "", err } b.Session.JWT = jwt return jwt, nil } func (s *SelectCreativeForPlacement) HandleCallback(b *bot.Bot, u *echotron.Update) { if u.CallbackQuery == nil || u.CallbackQuery.Data == "" { return } data := u.CallbackQuery.Data switch { case data == "prev": if s.CurrentPage > 0 { s.CurrentPage-- } s.Enter(b, bot.EditMessage) case data == "next": s.CurrentPage++ s.Enter(b, bot.EditMessage) case data == "page_info", data == "empty": return case data == "skip": // Пропускаем выбор креатива if s.AddPlacementState != nil { s.AddPlacementState.SelectedCreative = nil b.SetState(s.AddPlacementState, bot.EditMessage) } case data == "back": if s.AddPlacementState != nil { b.SetState(s.AddPlacementState, bot.EditMessage) } case strings.HasPrefix(data, "select:"): parts := strings.Split(data, ":") if len(parts) == 2 { creativeID := parts[1] // Получаем JWT jwt, err := s.ensureJWT(b) if err != nil { log.Error().Err(err).Msg("Failed to get JWT") return } // Загружаем полные данные креатива creative, err := b.Backend.GetCreative(context.Background(), jwt, s.WorkspaceID, creativeID) if err != nil { log.Error().Err(err).Str("creative_id", creativeID).Msg("Failed to get creative") return } // Сохраняем выбранный креатив в состояние AddPlacement if s.AddPlacementState != nil { s.AddPlacementState.SelectedCreative = creative b.SetState(s.AddPlacementState, bot.EditMessage) } } default: s.Enter(b, bot.NewMessage) } } func (s *SelectCreativeForPlacement) HandleMessage(_ *bot.Bot, _ *echotron.Update) { return } func (s *SelectCreativeForPlacement) Handle(_ *bot.Bot, _ *echotron.Update) { return }