mirror of
https://github.com/joaovitoriasilva/endurain.git
synced 2026-01-09 15:57:59 -05:00
Add target lines and labels to health charts
Enhanced Health dashboard, steps, and weight components to display user target values with visual indicators and updated i18n labels. Steps and weight charts now show dashed target lines if targets are set, and card footers display units and icons for progress direction.
This commit is contained in:
@@ -16,9 +16,14 @@
|
||||
<h1 v-else>{{ $t('generalItems.labelNotApplicable') }}</h1>
|
||||
</div>
|
||||
<div class="card-footer text-body-secondary">
|
||||
<span v-if="userHealthTargets && userHealthTargets['weight']">{{
|
||||
userHealthTargets.weight
|
||||
}}</span>
|
||||
<font-awesome-icon :icon="['fas', 'angle-down']" class="me-1" v-if="currentWeight > userHealthTargets.weight" />
|
||||
<font-awesome-icon :icon="['fas', 'angle-up']" class="me-1" v-else/>
|
||||
<span v-if="userHealthTargets && userHealthTargets['weight'] && Number(authStore?.user?.units) === 1">
|
||||
{{ userHealthTargets.weight }} {{ $t('generalItems.unitsKg') }}
|
||||
</span>
|
||||
<span v-else-if="userHealthTargets && userHealthTargets['weight'] && Number(authStore?.user?.units) === 2">
|
||||
{{ kgToLbs(userHealthTargets.weight) }} {{ $t('generalItems.unitsLbs') }}
|
||||
</span>
|
||||
<span v-else>{{ $t('healthDashboardZoneComponent.noWeightTarget') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -51,9 +56,11 @@
|
||||
<h1 v-else>{{ $t('generalItems.labelNotApplicable') }}</h1>
|
||||
</div>
|
||||
<div class="card-footer text-body-secondary">
|
||||
<span v-if="userHealthTargets && userHealthTargets['steps']">{{
|
||||
userHealthTargets.steps
|
||||
}}</span>
|
||||
<span v-if="userHealthTargets && userHealthTargets['steps']">
|
||||
<font-awesome-icon :icon="['fas', 'angle-down']" class="me-1" v-if="todaySteps < userHealthTargets.steps" />
|
||||
<font-awesome-icon :icon="['fas', 'angle-up']" class="me-1" v-else/>
|
||||
{{ userHealthTargets.steps }} {{ $t('healthDashboardZoneComponent.stepsTargetLabel') }}
|
||||
</span>
|
||||
<span v-else>{{ $t('healthDashboardZoneComponent.noStepsTarget') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
class="mt-3 p-3 bg-body-tertiary rounded shadow-sm"
|
||||
>
|
||||
<!-- show graph -->
|
||||
<HealthStepsBarChartComponent :userHealthSteps="dataWithSteps" :isLoading="isLoading" />
|
||||
<HealthStepsBarChartComponent :userHealthTargets="userHealthTargets":userHealthSteps="dataWithSteps" :isLoading="isLoading" />
|
||||
|
||||
<br />
|
||||
<p>
|
||||
|
||||
@@ -14,6 +14,10 @@ import zoomPlugin from 'chartjs-plugin-zoom'
|
||||
Chart.register(...registerables, zoomPlugin)
|
||||
|
||||
const props = defineProps({
|
||||
userHealthTargets: {
|
||||
type: [Object, null],
|
||||
required: true
|
||||
},
|
||||
userHealthSteps: {
|
||||
type: Object,
|
||||
required: true
|
||||
@@ -73,20 +77,38 @@ function updatedSortedArray() {
|
||||
`${createdAt.getDate()}/${createdAt.getMonth() + 1}/${createdAt.getFullYear()}`
|
||||
)
|
||||
}
|
||||
|
||||
const datasets = [
|
||||
{
|
||||
label: t('generalItems.labelSteps'),
|
||||
data: data,
|
||||
backgroundColor: function (context) {
|
||||
const chart = context.chart
|
||||
const { ctx, chartArea } = chart
|
||||
return 'rgba(59, 130, 246, 0.4)'
|
||||
},
|
||||
borderColor: 'rgba(59, 130, 246, 0.8)', // Blue border
|
||||
borderWidth: 1
|
||||
}
|
||||
]
|
||||
|
||||
// Add target line if steps target exists
|
||||
if (props.userHealthTargets?.steps != null) {
|
||||
datasets.push({
|
||||
label: t('generalItems.labelStepsTarget'),
|
||||
data: Array(labels.length).fill(props.userHealthTargets.steps),
|
||||
type: 'line',
|
||||
borderColor: 'rgba(107, 114, 128, 0.9)',
|
||||
borderWidth: 2,
|
||||
borderDash: [5, 5],
|
||||
fill: false,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 0
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
datasets: [
|
||||
{
|
||||
label: t('healthStepsListComponent.labelSteps'),
|
||||
data: data,
|
||||
backgroundColor: function (context) {
|
||||
const chart = context.chart
|
||||
const { ctx, chartArea } = chart
|
||||
return 'rgba(59, 130, 246, 0.4)'
|
||||
},
|
||||
borderColor: 'rgba(59, 130, 246, 0.8)', // Blue border
|
||||
borderWidth: 1
|
||||
}
|
||||
],
|
||||
datasets: datasets,
|
||||
labels: labels
|
||||
}
|
||||
})
|
||||
@@ -167,7 +189,7 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
// Format weight with 1 decimal place
|
||||
return `${label}: ${value.toFixed(1)}`
|
||||
return `${label}: ${value}`
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
class="mt-3 p-3 bg-body-tertiary rounded shadow-sm"
|
||||
>
|
||||
<!-- show graph -->
|
||||
<HealthWeightLineChartComponent :userHealthWeight="dataWithWeight" :isLoading="isLoading" />
|
||||
<HealthWeightLineChartComponent :userHealthTargets="userHealthTargets" :userHealthWeight="dataWithWeight" :isLoading="isLoading" />
|
||||
|
||||
<br />
|
||||
<p>
|
||||
|
||||
@@ -17,6 +17,10 @@ import zoomPlugin from 'chartjs-plugin-zoom'
|
||||
Chart.register(...registerables, zoomPlugin)
|
||||
|
||||
const props = defineProps({
|
||||
userHealthTargets: {
|
||||
type: [Object, null],
|
||||
required: true
|
||||
},
|
||||
userHealthWeight: {
|
||||
type: Object,
|
||||
required: true
|
||||
@@ -100,25 +104,51 @@ function updatedSortedArray() {
|
||||
label = t('generalItems.labelWeightInLbs')
|
||||
}
|
||||
|
||||
const datasets = [
|
||||
{
|
||||
label: label,
|
||||
data: data,
|
||||
backgroundColor: function (context) {
|
||||
const chart = context.chart
|
||||
const { ctx, chartArea } = chart
|
||||
if (!chartArea) {
|
||||
return 'rgba(59, 130, 246, 0.4)'
|
||||
}
|
||||
return createGradient(ctx, chartArea)
|
||||
},
|
||||
borderColor: 'rgba(59, 130, 246, 0.8)', // Blue border
|
||||
fill: true,
|
||||
pointHoverRadius: 4,
|
||||
pointHoverBackgroundColor: 'rgba(59, 130, 246, 0.8)'
|
||||
}
|
||||
]
|
||||
|
||||
// Add target line if weight target exists
|
||||
if (props.userHealthTargets?.weight != null) {
|
||||
const targetWeight =
|
||||
Number(authStore?.user?.units) === 1
|
||||
? props.userHealthTargets.weight
|
||||
: kgToLbs(props.userHealthTargets.weight)
|
||||
|
||||
const targetLabel =
|
||||
Number(authStore?.user?.units) === 1
|
||||
? t('generalItems.labelWeightTargetInKg')
|
||||
: t('generalItems.labelWeightTargetInLbs')
|
||||
|
||||
datasets.push({
|
||||
label: targetLabel,
|
||||
data: Array(labels.length).fill(targetWeight),
|
||||
borderColor: 'rgba(107, 114, 128, 0.9)',
|
||||
borderWidth: 2,
|
||||
borderDash: [5, 5],
|
||||
fill: false,
|
||||
pointRadius: 0,
|
||||
pointHoverRadius: 0
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
datasets: [
|
||||
{
|
||||
label: label,
|
||||
data: data,
|
||||
backgroundColor: function (context) {
|
||||
const chart = context.chart
|
||||
const { ctx, chartArea } = chart
|
||||
if (!chartArea) {
|
||||
return 'rgba(59, 130, 246, 0.4)'
|
||||
}
|
||||
return createGradient(ctx, chartArea)
|
||||
},
|
||||
borderColor: 'rgba(59, 130, 246, 0.8)', // Blue border
|
||||
fill: true,
|
||||
pointHoverRadius: 4,
|
||||
pointHoverBackgroundColor: 'rgba(59, 130, 246, 0.8)'
|
||||
}
|
||||
],
|
||||
datasets: datasets,
|
||||
labels: labels
|
||||
}
|
||||
})
|
||||
|
||||
@@ -11,5 +11,6 @@
|
||||
"bmiObesityClass2": "Obesity (Class 2)",
|
||||
"bmiObesityClass3": "Extreme Obesity (Class 3)",
|
||||
"steps": "Today's steps",
|
||||
"stepsTargetLabel": "steps",
|
||||
"noStepsTarget": "No steps target"
|
||||
}
|
||||
@@ -36,6 +36,7 @@
|
||||
"unitsKmH": "km/h",
|
||||
"unitsKg": "kg",
|
||||
"labelWeightInKg": "Weight in kg",
|
||||
"labelWeightTargetInKg": "Weight target in kg",
|
||||
"unitsInches": "inches",
|
||||
"unitsFeet": "feet",
|
||||
"unitsFeetShort": "ft",
|
||||
@@ -45,6 +46,9 @@
|
||||
"unitsMph": "mph",
|
||||
"unitsLbs": "lbs",
|
||||
"labelWeightInLbs": "Weight in lbs",
|
||||
"labelWeightTargetInLbs": "Weight target in lbs",
|
||||
"labelSteps": "Steps",
|
||||
"labelStepsTarget": "Steps target",
|
||||
"unitsCalories": "kcal",
|
||||
"unitsBpm": "bpm",
|
||||
"labelHRinBpm": "Heart rate in bpm",
|
||||
@@ -79,4 +83,4 @@
|
||||
"genderUnspecified": "Unspecified",
|
||||
"labelAverage": "Average",
|
||||
"labelMaximum": "Maximum"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user