diff --git a/frontend/autometabuilder/app/favicon.ico b/frontend/app/favicon.ico similarity index 100% rename from frontend/autometabuilder/app/favicon.ico rename to frontend/app/favicon.ico diff --git a/frontend/autometabuilder/app/layout.tsx b/frontend/app/layout.tsx similarity index 100% rename from frontend/autometabuilder/app/layout.tsx rename to frontend/app/layout.tsx diff --git a/frontend/autometabuilder/app/page.tsx b/frontend/app/page.tsx similarity index 100% rename from frontend/autometabuilder/app/page.tsx rename to frontend/app/page.tsx diff --git a/frontend/autometabuilder/components/layout/PageLayout.tsx b/frontend/autometabuilder/components/layout/PageLayout.tsx deleted file mode 100644 index ecc5b53..0000000 --- a/frontend/autometabuilder/components/layout/PageLayout.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { ReactNode } from "react"; -import { Box, Toolbar, Typography } from "@mui/material"; -import { NavigationItem } from "../../lib/types"; -import Sidebar from "./Sidebar"; - -type PageLayoutProps = { - navItems: NavigationItem[]; - section: string; - onSectionChange: (section: string) => void; - t: (key: string, fallback?: string) => string; - children: ReactNode; -}; - -export default function PageLayout({ navItems, section, onSectionChange, t, children }: PageLayoutProps) { - return ( - - - - - - - {t("ui.app.title", "AutoMetabuilder Dashboard")} - - - {t("ui.dashboard.subtitle", "Control the bot and monitor system activity")} - - - - {children} - - - ); -} diff --git a/frontend/autometabuilder/components/layout/Sidebar.tsx b/frontend/autometabuilder/components/layout/Sidebar.tsx deleted file mode 100644 index a588d41..0000000 --- a/frontend/autometabuilder/components/layout/Sidebar.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { Box, Divider, Drawer, List, ListItemButton, ListItemText, Typography } from "@mui/material"; -import { NavigationItem } from "../../lib/types"; - -type SidebarProps = { - items: NavigationItem[]; - selected: string; - onSelect: (section: string) => void; - t: (key: string, fallback?: string) => string; -}; - -export default function Sidebar({ items, selected, onSelect, t }: SidebarProps) { - return ( - - - - - {t("ui.app.name", "AutoMetabuilder")} - - - - - {items.map((item) => ( - onSelect(item.section)} - data-section={item.section} - sx={{ - color: selected === item.section ? "#fff" : "rgba(226,232,240,0.8)", - }} - > - - - ))} - - - - ); -} diff --git a/frontend/autometabuilder/components/sections/DashboardSection.tsx b/frontend/autometabuilder/components/sections/DashboardSection.tsx deleted file mode 100644 index 5208ae8..0000000 --- a/frontend/autometabuilder/components/sections/DashboardSection.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import { useState } from "react"; -import { - Box, - Button, - Checkbox, - FormControl, - FormControlLabel, - Paper, - Radio, - RadioGroup, - Stack, - TextField, - Typography, -} from "@mui/material"; -import { UIStatus } from "../../lib/types"; -import { emitWebhook } from "../../hooks/useWebhook"; - -type DashboardSectionProps = { - status: UIStatus; - logs: string; - onRun: (payload: { mode?: string; iterations?: number; yolo?: boolean; stop_at_mvp?: boolean }) => Promise; - t: (key: string, fallback?: string) => string; -}; - -export default function DashboardSection({ status, logs, onRun, t }: DashboardSectionProps) { - const [mode, setMode] = useState("once"); - const [iterations, setIterations] = useState(1); - const [stopAtMvp, setStopAtMvp] = useState(false); - const [feedback, setFeedback] = useState(""); - - const handleRun = async () => { - const isYolo = mode === "yolo"; - setFeedback(t("ui.dashboard.status.bot_label", "Bot Status") + " — submitting"); - try { - await onRun({ mode, iterations, yolo: isYolo, stop_at_mvp: stopAtMvp }); - setFeedback(t("ui.dashboard.start_bot", "Start Bot") + " " + t("ui.dashboard.status.running", "Running")); - emitWebhook("botRunComplete", { mode, iterations }); - } catch (error) { - console.error(error); - setFeedback(t("ui.dashboard.status.idle", "Idle")); - } - }; - - return ( - - - {t("ui.dashboard.title", "Dashboard")} - - - {t("ui.dashboard.subtitle", "Control the bot and monitor system activity")} - - - - - {t("ui.dashboard.bot_control", "Bot Control")} - - - setMode(event.target.value)} name="run-mode"> - {["once", "iterations", "yolo"].map((value) => ( - } - label={t(`ui.dashboard.run.${value}.title`, value === "iterations" ? "Repeat" : value.charAt(0).toUpperCase() + value.slice(1))} - /> - ))} - - - {mode === "iterations" && ( - setIterations(Number(event.target.value) || 1)} - sx={{ mt: 1, width: 140 }} - /> - )} - setStopAtMvp(event.target.checked)} />} - label={t("ui.dashboard.stop_mvp.title", "Stop at MVP")} - sx={{ mt: 1 }} - /> - - {t("ui.dashboard.start_bot", "Start Bot")} - - - {status.is_running ? t("ui.dashboard.status.running", "Running") : t("ui.dashboard.status.idle", "Idle")} • - {" "} - {status.mvp_reached ? t("ui.dashboard.status.mvp_reached", "Reached") : t("ui.dashboard.status.mvp_progress", "In Progress")} - - - {feedback} - - - - - {t("ui.dashboard.logs.title", "Recent Logs")} - - - {logs.slice(-1200) || t("ui.dashboard.status.idle", "Idle")} - - - - - ); -} diff --git a/frontend/autometabuilder/components/sections/PromptSection.tsx b/frontend/autometabuilder/components/sections/PromptSection.tsx deleted file mode 100644 index 1622267..0000000 --- a/frontend/autometabuilder/components/sections/PromptSection.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { useEffect, useState } from "react"; -import { Button, Paper, Stack, TextField, Typography } from "@mui/material"; - -type PromptSectionProps = { - content: string; - onSave: (content: string) => Promise; - t: (key: string, fallback?: string) => string; -}; - -export default function PromptSection({ content, onSave, t }: PromptSectionProps) { - const [draft, setDraft] = useState(content); - const [message, setMessage] = useState(""); - - useEffect(() => { - setDraft(content); - }, [content]); - - const handleSave = async () => { - await onSave(draft); - setMessage(t("ui.prompt.save", "Save Prompt")); - setTimeout(() => setMessage(""), 2000); - }; - - return ( - - - {t("ui.prompt.title", "Prompt Builder")} - - - {t("ui.prompt.subtitle", "Shape how the assistant thinks, speaks, and decides")} - - setDraft(event.target.value)} - fullWidth - InputProps={{ - sx: { - backgroundColor: "#030712", - borderRadius: 2, - color: "white", - fontFamily: "JetBrains Mono, monospace", - }, - }} - /> - - - {t("ui.prompt.save", "Save Prompt")} - - - {message} - - - - ); -} diff --git a/frontend/autometabuilder/components/sections/SettingsSection.tsx b/frontend/autometabuilder/components/sections/SettingsSection.tsx deleted file mode 100644 index 5ce2a12..0000000 --- a/frontend/autometabuilder/components/sections/SettingsSection.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import { useEffect, useState } from "react"; -import { Button, Paper, Stack, TextField, Typography } from "@mui/material"; - -type SettingsSectionProps = { - envVars: Record; - onSave: (values: Record) => Promise; - t: (key: string, fallback?: string) => string; -}; - -export default function SettingsSection({ envVars, onSave, t }: SettingsSectionProps) { - const [values, setValues] = useState>(envVars); - const [newKey, setNewKey] = useState(""); - const [newValue, setNewValue] = useState(""); - const [message, setMessage] = useState(""); - - useEffect(() => { - setValues(envVars); - }, [envVars]); - - const updateField = (key: string, next: string) => { - setValues((prev) => ({ ...prev, [key]: next })); - }; - - const handleSave = async () => { - await onSave(values); - setMessage(t("ui.settings.save_all", "Save All Settings")); - setTimeout(() => setMessage(""), 2000); - }; - - const handleAdd = () => { - if (!newKey.trim()) return; - updateField(newKey.trim(), newValue); - setNewKey(""); - setNewValue(""); - }; - - return ( - - - {t("ui.settings.title", "Settings")} - - - {t("ui.settings.subtitle", "Configure services, security, and environment preferences")} - - - {Object.entries(values).map(([key, value]) => ( - updateField(key, event.target.value)} - InputProps={{ - sx: { - backgroundColor: "#030712", - borderRadius: 1, - color: "white", - }, - }} - /> - ))} - - - setNewKey(event.target.value)} - fullWidth - /> - setNewValue(event.target.value)} - fullWidth - /> - - {t("ui.actions.add", "Add")} - - - - - {t("ui.settings.save_all", "Save All Settings")} - - - {message} - - - - ); -} diff --git a/frontend/autometabuilder/components/sections/TranslationsSection.tsx b/frontend/autometabuilder/components/sections/TranslationsSection.tsx deleted file mode 100644 index a91c8d9..0000000 --- a/frontend/autometabuilder/components/sections/TranslationsSection.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import { FormEvent, useEffect, useState } from "react"; -import { - Button, - Chip, - Paper, - Stack, - TextField, - Typography, -} from "@mui/material"; -import { - createTranslation, - deleteTranslation, - fetchTranslation, - updateTranslation, -} from "../../lib/api"; - -type TranslationsSectionProps = { - languages: Record; - onRefresh: () => void; - t: (key: string, fallback?: string) => string; -}; - -export default function TranslationsSection({ languages, onRefresh, t }: TranslationsSectionProps) { - const [selected, setSelected] = useState(null); - const [editorValue, setEditorValue] = useState("{}"); - const [message, setMessage] = useState(""); - const [error, setError] = useState(""); - const [newLang, setNewLang] = useState(""); - - const loadContent = async (lang: string) => { - setError(""); - const data = await fetchTranslation(lang); - setEditorValue(JSON.stringify(data.content, null, 2)); - }; - - /* eslint-disable react-hooks/set-state-in-effect */ - useEffect(() => { - if (!selected && Object.keys(languages).length) { - setSelected(Object.keys(languages)[0]); - } - }, [languages, selected]); - - useEffect(() => { - if (selected) { - loadContent(selected); - } - }, [selected]); - /* eslint-enable react-hooks/set-state-in-effect */ - - const handleSave = async () => { - if (!selected) return; - try { - const payload = JSON.parse(editorValue); - await updateTranslation(selected, payload); - setMessage(t("ui.translations.notice.saved", "Translation saved!")); - onRefresh(); - } catch (err) { - setError(String(err)); - } - }; - - const handleCreate = async (event: FormEvent) => { - event.preventDefault(); - if (!newLang.trim()) return; - await createTranslation(newLang.trim()); - setNewLang(""); - onRefresh(); - }; - - const handleDelete = async () => { - if (!selected) return; - await deleteTranslation(selected); - setSelected(null); - onRefresh(); - }; - - return ( - - - {t("ui.translations.title", "Translations")} - - - {t("ui.translations.subtitle", "Create, edit, and maintain language files for bot messages")} - - - - {Object.entries(languages).map(([lang, label]) => ( - setSelected(lang)} - clickable - /> - ))} - - setEditorValue(event.target.value)} - InputProps={{ - sx: { - backgroundColor: "#030712", - borderRadius: 2, - color: "white", - fontFamily: "JetBrains Mono, monospace", - }, - }} - /> - - - - {t("ui.actions.save", "Save")} - - - {t("ui.actions.delete", "Delete")} - - - setNewLang(event.target.value)} - fullWidth - /> - - {t("ui.actions.add", "Add")} - - - - {(message || error) && ( - - {message || error} - - )} - - ); -} diff --git a/frontend/autometabuilder/components/sections/WorkflowSection.tsx b/frontend/autometabuilder/components/sections/WorkflowSection.tsx deleted file mode 100644 index 7e99fc7..0000000 --- a/frontend/autometabuilder/components/sections/WorkflowSection.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { useEffect, useState } from "react"; -import { Box, Button, Paper, Stack, Typography } from "@mui/material"; -import { WorkflowPackageSummary } from "../../lib/types"; - -type WorkflowSectionProps = { - content: string; - packages: WorkflowPackageSummary[]; - onSave: (content: string) => Promise; - onTemplateSelect: (id: string) => void; - t: (key: string, fallback?: string) => string; -}; - -export default function WorkflowSection({ content, packages, onSave, onTemplateSelect, t }: WorkflowSectionProps) { - const [draft, setDraft] = useState(content); - const [message, setMessage] = useState(""); - - useEffect(() => { - setDraft(content); - }, [content]); - - const handleSave = async () => { - await onSave(draft); - setMessage(t("ui.workflow.save", "Save Workflow") + " " + t("ui.actions.save", "Save")); - setTimeout(() => setMessage(""), 2000); - }; - - return ( - - - {t("ui.workflow.title", "Workflow Builder")} - - - {t("ui.workflow.subtitle", "Design the bot's task execution pipeline")} - - - - setDraft(event.target.value)} - rows={18} - sx={{ - width: "100%", - fontFamily: "JetBrains Mono, monospace", - backgroundColor: "#030712", - border: "1px solid rgba(148, 163, 184, 0.4)", - borderRadius: 2, - color: "white", - p: 2, - }} - /> - - - {t("ui.workflow.save", "Save Workflow")} - - - {message} - - - - - - {t("ui.workflow.templates.title", "Workflow Templates")} - - - {packages.map((pkg) => ( - - - {pkg.label} - - {pkg.description} - - onTemplateSelect(pkg.id)}> - {t("ui.workflow.templates.apply", "Apply Template")} - - - - ))} - - - - - ); -}