Files
dailyou/lib/features/log_mood/widgets/activities_chip.dart
T
stefwill 6f3fb74e7e feat: implement multi-step mood logging wizard
Adds sleep/energy/positivity/self-worth tracking columns to the database
(schema v2 migration), a new 5-option StepScale widget, per-answer chips
at the top of the screen, a 2×2 activity grid chip, and a full step-by-step
wizard flow: mood → sleep (first entry today only) → energy → positivity →
self-worth → activities → review+save.
2026-04-26 12:14:45 +10:00

86 lines
2.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/database/app_database.dart';
import '../../../core/providers/activity_provider.dart';
/// 60 px chip showing selected activities:
/// - 0 selected : nothing (caller should not render)
/// - 1 selected : single Material icon centred
/// - 24 selected: 2×2 mini grid of 16 px icons
/// - 5+ selected : icon + count badge
class ActivitiesChip extends ConsumerWidget {
final Color backgroundColor;
final VoidCallback? onTap;
const ActivitiesChip({
super.key,
required this.backgroundColor,
this.onTap,
});
@override
Widget build(BuildContext context, WidgetRef ref) {
final activitiesAsync = ref.watch(activitiesProvider);
final selected = ref.watch(selectedActivitiesProvider);
return activitiesAsync.when(
loading: () => _shell(backgroundColor, onTap,
const CircularProgressIndicator(strokeWidth: 2)),
error: (_, __) => const SizedBox.shrink(),
data: (all) {
final picked =
all.where((a) => selected.contains(a.id)).toList();
if (picked.isEmpty) return const SizedBox(width: 60, height: 60);
return _shell(
backgroundColor,
onTap,
_iconContent(picked),
);
},
);
}
Widget _shell(Color bg, VoidCallback? tap, Widget child) {
return GestureDetector(
onTap: tap,
child: Container(
width: 60,
height: 60,
decoration: BoxDecoration(color: bg, shape: BoxShape.circle),
child: Center(child: child),
),
);
}
Widget _iconContent(List<Activity> picked) {
if (picked.length == 1) {
return Text(
String.fromCharCode(picked[0].iconCodepoint),
style: const TextStyle(
fontFamily: 'MaterialIcons',
fontSize: 24,
color: Colors.white,
),
);
}
final show = picked.take(4).toList();
return Wrap(
spacing: 2,
runSpacing: 2,
children: show
.map(
(a) => Text(
String.fromCharCode(a.iconCodepoint),
style: const TextStyle(
fontFamily: 'MaterialIcons',
fontSize: 16,
color: Colors.white,
),
),
)
.toList(),
);
}
}