Files
sf-app-platform/modules/home/lib/src/presentation/home_screen.dart

133 lines
4.7 KiB
Dart
Raw Normal View History

import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
2026-02-25 18:37:17 +01:00
import 'package:home/src/presentation/child_wallets_slider.dart';
import 'package:home/src/presentation/state/home_view_model.dart';
import 'package:payments/payments.dart';
import 'package:sf_shared/sf_shared.dart';
import 'package:sf_localizations/sf_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:navigation/navigation.dart';
class HomeScreen extends ConsumerWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final theme = ref.watch(themePortProvider);
final viewState = ref.watch(homeViewModelProvider);
if (viewState.isLoading) {
return const Center(child: AppLoadingIndicator());
}
if (viewState.errorMessage.isNotEmpty) {
return _buildError(context, ref, theme, viewState.errorMessage);
}
final NavigationContract navigationContract = GetIt.I<NavigationContract>();
2026-02-25 18:37:17 +01:00
final balance = ref.watch(parentWalletBalanceProvider);
final accountTotalBalance =
ref.watch(accountTotalBalanceProvider).value ?? balance?.totalBalance ?? 0;
return SafeArea(
child: SingleChildScrollView(
child: Container(
color: theme.getColorFor(ThemeCode.backgroundSecondary),
margin: EdgeInsets.all(30),
child: Column(
children: [
2026-03-13 09:44:59 +01:00
Align(
alignment: Alignment.centerLeft,
child: Text.rich(
TextSpan(
text: context.translate(I18n.homeGreeting),
style: TextStyle(fontSize: 25),
children: <TextSpan>[
TextSpan(
2026-03-13 09:44:59 +01:00
text: viewState.userName,
style: TextStyle(fontWeight: FontWeight.w500),
),
2026-03-13 09:44:59 +01:00
],
),
2026-03-13 09:44:59 +01:00
),
),
2026-02-25 18:37:17 +01:00
const ChildWalletsSlider(),
Align(
alignment: Alignment.topLeft,
child: TextButton(
onPressed: () =>
navigationContract.pushTo(AppRoutes.deviceSetup),
child: Text(
context.translate(I18n.homeAddAnotherKid),
style: TextStyle(
fontWeight: FontWeight.bold,
color: theme.getColorFor(ThemeCode.textPrimary),
),
),
),
),
if (balance != null)
WalletBalanceBlock(
2026-02-25 18:37:17 +01:00
availableBalance: balance.availableBalance,
allocatedBalance: balance.allocatedBalance,
totalBalance: balance.totalBalance,
),
if (balance != null)
DepositBlock(
2026-02-25 18:37:17 +01:00
max: 150 - accountTotalBalance,
onDeposit: (amount) async {
final result = await showPayinBottomSheet(
context,
amount: amount,
navigation: navigationContract,
);
if (result == true && context.mounted) {
showTopSnackbar(context, message: context.translate(I18n.payinSuccess), type: MessageType.success);
2026-02-25 18:37:17 +01:00
ref.read(parentWalletBalanceProvider.notifier).applyOptimisticPayin(amount);
return true;
}
2026-02-25 18:37:17 +01:00
return false;
},
),
],
),
),
),
);
}
Widget _buildError(BuildContext context, WidgetRef ref, ThemePort theme, String message) {
final viewModel = ref.read(homeViewModelProvider.notifier);
return Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
context.translate(I18n.errorLoadingData),
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: theme.getColorFor(ThemeCode.textPrimary),
),
),
const SizedBox(height: 8),
Text(
message,
textAlign: TextAlign.center,
style: TextStyle(color: theme.getColorFor(ThemeCode.textPrimary)),
),
const SizedBox(height: 16),
TextButton(
onPressed: () => viewModel.retry(),
child: Text(context.translate(I18n.retry)),
),
],
),
),
);
}
}