feat: add login and level 1 pages with UI components and actions

This commit is contained in:
2025-12-29 22:55:41 +00:00
parent bc1b8de3e0
commit 9f10d771d2
16 changed files with 842 additions and 16 deletions

View File

@@ -133,7 +133,7 @@ export function JsonEditor({ open, onClose, title, value, onSave, schema }: Json
<AlertDescription className="text-yellow-800">
{securityScanResult.issues.length} security{' '}
{securityScanResult.issues.length === 1 ? 'issue' : 'issues'}
 detected. Click Security Scan to review.
detected. Click Security Scan to review.
</AlertDescription>
</Alert>
)}

View File

@@ -3,7 +3,7 @@ import { toast } from 'sonner'
import { CssCategory, Database } from '@/lib/database'
const CLASS_TOKEN_PATTERN = /^[A-Za-z0-9:_/.\[\]()%#!,=+-]+$/
const CLASS_TOKEN_PATTERN = /^[A-Za-z0-9:_/.[\]()%#!,=+-]+$/
const parseClassList = (value: string) => Array.from(new Set(value.split(/\s+/).filter(Boolean)))
interface UseClassBuilderStateProps {

View File

@@ -1,4 +1,5 @@
import * as fengari from 'fengari-web'
import { fromLua } from '@/lib/lua/functions/converters/from-lua'
const lua = fengari.lua

View File

@@ -1,5 +1,6 @@
import { describe, it, expect } from 'bun:test'
import { describe, expect,it } from 'bun:test'
import React from 'react'
import { generateComponentTree } from './generate-component-tree'
import type { LuaUIComponent } from './types/lua-ui-package'

View File

@@ -1,9 +1,11 @@
import * as fengari from 'fengari-web'
import { readFile } from 'fs/promises'
import { join } from 'path'
import * as fengari from 'fengari-web'
import { createLuaEngine } from '@/lib/lua/engine/core/create-lua-engine'
import { pushToLua } from '@/lib/lua/functions/converters/push-to-lua'
import { fromLua } from '@/lib/lua/functions/converters/from-lua'
import { pushToLua } from '@/lib/lua/functions/converters/push-to-lua'
import { normalizeLuaComponent } from './normalize-lua-structure'
import type { LuaUIManifest, LuaUIPackage, LuaUIPage } from './types/lua-ui-package'
@@ -85,7 +87,7 @@ export async function loadLuaUIPackage(packagePath: string): Promise<LuaUIPackag
}
// Load all action files
const actions: Record<string, Function> = {}
const actions: Record<string, (...args: any[]) => any> = {}
if (manifest.actions) {
for (const actionManifest of manifest.actions) {
const actionPath = join(packagePath, actionManifest.file)
@@ -148,7 +150,7 @@ export async function loadLuaUIPackage(packagePath: string): Promise<LuaUIPackag
/**
* Create a JavaScript wrapper function that calls a Lua function
*/
function createLuaFunctionWrapper(luaSource: string, functionName: string): Function {
function createLuaFunctionWrapper(luaSource: string, functionName: string): (...args: any[]) => any {
return (...args: any[]) => {
// Create a new Lua engine for this call
const engine = createLuaEngine()

View File

@@ -58,7 +58,7 @@ export interface LuaUIComponent {
export interface LuaUIAction {
name: string
handler: string | Function
handler: string | ((...args: any[]) => any)
}
export interface LuaUIValidation {
@@ -71,7 +71,7 @@ export interface LuaUIValidation {
max?: number
pattern?: string
format?: string
custom?: string | Function
custom?: string | ((...args: any[]) => any)
}
}
@@ -81,5 +81,5 @@ export interface LuaUIValidation {
export interface LuaUIPackage {
manifest: LuaUIManifest
pages: LuaUIPage[]
actions: Record<string, Function>
actions: Record<string, (...args: any[]) => any>
}

View File

@@ -0,0 +1,118 @@
{
"type": "Box",
"props": {
"className": "min-h-screen bg-gradient-to-br from-primary/5 via-background to-accent/5"
},
"children": [
{
"type": "NavigationBar",
"props": {
"level": 1,
"onNavigate": "handleNavigate"
}
},
{
"type": "Container",
"props": {
"maxWidth": "lg",
"className": "px-4 sm:px-6 lg:px-8 pt-6 space-y-6"
},
"children": [
{
"type": "Card",
"children": [
{
"type": "CardHeader",
"children": [
{
"type": "CardTitle",
"props": { "text": "Server Status" }
}
]
},
{
"type": "CardContent",
"children": [
{
"type": "Typography",
"props": {
"variant": "body1",
"text": "MetaBuilder Development Server"
}
},
{
"type": "Typography",
"props": {
"variant": "body2",
"color": "textSecondary",
"text": "Status: Active"
}
}
]
}
]
},
{
"type": "Tabs",
"props": { "defaultValue": "overview" },
"children": [
{
"type": "TabsList",
"children": [
{
"type": "TabsTrigger",
"props": { "value": "overview", "text": "Overview" }
},
{
"type": "TabsTrigger",
"props": { "value": "features", "text": "Features" }
},
{
"type": "TabsTrigger",
"props": { "value": "docs", "text": "Documentation" }
}
]
},
{
"type": "TabsContent",
"props": { "value": "overview" },
"children": [
{
"type": "Stack",
"props": { "spacing": 2 },
"children": [
{
"type": "Typography",
"props": {
"variant": "h5",
"text": "Welcome to MetaBuilder"
}
},
{
"type": "Typography",
"props": {
"variant": "body1",
"text": "MetaBuilder is a powerful data-driven platform with multi-level navigation."
}
},
{
"type": "Button",
"props": {
"variant": "contained",
"text": "Explore Level 2",
"onClick": "navigateToLevel2"
}
}
]
}
]
}
]
}
]
},
{
"type": "AppFooter"
}
]
}

View File

@@ -0,0 +1,137 @@
local M = {}
function M.render()
return {
type = "Box",
props = {
className = "min-h-screen bg-gradient-to-br from-primary/5 via-background to-accent/5"
},
children = {
-- Navigation Bar
{
type = "NavigationBar",
props = {
level = 1,
onNavigate = "handleNavigate"
}
},
-- Main Content
{
type = "Container",
props = {
maxWidth = "lg",
className = "px-4 sm:px-6 lg:px-8 pt-6 space-y-6"
},
children = {
-- Credentials Section
{
type = "Card",
props = {},
children = {
{
type = "CardHeader",
props = {},
children = {
{
type = "CardTitle",
props = { text = "Server Status" }
}
}
},
{
type = "CardContent",
props = {},
children = {
{
type = "Typography",
props = {
variant = "body1",
text = "MetaBuilder Development Server"
}
},
{
type = "Typography",
props = {
variant = "body2",
color = "textSecondary",
text = "Status: Active"
}
}
}
}
}
},
-- Level Tabs
{
type = "Tabs",
props = { defaultValue = "overview" },
children = {
{
type = "TabsList",
props = {},
children = {
{
type = "TabsTrigger",
props = { value = "overview", text = "Overview" }
},
{
type = "TabsTrigger",
props = { value = "features", text = "Features" }
},
{
type = "TabsTrigger",
props = { value = "docs", text = "Documentation" }
}
}
},
{
type = "TabsContent",
props = { value = "overview" },
children = {
{
type = "Stack",
props = { spacing = 2 },
children = {
{
type = "Typography",
props = {
variant = "h5",
text = "Welcome to MetaBuilder"
}
},
{
type = "Typography",
props = {
variant = "body1",
text = "MetaBuilder is a powerful data-driven platform with multi-level navigation."
}
},
{
type = "Button",
props = {
variant = "contained",
text = "Explore Level 2",
onClick = "navigateToLevel2"
}
}
}
}
}
}
}
}
}
},
-- Footer
{
type = "AppFooter",
props = {}
}
}
}
end
return M

View File

@@ -0,0 +1,22 @@
{
"id": "level1-page",
"version": "1.0.0",
"name": "Level 1 - Home",
"description": "Main landing page with navigation and credentials",
"category": "ui",
"pages": [
{
"file": "level1-ui.lua",
"path": "/",
"title": "Home",
"level": 1,
"requiresAuth": false
}
],
"actions": [
{
"file": "level1-actions.lua",
"name": "level1_actions"
}
]
}

View File

@@ -0,0 +1,25 @@
local M = {}
function M.handleLogin(formData)
-- This will be called from React with form data
print("Login attempt for user:", formData.username)
-- Return result that React can handle
return {
action = "login",
username = formData.username,
password = formData.password
}
end
function M.handleRegister(formData)
print("Registration attempt for:", formData.username, formData.email)
return {
action = "register",
username = formData.username,
email = formData.email
}
end
return M

View File

@@ -0,0 +1,180 @@
local M = {}
function M.render()
return {
type = "Box",
props = {
className = "min-h-screen bg-gradient-to-br from-primary/5 via-background to-accent/5 flex items-center justify-center p-4"
},
children = {
{
type = "Card",
props = { className = "w-full max-w-md" },
children = {
{
type = "CardHeader",
props = {},
children = {
{
type = "CardTitle",
props = { text = "Welcome to MetaBuilder" }
},
{
type = "CardDescription",
props = { text = "Sign in to your account or create a new one" }
}
}
},
{
type = "CardContent",
props = {},
children = {
{
type = "Tabs",
props = { defaultValue = "login" },
children = {
{
type = "TabsList",
props = { className = "grid w-full grid-cols-2" },
children = {
{
type = "TabsTrigger",
props = { value = "login", text = "Login" }
},
{
type = "TabsTrigger",
props = { value = "register", text = "Register" }
}
}
},
{
type = "TabsContent",
props = { value = "login" },
children = {
{
type = "Stack",
props = { spacing = 3 },
children = {
{
type = "Box",
props = {},
children = {
{
type = "Label",
props = { htmlFor = "username", text = "Username" }
},
{
type = "Input",
props = {
id = "username",
name = "username",
placeholder = "Enter your username",
required = true
}
}
}
},
{
type = "Box",
props = {},
children = {
{
type = "Label",
props = { htmlFor = "password", text = "Password" }
},
{
type = "Input",
props = {
id = "password",
name = "password",
type = "password",
placeholder = "Enter your password",
required = true
}
}
}
},
{
type = "Button",
props = {
type = "submit",
className = "w-full",
text = "Sign In",
onClick = "handleLogin"
}
}
}
}
}
},
{
type = "TabsContent",
props = { value = "register" },
children = {
{
type = "Stack",
props = { spacing = 3 },
children = {
{
type = "Box",
props = {},
children = {
{
type = "Label",
props = { htmlFor = "reg-username", text = "Username" }
},
{
type = "Input",
props = {
id = "reg-username",
name = "username",
placeholder = "Choose a username",
required = true
}
}
}
},
{
type = "Box",
props = {},
children = {
{
type = "Label",
props = { htmlFor = "email", text = "Email" }
},
{
type = "Input",
props = {
id = "email",
name = "email",
type = "email",
placeholder = "your@email.com",
required = true
}
}
}
},
{
type = "Button",
props = {
type = "submit",
className = "w-full",
text = "Create Account",
onClick = "handleRegister"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
end
return M

View File

@@ -0,0 +1,22 @@
{
"id": "login-page",
"version": "1.0.0",
"name": "Login Page",
"description": "Unified login and registration page",
"category": "ui",
"pages": [
{
"file": "login-ui.lua",
"path": "/login",
"title": "Login",
"level": 1,
"requiresAuth": false
}
],
"actions": [
{
"file": "login-actions.lua",
"name": "login_actions"
}
]
}

View File

@@ -13,26 +13,26 @@ import { initializeDefaultPages } from './functions/initialize-default-pages'
*/
export class PageDefinitionBuilderUtils {
static async initializeDefaultPages(): Promise<void> {
return await initializeDefaultPages(...(arguments as any))
return await initializeDefaultPages()
}
static buildLevel1Homepage(): PageDefinition {
return buildLevel1Homepage(...(arguments as any))
return buildLevel1Homepage()
}
static buildLevel2UserDashboard(): PageDefinition {
return buildLevel2UserDashboard(...(arguments as any))
return buildLevel2UserDashboard()
}
static buildLevel3AdminPanel(): PageDefinition {
return buildLevel3AdminPanel(...(arguments as any))
return buildLevel3AdminPanel()
}
static getPages(): PageDefinition[] {
return getPages(...(arguments as any))
return getPages()
}
static getPageDefinitionBuilder(): PageDefinitionBuilder {
return getPageDefinitionBuilder(...(arguments as any))
return getPageDefinitionBuilder()
}
}

View File

@@ -0,0 +1,20 @@
{
"packageId": "ui_pages",
"name": "UI Pages",
"version": "1.0.0",
"description": "Declarative JSON-defined UI pages for all levels",
"author": "MetaBuilder",
"category": "ui",
"dependencies": [],
"exports": {
"pages": [
"login",
"level1",
"level2",
"level3",
"level4",
"level5",
"level6"
]
}
}

View File

@@ -0,0 +1,124 @@
{
"path": "/",
"title": "Home",
"level": 1,
"requiresAuth": false,
"layout": {
"type": "Box",
"props": {
"className": "min-h-screen bg-gradient-to-br from-primary/5 via-background to-accent/5"
},
"children": [
{
"type": "NavigationBar",
"props": {
"level": 1,
"onNavigate": "handleNavigate"
}
},
{
"type": "Container",
"props": {
"maxWidth": "lg",
"className": "px-4 sm:px-6 lg:px-8 pt-6 space-y-6"
},
"children": [
{
"type": "Card",
"children": [
{
"type": "CardHeader",
"children": [
{
"type": "CardTitle",
"props": { "text": "Server Status" }
}
]
},
{
"type": "CardContent",
"children": [
{
"type": "Typography",
"props": {
"variant": "body1",
"text": "MetaBuilder Development Server"
}
},
{
"type": "Typography",
"props": {
"variant": "body2",
"color": "textSecondary",
"text": "Status: Active"
}
}
]
}
]
},
{
"type": "Tabs",
"props": { "defaultValue": "overview" },
"children": [
{
"type": "TabsList",
"children": [
{
"type": "TabsTrigger",
"props": { "value": "overview", "text": "Overview" }
},
{
"type": "TabsTrigger",
"props": { "value": "features", "text": "Features" }
},
{
"type": "TabsTrigger",
"props": { "value": "docs", "text": "Documentation" }
}
]
},
{
"type": "TabsContent",
"props": { "value": "overview" },
"children": [
{
"type": "Stack",
"props": { "spacing": 2 },
"children": [
{
"type": "Typography",
"props": {
"variant": "h5",
"text": "Welcome to MetaBuilder"
}
},
{
"type": "Typography",
"props": {
"variant": "body1",
"text": "MetaBuilder is a powerful data-driven platform with multi-level navigation."
}
},
{
"type": "Button",
"props": {
"variant": "contained",
"text": "Explore Level 2",
"onClick": "navigateToLevel2"
}
}
]
}
]
}
]
}
]
},
{
"type": "AppFooter"
}
]
}
}

View File

@@ -0,0 +1,174 @@
{
"path": "/login",
"title": "Login",
"level": 1,
"requiresAuth": false,
"layout": {
"type": "Box",
"props": {
"className": "min-h-screen bg-gradient-to-br from-primary/5 via-background to-accent/5 flex items-center justify-center p-4"
},
"children": [
{
"type": "Card",
"props": { "className": "w-full max-w-md" },
"children": [
{
"type": "CardHeader",
"children": [
{
"type": "CardTitle",
"props": { "text": "Welcome to MetaBuilder" }
},
{
"type": "CardDescription",
"props": { "text": "Sign in to your account or create a new one" }
}
]
},
{
"type": "CardContent",
"children": [
{
"type": "Tabs",
"props": { "defaultValue": "login" },
"children": [
{
"type": "TabsList",
"props": { "className": "grid w-full grid-cols-2" },
"children": [
{
"type": "TabsTrigger",
"props": { "value": "login", "text": "Login" }
},
{
"type": "TabsTrigger",
"props": { "value": "register", "text": "Register" }
}
]
},
{
"type": "TabsContent",
"props": { "value": "login" },
"children": [
{
"type": "Stack",
"props": { "spacing": 3 },
"children": [
{
"type": "Box",
"children": [
{
"type": "Label",
"props": { "htmlFor": "username", "text": "Username" }
},
{
"type": "Input",
"props": {
"id": "username",
"name": "username",
"placeholder": "Enter your username",
"required": true
}
}
]
},
{
"type": "Box",
"children": [
{
"type": "Label",
"props": { "htmlFor": "password", "text": "Password" }
},
{
"type": "Input",
"props": {
"id": "password",
"name": "password",
"type": "password",
"placeholder": "Enter your password",
"required": true
}
}
]
},
{
"type": "Button",
"props": {
"type": "submit",
"className": "w-full",
"text": "Sign In",
"onClick": "handleLogin"
}
}
]
}
]
},
{
"type": "TabsContent",
"props": { "value": "register" },
"children": [
{
"type": "Stack",
"props": { "spacing": 3 },
"children": [
{
"type": "Box",
"children": [
{
"type": "Label",
"props": { "htmlFor": "reg-username", "text": "Username" }
},
{
"type": "Input",
"props": {
"id": "reg-username",
"name": "username",
"placeholder": "Choose a username",
"required": true
}
}
]
},
{
"type": "Box",
"children": [
{
"type": "Label",
"props": { "htmlFor": "email", "text": "Email" }
},
{
"type": "Input",
"props": {
"id": "email",
"name": "email",
"type": "email",
"placeholder": "your@email.com",
"required": true
}
}
]
},
{
"type": "Button",
"props": {
"type": "submit",
"className": "w-full",
"text": "Create Account",
"onClick": "handleRegister"
}
}
]
}
]
}
]
}
]
}
]
}
]
}
}