refactor: Consolidate script imports and update Alpine.js syntax in templates

This commit updates all generated template files and the header.templ source
to use consolidated script bundles and modern Alpine.js syntax.

Changes to templates/*.go (generated from .templ source files):
- Replace individual script imports (admin.js, toast.js, header.js, etc.)
  with single /static/main.js bundle
- Convert onclick attributes to Alpine.js @click directives for better
  integration with reactive components
- Add x-data attributes to body elements where needed for Alpine components
- Update event handlers to use Alpine.js syntax consistently

Changes to templates/header.templ source file:
- Add Alpine.js test div with x-data and x-init for debugging
- Reformat theme dropdown and user menu markup with proper indentation
- Maintain consistent Alpine.js directive formatting throughout

This change reduces the number of HTTP requests and ensures consistent
Alpine.js integration across all pages.
This commit is contained in:
john-okeefe committed 2026-03-09 20:58:46 -04:00
1 parent 33cf00f65c
commit 647644fdce
26 files changed
+299 -262

No files matched your search

+7 -7
View File
@@ -29,25 +29,25 @@ func Header(user User, currentPath string) templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<nav class=\"border-b header-nav\" style=\"border-color: var(--border); background-color: var(--bg-secondary);\"><div class=\"w-full px-4 sm:px-6 lg:px-8\"><div class=\"flex justify-between items-center h-16\"><!-- Left: App Title & Navigation --><div class=\"flex items-center space-x-6\"><a href=\"/dashboard\" class=\"text-xl font-bold hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); text-decoration: none;\">📚 Bookhoard</a><div class=\"hidden md:flex items-center space-x-4\"><a href=\"/dashboard\" class=\"text-sm hover:opacity-80 transition-opacity\" style=\"color: var(--text-secondary); text-decoration: none;\">Library</a> <a href=\"/collections\" class=\"text-sm hover:opacity-80 transition-opacity\" style=\"color: var(--text-secondary); text-decoration: none;\">Collections</a> <a href=\"/progress\" class=\"text-sm hover:opacity-80 transition-opacity\" style=\"color: var(--text-secondary); text-decoration: none;\">Progress</a> <a href=\"/devices\" class=\"text-sm hover:opacity-80 transition-opacity\" style=\"color: var(--text-secondary); text-decoration: none;\">Devices</a></div></div><!-- Center: Search Box --><div class=\"flex-1 max-w-2xl mx-8\"><div class=\"relative\"><input type=\"text\" id=\"header-search\" placeholder=\"Search your library...\" class=\"w-full px-4 py-2 pl-10 border rounded-lg\" style=\"background-color: var(--bg-primary); color: var(--text-primary); border-color: var(--border);\" autocomplete=\"off\"> <svg class=\"absolute left-3 top-2.5 h-5 w-5\" style=\"color: var(--text-secondary)\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"></path></svg></div></div><!-- Right: Theme Switcher & User Menu --><div class=\"flex items-center space-x-4\"><!-- Theme Switcher --><div class=\"relative\"><button onclick=\"toggleThemeDropdown()\" class=\"p-2 rounded-lg hover:bg-gray-700 transition-colors\" style=\"background-color: var(--bg-primary);\"><svg class=\"h-6 w-6\" style=\"color: var(--text-primary)\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01\"></path></svg></button><div id=\"theme-dropdown\" class=\"hidden absolute right-0 mt-2 w-64 rounded-lg shadow-lg z-50\" style=\"background-color: var(--bg-secondary); border: 1px solid var(--border);\"><div class=\"p-4\"><h3 class=\"text-sm font-semibold mb-3\" style=\"color: var(--text-primary)\">Select Theme</h3><div class=\"space-y-2\"><button onclick=\"changeThemeTo('tokyo-night')\" class=\"w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); background-color: var(--bg-primary);\"><span class=\"inline-block w-4 h-4 rounded mr-2\" style=\"background-color: #7aa2f7;\"></span> Tokyo Night</button> <button onclick=\"changeThemeTo('dracula')\" class=\"w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); background-color: var(--bg-primary);\"><span class=\"inline-block w-4 h-4 rounded mr-2\" style=\"background-color: #bd93f9;\"></span> Dracula</button> <button onclick=\"changeThemeTo('nord')\" class=\"w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); background-color: var(--bg-primary);\"><span class=\"inline-block w-4 h-4 rounded mr-2\" style=\"background-color: #88c0d0;\"></span> Nord</button> <button onclick=\"changeThemeTo('solarized-dark')\" class=\"w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); background-color: var(--bg-primary);\"><span class=\"inline-block w-4 h-4 rounded mr-2\" style=\"background-color: #2aa198;\"></span> Solarized Dark</button> <button onclick=\"changeThemeTo('monokai')\" class=\"w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); background-color: var(--bg-primary);\"><span class=\"inline-block w-4 h-4 rounded mr-2\" style=\"background-color: #a6e22e;\"></span> Monokai</button> <button onclick=\"changeThemeTo('one-dark-pro')\" class=\"w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); background-color: var(--bg-primary);\"><span class=\"inline-block w-4 h-4 rounded mr-2\" style=\"background-color: #61dafb;\"></span> One Dark Pro</button> <button onclick=\"changeThemeTo('material-dark')\" class=\"w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); background-color: var(--bg-primary);\"><span class=\"inline-Line truncated
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<nav class=\"border-b header-nav\" style=\"border-color: var(--border); background-color: var(--bg-secondary);\"><div x-data=\"{}\" x-init=\"console.log('Alpine is working!', $el)\"></div><div class=\"w-full px-4 sm:px-6 lg:px-8\"><div class=\"flex justify-between items-center h-16\"><!-- Left: App Title & Navigation --><div class=\"flex items-center space-x-6\"><a href=\"/dashboard\" class=\"text-xl font-bold hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); text-decoration: none;\">📚 Bookhoard</a><div class=\"hidden md:flex items-center space-x-4\"><a href=\"/dashboard\" class=\"text-sm hover:opacity-80 transition-opacity\" style=\"color: var(--text-secondary); text-decoration: none;\">Library</a> <a href=\"/collections\" class=\"text-sm hover:opacity-80 transition-opacity\" style=\"color: var(--text-secondary); text-decoration: none;\">Collections</a> <a href=\"/progress\" class=\"text-sm hover:opacity-80 transition-opacity\" style=\"color: var(--text-secondary); text-decoration: none;\">Progress</a> <a href=\"/devices\" class=\"text-sm hover:opacity-80 transition-opacity\" style=\"color: var(--text-secondary); text-decoration: none;\">Devices</a></div></div><!-- Center: Search Box --><div class=\"flex-1 max-w-2xl mx-8\"><div class=\"relative\"><input type=\"text\" id=\"header-search\" placeholder=\"Search your library...\" class=\"w-full px-4 py-2 pl-10 border rounded-lg\" style=\"background-color: var(--bg-primary); color: var(--text-primary); border-color: var(--border);\" autocomplete=\"off\"> <svg class=\"absolute left-3 top-2.5 h-5 w-5\" style=\"color: var(--text-secondary)\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"></path></svg></div></div><!-- Right: Theme Switcher & User Menu --><div x-data=\"{ themeDropdownOpen: false, userMenuOpen: false }\" class=\"flex items-center space-x-4\"><!-- Theme Switcher --><div class=\"relative\"><button @click=\"themeDropdownOpen = !themeDropdownOpen\" class=\"p-2 rounded-lg hover:bg-gray-700 transition-colors\" style=\"background-color: var(--bg-primary);\"><svg class=\"h-6 w-6\" style=\"color: var(--text-primary)\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01\"></path></svg></button><div x-show=\"themeDropdownOpen\" @click.outside=\"themeDropdownOpen = false\" x-transition:enter=\"transition ease-out duration-200\" x-transition:enter-start=\"opacity-0 scale-95\" x-transition:enter-end=\"opacity-100 scale-100\" x-transition:leave=\"transition ease-in duration-150\" x-transition:leave-start=\"opacity-100 scale-100\" x-transition:leave-end=\"opacity-0 scale-95\" class=\"absolute right-0 mt-2 w-64 rounded-lg shadow-lg z-50\" style=\"background-color: var(--bg-secondary); border: 1px solid var(--border); display: none;\"><div class=\"p-4\"><h3 class=\"text-sm font-semibold mb-3\" style=\"color: var(--text-primary)\">Select Theme</h3><div class=\"space-y-2\"><button @click=\"header.changeThemeTo('tokyo-night'); themeDropdownOpen = false\" class=\"w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); background-color: var(--bg-primary);\"><span class=\"inline-block w-4 h-4 rounded mr-2\" style=\"background-color: #7aa2f7;\"></span> Tokyo Night</button> <button @click=\"header.changeThemeTo('dracula'); themeDropdownOpen = false\" class=\"w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); background-color: var(--bg-primary);\"><span class=\"inline-block w-4 h-4 rounded mr-2\" style=\"background-color: #bd93f9;\"></span> Dracula</button> <button @click=\"header.changeThemeTo('nord'); themeDropdownOpen = false\" class=\"w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); background-color: var(--bg-primary);\"><span class=\"inline-block w-4 h-4 rounded mr-2\" style=\"background-color: #88c0d0;\"></span> Nord</button> <button @click=\"header.changeThemeTo('solarized-dark'); themeDropdownOpen = false\" class=\"w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); background-color: var(--bg-primary);\"><span class=\"inline-block w-4 h-4 rounded mr-2\" style=\"background-color: #2aa198;\"></span> Solarized Dark</button> <button @click=\"header.changeThemeTo('monokai'); themeDropdownOpen = false\" class=\"w-full text-left px-3 py-2 rounded hover:opacity-80 transition-opacity\" style=\"color: var(--text-primary); background-color: vaLine truncated
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if user.ID != "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<!-- LOGGED IN: Show user menu with logout --> <button onclick=\"toggleUserMenu()\" class=\"flex items-center space-x-2 p-2 rounded-lg hover:bg-gray-700 transition-colors\" style=\"background-color: var(--bg-primary);\"><svg class=\"h-6 w-6\" style=\"color: var(--text-primary)\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z\"></path></svg> <span class=\"text-sm hidden sm:block\" style=\"color: var(--text-primary)\">")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<!-- LOGGED IN: Show user menu with logout --> <button @click=\"userMenuOpen = !userMenuOpen\" class=\"flex items-center space-x-2 p-2 rounded-lg hover:bg-gray-700 transition-colors\" style=\"background-color: var(--bg-primary);\"><svg class=\"h-6 w-6\" style=\"color: var(--text-primary)\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z\"></path></svg> <span class=\"text-sm hidden sm:block\" style=\"color: var(--text-primary)\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(user.Username)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/header.templ`, Line: 131, Col: 120}
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/header.templ`, Line: 191, Col: 96}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</span></button><div id=\"user-menu\" class=\"hidden absolute right-0 mt-2 w-48 rounded-lg shadow-lg z-50\" style=\"background-color: var(--bg-secondary); border: 1px solid var(--border);\"><div class=\"py-1\"><a href=\"/profile\" class=\"block px-4 py-2 text-sm hover:opacity-80\" style=\"color: var(--text-primary); background-color: var(--bg-secondary); text-decoration: none;\">Profile</a> ")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</span></button><div x-show=\"userMenuOpen\" @click.outside=\"userMenuOpen = false\" x-transition class=\"absolute right-0 mt-2 w-48 rounded-lg shadow-lg z-50\" style=\"background-color: var(--bg-secondary); border: 1px solid var(--border); display: none;\"><div class=\"py-1\"><a href=\"/profile\" class=\"block px-4 py-2 text-sm hover:opacity-80\" style=\"color: var(--text-primary); background-color: var(--bg-secondary); text-decoration: none;\">Profile</a> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -57,17 +57,17 @@ func Header(user User, currentPath string) templ.Component {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<div class=\"border-t my-1\" style=\"border-color: var(--border);\"></div><button onclick=\"logout()\" class=\"block w-full text-left px-4 py-2 text-sm hover:opacity-80\" style=\"color: var(--text-primary); background-color: var(--bg-secondary);\">Logout</button></div></div>")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<div class=\"border-t my-1\" style=\"border-color: var(--border);\"></div><button @click=\"header.logout(); userMenuOpen = false\" class=\"block w-full text-left px-4 py-2 text-sm hover:opacity-80\" style=\"color: var(--text-primary); background-color: var(--bg-secondary);\">Logout</button></div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<!-- LOGGED OUT: Show login form --> <button onclick=\"toggleUserMenu()\" class=\"flex items-center space-x-2 p-2 rounded-lg hover:bg-gray-700 transition-colors\" style=\"background-color: var(--bg-primary);\"><svg class=\"h-6 w-6\" style=\"color: var(--text-primary)\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z\"></path></svg> <span class=\"text-sm hidden sm:block\" style=\"color: var(--text-primary)\">Login</span></button><div id=\"user-menu\" class=\"hidden absolute right-0 mt-2 w-64 rounded-lg shadow-lg z-50 p-4\" style=\"background-color: var(--bg-secondary); border: 1px solid var(--border);\"><form hx-post=\"/api/auth/login\" hx-target=\"#login-result\" hx-swap=\"innerHTML\" class=\"space-y-3\"><input type=\"hidden\" name=\"redirect\" value=\"{ currentPath }\"><div><label class=\"block text-sm mb-1\" style=\"color: var(--text-secondary)\">Email or Username</label> <input type=\"text\" name=\"login\" class=\"w-full px-3 py-2 border rounded text-sm\" style=\"background-color: var(--bg-primary); color: var(--text-primary); border-color: var(--border);\" required></div><div><label class=\"block text-sm mb-1\" style=\"color: var(--text-secondary)\">Password</label> <input type=\"password\" name=\"password\" class=\"w-full px-3 py-2 border rounded text-sm\" style=\"background-color: var(--bg-primary); color: var(--text-primary); border-color: var(--border);\" required></div><button type=\"submit\" class=\"w-full py-2 rounded text-sm\" style=\"background-color: var(--accent); color: white;\">Sign In</button></form><div id=\"login-result\"></div><div class=\"border-t my-2\" style=\"border-color: var(--border);\"></div><a href=\"/register\" class=\"block text-center text-sm hover:opacity-80\" style=\"color: var(--text-secondary); text-decoration: none;\">Don't have an account? Sign Up</a></div>")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<!-- LOGGED OUT: Show login form --> <button @click=\"userMenuOpen = !userMenuOpen\" class=\"flex items-center space-x-2 p-2 rounded-lg hover:bg-gray-700 transition-colors\" style=\"background-color: var(--bg-primary);\"><svg class=\"h-6 w-6\" style=\"color: var(--text-primary)\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z\"></path></svg> <span class=\"text-sm hidden sm:block\" style=\"color: var(--text-primary)\">Login</span></button><div x-show=\"userMenuOpen\" @click.outside=\"userMenuOpen = false\" x-transition class=\"absolute right-0 mt-2 w-64 rounded-lg shadow-lg z-50 p-4\" style=\"background-color: var(--bg-secondary); border: 1px solid var(--border); display: none;\"><form hx-post=\"/api/auth/login\" hx-target=\"#login-result\" hx-swap=\"innerHTML\" class=\"space-y-3\"><input type=\"hidden\" name=\"redirect\" value=\"{ currentPath }\"><div><label class=\"block text-sm mb-1\" style=\"color: var(--text-secondary)\">Email or Username</label> <input type=\"text\" name=\"login\" class=\"w-full px-3 py-2 border rounded text-sm\" style=\"background-color: var(--bg-primary); color: var(--text-primary); border-color: var(--border);\" required></div><div><label class=\"block text-sm mb-1\" style=\"color: var(--text-secondary)\">Password</label> <input type=\"password\" name=\"password\" class=\"w-full px-3 py-2 border rounded text-sm\" style=\"background-color: var(--bg-primary); color: var(--text-primary); border-color: var(--border);\" required></div><button type=\"submit\" class=\"w-full py-2 rounded text-sm\" style=\"background-color: var(--accent); color: white;\">Sign In</button></form><div id=\"login-result\"></div><div class=\"border-t my-2\" style=\"border-color: var(--border);\"></div><a href=\"/register\" class=\"block text-center text-sm hover:opacity-80\" style=\"color: var(--text-secondary); text-decoration: none;\">Don't have an account? Sign Up</a></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div></div></div></div></nav><script src=\"/static/theme.js\"></script><script src=\"/static/woodPaneling.js\"></script><script src=\"/static/themeDropdown.js\"></script><script src=\"/static/header.js\"></script>")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div></div></div></div></nav><script src=\"/static/main.js\" defer></script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}