diff --git a/frontends/nextjs/src/components/misc/viewers/ModelListView.tsx b/frontends/nextjs/src/components/misc/viewers/ModelListView.tsx index 101428678..c9ff5224f 100644 --- a/frontends/nextjs/src/components/misc/viewers/ModelListView.tsx +++ b/frontends/nextjs/src/components/misc/viewers/ModelListView.tsx @@ -17,9 +17,14 @@ import { getRecordsKey, sortRecords, } from '@/lib/schema-utils' +import type { JsonObject, JsonValue } from '@/types/utility-types' import { RecordForm } from './RecordForm' +type RecordValue = string | number | boolean | null | JsonObject | JsonValue[] + +type RecordData = Record + interface RelationCellValueProps { value: string relatedModel: string @@ -29,8 +34,8 @@ interface RelationCellValueProps { function RelationCellValue({ value, relatedModel, currentApp, schema }: RelationCellValueProps) { const relatedRecordsKey = getRecordsKey(currentApp, relatedModel) - const [relatedRecords] = useKV(relatedRecordsKey, []) - const relatedRecord = relatedRecords?.find((r: any) => r.id === value) + const [relatedRecords] = useKV(relatedRecordsKey, []) + const relatedRecord = relatedRecords?.find(r => r.id === value) if (!relatedRecord) return {value} @@ -53,7 +58,7 @@ interface ModelListViewProps { } export function ModelListView({ model, schema, currentApp }: ModelListViewProps) { - const [records, setRecords] = useKV(getRecordsKey(currentApp, model.name), []) + const [records, setRecords] = useKV(getRecordsKey(currentApp, model.name), []) const [searchTerm, setSearchTerm] = useState('') const [sortField, setSortField] = useState( model.ordering?.[0]?.replace('-', '') || null @@ -61,9 +66,9 @@ export function ModelListView({ model, schema, currentApp }: ModelListViewProps) const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>( model.ordering?.[0]?.startsWith('-') ? 'desc' : 'asc' ) - const [filters, setFilters] = useState>({}) + const [filters, setFilters] = useState>({}) const [formOpen, setFormOpen] = useState(false) - const [editingRecord, setEditingRecord] = useState(null) + const [editingRecord, setEditingRecord] = useState(null) const displayFields = model.listDisplay || @@ -102,7 +107,7 @@ export function ModelListView({ model, schema, currentApp }: ModelListViewProps) setFormOpen(true) } - const handleEdit = (record: any) => { + const handleEdit = (record: RecordData) => { setEditingRecord(record) setFormOpen(true) } @@ -112,7 +117,7 @@ export function ModelListView({ model, schema, currentApp }: ModelListViewProps) toast.success('Record deleted') } - const handleSave = (record: any) => { + const handleSave = (record: RecordData) => { if (editingRecord) { setRecords(current => (current || []).map(r => (r.id === record.id ? record : r))) toast.success('Record updated') @@ -122,7 +127,7 @@ export function ModelListView({ model, schema, currentApp }: ModelListViewProps) } } - const renderCellValue = (record: any, fieldName: string) => { + const renderCellValue = (record: RecordData, fieldName: string) => { const field = model.fields.find(f => f.name === fieldName) if (!field) return null diff --git a/frontends/nextjs/src/components/misc/viewers/model-list/DetailsDrawer.tsx b/frontends/nextjs/src/components/misc/viewers/model-list/DetailsDrawer.tsx index 2e3778f63..332ba6b4e 100644 --- a/frontends/nextjs/src/components/misc/viewers/model-list/DetailsDrawer.tsx +++ b/frontends/nextjs/src/components/misc/viewers/model-list/DetailsDrawer.tsx @@ -13,11 +13,14 @@ import { } from '@/components/ui' import type { ModelSchema } from '@/lib/schema-types' import { getFieldLabel } from '@/lib/schema-utils' +import type { JsonValue } from '@/types/utility-types' + +type RecordData = Record interface DetailsDrawerProps { open: boolean onOpenChange: (open: boolean) => void - record: any | null + record: RecordData | null model: ModelSchema } diff --git a/frontends/nextjs/src/components/misc/viewers/model-list/ModelFilters.tsx b/frontends/nextjs/src/components/misc/viewers/model-list/ModelFilters.tsx index 1c8946d20..2621e5c93 100644 --- a/frontends/nextjs/src/components/misc/viewers/model-list/ModelFilters.tsx +++ b/frontends/nextjs/src/components/misc/viewers/model-list/ModelFilters.tsx @@ -10,13 +10,14 @@ import { SelectValue, } from '@/components/ui' import type { FieldSchema, ModelSchema } from '@/lib/schema-types' +import type { JsonValue } from '@/types/utility-types' interface ModelFiltersProps { model: ModelSchema - filters: Record + filters: Record searchTerm: string onSearchChange: (value: string) => void - onFilterChange: (field: string, value: any) => void + onFilterChange: (field: string, value: JsonValue) => void } function getFilterableFields(model: ModelSchema): FieldSchema[] { diff --git a/frontends/nextjs/src/components/misc/viewers/model-list/ModelTable.tsx b/frontends/nextjs/src/components/misc/viewers/model-list/ModelTable.tsx index 13cbc67d3..e6cd1606d 100644 --- a/frontends/nextjs/src/components/misc/viewers/model-list/ModelTable.tsx +++ b/frontends/nextjs/src/components/misc/viewers/model-list/ModelTable.tsx @@ -13,17 +13,20 @@ import { } from '@/components/ui' import type { FieldSchema, ModelSchema } from '@/lib/schema-types' import { getFieldLabel } from '@/lib/schema-utils' +import type { JsonValue } from '@/types/utility-types' + +type RecordData = Record interface ModelTableProps { model: ModelSchema - records: any[] + records: RecordData[] displayFields: string[] sortField?: string | null sortDirection?: 'asc' | 'desc' onSortChange?: (field: string) => void - onEdit?: (record: any) => void + onEdit?: (record: RecordData) => void onDelete?: (id: string) => void - onRowClick?: (record: any) => void + onRowClick?: (record: RecordData) => void renderRelationValue?: (value: string, field: FieldSchema) => ReactNode } @@ -41,7 +44,7 @@ export function ModelTable({ }: ModelTableProps) { const actionColumns = onEdit || onDelete ? 1 : 0 - const renderCellValue = (record: any, fieldName: string) => { + const renderCellValue = (record: RecordData, fieldName: string) => { const field = model.fields.find(item => item.name === fieldName) if (!field) return null diff --git a/frontends/nextjs/src/components/ui/molecules/navigation/NavItem.tsx b/frontends/nextjs/src/components/ui/molecules/navigation/NavItem.tsx index 178caf9be..a7218e012 100644 --- a/frontends/nextjs/src/components/ui/molecules/navigation/NavItem.tsx +++ b/frontends/nextjs/src/components/ui/molecules/navigation/NavItem.tsx @@ -1,9 +1,17 @@ 'use client' -import { Badge, Box, ListItem, ListItemButton, ListItemIcon, ListItemText } from '@mui/material' +import { + Badge, + Box, + ListItem, + ListItemButton, + ListItemIcon, + ListItemText, + type ListItemProps, +} from '@mui/material' import { forwardRef, ReactNode } from 'react' -export interface NavItemProps { +export interface NavItemProps extends Omit { icon?: ReactNode label: string onClick?: () => void @@ -30,6 +38,7 @@ const NavItem = forwardRef( href, secondaryLabel, dense = false, + sx, ...props }, ref @@ -39,9 +48,7 @@ const NavItem = forwardRef( ref={ref} disablePadding {...props} - sx={{ - ...(props as any).sx, - }} + sx={sx} > normalizeLuaStructure(item as JsonValue)) } if (typeof value === 'object') { - const keys = Object.keys(value) + const obj = value as Record + const keys = Object.keys(obj) // Check if this looks like a Lua array (all keys are sequential numbers starting from 1) const isLuaArray = keys.every((key) => { @@ -24,20 +26,20 @@ export function normalizeLuaStructure(value: any): any { if (isLuaArray && keys.length > 0) { // Convert to JavaScript array - const arr: any[] = [] + const arr: JsonValue[] = [] const sortedKeys = keys.map(Number).sort((a, b) => a - b) for (const key of sortedKeys) { - arr.push(normalizeLuaStructure(value[key])) + arr.push(normalizeLuaStructure(obj[String(key)])) } return arr } // Otherwise, recursively normalize the object - const normalized: any = {} + const normalized: Record = {} for (const key of keys) { - normalized[key] = normalizeLuaStructure(value[key]) + normalized[key] = normalizeLuaStructure(obj[key]) } return normalized @@ -49,6 +51,6 @@ export function normalizeLuaStructure(value: any): any { /** * Normalize a LuaUIComponent structure */ -export function normalizeLuaComponent(component: any): LuaUIComponent { +export function normalizeLuaComponent(component: JsonValue): LuaUIComponent { return normalizeLuaStructure(component) as LuaUIComponent } diff --git a/frontends/nextjs/src/lib/lua/ui/types/lua-ui-package.ts b/frontends/nextjs/src/lib/lua/ui/types/lua-ui-package.ts index 3da417d93..b744d4e63 100644 --- a/frontends/nextjs/src/lib/lua/ui/types/lua-ui-package.ts +++ b/frontends/nextjs/src/lib/lua/ui/types/lua-ui-package.ts @@ -2,6 +2,7 @@ * TypeScript types for Lua UI packages * These types define the structure of UI packages written in Lua */ +import type { JsonValue } from '@/types/utility-types' /** * Manifest.json structure for Lua UI packages @@ -52,13 +53,13 @@ export interface LuaUIPage { export interface LuaUIComponent { type: string - props: Record + props: Record children?: LuaUIComponent[] } export interface LuaUIAction { name: string - handler: string | ((...args: any[]) => any) + handler: string | ((...args: JsonValue[]) => JsonValue) } export interface LuaUIValidation { @@ -71,7 +72,7 @@ export interface LuaUIValidation { max?: number pattern?: string format?: string - custom?: string | ((...args: any[]) => any) + custom?: string | ((...args: JsonValue[]) => JsonValue) } } @@ -81,5 +82,5 @@ export interface LuaUIValidation { export interface LuaUIPackage { manifest: LuaUIManifest pages: LuaUIPage[] - actions: Record any> + actions: Record JsonValue> } diff --git a/frontends/nextjs/src/lib/security/secure-db/types.ts b/frontends/nextjs/src/lib/security/secure-db/types.ts index 9ae652359..6441af62b 100644 --- a/frontends/nextjs/src/lib/security/secure-db/types.ts +++ b/frontends/nextjs/src/lib/security/secure-db/types.ts @@ -1,4 +1,5 @@ import type { User } from '../../types/level-types' +import type { JsonObject } from '@/types/utility-types' export type OperationType = 'CREATE' | 'READ' | 'UPDATE' | 'DELETE' export type ResourceType = @@ -28,7 +29,7 @@ export interface AuditLog { success: boolean errorMessage?: string ipAddress?: string - metadata?: Record + metadata?: JsonObject } export interface SecurityContext { diff --git a/frontends/nextjs/src/lib/seed/import-ui-pages.ts b/frontends/nextjs/src/lib/seed/import-ui-pages.ts index 6805a6300..d9bbe6f3c 100644 --- a/frontends/nextjs/src/lib/seed/import-ui-pages.ts +++ b/frontends/nextjs/src/lib/seed/import-ui-pages.ts @@ -2,11 +2,16 @@ import { readFile, readdir } from 'fs/promises' import { join } from 'path' import type { JsonObject } from '@/types/utility-types' +type UIPagesDb = { + query(sql: string, params?: unknown[]): Promise + execute(sql: string, params?: unknown[]): Promise +} + /** * Import UI pages from JSON seed data into the database * Flow: JSON (packages/ui_pages/seed/pages/*.json) → Database (ui_page table) */ -export async function importUIPages(db: any): Promise { +export async function importUIPages(db: UIPagesDb): Promise { const pagesDir = join(process.cwd(), '../../packages/ui_pages/seed/pages') try { diff --git a/frontends/nextjs/src/lib/types/builder-types.ts b/frontends/nextjs/src/lib/types/builder-types.ts index 3d0ef542b..4f1ea5654 100644 --- a/frontends/nextjs/src/lib/types/builder-types.ts +++ b/frontends/nextjs/src/lib/types/builder-types.ts @@ -1,9 +1,12 @@ +import type { JsonValue } from '@/types/utility-types' + /** * ComponentType - All supported UI component types in the builder * @description Union type of all available components * Supports: Layout (Flex, Grid, Container), Input (Input, Select, Switch), * Display (Text, Heading, Badge), Interactive (Button, Dialog, Tabs) */ + export type ComponentType = | 'Button' | 'Input' @@ -39,7 +42,7 @@ export type ComponentType = * @example { className: "mt-4", disabled: true, onClick: fn } */ export interface ComponentProps { - [key: string]: unknown + [key: string]: JsonValue } /** @@ -85,7 +88,7 @@ export interface PropDefinition { name: string label: string type: 'string' | 'number' | 'boolean' | 'select' | 'color' | 'dynamic-select' - defaultValue?: unknown + defaultValue?: JsonValue options?: Array<{ value: string; label: string }> dynamicSource?: string description?: string diff --git a/packages/index.json b/packages/index.json index c2d6d9634..cce34675a 100644 --- a/packages/index.json +++ b/packages/index.json @@ -1,19 +1,19 @@ { - "generatedAt": "2025-12-26T01:12:07.934Z", + "generatedAt": "2025-12-30T00:19:15.231Z", "packages": [ { "packageId": "admin_dialog", "name": "Admin Dialog", "version": "1.0.0", - "description": "Admin dialogs for user and settings management", + "description": "Admin dialog components", "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", - "dependencies": ["ui_dialogs"], + "dependencies": [], "exports": { - "scripts": ["user", "settings"], "components": [] - } + }, + "minLevel": 4 }, { "packageId": "arcade_lobby", @@ -26,7 +26,8 @@ "dependencies": [], "exports": { "components": [] - } + }, + "minLevel": 2 }, { "packageId": "codegen_studio", @@ -39,7 +40,8 @@ "dependencies": [], "exports": { "components": [] - } + }, + "minLevel": 5 }, { "packageId": "code_editor", @@ -51,51 +53,79 @@ "category": "editors", "dependencies": [], "exports": { - "scripts": ["json", "lua", "theme"], - "components": ["CodeEditor", "JsonEditor", "LuaEditor", "ThemeEditor"] - } + "scripts": [ + "json", + "lua", + "theme" + ], + "components": [ + "CodeEditor", + "JsonEditor", + "LuaEditor", + "ThemeEditor" + ] + }, + "minLevel": 5 }, { "packageId": "dashboard", "name": "Dashboard", "version": "1.0.0", - "description": "Dashboard components with stats and layouts", + "description": "Dashboard layouts, stat cards, and widgets", "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", "dependencies": [], "exports": { - "scripts": ["stats", "layout"], - "components": [] - } + "components": [ + "StatCard", + "DashboardGrid", + "Widget" + ], + "scripts": [ + "stats", + "layout" + ] + }, + "minLevel": 2 }, { "packageId": "data_table", "name": "Data Table", "version": "1.0.0", - "description": "Data table with columns, rows, and pagination", + "description": "Data table components", "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", "dependencies": [], "exports": { - "scripts": ["columns", "rows", "pagination"], "components": [] - } + }, + "minLevel": 1 }, { "packageId": "form_builder", "name": "Form Builder", "version": "1.0.0", - "description": "Form builder with field types and validation", + "description": "Form fields, validation, and submission handling", "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", "dependencies": [], "exports": { - "scripts": ["fields", "validate"], - "components": [] - } + "components": [ + "FormField", + "EmailField", + "PasswordField", + "NumberField", + "SearchBar" + ], + "scripts": [ + "fields", + "validate" + ] + }, + "minLevel": 1 }, { "packageId": "forum_forge", @@ -108,63 +138,71 @@ "dependencies": [], "exports": { "components": [] - } + }, + "minLevel": 2 }, { "packageId": "nav_menu", "name": "Navigation Menu", "version": "1.0.0", - "description": "Navigation sidebar and menu components", + "description": "Sidebar, navigation menus, and breadcrumbs", "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", - "dependencies": ["ui_permissions"], + "dependencies": [ + "ui_permissions" + ], "exports": { - "scripts": ["sidebar", "menu"], - "components": [] - } + "components": [ + "Sidebar", + "NavigationMenu", + "Breadcrumbs" + ], + "scripts": [ + "sidebar", + "menu" + ] + }, + "minLevel": 2 }, { "packageId": "notification_center", "name": "Notification Center", "version": "1.0.0", - "description": "Toast notifications and notification list", + "description": "Notification center components", "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", "dependencies": [], "exports": { - "scripts": ["toast", "list"], "components": [] - } + }, + "minLevel": 1 }, { - "packageId": "ui_auth", - "name": "Auth Components", + "packageId": "schema_editor", + "name": "Schema Editor", "version": "1.0.0", - "description": "Authentication gate and access denied views", + "description": "Database schema editor components", "icon": "static_content/icon.svg", "author": "MetaBuilder", - "category": "ui", - "dependencies": ["ui_permissions"], + "category": "editors", + "dependencies": [ + "form_builder" + ], "exports": { - "scripts": ["gate", "denied"], - "components": ["AuthGate", "AccessDenied"] - } - }, - { - "packageId": "ui_dialogs", - "name": "Dialog Components", - "version": "1.0.0", - "description": "Confirm and alert dialog components", - "icon": "static_content/icon.svg", - "author": "MetaBuilder", - "category": "ui", - "dependencies": [], - "exports": { - "scripts": ["confirm", "alert"], - "components": ["ConfirmDialog", "AlertDialog"] - } + "scripts": [ + "fields", + "tables", + "relations" + ], + "components": [ + "SchemaEditor", + "TableEditor", + "FieldEditor" + ] + }, + "minLevel": 5 }, { "packageId": "social_hub", @@ -207,21 +245,8 @@ "social_hub_feed_post_2_body", "social_hub_feed_post_2_badge" ] - } - }, - { - "packageId": "schema_editor", - "name": "Schema Editor", - "version": "1.0.0", - "description": "Database schema editor components", - "icon": "static_content/icon.svg", - "author": "MetaBuilder", - "category": "editors", - "dependencies": ["form_builder"], - "exports": { - "scripts": ["fields", "tables", "relations"], - "components": ["SchemaEditor", "TableEditor", "FieldEditor"] - } + }, + "minLevel": 2 }, { "packageId": "stream_cast", @@ -234,93 +259,54 @@ "dependencies": [], "exports": { "components": [] - } + }, + "minLevel": 2 }, { - "packageId": "user_manager", - "name": "User Manager", + "packageId": "ui_auth", + "name": "Auth UI", "version": "1.0.0", - "description": "User management components and actions", + "description": "Access denied, auth gate, and loading states", "icon": "static_content/icon.svg", "author": "MetaBuilder", - "category": "managers", - "dependencies": ["ui_permissions", "data_table"], + "category": "ui", + "dependencies": [ + "ui_permissions" + ], "exports": { - "scripts": ["list", "actions"], - "components": ["UserManagement", "UserList", "UserActions"] - } + "components": [ + "AccessDenied", + "AuthGate", + "PageLoader" + ], + "scripts": [ + "denied", + "gate" + ] + }, + "minLevel": 2 }, { - "packageId": "workflow_editor", - "name": "Workflow Editor", + "packageId": "ui_dialogs", + "name": "UI Dialogs", "version": "1.0.0", - "description": "Workflow editor and run status components", - "icon": "static_content/icon.svg", - "author": "MetaBuilder", - "category": "editors", - "dependencies": [], - "exports": { - "scripts": ["editor", "status", "run"], - "components": ["WorkflowEditor", "WorkflowRunCard", "WorkflowRunStatus"] - } - }, - { - "packageId": "ui_permissions", - "name": "UI Permissions", - "version": "1.0.0", - "description": "Shared permission utilities for page access control", + "description": "Confirmation, alert, and form dialogs", "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", "dependencies": [], "exports": { - "scripts": ["permissions"], - "components": [] - } - }, - { - "packageId": "ui_login", - "name": "Login Page", - "version": "1.0.0", - "description": "Login and registration page with form validation", - "icon": "static_content/icon.svg", - "author": "MetaBuilder", - "category": "ui", - "dependencies": ["ui_permissions"], - "exports": { - "pages": ["login"], - "scripts": ["login_ui", "login_validate"], - "components": [] - } - }, - { - "packageId": "ui_home", - "name": "Home Page", - "version": "1.0.0", - "description": "Level 1 home page with server status", - "icon": "static_content/icon.svg", - "author": "MetaBuilder", - "category": "ui", - "dependencies": ["ui_permissions"], - "exports": { - "pages": ["level1"], - "scripts": ["home_ui", "navigate"], - "components": [] - } - }, - { - "packageId": "ui_header", - "name": "App Header", - "version": "1.0.0", - "description": "Shared navigation header with user avatar and actions", - "icon": "static_content/icon.svg", - "author": "MetaBuilder", - "category": "ui", - "dependencies": ["ui_permissions"], - "exports": { - "components": ["AppHeader"], - "scripts": ["header"] - } + "components": [ + "ConfirmDialog", + "AlertDialog", + "FormDialog" + ], + "scripts": [ + "confirm", + "alert" + ] + }, + "minLevel": 1 }, { "packageId": "ui_footer", @@ -332,9 +318,60 @@ "category": "ui", "dependencies": [], "exports": { - "components": ["AppFooter"], - "scripts": ["footer"] - } + "components": [ + "AppFooter" + ], + "scripts": [ + "footer" + ], + "pages": [] + }, + "minLevel": 1 + }, + { + "packageId": "ui_header", + "name": "App Header", + "version": "1.0.0", + "description": "Shared navigation header with user avatar and actions", + "icon": "static_content/icon.svg", + "author": "MetaBuilder", + "category": "ui", + "dependencies": [ + "ui_permissions" + ], + "exports": { + "components": [ + "AppHeader" + ], + "scripts": [ + "header" + ], + "pages": [] + }, + "minLevel": 2 + }, + { + "packageId": "ui_home", + "name": "Home Page", + "version": "1.0.0", + "description": "Level 1 home page with server status", + "icon": "static_content/icon.svg", + "author": "MetaBuilder", + "category": "ui", + "dependencies": [ + "ui_permissions" + ], + "exports": { + "pages": [ + "level1" + ], + "scripts": [ + "home_ui", + "navigate" + ], + "components": [] + }, + "minLevel": 1 }, { "packageId": "ui_intro", @@ -346,9 +383,15 @@ "category": "ui", "dependencies": [], "exports": { - "components": ["IntroSection"], - "scripts": ["intro"] - } + "components": [ + "IntroSection" + ], + "scripts": [ + "intro" + ], + "pages": [] + }, + "minLevel": 1 }, { "packageId": "ui_level2", @@ -358,53 +401,248 @@ "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", - "dependencies": ["ui_permissions", "ui_header", "ui_intro"], + "dependencies": [ + "ui_permissions", + "ui_header", + "ui_intro" + ], "exports": { - "pages": ["level2"], - "scripts": ["layout", "profile", "comments"] - } + "pages": [ + "level2" + ], + "scripts": [ + "layout", + "profile", + "comments" + ], + "components": [] + }, + "minLevel": 2 }, { "packageId": "ui_level3", - "name": "Level 3 - Admin Panel", + "name": "Level 3 - Moderator Panel", "version": "1.0.0", - "description": "Admin panel for user and content management", + "description": "Moderator panel for content moderation", "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", - "dependencies": ["ui_permissions", "ui_header", "ui_intro"], + "dependencies": [ + "ui_permissions", + "ui_header", + "ui_intro" + ], "exports": { - "pages": ["level3"], - "scripts": ["layout", "users", "moderation"] - } + "pages": [ + "level3" + ], + "scripts": [ + "layout", + "users", + "moderation" + ], + "components": [] + }, + "minLevel": 3 }, { "packageId": "ui_level4", - "name": "Level 4 - Builder", + "name": "Level 4 - Admin Panel", "version": "1.0.0", - "description": "Application builder with schemas and workflows", + "description": "Admin panel for user and system management", "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", - "dependencies": ["ui_permissions", "ui_header", "ui_intro"], + "dependencies": [ + "ui_permissions", + "ui_header", + "ui_intro", + "user_manager", + "admin_dialog" + ], "exports": { - "pages": ["level4"], - "scripts": ["layout", "schemas", "workflows"] - } + "pages": [ + "level4" + ], + "scripts": [ + "layout", + "users", + "settings" + ], + "components": [] + }, + "minLevel": 4 }, { "packageId": "ui_level5", - "name": "Level 5 - Super God", + "name": "Level 5 - God Panel", "version": "1.0.0", - "description": "Super god panel for tenant management", + "description": "God panel for application building, schemas, and workflows", "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", - "dependencies": ["ui_permissions", "ui_header", "ui_intro"], + "dependencies": [ + "ui_permissions", + "ui_header", + "ui_intro", + "schema_editor", + "workflow_editor" + ], "exports": { - "pages": ["level5"], - "scripts": ["layout", "tenants", "transfer"] + "pages": [ + "level5" + ], + "scripts": [ + "layout", + "schemas", + "workflows" + ], + "components": [] + }, + "minLevel": 5 + }, + { + "packageId": "ui_level6", + "name": "Level 6 - Supergod Panel", + "version": "1.0.0", + "description": "Supergod panel for tenant management and system administration", + "icon": "static_content/icon.svg", + "author": "MetaBuilder", + "category": "ui", + "minLevel": 6, + "dependencies": [ + "ui_permissions", + "ui_header", + "ui_intro" + ], + "exports": { + "pages": [ + "level6" + ], + "scripts": [ + "layout", + "tenants", + "transfer", + "system" + ], + "components": [] } + }, + { + "packageId": "ui_login", + "name": "Login Page", + "version": "1.0.0", + "description": "Login and registration page with form validation", + "icon": "static_content/icon.svg", + "author": "MetaBuilder", + "category": "ui", + "dependencies": [ + "ui_permissions" + ], + "exports": { + "pages": [ + "login" + ], + "scripts": [ + "login_ui", + "login_actions" + ], + "components": [] + }, + "minLevel": 1 + }, + { + "packageId": "ui_pages", + "name": "UI Pages Bundle", + "version": "2.0.0", + "description": "Meta-package that bundles all UI page packages", + "icon": "static_content/icon.svg", + "author": "MetaBuilder", + "category": "ui", + "dependencies": [ + "ui_permissions", + "ui_header", + "ui_footer", + "ui_intro", + "ui_login", + "ui_home", + "ui_level2", + "ui_level3", + "ui_level4", + "ui_level5", + "ui_level6" + ], + "exports": { + "pages": [], + "scripts": [], + "components": [] + }, + "minLevel": 1 + }, + { + "packageId": "ui_permissions", + "name": "UI Permissions", + "version": "1.0.0", + "description": "Shared permission utilities for page access control", + "icon": "static_content/icon.svg", + "author": "MetaBuilder", + "category": "ui", + "dependencies": [], + "exports": { + "scripts": [ + "permissions" + ], + "components": [] + }, + "minLevel": 1 + }, + { + "packageId": "user_manager", + "name": "User Manager", + "version": "1.0.0", + "description": "User management components and actions", + "icon": "static_content/icon.svg", + "author": "MetaBuilder", + "category": "managers", + "dependencies": [ + "ui_permissions", + "data_table" + ], + "exports": { + "scripts": [ + "list", + "actions" + ], + "components": [ + "UserManagement", + "UserList", + "UserActions" + ] + }, + "minLevel": 4 + }, + { + "packageId": "workflow_editor", + "name": "Workflow Editor", + "version": "1.0.0", + "description": "Workflow editor and run status components", + "icon": "static_content/icon.svg", + "author": "MetaBuilder", + "category": "editors", + "dependencies": [], + "exports": { + "scripts": [ + "editor", + "status", + "run" + ], + "components": [ + "WorkflowEditor", + "WorkflowRunCard", + "WorkflowRunStatus" + ] + }, + "minLevel": 5 } ] -} +} \ No newline at end of file diff --git a/packages/social_hub/seed/scripts/lua/permissions.lua b/packages/social_hub/seed/scripts/lua/permissions.lua index fd3545ee8..f1582e31b 100644 --- a/packages/social_hub/seed/scripts/lua/permissions.lua +++ b/packages/social_hub/seed/scripts/lua/permissions.lua @@ -1,11 +1,11 @@ local Permissions = {} function Permissions.can_post(user) - return user and (user.role == "user" or user.role == "admin" or user.role == "god") + return user and (user.role == "user" or user.role == "moderator" or user.role == "admin" or user.role == "god" or user.role == "supergod") end function Permissions.can_moderate(user) - return user and (user.role == "admin" or user.role == "god" or user.role == "supergod") + return user and (user.role == "moderator" or user.role == "admin" or user.role == "god" or user.role == "supergod") end return Permissions diff --git a/packages/stream_cast/seed/scripts/lua/permissions.lua b/packages/stream_cast/seed/scripts/lua/permissions.lua index e36330610..6e198d573 100644 --- a/packages/stream_cast/seed/scripts/lua/permissions.lua +++ b/packages/stream_cast/seed/scripts/lua/permissions.lua @@ -2,12 +2,12 @@ local M = {} function M.can_publish(user) local role = user.role or "public" - return role == "admin" or role == "god" or role == "supergod" + return role == "moderator" or role == "admin" or role == "god" or role == "supergod" end function M.can_moderate(user) local role = user.role or "public" - return role == "admin" or role == "god" or role == "supergod" + return role == "moderator" or role == "admin" or role == "god" or role == "supergod" end return M diff --git a/packages/ui_level3/seed/metadata.json b/packages/ui_level3/seed/metadata.json index 9abae0f9f..6d7d2c912 100644 --- a/packages/ui_level3/seed/metadata.json +++ b/packages/ui_level3/seed/metadata.json @@ -1,8 +1,8 @@ { "packageId": "ui_level3", - "name": "Level 3 - Admin Panel", + "name": "Level 3 - Moderator Panel", "version": "1.0.0", - "description": "Admin panel for user and content management", + "description": "Moderator panel for content moderation", "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", diff --git a/packages/ui_level4/seed/metadata.json b/packages/ui_level4/seed/metadata.json index b47556cd9..5c2a3fa26 100644 --- a/packages/ui_level4/seed/metadata.json +++ b/packages/ui_level4/seed/metadata.json @@ -1,15 +1,17 @@ { "packageId": "ui_level4", - "name": "Level 4 - Builder", + "name": "Level 4 - Admin Panel", "version": "1.0.0", - "description": "Application builder with schemas and workflows", + "description": "Admin panel for user and system management", "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", "dependencies": [ "ui_permissions", "ui_header", - "ui_intro" + "ui_intro", + "user_manager", + "admin_dialog" ], "exports": { "pages": [ @@ -17,8 +19,8 @@ ], "scripts": [ "layout", - "schemas", - "workflows" + "users", + "settings" ], "components": [] }, diff --git a/packages/ui_level5/seed/metadata.json b/packages/ui_level5/seed/metadata.json index f8f464aff..258f84c0b 100644 --- a/packages/ui_level5/seed/metadata.json +++ b/packages/ui_level5/seed/metadata.json @@ -1,15 +1,17 @@ { "packageId": "ui_level5", - "name": "Level 5 - Super God", + "name": "Level 5 - God Panel", "version": "1.0.0", - "description": "Super god panel for tenant management", + "description": "God panel for application building, schemas, and workflows", "icon": "static_content/icon.svg", "author": "MetaBuilder", "category": "ui", "dependencies": [ "ui_permissions", "ui_header", - "ui_intro" + "ui_intro", + "schema_editor", + "workflow_editor" ], "exports": { "pages": [ @@ -17,8 +19,8 @@ ], "scripts": [ "layout", - "tenants", - "transfer" + "schemas", + "workflows" ], "components": [] }, diff --git a/packages/ui_level6/seed/components.json b/packages/ui_level6/seed/components.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/packages/ui_level6/seed/components.json @@ -0,0 +1 @@ +[] diff --git a/packages/ui_level6/seed/metadata.json b/packages/ui_level6/seed/metadata.json new file mode 100644 index 000000000..291e44f32 --- /dev/null +++ b/packages/ui_level6/seed/metadata.json @@ -0,0 +1,16 @@ +{ + "packageId": "ui_level6", + "name": "Level 6 - Supergod Panel", + "version": "1.0.0", + "description": "Supergod panel for tenant management and system administration", + "icon": "static_content/icon.svg", + "author": "MetaBuilder", + "category": "ui", + "minLevel": 6, + "dependencies": ["ui_permissions", "ui_header", "ui_intro"], + "exports": { + "pages": ["level6"], + "scripts": ["layout", "tenants", "transfer", "system"], + "components": [] + } +} diff --git a/packages/ui_level6/seed/scripts/init.lua b/packages/ui_level6/seed/scripts/init.lua new file mode 100644 index 000000000..61d2a7e44 --- /dev/null +++ b/packages/ui_level6/seed/scripts/init.lua @@ -0,0 +1,15 @@ +-- Level 6 (Supergod) package initialization +local levels = require("ui_permissions.levels") + +local M = {} + +M.REQUIRED_LEVEL = levels.SUPERGOD + +function M.init(context) + if context.user.level < M.REQUIRED_LEVEL then + return { allowed = false, redirect = "/access-denied" } + end + return { allowed = true } +end + +return M diff --git a/packages/ui_level6/seed/scripts/layout.lua b/packages/ui_level6/seed/scripts/layout.lua new file mode 100644 index 000000000..20225b808 --- /dev/null +++ b/packages/ui_level6/seed/scripts/layout.lua @@ -0,0 +1,31 @@ +-- Level 6 Supergod layout components +local M = {} + +function M.supergod_sidebar(items) + return { + type = "supergod_sidebar", + width = "320px", + theme = "system", + items = items or {} + } +end + +function M.supergod_toolbar(actions) + return { + type = "supergod_toolbar", + actions = actions or {}, + showAllTenants = true, + showSystemMetrics = true + } +end + +function M.supergod_content(children) + return { + type = "supergod_content", + fullWidth = true, + multiTenant = true, + children = children or {} + } +end + +return M diff --git a/packages/ui_level6/seed/scripts/manifest.json b/packages/ui_level6/seed/scripts/manifest.json new file mode 100644 index 000000000..a25e748bf --- /dev/null +++ b/packages/ui_level6/seed/scripts/manifest.json @@ -0,0 +1,9 @@ +{ + "scripts": [ + { "name": "init", "path": "init.lua", "description": "Level 6 initialization" }, + { "name": "layout", "path": "layout.lua", "description": "Supergod layout components" }, + { "name": "tenants", "path": "tenants.lua", "description": "Tenant management" }, + { "name": "transfer", "path": "transfer.lua", "description": "Power transfer utilities" }, + { "name": "system", "path": "system.lua", "description": "System administration" } + ] +} diff --git a/packages/ui_level6/seed/scripts/system.lua b/packages/ui_level6/seed/scripts/system.lua new file mode 100644 index 000000000..fb5bb6c9f --- /dev/null +++ b/packages/ui_level6/seed/scripts/system.lua @@ -0,0 +1,47 @@ +-- System administration for supergod +local M = {} + +function M.system_stats() + return { + type = "system_stats", + metrics = { + { id = "tenants", label = "Total Tenants" }, + { id = "users", label = "Total Users" }, + { id = "storage", label = "Storage Used" }, + { id = "requests", label = "API Requests (24h)" } + } + } +end + +function M.system_health() + return { + type = "system_health", + services = { + { id = "database", label = "Database" }, + { id = "cache", label = "Cache" }, + { id = "queue", label = "Job Queue" }, + { id = "storage", label = "Object Storage" } + } + } +end + +function M.system_logs() + return { + type = "system_logs", + filters = { + { id = "level", options = { "error", "warn", "info", "debug" } }, + { id = "service", options = { "api", "worker", "scheduler" } }, + { id = "tenant", type = "tenant_select" } + } + } +end + +function M.maintenance_mode(enabled) + return { + type = "maintenance_toggle", + enabled = enabled, + warningMessage = "Enabling maintenance mode will prevent all non-supergod users from accessing the system." + } +end + +return M diff --git a/packages/ui_level6/seed/scripts/tenants.lua b/packages/ui_level6/seed/scripts/tenants.lua new file mode 100644 index 000000000..ade0a1aa0 --- /dev/null +++ b/packages/ui_level6/seed/scripts/tenants.lua @@ -0,0 +1,40 @@ +-- Tenant management for supergod +local M = {} + +function M.tenant_list() + return { + type = "tenant_list", + columns = { + { id = "name", label = "Tenant Name" }, + { id = "owner", label = "Owner" }, + { id = "users", label = "Users", type = "number" }, + { id = "status", label = "Status", type = "badge" }, + { id = "actions", label = "", type = "actions" } + } + } +end + +function M.tenant_card(tenant) + return { + type = "tenant_card", + id = tenant.id, + name = tenant.name, + owner = tenant.owner, + userCount = tenant.userCount, + status = tenant.status + } +end + +function M.create_tenant_form() + return { + type = "form", + id = "create_tenant", + fields = { + { id = "name", type = "text", label = "Tenant Name", required = true }, + { id = "owner", type = "user_select", label = "Owner", required = true }, + { id = "plan", type = "select", label = "Plan", options = { "free", "pro", "enterprise" } } + } + } +end + +return M diff --git a/packages/ui_level6/seed/scripts/transfer.lua b/packages/ui_level6/seed/scripts/transfer.lua new file mode 100644 index 000000000..f24e4e163 --- /dev/null +++ b/packages/ui_level6/seed/scripts/transfer.lua @@ -0,0 +1,26 @@ +-- Power transfer utilities for supergod +local M = {} + +function M.transfer_form(from_user, to_user) + return { + type = "power_transfer_form", + fromUser = from_user, + toUser = to_user, + confirmationRequired = true, + warningMessage = "This action transfers all supergod privileges and cannot be undone." + } +end + +function M.transfer_history() + return { + type = "transfer_history", + columns = { + { id = "date", label = "Date", type = "date" }, + { id = "from", label = "From User" }, + { id = "to", label = "To User" }, + { id = "reason", label = "Reason" } + } + } +end + +return M diff --git a/packages/ui_level6/static_content/icon.svg b/packages/ui_level6/static_content/icon.svg new file mode 100644 index 000000000..3f4ac27a3 --- /dev/null +++ b/packages/ui_level6/static_content/icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/packages/ui_pages/seed/metadata.json b/packages/ui_pages/seed/metadata.json index 371235075..26be71a02 100644 --- a/packages/ui_pages/seed/metadata.json +++ b/packages/ui_pages/seed/metadata.json @@ -16,7 +16,8 @@ "ui_level2", "ui_level3", "ui_level4", - "ui_level5" + "ui_level5", + "ui_level6" ], "exports": { "pages": [], diff --git a/packages/ui_permissions/seed/scripts/check.lua b/packages/ui_permissions/seed/scripts/check.lua index 552961a65..e1ecd85e9 100644 --- a/packages/ui_permissions/seed/scripts/check.lua +++ b/packages/ui_permissions/seed/scripts/check.lua @@ -5,6 +5,7 @@ local M = {} local ROLE_MAP = { public = LEVELS.PUBLIC, user = LEVELS.USER, + moderator = LEVELS.MODERATOR, admin = LEVELS.ADMIN, god = LEVELS.GOD, supergod = LEVELS.SUPERGOD @@ -19,4 +20,12 @@ function M.can_access(user, required_level) return M.get_level(user) >= required_level end +function M.is_moderator_or_above(user) + return M.get_level(user) >= LEVELS.MODERATOR +end + +function M.is_admin_or_above(user) + return M.get_level(user) >= LEVELS.ADMIN +end + return M