Files
tgex-backend/telegram_bot/screens/select_creative_for_placement.go
2026-01-01 19:33:37 +03:00

189 lines
5.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 := "<b>Выбор креатива</b>\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 }