import 'dart:async'; import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:flutter/services.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 AddPromocodeCampaign { late PromoCodesCampaignDto campaignDto; late AdminApi adminApi; List _campaigns = []; final availableStatuses = [ PromoCodeCampaignStatus.created, PromoCodeCampaignStatus.preparing, PromoCodeCampaignStatus.ready, PromoCodeCampaignStatus.active, PromoCodeCampaignStatus.disabled, ]; AddPromocodeCampaign() { this.adminApi = getIt.get(); _init(null); } void _init(PromoCodesCampaignDto? dto) { final now = DateTime.now(); campaignDto = dto ?? PromoCodesCampaignDto( products: [], activationsPerCode: 1, generationSize: 100, start: now, finish: now.add(Duration(days: 30)), status: PromoCodeCampaignStatus.disabled, name: null, template: r'$s$s$s$s$s$s$s$s', ); } Future _loadCampaigns() async { try { _campaigns = await adminApi.getPromoCodeCampaigns(); } catch (e, s) { log('Error', error: e, stackTrace: s); print('Error $e'); return false; } return true; } Future _loadCampaign(String id) async { try { final campaign = await adminApi.getPromoCodeCampaign(id); if (campaign != null) { _campaigns.removeWhere((v) => v.id.toString() == id); _campaigns.add(campaign); campaignDto = campaign; } } catch (e, s) { log('Error', error: e, stackTrace: s); print('Error $e'); return false; } return true; } void _savePromoCodeCampaign() async { final result = await adminApi.addPromoCodeCampaign(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 _deletePromoCodeCampaign() async { if (campaignDto.id == null) return; final result = await adminApi.deletePromoCodeCampaign(campaignDto.id.toString()); if (!result) { 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) { final codes = campaignDto.promoCodes; return ListView( children: [ Header( '${campaignDto.id}', hasPopButton: true, trail: Row( children: [ if (campaignDto.id != null) IconButton( onPressed: () async { await _loadCampaign( campaignDto.id.toString(), ); setCampaign(() {}); }, icon: Icon(Icons.note), ), 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: _deletePromoCodeCampaign, 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, ); }, ), TextParam( 'Template', campaignDto.template, (v) { campaignDto = campaignDto.copyWith( template: v, ); }, description: r'$d - digit $l - letter $s - any', ), IntParam( 'Generation size', campaignDto.generationSize, (v) { campaignDto = campaignDto.copyWith( generationSize: v); }, ), IntParam( 'Activations per code', campaignDto.activationsPerCode, (v) { campaignDto = campaignDto.copyWith( activationsPerCode: 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', PromoCodeCampaignStatus.values, campaignDto.status, (v) { setState(() { campaignDto = campaignDto.copyWith(status: v); }); }), Text( 'Created to generate promocodes\n' 'Disabled to disable\n' 'Dont use other statuses!', style: TextStyle(fontSize: 12), ), Text('Products:'), ListView.builder( shrinkWrap: true, itemCount: campaignDto.products.length + 1, itemBuilder: (context, index) { if (index == campaignDto.products.length) { return ListTile( title: Text('Add'), onTap: () async { final p = await _showProductDialog( context, null); if (p != null) { setState(() { campaignDto.products.add(p); }); } }, ); } final item = campaignDto.products[index]; return ListTile( title: Text( '${item.type.name} ${item.id ?? ''}'), onTap: () async { final p = await _showProductDialog( context, item, ); if (p != null) { setState(() { campaignDto.products.add(p); }); } }, trailing: IconButton( icon: Icon(Icons.delete), onPressed: () { setState(() { campaignDto.products .remove(item); }); }, ), ); }, ), SimpleTile.text( text: codes == null ? 'Codes not loaded' : 'Codes: ${codes.length == 1 ? codes.first : codes.length}', onTap: () async { if (codes != null) { await Clipboard.setData( ClipboardData( text: codes.join('\n'), ), ); } }, ), ], ), ); }), ], ); }), ), ), ); }); }); } Future _showProductDialog( BuildContext context, MnemoCardsProduct? initialProduct, ) async { var prod = initialProduct ?? MnemoCardsProduct(); final result = await showDialog( context: context, builder: (c) => Center( child: Padding( padding: const EdgeInsets.all(8.0), child: Material( child: Column( mainAxisSize: MainAxisSize.min, children: [ TextParam('Id', prod.id, (v) { prod = prod.copyWith(id: v); }), EnumParam( 'Type', MnemoCardsProductType.values, prod.type, (v) { prod = prod.copyWith(type: v); }, ), MaterialButton( onPressed: () { Navigator.of(context).pop(prod); }, child: Text('Save'), ), ], ), ), ), ), ); return result; } Widget uiEditor() { return Column( children: [], ); } }