feat: implement Iteration 6 — profile screen

Add ProfileService (GET/PUT /profile), ProfileNotifier provider,
and full ProfileScreen with body-params, goal/activity, daily-calories
sections and logout confirmation. EditProfileSheet lets user update
name, height, weight, age, gender, goal and activity; backend
auto-recalculates daily_calories via Mifflin-St Jeor.
HomeScreen greeting now shows the user's real name from profileProvider.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
dbastrikin
2026-02-22 16:58:35 +02:00
parent 79c32f226c
commit c8b8c33bcb
4 changed files with 672 additions and 7 deletions

View File

@@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../shared/models/home_summary.dart';
import '../profile/profile_provider.dart';
import 'home_provider.dart';
class HomeScreen extends ConsumerWidget {
@@ -12,6 +13,7 @@ class HomeScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final state = ref.watch(homeProvider);
final userName = ref.watch(profileProvider).valueOrNull?.name;
return Scaffold(
body: state.when(
@@ -26,7 +28,7 @@ class HomeScreen extends ConsumerWidget {
onRefresh: () => ref.read(homeProvider.notifier).load(),
child: CustomScrollView(
slivers: [
_AppBar(summary: summary),
_AppBar(summary: summary, userName: userName),
SliverPadding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 100),
sliver: SliverList(
@@ -62,15 +64,22 @@ class HomeScreen extends ConsumerWidget {
class _AppBar extends StatelessWidget {
final HomeSummary summary;
const _AppBar({required this.summary});
final String? userName;
const _AppBar({required this.summary, this.userName});
String get _greeting {
String get _greetingBase {
final hour = DateTime.now().hour;
if (hour < 12) return 'Доброе утро';
if (hour < 18) return 'Добрый день';
return 'Добрый вечер';
}
String get _greeting {
final name = userName;
if (name != null && name.isNotEmpty) return '$_greetingBase, $name!';
return _greetingBase;
}
String get _dateLabel {
final now = DateTime.now();
const months = [