From 8cf3ce5c87df9913fa23425b024d9b57b52f89b9 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Thu, 19 Mar 2026 10:19:04 +0000 Subject: [PATCH] Remove frontends/qt6 views; update import path Delete duplicated frontend QML files under frontends/qt6 (GodPanel.qml, SettingsView.qml). Adjust qml/qt6/GodPanel.qml to import the local qmllib/MetaBuilder path instead of the MetaBuilder 1.0 module, keeping the canonical QML implementation in qml/qt6. --- frontends/qt6/GodPanel.qml | 227 --------------------------------- frontends/qt6/SettingsView.qml | 183 -------------------------- qml/qt6/GodPanel.qml | 2 +- 3 files changed, 1 insertion(+), 411 deletions(-) delete mode 100644 frontends/qt6/GodPanel.qml delete mode 100644 frontends/qt6/SettingsView.qml diff --git a/frontends/qt6/GodPanel.qml b/frontends/qt6/GodPanel.qml deleted file mode 100644 index 2b2e024ce..000000000 --- a/frontends/qt6/GodPanel.qml +++ /dev/null @@ -1,227 +0,0 @@ -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts -import QmlComponents 1.0 -import "qmllib/MetaBuilder" -import "config/GodPanelConfig.js" as GodPanelConfig - -Rectangle { - id: godPanel - color: Theme.background - - property int currentTab: 0 - - // Config summary counts (would come from DBAL in production) - property var configCounts: ({ - schemas: 39, workflows: 12, luaScripts: 8, packages: 62, - pages: 27, components: 152, users: 3, snippets: 5, - cssClasses: 44, dropdowns: 16, dbBackends: 14 - }) - - // ── Data loaded from JSON config ── - property var tabModel: [] - property var levelData: [] - property var configStatData: [] - property var tabSources: [] - - // ── MD3-inspired palette ── - readonly property bool isDark: Theme.mode === "dark" - readonly property color accentBlue: "#6366F1" - readonly property color accentCyan: "#06B6D4" - readonly property color accentViolet: "#8B5CF6" - readonly property color accentAmber: "#F59E0B" - readonly property color accentRose: "#F43F5E" - - // MD3 tonal surfaces - readonly property color surfaceContainer: isDark ? Qt.rgba(1, 1, 1, 0.05) : Qt.rgba(0.31, 0.31, 0.44, 0.06) - readonly property color surfaceContainerHigh: isDark ? Qt.rgba(1, 1, 1, 0.08) : Qt.rgba(0.31, 0.31, 0.44, 0.10) - readonly property color surfaceContainerHighest: isDark ? Qt.rgba(1, 1, 1, 0.12) : Qt.rgba(0.31, 0.31, 0.44, 0.14) - readonly property color onSurface: Theme.text - readonly property color onSurfaceVariant: Theme.textSecondary - readonly property color outline: Theme.border - readonly property color outlineVariant: isDark ? Qt.rgba(1, 1, 1, 0.06) : Qt.rgba(0, 0, 0, 0.08) - readonly property color primaryContainer: isDark ? Qt.rgba(accentBlue.r, accentBlue.g, accentBlue.b, 0.15) : Qt.rgba(accentBlue.r, accentBlue.g, accentBlue.b, 0.12) - - // Level accent colors for guide cards - readonly property var levelAccents: [ - "#94A3B8", accentBlue, accentCyan, accentViolet, accentRose - ] - - Component.onCompleted: { - var tabs = GodPanelConfig.loadTabs() - tabModel = tabs - - // Extract source paths for the Loader-based tabs - var sources = [] - for (var i = 0; i < tabs.length; i++) - sources.push(tabs[i].source || "") - tabSources = sources - - levelData = GodPanelConfig.loadLevels() - - var rawStats = GodPanelConfig.loadConfigStats() - var palette = { accentBlue: accentBlue, accentCyan: accentCyan, - accentViolet: accentViolet, accentAmber: accentAmber, - accentRose: accentRose } - configStatData = GodPanelConfig.resolveConfigStats(rawStats, configCounts, palette) - } - - ColumnLayout { - anchors.fill: parent - anchors.margins: 24 - spacing: 20 - - // ═══════════════════════════════════════════════════ - // HEADER - // ═══════════════════════════════════════════════════ - CGodPanelHeader { - Layout.fillWidth: true - configCounts: godPanel.configCounts - isDark: godPanel.isDark - onNavigateLevel: function(level) { - if (level === 1) appWindow.currentView = "frontpage" - else if (level === 2) appWindow.currentView = "dashboard" - else if (level === 3) appWindow.currentView = "admin" - } - } - - // ═══════════════════════════════════════════════════ - // TAB BAR - // ═══════════════════════════════════════════════════ - CTabBar { - id: tabBar - Layout.fillWidth: true - currentIndex: currentTab - onCurrentIndexChanged: currentTab = currentIndex - tabs: tabModel - } - - // ═══════════════════════════════════════════════════ - // TAB CONTENT - // ═══════════════════════════════════════════════════ - StackLayout { - Layout.fillWidth: true - Layout.fillHeight: true - currentIndex: currentTab - - // ── 0 - Guide ── - Rectangle { - color: "transparent" - ScrollView { - anchors.fill: parent - clip: true - contentWidth: availableWidth - - ColumnLayout { - width: parent.width - spacing: 20 - - // Intro section - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: guideIntroCol.implicitHeight + 48 - radius: 16; color: surfaceContainerHigh - border.width: 1; border.color: outlineVariant - - ColumnLayout { - id: guideIntroCol - anchors { left: parent.left; right: parent.right; top: parent.top; margins: 24 } - spacing: 16 - CText { text: "Builder Quick Reference"; font.pixelSize: 22; font.weight: Font.Bold; color: onSurface; Layout.fillWidth: true } - CText { text: "MetaBuilder uses a 5-level permission and interface system. Each level unlocks progressively more powerful tools."; font.pixelSize: 14; wrapMode: Text.Wrap; Layout.fillWidth: true; color: onSurfaceVariant; lineHeight: 1.5 } - } - } - - // Level cards - CText { text: "Access Levels"; font.pixelSize: 18; font.weight: Font.DemiBold; color: onSurface; Layout.fillWidth: true; Layout.topMargin: 4 } - Repeater { - model: levelData - delegate: CLevelReferenceCard { - Layout.fillWidth: true - levelName: modelData.level; role: modelData.role; description: modelData.desc - accent: levelAccents[modelData.accentIndex]; levelNumber: modelData.accentIndex + 1 - isDark: godPanel.isDark - } - } - - // Config summary section - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: configSummaryCol.implicitHeight + 48 - Layout.topMargin: 8; radius: 16; color: surfaceContainerHigh - border.width: 1; border.color: outlineVariant - - ColumnLayout { - id: configSummaryCol - anchors { left: parent.left; right: parent.right; top: parent.top; margins: 24 } - spacing: 16 - CText { text: "Current Configuration"; font.pixelSize: 16; font.weight: Font.DemiBold; color: onSurface; Layout.fillWidth: true } - GridLayout { - Layout.fillWidth: true - columns: Math.max(2, Math.min(4, Math.floor((parent.width + 12) / 180))) - columnSpacing: 12; rowSpacing: 12 - Repeater { - model: configStatData - delegate: CConfigStatCard { - Layout.fillWidth: true - label: modelData.label; value: modelData.value; accent: modelData.accent - isDark: godPanel.isDark - } - } - } - } - } - - CAlert { Layout.fillWidth: true; severity: "info"; text: "Philosophy: 95% JSON config, 5% TypeScript/C++ infrastructure. Entities, workflows, pages, and business logic are all declarative." } - Item { Layout.preferredHeight: 16 } - } - } - } - - // ── Tabs 1-12: data-driven Loader tabs ── - Repeater { - model: 12 - delegate: Rectangle { - color: "transparent" - Loader { - anchors.fill: parent - source: (tabSources.length > index + 1) ? tabSources[index + 1] : "" - } - } - } - - // ── 13 - Settings (Theme + SMTP side by side) ── - Rectangle { - color: "transparent" - ColumnLayout { - anchors.fill: parent; spacing: 20 - CText { text: "System Settings"; font.pixelSize: 22; font.weight: Font.Bold; color: onSurface; Layout.fillWidth: true } - CText { text: "Theme customization and SMTP configuration for outbound email."; font.pixelSize: 14; color: onSurfaceVariant; Layout.fillWidth: true } - RowLayout { - Layout.fillWidth: true; Layout.fillHeight: true; spacing: 16 - Rectangle { - Layout.fillWidth: true; Layout.fillHeight: true; radius: 16 - color: surfaceContainerHigh; border.width: 1; border.color: outlineVariant - ColumnLayout { - anchors.fill: parent; anchors.margins: 20; spacing: 12 - RowLayout { Layout.fillWidth: true; spacing: 10; CText { text: "Theme Editor"; font.pixelSize: 16; font.weight: Font.DemiBold; color: onSurface } CChip { text: "Visual"; variant: "info" } } - Rectangle { Layout.fillWidth: true; height: 1; color: outlineVariant } - Loader { Layout.fillWidth: true; Layout.fillHeight: true; source: "ThemeEditor.qml" } - } - } - Rectangle { - Layout.fillWidth: true; Layout.fillHeight: true; radius: 16 - color: surfaceContainerHigh; border.width: 1; border.color: outlineVariant - ColumnLayout { - anchors.fill: parent; anchors.margins: 20; spacing: 12 - RowLayout { Layout.fillWidth: true; spacing: 10; CText { text: "SMTP Configuration"; font.pixelSize: 16; font.weight: Font.DemiBold; color: onSurface } CChip { text: "Email"; variant: "primary" } } - Rectangle { Layout.fillWidth: true; height: 1; color: outlineVariant } - Loader { Layout.fillWidth: true; Layout.fillHeight: true; source: "SMTPConfigEditor.qml" } - } - } - } - } - } - } - } -} diff --git a/frontends/qt6/SettingsView.qml b/frontends/qt6/SettingsView.qml deleted file mode 100644 index 935e44323..000000000 --- a/frontends/qt6/SettingsView.qml +++ /dev/null @@ -1,183 +0,0 @@ -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts -import QmlComponents 1.0 -import "qmllib/dbal" -import "qmllib/MetaBuilder" - -Rectangle { - id: root - color: "transparent" - - DBALProvider { id: dbal } - property bool useLiveData: dbal.connected - - // ── JSON config ────────────────────────────────────────────── - function loadJson(path) { - var xhr = new XMLHttpRequest() - xhr.open("GET", Qt.resolvedUrl(path), false); xhr.send() - return xhr.status === 200 ? JSON.parse(xhr.responseText) : null - } - property var notificationConfig: loadJson("config/settings-notifications.json") || [] - property var aboutConfig: loadJson("config/settings-about.json") || [] - property var fontSizeConfig: loadJson("config/settings-font-sizes.json") || [] - - // ── State ──────────────────────────────────────────────────── - property string displayName: appWindow.currentUser - property string userEmail: appWindow.currentUser + "@metabuilder.io" - property bool profileSaved: false - property string selectedTheme: appWindow.currentTheme - property string fontSize: "medium" - property var notifValues: ({ emailNotifications: true, desktopNotifications: true, soundAlerts: false }) - - function userInitials() { - var n = appWindow.currentUser - if (!n || n.length === 0) return "??" - var p = n.split(" ") - return p.length >= 2 ? (p[0][0] + p[1][0]).toUpperCase() : n.substring(0, 2).toUpperCase() - } - - // ── DBAL persistence ───────────────────────────────────────── - function saveProfile() { - var onSaved = function() { profileSaved = true; profileSavedTimer.restart() } - if (useLiveData) { - dbal.update("user", appWindow.currentUser, - { displayName: displayName, email: userEmail }, - function(r, e) { if (!e) onSaved() }) - } else { onSaved(); console.log("[Settings] Profile saved (offline):", displayName, userEmail) } - } - - function savePreferences() { - if (!useLiveData) return - dbal.update("user", appWindow.currentUser, { - preferences: { theme: selectedTheme, fontSize: fontSize, - emailNotifications: notifValues.emailNotifications, - desktopNotifications: notifValues.desktopNotifications, - soundAlerts: notifValues.soundAlerts } - }, function(r, e) { if (!e) console.log("[Settings] Preferences saved to DBAL") }) - } - - function loadPreferences() { - if (!useLiveData) return - dbal.findFirst("user", { username: appWindow.currentUser }, function(result, error) { - if (error || !result) return - var items = result.items || []; if (items.length === 0) return - var u = items[0] - if (u.displayName) displayName = u.displayName - if (u.email) userEmail = u.email - if (u.preferences) { - if (u.preferences.theme) selectedTheme = u.preferences.theme - if (u.preferences.fontSize) fontSize = u.preferences.fontSize - var nv = JSON.parse(JSON.stringify(notifValues)) - if (u.preferences.emailNotifications !== undefined) nv.emailNotifications = u.preferences.emailNotifications - if (u.preferences.desktopNotifications !== undefined) nv.desktopNotifications = u.preferences.desktopNotifications - if (u.preferences.soundAlerts !== undefined) nv.soundAlerts = u.preferences.soundAlerts - notifValues = nv - } - }) - } - - Component.onCompleted: { if (useLiveData) loadPreferences() } - onUseLiveDataChanged: { if (useLiveData) loadPreferences() } - Timer { id: profileSavedTimer; interval: 3000; onTriggered: profileSaved = false } - - // ── UI ─────────────────────────────────────────────────────── - ScrollView { - anchors.fill: parent; anchors.margins: 24; clip: true - ColumnLayout { - width: parent.width; spacing: 20 - - CText { variant: "h3"; text: "Settings" } - - // Profile - CSettingsSection { - title: "Profile" - FlexRow { - Layout.fillWidth: true; Layout.topMargin: 4; spacing: 16 - CAvatar { size: "lg"; initials: userInitials() } - ColumnLayout { - Layout.fillWidth: true; spacing: 4 - CText { variant: "subtitle1"; text: appWindow.currentUser; font.bold: true } - CText { variant: "body2"; text: appWindow.currentRole + " \u00b7 Level " + appWindow.currentLevel; opacity: 0.7 } - } - } - CTextField { Layout.fillWidth: true; Layout.topMargin: 8; label: "Display Name"; placeholderText: "Enter display name"; text: displayName; onTextChanged: displayName = text } - CTextField { Layout.fillWidth: true; label: "Email"; placeholderText: "Enter email address"; text: userEmail; onTextChanged: userEmail = text } - FlexRow { - Layout.fillWidth: true; spacing: 12 - Item { Layout.fillWidth: true } - CAlert { visible: profileSaved; severity: "success"; text: "Profile saved successfully" } - CButton { text: "Save Profile"; variant: "primary"; onClicked: saveProfile() } - } - } - - // Appearance - CSettingsSection { - title: "Appearance" - CThemePicker { - Layout.fillWidth: true; currentTheme: root.selectedTheme - onThemeSelected: function(name) { - root.selectedTheme = name; appWindow.currentTheme = name - if (typeof Theme.setTheme === "function") Theme.setTheme(name) - savePreferences() - } - } - CText { variant: "subtitle2"; text: "Font Size"; Layout.topMargin: 8 } - FlexRow { - Layout.fillWidth: true; spacing: 8 - Repeater { - model: fontSizeConfig - delegate: CButton { - text: modelData.label; variant: fontSize === modelData.id ? "primary" : "default"; size: "sm" - onClicked: { fontSize = modelData.id; savePreferences() } - } - } - } - } - - // Notifications - CSettingsSection { - title: "Notifications" - CNotificationToggles { - Layout.fillWidth: true; model: notificationConfig; values: notifValues - onToggled: function(id, value) { - var nv = JSON.parse(JSON.stringify(notifValues)); nv[id] = value; notifValues = nv; savePreferences() - } - } - } - - // Connection - CSettingsSection { - title: "Connection" - CConnectionTest { Layout.fillWidth: true } - } - - // About - CSettingsSection { - title: "About" - Repeater { - model: aboutConfig - delegate: FlexRow { - Layout.fillWidth: true; spacing: 12 - CText { variant: "body2"; text: modelData.label; opacity: 0.6; Layout.preferredWidth: 120 } - CText { variant: "body1"; text: modelData.value } - } - } - FlexRow { - Layout.fillWidth: true; spacing: 12 - CText { variant: "body2"; text: "Platform"; opacity: 0.6; Layout.preferredWidth: 120 } - CText { variant: "body1"; text: Qt.platform.os } - } - CDivider { Layout.fillWidth: true } - FlexRow { - Layout.fillWidth: true; spacing: 12 - CButton { text: "View Documentation"; variant: "default"; size: "sm"; onClicked: Qt.openUrlExternally("https://github.com/nicholasgriffintn/metabuilder") } - CButton { text: "Report Issue"; variant: "ghost"; size: "sm"; onClicked: Qt.openUrlExternally("https://github.com/nicholasgriffintn/metabuilder/issues") } - } - } - - CText { variant: "caption"; text: useLiveData ? "Connected to DBAL \u2014 preferences synced" : "Offline \u2014 preferences stored locally"; opacity: 0.4 } - Item { Layout.preferredHeight: 20 } - } - } -} diff --git a/qml/qt6/GodPanel.qml b/qml/qt6/GodPanel.qml index 365905149..2b2e024ce 100644 --- a/qml/qt6/GodPanel.qml +++ b/qml/qt6/GodPanel.qml @@ -2,7 +2,7 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import QmlComponents 1.0 -import MetaBuilder 1.0 +import "qmllib/MetaBuilder" import "config/GodPanelConfig.js" as GodPanelConfig Rectangle {