Refine views for mobile-first and responsive layouts

This commit is contained in:
Rijad Zuzo
2026-02-15 17:20:52 +01:00
parent 4d21c6df82
commit 90c1a21d71
10 changed files with 1431 additions and 728 deletions
+93 -66
View File
@@ -19,71 +19,89 @@ class DashboardView extends ConsumerWidget {
final DashboardSummary summary = data.summary();
final List<DashboardTask> tasks = data.tasks;
return SingleChildScrollView(
padding: const EdgeInsets.fromLTRB(28, 24, 28, 36),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Today', style: Theme.of(context).textTheme.headlineMedium),
const SizedBox(height: 8),
Text(
'Focus on consistency over intensity. Small moments compound.',
style: Theme.of(
context,
).textTheme.bodyLarge?.copyWith(color: AppTheme.textSecondary),
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
final bool compact = constraints.maxWidth < 720;
return SingleChildScrollView(
padding: EdgeInsets.fromLTRB(
compact ? 16 : 28,
compact ? 16 : 24,
compact ? 16 : 28,
compact ? 24 : 36,
),
const SizedBox(height: 22),
Wrap(
spacing: 16,
runSpacing: 16,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_StatCard(
label: 'Active People',
value: '${summary.activePeople}',
accent: const Color(0xFF16B8CA),
Text(
'Today',
style: Theme.of(context).textTheme.headlineMedium,
),
_StatCard(
label: 'Upcoming Plans',
value: '${summary.upcomingPlans}',
accent: const Color(0xFF2B7FFF),
const SizedBox(height: 8),
Text(
'Focus on consistency over intensity. Small moments compound.',
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: AppTheme.textSecondary,
),
),
_StatCard(
label: 'Pending Ideas',
value: '${summary.pendingIdeas}',
accent: const Color(0xFFFFA447),
const SizedBox(height: 22),
Wrap(
spacing: 12,
runSpacing: 12,
children: <Widget>[
_StatCard(
label: 'Active People',
value: '${summary.activePeople}',
accent: const Color(0xFF16B8CA),
compact: compact,
),
_StatCard(
label: 'Upcoming Plans',
value: '${summary.upcomingPlans}',
accent: const Color(0xFF2B7FFF),
compact: compact,
),
_StatCard(
label: 'Pending Ideas',
value: '${summary.pendingIdeas}',
accent: const Color(0xFFFFA447),
compact: compact,
),
_StatCard(
label: 'Weekly Rhythm',
value: '${summary.weeklyConsistency}%',
accent: const Color(0xFF30B66A),
compact: compact,
),
],
),
_StatCard(
label: 'Weekly Rhythm',
value: '${summary.weeklyConsistency}%',
accent: const Color(0xFF30B66A),
const SizedBox(height: 24),
FrostedCard(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Next Moves',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 14),
...tasks.map(
(DashboardTask task) => _TaskRow(
task: task,
compact: compact,
onToggleDone: () {
ref
.read(localRepositoryProvider.notifier)
.toggleTaskDone(task.id);
},
),
),
],
),
),
],
),
const SizedBox(height: 24),
FrostedCard(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Next Moves',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 14),
...tasks.map(
(DashboardTask task) => _TaskRow(
task: task,
onToggleDone: () {
ref
.read(localRepositoryProvider.notifier)
.toggleTaskDone(task.id);
},
),
),
],
),
),
],
),
);
},
);
},
loading: () => const Center(child: CircularProgressIndicator()),
@@ -104,18 +122,20 @@ class _StatCard extends StatelessWidget {
required this.label,
required this.value,
required this.accent,
required this.compact,
});
final String label;
final String value;
final Color accent;
final bool compact;
@override
Widget build(BuildContext context) {
return FrostedCard(
padding: const EdgeInsets.all(16),
child: SizedBox(
width: 188,
width: compact ? double.infinity : 188,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
@@ -149,10 +169,15 @@ class _StatCard extends StatelessWidget {
}
class _TaskRow extends StatelessWidget {
const _TaskRow({required this.task, required this.onToggleDone});
const _TaskRow({
required this.task,
required this.onToggleDone,
required this.compact,
});
final DashboardTask task;
final VoidCallback onToggleDone;
final bool compact;
@override
Widget build(BuildContext context) {
@@ -200,13 +225,15 @@ class _TaskRow extends StatelessWidget {
],
),
),
const SizedBox(width: 12),
Text(
_shortDate(task.when),
style: Theme.of(
context,
).textTheme.labelLarge?.copyWith(color: AppTheme.textSecondary),
),
if (!compact) ...<Widget>[
const SizedBox(width: 12),
Text(
_shortDate(task.when),
style: Theme.of(
context,
).textTheme.labelLarge?.copyWith(color: AppTheme.textSecondary),
),
],
],
),
),