Files
tgex-backend/tg_bot/screens/project_details.go
Artem Tsyrulnikov b212b6c22f фиксы
2026-02-01 11:10:22 +03:00

192 lines
5.2 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"
"github.com/NicoNex/echotron/v3"
"github.com/TelegramExchange/tgex-backend/tg_bot/backend"
"github.com/TelegramExchange/tgex-backend/tg_bot/bot"
"github.com/rs/zerolog/log"
)
type ProjectDetails struct {
Project *backend.Project
BackState bot.State
}
func (s *ProjectDetails) Enter(b *bot.Bot, mode bot.RenderMode) {
if s.Project == nil {
b.SendNew("❌ Проект не найден", Keyboard(
Row(Button("← Назад", "back")),
))
return
}
text := s.formatProjectDetails()
keyboard := s.buildKeyboard()
b.Render(text, keyboard, mode)
messageID := b.LastMessageID
username := usernameFromProject(s.Project)
status := statusFromProject(s.Project)
updateProjectHeaderMedia(b, messageID, text, keyboard, s.Project.TelegramID, s.Project.Title, username, status)
}
func (s *ProjectDetails) formatProjectDetails() string {
p := s.Project
text := fmt.Sprintf("<b>%s</b>\n\n", p.Title)
if p.Username != nil && *p.Username != "" {
text += fmt.Sprintf("▸ Tg username: @%s\n", *p.Username)
} else {
text += "▸ Tg username: <i>не привязан</i>\n"
}
// Статус проекта
var statusSymbol, statusText string
switch p.Status {
case "active":
statusSymbol, statusText = "●", "Активный"
case "inactive":
statusSymbol, statusText = "○", "Неактивен"
case "archived":
statusSymbol, statusText = "■", "Архивный"
case "paused":
statusSymbol, statusText = "◐", "Приостановлен"
default:
statusSymbol, statusText = "○", p.Status
}
text += fmt.Sprintf("▸ Статус: %s %s\n", statusSymbol, statusText)
text += "\nУправление проектом"
return text
}
func (s *ProjectDetails) buildKeyboard() echotron.InlineKeyboardMarkup {
var buttons [][]echotron.InlineKeyboardButton
buttons = append(buttons, Row(
Button("Креативы", fmt.Sprintf("creatives:%s", s.Project.ID)),
Button("Размещения", fmt.Sprintf("placements:%s", s.Project.ID)),
))
// Второй ряд: Тип вступления по умолчанию для закупов
var currentType string
if s.Project.PurchaseInviteTypeDefault == "public" {
currentType = "открытая"
} else {
currentType = "с заявками"
}
buttons = append(buttons, Row(
Button(fmt.Sprintf("Ссылка: %s", currentType), fmt.Sprintf("link_type:%s", s.Project.ID)),
))
// Нижний ряд: Назад и Архивировать
buttons = append(buttons, Row(
Button("← Назад", "back"),
Button("≡ Архивировать", fmt.Sprintf("archive:%s", s.Project.ID)),
))
return Keyboard(buttons...)
}
func (s *ProjectDetails) HandleCallback(b *bot.Bot, u *echotron.Update) {
if u.CallbackQuery == nil || u.CallbackQuery.Data == "" {
return
}
data := u.CallbackQuery.Data
switch {
case data == "back":
if s.BackState != nil {
s.transitionWithNewMessage(b, s.BackState)
}
case strings.HasPrefix(data, "creatives:"):
b.SetState(&Creatives{
ProjectID: s.Project.ID,
ProjectTitle: s.Project.Title,
ProjectTelegramID: s.Project.TelegramID,
ProjectUsername: usernameFromProject(s.Project),
ProjectStatus: statusFromProject(s.Project),
BackState: s,
}, bot.EditMessage)
case strings.HasPrefix(data, "placements:"):
b.SetState(&Placements{
ProjectID: s.Project.ID,
ProjectTitle: s.Project.Title,
ProjectTelegramID: s.Project.TelegramID,
ProjectUsername: usernameFromProject(s.Project),
ProjectStatus: statusFromProject(s.Project),
BackState: s,
}, bot.EditMessage)
case data == "back_to_project":
s.Enter(b, bot.EditMessage)
case strings.HasPrefix(data, "link_type:"):
var newType string
if s.Project.PurchaseInviteTypeDefault == "public" {
newType = "approval"
} else {
newType = "public"
}
updatedProject, err := b.Backend.UpdateProjectInviteLinkType(context.Background(), b.Session.JWT, b.Session.WorkspaceID, s.Project.ID, newType)
if err != nil {
b.SendNew(fmt.Sprintf("❌ Ошибка при изменении типа ссылки: %v", err), Keyboard(
Row(Button("← Назад", "back_to_project")),
))
return
}
s.Project = updatedProject
s.Enter(b, bot.EditMessage)
default:
// Для остальных кнопок показываем заглушку
b.Edit(fmt.Sprintf("🚧 Функция в разработке\n\nCallback: %s", data), Keyboard(
Row(Button("← Назад", "back_to_project")),
))
}
return
}
func (s *ProjectDetails) HandleMessage(_ *bot.Bot, _ *echotron.Update) { return }
func (s *ProjectDetails) Handle(_ *bot.Bot, _ *echotron.Update) { return }
func (s *ProjectDetails) Exit() {}
func (s *ProjectDetails) transitionWithNewMessage(b *bot.Bot, next bot.State) {
if b.LastMessageID != 0 {
if _, err := b.DeleteMessage(b.ChatID, b.LastMessageID); err != nil {
log.Error().Err(err).Msg("DeleteMessage failed")
} else {
b.LastMessageID = 0
}
}
b.SetState(next, bot.NewMessage)
}
func usernameFromProject(p *backend.Project) string {
if p == nil || p.Username == nil {
return ""
}
return *p.Username
}
func statusFromProject(p *backend.Project) string {
if p == nil {
return ""
}
return p.Status
}