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

165 lines
4.4 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 projectsForPlacementPerPage = 6
type SelectProjectForPlacement struct {
WorkspaceID string
CurrentPage int
AddPlacementState *AddPlacement
}
func (s *SelectProjectForPlacement) 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.renderProjects(b, mode, jwt)
}
func (s *SelectProjectForPlacement) renderProjects(b *bot.Bot, mode bot.RenderMode, jwt string) {
page, err := b.Backend.GetProjects(context.Background(), jwt, s.WorkspaceID, s.CurrentPage+1, projectsForPlacementPerPage)
if err != nil {
log.Error().Err(err).Msg("Failed to get projects")
b.SendNew("❌ Не удалось загрузить проекты", bot.Keyboard())
return
}
text := "<b>Выбор проекта</b>\n\n"
var buttons [][]echotron.InlineKeyboardButton
if len(page.Items) == 0 {
text += "У вас пока нет проектов"
} 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
// Первый проект в ряду
project := page.Items[i]
row = append(row, bot.Button(project.Title, fmt.Sprintf("select:%s", project.ID)))
// Второй проект в ряду (если есть)
if i+1 < len(page.Items) {
project = page.Items[i+1]
row = append(row, bot.Button(project.Title, fmt.Sprintf("select:%s", project.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("« Назад", "back")))
keyboard := bot.Keyboard(buttons...)
b.Render(text, keyboard, mode)
}
func (s *SelectProjectForPlacement) 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 *SelectProjectForPlacement) 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 == "back":
if s.AddPlacementState != nil {
b.SetState(s.AddPlacementState, bot.EditMessage)
}
case strings.HasPrefix(data, "select:"):
parts := strings.Split(data, ":")
if len(parts) == 2 {
projectID := parts[1]
// Загружаем полные данные проекта
project, err := b.Backend.GetProject(context.Background(), s.WorkspaceID, projectID)
if err != nil {
log.Error().Err(err).Str("project_id", projectID).Msg("Failed to get project")
return
}
// Сохраняем выбранный проект в состояние AddPlacement
if s.AddPlacementState != nil {
s.AddPlacementState.SelectedProject = project
// Сбрасываем креатив при смене проекта
s.AddPlacementState.SelectedCreative = nil
b.SetState(s.AddPlacementState, bot.EditMessage)
}
}
default:
s.Enter(b, bot.NewMessage)
}
}
func (s *SelectProjectForPlacement) HandleMessage(_ *bot.Bot, _ *echotron.Update) { return }
func (s *SelectProjectForPlacement) Handle(_ *bot.Bot, _ *echotron.Update) { return }