feat: add onboarding view

This commit is contained in:
Khushboo Mehta 2026-02-20 18:10:59 +01:00
parent f9a5acb624
commit 34b543aa72
7 changed files with 197 additions and 27 deletions

15
flake.lock generated
View File

@ -574,17 +574,14 @@
]
},
"locked": {
"lastModified": 1771584803,
"narHash": "sha256-F6Kk98wy2L1b/Fziq0dbkbvQcTn0pgHJzWoDcuDqaS8=",
"owner": "logos-blockchain",
"repo": "logos-execution-zone-module",
"rev": "1291c407777667664ff8973e099d4f7d0076f575",
"type": "github"
"lastModified": 1771606875,
"narHash": "sha256-g6YPUN8LtRGAj5OG4PAZNuKyNQL0uTP+5IZEcQVaozE=",
"path": "/Users/khushboomehta/Documents/logos/logos-execution-zone-module",
"type": "path"
},
"original": {
"owner": "logos-blockchain",
"repo": "logos-execution-zone-module",
"type": "github"
"path": "/Users/khushboomehta/Documents/logos/logos-execution-zone-module",
"type": "path"
}
},
"logos-liblogos": {

View File

@ -5,7 +5,7 @@
nixpkgs.follows = "logos-liblogos/nixpkgs";
logos-cpp-sdk.url = "github:logos-co/logos-cpp-sdk";
logos-liblogos.url = "github:logos-co/logos-liblogos";
logos-execution-zone-module.url = "github:logos-blockchain/logos-execution-zone-module";
logos-execution-zone-module.url = "path:/Users/khushboomehta/Documents/logos/logos-execution-zone-module";
logos-capability-module.url = "github:logos-co/logos-capability-module";
logos-design-system.url = "github:logos-co/logos-design-system";
logos-design-system.inputs.nixpkgs.follows = "nixpkgs";

View File

@ -224,13 +224,14 @@ bool LEZWalletBackend::createNew(
const QString& storagePath,
const QString& password)
{
const QString localPath = QUrl::fromUserInput(configPath).toLocalFile();
if (!m_walletClient) return false;
QVariant result = m_walletClient->invokeRemoteMethod(
WALLET_MODULE_NAME, "create_new", configPath, storagePath, password);
WALLET_MODULE_NAME, "create_new", localPath, storagePath, password);
int err = result.isValid() ? result.toInt() : -1;
if (err != WALLET_FFI_SUCCESS) return false;
setConfigPath(configPath);
setConfigPath(localPath);
setStoragePath(storagePath);
setWalletOpen(true);
refreshAccounts();

View File

@ -6,34 +6,31 @@ import QtCore
import LEZWalletBackend
import Logos.Theme
import Logos.Controls
import "views"
Rectangle {
id: root
color: Theme.palette.background
SwipeView {
id: swipeView
StackView {
anchors.fill: parent
interactive: false
currentIndex: backend && backend.isWalletOpen ? 1 : 0
initialItem: backend && backend.isWalletOpen ? mainView: onboardingView
// Page 0: Onboarding placeholder (full OnboardingView added later)
Item {
Rectangle {
anchors.fill: parent
color: Theme.palette.background
LogosText {
anchors.centerIn: parent
text: qsTr("Wallet Setup")
font.pixelSize: Theme.typography.secondaryText
font.bold: true
Component {
id: onboardingView
OnboardingView {
onCreateWallet: function(configPath, storagePath, password) {
if (!backend || !backend.createNew(configPath, storagePath, password))
createError = qsTr("Failed to create wallet. Check paths and try again.")
}
}
}
// Page 1: Main screen placeholder (AccountsView / SendView added later)
Item {
Component {
id: mainView
Rectangle {
anchors.fill: parent
color: Theme.palette.background

View File

@ -0,0 +1,171 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Dialogs
import QtCore
import Logos.Theme
import Logos.Controls
Control {
id: root
property string createError: ""
signal createWallet(string configPath, string storagePath, string password)
ColumnLayout {
id: cardColumn
anchors.fill: parent
anchors.margins: Theme.spacing.xlarge
spacing: Theme.spacing.large
LogosText {
text: qsTr("Set up LEZ Wallet")
font.pixelSize: Theme.typography.titleText
font.weight: Theme.typography.weightBold
color: Theme.palette.text
}
LogosText {
text: qsTr("Configure storage and secure with a password.")
font.pixelSize: Theme.typography.secondaryText
color: Theme.palette.textSecondary
Layout.topMargin: -Theme.spacing.small
}
LogosText {
text: qsTr("Storage")
font.pixelSize: Theme.typography.secondaryText
font.weight: Theme.typography.weightMedium
color: Theme.palette.text
}
RowLayout {
Layout.fillWidth: true
spacing: Theme.spacing.small
CustomTextField {
id: storagePathField
placeholderText: qsTr("/Users/you/.lez-wallet/")
}
LogosButton {
text: qsTr("Browse")
onClicked: storageFolderDialog.open()
}
}
LogosText {
text: qsTr("Config file (optional)")
font.pixelSize: Theme.typography.secondaryText
font.weight: Theme.typography.weightMedium
color: Theme.palette.text
}
RowLayout {
Layout.fillWidth: true
spacing: Theme.spacing.small
CustomTextField {
id: configPathField
placeholderText: qsTr("Use default config")
}
LogosButton {
text: qsTr("Browse")
onClicked: configFileDialog.open()
}
}
LogosText {
text: qsTr("Security")
font.pixelSize: Theme.typography.secondaryText
font.weight: Theme.typography.weightMedium
color: Theme.palette.text
Layout.topMargin: Theme.spacing.medium
}
CustomTextField {
id: passwordField
placeholderText: qsTr("Password")
echoMode: TextInput.Password
}
CustomTextField {
id: confirmField
placeholderText: qsTr("Confirm")
echoMode: TextInput.Password
}
LogosText {
id: errorLabel
Layout.fillWidth: true
font.pixelSize: Theme.typography.secondaryText
color: Theme.palette.error
wrapMode: Text.WordWrap
visible: text.length > 0
text: root.createError
}
LogosButton {
Layout.alignment: Qt.AlignRight
text: qsTr("Create Wallet")
font.pixelSize: Theme.typography.secondaryText
onClicked: {
if (passwordField.text.length === 0) {
root.createError = qsTr("Password cannot be empty.")
} else if (passwordField.text !== confirmField.text) {
root.createError = qsTr("Passwords do not match.")
} else {
root.createError = ""
root.createWallet(configPathField.text, storagePathField.text, passwordField.text)
}
}
}
component CustomTextField: Item {
id: textFieldRoot
Layout.fillWidth: true
implicitHeight: 40
property alias text: input.text
property string placeholderText: ""
property int echoMode: TextInput.Normal
Rectangle {
anchors.fill: parent
radius: Theme.spacing.radiusSmall
color: Theme.palette.backgroundSecondary
border.width: 1
border.color: input.activeFocus ? Theme.palette.overlayOrange : Theme.palette.backgroundElevated
}
Text {
id: placeholder
anchors.fill: parent
anchors.leftMargin: 12
anchors.rightMargin: 12
verticalAlignment: Text.AlignVCenter
text: textFieldRoot.placeholderText
color: Theme.palette.textMuted
font.pixelSize: Theme.typography.secondaryText
visible: input.text.length === 0
}
TextInput {
id: input
anchors.fill: parent
anchors.leftMargin: 12
anchors.rightMargin: 12
verticalAlignment: Text.AlignVCenter
font.pixelSize: Theme.typography.secondaryText
color: Theme.palette.text
echoMode: textFieldRoot.echoMode
}
}
}
FolderDialog {
id: storageFolderDialog
modality: Qt.NonModal
onAccepted: storagePathField.text = selectedFolder.toString().replace(/^file:\/\//, "")
}
FileDialog {
id: configFileDialog
modality: Qt.NonModal
nameFilters: ["YAML files (*.yaml)"]
onAccepted: {
if (selectedFile) configPathField.text = selectedFile.toString().replace(/^file:\/\//, "")
}
}
}

2
src/qml/views/qmldir Normal file
View File

@ -0,0 +1,2 @@
module views
OnboardingView 1.0 OnboardingView.qml

View File

@ -1,5 +1,7 @@
<RCC>
<qresource prefix="/">
<file>qml/ExecutionZoneWalletView.qml</file>
<file>qml/views/qmldir</file>
<file>qml/views/OnboardingView.qml</file>
</qresource>
</RCC>