865 lines
37 KiB
QML
865 lines
37 KiB
QML
import QtQuick
|
||
import QtQuick.Window
|
||
import QtQuick.Layouts
|
||
import QtQuick.Controls as Controls
|
||
import org.kde.kirigami as Kirigami
|
||
|
||
Kirigami.ApplicationWindow {
|
||
id: root
|
||
|
||
title: "Configuration initiale du poste"
|
||
visibility: Window.FullScreen
|
||
color: "#eef2f7"
|
||
|
||
property int currentStep: 0
|
||
property var steps: [
|
||
{ "title": "Bienvenue", "subtitle": "Présentation" },
|
||
{ "title": "Mot de passe", "subtitle": "Accès de secours" },
|
||
{ "title": "YubiKey", "subtitle": "PIN personnel" },
|
||
{ "title": "Terminé", "subtitle": "Poste prêt" }
|
||
]
|
||
|
||
function goNext() {
|
||
if (currentStep < steps.length - 1) {
|
||
currentStep += 1
|
||
}
|
||
}
|
||
|
||
function goBack() {
|
||
if (currentStep > 0) {
|
||
currentStep -= 1
|
||
}
|
||
}
|
||
|
||
Shortcut {
|
||
sequence: "Ctrl+Q"
|
||
onActivated: Qt.quit()
|
||
}
|
||
|
||
component PrimaryButton: Controls.Button {
|
||
id: control
|
||
implicitHeight: 48
|
||
implicitWidth: 170
|
||
leftPadding: 24
|
||
rightPadding: 24
|
||
|
||
contentItem: Controls.Label {
|
||
text: control.text
|
||
font.pixelSize: 15
|
||
font.weight: Font.DemiBold
|
||
color: "white"
|
||
horizontalAlignment: Text.AlignHCenter
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
|
||
background: Rectangle {
|
||
radius: 12
|
||
color: control.down ? "#1e40af" : control.hovered ? "#2563eb" : "#1d4ed8"
|
||
Behavior on color { ColorAnimation { duration: 120 } }
|
||
}
|
||
}
|
||
|
||
component SecondaryButton: Controls.Button {
|
||
id: control
|
||
implicitHeight: 48
|
||
implicitWidth: 140
|
||
leftPadding: 22
|
||
rightPadding: 22
|
||
|
||
contentItem: Controls.Label {
|
||
text: control.text
|
||
font.pixelSize: 15
|
||
font.weight: Font.Medium
|
||
color: "#334155"
|
||
horizontalAlignment: Text.AlignHCenter
|
||
verticalAlignment: Text.AlignVCenter
|
||
}
|
||
|
||
background: Rectangle {
|
||
radius: 12
|
||
color: control.down ? "#dbe3ee" : control.hovered ? "#edf2f7" : "transparent"
|
||
border.width: 1
|
||
border.color: "#cbd5e1"
|
||
}
|
||
}
|
||
|
||
component SecretField: Controls.TextField {
|
||
id: field
|
||
Layout.fillWidth: true
|
||
implicitHeight: 50
|
||
echoMode: TextInput.Password
|
||
passwordCharacter: "●"
|
||
font.pixelSize: 15
|
||
leftPadding: 16
|
||
rightPadding: 16
|
||
selectByMouse: true
|
||
|
||
background: Rectangle {
|
||
radius: 10
|
||
color: field.activeFocus ? "#ffffff" : "#f8fafc"
|
||
border.width: field.activeFocus ? 2 : 1
|
||
border.color: field.activeFocus ? "#2563eb" : "#cbd5e1"
|
||
}
|
||
}
|
||
|
||
component StepDot: Rectangle {
|
||
required property int stepIndex
|
||
|
||
width: 34
|
||
height: 34
|
||
radius: 17
|
||
color: stepIndex < root.currentStep ? "#22c55e"
|
||
: stepIndex === root.currentStep ? "#ffffff"
|
||
: "#17345f"
|
||
border.width: stepIndex === root.currentStep ? 2 : 0
|
||
border.color: "#93c5fd"
|
||
|
||
Controls.Label {
|
||
anchors.centerIn: parent
|
||
text: parent.stepIndex < root.currentStep ? "✓" : (parent.stepIndex + 1)
|
||
color: parent.stepIndex === root.currentStep ? "#0f2b50" : "white"
|
||
font.pixelSize: 14
|
||
font.weight: Font.Bold
|
||
}
|
||
}
|
||
|
||
RowLayout {
|
||
anchors.fill: parent
|
||
spacing: 0
|
||
|
||
// -----------------------------------------------------
|
||
// Colonne gauche : identité + progression
|
||
// -----------------------------------------------------
|
||
Rectangle {
|
||
Layout.preferredWidth: Math.max(330, root.width * 0.29)
|
||
Layout.fillHeight: true
|
||
|
||
gradient: Gradient {
|
||
GradientStop { position: 0.0; color: "#081a33" }
|
||
GradientStop { position: 0.55; color: "#0b2a50" }
|
||
GradientStop { position: 1.0; color: "#123d70" }
|
||
}
|
||
|
||
ColumnLayout {
|
||
anchors.fill: parent
|
||
anchors.margins: 44
|
||
spacing: 0
|
||
|
||
RowLayout {
|
||
spacing: 14
|
||
|
||
Rectangle {
|
||
width: 54
|
||
height: 54
|
||
radius: 16
|
||
color: "#1d4ed8"
|
||
|
||
Controls.Label {
|
||
anchors.centerIn: parent
|
||
text: "N"
|
||
color: "white"
|
||
font.pixelSize: 25
|
||
font.weight: Font.Bold
|
||
}
|
||
}
|
||
|
||
ColumnLayout {
|
||
spacing: 2
|
||
|
||
Controls.Label {
|
||
text: "NixOS Workstations"
|
||
color: "white"
|
||
font.pixelSize: 19
|
||
font.weight: Font.DemiBold
|
||
}
|
||
|
||
Controls.Label {
|
||
text: "Configuration du poste"
|
||
color: "#a8c1e1"
|
||
font.pixelSize: 13
|
||
}
|
||
}
|
||
}
|
||
|
||
Item { Layout.preferredHeight: 70 }
|
||
|
||
Controls.Label {
|
||
text: "VOTRE CONFIGURATION"
|
||
color: "#7fa4d1"
|
||
font.pixelSize: 11
|
||
font.weight: Font.Bold
|
||
font.letterSpacing: 1.5
|
||
}
|
||
|
||
Item { Layout.preferredHeight: 26 }
|
||
|
||
Repeater {
|
||
model: root.steps
|
||
|
||
delegate: Item {
|
||
required property int index
|
||
required property var modelData
|
||
|
||
Layout.fillWidth: true
|
||
Layout.preferredHeight: 78
|
||
|
||
RowLayout {
|
||
anchors.fill: parent
|
||
spacing: 16
|
||
|
||
ColumnLayout {
|
||
Layout.alignment: Qt.AlignTop
|
||
spacing: 0
|
||
|
||
StepDot { stepIndex: index }
|
||
|
||
Rectangle {
|
||
visible: index < root.steps.length - 1
|
||
Layout.alignment: Qt.AlignHCenter
|
||
Layout.preferredWidth: 2
|
||
Layout.preferredHeight: 36
|
||
color: index < root.currentStep ? "#22c55e" : "#28517e"
|
||
}
|
||
}
|
||
|
||
ColumnLayout {
|
||
Layout.fillWidth: true
|
||
Layout.alignment: Qt.AlignTop
|
||
spacing: 3
|
||
|
||
Controls.Label {
|
||
text: modelData.title
|
||
color: index === root.currentStep ? "white" : "#c1d3e8"
|
||
font.pixelSize: 15
|
||
font.weight: index === root.currentStep ? Font.DemiBold : Font.Medium
|
||
}
|
||
|
||
Controls.Label {
|
||
text: modelData.subtitle
|
||
color: "#7699c2"
|
||
font.pixelSize: 12
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Item { Layout.fillHeight: true }
|
||
|
||
Rectangle {
|
||
Layout.fillWidth: true
|
||
implicitHeight: 86
|
||
radius: 14
|
||
color: "#102f55"
|
||
border.width: 1
|
||
border.color: "#214b78"
|
||
|
||
RowLayout {
|
||
anchors.fill: parent
|
||
anchors.margins: 16
|
||
spacing: 12
|
||
|
||
Controls.Label {
|
||
text: "🛡"
|
||
font.pixelSize: 23
|
||
}
|
||
|
||
ColumnLayout {
|
||
Layout.fillWidth: true
|
||
spacing: 3
|
||
|
||
Controls.Label {
|
||
text: "Configuration locale"
|
||
color: "white"
|
||
font.pixelSize: 13
|
||
font.weight: Font.DemiBold
|
||
}
|
||
|
||
Controls.Label {
|
||
Layout.fillWidth: true
|
||
text: "Les secrets définitifs ne seront pas enregistrés dans Git."
|
||
wrapMode: Text.WordWrap
|
||
color: "#91add0"
|
||
font.pixelSize: 11
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Item { Layout.preferredHeight: 20 }
|
||
|
||
Controls.Label {
|
||
text: "Ctrl+Q : quitter l'aperçu"
|
||
color: "#6289b6"
|
||
font.pixelSize: 11
|
||
Layout.alignment: Qt.AlignHCenter
|
||
}
|
||
}
|
||
}
|
||
|
||
// -----------------------------------------------------
|
||
// Partie droite
|
||
// -----------------------------------------------------
|
||
Rectangle {
|
||
id: contentArea
|
||
Layout.fillWidth: true
|
||
Layout.fillHeight: true
|
||
color: "#eef2f7"
|
||
|
||
ColumnLayout {
|
||
anchors.fill: parent
|
||
anchors.leftMargin: Math.max(48, contentArea.width * 0.07)
|
||
anchors.rightMargin: Math.max(48, contentArea.width * 0.07)
|
||
anchors.topMargin: 34
|
||
anchors.bottomMargin: 34
|
||
spacing: 20
|
||
|
||
RowLayout {
|
||
Layout.fillWidth: true
|
||
|
||
Rectangle {
|
||
implicitWidth: previewLabel.implicitWidth + 28
|
||
implicitHeight: 32
|
||
radius: 16
|
||
color: "#fff7ed"
|
||
border.width: 1
|
||
border.color: "#fed7aa"
|
||
|
||
Controls.Label {
|
||
id: previewLabel
|
||
anchors.centerIn: parent
|
||
text: "MODE APERÇU — aucune modification système"
|
||
color: "#c2410c"
|
||
font.pixelSize: 11
|
||
font.weight: Font.Bold
|
||
}
|
||
}
|
||
|
||
Item { Layout.fillWidth: true }
|
||
|
||
SecondaryButton {
|
||
text: "Quitter l'aperçu"
|
||
onClicked: Qt.quit()
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
Layout.fillWidth: true
|
||
Layout.fillHeight: true
|
||
radius: 24
|
||
color: "white"
|
||
border.width: 1
|
||
border.color: "#dce3ec"
|
||
|
||
ColumnLayout {
|
||
anchors.fill: parent
|
||
anchors.margins: Math.max(34, Math.min(64, parent.width * 0.055))
|
||
spacing: 24
|
||
|
||
// Petit indicateur de progression supérieur
|
||
RowLayout {
|
||
Layout.fillWidth: true
|
||
spacing: 10
|
||
|
||
Repeater {
|
||
model: root.steps.length
|
||
|
||
Rectangle {
|
||
required property int index
|
||
Layout.fillWidth: true
|
||
implicitHeight: 5
|
||
radius: 3
|
||
color: index <= root.currentStep ? "#2563eb" : "#e2e8f0"
|
||
|
||
Behavior on color { ColorAnimation { duration: 180 } }
|
||
}
|
||
}
|
||
}
|
||
|
||
StackLayout {
|
||
id: wizard
|
||
Layout.fillWidth: true
|
||
Layout.fillHeight: true
|
||
currentIndex: root.currentStep
|
||
|
||
// ---------------------------------
|
||
// 0 - Bienvenue
|
||
// ---------------------------------
|
||
Item {
|
||
ColumnLayout {
|
||
anchors.fill: parent
|
||
spacing: 20
|
||
|
||
Item { Layout.fillHeight: true }
|
||
|
||
Rectangle {
|
||
Layout.preferredWidth: 86
|
||
Layout.preferredHeight: 86
|
||
Layout.alignment: Qt.AlignHCenter
|
||
radius: 24
|
||
color: "#eff6ff"
|
||
border.width: 1
|
||
border.color: "#bfdbfe"
|
||
|
||
Controls.Label {
|
||
anchors.centerIn: parent
|
||
text: "✦"
|
||
color: "#2563eb"
|
||
font.pixelSize: 42
|
||
font.weight: Font.Bold
|
||
}
|
||
}
|
||
|
||
Controls.Label {
|
||
Layout.fillWidth: true
|
||
text: "Bienvenue sur votre nouveau poste"
|
||
color: "#0f172a"
|
||
font.pixelSize: 32
|
||
font.weight: Font.Bold
|
||
horizontalAlignment: Text.AlignHCenter
|
||
}
|
||
|
||
Controls.Label {
|
||
Layout.maximumWidth: 720
|
||
Layout.alignment: Qt.AlignHCenter
|
||
text: "Quelques étapes rapides vont personnaliser vos moyens d'authentification et finaliser la préparation de votre environnement de travail."
|
||
wrapMode: Text.WordWrap
|
||
color: "#64748b"
|
||
font.pixelSize: 16
|
||
lineHeight: 1.25
|
||
horizontalAlignment: Text.AlignHCenter
|
||
}
|
||
|
||
Item { Layout.preferredHeight: 12 }
|
||
|
||
RowLayout {
|
||
Layout.alignment: Qt.AlignHCenter
|
||
spacing: 14
|
||
|
||
Repeater {
|
||
model: [
|
||
{ "icon": "🔑", "title": "Mot de passe", "text": "Définir votre accès local de secours" },
|
||
{ "icon": "🔐", "title": "YubiKey", "text": "Personnaliser votre PIN FIDO2" }
|
||
]
|
||
|
||
Rectangle {
|
||
required property var modelData
|
||
Layout.preferredWidth: 290
|
||
Layout.preferredHeight: 128
|
||
radius: 16
|
||
color: "#f8fafc"
|
||
border.width: 1
|
||
border.color: "#e2e8f0"
|
||
|
||
RowLayout {
|
||
anchors.fill: parent
|
||
anchors.margins: 18
|
||
spacing: 14
|
||
|
||
Controls.Label {
|
||
text: modelData.icon
|
||
font.pixelSize: 28
|
||
}
|
||
|
||
ColumnLayout {
|
||
Layout.fillWidth: true
|
||
spacing: 5
|
||
|
||
Controls.Label {
|
||
text: modelData.title
|
||
color: "#0f172a"
|
||
font.pixelSize: 15
|
||
font.weight: Font.DemiBold
|
||
}
|
||
|
||
Controls.Label {
|
||
Layout.fillWidth: true
|
||
text: modelData.text
|
||
wrapMode: Text.WordWrap
|
||
color: "#64748b"
|
||
font.pixelSize: 12
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
Item { Layout.fillHeight: true }
|
||
|
||
PrimaryButton {
|
||
Layout.alignment: Qt.AlignHCenter
|
||
text: "Commencer"
|
||
onClicked: root.goNext()
|
||
}
|
||
}
|
||
}
|
||
|
||
// ---------------------------------
|
||
// 1 - Mot de passe
|
||
// ---------------------------------
|
||
Item {
|
||
ColumnLayout {
|
||
anchors.fill: parent
|
||
spacing: 18
|
||
|
||
Controls.Label {
|
||
text: "Mot de passe local"
|
||
color: "#0f172a"
|
||
font.pixelSize: 29
|
||
font.weight: Font.Bold
|
||
}
|
||
|
||
Controls.Label {
|
||
Layout.maximumWidth: 720
|
||
text: "Ce mot de passe reste disponible comme solution de secours si votre YubiKey est momentanément indisponible."
|
||
wrapMode: Text.WordWrap
|
||
color: "#64748b"
|
||
font.pixelSize: 15
|
||
lineHeight: 1.2
|
||
}
|
||
|
||
Rectangle {
|
||
Layout.fillWidth: true
|
||
implicitHeight: 70
|
||
radius: 12
|
||
color: "#eff6ff"
|
||
border.width: 1
|
||
border.color: "#bfdbfe"
|
||
|
||
RowLayout {
|
||
anchors.fill: parent
|
||
anchors.margins: 16
|
||
spacing: 12
|
||
|
||
Controls.Label {
|
||
text: "ℹ"
|
||
color: "#2563eb"
|
||
font.pixelSize: 22
|
||
font.weight: Font.Bold
|
||
}
|
||
|
||
Controls.Label {
|
||
Layout.fillWidth: true
|
||
text: "Aperçu uniquement : les champs ci-dessous ne modifient actuellement aucun mot de passe."
|
||
wrapMode: Text.WordWrap
|
||
color: "#1e40af"
|
||
font.pixelSize: 13
|
||
}
|
||
}
|
||
}
|
||
|
||
Item { Layout.preferredHeight: 4 }
|
||
|
||
Controls.Label {
|
||
text: "Mot de passe temporaire actuel"
|
||
color: "#334155"
|
||
font.pixelSize: 13
|
||
font.weight: Font.DemiBold
|
||
}
|
||
|
||
SecretField {
|
||
id: currentPassword
|
||
placeholderText: "Saisissez le mot de passe temporaire"
|
||
}
|
||
|
||
Controls.Label {
|
||
text: "Nouveau mot de passe"
|
||
color: "#334155"
|
||
font.pixelSize: 13
|
||
font.weight: Font.DemiBold
|
||
}
|
||
|
||
SecretField {
|
||
id: newPassword
|
||
placeholderText: "Choisissez votre mot de passe personnel"
|
||
}
|
||
|
||
Controls.Label {
|
||
text: "Confirmation"
|
||
color: "#334155"
|
||
font.pixelSize: 13
|
||
font.weight: Font.DemiBold
|
||
}
|
||
|
||
SecretField {
|
||
id: confirmPassword
|
||
placeholderText: "Confirmez votre nouveau mot de passe"
|
||
}
|
||
|
||
Controls.Label {
|
||
visible: confirmPassword.text.length > 0 && newPassword.text !== confirmPassword.text
|
||
text: "Les deux nouveaux mots de passe ne correspondent pas."
|
||
color: "#dc2626"
|
||
font.pixelSize: 12
|
||
}
|
||
|
||
Item { Layout.fillHeight: true }
|
||
|
||
RowLayout {
|
||
Layout.fillWidth: true
|
||
|
||
SecondaryButton {
|
||
text: "Retour"
|
||
onClicked: root.goBack()
|
||
}
|
||
|
||
Item { Layout.fillWidth: true }
|
||
|
||
PrimaryButton {
|
||
text: "Continuer"
|
||
enabled: newPassword.text.length > 0 && newPassword.text === confirmPassword.text
|
||
opacity: enabled ? 1.0 : 0.45
|
||
onClicked: root.goNext()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// ---------------------------------
|
||
// 2 - YubiKey
|
||
// ---------------------------------
|
||
Item {
|
||
ColumnLayout {
|
||
anchors.fill: parent
|
||
spacing: 18
|
||
|
||
RowLayout {
|
||
Layout.fillWidth: true
|
||
spacing: 20
|
||
|
||
Rectangle {
|
||
Layout.preferredWidth: 80
|
||
Layout.preferredHeight: 80
|
||
radius: 22
|
||
color: "#f0fdf4"
|
||
border.width: 1
|
||
border.color: "#bbf7d0"
|
||
|
||
Controls.Label {
|
||
anchors.centerIn: parent
|
||
text: "🔐"
|
||
font.pixelSize: 34
|
||
}
|
||
}
|
||
|
||
ColumnLayout {
|
||
Layout.fillWidth: true
|
||
spacing: 5
|
||
|
||
Controls.Label {
|
||
text: "PIN de votre YubiKey"
|
||
color: "#0f172a"
|
||
font.pixelSize: 29
|
||
font.weight: Font.Bold
|
||
}
|
||
|
||
Controls.Label {
|
||
Layout.fillWidth: true
|
||
text: "Remplacez le PIN temporaire de préparation par un PIN personnel que vous serez seul à connaître."
|
||
wrapMode: Text.WordWrap
|
||
color: "#64748b"
|
||
font.pixelSize: 15
|
||
}
|
||
}
|
||
}
|
||
|
||
Rectangle {
|
||
Layout.fillWidth: true
|
||
implicitHeight: 78
|
||
radius: 12
|
||
color: "#fffbeb"
|
||
border.width: 1
|
||
border.color: "#fde68a"
|
||
|
||
RowLayout {
|
||
anchors.fill: parent
|
||
anchors.margins: 16
|
||
spacing: 12
|
||
|
||
Controls.Label {
|
||
text: "⌨"
|
||
color: "#b45309"
|
||
font.pixelSize: 23
|
||
}
|
||
|
||
Controls.Label {
|
||
Layout.fillWidth: true
|
||
text: "Vérifiez Verr Num avant d'utiliser le pavé numérique. En cas de doute, utilisez les chiffres situés au-dessus des lettres."
|
||
wrapMode: Text.WordWrap
|
||
color: "#92400e"
|
||
font.pixelSize: 13
|
||
}
|
||
}
|
||
}
|
||
|
||
Controls.Label {
|
||
text: "PIN temporaire actuel"
|
||
color: "#334155"
|
||
font.pixelSize: 13
|
||
font.weight: Font.DemiBold
|
||
}
|
||
|
||
SecretField {
|
||
id: currentPin
|
||
placeholderText: "PIN temporaire"
|
||
inputMethodHints: Qt.ImhDigitsOnly
|
||
}
|
||
|
||
Controls.Label {
|
||
text: "Nouveau PIN"
|
||
color: "#334155"
|
||
font.pixelSize: 13
|
||
font.weight: Font.DemiBold
|
||
}
|
||
|
||
SecretField {
|
||
id: newPin
|
||
placeholderText: "Nouveau PIN personnel"
|
||
inputMethodHints: Qt.ImhDigitsOnly
|
||
}
|
||
|
||
Controls.Label {
|
||
text: "Confirmation du nouveau PIN"
|
||
color: "#334155"
|
||
font.pixelSize: 13
|
||
font.weight: Font.DemiBold
|
||
}
|
||
|
||
SecretField {
|
||
id: confirmPin
|
||
placeholderText: "Confirmez le nouveau PIN"
|
||
inputMethodHints: Qt.ImhDigitsOnly
|
||
}
|
||
|
||
Controls.Label {
|
||
visible: confirmPin.text.length > 0 && newPin.text !== confirmPin.text
|
||
text: "Les deux nouveaux PIN ne correspondent pas."
|
||
color: "#dc2626"
|
||
font.pixelSize: 12
|
||
}
|
||
|
||
Item { Layout.fillHeight: true }
|
||
|
||
RowLayout {
|
||
Layout.fillWidth: true
|
||
|
||
SecondaryButton {
|
||
text: "Retour"
|
||
onClicked: root.goBack()
|
||
}
|
||
|
||
Item { Layout.fillWidth: true }
|
||
|
||
PrimaryButton {
|
||
text: "Finaliser"
|
||
enabled: newPin.text.length >= 4 && newPin.text === confirmPin.text
|
||
opacity: enabled ? 1.0 : 0.45
|
||
onClicked: root.goNext()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// ---------------------------------
|
||
// 3 - Terminé
|
||
// ---------------------------------
|
||
Item {
|
||
ColumnLayout {
|
||
anchors.fill: parent
|
||
spacing: 18
|
||
|
||
Item { Layout.fillHeight: true }
|
||
|
||
Rectangle {
|
||
Layout.preferredWidth: 96
|
||
Layout.preferredHeight: 96
|
||
Layout.alignment: Qt.AlignHCenter
|
||
radius: 48
|
||
color: "#dcfce7"
|
||
border.width: 1
|
||
border.color: "#86efac"
|
||
|
||
Controls.Label {
|
||
anchors.centerIn: parent
|
||
text: "✓"
|
||
color: "#16a34a"
|
||
font.pixelSize: 50
|
||
font.weight: Font.Bold
|
||
}
|
||
}
|
||
|
||
Controls.Label {
|
||
Layout.fillWidth: true
|
||
text: "Votre poste est prêt"
|
||
color: "#0f172a"
|
||
font.pixelSize: 32
|
||
font.weight: Font.Bold
|
||
horizontalAlignment: Text.AlignHCenter
|
||
}
|
||
|
||
Controls.Label {
|
||
Layout.maximumWidth: 680
|
||
Layout.alignment: Qt.AlignHCenter
|
||
text: "Dans la version finale, cet écran confirmera que votre mot de passe local et le PIN de votre YubiKey ont été personnalisés avec succès."
|
||
wrapMode: Text.WordWrap
|
||
color: "#64748b"
|
||
font.pixelSize: 15
|
||
lineHeight: 1.25
|
||
horizontalAlignment: Text.AlignHCenter
|
||
}
|
||
|
||
Item { Layout.preferredHeight: 12 }
|
||
|
||
Rectangle {
|
||
Layout.preferredWidth: 520
|
||
Layout.preferredHeight: 112
|
||
Layout.alignment: Qt.AlignHCenter
|
||
radius: 16
|
||
color: "#f8fafc"
|
||
border.width: 1
|
||
border.color: "#e2e8f0"
|
||
|
||
ColumnLayout {
|
||
anchors.fill: parent
|
||
anchors.margins: 18
|
||
spacing: 10
|
||
|
||
RowLayout {
|
||
Controls.Label { text: "✓"; color: "#16a34a"; font.pixelSize: 17; font.weight: Font.Bold }
|
||
Controls.Label { text: "Mot de passe personnel configuré"; color: "#334155"; font.pixelSize: 14 }
|
||
}
|
||
|
||
RowLayout {
|
||
Controls.Label { text: "✓"; color: "#16a34a"; font.pixelSize: 17; font.weight: Font.Bold }
|
||
Controls.Label { text: "PIN personnel YubiKey configuré"; color: "#334155"; font.pixelSize: 14 }
|
||
}
|
||
}
|
||
}
|
||
|
||
Item { Layout.fillHeight: true }
|
||
|
||
RowLayout {
|
||
Layout.alignment: Qt.AlignHCenter
|
||
spacing: 12
|
||
|
||
SecondaryButton {
|
||
text: "Revoir"
|
||
onClicked: root.currentStep = 0
|
||
}
|
||
|
||
PrimaryButton {
|
||
text: "Fermer l'aperçu"
|
||
onClicked: Qt.quit()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|