181 lines
6.8 KiB
QML
181 lines
6.8 KiB
QML
// The day, summarised — the same payload the Telegram message is built from.
|
|
import QtQuick
|
|
import QtQuick.Controls.Material
|
|
import QtQuick.Layouts
|
|
|
|
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
|
|
spacing: 16
|
|
|
|
ColumnLayout {
|
|
Layout.fillWidth: true
|
|
Layout.margins: 20
|
|
spacing: 16
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
Label {
|
|
text: page.payload ? "Report for " + page.payload.date : "Report"
|
|
font.pixelSize: 20
|
|
font.weight: Font.Medium
|
|
Layout.fillWidth: true
|
|
}
|
|
Button { text: "⟳"; flat: true; onClicked: controller.loadReport() }
|
|
PrimaryButton { text: "Send to Telegram"; onClicked: controller.sendReport() }
|
|
}
|
|
|
|
GridLayout {
|
|
Layout.fillWidth: true
|
|
columns: page.width > 760 ? 4 : 2
|
|
columnSpacing: 12
|
|
rowSpacing: 12
|
|
|
|
StatTile {
|
|
label: "Pomodoros"
|
|
value: page.metrics ? page.metrics.pomodoros + "/" + page.metrics.goal : "—"
|
|
caption: page.metrics && page.metrics.goal_met ? "goal met 🎯" : "keep going"
|
|
accent: window.workColor
|
|
}
|
|
StatTile {
|
|
label: "Focus"
|
|
value: page.metrics ? page.metrics.focus_minutes + "m" : "—"
|
|
caption: page.metrics ? page.metrics.break_minutes + "m resting" : ""
|
|
}
|
|
StatTile {
|
|
label: "Score"
|
|
value: page.payload ? Math.round(page.payload.score) : "—"
|
|
caption: "out of 100"
|
|
}
|
|
StatTile {
|
|
label: "Streak"
|
|
value: page.payload ? page.payload.streak.current + "d" : "—"
|
|
caption: page.payload ? "best " + page.payload.streak.best : ""
|
|
}
|
|
}
|
|
|
|
Card {
|
|
title: "Last 30 days"
|
|
subtitle: "Goal line is the dashed row; darker bars cleared it."
|
|
BarRow {
|
|
Layout.fillWidth: true
|
|
days: controller.stats.range ? controller.stats.range : []
|
|
goal: controller.goal
|
|
}
|
|
}
|
|
|
|
Card {
|
|
visible: page.payload && page.payload.achievements.length > 0
|
|
title: "Achievements"
|
|
Flow {
|
|
Layout.fillWidth: true
|
|
spacing: 8
|
|
Repeater {
|
|
model: page.payload ? page.payload.achievements : []
|
|
delegate: Pane {
|
|
required property var modelData
|
|
Material.elevation: 0
|
|
Material.roundedScale: Material.SmallScale
|
|
padding: 10
|
|
background: Rectangle {
|
|
radius: 10
|
|
color: Material.accent
|
|
opacity: 0.14
|
|
}
|
|
ColumnLayout {
|
|
spacing: 1
|
|
Label {
|
|
text: modelData.emoji + " " + modelData.title
|
|
font.weight: Font.DemiBold
|
|
font.pixelSize: 13
|
|
}
|
|
Label {
|
|
text: modelData.detail
|
|
visible: modelData.detail !== ""
|
|
font.pixelSize: 11
|
|
opacity: 0.75
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Card {
|
|
visible: page.payload && page.payload.fun_facts.length > 0
|
|
title: "The funny part"
|
|
Repeater {
|
|
model: page.payload ? page.payload.fun_facts : []
|
|
delegate: Label {
|
|
required property var modelData
|
|
text: modelData
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
font.pixelSize: 13
|
|
}
|
|
}
|
|
}
|
|
|
|
Card {
|
|
visible: page.metrics && page.metrics.tasks_completed.length > 0
|
|
title: "Closed today"
|
|
Repeater {
|
|
model: page.metrics ? page.metrics.tasks_completed : []
|
|
delegate: RowLayout {
|
|
required property var modelData
|
|
Layout.fillWidth: true
|
|
Label { text: "✅"; font.pixelSize: 12 }
|
|
Label { text: modelData.title; Layout.fillWidth: true; elide: Text.ElideRight }
|
|
Label { text: modelData.source; font.pixelSize: 11; opacity: 0.6 }
|
|
}
|
|
}
|
|
}
|
|
|
|
Card {
|
|
title: "All time"
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: 12
|
|
StatTile {
|
|
label: "Pomodoros"
|
|
value: controller.stats.lifetime ? controller.stats.lifetime.pomodoros : "—"
|
|
}
|
|
StatTile {
|
|
label: "Hours focused"
|
|
value: controller.stats.lifetime ? controller.stats.lifetime.focus_hours : "—"
|
|
}
|
|
StatTile {
|
|
label: "Tasks closed"
|
|
value: controller.stats.lifetime ? controller.stats.lifetime.tasks_completed : "—"
|
|
}
|
|
StatTile {
|
|
label: "Blocked"
|
|
value: controller.stats.lifetime ? controller.stats.lifetime.blocked_attempts : "—"
|
|
}
|
|
}
|
|
}
|
|
|
|
Label {
|
|
visible: page.payload && page.payload.verdict !== ""
|
|
text: page.payload ? page.payload.verdict : ""
|
|
font.italic: true
|
|
font.pixelSize: 14
|
|
opacity: 0.85
|
|
wrapMode: Text.WordWrap
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: controller.loadReport()
|
|
}
|