From 27c8c06cdb05ece640ec626233069ff0be3d8ed6 Mon Sep 17 00:00:00 2001 From: Mahmoud-Emad Date: Thu, 21 Aug 2025 13:10:44 +0300 Subject: [PATCH] chore: Comment the web ui package --- examples/web/ui_demo.vsh | 18 +- lib/web/ui/endpoints.v | 450 ++++++++++----------- lib/web/ui/factory.v | 852 +++++++++++++++++++-------------------- lib/web/ui/server.v | 426 ++++++++++---------- lib/web/ui/utils.v | 56 +-- 5 files changed, 901 insertions(+), 901 deletions(-) diff --git a/examples/web/ui_demo.vsh b/examples/web/ui_demo.vsh index 10f395eb..50711018 100755 --- a/examples/web/ui_demo.vsh +++ b/examples/web/ui_demo.vsh @@ -1,13 +1,13 @@ #!/usr/bin/env -S v -n -w -gc none -cg -cc tcc -d use_openssl -enable-globals run -import freeflowuniverse.herolib.web.ui +// import freeflowuniverse.herolib.web.ui -fn main() { - println('Starting UI test server on port 8080...') - println('Visit http://localhost:8080 to see the admin interface') +// fn main() { +// println('Starting UI test server on port 8080...') +// println('Visit http://localhost:8080 to see the admin interface') - ui.start( - title: 'Test Admin Panel' - port: 8080 - )! -} +// ui.start( +// title: 'Test Admin Panel' +// port: 8080 +// )! +// } diff --git a/lib/web/ui/endpoints.v b/lib/web/ui/endpoints.v index 7dbbd8fb..91d694c8 100644 --- a/lib/web/ui/endpoints.v +++ b/lib/web/ui/endpoints.v @@ -1,244 +1,244 @@ module ui -import veb -import freeflowuniverse.herolib.develop.heroprompt -import os -import json +// import veb +// import freeflowuniverse.herolib.develop.heroprompt +// import os +// import json -// Directory browsing and file read endpoints for Heroprompt.js compatibility -struct DirItem { - name string - typ string @[json: 'type'] -} +// // Directory browsing and file read endpoints for Heroprompt.js compatibility +// struct DirItem { +// name string +// typ string @[json: 'type'] +// } -struct DirResp { - path string -mut: - items []DirItem -} +// struct DirResp { +// path string +// mut: +// items []DirItem +// } -@['/api/heroprompt/directory'; get] -pub fn (app &App) api_heroprompt_directory(mut ctx Context) veb.Result { - // Optional workspace name, defaults to 'default' - wsname := ctx.query['name'] or { 'default' } - path_q := ctx.query['path'] or { '' } - if path_q.len == 0 { - return ctx.text('{"error":"path required"}') - } - // Try to resolve against workspace base_path if available, but do not require it - mut base := '' - if wsp := heroprompt.get(name: wsname, create: false) { - base = wsp.base_path - } - // Resolve path: if absolute, use as-is; else join with base - mut dir_path := path_q - if !os.is_abs_path(dir_path) && base.len > 0 { - dir_path = os.join_path(base, dir_path) - } - // List entries - entries := os.ls(dir_path) or { return ctx.text('{"error":"cannot list directory"}') } - mut items := []map[string]string{} - for e in entries { - full := os.join_path(dir_path, e) - if os.is_dir(full) { - items << { - 'name': e - 'type': 'directory' - } - } else if os.is_file(full) { - items << { - 'name': e - 'type': 'file' - } - } - } - ctx.set_content_type('application/json') - // Encode strongly typed JSON response - mut resp := DirResp{ - path: dir_path - } - for it in items { - resp.items << DirItem{ - name: it['name'] or { '' } - typ: it['type'] or { '' } - } - } - return ctx.text(json.encode(resp)) -} +// @['/api/heroprompt/directory'; get] +// pub fn (app &App) api_heroprompt_directory(mut ctx Context) veb.Result { +// // Optional workspace name, defaults to 'default' +// wsname := ctx.query['name'] or { 'default' } +// path_q := ctx.query['path'] or { '' } +// if path_q.len == 0 { +// return ctx.text('{"error":"path required"}') +// } +// // Try to resolve against workspace base_path if available, but do not require it +// mut base := '' +// if wsp := heroprompt.get(name: wsname, create: false) { +// base = wsp.base_path +// } +// // Resolve path: if absolute, use as-is; else join with base +// mut dir_path := path_q +// if !os.is_abs_path(dir_path) && base.len > 0 { +// dir_path = os.join_path(base, dir_path) +// } +// // List entries +// entries := os.ls(dir_path) or { return ctx.text('{"error":"cannot list directory"}') } +// mut items := []map[string]string{} +// for e in entries { +// full := os.join_path(dir_path, e) +// if os.is_dir(full) { +// items << { +// 'name': e +// 'type': 'directory' +// } +// } else if os.is_file(full) { +// items << { +// 'name': e +// 'type': 'file' +// } +// } +// } +// ctx.set_content_type('application/json') +// // Encode strongly typed JSON response +// mut resp := DirResp{ +// path: dir_path +// } +// for it in items { +// resp.items << DirItem{ +// name: it['name'] or { '' } +// typ: it['type'] or { '' } +// } +// } +// return ctx.text(json.encode(resp)) +// } -@['/api/heroprompt/file'; get] -pub fn (app &App) api_heroprompt_file(mut ctx Context) veb.Result { - wsname := ctx.query['name'] or { 'default' } - path_q := ctx.query['path'] or { '' } - if path_q.len == 0 { - return ctx.text('{"error":"path required"}') - } - // Try to resolve against workspace base_path if available, but do not require it - mut base := '' - if wsp := heroprompt.get(name: wsname, create: false) { - base = wsp.base_path - } - mut file_path := path_q - if !os.is_abs_path(file_path) && base.len > 0 { - file_path = os.join_path(base, file_path) - } - content := os.read_file(file_path) or { return ctx.text('{"error":"failed to read"}') } - lang := detect_lang(file_path) - ctx.set_content_type('application/json') - return ctx.text(json.encode({ - 'language': lang - 'content': content - })) -} +// @['/api/heroprompt/file'; get] +// pub fn (app &App) api_heroprompt_file(mut ctx Context) veb.Result { +// wsname := ctx.query['name'] or { 'default' } +// path_q := ctx.query['path'] or { '' } +// if path_q.len == 0 { +// return ctx.text('{"error":"path required"}') +// } +// // Try to resolve against workspace base_path if available, but do not require it +// mut base := '' +// if wsp := heroprompt.get(name: wsname, create: false) { +// base = wsp.base_path +// } +// mut file_path := path_q +// if !os.is_abs_path(file_path) && base.len > 0 { +// file_path = os.join_path(base, file_path) +// } +// content := os.read_file(file_path) or { return ctx.text('{"error":"failed to read"}') } +// lang := detect_lang(file_path) +// ctx.set_content_type('application/json') +// return ctx.text(json.encode({ +// 'language': lang +// 'content': content +// })) +// } -fn detect_lang(path string) string { - ext := os.file_ext(path).trim_left('.') - return match ext.to_lower() { - 'v' { 'v' } - 'js' { 'javascript' } - 'ts' { 'typescript' } - 'py' { 'python' } - 'rs' { 'rust' } - 'go' { 'go' } - 'java' { 'java' } - 'c', 'h' { 'c' } - 'cpp', 'hpp', 'cc', 'hh' { 'cpp' } - 'sh', 'bash' { 'bash' } - 'json' { 'json' } - 'yaml', 'yml' { 'yaml' } - 'html', 'htm' { 'html' } - 'css' { 'css' } - 'md' { 'markdown' } - else { 'text' } - } -} +// fn detect_lang(path string) string { +// ext := os.file_ext(path).trim_left('.') +// return match ext.to_lower() { +// 'v' { 'v' } +// 'js' { 'javascript' } +// 'ts' { 'typescript' } +// 'py' { 'python' } +// 'rs' { 'rust' } +// 'go' { 'go' } +// 'java' { 'java' } +// 'c', 'h' { 'c' } +// 'cpp', 'hpp', 'cc', 'hh' { 'cpp' } +// 'sh', 'bash' { 'bash' } +// 'json' { 'json' } +// 'yaml', 'yml' { 'yaml' } +// 'html', 'htm' { 'html' } +// 'css' { 'css' } +// 'md' { 'markdown' } +// else { 'text' } +// } +// } -// Heroprompt API: list workspaces -@['/api/heroprompt/workspaces'; get] -pub fn (app &App) api_heroprompt_list(mut ctx Context) veb.Result { - mut names := []string{} - ws := heroprompt.list(fromdb: true) or { []&heroprompt.Workspace{} } - for w in ws { - names << w.name - } - ctx.set_content_type('application/json') - return ctx.text(json.encode(names)) -} +// // Heroprompt API: list workspaces +// @['/api/heroprompt/workspaces'; get] +// pub fn (app &App) api_heroprompt_list(mut ctx Context) veb.Result { +// mut names := []string{} +// ws := heroprompt.list(fromdb: true) or { []&heroprompt.Workspace{} } +// for w in ws { +// names << w.name +// } +// ctx.set_content_type('application/json') +// return ctx.text(json.encode(names)) +// } -// Heroprompt API: create/get workspace -@['/api/heroprompt/workspaces'; post] -pub fn (app &App) api_heroprompt_create(mut ctx Context) veb.Result { - name := ctx.form['name'] or { '' } - base_path := ctx.form['base_path'] or { '' } +// // Heroprompt API: create/get workspace +// @['/api/heroprompt/workspaces'; post] +// pub fn (app &App) api_heroprompt_create(mut ctx Context) veb.Result { +// name := ctx.form['name'] or { '' } +// base_path := ctx.form['base_path'] or { '' } - if base_path.len == 0 { - return ctx.text('{"error":"base_path required"}') - } +// if base_path.len == 0 { +// return ctx.text('{"error":"base_path required"}') +// } - mut wsp := heroprompt.get(name: name, create: true, path: base_path) or { - return ctx.text('{"error":"create failed"}') - } +// mut wsp := heroprompt.get(name: name, create: true, path: base_path) or { +// return ctx.text('{"error":"create failed"}') +// } - ctx.set_content_type('application/json') - return ctx.text(json.encode({ - 'name': name - 'base_path': base_path - })) -} +// ctx.set_content_type('application/json') +// return ctx.text(json.encode({ +// 'name': name +// 'base_path': base_path +// })) +// } -// Heroprompt API: add directory to workspace -@['/api/heroprompt/workspaces/:name/dirs'; post] -pub fn (app &App) api_heroprompt_add_dir(mut ctx Context, name string) veb.Result { - path := ctx.form['path'] or { '' } - if path.len == 0 { - return ctx.text('{"error":"path required"}') - } - mut wsp := heroprompt.get(name: name, create: true) or { - return ctx.text('{"error":"workspace not found"}') - } - wsp.add_dir(path: path) or { return ctx.text('{"error":"' + err.msg() + '"}') } - ctx.set_content_type('application/json') - return ctx.text('{"ok":true}') -} +// // Heroprompt API: add directory to workspace +// @['/api/heroprompt/workspaces/:name/dirs'; post] +// pub fn (app &App) api_heroprompt_add_dir(mut ctx Context, name string) veb.Result { +// path := ctx.form['path'] or { '' } +// if path.len == 0 { +// return ctx.text('{"error":"path required"}') +// } +// mut wsp := heroprompt.get(name: name, create: true) or { +// return ctx.text('{"error":"workspace not found"}') +// } +// wsp.add_dir(path: path) or { return ctx.text('{"error":"' + err.msg() + '"}') } +// ctx.set_content_type('application/json') +// return ctx.text('{"ok":true}') +// } -// Heroprompt API: add file to workspace -@['/api/heroprompt/workspaces/:name/files'; post] -pub fn (app &App) api_heroprompt_add_file(mut ctx Context, name string) veb.Result { - path := ctx.form['path'] or { '' } - if path.len == 0 { - return ctx.text('{"error":"path required"}') - } - mut wsp := heroprompt.get(name: name, create: true) or { - return ctx.text('{"error":"workspace not found"}') - } - wsp.add_file(path: path) or { return ctx.text('{"error":"' + err.msg() + '"}') } - ctx.set_content_type('application/json') - return ctx.text('{"ok":true}') -} +// // Heroprompt API: add file to workspace +// @['/api/heroprompt/workspaces/:name/files'; post] +// pub fn (app &App) api_heroprompt_add_file(mut ctx Context, name string) veb.Result { +// path := ctx.form['path'] or { '' } +// if path.len == 0 { +// return ctx.text('{"error":"path required"}') +// } +// mut wsp := heroprompt.get(name: name, create: true) or { +// return ctx.text('{"error":"workspace not found"}') +// } +// wsp.add_file(path: path) or { return ctx.text('{"error":"' + err.msg() + '"}') } +// ctx.set_content_type('application/json') +// return ctx.text('{"ok":true}') +// } -// Heroprompt API: generate prompt -@['/api/heroprompt/workspaces/:name/prompt'; post] -pub fn (app &App) api_heroprompt_prompt(mut ctx Context, name string) veb.Result { - text := ctx.form['text'] or { '' } - mut wsp := heroprompt.get(name: name, create: false) or { - return ctx.text('{"error":"workspace not found"}') - } - prompt := wsp.prompt(text: text) - ctx.set_content_type('text/plain') - return ctx.text(prompt) -} +// // Heroprompt API: generate prompt +// @['/api/heroprompt/workspaces/:name/prompt'; post] +// pub fn (app &App) api_heroprompt_prompt(mut ctx Context, name string) veb.Result { +// text := ctx.form['text'] or { '' } +// mut wsp := heroprompt.get(name: name, create: false) or { +// return ctx.text('{"error":"workspace not found"}') +// } +// prompt := wsp.prompt(text: text) +// ctx.set_content_type('text/plain') +// return ctx.text(prompt) +// } -// Heroprompt API: get workspace details -@['/api/heroprompt/workspaces/:name'; get] -pub fn (app &App) api_heroprompt_get(mut ctx Context, name string) veb.Result { - wsp := heroprompt.get(name: name, create: false) or { - return ctx.text('{"error":"workspace not found"}') - } - mut children := []map[string]string{} - for ch in wsp.children { - children << { - 'name': ch.name - 'path': ch.path.path - 'type': if ch.path.cat == .dir { 'directory' } else { 'file' } - } - } - ctx.set_content_type('application/json') - return ctx.text(json.encode({ - 'name': wsp.name - 'base_path': wsp.base_path - 'children': json.encode(children) - })) -} +// // Heroprompt API: get workspace details +// @['/api/heroprompt/workspaces/:name'; get] +// pub fn (app &App) api_heroprompt_get(mut ctx Context, name string) veb.Result { +// wsp := heroprompt.get(name: name, create: false) or { +// return ctx.text('{"error":"workspace not found"}') +// } +// mut children := []map[string]string{} +// for ch in wsp.children { +// children << { +// 'name': ch.name +// 'path': ch.path.path +// 'type': if ch.path.cat == .dir { 'directory' } else { 'file' } +// } +// } +// ctx.set_content_type('application/json') +// return ctx.text(json.encode({ +// 'name': wsp.name +// 'base_path': wsp.base_path +// 'children': json.encode(children) +// })) +// } -// Heroprompt API: delete workspace -@['/api/heroprompt/workspaces/:name'; delete] -pub fn (app &App) api_heroprompt_delete(mut ctx Context, name string) veb.Result { - wsp := heroprompt.get(name: name, create: false) or { - return ctx.text('{"error":"workspace not found"}') - } - wsp.delete_workspace() or { return ctx.text('{"error":"delete failed"}') } - ctx.set_content_type('application/json') - return ctx.text('{"ok":true}') -} +// // Heroprompt API: delete workspace +// @['/api/heroprompt/workspaces/:name'; delete] +// pub fn (app &App) api_heroprompt_delete(mut ctx Context, name string) veb.Result { +// wsp := heroprompt.get(name: name, create: false) or { +// return ctx.text('{"error":"workspace not found"}') +// } +// wsp.delete_workspace() or { return ctx.text('{"error":"delete failed"}') } +// ctx.set_content_type('application/json') +// return ctx.text('{"ok":true}') +// } -// Heroprompt API: remove directory -@['/api/heroprompt/workspaces/:name/dirs/remove'; post] -pub fn (app &App) api_heroprompt_remove_dir(mut ctx Context, name string) veb.Result { - path := ctx.form['path'] or { '' } - mut wsp := heroprompt.get(name: name, create: false) or { - return ctx.text('{"error":"workspace not found"}') - } - wsp.remove_dir(path: path, name: '') or { return ctx.text('{"error":"' + err.msg() + '"}') } - return ctx.text('{"ok":true}') -} +// // Heroprompt API: remove directory +// @['/api/heroprompt/workspaces/:name/dirs/remove'; post] +// pub fn (app &App) api_heroprompt_remove_dir(mut ctx Context, name string) veb.Result { +// path := ctx.form['path'] or { '' } +// mut wsp := heroprompt.get(name: name, create: false) or { +// return ctx.text('{"error":"workspace not found"}') +// } +// wsp.remove_dir(path: path, name: '') or { return ctx.text('{"error":"' + err.msg() + '"}') } +// return ctx.text('{"ok":true}') +// } -// Heroprompt API: remove file -@['/api/heroprompt/workspaces/:name/files/remove'; post] -pub fn (app &App) api_heroprompt_remove_file(mut ctx Context, name string) veb.Result { - path := ctx.form['path'] or { '' } - mut wsp := heroprompt.get(name: name, create: false) or { - return ctx.text('{"error":"workspace not found"}') - } - wsp.remove_file(path: path, name: '') or { return ctx.text('{"error":"' + err.msg() + '"}') } - return ctx.text('{"ok":true}') -} +// // Heroprompt API: remove file +// @['/api/heroprompt/workspaces/:name/files/remove'; post] +// pub fn (app &App) api_heroprompt_remove_file(mut ctx Context, name string) veb.Result { +// path := ctx.form['path'] or { '' } +// mut wsp := heroprompt.get(name: name, create: false) or { +// return ctx.text('{"error":"workspace not found"}') +// } +// wsp.remove_file(path: path, name: '') or { return ctx.text('{"error":"' + err.msg() + '"}') } +// return ctx.text('{"ok":true}') +// } diff --git a/lib/web/ui/factory.v b/lib/web/ui/factory.v index 5c703d96..384b1055 100644 --- a/lib/web/ui/factory.v +++ b/lib/web/ui/factory.v @@ -1,471 +1,471 @@ module ui -import veb -import os +// import veb +// import os -// Public Context type for veb -pub struct Context { - veb.Context -} +// // Public Context type for veb +// pub struct Context { +// veb.Context +// } -// Simple tree menu structure -pub struct MenuItem { -pub: - title string - href string - children []MenuItem -} +// // 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 -} +// // 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 -} +// // 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) -} +// // 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 +// // Routes -// Redirect root to /admin -@['/'; get] -pub fn (app &App) root(mut ctx Context) veb.Result { - return ctx.redirect('/admin') -} +// // 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')) -} +// // 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()) -} +// // 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()) -} +// // 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 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/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 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/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/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/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) -} +// @['/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')) -} +// // 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 +// // 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') +// 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) - } +// // 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') +// // 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') +// // 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 -} +// 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') +// // 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() - } +// // 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') +// // 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') +// // 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 -} +// 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') +// // 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() - } +// // 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') +// // 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') +// // 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 -} +// 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 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 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} - - - - - +// // 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.

-
-
-
-
+//
+//
+//
+//
${heading}
+// /admin/${path} +//
+//
+//
+//

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

+//

Use the treeview on the left to navigate.

+//
+//
+//
+//
- - - -' -} +// +// +// +// ' +// } -// Recursive menu renderer +// // 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') -} +// 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' - }, - ] - }, - ] -} +// // 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' +// }, +// ] +// }, +// ] +// } diff --git a/lib/web/ui/server.v b/lib/web/ui/server.v index d804ab16..fa1dcec5 100644 --- a/lib/web/ui/server.v +++ b/lib/web/ui/server.v @@ -1,243 +1,243 @@ module ui -import veb -import os -import net.http -import json -import freeflowuniverse.herolib.develop.heroprompt +// import veb +// import os +// import net.http +// import json +// import freeflowuniverse.herolib.develop.heroprompt -// Public Context type for veb -pub struct Context { - veb.Context -} +// // Public Context type for veb +// pub struct Context { +// veb.Context +// } -// Simple tree menu structure -pub struct MenuItem { -pub: - title string - href string - children []MenuItem -} +// // Simple tree menu structure +// pub struct MenuItem { +// pub: +// title string +// href string +// children []MenuItem +// } -// Factory args -@[params] -pub struct FactoryArgs { -pub mut: - name string = 'default' - host string = 'localhost' - port int = 8080 - title string = 'Admin' - menu []MenuItem - open bool -} +// // Factory args +// @[params] +// pub struct FactoryArgs { +// 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 - menu []MenuItem - port int -} +// // The App holds server state and config +// pub struct App { +// veb.StaticHandler +// pub mut: +// title string +// menu []MenuItem +// port int +// } -pub fn new(args FactoryArgs) !&App { - mut app := App{ - title: args.title - menu: args.menu - port: args.port - } - return &app -} +// pub fn new(args FactoryArgs) !&App { +// mut app := App{ +// title: args.title +// menu: args.menu +// port: args.port +// } +// return &app +// } -// Start the webserver (blocking) -pub fn start(args FactoryArgs) ! { - mut app := new(args)! - veb.run[App, Context](mut app, app.port) -} +// // Start the webserver (blocking) +// pub fn start(args FactoryArgs) ! { +// mut app := new(args)! +// veb.run[App, Context](mut app, app.port) +// } -// Routes +// // Routes -// Redirect root to /admin -@['/'; get] -pub fn (app &App) root(mut ctx Context) veb.Result { - return ctx.redirect('/admin') -} +// // 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(render_admin(app, '/', 'Welcome')) -} +// // Admin home page +// @['/admin'; get] +// pub fn (app &App) admin_index(mut ctx Context) veb.Result { +// return ctx.html(render_admin(app, '/', 'Welcome')) +// } -// HeroScript editor page -@['/admin/heroscript'; get] -pub fn (app &App) admin_heroscript(mut ctx Context) veb.Result { - return ctx.html(render_heroscript(app)) -} +// // HeroScript editor page +// @['/admin/heroscript'; get] +// pub fn (app &App) admin_heroscript(mut ctx Context) veb.Result { +// return ctx.html(render_heroscript(app)) +// } -// Chat page -@['/admin/chat'; get] -pub fn (app &App) admin_chat(mut ctx Context) veb.Result { - return ctx.html(render_chat(app)) -} +// // Chat page +// @['/admin/chat'; get] +// pub fn (app &App) admin_chat(mut ctx Context) veb.Result { +// return ctx.html(render_chat(app)) +// } -// Heroprompt page -@['/admin/heroprompt'; get] -pub fn (app &App) admin_heroprompt_page(mut ctx Context) veb.Result { - template_path := os.join_path(os.dir(@FILE), 'templates', 'heroprompt.html') - template_content := os.read_file(template_path) or { return ctx.text('template not found') } - menu_content := menu_html(app.menu, 0, 'm') - 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_heroprompt_url}}', '/static/css/heroprompt.css?v=2') - result = result.replace('{{.js_theme_url}}', '/static/js/theme.js?v=2') - result = result.replace('{{.js_heroprompt_url}}', '/static/js/heroprompt.js?v=2') - return ctx.html(result) -} +// // Heroprompt page +// @['/admin/heroprompt'; get] +// pub fn (app &App) admin_heroprompt_page(mut ctx Context) veb.Result { +// template_path := os.join_path(os.dir(@FILE), 'templates', 'heroprompt.html') +// template_content := os.read_file(template_path) or { return ctx.text('template not found') } +// menu_content := menu_html(app.menu, 0, 'm') +// 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_heroprompt_url}}', '/static/css/heroprompt.css?v=2') +// result = result.replace('{{.js_theme_url}}', '/static/js/theme.js?v=2') +// result = result.replace('{{.js_heroprompt_url}}', '/static/js/heroprompt.js?v=2') +// return ctx.html(result) +// } -// Static Heroprompt assets -@['/static/css/heroprompt.css'; get] -pub fn (app &App) serve_heroprompt_css(mut ctx Context) veb.Result { - css_path := os.join_path(os.dir(@FILE), 'templates', 'css', 'heroprompt.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 Heroprompt assets +// @['/static/css/heroprompt.css'; get] +// pub fn (app &App) serve_heroprompt_css(mut ctx Context) veb.Result { +// css_path := os.join_path(os.dir(@FILE), 'templates', 'css', 'heroprompt.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/heroprompt.js'; get] -pub fn (app &App) serve_heroprompt_js(mut ctx Context) veb.Result { - js_path := os.join_path(os.dir(@FILE), 'templates', 'js', 'heroprompt.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/heroprompt.js'; get] +// pub fn (app &App) serve_heroprompt_js(mut ctx Context) veb.Result { +// js_path := os.join_path(os.dir(@FILE), 'templates', 'js', 'heroprompt.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 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 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/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 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/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/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/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) -} +// @['/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(render_admin(app, path, '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(render_admin(app, path, 'Content')) +// } -// Pure functions for rendering templates -fn render_admin(app &App, path string, heading string) string { - template_path := os.join_path(os.dir(@FILE), 'templates', 'admin_layout.html') - template_content := os.read_file(template_path) or { - return render_admin_fallback(app, path, heading) - } - menu_content := menu_html(app.menu, 0, 'm') - 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 -} +// // Pure functions for rendering templates +// fn render_admin(app &App, path string, heading string) string { +// template_path := os.join_path(os.dir(@FILE), 'templates', 'admin_layout.html') +// template_content := os.read_file(template_path) or { +// return render_admin_fallback(app, path, heading) +// } +// menu_content := menu_html(app.menu, 0, 'm') +// 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 +// } -fn render_heroscript(app &App) string { - template_path := os.join_path(os.dir(@FILE), 'templates', 'heroscript_editor.html') - template_content := os.read_file(template_path) or { return render_heroscript_fallback(app) } - menu_content := menu_html(app.menu, 0, 'm') - 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 -} +// fn render_heroscript(app &App) string { +// template_path := os.join_path(os.dir(@FILE), 'templates', 'heroscript_editor.html') +// template_content := os.read_file(template_path) or { return render_heroscript_fallback(app) } +// menu_content := menu_html(app.menu, 0, 'm') +// 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 +// } -fn render_chat(app &App) string { - template_path := os.join_path(os.dir(@FILE), 'templates', 'chat.html') - template_content := os.read_file(template_path) or { return render_chat_fallback(app) } - menu_content := menu_html(app.menu, 0, 'm') - 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 -} +// fn render_chat(app &App) string { +// template_path := os.join_path(os.dir(@FILE), 'templates', 'chat.html') +// template_content := os.read_file(template_path) or { return render_chat_fallback(app) } +// menu_content := menu_html(app.menu, 0, 'm') +// 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 +// } -// Fallbacks -fn render_heroscript_fallback(app &App) string { - return '\n\n\n\n\t\n\t\n\t${app.title} - HeroScript Editor\n\t\n\n\n\t
\n\t\t

HeroScript Editor

\n\t\t

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

\n\t\tBack to Admin\n\t
\n\n\n' -} +// // Fallbacks +// fn render_heroscript_fallback(app &App) string { +// return '\n\n\n\n\t\n\t\n\t${app.title} - HeroScript Editor\n\t\n\n\n\t
\n\t\t

HeroScript Editor

\n\t\t

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

\n\t\tBack to Admin\n\t
\n\n\n' +// } -fn render_chat_fallback(app &App) string { - return '\n\n\n\n\t\n\t\n\t${app.title} - Chat\n\t\n\n\n\t
\n\t\t

Chat Assistant

\n\t\t

Chat template not found. Please check the template files.

\n\t\tBack to Admin\n\t
\n\n\n' -} +// fn render_chat_fallback(app &App) string { +// return '\n\n\n\n\t\n\t\n\t${app.title} - Chat\n\t\n\n\n\t
\n\t\t

Chat Assistant

\n\t\t

Chat template not found. Please check the template files.

\n\t\tBack to Admin\n\t
\n\n\n' +// } -fn render_admin_fallback(app &App, path string, heading string) string { - return '\n\n\n\n\t\n\t\n\t${app.title}\n\t\n\t\n\n\n\t\n\n\t\n\n\t
\n\t\t
\n\t\t\t
\n\t\t\t\t
${heading}
\n\t\t\t\t/admin/${path}\n\t\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

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

\n\t\t\t\t\t

Use the treeview on the left to navigate.

\n\t\t\t\t
\n\t\t\t
\n\t\t
\n\t
\n\n\t\n\n\n' -} +// fn render_admin_fallback(app &App, path string, heading string) string { +// return '\n\n\n\n\t\n\t\n\t${app.title}\n\t\n\t\n\n\n\t\n\n\t\n\n\t
\n\t\t
\n\t\t\t
\n\t\t\t\t
${heading}
\n\t\t\t\t/admin/${path}\n\t\t\t
\n\t\t\t
\n\t\t\t\t
\n\t\t\t\t\t

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

\n\t\t\t\t\t

Use the treeview on the left to navigate.

\n\t\t\t\t
\n\t\t\t
\n\t\t
\n\t
\n\n\t\n\n\n' +// } diff --git a/lib/web/ui/utils.v b/lib/web/ui/utils.v index 1f81f654..e21fe0cc 100644 --- a/lib/web/ui/utils.v +++ b/lib/web/ui/utils.v @@ -1,30 +1,30 @@ module ui -// 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 << '${it.title}' - } - } - return out.join('\n') -} +// // 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 << '${it.title}' +// } +// } +// return out.join('\n') +// }