import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:gymlink_module_web/components/app_bar.dart'; import 'package:gymlink_module_web/components/heading.dart'; import 'package:gymlink_module_web/components/order_confirm_item_card.dart'; import 'package:gymlink_module_web/interfaces/items.dart'; import 'package:gymlink_module_web/pages/order_history.dart'; import 'package:gymlink_module_web/providers/cart.dart'; import 'package:gymlink_module_web/tools/history.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:gymlink_module_web/tools/text.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.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 OrderConfirmationPage extends StatefulWidget { const OrderConfirmationPage({super.key}); @override State createState() => _OrderConfirmationPageState(); } class _OrderConfirmationPageState extends State { List cartItems = []; double totalPrice = 0; List gymCart = []; bool isAgree = false; bool _isLoading = true; final _emailController = TextEditingController(); final _addressController = TextEditingController(); final _nameController = TextEditingController(); Future _addOrderToHistory() async { String name = _nameController.text; String email = _emailController.text; String address = _addressController.text; Set supplierIdsSet = {}; for (final item in cartItems) { supplierIdsSet.add(item.supplierId); } List providers = []; for (final supplierId in supplierIdsSet) { List items = cartItems.where((e) => e.supplierId == supplierId).toList(); List detailItems = []; for (final item in items) { detailItems.add(GymHistoryItemDetailItem( id: item.id, photo: item.images[0].url, count: item.localCount, price: item.price.toString(), name: item.title, )); } GymHistoryItemDetailProvider provider = GymHistoryItemDetailProvider( id: supplierId, name: items.first.supplierName, items: detailItems, // status: 'Не оплачен' status: Random().nextBool() ? 'Не оплачен' : Random().nextBool() ? 'Не оплачен' : Random().nextBool() ? 'Сборка' : 'Доставляется', ); providers.add(provider); } final order = GymHistoryItemDetail( id: Random().nextInt(1000000).toString(), receiver: name, email: email, address: address, sum: totalPrice.toString(), date: '', providers: providers, ); await addToHistory(order); } @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; }); })); } Future _goToPage() async { final Uri url = Uri.parse('https://example.org'); if (!await launchUrl(url, webOnlyWindowName: '_blank')) { throw 'Could not launch $url'; } } bool _checkInputs() { final email = _emailController.text; final address = _addressController.text; final name = _nameController.text; if (!RegExp(r"^((?!\.)[\w\-_.]*[^.])(@\w+)(\.\w+(\.\w+)?[^.\W])$") .hasMatch(email)) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Ошибка'), content: const Text('Некорректный email'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('ОК'), ) ], ), ); return false; } if (address.isEmpty) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Ошибка'), content: const Text('Адрес не может быть пустым'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('ОК'), ) ], ), ); return false; } if (name.isEmpty) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Ошибка'), content: const Text('ФИО не может быть пустым'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('ОК'), ) ], ), ); return false; } return true; } @override Widget build(BuildContext context) { return Scaffold( appBar: const GymLinkAppBar(), resizeToAvoidBottomInset: false, body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const GymLinkHeader(title: 'Оформление заказа'), const MarkdownBody(data: '## Состав заказа:'), Expanded( child: _isLoading ? const Center(child: CircularProgressIndicator()) : ConstrainedBox( constraints: const BoxConstraints(maxHeight: 350), child: ListView.builder( shrinkWrap: true, itemCount: cartItems.length, itemBuilder: (context, index) { final item = cartItems[index]; return OrderConfirmItemCard( name: shortString(item.title), image: FutureBuilder( future: precacheImage( NetworkImage(item.images[0].url), context), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { return Image( image: NetworkImage(item.images[0].url), width: 50, height: 50, ); } else { return const CircularProgressIndicator(); } }, ), price: item.price, count: item.localCount, ); }, ), ), ), const SizedBox( height: 10, ), Expanded( child: Column( children: [ MarkdownBody( data: '## Итого: ${totalPrice.toStringAsFixed(2)} руб.'), Expanded( child: TextField( controller: _addressController, decoration: InputDecoration( hintText: 'Адрес доставки', border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), ), ), ), Expanded( child: TextField( controller: _emailController, decoration: InputDecoration( hintText: 'Электронная почта', border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), ), keyboardType: TextInputType.emailAddress, ), ), Expanded( child: TextField( controller: _nameController, decoration: InputDecoration( hintText: 'Получатель', border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), ), ), ), ElevatedButton( onPressed: () async { if (!_checkInputs()) return; _goToPage(); await clearCart(); await _addOrderToHistory(); Provider.of(context, listen: false) .updateCartLength(); Navigator.of(context).pushAndRemoveUntil( CustomPageRoute( builder: (context) => const HistoryPage()), (route) => route.isFirst); }, 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: 20), ], ), ), ], ), ); } }