399 lines
16 KiB
Dart
399 lines
16 KiB
Dart
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<PromoCodesCampaignDto> _campaigns = [];
|
|
|
|
final availableStatuses = [
|
|
PromoCodeCampaignStatus.created,
|
|
PromoCodeCampaignStatus.preparing,
|
|
PromoCodeCampaignStatus.ready,
|
|
PromoCodeCampaignStatus.active,
|
|
PromoCodeCampaignStatus.disabled,
|
|
];
|
|
|
|
AddPromocodeCampaign() {
|
|
this.adminApi = getIt.get<AdminApi>();
|
|
_init(null);
|
|
}
|
|
|
|
void _init(PromoCodesCampaignDto? dto) {
|
|
final now = DateTime.now();
|
|
campaignDto = dto ??
|
|
PromoCodesCampaignDto(
|
|
products: [],
|
|
activationsPerCode: 1,
|
|
activationsPerUser: 1,
|
|
generationSize: 100,
|
|
start: now,
|
|
finish: now.add(Duration(days: 60)),
|
|
status: PromoCodeCampaignStatus.disabled,
|
|
name: null,
|
|
template: r'$s$s$s$s$s$s$s$s',
|
|
tags: [],
|
|
);
|
|
}
|
|
|
|
Future<bool> _loadCampaigns() async {
|
|
try {
|
|
_campaigns = await adminApi.getPromoCodeCampaigns();
|
|
} catch (e, s) {
|
|
log('Error', error: e, stackTrace: s);
|
|
print('Error $e');
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
Future<bool> _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<int?>(
|
|
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,
|
|
);
|
|
},
|
|
),
|
|
IntParam(
|
|
'Activations per user',
|
|
campaignDto.activationsPerUser,
|
|
(v) {
|
|
campaignDto = campaignDto.copyWith(
|
|
activationsPerUser: 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<MnemoCardsProductDto?> _showProductDialog(
|
|
BuildContext context,
|
|
MnemoCardsProductDto? initialProduct,
|
|
) async {
|
|
var prod = initialProduct ?? MnemoCardsProductDto();
|
|
final result = await showDialog<MnemoCardsProductDto?>(
|
|
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: [],
|
|
);
|
|
}
|
|
}
|