package screens
import (
"context"
"fmt"
"strings"
"example.com/m/adapter/backend"
"example.com/m/bot"
"github.com/NicoNex/echotron/v3"
"github.com/rs/zerolog/log"
)
type ProjectDetails struct {
Project *backend.Project
WorkspaceID string
BackState bot.State
confirmingLinkTypeChange bool // Флаг для двухшагового подтверждения смены типа ссылки
}
func (s *ProjectDetails) Enter(b *bot.Bot, mode bot.RenderMode) {
if s.Project == nil {
b.SendNew("❌ Проект не найден", Keyboard(
Row(Button("← Назад", "back_to_projects")),
))
return
}
text := s.formatProjectDetails()
keyboard := s.buildKeyboard()
b.Render(text, keyboard, mode)
}
func (s *ProjectDetails) formatProjectDetails() string {
p := s.Project
text := fmt.Sprintf("%s\n\n", p.Title)
// Информация о канале
if p.Username != nil && *p.Username != "" {
text += fmt.Sprintf("▸ Telegram: @%s\n", *p.Username)
} else {
text += "▸ Telegram: не привязан\n"
}
// Статус проекта
var statusSymbol string
var 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("purchases:%s", s.Project.ID)),
))
// Второй ряд: Тип вступления по умолчанию для закупов (с подтверждением)
var linkTypeButtonText string
if s.confirmingLinkTypeChange {
// Показываем подтверждение
var newType string
if s.Project.PurchaseInviteTypeDefault == "public" {
newType = "По заявке"
} else {
newType = "Свободное"
}
linkTypeButtonText = fmt.Sprintf("Изменить → %s", newType)
} else {
// Показываем текущий тип вступления
var currentType string
if s.Project.PurchaseInviteTypeDefault == "public" {
currentType = "Свободное"
} else {
currentType = "По заявке"
}
linkTypeButtonText = fmt.Sprintf("Вступление: %s", currentType)
}
buttons = append(buttons, Row(
Button(linkTypeButtonText, fmt.Sprintf("link_type:%s", s.Project.ID)),
))
// Нижний ряд: Назад и Архивировать
buttons = append(buttons, Row(
Button("← Назад", "back_to_projects"),
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_to_projects", data == "back":
s.confirmingLinkTypeChange = false // Сбрасываем флаг подтверждения
if s.BackState != nil {
b.SetState(s.BackState, bot.EditMessage)
}
case strings.HasPrefix(data, "creatives:"):
s.confirmingLinkTypeChange = false // Сбрасываем флаг подтверждения
b.SetState(&Creatives{
ProjectID: s.Project.ID,
WorkspaceID: s.WorkspaceID,
BackState: s,
}, bot.EditMessage)
case strings.HasPrefix(data, "purchases:"):
s.confirmingLinkTypeChange = false // Сбрасываем флаг подтверждения
b.SetState(&Purchases{
WorkspaceID: s.WorkspaceID,
ProjectID: s.Project.ID,
ProjectTitle: s.Project.Title,
BackState: s,
}, bot.EditMessage)
case data == "back_to_project":
s.confirmingLinkTypeChange = false // Сбрасываем флаг подтверждения
s.Enter(b, bot.EditMessage)
case strings.HasPrefix(data, "link_type:"):
if !s.confirmingLinkTypeChange {
// Первое нажатие - включаем режим подтверждения
s.confirmingLinkTypeChange = true
s.Enter(b, bot.EditMessage)
} else {
// Второе нажатие - меняем тип ссылки
var newType string
if s.Project.PurchaseInviteTypeDefault == "public" {
newType = "approval"
} else {
newType = "public"
}
log.Info().
Str("workspace_id", s.WorkspaceID).
Str("project_id", s.Project.ID).
Str("old_type", s.Project.PurchaseInviteTypeDefault).
Str("new_type", newType).
Msg("Updating project invite link type")
updatedProject, err := b.Backend.UpdateProjectInviteLinkType(
context.Background(),
b.Session.JWT,
s.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.confirmingLinkTypeChange = false
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() {}