211 lines
6.2 KiB
Go
211 lines
6.2 KiB
Go
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("❌ Проект не найден", bot.Keyboard(
|
||
bot.Row(bot.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(`<b>%s</b>`, p.Title)
|
||
|
||
// Информация о канале
|
||
if p.Username != nil && *p.Username != "" {
|
||
text += fmt.Sprintf(`
|
||
<b>Канал:</b> @%s`, *p.Username)
|
||
} else {
|
||
text += `
|
||
<b>Канал:</b> <i>не привязан</i>`
|
||
}
|
||
|
||
// Статус проекта
|
||
var statusText string
|
||
switch p.Status {
|
||
case "active":
|
||
statusText = "Активный"
|
||
case "inactive":
|
||
statusText = "Неактивен"
|
||
case "archived":
|
||
statusText = "Архивный"
|
||
case "paused":
|
||
statusText = "Приостановлен"
|
||
default:
|
||
statusText = p.Status
|
||
}
|
||
text += fmt.Sprintf(`
|
||
<b>Статус:</b> %s`, statusText)
|
||
|
||
// ID проекта (для технических целей)
|
||
text += fmt.Sprintf(`
|
||
<b>ID:</b> <code>%s</code>`, p.ID)
|
||
|
||
return text
|
||
}
|
||
|
||
func (s *ProjectDetails) buildKeyboard() echotron.InlineKeyboardMarkup {
|
||
var buttons [][]echotron.InlineKeyboardButton
|
||
|
||
// Первый ряд: Креативы и Создать закуп
|
||
buttons = append(buttons, bot.Row(
|
||
bot.Button("Креативы", fmt.Sprintf("creatives:%s", s.Project.ID)),
|
||
bot.Button("Создать закуп", fmt.Sprintf("create_purchase:%s", s.Project.ID)),
|
||
))
|
||
|
||
// Второй ряд: План закупов
|
||
buttons = append(buttons, bot.Row(
|
||
bot.Button("План закупов", fmt.Sprintf("purchase_plan:%s", s.Project.ID)),
|
||
))
|
||
|
||
// Третий ряд: Тип ссылки по умолчанию
|
||
var linkTypeButtonText string
|
||
if s.confirmingLinkTypeChange {
|
||
// Показываем текст подтверждения с противоположным типом
|
||
var newType string
|
||
if s.Project.InviteLinkType == "public" {
|
||
newType = "С одобрением"
|
||
} else {
|
||
newType = "Открытая"
|
||
}
|
||
linkTypeButtonText = fmt.Sprintf("Нажмите еще раз → %s", newType)
|
||
} else {
|
||
// Показываем текущий тип
|
||
var currentType string
|
||
if s.Project.InviteLinkType == "public" {
|
||
currentType = "Открытая"
|
||
} else {
|
||
currentType = "С одобрением"
|
||
}
|
||
linkTypeButtonText = fmt.Sprintf("Тип ссылки: %s", currentType)
|
||
}
|
||
buttons = append(buttons, bot.Row(
|
||
bot.Button(linkTypeButtonText, fmt.Sprintf("link_type:%s", s.Project.ID)),
|
||
))
|
||
|
||
// Четвертый ряд: Команда и Архивировать
|
||
buttons = append(buttons, bot.Row(
|
||
bot.Button("👥 Команда", fmt.Sprintf("team:%s", s.Project.ID)),
|
||
bot.Button("Архивировать", fmt.Sprintf("archive:%s", s.Project.ID)),
|
||
))
|
||
|
||
// Пятый ряд: Назад и Главное меню
|
||
buttons = append(buttons, bot.Row(
|
||
bot.Button("Назад", "back_to_projects"),
|
||
bot.Button("Главное меню", "main_menu"),
|
||
))
|
||
|
||
return bot.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 data == "main_menu":
|
||
s.confirmingLinkTypeChange = false // Сбрасываем флаг подтверждения
|
||
b.SetState(&MainMenu{}, bot.NewMessage)
|
||
|
||
case strings.HasPrefix(data, "creatives:"):
|
||
s.confirmingLinkTypeChange = false // Сбрасываем флаг подтверждения
|
||
b.SetState(&Creatives{
|
||
ProjectID: s.Project.ID,
|
||
WorkspaceID: s.WorkspaceID,
|
||
BackState: s,
|
||
}, bot.NewMessage)
|
||
|
||
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.InviteLinkType == "public" {
|
||
newType = "approval"
|
||
} else {
|
||
newType = "public"
|
||
}
|
||
|
||
log.Info().
|
||
Str("workspace_id", s.WorkspaceID).
|
||
Str("project_id", s.Project.ID).
|
||
Str("old_type", s.Project.InviteLinkType).
|
||
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), bot.Keyboard(
|
||
bot.Row(bot.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), bot.Keyboard(
|
||
bot.Row(bot.Button("« Назад", "back_to_project")),
|
||
))
|
||
}
|
||
return
|
||
}
|
||
|
||
func (s *ProjectDetails) HandleMessage(_ *bot.Bot, _ *echotron.Update) { return }
|
||
|
||
func (s *ProjectDetails) Handle(_ *bot.Bot, _ *echotron.Update) { return }
|