import 'package:flutter/cupertino.dart'; import 'package:please_pay_me/core/branding/app_brand.dart'; import 'package:please_pay_me/core/legal/legal_links.dart'; import 'package:please_pay_me/features/auth/session_controller.dart'; import 'package:please_pay_me/features/budgets/budgets_controller.dart'; import 'package:please_pay_me/features/journal/journal_controller.dart'; import 'package:please_pay_me/features/work/jobs_controller.dart'; import 'package:please_pay_me/theme/theme.dart'; import 'package:please_pay_me/ui/ui.dart'; import 'package:provider/provider.dart'; class ProfileScreen extends StatelessWidget { const ProfileScreen({super.key}); @override Widget build(BuildContext context) { final session = context.watch(); final user = session.user; return CupertinoPageScaffold( backgroundColor: AppColors.of(context, AppColors.groupedBackground), child: CustomScrollView( physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()), slivers: [ const AppLargeNavBar(title: 'Профиль'), SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.fromLTRB( AppSpacing.gutter, AppSpacing.s2, AppSpacing.gutter, AppSpacing.s5, ), child: Row( children: [ AppAvatar( initials: user?.initials, imageUrl: user?.photoUrl, radius: 32, ), const SizedBox(width: AppSpacing.s4), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ AppText.title(user?.displayName ?? 'Гость'), AppText.subhead(user?.handle ?? 'не авторизован'), ], ), ), ], ), ), ), SliverToBoxAdapter( child: AppListSection( header: 'Подключение', footer: session.isDemo ? 'Демо-режим: данные живут только в памяти устройства.' : 'Данные синхронизируются с веб-кабинетом «${AppBrand.name}».', separatorIndent: 60, children: [ AppListTile( leading: AppIconBadge( icon: session.isDemo ? CupertinoIcons.wrench_fill : CupertinoIcons.cloud_fill, color: session.isDemo ? AppColors.systemOrange : AppColors.systemGreen, ), title: 'Режим', value: session.isDemo ? 'Демо' : 'Сервер', showChevron: false, ), if (!session.isDemo) AppListTile( leading: const AppIconBadge( icon: CupertinoIcons.link, color: AppColors.systemGray, ), title: 'Адрес API', subtitle: session.baseUrl, showChevron: false, ), ], ), ), const SliverToBoxAdapter(child: SizedBox(height: AppSpacing.s5)), SliverToBoxAdapter( child: AppListSection( header: 'Оформление', footer: 'Системная повторяет тему устройства.', children: [ Padding( padding: const EdgeInsets.fromLTRB( AppSpacing.s3, AppSpacing.s3, AppSpacing.s3, AppSpacing.s3, ), child: AppSegmentedControl( padding: EdgeInsets.zero, labels: const ['Системная', 'Светлая', 'Тёмная'], index: context.watch().preference.index, onChanged: (index) { context.read().setPreference( ThemePreference.values[index], ); }, ), ), ], ), ), const SliverToBoxAdapter(child: SizedBox(height: AppSpacing.s5)), SliverToBoxAdapter( child: AppListSection( separatorIndent: 60, children: [ AppListTile( leading: const AppIconBadge( icon: CupertinoIcons.arrow_clockwise, color: AppColors.accent, ), title: 'Обновить данные', onTap: () => _refreshAll(context), ), ], ), ), const SliverToBoxAdapter(child: SizedBox(height: AppSpacing.s5)), SliverToBoxAdapter( child: AppListSection( header: 'Правовая информация', footer: 'Открывается веб-версия на please-pay-me.ru.', separatorIndent: 60, children: [ AppListTile( leading: const AppIconBadge( icon: CupertinoIcons.doc_text, color: AppColors.accent, ), title: 'Пользовательское соглашение', onTap: () => openLegalDocument( context, LegalLinks.resolve(session.webCabinetUrl, LegalLinks.offer), ), ), AppListTile( leading: const AppIconBadge( icon: CupertinoIcons.lock_shield, color: AppColors.systemGray, ), title: 'Политика конфиденциальности', onTap: () => openLegalDocument( context, LegalLinks.resolve(session.webCabinetUrl, LegalLinks.privacy), ), ), AppListTile( leading: const AppIconBadge( icon: CupertinoIcons.checkmark_shield, color: AppColors.systemGray, ), title: 'Согласие на обработку данных', onTap: () => openLegalDocument( context, LegalLinks.resolve(session.webCabinetUrl, LegalLinks.consent), ), ), AppListTile( leading: const AppIconBadge( icon: CupertinoIcons.circle_grid_hex, color: AppColors.systemGray, ), title: 'Политика cookie', onTap: () => openLegalDocument( context, LegalLinks.resolve(session.webCabinetUrl, LegalLinks.cookies), ), ), ], ), ), const SliverToBoxAdapter(child: SizedBox(height: AppSpacing.s5)), SliverToBoxAdapter( child: AppListSection( footer: '${AppBrand.name} · версия 0.1.0', children: [ AppListTile( title: 'Выйти', destructive: true, showChevron: false, onTap: () => _signOut(context, session), ), ], ), ), const SliverToBoxAdapter(child: SizedBox(height: AppSpacing.s7)), ], ), ); } Future _refreshAll(BuildContext context) async { await Future.wait([ context.read().load(silent: true), context.read().load(silent: true), context.read().load(silent: true), ]); if (context.mounted) { await showAppToast(context, message: 'Данные обновлены'); } } Future _signOut(BuildContext context, SessionController session) async { final confirmed = await showAppAlert( context: context, title: 'Выйти из аккаунта?', message: 'Токен будет удалён с устройства.', confirmLabel: 'Выйти', cancelLabel: 'Отмена', destructive: true, ); if (confirmed == true) await session.signOut(); } }