Files
tgex-backend/telegram_bot/screens/purchases.go
2026-01-03 12:41:33 +03:00

168 lines
4.1 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"
"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, err := s.ensureJWT(b)
if err != nil {
log.Error().Err(err).Msg("Failed to get JWT")
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("<i>%s</i>\n\n<b>Закупы</b>\n\n", navPath)
var buttons [][]echotron.InlineKeyboardButton
if len(purchases) == 0 {
text += `Список закупов пуст.
<i>Закуп — это план размещения рекламы в каналах:</i>
‣ Выбор креатива
‣ Список каналов для размещения
‣ Планируемая стоимость
‣ Статус выполнения
Создайте первый закуп`
} 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) 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 *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 }