client-qml: add initial commit

Change-Id: I32bfdd2a618aa7ac6181da2697e241667b010aab
diff --git a/src/wizardview/WizardView.qml b/src/wizardview/WizardView.qml
new file mode 100644
index 0000000..0f3c29d
--- /dev/null
+++ b/src/wizardview/WizardView.qml
@@ -0,0 +1,736 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Window 2.14
+import QtQuick.Controls 1.4 as CT
+import QtQuick.Controls 2.14
+import QtQuick.Controls.Universal 2.12
+import QtQuick.Layouts 1.3
+import QtGraphicalEffects 1.14
+import net.jami.Models 1.0
+
+import "../commoncomponents"
+import "../constant"
+import "components"
+
+Window {
+    id: wizardViewWindow
+
+    enum Mode {
+        CREATE,
+        IMPORT,
+        MIGRATE,
+        CREATESIP,
+        CONNECTMANAGER
+    }
+
+    enum NameRegistrationState {
+        BLANK,
+        INVALID,
+        TAKEN,
+        FREE,
+        SEARCHING
+    }
+
+    property int layoutWidth: 768
+    property int layoutHeight: 768
+    property int textFontSize: 9
+    property int wizardMode: WizardView.CREATE
+    property int addedAccountIndex: -1
+    property bool registrationStateOk: false
+    property string fileToImport: ""
+    property string registedName: ""
+
+    property var inputParaObject: ({})
+
+    /*
+     * signal to redirect the page to main view
+     */
+    signal needToShowMainViewWindow(int accountIndex)
+    signal wizardViewIsClosed
+
+    title: "Jami"
+    visible: true
+    width: layoutWidth
+    height: layoutHeight
+
+    onClosing: {
+        close.accepted = false
+        changePageQML(controlPanelStackView.welcomePageStackId)
+        wizardViewWindow.hide()
+        wizardViewWindow.wizardViewIsClosed()
+    }
+
+    Component.onCompleted: {
+        changePageQML(
+                    controlPanelStackView.welcomePageStackId)
+    }
+
+    Connections{
+        target: ClientWrapper.accountAdaptor
+
+        function onAccountAdded(showBackUp, index) {
+            addedAccountIndex = index
+            if (showBackUp) {
+                changePageQML(controlPanelStackView.backupKeysPageId)
+            } else {
+                wizardViewWindow.hide()
+                changePageQML(controlPanelStackView.welcomePageStackId)
+                needToShowMainViewWindow(addedAccountIndex)
+                ClientWrapper.lrcInstance.accountListChanged()
+            }
+        }
+
+        // reportFailure
+        function onReportFailure() {
+            reportFailureQML()
+        }
+    }
+
+    Connections {
+        id: registeredNameFoundConnection
+        target: ClientWrapper.nameDirectory
+        enabled: false
+
+        function onRegisteredNameFound(status, address, name) {
+            slotRegisteredNameFound(status, address, name)
+        }
+    }
+
+    // failure redirect timer and qml object holder
+    Timer {
+        id: failureRedirectPageTimer
+
+        repeat: false
+        triggeredOnStart: false
+        interval: 1000
+
+        onTriggered: {
+            spinnerPage.successState = true
+        }
+    }
+
+    function reportFailureQML() {
+        spinnerPage.successState = false
+        failureRedirectPageTimer.restart()
+    }
+
+    function createAccountQML() {
+        switch (wizardMode) {
+        case WizardView.CONNECTMANAGER:
+            ClientWrapper.accountAdaptor.createJAMSAccount(inputParaObject)
+            break
+        case WizardView.CREATE:
+        case WizardView.IMPORT:
+            ClientWrapper.accountAdaptor.createJamiAccount(registedName,
+                                                           inputParaObject,
+                                                           createAccountPage.boothImgBase64,
+                                                           (wizardMode === WizardView.CREATE))
+            break
+        default:
+            ClientWrapper.accountAdaptor.createSIPAccount(inputParaObject,createSIPAccountPage.boothImgBase64)
+        }
+
+        changePageQML(controlPanelStackView.spinnerPageId)
+        update()
+    }
+
+    function slotRegisteredNameFound(status, address, name) {
+        if (name.length < 3) {
+            registrationStateOk = false
+            createAccountPage.nameRegistrationUIState = WizardView.INVALID
+        } else if (registedName === name) {
+            switch (status) {
+            case NameDirectory.LookupStatus.NOT_FOUND:
+            case NameDirectory.LookupStatus.ERROR:
+                registrationStateOk = true
+                createAccountPage.nameRegistrationUIState = WizardView.FREE
+                break
+            case NameDirectory.LookupStatus.INVALID_NAME:
+            case NameDirectory.LookupStatus.INVALID:
+                registrationStateOk = false
+                createAccountPage.nameRegistrationUIState = WizardView.INVALID
+                break
+            case NameDirectory.LookupStatus.SUCCESS:
+                registrationStateOk = false
+                createAccountPage.nameRegistrationUIState = WizardView.TAKEN
+                break
+            }
+        }
+        validateWizardProgressionQML()
+    }
+
+    // function to set up nav bar visibility and the three buttons' visibiliy
+    function setNavBarVisibility(navVisible, back) {
+        navBarView.visible = (navVisible == true) || (back == true)
+        btnNext.visible = (navVisible == true)
+        btnPevious.visible = (navVisible == true)
+        btnBack.visible = (back == true)
+                && (ClientWrapper.utilsAdaptor.getAccountListSize() != 0)
+    }
+
+    function processWizardInformationsQML() {
+        inputParaObject = {}
+        switch (wizardMode) {
+        case WizardView.CREATE:
+            spinnerPage.progressLabelEditText = qsTr(
+                        "Generating your Jami account...")
+            inputParaObject["alias"] = createAccountPage.text_fullNameEditAlias
+
+            inputParaObject["password"] = createAccountPage.text_confirmPasswordEditAlias
+
+            createAccountPage.clearAllTextFields()
+            break
+        case WizardView.IMPORT:
+            registedName = ""
+            spinnerPage.progressLabelEditText = qsTr(
+                        "Importing account archive...")
+            // should only work in import from backup page or import from device page
+            if (controlPanelStackView.currentIndex
+                    == controlPanelStackView.importFromBackupPageId) {
+                inputParaObject["password"]
+                        = importFromBackupPage.text_passwordFromDeviceAlias
+                importFromBackupPage.clearAllTextFields()
+            } else if (controlPanelStackView.currentIndex
+                       == controlPanelStackView.importFromDevicePageId) {
+                inputParaObject["archivePin"] = importFromBackupPage.text_pinFromDeviceAlias
+                inputParaObject["password"]
+                        = importFromDevicePage.text_passwordFromDeviceAlias
+                importFromDevicePage.clearAllTextFields()
+            }
+            break
+        case WizardView.MIGRATE:
+            spinnerPage.progressLabelEditText = qsTr(
+                        "Migrating your Jami account...")
+            break
+        case WizardView.CREATESIP:
+            spinnerPage.progressLabelEditText = qsTr(
+                        "Generating your SIP account...")
+            if (createSIPAccountPage.text_sipFullNameEditAlias.length == 0) {
+                inputParaObject["alias"] = "SIP"
+            } else {
+                inputParaObject["alias"] = createSIPAccountPage.text_sipFullNameEditAlias
+            }
+
+            inputParaObject["hostname"] = createSIPAccountPage.text_sipServernameEditAlias
+            inputParaObject["username"] = createSIPAccountPage.text_sipUsernameEditAlias
+            inputParaObject["password"] = createSIPAccountPage.text_sipPasswordEditAlias
+            inputParaObject["proxy"] = createSIPAccountPage.text_sipProxyEditAlias
+
+            break
+        case WizardView.CONNECTMANAGER:
+            spinnerPage.progressLabelEditText = qsTr(
+                        "Connecting to account manager...")
+            inputParaObject["username"]
+                    = connectToAccountManagerPage.text_usernameManagerEditAlias
+            inputParaObject["password"]
+                    = connectToAccountManagerPage.text_passwordManagerEditAlias
+            inputParaObject["manager"]
+                    = connectToAccountManagerPage.text_accountManagerEditAlias
+            connectToAccountManagerPage.clearAllTextFields()
+            break
+        }
+
+        inputParaObject["archivePath"] = fileToImport
+
+        if (!("archivePin" in inputParaObject)) {
+            inputParaObject["archivePath"] = ""
+        }
+
+        // change page to spinner page
+        changePageQML(controlPanelStackView.spinnerPageId)
+        //create account
+        createAccountQML()
+        ClientWrapper.utilsAdaptor.createStartupLink()
+    }
+
+    function changePageQML(pageIndex) {
+        if (pageIndex == controlPanelStackView.spinnerPageId) {
+            setNavBarVisibility(false)
+        }
+        controlPanelStackView.currentIndex = pageIndex
+        if (pageIndex == controlPanelStackView.welcomePageStackId) {
+            fileToImport = ""
+            setNavBarVisibility(false, true)
+            createAccountPage.nameRegistrationUIState = WizardView.BLANK
+        } else if (pageIndex == controlPanelStackView.createAccountPageId) {
+            createAccountPage.initializeOnShowUp()
+            setNavBarVisibility(true)
+            // connection between register name found and its slot
+            registeredNameFoundConnection.enabled = true
+            // validate wizard progression
+            validateWizardProgressionQML()
+            // start photobooth
+            createAccountPage.startBooth()
+        } else if (pageIndex == controlPanelStackView.createSIPAccountPageId) {
+            createSIPAccountPage.initializeOnShowUp()
+            setNavBarVisibility(true)
+            btnNext.enabled = true
+            // start photo booth
+            createSIPAccountPage.startBooth()
+        } else if (pageIndex == controlPanelStackView.importFromDevicePageId) {
+            importFromDevicePage.initializeOnShowUp()
+            setNavBarVisibility(true)
+        } else if (pageIndex == controlPanelStackView.spinnerPageId) {
+            createAccountPage.nameRegistrationUIState = WizardView.BLANK
+            createAccountPage.isToSetPassword_checkState_choosePasswordCheckBox = false
+        } else if (pageIndex == controlPanelStackView.connectToAccountManagerPageId) {
+            setNavBarVisibility(true)
+            connectToAccountManagerPage.initializeOnShowUp()
+            btnNext.enabled = false
+        } else if (pageIndex == controlPanelStackView.importFromBackupPageId) {
+            setNavBarVisibility(true)
+            importFromBackupPage.clearAllTextFields()
+            fileToImport = ""
+            btnNext.enabled = false
+        } else if (pageIndex == controlPanelStackView.backupKeysPageId) {
+            setNavBarVisibility(false)
+        }
+    }
+
+    function validateWizardProgressionQML() {
+        if (controlPanelStackView.currentIndex
+                == controlPanelStackView.importFromDevicePageId) {
+            var validPin = !(importFromDevicePage.text_pinFromDeviceAlias.length == 0)
+            btnNext.enabled = validPin
+            return
+        } else if (controlPanelStackView.currentIndex
+                   == controlPanelStackView.connectToAccountManagerPageId) {
+            var validUsername = !(connectToAccountManagerPage.text_usernameManagerEditAlias.length == 0)
+            var validPassword = !(connectToAccountManagerPage.text_passwordManagerEditAlias.length == 0)
+            var validManager = !(connectToAccountManagerPage.text_accountManagerEditAlias.length == 0)
+            btnNext.enabled = validUsername && validPassword
+                    && validManager
+            return
+        } else if (controlPanelStackView.currentIndex
+                   == controlPanelStackView.importFromBackupPageId) {
+            var validImport = !(fileToImport.length == 0)
+            btnNext.enabled = validImport
+            return
+        }
+
+        var usernameOk = !createAccountPage.checkState_signUpCheckboxAlias
+                || (createAccountPage.checkState_signUpCheckboxAlias
+                    && !(registedName.length == 0)
+                    && (registedName == createAccountPage.text_usernameEditAlias)
+                    && (registrationStateOk == true))
+        var passwordOk = (createAccountPage.text_passwordEditAlias
+                          == createAccountPage.text_confirmPasswordEditAlias)
+
+        // set password status label
+        if (passwordOk
+                && !(createAccountPage.text_passwordEditAlias.length == 0)) {
+            createAccountPage.displayState_passwordStatusLabelAlias = "Success"
+        } else if (!passwordOk) {
+            createAccountPage.displayState_passwordStatusLabelAlias = "Fail"
+        } else {
+            createAccountPage.displayState_passwordStatusLabelAlias = "Hide"
+        }
+        //set enable state of next button
+        btnNext.enabled = (usernameOk && passwordOk)
+    }
+
+    PasswordDialog {
+        id: passwordDialog
+
+        anchors.centerIn: parent.Center
+        x: (parent.width - width) / 2
+        y: (parent.height - height) / 2
+
+        visible: false
+        purpose: PasswordDialog.ExportAccount
+
+        onDoneSignal: {
+            if (currentPurpose === passwordDialog.ExportAccount) {
+                var success = (code === successCode)
+
+                var title = success ? qsTr("Success") : qsTr("Error")
+                var info = success ? qsTr("Export Successful") : qsTr(
+                                         "Export Failed")
+
+                ClientWrapper.accountAdaptor.passwordSetStatusMessageBox(success,
+                                                         title, info)
+                if (success) {
+                    console.log("Account Export Succeed")
+                    wizardViewWindow.hide()
+                    needToShowMainViewWindow(addedAccountIndex)
+                    ClientWrapper.lrcInstance.accountListChanged()
+                }
+            }
+        }
+    }
+
+    MouseArea {
+            anchors.fill: parent
+            onClicked: forceActiveFocus()
+        }
+
+    // main frame rectangle
+    ScrollView  {
+        id: wizardViewRect
+        anchors.fill: parent
+
+        clip: true
+
+        ColumnLayout {
+                id: content
+                width: wizardViewWindow.width      // ensure correct width
+                height: wizardViewWindow.height     // ensure correct height
+
+                Layout.alignment: Qt.AlignHCenter
+                RowLayout {
+                    Layout.alignment: Qt.AlignHCenter
+                    Layout.fillWidth: true
+                    Layout.fillHeight: true
+
+                    StackLayout {
+                        id: controlPanelStackView
+                        currentIndex: welcomePageStackId
+                        Layout.fillWidth: true
+                        Layout.fillHeight: true
+
+                        property int welcomePageStackId: 0
+                        property int createAccountPageId: 1
+                        property int createSIPAccountPageId: 2
+                        property int importFromBackupPageId: 3
+                        property int backupKeysPageId: 4
+                        property int importFromDevicePageId: 5
+                        property int connectToAccountManagerPageId: 6
+                        property int spinnerPageId: 7
+
+                        WelcomePageLayout {
+                            // welcome page, index 0
+                            id: welcomePage
+
+                            onWelcomePageRedirectPage: {
+                                changePageQML(toPageIndex)
+                            }
+
+                            onVisibleChanged: {
+                                if (visible)
+                                    setNavBarVisibility(false,
+                                                                          true)
+                            }
+
+                            Component.onCompleted: {
+                                setNavBarVisibility(false, true)
+                            }
+                        }
+
+                        CreateAccountPage {
+                            // create account page, index 1
+                            id: createAccountPage
+
+                            onText_usernameEditAliasChanged: {
+                            registrationStateOk = false
+                            if (createAccountPage.checkState_signUpCheckboxAlias
+                                    && (createAccountPage.text_usernameEditAlias.length != 0)) {
+                                registedName = ClientWrapper.utilsAdaptor.stringSimplifier(
+                                            createAccountPage.text_usernameEditAlias)
+                                lookupTimer.restart()
+                                } else {
+                                createAccountPage.nameRegistrationUIState = WizardView.BLANK
+                                lookupTimer.stop()
+                                if (createAccountPage.text_usernameEditAlias.length == 0) {
+                                    lookupTimer.restart()
+                                    }
+                                }
+                                validateWizardProgressionQML()
+                            }
+
+                            onValidateWizardProgressionCreateAccountPage: {
+                                validateWizardProgressionQML()
+                            }
+
+                            onText_passwordEditAliasChanged: {
+                                validateWizardProgressionQML()
+                            }
+
+                            onText_confirmPasswordEditAliasChanged: {
+                                validateWizardProgressionQML()
+                            }
+
+                        Timer {
+                            id: lookupTimer
+
+                            repeat: false
+                            triggeredOnStart: false
+                            interval: 200
+
+                            onTriggered: {
+                                if (createAccountPage.checkState_signUpCheckboxAlias
+                                        && (createAccountPage.text_usernameEditAlias.length != 0)) {
+                                    createAccountPage.nameRegistrationUIState = WizardView.SEARCHING
+                                    ClientWrapper.nameDirectory.lookupName("", registedName)
+                                }
+                            }
+                        }
+                    }
+
+                        CreateSIPAccountPage {
+                            // create SIP account page, index 2
+                            id: createSIPAccountPage
+                        }
+
+                        ImportFromBackupPage {
+                            // import from backup page, index 3
+                            id: importFromBackupPage
+
+                            onText_passwordFromBackupEditAliasChanged: {
+                                validateWizardProgressionQML()
+                            }
+
+                        onImportFromFile_Dialog_Accepted: {
+                            fileToImport = ClientWrapper.utilsAdaptor.toNativeSeparators(fileDir)
+                            inputParaObject[""]
+
+                            if (fileToImport.length != 0) {
+                                importFromBackupPage.fileImportBtnText = ClientWrapper.utilsAdaptor.toFileInfoName(
+                                            fileToImport)
+                            } else {
+                                importFromBackupPage.fileImportBtnText = qsTr(
+                                            "Archive(none)")
+                            }
+                            validateWizardProgressionQML()
+                            }
+                        }
+
+                        BackupKeyPage {
+                            // backup keys page, index 4
+                            id: backupKeysPage
+
+                            onNeverShowAgainBoxClicked: {
+                                ClientWrapper.accountAdaptor.settingsNeverShowAgain(isChecked)
+                            }
+
+                            onExport_Btn_FileDialogAccepted: {
+                                if (accepted) {
+                                    // is there password? If so, go to password dialog, else, go to following directly
+                                    if (ClientWrapper.accountAdaptor.hasPassword()) {
+                                        passwordDialog.path = ClientWrapper.utilsAdaptor.getAbsPath(folderDir)
+                                        passwordDialog.open()
+                                        return
+                                    } else {
+                                        if (folderDir.length > 0) {
+                                            ClientWrapper.accountAdaptor.exportToFile(
+                                                        ClientWrapper.utilsAdaptor.getCurrAccId(),
+                                                        ClientWrapper.utilsAdaptor.getAbsPath(folderDir))
+                                        }
+                                    }
+                                }
+
+                                wizardViewWindow.hide()
+                                changePageQML(controlPanelStackView.welcomePageStackId)
+                                needToShowMainViewWindow(addedAccountIndex)
+                                ClientWrapper.lrcInstance.accountListChanged()
+                            }
+
+
+                            onSkip_Btn_Clicked: {
+                                wizardViewWindow.hide()
+                                changePageQML(controlPanelStackView.welcomePageStackId)
+                                needToShowMainViewWindow(addedAccountIndex)
+                                ClientWrapper.lrcInstance.accountListChanged()
+                            }
+                    }
+
+                        ImportFromDevicePage {
+                            // import from device page, index 5
+                            id: importFromDevicePage
+
+                            onText_pinFromDeviceAliasChanged: {
+                                validateWizardProgressionQML()
+                            }
+
+                            onText_passwordFromDeviceAliasChanged: {
+                                validateWizardProgressionQML()
+                            }
+                        }
+
+                        ConnectToAccountManagerPage {
+                            // connect to account manager Page, index 6
+                            id: connectToAccountManagerPage
+
+                            onText_usernameManagerEditAliasChanged: {
+                                validateWizardProgressionQML()
+                            }
+
+                            onText_passwordManagerEditAliasChanged: {
+                                validateWizardProgressionQML()
+                            }
+
+                            onText_accountManagerEditAliasChanged: {
+                                validateWizardProgressionQML()
+                            }
+                        }
+
+                        SpinnerPage {
+                            // spinner Page, index 7
+                            id: spinnerPage
+                        }
+                    }
+                }
+
+                RowLayout {
+                    id: navBarView
+
+                    Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
+                    Layout.fillWidth: true
+
+                    Layout.maximumHeight: 52
+                    Layout.preferredHeight: 52
+
+                    HoverableGradientButton {
+                        id: btnPevious
+                        Layout.alignment: Qt.AlignLeft
+                        width: 85
+                        height: 30
+                        radius: height / 2
+
+                        Layout.leftMargin: 11
+
+                        Layout.preferredWidth: 85
+                        Layout.preferredHeight: 30
+                        text: qsTr("Previous")
+                        font.pointSize: 10
+                        font.kerning: true
+
+                        onClicked: {
+                            // stop photobooth previewing
+                            if(controlPanelStackView.currentIndex == controlPanelStackView.createAccountPageId) {
+                                createAccountPage.stopBooth()
+                            }
+                            if(controlPanelStackView.currentIndex == controlPanelStackView.createSIPAccountPageId) {
+                                createSIPAccountPage.stopBooth()
+                            }
+
+                            // Disconnect registered name found Connection
+                            registeredNameFoundConnection.enabled = false
+                            // deal with look up status label and collapsible password widget
+                            createAccountPage.nameRegistrationUIState = WizardView.BLANK
+                            createAccountPage.isToSetPassword_checkState_choosePasswordCheckBox = false
+                            // switch to welcome page
+                            if (controlPanelStackView.currentIndex
+                                    == controlPanelStackView.createAccountPageId
+                                    || controlPanelStackView.currentIndex
+                                    == controlPanelStackView.createSIPAccountPageId
+                                    || controlPanelStackView.currentIndex
+                                    == controlPanelStackView.importFromBackupPageId
+                                    || controlPanelStackView.currentIndex
+                                    == controlPanelStackView.importFromDevicePageId
+                                    || controlPanelStackView.currentIndex
+                                    == controlPanelStackView.connectToAccountManagerPageId) {
+                                changePageQML(
+                                            controlPanelStackView.welcomePageStackId)
+                            }
+                        }
+                    }
+
+                    Item {
+                        Layout.alignment: Qt.AlignHCenter
+                        Layout.fillHeight: true
+                        Layout.minimumWidth: 40
+                        Layout.fillWidth: true
+                    }
+
+                    HoverableGradientButton {
+                        id: btnBack
+                        Layout.alignment: Qt.AlignLeft
+                        width: 85
+                        height: 30
+                        radius: height / 2
+
+                        Layout.preferredWidth: 85
+                        Layout.preferredHeight: 30
+                        text: qsTr("Back")
+                        font.pointSize: 10
+                        font.kerning: true
+
+                        onClicked: {
+                            wizardViewWindow.hide()
+                            needToShowMainViewWindow(addedAccountIndex)
+                        }
+                    }
+
+                    Item {
+                        Layout.alignment: Qt.AlignHCenter
+                        Layout.fillHeight: true
+                        Layout.minimumWidth: 40
+                        Layout.fillWidth: true
+                    }
+
+                    HoverableGradientButton {
+                        id: btnNext
+                        Layout.alignment: Qt.AlignRight
+                        width: 85
+                        height: 30
+                        radius: height / 2
+
+                        Layout.rightMargin: 11
+
+                        Layout.minimumWidth: 85
+                        Layout.preferredWidth: 85
+                        Layout.maximumWidth: 85
+
+                        Layout.minimumHeight: 30
+                        Layout.preferredHeight: 30
+                        Layout.maximumHeight: 30
+
+                        text: qsTr("Next")
+                        font.pointSize: 10
+                        font.kerning: true
+
+                        onClicked: {
+                            // stop photobooth previewing
+                            if(controlPanelStackView.currentIndex == controlPanelStackView.createAccountPageId) {
+                                createAccountPage.stopBooth()
+                            }
+                            if(controlPanelStackView.currentIndex == controlPanelStackView.createSIPAccountPageId) {
+                                createSIPAccountPage.stopBooth()
+                            }
+
+                            registeredNameFoundConnection.enabled = false
+
+                            if (controlPanelStackView.currentIndex
+                                    == controlPanelStackView.createAccountPageId) {
+                                wizardMode = WizardView.CREATE
+                                processWizardInformationsQML()
+                            } else if (controlPanelStackView.currentIndex
+                                       == controlPanelStackView.importFromDevicePageId) {
+                                wizardMode = WizardView.IMPORT
+                                processWizardInformationsQML()
+                            } else if (controlPanelStackView.currentIndex
+                                       == controlPanelStackView.createSIPAccountPageId) {
+                                wizardMode = WizardView.CREATESIP
+                                processWizardInformationsQML()
+                            } else if (controlPanelStackView.currentIndex
+                                       == controlPanelStackView.connectToAccountManagerPageId) {
+                                wizardMode = WizardView.CONNECTMANAGER
+                                processWizardInformationsQML()
+                            } else if (controlPanelStackView.currentIndex
+                                       == controlPanelStackView.importFromBackupPageId) {
+                                wizardMode = WizardView.IMPORT
+                                processWizardInformationsQML()
+                            }
+                        }
+                    }
+                }
+            }
+    }
+}
diff --git a/src/wizardview/components/BackupKeyPage.qml b/src/wizardview/components/BackupKeyPage.qml
new file mode 100644
index 0000000..59ec3ef
--- /dev/null
+++ b/src/wizardview/components/BackupKeyPage.qml
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+import Qt.labs.platform 1.1
+
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+    signal neverShowAgainBoxClicked(bool isChecked)
+    signal skip_Btn_Clicked
+    signal export_Btn_FileDialogAccepted(bool accepted, string folderDir)
+
+    /*
+     * JamiFileDialog for exporting account
+     */
+    JamiFileDialog {
+        id: exportBtn_Dialog
+
+        mode: JamiFileDialog.SaveFile
+
+        title: qsTr("Export Account Here")
+        folder: StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/Desktop"
+
+        nameFilters: [qsTr("Jami archive files") + " (*.gz)", qsTr(
+                "All files") + " (*)"]
+
+        onAccepted: {
+            export_Btn_FileDialogAccepted(true, file)
+        }
+
+        onRejected: {
+            export_Btn_FileDialogAccepted(false, folder)
+        }
+
+        onVisibleChanged: {
+            if (!visible) {
+                rejected()
+            }
+        }
+    }
+
+    Layout.fillWidth: true
+    Layout.fillHeight: true
+
+    Item {
+        Layout.alignment: Qt.AlignHCenter
+        Layout.fillWidth: true
+        Layout.fillHeight: true
+    }
+
+    /*
+     * Main layout for BackupKeyPage which consists of the buttons and "never show again" check box
+     */
+    ColumnLayout {
+        Layout.alignment: Qt.AlignCenter
+        Layout.maximumWidth: 366
+
+        spacing: 12
+
+        Label {
+            id: backupKeysLabel
+            Layout.alignment: Qt.AlignHCenter
+
+            Layout.maximumWidth: 366
+            Layout.maximumHeight: 21
+            Layout.preferredWidth: 366
+            Layout.preferredHeight: 21
+
+            text: qsTr("Backup your account")
+            font.pointSize: 13
+            font.kerning: true
+        }
+        Label {
+            id: backupInfoLabel1
+            Layout.maximumWidth: 366
+            Layout.maximumHeight: 57
+            Layout.preferredWidth: 366
+            Layout.preferredHeight: 57
+
+            text: qsTr("This account only exists on this device. If you lost your device or uninstall the application,your account will be deleted. You can backup your account now or later.")
+            wrapMode: Text.WordWrap
+            horizontalAlignment: Text.AlignJustify
+            verticalAlignment: Text.AlignVCenter
+        }
+        CheckBox {
+            id: neverShowAgainBox
+            checked: false
+
+            Layout.maximumWidth: 366
+            Layout.maximumHeight: 19
+            Layout.preferredWidth: 366
+            Layout.preferredHeight: 19
+
+            indicator.implicitWidth: 10
+            indicator.implicitHeight:10
+
+            text: qsTr("Never show me this again")
+            font.pointSize: 8
+
+            onClicked: {
+                neverShowAgainBoxClicked(checked)
+            }
+        }
+        RowLayout {
+            Layout.fillWidth: true
+            Layout.maximumHeight: 20
+
+            Item {
+                Layout.alignment: Qt.AlignVCenter
+                Layout.fillHeight: true
+                Layout.maximumWidth: 40
+                Layout.minimumWidth: 10
+            }
+
+            HoverableGradientButton {
+                id: exportBtn
+
+                Layout.alignment: Qt.AlignVCenter
+                Layout.minimumWidth: 85
+                Layout.preferredWidth: 85
+                Layout.maximumWidth: 85
+
+                Layout.minimumHeight: 30
+                Layout.preferredHeight: 30
+                Layout.maximumHeight: 30
+
+                text: qsTr("Export")
+                font.kerning: true
+                fontPointSize: 10
+                radius: height / 2
+                backgroundColor: JamiTheme.releaseColor
+
+                onClicked: {
+                    exportBtn_Dialog.open()
+                }
+            }
+
+            Item {
+                Layout.alignment: Qt.AlignVCenter
+                Layout.fillWidth: true
+                Layout.fillHeight: true
+            }
+
+            HoverableGradientButton {
+                id: skipBtn
+
+                Layout.alignment: Qt.AlignVCenter
+                Layout.minimumWidth: 85
+                Layout.preferredWidth: 85
+                Layout.maximumWidth: 85
+
+                Layout.minimumHeight: 30
+                Layout.preferredHeight: 30
+                Layout.maximumHeight: 30
+
+                text: qsTr("Skip")
+                fontPointSize: 10
+                font.kerning: true
+                radius: height / 2
+                backgroundColor: JamiTheme.releaseColor
+
+                onClicked: {
+                    skip_Btn_Clicked()
+                }
+            }
+
+            Item {
+                Layout.alignment: Qt.AlignVCenter
+                Layout.fillHeight: true
+                Layout.maximumWidth: 40
+                Layout.minimumWidth: 10
+            }
+        }
+    }
+
+    Item {
+        Layout.alignment: Qt.AlignHCenter
+        Layout.fillWidth: true
+        Layout.fillHeight: true
+    }
+}
diff --git a/src/wizardview/components/CollapsiblePasswordWidget.qml b/src/wizardview/components/CollapsiblePasswordWidget.qml
new file mode 100644
index 0000000..82af6e2
--- /dev/null
+++ b/src/wizardview/components/CollapsiblePasswordWidget.qml
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../../constant"
+import "../../commoncomponents"
+
+/*
+ * an independent widget that keeps the password's textfields, including password field and confirm password field
+ */
+
+GridLayout {
+    id: root
+
+    property alias text_passwordEditAlias: passwordEdit.text
+    property alias text_confirmPasswordEditAlias: confirmPasswordEdit.text
+    property alias state_passwordStatusLabelAlias: passwordStatusLabel.passwordStatusState
+
+    property bool visibleCollapsble: false
+
+    function clearAllTextFields() {
+        passwordEdit.clear()
+        confirmPasswordEdit.clear()
+    }
+
+    visible: visibleCollapsble
+    Layout.fillWidth: true
+    rowSpacing: 6
+    columnSpacing: 6
+
+    rows: 2
+    columns: 2
+
+    Layout.leftMargin: 32
+
+    InfoLineEdit {
+        id: passwordEdit
+
+        visible: visibleCollapsble
+
+        Layout.row: 0
+        Layout.column: 0
+
+        fieldLayoutWidth: 261
+
+        Layout.alignment: Qt.AlignHCenter
+
+        selectByMouse: true
+        echoMode: TextInput.Password
+        placeholderText: qsTr("Password")
+        font.pointSize: 10
+        font.kerning: true
+    }
+
+    Item {
+        Layout.row: 0
+        Layout.column: 1
+
+        Layout.maximumWidth: 32
+        Layout.preferredWidth: 32
+        Layout.minimumWidth: 32
+
+        Layout.maximumHeight: 30
+        Layout.preferredHeight: 30
+        Layout.minimumHeight: 30
+    }
+
+    InfoLineEdit {
+        id: confirmPasswordEdit
+
+        visible: visibleCollapsble
+
+        Layout.row: 1
+        Layout.column: 0
+
+        fieldLayoutWidth: 261
+
+        Layout.alignment: Qt.AlignHCenter
+
+        selectByMouse: true
+        echoMode: TextInput.Password
+        placeholderText: qsTr("Confirm Password")
+        font.pointSize: 10
+        font.kerning: true
+    }
+
+    Label {
+        id: passwordStatusLabel
+
+        visible: visibleCollapsble
+
+        Layout.row: 1
+        Layout.column: 1
+
+        Layout.maximumWidth: 32
+        Layout.preferredWidth: 32
+        Layout.minimumWidth: 32
+
+        Layout.maximumHeight: 30
+        Layout.preferredHeight: 30
+        Layout.minimumHeight: 30
+
+        Layout.alignment: Qt.AlignRight
+
+        property string passwordStatusState: "Hide"
+
+        background: {
+            switch (passwordStatusState) {
+            case "Hide":
+                return Qt.createQmlObject("import QtQuick 2.14;
+import \"qrc:/src/constant/\";
+Rectangle {
+anchors.fill: parent;
+color: \"transparent\"; }", passwordStatusLabel)
+            case "Fail":
+                return Qt.createQmlObject("import QtQuick 2.14;
+import \"qrc:/src/constant/\";
+Rectangle {
+anchors.fill: parent;
+Image{
+anchors.fill: parent;
+source: \"image://tintedPixmap/\"+ (\"qrc:/images/icons/baseline-close-24px.svg\").replace(\"qrc:/images/icons/\",\"\") + \"+\" + JamiTheme.red_;
+mipmap: true;}
+}", passwordStatusLabel)
+            case "Success":
+                return Qt.createQmlObject("import QtQuick 2.14;
+import \"qrc:/src/constant/\";
+Rectangle {
+anchors.fill: parent;
+Image {
+anchors.fill: parent;
+source: \"image://tintedPixmap/\"+ (\"qrc:/images/icons/baseline-done-24px.svg\").replace(\"qrc:/images/icons/\",\"\") + \"+\" + JamiTheme.presenceGreen_;
+mipmap: true;}
+}", passwordStatusLabel)
+            }
+        }
+    }
+}
diff --git a/src/wizardview/components/ConnectToAccountManagerPage.qml b/src/wizardview/components/ConnectToAccountManagerPage.qml
new file mode 100644
index 0000000..c41dcef
--- /dev/null
+++ b/src/wizardview/components/ConnectToAccountManagerPage.qml
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+    property alias text_usernameManagerEditAlias: usernameManagerEdit.text
+    property alias text_passwordManagerEditAlias: passwordManagerEdit.text
+    property alias text_accountManagerEditAlias: accountManagerEdit.text
+
+    function initializeOnShowUp() {
+        clearAllTextFields()
+    }
+
+    function clearAllTextFields() {
+        usernameManagerEdit.clear()
+        passwordManagerEdit.clear()
+        accountManagerEdit.clear()
+    }
+
+    Layout.fillWidth: true
+    Layout.fillHeight: true
+
+    Item {
+        Layout.alignment: Qt.AlignHCenter
+        Layout.preferredHeight: 40
+        Layout.fillWidth: true
+        Layout.fillHeight: true
+    }
+
+    ColumnLayout {
+        Layout.alignment: Qt.AlignCenter
+        Layout.fillWidth: true
+
+        spacing: 12
+
+        Label {
+            id: signInLabel
+
+            Layout.alignment: Qt.AlignHCenter
+            Layout.minimumWidth: 256
+            Layout.preferredHeight: 21
+            text: qsTr("Sign in")
+            font.pointSize: 13
+            font.kerning: true
+        }
+
+        InfoLineEdit {
+            id: usernameManagerEdit
+
+            Layout.alignment: Qt.AlignHCenter
+
+            selectByMouse: true
+            placeholderText: qsTr("Username")
+        }
+
+        InfoLineEdit {
+            id: passwordManagerEdit
+
+            Layout.alignment: Qt.AlignHCenter
+            selectByMouse: true
+            echoMode: TextInput.Password
+            placeholderText: qsTr("Password")
+        }
+
+        InfoLineEdit {
+            id: accountManagerEdit
+
+            Layout.alignment: Qt.AlignHCenter
+
+            selectByMouse: true
+            placeholderText: qsTr("Account Manager")
+        }
+    }
+
+    Item {
+        Layout.alignment: Qt.AlignHCenter
+        Layout.preferredHeight: 40
+        Layout.fillWidth: true
+        Layout.fillHeight: true
+    }
+}
diff --git a/src/wizardview/components/CreateAccountPage.qml b/src/wizardview/components/CreateAccountPage.qml
new file mode 100644
index 0000000..f59b2c6
--- /dev/null
+++ b/src/wizardview/components/CreateAccountPage.qml
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../"
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+    property alias text_fullNameEditAlias: fullNameEdit.text
+    property alias text_usernameEditAlias: usernameEdit.text
+
+    property int nameRegistrationUIState: WizardView.BLANK
+
+    property alias checkState_signUpCheckboxAlias: signUpCheckbox.checked
+    property alias isToSetPassword_checkState_choosePasswordCheckBox: choosePasswordCheckBox.checked
+
+    // photo booth alias
+    property alias boothImgBase64: setAvatarWidget.imgBase64
+
+    // collapse password widget property aliases
+    property alias text_passwordEditAlias: collapsiblePasswordWidget.text_passwordEditAlias
+    property alias text_confirmPasswordEditAlias: collapsiblePasswordWidget.text_confirmPasswordEditAlias
+    property alias displayState_passwordStatusLabelAlias: collapsiblePasswordWidget.state_passwordStatusLabelAlias
+
+    signal validateWizardProgressionCreateAccountPage
+
+    function initializeOnShowUp() {
+        clearAllTextFields()
+
+        signUpCheckbox.checked = true
+        choosePasswordCheckBox.checked = false
+        usernameEdit.enabled = true
+        fullNameEdit.enabled = true
+    }
+
+    function clearAllTextFields() {
+        usernameEdit.clear()
+        fullNameEdit.clear()
+
+        collapsiblePasswordWidget.clearAllTextFields()
+    }
+
+    function setCollapsiblePasswordWidgetVisibility(visible) {
+        choosePasswordCheckBox.checked = visible
+        if (visible) {
+            choosePasswordCheckBox.visible = true
+        }
+    }
+
+    function startBooth(){
+        setAvatarWidget.startBooth()
+    }
+
+    function stopBooth(){
+        setAvatarWidget.stopBooth()
+    }
+
+    Layout.fillWidth: true
+    Layout.fillHeight: true
+
+    spacing: 6
+
+    Item {
+        Layout.fillHeight: true
+        Layout.fillWidth: true
+    }
+
+    ColumnLayout {
+        Layout.alignment: Qt.AlignHCenter
+
+        spacing: 5
+
+        ColumnLayout {
+            Layout.fillWidth: true
+            spacing: 6
+
+            Layout.alignment: Qt.AlignHCenter
+
+        Label {
+            id: profileSectionLabel
+
+
+            Layout.alignment: Qt.AlignHCenter
+
+            text: qsTr("Profile")
+            font.pointSize: 13
+            font.kerning: true
+
+            horizontalAlignment: Text.AlignHCenter
+            verticalAlignment: Text.AlignVCenter
+        }
+
+    PhotoboothView{
+        id: setAvatarWidget
+
+        Layout.alignment: Qt.AlignHCenter
+
+        Layout.maximumWidth: 261
+        Layout.preferredWidth: 261
+        Layout.minimumWidth: 261
+        Layout.maximumHeight: 261
+        Layout.preferredHeight: 261
+        Layout.minimumHeight: 261
+    }
+
+        RowLayout {
+            spacing: 6
+            Layout.alignment: Qt.AlignHCenter
+            Layout.maximumHeight: 30
+
+            Item {
+                Layout.fillWidth: true
+                Layout.maximumHeight: 10
+            }
+
+            InfoLineEdit {
+                id: fullNameEdit
+
+                fieldLayoutWidth: 261
+
+                Layout.alignment: Qt.AlignCenter
+
+                selectByMouse: true
+                placeholderText: qsTr("Profile name")
+                font.pointSize: 10
+                font.kerning: true
+            }
+
+            Item {
+                Layout.fillHeight: true
+                Layout.fillWidth: true
+            }
+        }
+        }
+    }
+
+    Item {
+        Layout.fillHeight: true
+        Layout.fillWidth: true
+    }
+
+    ColumnLayout {
+        Layout.alignment: Qt.AlignHCenter
+
+        spacing: 5
+        Label {
+            id: accountSectionLabel
+            Layout.alignment: Qt.AlignHCenter
+
+            Layout.maximumWidth: 261
+            Layout.preferredWidth: 261
+            Layout.minimumWidth: 261
+            Layout.maximumHeight: 30
+            Layout.preferredHeight: 30
+            Layout.minimumHeight: 30
+
+            text: qsTr("Account")
+            font.pointSize: 13
+            font.kerning: true
+
+            horizontalAlignment: Text.AlignHCenter
+            verticalAlignment: Text.AlignVCenter
+        }
+
+        ColumnLayout {
+            Layout.fillWidth: true
+            spacing: 6
+
+            CheckBox {
+                id: signUpCheckbox
+                checked: true
+
+                indicator.width: 10
+                indicator.height: 10
+
+                Layout.leftMargin: 32
+
+                Layout.minimumWidth: 261
+
+                Layout.maximumHeight: 30
+                Layout.preferredHeight: 30
+                Layout.minimumHeight: 25
+
+                Layout.alignment: Qt.AlignLeft
+
+                text: qsTr("Register public username")
+                font.pointSize: 10
+                font.kerning: true
+
+                indicator.implicitWidth: 20
+                indicator.implicitHeight:20
+
+                onClicked: {
+                    if (!checked) {
+                        usernameEdit.clear()
+                    }
+
+                    validateWizardProgressionCreateAccountPage()
+                }
+            }
+        }
+
+        RowLayout {
+            spacing: 6
+            Layout.fillWidth: true
+
+            Layout.leftMargin: 32
+
+            InfoLineEdit {
+                id: usernameEdit
+
+                fieldLayoutWidth: 261
+
+                Layout.alignment: Qt.AlignHCenter
+
+                selectByMouse: true
+                placeholderText: qsTr("Choose your username")
+                font.pointSize: 10
+                font.kerning: true
+
+                enabled: signUpCheckbox.visible && signUpCheckbox.checked
+            }
+
+            LookupStatusLabel{
+                id: lookupStatusLabel
+
+                visible: true
+
+                lookupStatusState: {
+                    switch (nameRegistrationUIState) {
+                    case WizardView.BLANK:
+                        return "Blank"
+                    case WizardView.INVALID:
+                        return "Invalid"
+                    case WizardView.TAKEN:
+                        return "Taken"
+                    case WizardView.FREE:
+                        return "Free"
+                    case WizardView.SEARCHING:
+                        return "Searching"
+                    default:
+                        return "Blank"
+                    }
+                }
+            }
+        }
+
+        ColumnLayout {
+            Layout.fillWidth: true
+            spacing: 6
+
+            CheckBox {
+                id: choosePasswordCheckBox
+                checked: false
+
+                indicator.width: 10
+                indicator.height: 10
+
+                Layout.leftMargin: 32
+
+                Layout.minimumWidth: 261
+
+                Layout.preferredHeight: 30
+                Layout.minimumHeight: 25
+
+                indicator.implicitWidth: 20
+                indicator.implicitHeight:20
+
+                Layout.alignment: Qt.AlignLeft
+
+                text: qsTr("Choose a password for enhanced security")
+                font.pointSize: 8
+                font.kerning: true
+
+                onClicked: {
+                    if (!checked) {
+                        collapsiblePasswordWidget.clearAllTextFields()
+                    }
+
+                    validateWizardProgressionCreateAccountPage()
+                }
+            }
+
+            CollapsiblePasswordWidget {
+                id: collapsiblePasswordWidget
+
+                Layout.alignment: Qt.AlignHCenter
+
+                visibleCollapsble: choosePasswordCheckBox.checked
+                                   && choosePasswordCheckBox.visible
+            }
+        }
+
+        Item {
+            Layout.maximumWidth: 261
+            Layout.preferredWidth: 261
+            Layout.minimumWidth: 261
+
+            Layout.maximumHeight: 30
+            Layout.preferredHeight: 30
+            Layout.minimumHeight: 30
+
+            Layout.alignment: Qt.AlignHCenter
+        }
+    }
+}
diff --git a/src/wizardview/components/CreateSIPAccountPage.qml b/src/wizardview/components/CreateSIPAccountPage.qml
new file mode 100644
index 0000000..3f3da17
--- /dev/null
+++ b/src/wizardview/components/CreateSIPAccountPage.qml
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+    property alias text_sipFullNameEditAlias: sipFullNameEdit.text
+    property alias text_sipServernameEditAlias: sipServernameEdit.text
+    property alias text_sipProxyEditAlias: sipProxyEdit.text
+    property alias text_sipUsernameEditAlias: sipUsernameEdit.text
+    property alias text_sipPasswordEditAlias: sipPasswordEdit.text
+
+    property alias boothImgBase64: setSIPAvatarWidget.imgBase64
+
+    function initializeOnShowUp() {
+        clearAllTextFields()
+    }
+
+    function clearAllTextFields() {
+        sipUsernameEdit.clear()
+        sipPasswordEdit.clear()
+        sipServernameEdit.clear()
+        sipProxyEdit.clear()
+        sipFullNameEdit.clear()
+        sipUsernameEdit.clear()
+    }
+
+    function startBooth(){
+        setSIPAvatarWidget.startBooth()
+    }
+
+    function stopBooth(){
+        setSIPAvatarWidget.stopBooth()
+    }
+
+    Layout.fillWidth: true
+    Layout.fillHeight: true
+
+    spacing: 6
+
+    Item {
+        Layout.fillHeight: true
+        Layout.fillWidth: true
+    }
+
+    Label {
+        id: sipProfileSectionLabel
+
+        Layout.maximumWidth: 368
+        Layout.preferredWidth: 368
+        Layout.maximumHeight: 21
+        Layout.preferredHeight: 21
+
+        Layout.alignment: Qt.AlignHCenter
+
+        text: qsTr("Profile")
+        font.pointSize: 13
+        font.kerning: true
+
+        horizontalAlignment: Text.AlignHCenter
+        verticalAlignment: Text.AlignVCenter
+    }
+
+    PhotoboothView{
+        id: setSIPAvatarWidget
+
+        Layout.alignment: Qt.AlignHCenter
+
+        Layout.maximumWidth: 261
+        Layout.preferredWidth: 261
+        Layout.minimumWidth: 261
+        Layout.maximumHeight: 261
+        Layout.preferredHeight: 261
+        Layout.minimumHeight: 261
+    }
+
+    RowLayout {
+        spacing: 0
+        Layout.alignment: Qt.AlignHCenter
+        Layout.maximumHeight: 30
+
+        Item {
+            Layout.fillWidth: true
+            Layout.maximumHeight: 10
+        }
+
+        InfoLineEdit {
+            id: sipFullNameEdit
+
+            fieldLayoutWidth : 261
+            Layout.alignment: Qt.AlignCenter
+            selectByMouse: true
+            placeholderText: qsTr("Profile name")
+            font.pointSize: 10
+            font.kerning: true
+        }
+
+        Item {
+            Layout.fillHeight: true
+            Layout.fillWidth: true
+        }
+    }
+    Item {
+        Layout.fillHeight: true
+        Layout.fillWidth: true
+    }
+
+    Label {
+        id: sipAccountSectionLabel
+        Layout.maximumWidth: 368
+        Layout.preferredWidth: 368
+        Layout.maximumHeight: 21
+        Layout.preferredHeight: 21
+
+        Layout.alignment: Qt.AlignHCenter
+
+        text: qsTr("SIP Account")
+        font.pointSize: 12
+        font.kerning: true
+
+        horizontalAlignment: Text.AlignHCenter
+        verticalAlignment: Text.AlignVCenter
+    }
+
+    ColumnLayout {
+        Layout.alignment: Qt.AlignHCenter
+        spacing: 7
+
+        Item {
+            Layout.fillWidth: true
+            Layout.alignment: Qt.AlignHCenter
+            Layout.maximumHeight: 40
+            Layout.minimumHeight: 30
+            Layout.preferredHeight: 40
+        }
+
+        InfoLineEdit {
+            id: sipServernameEdit
+            Layout.alignment: Qt.AlignHCenter
+            fieldLayoutWidth: 261
+
+            selectByMouse: true
+            placeholderText: qsTr("Server")
+            font.pointSize: 10
+            font.kerning: true
+        }
+
+        InfoLineEdit {
+            id: sipProxyEdit
+            Layout.alignment: Qt.AlignHCenter
+            fieldLayoutWidth: 261
+
+            selectByMouse: true
+            placeholderText: qsTr("Proxy")
+            font.pointSize: 10
+            font.kerning: true
+        }
+
+        InfoLineEdit {
+            id: sipUsernameEdit
+            Layout.alignment: Qt.AlignHCenter
+            fieldLayoutWidth: 261
+
+            selectByMouse: true
+            placeholderText: qsTr("Username")
+            font.pointSize: 10
+            font.kerning: true
+        }
+
+        InfoLineEdit {
+            id: sipPasswordEdit
+            Layout.alignment: Qt.AlignHCenter
+            fieldLayoutWidth: 261
+
+            selectByMouse: true
+            echoMode: TextInput.Password
+            placeholderText: qsTr("Password")
+            font.pointSize: 10
+            font.kerning: true
+        }
+    }
+}
diff --git a/src/wizardview/components/HoverableGradientButton.qml b/src/wizardview/components/HoverableGradientButton.qml
new file mode 100644
index 0000000..905bd41
--- /dev/null
+++ b/src/wizardview/components/HoverableGradientButton.qml
@@ -0,0 +1,142 @@
+
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.15
+import QtQuick.Controls 2.14
+import QtGraphicalEffects 1.15
+import net.jami.Models 1.0
+
+
+/*
+ * HoverableButton contains the following configurable properties:
+ * 1. Color changes on different button state
+ * 2. Radius control (rounded)
+ * 3. Text content or image content
+ * 4. Can use OnClicked slot to implement some click logic
+ */
+Button {
+    id: hoverableButton
+    property int fontPointSize: 9
+    property string backgroundColor: JamiTheme.releaseColor
+    property string backgroundColorDisabled : Qt.rgba(242/256, 242/256, 242/256, 0.8)
+
+    property string startColor :"#109ede"
+    property string endColor : "#2b5084"
+
+    property string startColorPressed :"#043161"
+    property string endColorPressed : "#00113f"
+
+    property string startColorHovered :"#2b4b7e"
+    property string endColorHovered : "#001d4d"
+
+    property string onPressColor: JamiTheme.pressColor
+    property string onReleaseColor: backgroundColor
+    property string onEnterColor: JamiTheme.hoverColor
+    property string onExitColor: backgroundColor
+    property string textColor: "white"
+
+    property alias radius: hoverableButtonBackground.radius
+
+    property bool isHovering: false
+    property bool isBeingPressed: false
+
+    radius: height / 2
+    font.pointSize: fontPointSize
+    font.kerning:  true
+    hoverEnabled: true
+
+    contentItem: Text {
+            text: hoverableButton.text
+            font: hoverableButton.font
+            opacity: enabled ? 1.0 : 0.3
+            color: enabled? textColor : "grey"
+            horizontalAlignment: Text.AlignHCenter
+            verticalAlignment: Text.AlignVCenter
+            elide: Text.ElideRight
+        }
+
+    background: Rectangle {
+        id: hoverableButtonBackground
+        color: backgroundColor
+
+        MouseArea {
+            id: btnMouseArea
+            anchors.fill: hoverableButtonBackground
+            hoverEnabled: true
+            onPressed: {
+                hoverableButtonBackground.color = onPressColor
+                isBeingPressed = true
+            }
+            onReleased: {
+                hoverableButtonBackground.color = onReleaseColor
+                isBeingPressed = false
+                hoverableButton.clicked()
+            }
+            onEntered: {
+                hoverableButtonBackground.color = onEnterColor
+                isHovering = true
+            }
+            onExited: {
+                hoverableButtonBackground.color = onExitColor
+                isHovering = false
+            }
+        }
+    }
+
+    LinearGradient {
+        id: backgroundGradient
+
+        source: hoverableButtonBackground
+        anchors.fill: hoverableButtonBackground
+        start: Qt.point(0, 0)
+        end: Qt.point(width, 0)
+        gradient: Gradient {
+            GradientStop { position: 0.0; color: {
+                    if(!hoverableButton.enabled){
+                        return backgroundColorDisabled
+                    }
+
+                if(isBeingPressed){
+                    return startColorPressed
+                } else {
+                    if(isHovering){
+                        return startColorHovered
+                    } else {
+                        return startColor
+                    }
+                }
+                } }
+
+            GradientStop { position: 1.0; color: {
+                    if(!hoverableButton.enabled){
+                        return backgroundColorDisabled
+                    }
+
+                    if(isBeingPressed){
+                        return endColorPressed
+                    } else {
+                        if(isHovering){
+                            return endColorHovered
+                        } else {
+                            return endColor
+                        }
+                    }
+                    } }
+        }
+    }
+}
diff --git a/src/wizardview/components/ImportFromBackupPage.qml b/src/wizardview/components/ImportFromBackupPage.qml
new file mode 100644
index 0000000..bd7d26e
--- /dev/null
+++ b/src/wizardview/components/ImportFromBackupPage.qml
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+import Qt.labs.platform 1.1
+
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+    property alias text_passwordFromBackupEditAlias: passwordFromBackupEdit.text
+    property string fileImportBtnText: qsTr("Archive(none)")
+
+    signal importFromFile_Dialog_Accepted(string fileDir)
+
+    function clearAllTextFields() {
+        passwordFromBackupEdit.clear()
+        fileImportBtnText = qsTr("Archive(none)")
+    }
+
+    JamiFileDialog {
+        id: importFromFile_Dialog
+
+        mode: JamiFileDialog.OpenFile
+        title: qsTr("Open File")
+        folder: StandardPaths.writableLocation(StandardPaths.HomeLocation) + "/Desktop"
+
+        nameFilters: [qsTr("Jami archive files") + " (*.gz)", qsTr(
+                "All files") + " (*)"]
+
+        onAccepted: {
+            importFromFile_Dialog_Accepted(file)
+        }
+    }
+
+    Layout.fillWidth: true
+    Layout.fillHeight: true
+
+    Item {
+        Layout.alignment: Qt.AlignHCenter
+        Layout.fillWidth: true
+        Layout.fillHeight: true
+    }
+
+    ColumnLayout {
+        Layout.alignment: Qt.AlignCenter
+        Layout.maximumWidth: 366
+
+        spacing: 12
+
+        RowLayout {
+            Layout.fillWidth: true
+            Layout.maximumHeight: 24
+            spacing: 0
+
+            Item {
+                Layout.alignment: Qt.AlignVCenter
+                Layout.fillWidth: true
+                Layout.fillHeight: true
+            }
+
+            Label {
+                id: importFromBackupLabel
+                Layout.minimumHeight: 24
+                Layout.minimumWidth: 234
+                text: qsTr("Import from backup")
+                font.pointSize: 13
+                font.kerning: true
+                horizontalAlignment: Qt.AlignLeft
+                verticalAlignment: Qt.AlignVCenter
+            }
+
+            HoverableRadiusButton {
+                id: backupInfoBtn
+
+                buttonImageHeight: height
+                buttonImageWidth: width
+
+                Layout.alignment: Qt.AlignVCenter
+                Layout.minimumWidth: 24
+                Layout.preferredWidth: 24
+                Layout.maximumWidth: 24
+
+                Layout.minimumHeight: 24
+                Layout.preferredHeight: 24
+                Layout.maximumHeight: 24
+
+                radius: height / 2
+                icon.source: "/images/icons/info-24px.svg"
+                icon.height: 24
+                icon.width: 24
+
+                backgroundColor: JamiTheme.releaseColor
+                onClicked: {
+                    backupInfoLabel.visible = !backupInfoLabel.visible
+                }
+            }
+            Item {
+                Layout.alignment: Qt.AlignVCenter
+                Layout.fillWidth: true
+                Layout.fillHeight: true
+            }
+        }
+
+        HoverableGradientButton {
+            id: fileImportBtn
+
+            Layout.alignment: Qt.AlignHCenter
+            Layout.maximumWidth: 256
+            Layout.preferredWidth: 256
+
+            Layout.maximumHeight: 30
+            Layout.preferredHeight: 30
+            Layout.minimumHeight: 30
+
+            text: fileImportBtnText
+            font.pointSize: 10
+            font.kerning: true
+
+            radius: height / 2
+            backgroundColor: JamiTheme.releaseColor
+
+            onClicked: {
+                importFromFile_Dialog.open()
+            }
+        }
+
+        InfoLineEdit {
+            id: passwordFromBackupEdit
+
+            Layout.alignment: Qt.AlignHCenter
+
+            selectByMouse: true
+            echoMode: TextInput.Password
+            placeholderText: qsTr("Password")
+        }
+
+        Label {
+            id: backupInfoLabel
+
+            Layout.alignment: Qt.AlignHCenter
+            Layout.maximumWidth: 366
+            Layout.preferredWidth: 366
+
+            text: qsTr("You can obtain an archive by clicking on \"Export account\" in the account settings. This will create a .gz file on your device.")
+            wrapMode: Text.WordWrap
+            horizontalAlignment: Text.AlignHCenter
+            verticalAlignment: Text.AlignVCenter
+
+            visible: false
+        }
+    }
+
+    Item {
+        Layout.alignment: Qt.AlignHCenter
+        Layout.fillWidth: true
+        Layout.fillHeight: true
+    }
+}
diff --git a/src/wizardview/components/ImportFromDevicePage.qml b/src/wizardview/components/ImportFromDevicePage.qml
new file mode 100644
index 0000000..5181635
--- /dev/null
+++ b/src/wizardview/components/ImportFromDevicePage.qml
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+    property alias text_pinFromDeviceAlias: pinFromDevice.text
+    property alias text_passwordFromDeviceAlias: passwordFromDevice.text
+
+    function initializeOnShowUp() {
+        clearAllTextFields()
+    }
+
+    function clearAllTextFields() {
+        pinFromDevice.clear()
+        passwordFromDevice.clear()
+    }
+
+    Layout.fillWidth: true
+    Layout.fillHeight: true
+
+    Item {
+        Layout.alignment: Qt.AlignHCenter
+        Layout.preferredHeight: 40
+        Layout.fillWidth: true
+        Layout.fillHeight: true
+    }
+
+    ColumnLayout {
+        Layout.alignment: Qt.AlignCenter
+        Layout.fillWidth: true
+
+        spacing: 12
+
+        RowLayout {
+            Layout.fillWidth: true
+            Layout.maximumHeight: 24
+            spacing: 0
+
+            Item {
+                Layout.alignment: Qt.AlignVCenter
+                Layout.fillWidth: true
+                Layout.fillHeight: true
+            }
+
+            Label {
+                id: importFromDeviceLabel
+                Layout.minimumHeight: 24
+                Layout.minimumWidth: 234
+                text: qsTr("Import from device")
+                font.pointSize: 13
+                font.kerning: true
+            }
+
+            HoverableRadiusButton {
+                id: pinInfoBtn
+
+                buttonImageHeight: height
+                buttonImageWidth: width
+
+                Layout.alignment: Qt.AlignVCenter
+                Layout.minimumWidth: 24
+                Layout.maximumWidth: 24
+                Layout.minimumHeight: 24
+                Layout.maximumHeight: 24
+
+                radius: height / 2
+                icon.source: "/images/icons/info-24px.svg"
+                backgroundColor: JamiTheme.releaseColor
+
+                onClicked: {
+                    pinInfoLabel.visible = !pinInfoLabel.visible
+                }
+            }
+            Item {
+                Layout.alignment: Qt.AlignVCenter
+                Layout.fillWidth: true
+                Layout.fillHeight: true
+            }
+        }
+        InfoLineEdit {
+            id: pinFromDevice
+
+            Layout.alignment: Qt.AlignHCenter
+
+            selectByMouse: true
+            placeholderText: qsTr("PIN")
+        }
+
+        InfoLineEdit {
+            id: passwordFromDevice
+
+            Layout.alignment: Qt.AlignHCenter
+
+            selectByMouse: true
+            echoMode: TextInput.Password
+            placeholderText: qsTr("Password")
+        }
+
+        Label {
+            id: pinInfoLabel
+
+            Layout.alignment: Qt.AlignHCenter
+            Layout.minimumWidth: 256
+            Layout.maximumWidth: 256
+
+            text: qsTr("To obtain a PIN (valid for 10 minutes), you need to open the account settings on the other device and click on \"Link to another device\".")
+            wrapMode: Text.WordWrap
+            horizontalAlignment: Text.AlignHCenter
+            verticalAlignment: Text.AlignVCenter
+
+            visible: false
+        }
+    }
+
+    Item {
+        Layout.alignment: Qt.AlignHCenter
+        Layout.preferredHeight: 40
+        Layout.fillWidth: true
+        Layout.fillHeight: true
+    }
+}
diff --git a/src/wizardview/components/SpinnerPage.qml b/src/wizardview/components/SpinnerPage.qml
new file mode 100644
index 0000000..2fb3f8d
--- /dev/null
+++ b/src/wizardview/components/SpinnerPage.qml
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../../constant"
+
+ColumnLayout {
+    Layout.fillWidth: true
+    Layout.fillHeight: true
+    spacing: 6
+
+    property bool successState: true
+    property string progressLabelEditText: "Generating your Jami account"
+
+    Item {
+        Layout.alignment: Qt.AlignHCenter
+        Layout.preferredHeight: 40
+        Layout.fillWidth: true
+        Layout.fillHeight: true
+    }
+    Label {
+        id: spinnerLabel
+        Layout.alignment: Qt.AlignHCenter
+        Layout.minimumWidth: 200
+        Layout.minimumHeight: 200
+
+        Layout.maximumWidth: 16777215
+        Layout.maximumHeight: 16777215
+
+        property string spinnerDisplyState: successState ? "spinnerLabel_Regular" : "spinnerLabel_Failure"
+        onSpinnerDisplyStateChanged: {
+            switch (spinnerDisplyState) {
+            case "spinnerLabel_Regular":
+                background = Qt.createQmlObject("import QtQuick 2.14;
+AnimatedImage {
+source: \"qrc:/images/jami_eclipse_spinner.gif\"
+
+playing: true
+paused: false
+fillMode: Image.PreserveAspectFit
+mipmap: true
+}", spinnerLabel)
+                break
+            case "spinnerLabel_Failure":
+                background = Qt.createQmlObject("import QtQuick 2.14;
+import \"qrc:/src/constant/\";
+Image {
+anchors.fill: parent;
+source:\"image://tintedPixmap/\" + (\"qrc:/images/icons/baseline-error_outline-24px.svg\").replace(\"qrc:/images/icons/\", \"\") + \"+\" + JamiTheme.urgentOrange_;
+mipmap: true;}", spinnerLabel)
+                break
+            }
+        }
+    }
+    Item {
+        Layout.alignment: Qt.AlignHCenter
+        Layout.preferredHeight: 40
+        Layout.fillWidth: true
+        Layout.fillHeight: true
+    }
+    Label {
+        id: progressLabel
+        Layout.alignment: Qt.AlignHCenter
+        text: successState ? progressLabelEditText : "Error creating account"
+        font.pointSize: 11
+        font.kerning: true
+
+        property string progressLabelState: successState ? "color_success" : "color_fail"
+        onProgressLabelStateChanged: {
+            switch (progressLabelState) {
+            case "color_success":
+                background = Qt.createQmlObject(
+                            "import QtQuick 2.14; Rectangle { anchors.fill: parent; color: \"transparent\"; }",
+                            progressLabel)
+                break
+            case "color_fail":
+                background = Qt.createQmlObject(
+                            "import QtQuick 2.14; Rectangle { anchors.fill: parent; color: \"red\"; }",
+                            progressLabel)
+                break
+            }
+        }
+    }
+    Item {
+        Layout.alignment: Qt.AlignHCenter
+        Layout.minimumHeight: 20
+        Layout.maximumHeight: 20
+        Layout.preferredHeight: 20
+        Layout.fillWidth: true
+        Layout.fillHeight: false
+    }
+}
diff --git a/src/wizardview/components/WelcomePageLayout.qml b/src/wizardview/components/WelcomePageLayout.qml
new file mode 100644
index 0000000..3c7190b
--- /dev/null
+++ b/src/wizardview/components/WelcomePageLayout.qml
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Yang Wang <yang.wang@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.14
+import QtQuick.Layouts 1.3
+import QtQuick.Controls 2.14
+
+import "../../constant"
+import "../../commoncomponents"
+
+ColumnLayout {
+    property alias connectAccountManagerButtonAlias: connectAccountManagerButton
+    property alias newSIPAccountButtonAlias: newSIPAccountButton
+
+    Layout.fillWidth: true
+    Layout.fillHeight: true
+    spacing: 6
+
+    signal welcomePageRedirectPage(int toPageIndex)
+
+    Item {
+        // put a spacer to make the buttons closs to the middle
+        Layout.minimumHeight: 57
+        Layout.maximumHeight: 57
+        Layout.preferredHeight: 57
+        Layout.fillWidth: true
+    }
+    RowLayout {
+        Layout.fillWidth: true
+        Layout.alignment: Qt.AlignHCenter
+        Label {
+            id: welcomeLabel
+            Layout.maximumHeight: 40
+            Layout.alignment: Qt.AlignCenter
+            text: qsTr("Welcome to")
+            font.pointSize: 30
+            font.kerning: true
+        }
+    }
+    Item {
+        Layout.minimumHeight: 17
+        Layout.maximumHeight: 17
+        Layout.preferredHeight: 17
+        Layout.fillWidth: true
+    }
+
+    RowLayout {
+        Layout.fillWidth: true
+        Layout.alignment: Qt.AlignHCenter
+        Label {
+            id: welcomeLogo
+            Layout.alignment: Qt.AlignCenter
+            Layout.minimumWidth: 100
+            Layout.minimumHeight: 100
+            Layout.maximumWidth: 16777215
+            Layout.maximumHeight: 16777215
+            Layout.preferredWidth: 300
+            Layout.preferredHeight: 150
+            color: "transparent"
+            background: Image {
+                id: logoIMG
+                source: "qrc:/images/logo-jami-standard-coul.png"
+                fillMode: Image.PreserveAspectFit
+                mipmap: true
+            }
+        }
+    }
+    Item {
+        // put a spacer to make the buttons closs to the middle
+        Layout.preferredHeight: 57
+        Layout.fillWidth: true
+        Layout.fillHeight: true
+    }
+    RowLayout {
+        spacing: 6
+        Layout.fillWidth: true
+        Layout.maximumHeight: 30
+        Layout.alignment: Qt.AlignHCenter
+        HoverableGradientButton {
+            id: newAccountButton
+
+            Layout.alignment: Qt.AlignCenter
+            Layout.preferredWidth: 256
+            Layout.preferredHeight: 30
+            text: qsTr("Create local account")
+            font.pointSize: 10
+            font.kerning: true
+            radius: height / 2
+
+            onClicked: {
+                welcomePageRedirectPage(1)
+            }
+        }
+    }
+    RowLayout {
+        spacing: 6
+        Layout.fillWidth: true
+
+        Layout.maximumHeight: 30
+        Layout.alignment: Qt.AlignHCenter
+        HoverableGradientButton {
+            id: fromDeviceButton
+            Layout.alignment: Qt.AlignCenter
+            Layout.preferredWidth: 256
+            Layout.preferredHeight: 30
+            text: qsTr("Import from device")
+            font.pointSize: 10
+            font.kerning: true
+
+            backgroundColor: JamiTheme.releaseColor
+            radius: height / 2
+
+            onClicked: {
+                welcomePageRedirectPage(5)
+            }
+        }
+    }
+    RowLayout {
+        spacing: 6
+        Layout.fillWidth: true
+
+        Layout.maximumHeight: 30
+        Layout.alignment: Qt.AlignHCenter
+        HoverableGradientButton {
+            id: fromBackupButton
+            Layout.alignment: Qt.AlignCenter
+            Layout.preferredWidth: 256
+            Layout.preferredHeight: 30
+            text: qsTr("Import from backup")
+            font.pointSize: 10
+            font.kerning: true
+
+            backgroundColor: JamiTheme.releaseColor
+            radius: height / 2
+
+            onClicked: {
+                welcomePageRedirectPage(3)
+            }
+        }
+    }
+    RowLayout {
+        spacing: 6
+        Layout.fillWidth: true
+
+        Layout.maximumHeight: 30
+        Layout.alignment: Qt.AlignHCenter
+        Button {
+            id: showAdvancedButton
+            Layout.preferredWidth: 256
+            Layout.preferredHeight: 30
+            Layout.alignment: Qt.AlignCenter
+            text: qsTr("Show Advanced")
+            font.pointSize: 8
+            font.kerning: true
+
+            background: Rectangle{
+                anchors.fill: parent
+
+                color: "transparent"
+                radius: height /2
+            }
+
+            onClicked: {
+                connectAccountManagerButton.visible = !connectAccountManagerButton.visible
+                newSIPAccountButton.visible = !newSIPAccountButton.visible
+            }
+        }
+    }
+    RowLayout {
+        spacing: 6
+        Layout.fillWidth: true
+        Layout.alignment: Qt.AlignHCenter
+
+        Layout.maximumHeight: 30
+        HoverableGradientButton {
+            id: connectAccountManagerButton
+            Layout.preferredWidth: 256
+            Layout.preferredHeight: 30
+            Layout.alignment: Qt.AlignCenter
+            text: qsTr("Connect to account manager")
+            visible: false
+            font.pointSize: 10
+            font.kerning: true
+
+            backgroundColor: JamiTheme.releaseColor
+            radius: height / 2
+
+            onClicked: {
+                welcomePageRedirectPage(6)
+            }
+        }
+    }
+    RowLayout {
+        spacing: 6
+        Layout.fillWidth: true
+        Layout.alignment: Qt.AlignHCenter
+        Layout.maximumHeight: 30
+
+        HoverableGradientButton {
+            id: newSIPAccountButton
+            Layout.preferredWidth: 256
+            Layout.preferredHeight: 30
+            Layout.alignment: Qt.AlignCenter
+            text: qsTr("Add a new SIP account")
+            visible: false
+            font.pointSize: 10
+            font.kerning: true
+
+            radius: height / 2
+            backgroundColor: JamiTheme.releaseColor
+
+            onClicked: {
+                welcomePageRedirectPage(2)
+            }
+        }
+    }
+    Item {
+        // put a spacer to make the buttons closs to the middle
+        Layout.fillHeight: true
+        Layout.preferredHeight: 65
+        Layout.fillWidth: true
+    }
+}