feat: adds RDA for intake of vitamins and certain elements based on

canada health values
This commit is contained in:
2025-08-28 15:29:20 +02:00
parent 6524e625d8
commit 31e04fe260
24 changed files with 2542 additions and 369 deletions

View File

@@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
class InfoChip extends StatelessWidget {
final IconData icon;
final String label;
final BuildContext context;
final bool fullWidth;
const InfoChip({
required this.icon,
required this.label,
required this.context,
this.fullWidth = false,
});
@override
Widget build(BuildContext context) {
return Container(
width: fullWidth ? double.infinity : null,
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.4),
borderRadius: BorderRadius.circular(8),
),
child: Row(
mainAxisSize: fullWidth ? MainAxisSize.max : MainAxisSize.min,
children: [
Icon(
icon,
size: 14,
color: Theme.of(context).colorScheme.outline,
),
const SizedBox(width: 4),
Flexible(
child: Text(
label,
style: TextStyle(
fontSize: 11,
color: Theme.of(context).colorScheme.outline,
fontWeight: FontWeight.w500,
),
overflow: TextOverflow.ellipsis,
),
),
],
),
);
}
}

View File

@@ -9,6 +9,7 @@ class SupplementCard extends StatefulWidget {
final VoidCallback onEdit;
final VoidCallback onDelete;
final VoidCallback onArchive;
final VoidCallback onDuplicate;
const SupplementCard({
super.key,
@@ -17,6 +18,7 @@ class SupplementCard extends StatefulWidget {
required this.onEdit,
required this.onDelete,
required this.onArchive,
required this.onDuplicate,
});
@override
@@ -33,7 +35,7 @@ class _SupplementCardState extends State<SupplementCard> {
final bool isTakenToday = provider.hasBeenTakenToday(widget.supplement.id!);
final int todayIntakeCount = provider.getTodayIntakeCount(widget.supplement.id!);
final bool isCompletelyTaken = todayIntakeCount >= widget.supplement.frequencyPerDay;
// Get today's intake times for this supplement
final todayIntakes = provider.todayIntakes
.where((intake) => intake['supplement_id'] == widget.supplement.id)
@@ -45,7 +47,7 @@ class _SupplementCardState extends State<SupplementCard> {
'units': unitsTaken is int ? unitsTaken.toDouble() : unitsTaken as double,
};
}).toList();
return Card(
margin: const EdgeInsets.only(bottom: 16),
elevation: 3,
@@ -175,7 +177,7 @@ class _SupplementCardState extends State<SupplementCard> {
),
),
ElevatedButton(
onPressed: isCompletelyTaken ? null : widget.onTake,
onPressed: widget.onTake,
style: ElevatedButton.styleFrom(
backgroundColor: isCompletelyTaken
? Colors.green.shade500
@@ -209,6 +211,9 @@ class _SupplementCardState extends State<SupplementCard> {
case 'edit':
widget.onEdit();
break;
case 'duplicate':
widget.onDuplicate();
break;
case 'archive':
widget.onArchive();
break;
@@ -218,6 +223,18 @@ class _SupplementCardState extends State<SupplementCard> {
}
},
itemBuilder: (context) => [
if (isTakenToday)
PopupMenuItem(
value: 'take',
onTap: widget.onTake,
child: const Row(
children: [
Icon(Icons.add_circle_outline),
SizedBox(width: 8),
Text('Take Again'),
],
),
),
const PopupMenuItem(
value: 'edit',
child: Row(
@@ -228,6 +245,16 @@ class _SupplementCardState extends State<SupplementCard> {
],
),
),
const PopupMenuItem(
value: 'duplicate',
child: Row(
children: [
Icon(Icons.copy),
SizedBox(width: 8),
Text('Duplicate'),
],
),
),
const PopupMenuItem(
value: 'archive',
child: Row(
@@ -297,10 +324,10 @@ class _SupplementCardState extends State<SupplementCard> {
runSpacing: 4,
children: todayIntakes.map((intake) {
final units = intake['units'] as double;
final unitsText = units == 1.0
final unitsText = units == 1.0
? '${widget.supplement.unitType}'
: '${units.toStringAsFixed(units % 1 == 0 ? 0 : 1)} ${widget.supplement.unitType}';
return Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
@@ -327,7 +354,7 @@ class _SupplementCardState extends State<SupplementCard> {
),
const SizedBox(height: 16),
],
// Ingredients section
Container(
padding: const EdgeInsets.all(12),
@@ -374,9 +401,9 @@ class _SupplementCardState extends State<SupplementCard> {
],
),
),
const SizedBox(height: 12),
// Schedule and dosage info
Row(
children: [
@@ -397,7 +424,7 @@ class _SupplementCardState extends State<SupplementCard> {
),
],
),
if (widget.supplement.reminderTimes.isNotEmpty) ...[
const SizedBox(height: 8),
_InfoChip(
@@ -407,7 +434,7 @@ class _SupplementCardState extends State<SupplementCard> {
fullWidth: true,
),
],
if (widget.supplement.notes != null && widget.supplement.notes!.isNotEmpty) ...[
const SizedBox(height: 8),
Container(
@@ -427,14 +454,14 @@ class _SupplementCardState extends State<SupplementCard> {
),
),
],
const SizedBox(height: 16),
// Take button
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: isCompletelyTaken ? null : widget.onTake,
onPressed: widget.onTake,
icon: Icon(
isCompletelyTaken ? Icons.check_circle : Icons.medication,
size: 18,