import 'dart:async'; import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:mnemo_cards/admin/admin_api.dart'; import 'package:mnemo_cards_common/mnemo_cards_common.dart'; import 'package:mnemo_cards_frontend_common/mnemo_cards_frontend_common.dart'; import '../di/injector.dart'; import '../main.dart'; import 'date_param.dart'; import 'enum_param.dart'; import 'int_param.dart'; import 'text_param.dart'; class AddDiscountCampaign { late DiscountCampaignDto campaignDto; late AdminApi adminApi; List _campaigns = []; AddDiscountCampaign() { this.adminApi = getIt.get(); _init(null); } void _init(DiscountCampaignDto? dto) { final now = DateTime.now(); campaignDto = dto ?? DiscountCampaignDto( start: now, finish: now.add(Duration(days: 30)), status: DiscountCampaignStatus.disabled, name: null, tags: [], discounts: [], ); } Future _loadCampaigns() async { try { _campaigns = await adminApi.getDiscountCampaigns(); } catch (e, s) { log('Error', error: e, stackTrace: s); print('Error $e'); return false; } return true; } void _savePromoCodeCampaign() async { for (final d in campaignDto.discounts) { final products = d.products.map((p) => p.toProduct()); d.products.replaceRange(0, products.length, products); } final result = await adminApi.addDiscountCampaign(campaignDto); if (!result) { ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar( content: Text('ERROR'), )); } else { ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar( content: Text('Success!!!'), )); appRouter.maybePop(); } } void _deleteDiscountCampaign() async { if (campaignDto.id == null) return; final result = await adminApi.deleteDiscountCampaign(campaignDto.id.toString()); if (result != null) { ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar( content: Text('ERROR'), )); } else { ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar( content: Text('Success!!!'), )); appRouter.maybePop(); } } void addCampaign(BuildContext context) { showDialog( context: context, builder: (c) { return FutureBuilder( future: _loadCampaigns(), builder: (context, snapshot) { if (snapshot.data != true) { return Center( child: Material( child: Center(child: CircularProgressIndicator()), ), ); } return Center( child: Scaffold( body: Material( child: StatefulBuilder(builder: (context, setCampaign) { return ListView( children: [ Header( '${campaignDto.id}', hasPopButton: true, trail: Row( children: [ IconButton( onPressed: _savePromoCodeCampaign, icon: Icon(Icons.save), ), if (campaignDto.id != null) IconButton( onPressed: () async { campaignDto = campaignDto.copyWith(id: null); _savePromoCodeCampaign(); }, icon: Icon(Icons.copy), ), if (campaignDto.id != null) GestureDetector( onLongPress: _deleteDiscountCampaign, child: Icon(Icons.delete), ) ], ), ), DropdownMenu( initialSelection: null, onSelected: (int? value) { setCampaign(() { _init( _campaigns .firstWhereOrNull((v) => v.id == value), ); }); }, dropdownMenuEntries: [ ..._campaigns, null, ].map((campaign) { return DropdownMenuEntry( value: campaign?.id, label: campaign == null ? 'New' : '${campaign.name ?? campaign.id} ${campaign.status.name}', ); }).toList(), ), StatefulBuilder(builder: (context, setState) { return Padding( padding: EdgeInsets.all(8.0), child: Column( children: [ TextParam( 'Name', campaignDto.name, (v) { campaignDto = campaignDto.copyWith( name: v, ); }, ), DateParam( 'Start', campaignDto.start, (v) { setState(() { campaignDto = campaignDto.copyWith(start: v); }); }, ), DateParam( 'Finish', campaignDto.finish, (v) { setState(() { campaignDto = campaignDto.copyWith(finish: v); }); }, ), EnumParam( 'Status', DiscountCampaignStatus.values, campaignDto.status, (v) { setState(() { campaignDto = campaignDto.copyWith(status: v); }); }), Text( 'Created to create or change\n' 'Disabled to disable\n' 'Dont use other statuses!', style: TextStyle(fontSize: 12), ), Text('Discounts:'), ListView.builder( shrinkWrap: true, itemCount: campaignDto.discounts.length + 1, itemBuilder: (context, index) { if (index == campaignDto.discounts.length) { return Container( child: SimpleTile( title: Text('Add'), onTap: () async { final discount = await _showDiscountDialog( context, null); if (discount != null) { setState(() { final ex = campaignDto .discounts .firstWhereOrNull((d) => d.id == discount.id); if (ex != null) { campaignDto.discounts .remove(ex); } campaignDto.discounts .add(discount); }); } }, ), ); } final item = campaignDto.discounts[index]; return ListTile( title: Text( '${item.type.name} ${item.id ?? ''}'), onTap: () async { final p = await _showDiscountDialog( context, item, ); if (p != null) { setState(() { campaignDto.discounts.add(p); }); } }, trailing: IconButton( icon: Icon(Icons.delete), onPressed: () { setState(() { campaignDto.discounts .remove(item); }); }, ), ); }, ), ], ), ); }), ], ); }), ), ), ); }); }); } Future _showDiscountDialog( BuildContext context, DiscountDto? initialDiscount, ) async { var prod = initialDiscount ?? DiscountDto(discountPercent: 0, products: []); final result = await showDialog( context: context, builder: (c) => Center( child: Padding( padding: const EdgeInsets.all(8.0), child: Material( child: FutureBuilder( future: () async { final allPacks = await adminApi.packs(); final allPlans = await adminApi.getSubscriptionPlans(); return [...allPacks, ...allPlans]; }.call(), builder: (context, snapshot) { if (!snapshot.hasData) { return Padding( padding: const EdgeInsets.all(8.0), child: Text('Loading products...'), ); } final products = snapshot.requireData; return SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ Text('Adding discount'), TextParam( 'Id', prod.id, (v) { prod = prod.copyWith(id: v); }, description: 'Leave empty for new', ), IntParam('Discount 0-100', prod.discountPercent.toInt(), (v) { prod = prod.copyWith( discountPercent: v?.toDouble() ?? 0.0); }), StatefulBuilder(builder: (context, ss) { return ListView.builder( shrinkWrap: true, itemCount: prod.products.length + 1, itemBuilder: (BuildContext context, int index) { if (index == prod.products.length) { return EnumParam( 'Add product', products, null, (p) { if (p != null) { ss(() { prod.products.add(p); }); } }, getName: (p) => _productName(p, products), ); } final p = prod.products[index]; return ListTile( title: Text(_productName(p, products)), onTap: () async { ss(() { prod.products.remove(p); }); }, ); }, ); }), MaterialButton( onPressed: () { Navigator.of(context).pop(prod); }, child: Text('Save'), ), ], ), ); }), ), ), ), ); return result; } String _productName(MnemoCardsProductDto? p, List products) { if (p is CardPackPreviewDto) { return '${p.id} ${p.title} ${p.price} pack'; } else if (p is SubscriptionPlanAdminDto) { return '${p.id} ${p.ui.titleLead ?? ''} ${p.ui.title ?? ''} ${p.paymentSystem.name} ${p.price} plan'; } final matchedProduct = products.firstWhereOrNull((m) => m.productEquals(p)); if (matchedProduct != null) { return _productName(matchedProduct, []); } return '${p?.type.name} ${p?.id}'; } }