feat(amm-ui): add navbar to switch between views

This commit is contained in:
r4bbit 2026-04-28 14:41:54 +02:00
parent e18f0f3c32
commit 0cec2e2573
2 changed files with 225 additions and 118 deletions

View File

@ -14,139 +14,160 @@ Item {
{ symbol: "TOK6", name: "Token 6", color: "#9b59b6", letter: "L", address: "0x1337000000000000000000000000000000000cafe", usdPrice: 0.42 }
]
// Theme
QtObject {
id: theme
property bool isDark: false
property var colors: isDark ? dark : light
readonly property var light: ({
background: "#f7f7f5",
cardBg: "#ffffff",
inputBg: "#f0f0ee",
panelBg: "#e8e8e4",
panelHoverBg: "#ddddd8",
textPrimary: "#111111",
textSecondary: "#777770",
textPlaceholder: "#bbbbb5",
border: Qt.rgba(0,0,0,0.08),
borderStrong: Qt.rgba(0,0,0,0.10),
divider: Qt.rgba(0,0,0,0.06),
ctaBg: "#111111",
ctaHoverBg: "#2a2a28",
selection: "#b5c4a5",
noTokenCircle: "#c8c8c4",
orb1: "#7a8c6a",
orb2: "#b5c4a5",
orb3: "#7a8c6a",
orb4: "#c8d4b8"
})
readonly property var dark: ({
background: "#0d0d12",
cardBg: "#1a1a22",
inputBg: "#222230",
panelBg: "#2a2a38",
panelHoverBg: "#363650",
textPrimary: "#ffffff",
textSecondary: "#888899",
textPlaceholder: "#444455",
border: Qt.rgba(1,1,1,0.08),
borderStrong: Qt.rgba(1,1,1,0.10),
divider: Qt.rgba(1,1,1,0.06),
ctaBg: "#2d1530",
ctaHoverBg: "#3d1f40",
selection: "#4c1d4b",
noTokenCircle: "#444455",
orb1: "#627eea",
orb2: "#9b59b6",
orb3: "#fc72ff",
orb4: "#26a17b"
})
// Navigation bar
// Pinned to the top; self-contained styling, unaffected by view themes.
NavBar {
id: navbar
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
z: 100
}
// Root background
Rectangle {
anchors.fill: parent
color: theme.colors.background
Behavior on color { ColorAnimation { duration: 300 } }
// Content area (below the nav bar)
Item {
anchors.top: navbar.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
// Theme toggle
Rectangle {
anchors.top: parent.top
anchors.right: parent.right
anchors.margins: 16
width: 44; height: 24; radius: 12
color: theme.colors.panelBg
border.color: theme.colors.border
border.width: 1
Text {
anchors.centerIn: parent
text: theme.isDark ? "☀" : "☾"
font.pixelSize: 13
color: theme.colors.textSecondary
// Trade view
Item {
anchors.fill: parent
visible: navbar.currentIndex === 0
// Trade view theme scoped here, invisible to NavBar and LP view.
QtObject {
id: theme
property bool isDark: false
property var colors: isDark ? dark : light
readonly property var light: ({
background: "#f7f7f5",
cardBg: "#ffffff",
inputBg: "#f0f0ee",
panelBg: "#e8e8e4",
panelHoverBg: "#ddddd8",
textPrimary: "#111111",
textSecondary: "#777770",
textPlaceholder: "#bbbbb5",
border: Qt.rgba(0,0,0,0.08),
borderStrong: Qt.rgba(0,0,0,0.10),
divider: Qt.rgba(0,0,0,0.06),
ctaBg: "#111111",
ctaHoverBg: "#2a2a28",
selection: "#b5c4a5",
noTokenCircle: "#c8c8c4",
orb1: "#7a8c6a",
orb2: "#b5c4a5",
orb3: "#7a8c6a",
orb4: "#c8d4b8"
})
readonly property var dark: ({
background: "#0d0d12",
cardBg: "#1a1a22",
inputBg: "#222230",
panelBg: "#2a2a38",
panelHoverBg: "#363650",
textPrimary: "#ffffff",
textSecondary: "#888899",
textPlaceholder: "#444455",
border: Qt.rgba(1,1,1,0.08),
borderStrong: Qt.rgba(1,1,1,0.10),
divider: Qt.rgba(1,1,1,0.06),
ctaBg: "#2d1530",
ctaHoverBg: "#3d1f40",
selection: "#4c1d4b",
noTokenCircle: "#444455",
orb1: "#627eea",
orb2: "#9b59b6",
orb3: "#fc72ff",
orb4: "#26a17b"
})
}
MouseArea {
Rectangle {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: theme.isDark = !theme.isDark
}
}
color: theme.colors.background
Behavior on color { ColorAnimation { duration: 300 } }
// Decorative orbs
Rectangle { x: -180; y: -120; width: 560; height: 560; radius: 280; color: theme.colors.orb1; opacity: 0.07 }
Rectangle { x: parent.width - 280; y: parent.height - 320; width: 480; height: 480; radius: 240; color: theme.colors.orb2; opacity: 0.09 }
Rectangle { x: parent.width - 200; y: -80; width: 380; height: 380; radius: 190; color: theme.colors.orb3; opacity: 0.05 }
Rectangle { x: 40; y: parent.height - 260; width: 320; height: 320; radius: 160; color: theme.colors.orb4; opacity: 0.08 }
// Theme toggle
Rectangle {
anchors.top: parent.top
anchors.right: parent.right
anchors.margins: 16
width: 44; height: 24; radius: 12
color: theme.colors.panelBg
border.color: theme.colors.border
border.width: 1
Text {
anchors.centerIn: parent
text: theme.isDark ? "☀" : "☾"
font.pixelSize: 13
color: theme.colors.textSecondary
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: theme.isDark = !theme.isDark
}
}
ColumnLayout {
anchors.centerIn: parent
spacing: 28
// Decorative orbs
Rectangle { x: -180; y: -120; width: 560; height: 560; radius: 280; color: theme.colors.orb1; opacity: 0.07 }
Rectangle { x: parent.width - 280; y: parent.height - 320; width: 480; height: 480; radius: 240; color: theme.colors.orb2; opacity: 0.09 }
Rectangle { x: parent.width - 200; y: -80; width: 380; height: 380; radius: 190; color: theme.colors.orb3; opacity: 0.05 }
Rectangle { x: 40; y: parent.height - 260; width: 320; height: 320; radius: 160; color: theme.colors.orb4; opacity: 0.08 }
Text {
Layout.alignment: Qt.AlignHCenter
text: "Logos AMM"
color: theme.colors.textPrimary
font.pixelSize: 48
font.weight: Font.Bold
}
ColumnLayout {
anchors.centerIn: parent
spacing: 28
SwapCard {
id: swapCard
Layout.alignment: Qt.AlignHCenter
theme: theme
tokens: root.tokenData
width: Math.min(480, root.width - 32)
SwapCard {
id: swapCard
Layout.alignment: Qt.AlignHCenter
theme: theme
tokens: root.tokenData
width: Math.min(480, root.width - 32)
onRequestTokenSelect: function(side) {
tokenModal.targetSide = side
tokenModal.open()
onRequestTokenSelect: function(side) {
tokenModal.targetSide = side
tokenModal.open()
}
}
Text {
Layout.alignment: Qt.AlignHCenter
text: "Buy and sell crypto on <font color='" + theme.colors.textPrimary + "'>LEZ</font>."
textFormat: Text.RichText
color: theme.colors.textSecondary
font.pixelSize: 15
horizontalAlignment: Text.AlignHCenter
}
}
TokenSelectorModal {
id: tokenModal
anchors.fill: parent
z: 10
theme: theme
tokens: root.tokenData
property string targetSide: "sell"
onTokenSelected: function(tok) {
swapCard.setToken(targetSide, tok)
tokenModal.close()
}
}
}
Text {
Layout.alignment: Qt.AlignHCenter
text: "Buy and sell crypto on <font color='" + theme.colors.textPrimary + "'>LEZ</font>."
textFormat: Text.RichText
color: theme.colors.textSecondary
font.pixelSize: 15
horizontalAlignment: Text.AlignHCenter
}
}
TokenSelectorModal {
id: tokenModal
// Liquidity view (placeholder replaced when LP branch merges)
Item {
anchors.fill: parent
z: 10
theme: theme
tokens: root.tokenData
property string targetSide: "sell"
onTokenSelected: function(tok) {
swapCard.setToken(targetSide, tok)
tokenModal.close()
}
visible: navbar.currentIndex === 1
}
}
}

86
amm-ui/qml/NavBar.qml Normal file
View File

@ -0,0 +1,86 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
// Self-contained navigation bar styling is independent of any view's theme.
// Use currentIndex to read the active tab; tabChanged(index) fires on selection.
Item {
id: root
property int currentIndex: 0
readonly property var tabs: ["Trade", "Liquidity"]
signal tabChanged(int index)
implicitHeight: 56
Rectangle {
anchors.fill: parent
color: "#ffffff"
// Bottom separator
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: 1
color: Qt.rgba(0, 0, 0, 0.08)
}
RowLayout {
anchors.fill: parent
anchors.leftMargin: 20
anchors.rightMargin: 20
spacing: 4
// App identity
Text {
text: "Logos AMM"
color: "#111111"
font.pixelSize: 17
font.weight: Font.Bold
}
Item { Layout.fillWidth: true }
// Tab pills
Row {
spacing: 4
Repeater {
model: root.tabs
delegate: Rectangle {
readonly property bool active: root.currentIndex === index
height: 36
width: tabLabel.implicitWidth + 28
radius: 18
color: active ? "#111111" : "transparent"
Behavior on color { ColorAnimation { duration: 150 } }
Text {
id: tabLabel
anchors.centerIn: parent
text: modelData
color: active ? "#ffffff" : "#666666"
font.pixelSize: 14
font.weight: active ? Font.Medium : Font.Normal
Behavior on color { ColorAnimation { duration: 150 } }
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
root.currentIndex = index
root.tabChanged(index)
}
}
}
}
}
}
}
}