Files
weight-tracker/lib/pages/home/home_view.dart
2026-02-24 22:38:01 +01:00

129 lines
4.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../controllers/home_controller.dart';
import '../../models/home_model.dart';
import '../../widgets/glass_app_bar.dart';
import '../../widgets/person_weight_card.dart';
class HomePage extends GetView<HomeController> {
static const String namedRoute = '/home-page';
const HomePage({super.key});
/// Gruppiert eine flache Liste nach `name` und gibt eine Map zurück,
/// die je Person alle zugehörigen Einträge enthält.
Map<String, List<WeightModel>> _groupByName(List<WeightModel> weights) {
final map = <String, List<WeightModel>>{};
for (final w in weights) {
map.putIfAbsent(w.name, () => []).add(w);
}
return map;
}
@override
Widget build(BuildContext context) {
final homeCtrl = controller;
return Scaffold(
extendBodyBehindAppBar: true,
appBar: GlassAppBar(
title: 'Weight Tracker',
subtitle: 'Verfolge dein Gewicht',
),
body: Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Color(0xFF0D0F14),
Color(0xFF141824),
Color(0xFF1A2035),
Color(0xFF0F1520),
],
stops: [0.0, 0.35, 0.65, 1.0],
),
),
child: Obx(() {
if (homeCtrl.isloading.value) {
return const Center(child: CircularProgressIndicator());
}
if (homeCtrl.weights.isEmpty) {
return const Center(
child: Text(
'Noch keine Gewichtsangaben.\nKlicke auf das "+" Symbol, um deinen ersten Eintrag hinzuzufügen.',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18, color: Colors.white70),
),
);
}
final grouped = _groupByName(homeCtrl.weights);
final names = grouped.keys.toList()..sort();
return LayoutBuilder(
builder: (context, constraints) {
// Responsive: ab 700 px Breite → 2-spaltiges Grid
final isWide = constraints.maxWidth >= 700;
return CustomScrollView(
slivers: [
SliverPadding(
padding: EdgeInsets.only(
top: MediaQuery.of(context).padding.top + 96,
left: isWide ? 24 : 16,
right: isWide ? 24 : 16,
bottom: 24,
),
sliver: isWide
? SliverGrid(
gridDelegate:
const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 600,
mainAxisSpacing: 16,
crossAxisSpacing: 16,
childAspectRatio: 0.95,
),
delegate: SliverChildBuilderDelegate(
(context, i) => PersonWeightCard(
personName: names[i],
entries: grouped[names[i]]!,
onAddWeight: () => homeCtrl.openAddDialog(
names[i],
grouped[names[i]]!.first.documentId,
),
onEditEntry: (entry) =>
homeCtrl.openEditDialog(entry),
),
childCount: names.length,
),
)
: SliverList(
delegate: SliverChildBuilderDelegate(
(context, i) => Padding(
padding: const EdgeInsets.only(bottom: 16),
child: PersonWeightCard(
personName: names[i],
entries: grouped[names[i]]!,
onAddWeight: () => homeCtrl.openAddDialog(
names[i],
grouped[names[i]]!.first.documentId,
),
onEditEntry: (entry) =>
homeCtrl.openEditDialog(entry),
),
),
childCount: names.length,
),
),
),
],
);
},
);
}),
),
);
}
}