mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
docs: nextjs,frontends,prisma (6 files)
This commit is contained in:
@@ -18,7 +18,7 @@ namespace lua_script {
|
||||
*/
|
||||
inline Result<LuaScript> get(InMemoryStore& store, const std::string& id) {
|
||||
if (id.empty()) {
|
||||
return Error::validationError("Script ID cannot be empty");
|
||||
return Error::validationError("Lua script ID cannot be empty");
|
||||
}
|
||||
|
||||
auto it = store.lua_scripts.find(id);
|
||||
|
||||
@@ -35,6 +35,7 @@ The runtime-specific paragraph is drawn from the `runtime` value, and the CLI st
|
||||
- **Experience**: A Material UI-powered scaffold designer that bundles the same payload used by the API and streams the ZIP for download.
|
||||
- **Feedback**: Inline alerts surface success or failure so teams can iteratively tune briefs before sharing the starter kit with collaborators.
|
||||
- **Preview**: A manifest panel summarizes the generated values (runtime, tone, package, timestamp) after each export.
|
||||
- **Bundle contents**: The UI also renders the file list that will land inside the archive so creators can make last-second adjustments.
|
||||
|
||||
## Development tooling
|
||||
|
||||
|
||||
@@ -93,6 +93,21 @@ export default function CodegenStudioClient() {
|
||||
}
|
||||
}, [form.runtime])
|
||||
|
||||
const previewFiles = useMemo(() => {
|
||||
const root = form.projectName
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/[^a-z0-9_-]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '') || 'metabuilder-starter'
|
||||
return [
|
||||
`${root}/README.md`,
|
||||
`${root}/package.json`,
|
||||
`${root}/src/app/page.tsx`,
|
||||
`${root}/cli/main.cpp`,
|
||||
`${root}/spec.json`,
|
||||
]
|
||||
}, [form.projectName])
|
||||
|
||||
const handleChange = (key: keyof FormState) => (event: ChangeEvent<HTMLInputElement>) => {
|
||||
setForm((prev) => ({ ...prev, [key]: event.target.value }))
|
||||
}
|
||||
@@ -209,6 +224,14 @@ export default function CodegenStudioClient() {
|
||||
</Stack>
|
||||
</Paper>
|
||||
)}
|
||||
<Stack spacing={0.5}>
|
||||
<Typography variant="subtitle2">Bundle contents</Typography>
|
||||
{previewFiles.map((entry) => (
|
||||
<Typography key={entry} variant="body2" color="text.secondary">
|
||||
• {entry}
|
||||
</Typography>
|
||||
))}
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Container>
|
||||
|
||||
255
frontends/nextjs/src/components/LuaBlocksEditor.module.scss
Normal file
255
frontends/nextjs/src/components/LuaBlocksEditor.module.scss
Normal file
@@ -0,0 +1,255 @@
|
||||
@use '../styles/variables' as *;
|
||||
|
||||
.root {
|
||||
--block-basics: #f59e0b;
|
||||
--block-basics-dark: #d97706;
|
||||
--block-basics-soft: #fff6df;
|
||||
--block-basics-border: #fbd38d;
|
||||
|
||||
--block-logic: #0ea5e9;
|
||||
--block-logic-dark: #0284c7;
|
||||
--block-logic-soft: #e0f2fe;
|
||||
--block-logic-border: #bae6fd;
|
||||
|
||||
--block-loops: #22c55e;
|
||||
--block-loops-dark: #16a34a;
|
||||
--block-loops-soft: #dcfce7;
|
||||
--block-loops-border: #bbf7d0;
|
||||
|
||||
--block-data: #14b8a6;
|
||||
--block-data-dark: #0d9488;
|
||||
--block-data-soft: #ccfbf1;
|
||||
--block-data-border: #99f6e4;
|
||||
|
||||
--block-functions: #ef4444;
|
||||
--block-functions-dark: #dc2626;
|
||||
--block-functions-soft: #fee2e2;
|
||||
--block-functions-border: #fecaca;
|
||||
}
|
||||
|
||||
.workspaceSurface {
|
||||
border-radius: $radius-xl;
|
||||
padding: $space-6;
|
||||
background: linear-gradient(135deg, #f8fafc, #ffffff);
|
||||
border: 1px solid $color-neutral-200;
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
|
||||
min-height: 240px;
|
||||
}
|
||||
|
||||
.blockStack {
|
||||
display: grid;
|
||||
gap: $space-4;
|
||||
}
|
||||
|
||||
.blockCard {
|
||||
--block-accent: var(--block-basics);
|
||||
--block-accent-dark: var(--block-basics-dark);
|
||||
--block-bg: var(--block-basics-soft);
|
||||
--block-border: var(--block-basics-border);
|
||||
|
||||
border-radius: $radius-xl;
|
||||
background: var(--block-bg);
|
||||
border: 1px solid var(--block-border);
|
||||
box-shadow: $shadow-sm;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.blockCard[data-category='Basics'] {
|
||||
--block-accent: var(--block-basics);
|
||||
--block-accent-dark: var(--block-basics-dark);
|
||||
--block-bg: var(--block-basics-soft);
|
||||
--block-border: var(--block-basics-border);
|
||||
}
|
||||
|
||||
.blockCard[data-category='Logic'] {
|
||||
--block-accent: var(--block-logic);
|
||||
--block-accent-dark: var(--block-logic-dark);
|
||||
--block-bg: var(--block-logic-soft);
|
||||
--block-border: var(--block-logic-border);
|
||||
}
|
||||
|
||||
.blockCard[data-category='Loops'] {
|
||||
--block-accent: var(--block-loops);
|
||||
--block-accent-dark: var(--block-loops-dark);
|
||||
--block-bg: var(--block-loops-soft);
|
||||
--block-border: var(--block-loops-border);
|
||||
}
|
||||
|
||||
.blockCard[data-category='Data'] {
|
||||
--block-accent: var(--block-data);
|
||||
--block-accent-dark: var(--block-data-dark);
|
||||
--block-bg: var(--block-data-soft);
|
||||
--block-border: var(--block-data-border);
|
||||
}
|
||||
|
||||
.blockCard[data-category='Functions'] {
|
||||
--block-accent: var(--block-functions);
|
||||
--block-accent-dark: var(--block-functions-dark);
|
||||
--block-bg: var(--block-functions-soft);
|
||||
--block-border: var(--block-functions-border);
|
||||
}
|
||||
|
||||
.blockHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: $space-3;
|
||||
padding: $space-3 $space-4;
|
||||
background: linear-gradient(135deg, var(--block-accent), var(--block-accent-dark));
|
||||
color: #ffffff;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.blockTitle {
|
||||
font-family: var(--font-family-heading);
|
||||
font-weight: $font-weight-semibold;
|
||||
font-size: $font-size-base;
|
||||
}
|
||||
|
||||
.blockActions {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: $space-1;
|
||||
}
|
||||
|
||||
.blockFields {
|
||||
display: grid;
|
||||
gap: $space-3;
|
||||
padding: $space-4;
|
||||
}
|
||||
|
||||
.blockFieldLabel {
|
||||
display: block;
|
||||
font-size: $font-size-xs;
|
||||
font-weight: $font-weight-semibold;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: $color-neutral-700;
|
||||
margin-bottom: $space-2;
|
||||
}
|
||||
|
||||
.blockSection {
|
||||
border-radius: $radius-lg;
|
||||
border: 1px dashed $color-neutral-300;
|
||||
background: rgba(255, 255, 255, 0.75);
|
||||
padding: $space-3;
|
||||
margin: $space-3 $space-4 $space-4;
|
||||
}
|
||||
|
||||
.blockSectionHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: $space-3;
|
||||
margin-bottom: $space-3;
|
||||
}
|
||||
|
||||
.blockSectionTitle {
|
||||
font-weight: $font-weight-semibold;
|
||||
color: $color-neutral-800;
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
|
||||
.blockSectionBody {
|
||||
display: grid;
|
||||
gap: $space-3;
|
||||
}
|
||||
|
||||
.blockEmpty {
|
||||
text-align: center;
|
||||
padding: $space-4;
|
||||
font-size: $font-size-sm;
|
||||
color: $color-neutral-600;
|
||||
border-radius: $radius-md;
|
||||
border: 1px dashed $color-neutral-300;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.libraryBlock {
|
||||
border-radius: $radius-lg;
|
||||
padding: $space-3;
|
||||
border: 1px solid $color-neutral-200;
|
||||
background: #ffffff;
|
||||
cursor: pointer;
|
||||
transition: transform $transition-fast, box-shadow $transition-fast, border-color $transition-fast;
|
||||
box-shadow: $shadow-sm;
|
||||
}
|
||||
|
||||
.libraryBlock:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: $shadow-md;
|
||||
border-color: $color-neutral-300;
|
||||
}
|
||||
|
||||
.libraryBlockTitle {
|
||||
font-weight: $font-weight-semibold;
|
||||
color: $color-neutral-900;
|
||||
}
|
||||
|
||||
.libraryBlockDesc {
|
||||
font-size: $font-size-xs;
|
||||
color: $color-neutral-600;
|
||||
}
|
||||
|
||||
.libraryBlock[data-category='Basics'] {
|
||||
border-left: 4px solid var(--block-basics);
|
||||
}
|
||||
|
||||
.libraryBlock[data-category='Logic'] {
|
||||
border-left: 4px solid var(--block-logic);
|
||||
}
|
||||
|
||||
.libraryBlock[data-category='Loops'] {
|
||||
border-left: 4px solid var(--block-loops);
|
||||
}
|
||||
|
||||
.libraryBlock[data-category='Data'] {
|
||||
border-left: 4px solid var(--block-data);
|
||||
}
|
||||
|
||||
.libraryBlock[data-category='Functions'] {
|
||||
border-left: 4px solid var(--block-functions);
|
||||
}
|
||||
|
||||
.menuSwatch {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(15, 23, 42, 0.2);
|
||||
background: var(--block-basics);
|
||||
}
|
||||
|
||||
.menuSwatch[data-category='Basics'] {
|
||||
background: var(--block-basics);
|
||||
}
|
||||
|
||||
.menuSwatch[data-category='Logic'] {
|
||||
background: var(--block-logic);
|
||||
}
|
||||
|
||||
.menuSwatch[data-category='Loops'] {
|
||||
background: var(--block-loops);
|
||||
}
|
||||
|
||||
.menuSwatch[data-category='Data'] {
|
||||
background: var(--block-data);
|
||||
}
|
||||
|
||||
.menuSwatch[data-category='Functions'] {
|
||||
background: var(--block-functions);
|
||||
}
|
||||
|
||||
.codePreview {
|
||||
border-radius: $radius-lg;
|
||||
background: #0f172a;
|
||||
color: #e2e8f0;
|
||||
padding: $space-4;
|
||||
font-family: var(--font-family-mono);
|
||||
font-size: $font-size-sm;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.codePreview pre {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
@@ -99,6 +99,9 @@ export interface LuaScript {
|
||||
code: string
|
||||
parameters: Array<{ name: string; type: string }>
|
||||
returnType?: string
|
||||
isSandboxed?: boolean
|
||||
allowedGlobals?: string[]
|
||||
timeoutMs?: number
|
||||
}
|
||||
|
||||
export interface PageConfig {
|
||||
|
||||
@@ -61,6 +61,9 @@ model LuaScript {
|
||||
code String
|
||||
parameters String
|
||||
returnType String?
|
||||
isSandboxed Boolean @default(true)
|
||||
allowedGlobals String @default("[]")
|
||||
timeoutMs Int @default(5000)
|
||||
}
|
||||
|
||||
model PageConfig {
|
||||
|
||||
Reference in New Issue
Block a user