module ui // import veb // import os // // Public Context type for veb // pub struct Context { // veb.Context // } // // Simple tree menu structure // pub struct MenuItem { // pub: // title string // href string // children []MenuItem // } // // Factory args // @[params] // pub struct WebArgs { // pub mut: // name string = 'default' // host string = 'localhost' // port int = 8080 // title string = 'Admin' // menu []MenuItem // open bool // } // // The App holds server state and config // pub struct App { // veb.StaticHandler // pub mut: // title string = 'default' // menu []MenuItem // port int = 7711 // } // // Start the webserver (blocking) // pub fn start(args WebArgs) ! { // mut app := App{ // title: args.title // menu: args.menu // port: args.port // } // veb.run[App, Context](mut app, app.port) // } // // Routes // // Redirect root to /admin // @['/'; get] // pub fn (app &App) root(mut ctx Context) veb.Result { // return ctx.redirect('/admin') // } // // Admin home page // @['/admin'; get] // pub fn (app &App) admin_index(mut ctx Context) veb.Result { // return ctx.html(app.render_admin('/', 'Welcome')) // } // // HeroScript editor page // @['/admin/heroscript'; get] // pub fn (app &App) admin_heroscript(mut ctx Context) veb.Result { // return ctx.html(app.render_heroscript()) // } // // Chat page // @['/admin/chat'; get] // pub fn (app &App) admin_chat(mut ctx Context) veb.Result { // return ctx.html(app.render_chat()) // } // // Static CSS files // @['/static/css/colors.css'; get] // pub fn (app &App) serve_colors_css(mut ctx Context) veb.Result { // css_path := os.join_path(os.dir(@FILE), 'templates', 'css', 'colors.css') // css_content := os.read_file(css_path) or { return ctx.text('/* CSS file not found */') } // ctx.set_content_type('text/css') // return ctx.text(css_content) // } // @['/static/css/main.css'; get] // pub fn (app &App) serve_main_css(mut ctx Context) veb.Result { // css_path := os.join_path(os.dir(@FILE), 'templates', 'css', 'main.css') // css_content := os.read_file(css_path) or { return ctx.text('/* CSS file not found */') } // ctx.set_content_type('text/css') // return ctx.text(css_content) // } // // Static JS files // @['/static/js/theme.js'; get] // pub fn (app &App) serve_theme_js(mut ctx Context) veb.Result { // js_path := os.join_path(os.dir(@FILE), 'templates', 'js', 'theme.js') // js_content := os.read_file(js_path) or { return ctx.text('/* JS file not found */') } // ctx.set_content_type('application/javascript') // return ctx.text(js_content) // } // @['/static/js/heroscript.js'; get] // pub fn (app &App) serve_heroscript_js(mut ctx Context) veb.Result { // js_path := os.join_path(os.dir(@FILE), 'templates', 'js', 'heroscript.js') // js_content := os.read_file(js_path) or { return ctx.text('/* JS file not found */') } // ctx.set_content_type('application/javascript') // return ctx.text(js_content) // } // @['/static/js/chat.js'; get] // pub fn (app &App) serve_chat_js(mut ctx Context) veb.Result { // js_path := os.join_path(os.dir(@FILE), 'templates', 'js', 'chat.js') // js_content := os.read_file(js_path) or { return ctx.text('/* JS file not found */') } // ctx.set_content_type('application/javascript') // return ctx.text(js_content) // } // @['/static/css/heroscript.css'; get] // pub fn (app &App) serve_heroscript_css(mut ctx Context) veb.Result { // css_path := os.join_path(os.dir(@FILE), 'templates', 'css', 'heroscript.css') // css_content := os.read_file(css_path) or { return ctx.text('/* CSS file not found */') } // ctx.set_content_type('text/css') // return ctx.text(css_content) // } // @['/static/css/chat.css'; get] // pub fn (app &App) serve_chat_css(mut ctx Context) veb.Result { // css_path := os.join_path(os.dir(@FILE), 'templates', 'css', 'chat.css') // css_content := os.read_file(css_path) or { return ctx.text('/* CSS file not found */') } // ctx.set_content_type('text/css') // return ctx.text(css_content) // } // // Catch-all content under /admin/* // @['/admin/:path...'; get] // pub fn (app &App) admin_section(mut ctx Context, path string) veb.Result { // // Render current path in the main content // return ctx.html(app.render_admin(path, 'Content')) // } // // View rendering using external template // fn (app &App) render_admin(path string, heading string) string { // // Get the template file path relative to the module // template_path := os.join_path(os.dir(@FILE), 'templates', 'admin_layout.html') // // Read the template file // template_content := os.read_file(template_path) or { // // Fallback to inline template if file not found // return app.render_admin_fallback(path, heading) // } // // Generate menu HTML // menu_content := menu_html(app.menu, 0, 'm') // // Simple template variable replacement // mut result := template_content // result = result.replace('{{.title}}', app.title) // result = result.replace('{{.heading}}', heading) // result = result.replace('{{.path}}', path) // result = result.replace('{{.menu_html}}', menu_content) // result = result.replace('{{.css_colors_url}}', '/static/css/colors.css') // result = result.replace('{{.css_main_url}}', '/static/css/main.css') // result = result.replace('{{.js_theme_url}}', '/static/js/theme.js') // return result // } // // HeroScript editor rendering using external template // fn (app &App) render_heroscript() string { // // Get the template file path relative to the module // template_path := os.join_path(os.dir(@FILE), 'templates', 'heroscript_editor.html') // // Read the template file // template_content := os.read_file(template_path) or { // // Fallback to basic template if file not found // return app.render_heroscript_fallback() // } // // Generate menu HTML // menu_content := menu_html(app.menu, 0, 'm') // // Simple template variable replacement // mut result := template_content // result = result.replace('{{.title}}', app.title) // result = result.replace('{{.menu_html}}', menu_content) // result = result.replace('{{.css_colors_url}}', '/static/css/colors.css') // result = result.replace('{{.css_main_url}}', '/static/css/main.css') // result = result.replace('{{.css_heroscript_url}}', '/static/css/heroscript.css') // result = result.replace('{{.js_theme_url}}', '/static/js/theme.js') // result = result.replace('{{.js_heroscript_url}}', '/static/js/heroscript.js') // return result // } // // Chat rendering using external template // fn (app &App) render_chat() string { // // Get the template file path relative to the module // template_path := os.join_path(os.dir(@FILE), 'templates', 'chat.html') // // Read the template file // template_content := os.read_file(template_path) or { // // Fallback to basic template if file not found // return app.render_chat_fallback() // } // // Generate menu HTML // menu_content := menu_html(app.menu, 0, 'm') // // Simple template variable replacement // mut result := template_content // result = result.replace('{{.title}}', app.title) // result = result.replace('{{.menu_html}}', menu_content) // result = result.replace('{{.css_colors_url}}', '/static/css/colors.css') // result = result.replace('{{.css_main_url}}', '/static/css/main.css') // result = result.replace('{{.css_chat_url}}', '/static/css/chat.css') // result = result.replace('{{.js_theme_url}}', '/static/js/theme.js') // result = result.replace('{{.js_chat_url}}', '/static/js/chat.js') // return result // } // // Fallback HeroScript rendering method // fn (app &App) render_heroscript_fallback() string { // return ' // // // // // // ${app.title} - HeroScript Editor // // // //
//

HeroScript Editor

//

HeroScript editor template not found. Please check the template files.

// Back to Admin //
// // // ' // } // // Fallback Chat rendering method // fn (app &App) render_chat_fallback() string { // return ' // // // // // // ${app.title} - Chat // // // //
//

Chat Assistant

//

Chat template not found. Please check the template files.

// Back to Admin //
// // // ' // } // // Fallback rendering method (inline template) // fn (app &App) render_admin_fallback(path string, heading string) string { // return ' // // // // // // ${app.title} // // // // // // //
//
//
//
${heading}
// /admin/${path} //
//
//
//

This is a placeholder admin content area for: /admin/${path}.

//

Use the treeview on the left to navigate.

//
//
//
//
// // // // ' // } // // Recursive menu renderer // fn menu_html(items []MenuItem, depth int, prefix string) string { // mut out := []string{} // for i, it in items { // id := '${prefix}_${depth}_${i}' // if it.children.len > 0 { // // expandable group // out << '
' // out << '' // out << '${it.title}' // out << '' // out << '
' // out << '
' // out << menu_html(it.children, depth + 1, id) // out << '
' // out << '
' // out << '
' // } else { // // leaf // out << '' // } // } // return out.join('\n') // } // // Default sample menu // fn default_menu() []MenuItem { // return [ // MenuItem{ // title: 'Dashboard' // href: '/admin' // }, // MenuItem{ // title: 'HeroScript' // href: '/admin/heroscript' // }, // MenuItem{ // title: 'Chat' // href: '/admin/chat' // }, // MenuItem{ // title: 'Users' // children: [ // MenuItem{ // title: 'Overview' // href: '/admin/users/overview' // }, // MenuItem{ // title: 'Create' // href: '/admin/users/create' // }, // MenuItem{ // title: 'Roles' // href: '/admin/users/roles' // }, // ] // }, // MenuItem{ // title: 'Content' // children: [ // MenuItem{ // title: 'Pages' // href: '/admin/content/pages' // }, // MenuItem{ // title: 'Media' // href: '/admin/content/media' // }, // MenuItem{ // title: 'Settings' // children: [ // MenuItem{ // title: 'SEO' // href: '/admin/content/settings/seo' // }, // MenuItem{ // title: 'Themes' // href: '/admin/content/settings/themes' // }, // ] // }, // ] // }, // MenuItem{ // title: 'System' // children: [ // MenuItem{ // title: 'Status' // href: '/admin/system/status' // }, // MenuItem{ // title: 'Logs' // href: '/admin/system/logs' // }, // MenuItem{ // title: 'Backups' // href: '/admin/system/backups' // }, // ] // }, // ] // }