package screens import ( "context" "fmt" "example.com/m/bot" "github.com/NicoNex/echotron/v3" "github.com/rs/zerolog/log" ) type Purchases struct { WorkspaceID string ProjectID string ProjectTitle string BackState bot.State } func (s *Purchases) Enter(b *bot.Bot, mode bot.RenderMode) { jwt := b.Session.JWT if jwt == "" { log.Error().Msg("JWT is empty in session") b.SendNew("❌ Ошибка авторизации. Попробуйте /start", bot.Keyboard()) return } s.renderPurchases(b, mode, jwt) } func (s *Purchases) renderPurchases(b *bot.Bot, mode bot.RenderMode, jwt string) { purchases, err := b.Backend.GetPurchases( context.Background(), jwt, s.WorkspaceID, s.ProjectID, ) if err != nil { log.Error().Err(err).Msg("Failed to get purchases") b.SendNew("❌ Не удалось загрузить закупы", bot.Keyboard()) return } // Навигация: 2 последних уровня navPath := "… › Закупы" if s.ProjectTitle != "" { navPath = fmt.Sprintf("… › %s › Закупы", s.ProjectTitle) } text := fmt.Sprintf("%s\n\nЗакупы\n\n", navPath) var buttons [][]echotron.InlineKeyboardButton if len(purchases) == 0 { text += `Список закупов пуст. Закуп — это план размещения рекламы в каналах: ‣ Выбор креатива ‣ Список каналов для размещения ‣ Планируемая стоимость ‣ Статус выполнения Создайте первый закуп` } else { text += "Управление закупами для проекта.\n\n" text += "Выберите закуп для деталей:\n\n" for i, purchase := range purchases { // Определяем статус statusSymbol := "●" switch purchase.Status { case "active": statusSymbol = "●" case "archived": statusSymbol = "■" } // Считаем каналы по статусам totalChannels := len(purchase.Channels) completedChannels := 0 for _, ch := range purchase.Channels { if ch.Status == "completed" { completedChannels++ } } buttonText := fmt.Sprintf("%s Закуп #%d (%d/%d каналов)", statusSymbol, i+1, completedChannels, totalChannels, ) buttons = append(buttons, bot.Row( bot.Button(buttonText, fmt.Sprintf("purchase:%s", purchase.ID)), )) } } // Кнопка создания нового закупа buttons = append(buttons, bot.Row( bot.Button("+ Создать закуп", "add_purchase"), )) // Кнопка назад buttons = append(buttons, bot.Row( bot.Button("← Назад", "back"), )) keyboard := bot.Keyboard(buttons...) b.Render(text, keyboard, mode) } func (s *Purchases) 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, ActivePicker: "", BackState: s, }, bot.EditMessage) default: // Проверяем, не нажали ли на конкретный закуп if len(data) > 9 && data[:9] == "purchase:" { purchaseID := data[9:] b.SetState(&PurchaseDetails{ WorkspaceID: s.WorkspaceID, ProjectID: s.ProjectID, ProjectTitle: s.ProjectTitle, PurchaseID: purchaseID, BackState: s, }, bot.NewMessage) } else { s.Enter(b, bot.NewMessage) } } } func (s *Purchases) HandleMessage(_ *bot.Bot, _ *echotron.Update) { return } func (s *Purchases) Handle(_ *bot.Bot, _ *echotron.Update) { return }