fix(apps): all tiles clickable, open in new tab
This commit is contained in:
parent
151ddc6f63
commit
7d432d0af5
2 changed files with 88 additions and 260 deletions
|
|
@ -1,93 +1,32 @@
|
|||
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
|
||||
Icon string
|
||||
Color string
|
||||
Status string
|
||||
AdminOnly bool
|
||||
}
|
||||
|
||||
// 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
|
||||
{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:"/files",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:"/mail",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:"/calendar",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:"/contacts",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:"/tasks",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:"/chat",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"},
|
||||
}
|
||||
filtered := make([]AppTile,0,len(all))
|
||||
for _,a := range all {
|
||||
if a.AdminOnly && role != "admin" { continue }
|
||||
filtered = append(filtered, a)
|
||||
}
|
||||
return filtered
|
||||
|
|
@ -102,20 +41,9 @@ templ AppGrid(apps []AppTile) {
|
|||
}
|
||||
|
||||
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-card" data-url={ a.URL } onclick="window.open(this.getAttribute('data-url'),'_blank')" 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>
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,89 +8,30 @@ package ui
|
|||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
// 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
|
||||
Icon string
|
||||
Color string
|
||||
Status string
|
||||
AdminOnly bool
|
||||
}
|
||||
|
||||
// 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",
|
||||
},
|
||||
{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: "/files", 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: "/mail", 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: "/calendar", 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: "/contacts", 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: "/tasks", 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: "/chat", 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" {
|
||||
|
|
@ -161,73 +102,33 @@ func appTile(a AppTile) templ.Component {
|
|||
templ_7745c5c3_Var2 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
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\" data-url=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templruntime.SanitizeStyleAttributeValues("background:" + a.Color)
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.ResolveAttributeValue(a.URL)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `core/ui/app-grid.templ`, Line: 110, Col: 56}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `core/ui/app-grid.templ`, Line: 44, Col: 39}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var3)
|
||||
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
|
||||
}
|
||||
templ_7745c5c3_Err = templ.Raw(a.Icon).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</div><div class=\"app-name\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\" onclick=\"window.open(this.getAttribute('data-url'),'_blank')\" oncontextmenu=\"return false\"><div class=\"app-icon\" style=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(a.Name)
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templruntime.SanitizeStyleAttributeValues("background:" + a.Color)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `core/ui/app-grid.templ`, Line: 111, Col: 33}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `core/ui/app-grid.templ`, Line: 45, Col: 55}
|
||||
}
|
||||
_, 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, 6, "</div><div class=\"app-badge\">Coming Soon</div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "<div class=\"app-card\" data-url=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.ResolveAttributeValue(a.URL)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `core/ui/app-grid.templ`, Line: 115, Col: 40}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var5)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\" onclick=\"window.location.href=this.getAttribute('data-url')\" oncontextmenu=\"return false\"><div class=\"app-icon\" style=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templruntime.SanitizeStyleAttributeValues("background:" + a.Color)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `core/ui/app-grid.templ`, Line: 116, Col: 56}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
|
@ -235,24 +136,23 @@ func appTile(a AppTile) templ.Component {
|
|||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</div><div class=\"app-name\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</div><div class=\"app-name\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(a.Name)
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(a.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `core/ui/app-grid.templ`, Line: 117, Col: 33}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `core/ui/app-grid.templ`, Line: 46, Col: 32}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
_, 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, 11, "</div><div class=\"app-badge\">Available</div></div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div><div class=\"app-badge\">Available</div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue