Files
sendico/frontend/pweb/lib/pages/dashboard/buttons/balance/carousel.dart
2026-02-05 15:36:43 +03:00

147 lines
4.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/gestures.dart';
import 'package:pshared/models/payment/wallet.dart';
import 'package:pweb/pages/dashboard/buttons/balance/add/card.dart';
import 'package:pweb/pages/dashboard/buttons/balance/balance_item.dart';
import 'package:pweb/pages/dashboard/buttons/balance/card.dart';
import 'package:pweb/pages/dashboard/buttons/balance/config.dart';
import 'package:pweb/pages/dashboard/buttons/balance/indicator.dart';
import 'package:pweb/pages/dashboard/buttons/balance/ledger.dart';
class BalanceCarousel extends StatefulWidget {
final List<BalanceItem> items;
final int currentIndex;
final ValueChanged<int> onIndexChanged;
final ValueChanged<Wallet> onTopUp;
final ValueChanged<Wallet> onWalletTap;
const BalanceCarousel({
super.key,
required this.items,
required this.currentIndex,
required this.onIndexChanged,
required this.onTopUp,
required this.onWalletTap,
});
@override
State<BalanceCarousel> createState() => _BalanceCarouselState();
}
class _BalanceCarouselState extends State<BalanceCarousel> {
late final PageController _controller;
@override
void initState() {
super.initState();
_controller = PageController(
initialPage: widget.currentIndex,
viewportFraction: WalletCardConfig.viewportFraction,
);
}
@override
void didUpdateWidget(covariant BalanceCarousel oldWidget) {
super.didUpdateWidget(oldWidget);
if (!mounted) return;
if (_controller.hasClients) {
final currentPage = _controller.page?.round();
if (currentPage != widget.currentIndex) {
_controller.jumpToPage(widget.currentIndex);
}
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _goToPage(int index) {
if (!_controller.hasClients) return;
_controller.animateToPage(
index,
duration: const Duration(milliseconds: 220),
curve: Curves.easeOut,
);
}
@override
Widget build(BuildContext context) {
if (widget.items.isEmpty) {
return const SizedBox.shrink();
}
final safeIndex = widget.currentIndex.clamp(0, widget.items.length - 1);
final scrollBehavior = ScrollConfiguration.of(context).copyWith(
dragDevices: const {
PointerDeviceKind.touch,
PointerDeviceKind.mouse,
PointerDeviceKind.trackpad,
},
);
return Column(
children: [
SizedBox(
height: WalletCardConfig.cardHeight,
child: MouseRegion(
cursor: SystemMouseCursors.grab,
child: ScrollConfiguration(
behavior: scrollBehavior,
child: PageView.builder(
controller: _controller,
onPageChanged: widget.onIndexChanged,
itemCount: widget.items.length,
itemBuilder: (context, index) {
final item = widget.items[index];
final Widget card = switch (item.type) {
BalanceItemType.wallet => WalletCard(
wallet: item.wallet!,
onTopUp: () => widget.onTopUp(item.wallet!),
onTap: () => widget.onWalletTap(item.wallet!),
),
BalanceItemType.ledger => LedgerAccountCard(account: item.account!),
BalanceItemType.addAction => const AddBalanceCard(),
};
return Padding(
padding: WalletCardConfig.cardPadding,
child: card,
);
},
),
),
),
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconButton(
onPressed: safeIndex > 0
? () => _goToPage(safeIndex - 1)
: null,
icon: const Icon(Icons.arrow_back),
),
const SizedBox(width: 16),
CarouselIndicator(
itemCount: widget.items.length,
index: safeIndex,
),
const SizedBox(width: 16),
IconButton(
onPressed: safeIndex < widget.items.length - 1 ? () => _goToPage(safeIndex + 1) : null,
icon: const Icon(Icons.arrow_forward),
),
],
),
],
);
}
}