fix(apps): 4 tiles clickable (Admin + WorkSheets/TypeWriter/DeckCreator/NotesFiles)

This commit is contained in:
Claus Lohmar 2026-06-15 19:53:37 +00:00
parent 5eb5399088
commit 151ddc6f63
2 changed files with 122 additions and 1 deletions

View file

@ -0,0 +1,121 @@
package ui
// AppTile represents an app on the workspace launcher.
type AppTile struct {
Name string
Description string
URL string
Icon string // SVG inline
Color string // Background color
Status string // "ready" or "coming-soon"
AdminOnly bool // Only visible to admin role
}
// DefaultApps returns apps filtered by user role.
func DefaultApps(role string) []AppTile {
all := []AppTile{
{
Name: "Admin Panel", Description: "Users, groups & settings",
URL: "/admin", Color: "#9333ea",
Icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06A1.65 1.65 0 004.68 15a1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06A1.65 1.65 0 009 4.68a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06A1.65 1.65 0 0019.4 9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z"/></svg>`,
Status: "ready", AdminOnly: true,
},
{
Name: "Files", Description: "Storage & sharing",
URL: "#", Color: "#2563eb",
Icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>`,
Status: "coming-soon",
},
{
Name: "Mail", Description: "Email client",
URL: "#", Color: "#dc2626",
Icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>`,
Status: "coming-soon",
},
{
Name: "Calendar", Description: "Schedule & events",
URL: "#", Color: "#059669",
Icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>`,
Status: "coming-soon",
},
{
Name: "WorkSheets", Description: "Spreadsheets",
URL: "/worksheets", Color: "#059669",
Icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="3" y1="9" x2="21" y2="9"/><line x1="3" y1="15" x2="21" y2="15"/></svg>`,
Status: "coming-soon",
},
{
Name: "TypeWriter", Description: "Documents",
URL: "/typewriter", Color: "#2563eb",
Icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg>`,
Status: "coming-soon",
},
{
Name: "DeckCreator", Description: "Presentations",
URL: "/deckcreator", Color: "#dc2626",
Icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>`,
Status: "coming-soon",
},
{
Name: "NotesFiles", Description: "Notes & files",
URL: "/notesfiles", Color: "#d97706",
Icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><path d="M4 19.5A2.5 2.5 0 016.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z"/></svg>`,
Status: "coming-soon",
},
{
Name: "Contacts", Description: "People & directory",
URL: "#", Color: "#d97706",
Icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>`,
Status: "coming-soon",
},
{
Name: "Tasks", Description: "Project management",
URL: "#", Color: "#7c3aed",
Icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 01-2 2H5a2 2 0 01-2-2V5a2 2 0 012-2h11"/></svg>`,
Status: "coming-soon",
},
{
Name: "Chat", Description: "Team messaging",
URL: "#", Color: "#db2777",
Icon: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/></svg>`,
Status: "coming-soon",
},
}
// Filter by role
filtered := make([]AppTile, 0, len(all))
for _, a := range all {
if a.AdminOnly && role != "admin" {
continue
}
filtered = append(filtered, a)
}
return filtered
}
templ AppGrid(apps []AppTile) {
<div class="app-grid">
for _, a := range apps {
@appTile(a)
}
</div>
}
templ appTile(a AppTile) {
if a.Status == "coming-soon" {
<div class="app-card disabled"
oncontextmenu="return false"
ontouchstart="startLongPress(event)" ontouchend="cancelLongPress()"
onmousedown="startLongPress(event)" onmouseup="cancelLongPress()">
<div class="app-icon" style={ "background:" + a.Color }>@templ.Raw(a.Icon)</div>
<div class="app-name">{ a.Name }</div>
<div class="app-badge">Coming Soon</div>
</div>
} else {
<div class="app-card" data-url={ a.URL } onclick="window.location.href=this.getAttribute('data-url')" oncontextmenu="return false">
<div class="app-icon" style={ "background:" + a.Color }>@templ.Raw(a.Icon)</div>
<div class="app-name">{ a.Name }</div>
<div class="app-badge">Available</div>
</div>
}
}

View file

@ -161,7 +161,7 @@ func appTile(a AppTile) templ.Component {
templ_7745c5c3_Var2 = templ.NopComponent templ_7745c5c3_Var2 = templ.NopComponent
} }
ctx = templ.ClearChildren(ctx) ctx = templ.ClearChildren(ctx)
if a.Status == "coming-soon" { if a.URL == "#" || a.URL == "" {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<div class=\"app-card disabled\" oncontextmenu=\"return false\" ontouchstart=\"startLongPress(event)\" ontouchend=\"cancelLongPress()\" onmousedown=\"startLongPress(event)\" onmouseup=\"cancelLongPress()\"><div class=\"app-icon\" style=\"") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<div class=\"app-card disabled\" oncontextmenu=\"return false\" ontouchstart=\"startLongPress(event)\" ontouchend=\"cancelLongPress()\" onmousedown=\"startLongPress(event)\" onmouseup=\"cancelLongPress()\"><div class=\"app-icon\" style=\"")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err