core/templates/bn/toolbar_templ.go
Alex Dunmow 868df2d761 feat: WO-PS-011 SDK templates/bn shared components
Head, engagement, toolbar templ components and validation helpers
for use by template plugins.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-01 09:17:55 +08:00

970 lines
50 KiB
Go

// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.1001
package bn
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime"
import (
"fmt"
"time"
"github.com/google/uuid"
)
// ToolbarData contains data for the admin editor toolbar
type ToolbarData struct {
Enabled bool
PageID uuid.UUID
PageSlug string
PageTitle string
PostType string // "page", "post", "master", "system"
Status string // "published", "draft", "scheduled"
HasUnpublishedChanges bool
PreviewMode string // "published" or "draft"
Position string // "tl", "tc", "tr", "bl", "bc", "br" (default: "tr")
ScheduledAt *time.Time
TemplateName string
AuthorName string
LastModified time.Time
EditURL string
SettingsURL string
HistoryURL string
AnalyticsURL string
// Analytics snapshot
TodayPageviews int64
PageviewsTrend string // "up", "down", "flat"
TrendPercent int
// Blog-specific fields
ReadingTime int // minutes
WordCount int
CategoryCount int
AuthorSlug string
}
// StatusBadgeClass returns the Tailwind classes for the status badge
func (t ToolbarData) StatusBadgeClass() string {
switch t.Status {
case "published":
return "bg-success text-success-foreground"
case "scheduled":
return "bg-info text-info-foreground"
default:
return "bg-warning text-warning-foreground"
}
}
// StatusLabel returns a human-readable status label
func (t ToolbarData) StatusLabel() string {
switch t.Status {
case "published":
return "Published"
case "scheduled":
return "Scheduled"
default:
return "Draft"
}
}
// PostTypeLabel returns a human-readable post type label
func (t ToolbarData) PostTypeLabel() string {
switch t.PostType {
case "post":
return "Post"
case "master":
return "Master"
case "system":
return "System"
default:
return "Page"
}
}
// IsPreviewMode returns true if currently viewing draft/preview
func (t ToolbarData) IsPreviewMode() bool {
return t.PreviewMode == "draft"
}
// CanPublish returns true if the publish button should be enabled
func (t ToolbarData) CanPublish() bool {
return t.HasUnpublishedChanges
}
// LastModifiedFormatted returns the last modified time in a readable format
func (t ToolbarData) LastModifiedFormatted() string {
return t.LastModified.Format("Jan 2, 2006 3:04 PM")
}
// IsTopPosition returns true if toolbar should be at top (for legacy compatibility)
func (t ToolbarData) IsTopPosition() bool {
return t.Position == "tl" || t.Position == "tc" || t.Position == "tr" || t.Position == ""
}
// IsBottomPosition returns true if toolbar is at bottom
func (t ToolbarData) IsBottomPosition() bool {
return t.Position == "bl" || t.Position == "bc" || t.Position == "br"
}
// IsLeftPosition returns true if toolbar is on the left side
func (t ToolbarData) IsLeftPosition() bool {
return t.Position == "tl" || t.Position == "bl"
}
// IsRightPosition returns true if toolbar is on the right side
func (t ToolbarData) IsRightPosition() bool {
return t.Position == "tr" || t.Position == "br" || t.Position == ""
}
// IsCenterPosition returns true if toolbar is centered
func (t ToolbarData) IsCenterPosition() bool {
return t.Position == "tc" || t.Position == "bc"
}
// DropdownDirection returns "up" or "down" based on toolbar vertical position
func (t ToolbarData) DropdownDirection() string {
if t.IsBottomPosition() {
return "up"
}
return "down"
}
// DropdownAlign returns "left", "center", or "right" based on toolbar horizontal position
func (t ToolbarData) DropdownAlign() string {
if t.IsLeftPosition() {
return "left"
} else if t.IsCenterPosition() {
return "center"
}
return "right"
}
// PositionClasses returns the positioning classes for the floating pill
func (t ToolbarData) PositionClasses() string {
switch t.Position {
case "tl":
return "top-4 left-4"
case "tc":
return "top-4 left-1/2 -translate-x-1/2"
case "bl":
return "bottom-4 left-4"
case "bc":
return "bottom-4 left-1/2 -translate-x-1/2"
case "br":
return "bottom-4 right-4"
default: // "tr" or empty
return "top-4 right-4"
}
}
// IsBlogPost returns true if this is a blog post
func (t ToolbarData) IsBlogPost() bool {
return t.PostType == "post"
}
// TrendIcon returns the trend icon for pageviews
func (t ToolbarData) TrendIcon() string {
switch t.PageviewsTrend {
case "up":
return "↑"
case "down":
return "↓"
default:
return "→"
}
}
// TrendColorClass returns the color class for the trend indicator
func (t ToolbarData) TrendColorClass() string {
switch t.PageviewsTrend {
case "up":
return "text-success"
case "down":
return "text-destructive"
default:
return "text-muted-foreground"
}
}
// AdminEditorToolbar renders the floating pill toolbar for admins on public pages
// Uses inverted color scheme - dark on light backgrounds, light on dark backgrounds
func AdminEditorToolbar(data ToolbarData) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
if data.Enabled {
var templ_7745c5c3_Var2 = []any{"bn-toolbar fixed z-[9999] flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-full backdrop-blur-md transition-all duration-300", data.PositionClasses()}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div id=\"bn-admin-toolbar\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\"><style>\n\t\t\t\t/* Toolbar: dark by default (for light pages), light when page has .dark class */\n\t\t\t\t.bn-toolbar {\n\t\t\t\t\t--bn-toolbar-bg: rgba(24, 24, 27, 0.95);\n\t\t\t\t\t--bn-toolbar-fg: #fafafa;\n\t\t\t\t\t--bn-toolbar-muted: #a1a1aa;\n\t\t\t\t\t--bn-toolbar-border: rgba(63, 63, 70, 0.8);\n\t\t\t\t\t--bn-toolbar-hover: rgba(63, 63, 70, 0.5);\n\t\t\t\t\t--bn-toolbar-primary-bg: #3b82f6;\n\t\t\t\t\t--bn-toolbar-primary-fg: #ffffff;\n\t\t\t\t\tbackground: var(--bn-toolbar-bg);\n\t\t\t\t\tcolor: var(--bn-toolbar-fg);\n\t\t\t\t\tborder: 1px solid var(--bn-toolbar-border);\n\t\t\t\t\tbox-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.25), 0 8px 10px -6px rgba(0, 0, 0, 0.2);\n\t\t\t\t}\n\t\t\t\t/* Light toolbar when page theme is dark (.dark class on html or body) */\n\t\t\t\t.dark .bn-toolbar, html.dark .bn-toolbar, body.dark .bn-toolbar {\n\t\t\t\t\t--bn-toolbar-bg: rgba(250, 250, 250, 0.95);\n\t\t\t\t\t--bn-toolbar-fg: #18181b;\n\t\t\t\t\t--bn-toolbar-muted: #71717a;\n\t\t\t\t\t--bn-toolbar-border: rgba(228, 228, 231, 0.8);\n\t\t\t\t\t--bn-toolbar-hover: rgba(228, 228, 231, 0.5);\n\t\t\t\t\tbox-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.3), 0 8px 10px -6px rgba(0, 0, 0, 0.25);\n\t\t\t\t}\n\t\t\t\t.bn-toolbar .bn-toolbar-text { color: var(--bn-toolbar-fg); }\n\t\t\t\t.bn-toolbar .bn-toolbar-muted { color: var(--bn-toolbar-muted); }\n\t\t\t\t.bn-toolbar .bn-toolbar-divider { background: var(--bn-toolbar-border); }\n\t\t\t\t.bn-toolbar .bn-toolbar-hover:hover { background: var(--bn-toolbar-hover); }\n\t\t\t\t.bn-toolbar .bn-toolbar-primary {\n\t\t\t\t\tbackground: var(--bn-toolbar-primary-bg);\n\t\t\t\t\tcolor: var(--bn-toolbar-primary-fg);\n\t\t\t\t}\n\t\t\t\t.bn-toolbar .bn-toolbar-primary:hover {\n\t\t\t\t\tbackground: color-mix(in srgb, var(--bn-toolbar-primary-bg) 90%, black);\n\t\t\t\t}\n\t\t\t\t/* Dropdown styling - inherits toolbar vars */\n\t\t\t\t.bn-toolbar-dropdown {\n\t\t\t\t\tbackground: var(--bn-toolbar-bg);\n\t\t\t\t\tcolor: var(--bn-toolbar-fg);\n\t\t\t\t\tborder: 1px solid var(--bn-toolbar-border);\n\t\t\t\t\tbox-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.25), 0 8px 10px -6px rgba(0, 0, 0, 0.2);\n\t\t\t\t}\n\t\t\t\t.bn-toolbar-dropdown .bn-dd-border { border-color: var(--bn-toolbar-border); }\n\t\t\t\t.bn-toolbar-dropdown .bn-dd-text { color: var(--bn-toolbar-fg); }\n\t\t\t\t.bn-toolbar-dropdown .bn-dd-muted { color: var(--bn-toolbar-muted); }\n\t\t\t\t.bn-toolbar-dropdown .bn-dd-hover:hover { background: var(--bn-toolbar-hover); }\n\t\t\t\t.bn-toolbar-dropdown .bn-dd-link { color: var(--bn-toolbar-primary-bg); }\n\t\t\t\t.bn-toolbar-dropdown .bn-dd-link:hover { text-decoration: underline; }\n\t\t\t\t/* Dropdown positioning based on data attributes */\n\t\t\t\t.bn-dropdown-container { position: absolute; }\n\t\t\t\t.bn-dropdown-container[data-direction=\"up\"] { bottom: 100%; margin-bottom: 0.5rem; }\n\t\t\t\t.bn-dropdown-container[data-direction=\"down\"] { top: 100%; margin-top: 0.5rem; }\n\t\t\t\t.bn-dropdown-container[data-align=\"left\"] { left: 0; }\n\t\t\t\t.bn-dropdown-container[data-align=\"right\"] { right: 0; }\n\t\t\t\t.bn-dropdown-container[data-align=\"center\"] { left: 50%; transform: translateX(-50%); }\n\t\t\t</style><!-- Edit button --><a href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 templ.SafeURL
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(data.EditURL))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 251, Col: 38}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\" class=\"bn-toolbar-primary inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full transition-colors\" title=\"Edit this page\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z\"></path></svg> <span class=\"hidden sm:inline\">Edit</span></a><!-- Status indicator --><div class=\"flex items-center gap-1.5 px-2\" title=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(data.StatusLabel())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 261, Col: 73}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 = []any{"w-2 h-2 rounded-full", templ.KV("bg-success", data.Status == "published"), templ.KV("bg-warning", data.Status == "draft"), templ.KV("bg-info", data.Status == "scheduled"), templ.KV("animate-pulse ring-2 ring-warning/50", data.HasUnpublishedChanges)}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<span class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\"></span> <span class=\"bn-toolbar-muted text-xs hidden sm:inline\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(data.StatusLabel())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 263, Col: 80}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</span></div><!-- Divider --><div class=\"bn-toolbar-divider w-px h-5\"></div><!-- Preview toggle - compact -->")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var9 = []any{"bn-toolbar-hover inline-flex items-center gap-1 px-2 py-1 rounded-full text-xs transition-colors", templ.KV("!bg-info/20 text-info", data.IsPreviewMode()), templ.KV("bn-toolbar-muted", !data.IsPreviewMode())}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, togglePreviewMode(data.IsPreviewMode()))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<button type=\"button\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var9).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\" onclick=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 templ.ComponentScript = togglePreviewMode(data.IsPreviewMode())
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var11.Call)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\" title=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(func() string {
if data.IsPreviewMode() {
return "Viewing draft - click to view published"
} else {
return "Viewing published - click to preview draft"
}
}())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 272, Col: 169}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if data.IsPreviewMode() {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-3.5 w-3.5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M10 12a2 2 0 100-4 2 2 0 000 4z\"></path> <path fill-rule=\"evenodd\" d=\"M.458 10C1.732 5.943 5.522 3 10 3s8.268 2.943 9.542 7c-1.274 4.057-5.064 7-9.542 7S1.732 14.057.458 10zM14 10a4 4 0 11-8 0 4 4 0 018 0z\" clip-rule=\"evenodd\"></path></svg> <span class=\"hidden sm:inline\">Draft</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "<svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-3.5 w-3.5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clip-rule=\"evenodd\"></path></svg> <span class=\"hidden sm:inline\">Live</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</button><!-- Blog-specific: Reading time -->")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if data.IsBlogPost() && data.ReadingTime > 0 {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<div class=\"bn-toolbar-muted hidden md:flex items-center gap-1 px-2 text-xs\" title=\"Reading time\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-3.5 w-3.5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z\" clip-rule=\"evenodd\"></path></svg> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var13 string
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d min", data.ReadingTime))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 293, Col: 46}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<!-- Publish button (if changes) -->")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if data.CanPublish() {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "<button type=\"button\" class=\"inline-flex items-center gap-1.5 px-3 py-1.5 bg-success hover:bg-success/90 text-success-foreground rounded-full transition-colors\" hx-post=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("/toolbar/publish/%s", data.PageID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 301, Col: 62}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\" hx-target=\"#bn-admin-toolbar\" hx-swap=\"outerHTML\" hx-confirm=\"Publish this page?\" title=\"Publish changes\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\" clip-rule=\"evenodd\"></path></svg> <span class=\"hidden sm:inline\">Publish</span></button>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "<!-- More menu --><div class=\"relative\" id=\"more-menu-container\"><button type=\"button\" class=\"bn-toolbar-hover bn-toolbar-muted inline-flex items-center justify-center w-8 h-8 rounded-full transition-colors\" hx-get=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("/toolbar/page-info/%s", data.PageID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 318, Col: 63}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "\" hx-target=\"#page-info-dropdown\" hx-trigger=\"click\" hx-swap=\"innerHTML\" title=\"More options\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-5 w-5\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M6 10a2 2 0 11-4 0 2 2 0 014 0zM12 10a2 2 0 11-4 0 2 2 0 014 0zM16 12a2 2 0 100-4 2 2 0 000 4z\"></path></svg></button><div id=\"page-info-dropdown\" class=\"bn-dropdown-container\" data-direction=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(data.DropdownDirection())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 331, Col: 46}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "\" data-align=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(data.DropdownAlign())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 332, Col: 38}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "\"></div></div></div><!-- Click outside to close dropdowns --> <script>\n\t\t\tdocument.addEventListener('click', function(e) {\n\t\t\t\tif (!e.target.closest('#more-menu-container')) {\n\t\t\t\t\tdocument.getElementById('page-info-dropdown').innerHTML = '';\n\t\t\t\t}\n\t\t\t});\n\t\t</script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
return nil
})
}
// PageInfoDropdown renders the page info and quick actions dropdown
func PageInfoDropdown(data ToolbarData) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var18 := templ.GetChildren(ctx)
if templ_7745c5c3_Var18 == nil {
templ_7745c5c3_Var18 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "<div class=\"bn-toolbar-dropdown rounded-lg py-2 min-w-[260px] max-w-[320px]\"><!-- Analytics snapshot -->")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if data.TodayPageviews > 0 || data.PageviewsTrend != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "<div class=\"bn-dd-border px-3 py-2 border-b\"><div class=\"flex items-center justify-between\"><div class=\"flex items-center gap-2\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"bn-dd-muted h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M2 11a1 1 0 011-1h2a1 1 0 011 1v5a1 1 0 01-1 1H3a1 1 0 01-1-1v-5zM8 7a1 1 0 011-1h2a1 1 0 011 1v9a1 1 0 01-1 1H9a1 1 0 01-1-1V7zM14 4a1 1 0 011-1h2a1 1 0 011 1v12a1 1 0 01-1 1h-2a1 1 0 01-1-1V4z\"></path></svg> <span class=\"bn-dd-text text-sm font-medium\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var19 string
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", data.TodayPageviews))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 358, Col: 91}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, " views today</span></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if data.TrendPercent != 0 {
var templ_7745c5c3_Var20 = []any{"text-xs font-medium", data.TrendColorClass()}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "<span class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var21 string
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var20).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var22 string
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(data.TrendIcon())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 362, Col: 25}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var23 string
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d%%", abs(data.TrendPercent)))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 362, Col: 73}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "</div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "<!-- Blog-specific: Author & Reading time -->")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if data.IsBlogPost() {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "<div class=\"bn-dd-border px-3 py-2 border-b\"><div class=\"flex items-center justify-between text-sm\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if data.AuthorName != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "<div class=\"flex items-center gap-2\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"bn-dd-muted h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z\" clip-rule=\"evenodd\"></path></svg> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if data.AuthorSlug != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "<a href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var24 templ.SafeURL
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL("/author/" + data.AuthorSlug))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 378, Col: 61}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "\" class=\"bn-dd-link\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var25 string
templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(data.AuthorName)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 378, Col: 100}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "</a>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "<span class=\"bn-dd-text\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var26 string
templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(data.AuthorName)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 380, Col: 50}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
if data.ReadingTime > 0 {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "<span class=\"bn-dd-muted text-xs\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var27 string
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d min read", data.ReadingTime))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 385, Col: 86}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "</span>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if data.WordCount > 0 {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "<div class=\"bn-dd-muted text-xs mt-1\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var28 string
templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d words", data.WordCount))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 389, Col: 84}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "<!-- Page info --><div class=\"bn-dd-border bn-dd-muted px-3 py-2 border-b text-xs\"><div class=\"flex justify-between\"><span>Template</span> <span class=\"bn-dd-text\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var29 string
templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(data.TemplateName)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 397, Col: 48}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "</span></div><div class=\"flex justify-between mt-1\"><span>Modified</span> <span class=\"bn-dd-text\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var30 string
templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(data.LastModifiedFormatted())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 401, Col: 59}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "</span></div></div><!-- Quick actions --><div class=\"py-1\"><a href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var31 templ.SafeURL
templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(data.SettingsURL))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 406, Col: 44}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "\" class=\"bn-dd-hover bn-dd-text flex items-center gap-2 px-3 py-1.5 text-sm transition-colors\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"bn-dd-muted h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M11.49 3.17c-.38-1.56-2.6-1.56-2.98 0a1.532 1.532 0 01-2.286.948c-1.372-.836-2.942.734-2.106 2.106.54.886.061 2.042-.947 2.287-1.561.379-1.561 2.6 0 2.978a1.532 1.532 0 01.947 2.287c-.836 1.372.734 2.942 2.106 2.106a1.532 1.532 0 012.287.947c.379 1.561 2.6 1.561 2.978 0a1.533 1.533 0 012.287-.947c1.372.836 2.942-.734 2.106-2.106a1.533 1.533 0 01.947-2.287c1.561-.379 1.561-2.6 0-2.978a1.532 1.532 0 01-.947-2.287c.836-1.372-.734-2.942-2.106-2.106a1.532 1.532 0 01-2.287-.947zM10 13a3 3 0 100-6 3 3 0 000 6z\" clip-rule=\"evenodd\"></path></svg> Settings</a> <a href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var32 templ.SafeURL
templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(data.HistoryURL))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 412, Col: 43}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "\" class=\"bn-dd-hover bn-dd-text flex items-center gap-2 px-3 py-1.5 text-sm transition-colors\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"bn-dd-muted h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z\" clip-rule=\"evenodd\"></path></svg> History</a> <a href=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var33 templ.SafeURL
templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(data.AnalyticsURL))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 418, Col: 45}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "\" class=\"bn-dd-hover bn-dd-text flex items-center gap-2 px-3 py-1.5 text-sm transition-colors\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"bn-dd-muted h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M2 11a1 1 0 011-1h2a1 1 0 011 1v5a1 1 0 01-1 1H3a1 1 0 01-1-1v-5zM8 7a1 1 0 011-1h2a1 1 0 011 1v9a1 1 0 01-1 1H9a1 1 0 01-1-1V7zM14 4a1 1 0 011-1h2a1 1 0 011 1v12a1 1 0 01-1 1h-2a1 1 0 01-1-1V4z\"></path></svg> Analytics</a></div><!-- Sharing --><div class=\"bn-dd-border border-t py-1\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, copyPageURL(data.PageSlug))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "<button type=\"button\" class=\"bn-dd-hover bn-dd-text w-full flex items-center gap-2 px-3 py-1.5 text-sm transition-colors\" onclick=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var34 templ.ComponentScript = copyPageURL(data.PageSlug)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var34.Call)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"bn-dd-muted h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M12.586 4.586a2 2 0 112.828 2.828l-3 3a2 2 0 01-2.828 0 1 1 0 00-1.414 1.414 4 4 0 005.656 0l3-3a4 4 0 00-5.656-5.656l-1.5 1.5a1 1 0 101.414 1.414l1.5-1.5zm-5 5a2 2 0 012.828 0 1 1 0 101.414-1.414 4 4 0 00-5.656 0l-3 3a4 4 0 105.656 5.656l1.5-1.5a1 1 0 10-1.414-1.414l-1.5 1.5a2 2 0 11-2.828-2.828l3-3z\"></path></svg> Copy link</button> <button type=\"button\" class=\"bn-dd-hover bn-dd-text w-full flex items-center gap-2 px-3 py-1.5 text-sm transition-colors\" hx-post=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var35 string
templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("/toolbar/share-preview/%s", data.PageID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 440, Col: 67}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "\" hx-swap=\"innerHTML\" hx-target=\"this\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"bn-dd-muted h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path d=\"M15 8a3 3 0 10-2.977-2.63l-4.94 2.47a3 3 0 100 4.319l4.94 2.47a3 3 0 10.895-1.789l-4.94-2.47a3.027 3.027 0 000-.74l4.94-2.47C13.456 7.68 14.19 8 15 8z\"></path></svg> Share preview link</button></div><!-- Position selector --><div class=\"bn-dd-border border-t px-3 py-2\"><div class=\"bn-dd-muted text-xs mb-2\">Move toolbar</div><div class=\"grid grid-cols-3 gap-1\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = positionButton(data.PageID, "tl", data.Position, "Top left").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = positionButton(data.PageID, "tc", data.Position, "Top center").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = positionButton(data.PageID, "tr", data.Position, "Top right").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = positionButton(data.PageID, "bl", data.Position, "Bottom left").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = positionButton(data.PageID, "bc", data.Position, "Bottom center").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = positionButton(data.PageID, "br", data.Position, "Bottom right").Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "</div></div><!-- Danger zone -->")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if data.HasUnpublishedChanges {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "<div class=\"bn-dd-border border-t py-1\"><button type=\"button\" class=\"w-full flex items-center gap-2 px-3 py-1.5 text-sm text-destructive hover:bg-destructive/10 transition-colors\" hx-post=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var36 string
templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("/toolbar/discard/%s", data.PageID))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 468, Col: 62}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "\" hx-target=\"#bn-admin-toolbar\" hx-swap=\"outerHTML\" hx-confirm=\"Discard all unpublished changes? This cannot be undone.\"><svg xmlns=\"http://www.w3.org/2000/svg\" class=\"h-4 w-4\" viewBox=\"0 0 20 20\" fill=\"currentColor\"><path fill-rule=\"evenodd\" d=\"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z\" clip-rule=\"evenodd\"></path></svg> Discard changes</button></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// positionButton renders a position selector button
func positionButton(pageID uuid.UUID, pos string, currentPos string, label string) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
if !templ_7745c5c3_IsBuffer {
defer func() {
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
if templ_7745c5c3_Err == nil {
templ_7745c5c3_Err = templ_7745c5c3_BufErr
}
}()
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var37 := templ.GetChildren(ctx)
if templ_7745c5c3_Var37 == nil {
templ_7745c5c3_Var37 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
var templ_7745c5c3_Var38 = []any{"w-8 h-6 rounded border transition-colors flex items-center justify-center", templ.KV("bg-info border-info", pos == currentPos || (currentPos == "" && pos == "tr")), templ.KV("bn-dd-border bn-dd-hover", pos != currentPos && !(currentPos == "" && pos == "tr"))}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var38...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "<button type=\"button\" class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var39 string
templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var38).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var39))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "\" hx-post=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var40 string
templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("/toolbar/set-position/%s?pos=%s", pageID, pos))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 488, Col: 71}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "\" hx-target=\"#bn-admin-toolbar\" hx-swap=\"outerHTML\" title=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var41 string
templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinStringErrs(label)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 491, Col: 15}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var42 = []any{"w-1.5 h-1.5 rounded-full", templ.KV("bg-info-foreground", pos == currentPos || (currentPos == "" && pos == "tr")), templ.KV("bn-dd-muted", pos != currentPos && !(currentPos == "" && pos == "tr"))}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var42...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "<span class=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var43 string
templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var42).String())
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `toolbar.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var43))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "\"></span></button>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
// abs returns the absolute value of an integer
func abs(n int) int {
if n < 0 {
return -n
}
return n
}
// copyPageURL generates the script to copy page URL
func copyPageURL(slug string) templ.ComponentScript {
return templ.ComponentScript{
Name: `__templ_copyPageURL_044c`,
Function: `function __templ_copyPageURL_044c(slug){const url = window.location.origin + slug;
navigator.clipboard.writeText(url).then(() => {
// Show brief feedback - could enhance with toast later
const btn = event.currentTarget;
const originalText = btn.innerHTML;
btn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/></svg> Copied!';
setTimeout(() => { btn.innerHTML = originalText; }, 2000);
});
}`,
Call: templ.SafeScript(`__templ_copyPageURL_044c`, slug),
CallInline: templ.SafeScriptInline(`__templ_copyPageURL_044c`, slug),
}
}
// togglePreviewMode toggles between preview (draft) and published mode via URL
func togglePreviewMode(isCurrentlyPreview bool) templ.ComponentScript {
return templ.ComponentScript{
Name: `__templ_togglePreviewMode_114f`,
Function: `function __templ_togglePreviewMode_114f(isCurrentlyPreview){const url = new URL(window.location.href);
if (isCurrentlyPreview) {
// Currently previewing, remove preview param
url.searchParams.delete('preview');
} else {
// Not previewing, add preview param
url.searchParams.set('preview', '1');
}
window.location.href = url.toString();
}`,
Call: templ.SafeScript(`__templ_togglePreviewMode_114f`, isCurrentlyPreview),
CallInline: templ.SafeScriptInline(`__templ_togglePreviewMode_114f`, isCurrentlyPreview),
}
}
var _ = templruntime.GeneratedTemplate