package screens import ( "context" "fmt" "example.com/m/bot" "github.com/NicoNex/echotron/v3" "github.com/rs/zerolog/log" ) const addPurchaseCreativesPerPage = 5 type AddPurchase struct { WorkspaceID string ProjectID string ProjectTitle string CurrentPage int BackState bot.State } func (s *AddPurchase) 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.renderCreativeSelection(b, mode, jwt) } func (s *AddPurchase) renderCreativeSelection(b *bot.Bot, mode bot.RenderMode, jwt string) { // Получаем список активных креативов page, err := b.Backend.GetCreatives( context.Background(), jwt, s.WorkspaceID, &s.ProjectID, false, // только активные s.CurrentPage+1, addPurchaseCreativesPerPage, ) if err != nil { log.Error().Err(err).Msg("Failed to get creatives") b.SendNew("❌ Не удалось загрузить креативы", bot.Keyboard()) return } text := "… › Закупы › Создание\n\nСоздание закупа\n\n" var buttons [][]echotron.InlineKeyboardButton if len(page.Items) == 0 { text += `Для создания закупа сначала нужно создать креатив. Вернитесь назад и создайте креатив в разделе Креативы` buttons = append(buttons, bot.Row( bot.Button("← Назад", "back"), )) } else { pageInfo := "" if page.Pages > 1 { pageInfo = fmt.Sprintf(" (стр. %d/%d)", page.Page, page.Pages) } text += fmt.Sprintf(`Шаг 1/2: Выбор креатива%s Выберите креатив для закупа `, pageInfo) // Кнопки с креативами for _, creative := range page.Items { buttons = append(buttons, bot.Row( bot.Button(creative.Name, fmt.Sprintf("creative:%s", creative.ID)), )) } // Пагинация var navRow []echotron.InlineKeyboardButton if s.CurrentPage > 0 { navRow = append(navRow, bot.Button("←", "prev")) } if s.CurrentPage+1 < page.Pages { navRow = append(navRow, bot.Button("→", "next")) } if len(navRow) > 0 { buttons = append(buttons, navRow) } // Кнопка назад buttons = append(buttons, bot.Row( bot.Button("← Отмена", "back"), )) } keyboard := bot.Keyboard(buttons...) b.Render(text, keyboard, mode) } func (s *AddPurchase) 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 *AddPurchase) 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 "prev": if s.CurrentPage > 0 { s.CurrentPage-- } s.Enter(b, bot.EditMessage) case "next": s.CurrentPage++ s.Enter(b, bot.EditMessage) default: // Проверяем, не выбрали ли креатив if len(data) > 9 && data[:9] == "creative:" { creativeID := data[9:] // Переходим к выбору каналов b.SetState(&SelectChannelsForPurchase{ WorkspaceID: s.WorkspaceID, ProjectID: s.ProjectID, ProjectTitle: s.ProjectTitle, CreativeID: creativeID, Channels: []PurchaseChannelInput{}, BackState: s.BackState, }, bot.EditMessage) } else { s.Enter(b, bot.NewMessage) } } } func (s *AddPurchase) HandleMessage(_ *bot.Bot, _ *echotron.Update) { return } func (s *AddPurchase) Handle(_ *bot.Bot, _ *echotron.Update) { return }