Files
tgex-backend/tg_bot/screens/purchases.go
2026-01-19 19:24:34 +03:00

139 lines
3.6 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"
"github.com/NicoNex/echotron/v3"
"github.com/TelegramExchange/tgex-backend/tg_bot/bot"
"github.com/rs/zerolog/log"
)
type Placements struct {
WorkspaceID string
ProjectID string
ProjectTitle string
BackState bot.State
}
func (s *Placements) Enter(b *bot.Bot, mode bot.RenderMode) {
jwt := b.Session.JWT
if jwt == "" {
log.Error().Msg("JWT is empty in session")
b.SendNew("❌ Ошибка авторизации. Попробуйте /start", Keyboard())
return
}
s.renderPurchases(b, mode, jwt)
}
func (s *Placements) renderPurchases(b *bot.Bot, mode bot.RenderMode, jwt string) {
resp, err := b.Backend.GetPlacements(
context.Background(),
jwt,
s.WorkspaceID,
s.ProjectID,
)
if err != nil {
log.Error().Err(err).Msg("Failed to get placements")
b.SendNew("❌ Не удалось загрузить размещения", Keyboard())
return
}
text := "<b>Размещения</b>\n\n"
var buttons [][]echotron.InlineKeyboardButton
if len(resp.Placements) == 0 {
text += `Список размещений пуст.
<i>Размещение — это план публикации рекламы в канале:</i>
‣ Выбор креатива
‣ Канал размещения
‣ Стоимость и формат
‣ Статус выполнения
Создайте первое размещение`
} else {
text += "Управление размещениями для проекта.\n\n"
text += "Выберите размещение для деталей:\n\n"
for i, placement := range resp.Placements {
statusSymbol := "●"
if placement.Status == "archived" {
statusSymbol = "■"
}
channelName := "Без названия"
if placement.Channel.Title != nil && *placement.Channel.Title != "" {
channelName = *placement.Channel.Title
} else if placement.Channel.Username != nil && *placement.Channel.Username != "" {
channelName = "@" + *placement.Channel.Username
}
buttonText := fmt.Sprintf("%s Размещение #%d — %s", statusSymbol, i+1, channelName)
buttons = append(buttons, Row(
Button(buttonText, fmt.Sprintf("placement:%s", placement.ID)),
))
}
}
// Кнопка создания нового размещения
buttons = append(buttons, Row(
Button(" Создать размещение", "add_purchase"),
))
// Кнопка назад
buttons = append(buttons, Row(
Button("← Назад", "back"),
))
keyboard := Keyboard(buttons...)
b.Render(text, keyboard, mode)
}
func (s *Placements) 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) > 10 && data[:10] == "placement:" {
placementID := data[10:]
b.SetState(&PlacementDetails{
WorkspaceID: s.WorkspaceID,
ProjectID: s.ProjectID,
PlacementID: placementID,
BackState: s,
}, bot.EditMessage)
} else {
s.Enter(b, bot.NewMessage)
}
}
}
func (s *Placements) HandleMessage(_ *bot.Bot, _ *echotron.Update) { return }
func (s *Placements) Handle(_ *bot.Bot, _ *echotron.Update) { return }
func (s *Placements) Exit() {}