import 'package:flutter/material.dart'; import 'package:gymlink_module_web/components/app_bar.dart'; import 'package:gymlink_module_web/components/basket_item_card.dart'; import 'package:gymlink_module_web/components/heading.dart'; import 'package:gymlink_module_web/interfaces/items.dart'; import 'package:gymlink_module_web/pages/order_confirmation.dart'; import 'package:gymlink_module_web/providers/cart.dart'; import 'package:gymlink_module_web/tools/items.dart'; import 'package:gymlink_module_web/tools/prefs.dart'; import 'package:gymlink_module_web/tools/routes.dart'; import 'package:lazy_load_scrollview/lazy_load_scrollview.dart'; import 'package:provider/provider.dart'; List> cart = [ { "name": "Протеин", "image": "product.png", "price": "120", "details": "Test details", "id": "34fa3126-bfaf-5dec-8f4a-b246c097ef73" }, { "name": "Протеин", "image": "product.png", "price": "150", "details": "Test details", "id": "34a26e82-7656-5e98-a44a-c2d01d0b1ad1123" }, { "name": "Протеин", "image": "product.png", "price": "250", "details": "Test details", "id": "4fb204b7-3f9e-52a2-bed1-415c00a31a37123" }, { "name": "Протеин", "image": "product.png", "price": "300", "details": "Test details", "id": "09b2f5bb-683e-5c39-ae89-b8e152fa8bcf123" }, { "name": "Протеин", "image": "product.png", "price": "100", "details": "Test details", "id": "cd1b6817-db94-5394-be1d-af88af79749f123" } ]; class BasketPage extends StatefulWidget { const BasketPage({super.key}); @override State createState() => _BasketPageState(); } class _BasketPageState extends State { List cartItems = []; double totalPrice = 0; List gymCart = []; bool _isLoading = true; @override void initState() { super.initState(); Future.microtask(() => getCart().then((value) async { final itemIds = value.map((element) => element['id'] as String).toList(); final items = await getItemsByIds(context, itemIds); setState(() { gymCart = items; cartItems = value.map((element) { final item = gymCart.firstWhere((e) => e.id == element['id']); item.localCount = element['count'] as int; return item; }).toList(); totalPrice = cartItems.fold( 0, (sum, item) => sum + item.price * item.localCount); _isLoading = false; }); })); } void _updateCart() { Provider.of(context, listen: false).updateCartLength(); } void removeItem(String id) async { final item = cartItems.firstWhere((element) => element.id == id); bool toDelete = false; setState(() { if (item.localCount > 1) { item.localCount--; cartItems[cartItems.indexOf(item)].localCount = item.localCount; } else { toDelete = true; } totalPrice = cartItems.fold(0, (sum, item) => sum + item.price * item.localCount); }); if (toDelete) { await _deleteItemAlert(id, item.title); } else { await removeItemFromCart(id); } } void addItem(String id) async { setState(() { final item = cartItems.firstWhere((element) => element.id == id, orElse: () { final cartItem = gymCart.firstWhere((element) => element.id == id); cartItem.localCount = 0; return cartItem; }); item.localCount++; cartItems[cartItems.indexOf(item)].localCount = item.localCount; totalPrice = cartItems.fold(0, (sum, item) => sum + item.price * item.localCount); }); await addItemToCart(id); } Future _deleteItemAlert(String id, String name) async { return showDialog( context: context, barrierDismissible: true, builder: (BuildContext context) { return AlertDialog( title: const Text('Удаление из корзины'), content: SingleChildScrollView( child: ListBody( children: [ Text('Вы действительно хотите убрать "$name" из корзины?'), ], ), ), actions: [ TextButton( child: const Text('Отмена'), onPressed: () { Navigator.of(context).pop(); }, ), TextButton( child: const Text('Удалить'), onPressed: () { removeItemFromCart(id); setState(() { cartItems.removeWhere((element) => element.id == id); }); if (mounted) { _updateCart(); } Navigator.of(context).pop(); }, ), ], ); }, ); } Future _clearCartAlert() async { return showDialog( context: context, barrierDismissible: true, builder: (BuildContext context) { return AlertDialog( title: const Text('Очистка корзины'), content: const SingleChildScrollView( child: ListBody( children: [ Text('Вы действительно хотите очистить корзину?'), ], ), ), actions: [ TextButton( child: const Text('Отмена'), onPressed: () { Navigator.of(context).pop(); }, ), TextButton( child: const Text('Очистить'), onPressed: () { clearCart(); setState(() { cartItems = []; }); if (mounted) { _updateCart(); } Navigator.of(context).pop(); }, ), ], ); }, ); } Widget _buildRowOrCol( {required BuildContext context, required List children}) { if (MediaQuery.of(context).size.width > 600) { return Row(children: children); } return Column(children: children); } Widget _buildSpacer() { if (MediaQuery.of(context).size.width > 600) { return const Spacer(); } return const SizedBox(height: 10); } void _onLoad() async { await Future.delayed(const Duration(microseconds: 1000)); setState(() {}); } @override Widget build(BuildContext context) { return Scaffold( appBar: const GymLinkAppBar(), body: Column( children: [ const GymLinkHeader(title: "Корзина"), _isLoading ? const Expanded( child: Center(child: CircularProgressIndicator())) : cartItems.isEmpty ? Expanded( child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Корзина пуста', style: Theme.of(context).textTheme.bodyLarge), const SizedBox(height: 10), ElevatedButton( onPressed: () => Navigator.pop(context, true), style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).primaryColor, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(50)), ), foregroundColor: Colors.white, ), child: const Text('Вернуться назад'), ), ], ), ), ) : Expanded( child: _buildRowOrCol( context: context, children: [ Expanded( child: LazyLoadScrollView( onEndOfPage: _onLoad, child: ListView.builder( itemCount: cartItems.length, itemBuilder: (context, index) { final item = cartItems[index]; return BasketItemCard( name: item.title, price: item.price.toString(), id: item.id, image: Image( image: NetworkImage(item.images[0].url), width: 50, ), onTapPlus: () => addItem(item.id.toString()), onTapMinus: () { removeItem(item.id.toString()); }, quantity: item.localCount.toString(), ); }, ), ), ), _buildSpacer(), Padding( padding: const EdgeInsetsDirectional.symmetric( horizontal: 10, vertical: 10), child: Column( children: [ Text( 'Итого: $totalPrice руб.', ), ElevatedButton( onPressed: () => Navigator.of(context).push( CustomPageRoute( builder: (context) => const OrderConfirmationPage(), ), ), style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).primaryColor, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(50)), ), foregroundColor: Colors.white, ), child: const Text('Оформить заказ'), ), const SizedBox(height: 10), ElevatedButton( onPressed: _clearCartAlert, style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).primaryColor, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all( Radius.circular(50))), foregroundColor: Colors.white, ), child: const Text('Очистить корзину'), ), ], ), ), const SizedBox(width: 50), ], ), ), ], ), ); } }