mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
feat: add login and level 1 pages with UI components and actions
This commit is contained in:
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import * as fengari from 'fengari-web'
|
||||
|
||||
import { fromLua } from '@/lib/lua/functions/converters/from-lua'
|
||||
|
||||
const lua = fengari.lua
|
||||
|
||||
@@ -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'
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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
|
||||
180
frontends/nextjs/src/lib/packages/lua-ui/login-page/login-ui.lua
Normal file
180
frontends/nextjs/src/lib/packages/lua-ui/login-page/login-ui.lua
Normal 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
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
20
packages/ui_pages/seed/metadata.json
Normal file
20
packages/ui_pages/seed/metadata.json
Normal 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"
|
||||
]
|
||||
}
|
||||
}
|
||||
124
packages/ui_pages/seed/pages/level1.json
Normal file
124
packages/ui_pages/seed/pages/level1.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
174
packages/ui_pages/seed/pages/login.json
Normal file
174
packages/ui_pages/seed/pages/login.json
Normal 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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user