xtablo-source/go-backend/internal/web/views/tablos_view.go
2026-05-09 20:18:24 +02:00

161 lines
4.1 KiB
Go

package views
import (
"fmt"
"net/url"
"strings"
"xtablo-backend/internal/web/ui"
)
type TabloCardView struct {
ID string
Name string
Status string
StatusLabel string
StatusClass string
StatusTone string
Progress int
CreatedAtLabel string
CardDateLabel string
ProgressLabel string
DeleteURL string
DeleteRequestURL string
IconKind string
IconBgClass string
IconFgClass string
Accent string
Initial string
}
type TablosPageViewModel struct {
DisplayName string
View string
Query string
Status string
ModalOpen bool
FormName string
ErrorMessage string
Tablos []TabloCardView
}
func NewTablosPageViewModel(displayName string, view string, query string, status string, modalOpen bool, formName string, errorMessage string, tablos []TabloCardView) TablosPageViewModel {
return TablosPageViewModel{
DisplayName: displayName,
View: normalizedView(view),
Query: strings.TrimSpace(query),
Status: normalizedStatus(status),
ModalOpen: modalOpen,
FormName: strings.TrimSpace(formName),
ErrorMessage: strings.TrimSpace(errorMessage),
Tablos: tablos,
}
}
func (vm TablosPageViewModel) IsGridView() bool {
return vm.View != "list"
}
func (vm TablosPageViewModel) HasTablos() bool {
return len(vm.Tablos) > 0
}
func (vm TablosPageViewModel) StatusHref(status string) string {
values := vm.baseValues()
values.Set("status", normalizedStatus(status))
return "/tablos?" + values.Encode()
}
func (vm TablosPageViewModel) ViewHref(view string) string {
values := vm.baseValues()
values.Set("view", normalizedView(view))
return "/tablos?" + values.Encode()
}
func (vm TablosPageViewModel) SearchHref() string {
return "/tablos"
}
func (vm TablosPageViewModel) HiddenStateFields() map[string]string {
return map[string]string{
"view": vm.View,
"status": vm.Status,
"q": vm.Query,
}
}
func (vm TablosPageViewModel) SearchValues() string {
return fmt.Sprintf("view=%s&status=%s", vm.View, vm.Status)
}
func (vm TablosPageViewModel) CreateModalHref() string {
values := vm.baseValues()
values.Set("modal", "create")
return "/tablos?" + values.Encode()
}
func (vm TablosPageViewModel) CloseModalHref() string {
values := vm.baseValues()
return "/tablos?" + values.Encode()
}
func (vm TablosPageViewModel) HasSearch() bool {
return vm.Query != ""
}
func normalizedView(view string) string {
if view == "list" {
return "list"
}
return "grid"
}
func normalizedStatus(status string) string {
switch status {
case "todo", "in_progress", "done":
return status
default:
return "all"
}
}
func (vm TablosPageViewModel) baseValues() url.Values {
values := url.Values{}
values.Set("view", vm.View)
values.Set("status", vm.Status)
if vm.Query != "" {
values.Set("q", vm.Query)
}
return values
}
func gridToggleClass(active bool) string {
if active {
return "flex items-center gap-2 pb-3 border-b-2 transition-colors border-purple-600 text-purple-600 dark:border-purple-400 dark:text-purple-400 font-semibold"
}
return "flex items-center gap-2 pb-3 border-b-2 transition-colors border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200"
}
func listToggleClass(gridActive bool) string {
return gridToggleClass(!gridActive)
}
func statusPillClass(active bool) string {
if active {
return "flex items-center gap-1.5 px-4 py-2.5 border rounded-[8px] font-medium text-sm transition-colors border-purple-600 bg-purple-50 dark:bg-purple-950/30 text-purple-600 dark:text-purple-400"
}
return "flex items-center gap-1.5 px-4 py-2.5 border rounded-[8px] font-medium text-sm transition-colors border-[#EAECF0] dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-800 text-gray-700 dark:text-gray-300"
}
func badgeVariantForTone(tone string) ui.BadgeVariant {
switch tone {
case "warning":
return ui.BadgeVariantWarning
case "success":
return ui.BadgeVariantSuccess
case "danger":
return ui.BadgeVariantDanger
default:
return ui.BadgeVariantInfo
}
}