// The day in numbers — the same payload the Telegram message is built from. import QtQuick import QtQuick.Controls import QtQuick.Layouts import "." import "components" ScrollView { id: page contentWidth: availableWidth clip: true readonly property var payload: controller.report.report ? controller.report.report : null readonly property var metrics: payload ? payload.metrics : null ColumnLayout { width: page.availableWidth - 56 x: 28 y: 26 spacing: 22 PageHeader { eyebrow: controller.report.sent_at ? "sent to Telegram" : "not sent yet" title: page.payload ? "Report · " + page.payload.date : "Report" caption: page.payload ? page.payload.verdict : "" GhostButton { text: "Reload"; onClicked: controller.loadReport() } PrimaryButton { text: "Send to Telegram"; onClicked: controller.sendReport() } } Panel { padding: 0 RowLayout { Layout.fillWidth: true spacing: 0 Repeater { model: [ { label: "Pomodoros", value: page.metrics ? page.metrics.pomodoros + "/" + page.metrics.goal : "—", caption: page.metrics && page.metrics.goal_met ? "goal met" : "goal not met yet", accent: true }, { label: "Focus", value: page.metrics ? Theme.humanMinutes(page.metrics.focus_minutes) : "—", caption: page.metrics ? Theme.humanMinutes(page.metrics.break_minutes) + " resting" : "" }, { label: "Score", value: page.payload ? "" + Math.round(page.payload.score) : "—", caption: "out of 100" }, { label: "Streak", value: page.payload ? page.payload.streak.current + "d" : "—", caption: page.payload ? "best " + page.payload.streak.best : "" } ] delegate: RowLayout { required property int index required property var modelData Layout.fillWidth: true spacing: 0 Rectangle { visible: index > 0 width: 1 Layout.preferredHeight: 84 color: Theme.rule } Stat { Layout.fillWidth: true Layout.margins: 20 label: modelData.label value: modelData.value caption: modelData.caption size: 38 accent: modelData.accent ? Theme.work : Theme.ink } } } } } ColumnLayout { Layout.fillWidth: true spacing: 10 SectionTitle { text: "Last 30 days"; trailing: "goal line dashed" } Panel { BarRow { Layout.fillWidth: true days: controller.stats.range ? controller.stats.range : [] goal: controller.goal } } } ColumnLayout { Layout.fillWidth: true visible: page.payload && page.payload.achievements.length > 0 spacing: 10 SectionTitle { text: "Achievements" } Flow { Layout.fillWidth: true spacing: 8 Repeater { model: page.payload ? page.payload.achievements : [] delegate: Rectangle { required property var modelData implicitWidth: badge.implicitWidth + 24 implicitHeight: badge.implicitHeight + 18 radius: 10 color: Qt.alpha(Theme.ember, 0.08) border.width: 1 border.color: Qt.alpha(Theme.ember, 0.22) ColumnLayout { id: badge anchors.centerIn: parent spacing: 1 Label { text: modelData.emoji + " " + modelData.title color: Theme.ink font.pixelSize: 13 font.weight: Font.DemiBold font.family: Theme.sansFamily } Label { visible: modelData.detail !== "" text: modelData.detail color: Theme.muted font.pixelSize: 11 font.family: Theme.sansFamily } } } } } } ColumnLayout { Layout.fillWidth: true visible: page.payload && page.payload.fun_facts.length > 0 spacing: 8 SectionTitle { text: "The funny part" } Repeater { model: page.payload ? page.payload.fun_facts : [] delegate: Label { required property var modelData text: modelData color: Theme.ink font.pixelSize: 13 font.family: Theme.sansFamily wrapMode: Text.WordWrap Layout.fillWidth: true } } } ColumnLayout { Layout.fillWidth: true visible: page.metrics && page.metrics.tasks_completed.length > 0 spacing: 6 SectionTitle { text: "Closed today" } Repeater { model: page.metrics ? page.metrics.tasks_completed : [] delegate: RowLayout { required property var modelData Layout.fillWidth: true spacing: 12 Label { text: modelData.title color: Theme.ink font.pixelSize: 13 font.family: Theme.sansFamily elide: Text.ElideRight Layout.fillWidth: true } Label { text: modelData.source color: Theme.faint font.pixelSize: 11 font.family: Theme.sansFamily } } } } ColumnLayout { Layout.fillWidth: true spacing: 10 SectionTitle { text: "All time" } Panel { padding: 0 RowLayout { Layout.fillWidth: true spacing: 0 Repeater { model: [ { label: "Pomodoros", value: controller.stats.lifetime ? "" + controller.stats.lifetime.pomodoros : "—" }, { label: "Hours focused", value: controller.stats.lifetime ? "" + controller.stats.lifetime.focus_hours : "—" }, { label: "Tasks closed", value: controller.stats.lifetime ? "" + controller.stats.lifetime.tasks_completed : "—" }, { label: "Blocked", value: controller.stats.lifetime ? "" + controller.stats.lifetime.blocked_attempts : "—" } ] delegate: RowLayout { required property int index required property var modelData Layout.fillWidth: true spacing: 0 Rectangle { visible: index > 0 width: 1 Layout.preferredHeight: 64 color: Theme.rule } Stat { Layout.fillWidth: true Layout.margins: 18 label: modelData.label value: modelData.value } } } } } } Item { Layout.preferredHeight: 10 } } Component.onCompleted: controller.loadReport() }