package screens import ( "context" "fmt" "example.com/m/bot" "github.com/NicoNex/echotron/v3" "github.com/rs/zerolog/log" ) type PurchaseDetails struct { WorkspaceID string ProjectID string ProjectTitle string PurchaseID string BackState bot.State } func (s *PurchaseDetails) 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.renderDetails(b, mode, jwt) } func (s *PurchaseDetails) renderDetails(b *bot.Bot, mode bot.RenderMode, jwt string) { purchase, err := b.Backend.GetPurchase( context.Background(), jwt, s.WorkspaceID, s.ProjectID, s.PurchaseID, ) if err != nil { log.Error().Err(err).Msg("Failed to get purchase") b.SendNew("❌ Не удалось загрузить закуп", bot.Keyboard()) return } // Получаем информацию о креативе creative, err := b.Backend.GetCreative( context.Background(), jwt, s.WorkspaceID, purchase.CreativeID, ) if err != nil { log.Error().Err(err).Msg("Failed to get creative") creative = nil } text := "… › Закупы › Детали\n\nДетали закупа\n\n" // Информация о креативе if creative != nil { text += fmt.Sprintf("▪ Креатив: %s\n", creative.Name) } else { text += fmt.Sprintf("▪ Креатив ID: %s\n", purchase.CreativeID) } // Статус закупа statusSymbol := "●" statusText := "Активный" if purchase.Status == "archived" { statusSymbol = "■" statusText = "Архивирован" } text += fmt.Sprintf("▪ Статус: %s %s\n\n", statusSymbol, statusText) // Информация о каналах if len(purchase.Channels) == 0 { text += "Каналы не добавлены\n" } else { text += fmt.Sprintf("Каналы (%d):\n\n", len(purchase.Channels)) for i, ch := range purchase.Channels { // Определяем статус statusSymbol := "○" switch ch.Status { case "planned": statusSymbol = "○" case "approved": statusSymbol = "◉" case "rejected": statusSymbol = "⊗" case "in_progress": statusSymbol = "◐" case "completed": statusSymbol = "●" } // Название канала channelName := "Без названия" if ch.Channel.Title != nil { channelName = *ch.Channel.Title } else if ch.Channel.Username != nil { channelName = "@" + *ch.Channel.Username } text += fmt.Sprintf("%d. %s %s\n", i+1, statusSymbol, channelName) // Стоимость if ch.Details != nil && ch.Details.Cost != nil { text += fmt.Sprintf(" ▸ Стоимость: %.0f₽\n", ch.Details.Cost.Value) } // Комментарий if ch.Comment != nil && *ch.Comment != "" { text += fmt.Sprintf(" ▸ %s\n", *ch.Comment) } // Тип invite link inviteLinkTypeText := "публичная" if ch.InviteLinkType == "approval" { inviteLinkTypeText = "с одобрением" } text += fmt.Sprintf(" ▸ Ссылка: %s\n", inviteLinkTypeText) text += "\n" } } var buttons [][]echotron.InlineKeyboardButton // Кнопка назад buttons = append(buttons, bot.Row( bot.Button("← Назад", "back"), )) keyboard := bot.Keyboard(buttons...) b.Render(text, keyboard, mode) } func (s *PurchaseDetails) 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) } default: s.Enter(b, bot.NewMessage) } } func (s *PurchaseDetails) HandleMessage(_ *bot.Bot, _ *echotron.Update) { return } func (s *PurchaseDetails) Handle(_ *bot.Bot, _ *echotron.Update) { return }