389 lines
19 KiB
Dart
389 lines
19 KiB
Dart
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 'text_param.dart';
|
||
|
||
class AddPlan {
|
||
List<SubscriptionPlanAdminDto> allPlans = [];
|
||
List<SubscriptionFeatureEnum> selectedFeatures = [];
|
||
late SubscriptionPlanAdminDto planDto;
|
||
late AdminApi adminApi;
|
||
|
||
final availableFeatures = [
|
||
SubscriptionFeatureEnum.ads,
|
||
SubscriptionFeatureEnum.packs,
|
||
];
|
||
|
||
AddPlan() {
|
||
this.adminApi = getIt.get<AdminApi>();
|
||
_init(null);
|
||
}
|
||
|
||
void _init(SubscriptionPlanAdminDto? dto) {
|
||
planDto = dto ??
|
||
const SubscriptionPlanAdminDto(
|
||
ui: SubscriptionPlanUIDto(
|
||
currency: 'руб',
|
||
),
|
||
price: '123',
|
||
currency: 'руб',
|
||
durationDays: 0,
|
||
features: [
|
||
SubscriptionFeatureEnum.ads,
|
||
SubscriptionFeatureEnum.packs,
|
||
],
|
||
paymentId: null,
|
||
paymentSystem: PaymentSystem.unknown,
|
||
);
|
||
selectedFeatures = planDto.features.toList();
|
||
}
|
||
|
||
Future<bool> _loadPlans() async {
|
||
final result = await adminApi.getSubscriptionPlans();
|
||
allPlans = result;
|
||
return true;
|
||
}
|
||
|
||
void _saveSubscriptionPlan() async {
|
||
final result = await adminApi.addSubscriptionPlan(
|
||
planDto.copyWith(
|
||
features: selectedFeatures,
|
||
),
|
||
);
|
||
if (!result) {
|
||
ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar(
|
||
content: Text('ERROR'),
|
||
));
|
||
} else {
|
||
ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar(
|
||
content: Text('Success!!!'),
|
||
));
|
||
appRouter.maybePop();
|
||
}
|
||
}
|
||
|
||
void _deletePLan() async {
|
||
if (planDto.id == null) return;
|
||
final result = await adminApi.deleteSubscriptionPlan(planDto.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 addPlan(BuildContext context) {
|
||
showDialog(
|
||
context: context,
|
||
builder: (c) {
|
||
return FutureBuilder(
|
||
future: _loadPlans(),
|
||
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, setPlan) {
|
||
return ListView(
|
||
children: [
|
||
Header(
|
||
'${planDto.id}',
|
||
hasPopButton: true,
|
||
trail: Row(
|
||
children: [
|
||
IconButton(
|
||
onPressed: () async {
|
||
await _loadPlans();
|
||
setPlan(() {});
|
||
},
|
||
icon: Icon(Icons.sync),
|
||
),
|
||
IconButton(
|
||
onPressed: _saveSubscriptionPlan,
|
||
icon: Icon(Icons.save),
|
||
),
|
||
if (planDto.id != null)
|
||
IconButton(
|
||
onPressed: () async {
|
||
planDto = planDto.copyWith(id: null);
|
||
_saveSubscriptionPlan();
|
||
},
|
||
icon: Icon(Icons.copy),
|
||
),
|
||
if (planDto.id != null)
|
||
GestureDetector(
|
||
onLongPress: _deletePLan,
|
||
child: Icon(Icons.delete),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
DropdownMenu<String?>(
|
||
initialSelection: null,
|
||
onSelected: (String? value) {
|
||
setPlan(() {
|
||
_init(
|
||
allPlans
|
||
.firstWhereOrNull((v) => v.id == value),
|
||
);
|
||
});
|
||
},
|
||
dropdownMenuEntries: [
|
||
...allPlans,
|
||
null,
|
||
].map((plan) {
|
||
return DropdownMenuEntry(
|
||
value: plan?.id,
|
||
label: plan == null
|
||
? 'New'
|
||
: '${plan.ui.titleLead ?? ''} ${plan.ui.title ?? ''} ${plan.paymentSystem.name}',
|
||
);
|
||
}).toList(),
|
||
),
|
||
StatefulBuilder(builder: (context, setState) {
|
||
return Stack(
|
||
alignment: Alignment.center,
|
||
children: [
|
||
Padding(
|
||
padding: EdgeInsets.all(8.0),
|
||
child: Column(
|
||
mainAxisSize: MainAxisSize.max,
|
||
mainAxisAlignment:
|
||
MainAxisAlignment.spaceEvenly,
|
||
children: [
|
||
Column(
|
||
children: [
|
||
TextParam(
|
||
'Currency',
|
||
planDto.currency,
|
||
(v) {
|
||
planDto = planDto.copyWith(
|
||
currency: v);
|
||
},
|
||
),
|
||
TextParam(
|
||
'Price',
|
||
planDto.price,
|
||
(v) {
|
||
planDto =
|
||
planDto.copyWith(price: v);
|
||
},
|
||
),
|
||
TextParam(
|
||
'Days',
|
||
planDto.durationDays.toString(),
|
||
(v) {
|
||
final days = int.parse(v);
|
||
planDto = planDto.copyWith(
|
||
durationDays: days,
|
||
);
|
||
},
|
||
),
|
||
Text('Features:'),
|
||
ListView.builder(
|
||
shrinkWrap: true,
|
||
itemCount:
|
||
availableFeatures.length,
|
||
itemBuilder: (context, index) {
|
||
final item =
|
||
availableFeatures[index];
|
||
return ListTile(
|
||
title: Text(item.name),
|
||
onTap: () {
|
||
setState(() {
|
||
if (selectedFeatures
|
||
.contains(item)) {
|
||
selectedFeatures
|
||
.remove(item);
|
||
} else {
|
||
selectedFeatures
|
||
.add(item);
|
||
}
|
||
});
|
||
},
|
||
selected: selectedFeatures
|
||
.contains(item),
|
||
selectedTileColor: Colors.blue
|
||
.withOpacity(0.5),
|
||
);
|
||
},
|
||
),
|
||
Text('UI:'),
|
||
TextParam(
|
||
'UI Currency',
|
||
planDto.ui.currency,
|
||
(v) {
|
||
final ui = planDto.ui.copyWith(
|
||
currency: v,
|
||
);
|
||
planDto =
|
||
planDto.copyWith.ui(ui);
|
||
},
|
||
),
|
||
TextParam(
|
||
'UI Title lead',
|
||
planDto.ui.titleLead,
|
||
(v) {
|
||
final ui = planDto.ui.copyWith(
|
||
titleLead: v,
|
||
);
|
||
planDto =
|
||
planDto.copyWith.ui(ui);
|
||
},
|
||
),
|
||
TextParam(
|
||
'UI Title',
|
||
planDto.ui.title,
|
||
(v) {
|
||
final ui = planDto.ui.copyWith(
|
||
title: v,
|
||
);
|
||
planDto =
|
||
planDto.copyWith.ui(ui);
|
||
},
|
||
),
|
||
TextParam(
|
||
'UI Price per month',
|
||
planDto.ui.pricePerMonth,
|
||
(v) {
|
||
final ui = planDto.ui.copyWith(
|
||
pricePerMonth: v,
|
||
);
|
||
planDto =
|
||
planDto.copyWith.ui(ui);
|
||
},
|
||
),
|
||
TextParam(
|
||
'UI Subtitle crossed',
|
||
planDto.ui.subtitleCrossed,
|
||
(v) {
|
||
final ui = planDto.ui.copyWith(
|
||
subtitleCrossed: v,
|
||
);
|
||
planDto =
|
||
planDto.copyWith.ui(ui);
|
||
},
|
||
),
|
||
TextParam(
|
||
'UI Subtitle',
|
||
planDto.ui.subtitle,
|
||
(v) {
|
||
final ui = planDto.ui.copyWith(
|
||
subtitle: v,
|
||
);
|
||
planDto =
|
||
planDto.copyWith.ui(ui);
|
||
},
|
||
),
|
||
TextParam(
|
||
'UI Tip',
|
||
planDto.ui.tip,
|
||
(v) {
|
||
final ui = planDto.ui.copyWith(
|
||
tip: v,
|
||
);
|
||
planDto =
|
||
planDto.copyWith.ui(ui);
|
||
},
|
||
),
|
||
TextParam(
|
||
'UI Tip color',
|
||
planDto.ui.tipColor,
|
||
(v) {
|
||
final ui = planDto.ui.copyWith(
|
||
tipColor: v,
|
||
);
|
||
planDto =
|
||
planDto.copyWith.ui(ui);
|
||
},
|
||
),
|
||
Padding(
|
||
padding:
|
||
const EdgeInsets.all(8.0),
|
||
child: Row(
|
||
children: [
|
||
Text('Payment type '),
|
||
Expanded(
|
||
child: StatefulBuilder(
|
||
builder: (context,
|
||
setState) {
|
||
return DropdownButton<
|
||
PaymentSystem>(
|
||
value: planDto
|
||
.paymentSystem,
|
||
items:
|
||
PaymentSystem.values
|
||
.map(
|
||
(v) =>
|
||
DropdownMenuItem(
|
||
child: Text(
|
||
v.name),
|
||
value: v,
|
||
),
|
||
)
|
||
.toList(),
|
||
onChanged: (v) {
|
||
setState(() {
|
||
planDto = planDto
|
||
.copyWith(
|
||
paymentSystem: v ??
|
||
PaymentSystem
|
||
.unknown,
|
||
);
|
||
});
|
||
},
|
||
);
|
||
}),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
TextParam(
|
||
'Payment id',
|
||
planDto.paymentId,
|
||
(v) {
|
||
planDto = planDto.copyWith(
|
||
paymentId: v,
|
||
);
|
||
},
|
||
),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
);
|
||
}),
|
||
],
|
||
);
|
||
}),
|
||
),
|
||
),
|
||
);
|
||
});
|
||
});
|
||
}
|
||
|
||
Widget uiEditor() {
|
||
return Column(
|
||
children: [],
|
||
);
|
||
}
|
||
}
|