229 lines
8.2 KiB
Dart
229 lines
8.2 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:dio/dio.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:file_picker/file_picker.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:mnemo_cards/admin/admin_api.dart';
|
|
import 'package:mnemo_cards/domain/router/app_router.dart';
|
|
import 'package:mnemo_cards/features/packs/images_holder.dart';
|
|
import 'package:mnemo_cards/utils/iterable_helper.dart';
|
|
import 'package:mnemo_cards/widgets/game_card_widget.dart';
|
|
import 'package:mnemo_cards/widgets/header.dart';
|
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
|
|
|
import '../di/locator.dart';
|
|
import '../main.dart';
|
|
import '../widgets/image_fade.dart';
|
|
|
|
class EditUser {
|
|
UserDto userDto;
|
|
AdminApi adminApi;
|
|
bool imageChanged = false;
|
|
|
|
EditUser(UserDto userDto, this.adminApi) : userDto = userDto;
|
|
|
|
void _saveUser() async {
|
|
final dto = userDto;
|
|
final result = await adminApi.editUser(dto);
|
|
if (!result) {
|
|
ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar(
|
|
content: Text('ERROR'),
|
|
));
|
|
} else {
|
|
ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar(
|
|
content: Text('Success!!!'),
|
|
));
|
|
appRouter.maybePop();
|
|
}
|
|
}
|
|
|
|
void _deleteCard() async {
|
|
final result = await adminApi.deleteUser(userDto);
|
|
if (!result) {
|
|
ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar(
|
|
content: Text('ERROR'),
|
|
));
|
|
} else {
|
|
ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar(
|
|
content: Text('Success!!!'),
|
|
));
|
|
appRouter.maybePop();
|
|
}
|
|
}
|
|
|
|
void addUser(BuildContext context) {
|
|
final theme = Theme.of(context).textTheme;
|
|
|
|
final TextEditingController nameController =
|
|
TextEditingController(text: userDto.name);
|
|
|
|
final TextEditingController packsController =
|
|
TextEditingController(text: userDto.packs.join(','));
|
|
|
|
showDialog(
|
|
context: context,
|
|
builder: (c) {
|
|
return Center(
|
|
child: Scaffold(
|
|
body: Material(
|
|
child: ListView(
|
|
children: [
|
|
Header(
|
|
'${userDto.id}',
|
|
hasPopButton: true,
|
|
trail: Row(
|
|
children: [
|
|
IconButton(
|
|
onPressed: _saveUser,
|
|
icon: Icon(Icons.save),
|
|
),
|
|
if (userDto.id != null && userDto.id! >= 0)
|
|
GestureDetector(
|
|
onLongPress: _deleteCard,
|
|
child: Icon(Icons.delete),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
StatefulBuilder(builder: (context, setState) {
|
|
return Padding(
|
|
padding: EdgeInsets.all(8.0),
|
|
child: Column(
|
|
children: [
|
|
GestureDetector(
|
|
onTap: () {
|
|
if (userDto.id != null) {
|
|
Clipboard.setData(ClipboardData(
|
|
text: userDto.id.toString()));
|
|
}
|
|
},
|
|
child: Text('ID: ${userDto.id}'),
|
|
),
|
|
Text('Admin: ${userDto.admin}'),
|
|
TextField(
|
|
controller: nameController,
|
|
onChanged: (v) {
|
|
userDto = userDto.copyWith(name: v);
|
|
},
|
|
decoration: InputDecoration(hintText: 'Name'),
|
|
maxLines: 1,
|
|
style: theme.displayMedium?.copyWith(
|
|
fontSize: theme.displayMedium!.fontSize!,
|
|
),
|
|
),
|
|
Row(
|
|
children: [
|
|
Expanded(child: Text('Subscription ')),
|
|
StatefulBuilder(builder: (context, setState) {
|
|
return Switch(
|
|
value: userDto.subscription ?? false,
|
|
onChanged: (v) {
|
|
setState(() {
|
|
userDto =
|
|
userDto.copyWith.subscription(v);
|
|
});
|
|
});
|
|
}),
|
|
],
|
|
),
|
|
TextField(
|
|
controller: packsController,
|
|
onChanged: (v) {
|
|
final packs = v
|
|
.split(',')
|
|
.map((s) =>
|
|
int.tryParse(s.trim())?.toString())
|
|
.whereNotNull()
|
|
.toList();
|
|
userDto = userDto.copyWith(packs: packs);
|
|
final packsText = packs.join(',');
|
|
if (!packsController.text
|
|
.startsWith(packsText)) {
|
|
packsController.text = packsText;
|
|
}
|
|
},
|
|
decoration: InputDecoration(hintText: 'Packs'),
|
|
maxLines: 1,
|
|
style: theme.displayMedium?.copyWith(
|
|
fontSize: theme.displayMedium!.fontSize!,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}),
|
|
_Payments(adminApi, userDto),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
});
|
|
}
|
|
}
|
|
|
|
class _Payments extends StatelessWidget {
|
|
final AdminApi adminApi;
|
|
final UserDto userDto;
|
|
|
|
_Payments(this.adminApi, this.userDto);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final sc = StreamController<List<PaymentDto>?>();
|
|
final stream = sc.stream;
|
|
|
|
return ExpansionTile(
|
|
title: Text('Транзакции'),
|
|
maintainState: true,
|
|
onExpansionChanged: (v) async {
|
|
if (v) {
|
|
sc.add(null);
|
|
final payments =
|
|
await adminApi.getUserPurchases(userDto.id.toString());
|
|
sc.add(payments);
|
|
}
|
|
},
|
|
children: [
|
|
StreamBuilder<List<PaymentDto>?>(
|
|
stream: stream,
|
|
builder: (context, snapshot) {
|
|
final payments = snapshot.data;
|
|
if (payments == null) {
|
|
return Text('Loading...');
|
|
}
|
|
if (payments.isEmpty) {
|
|
return Text('Нет покупок');
|
|
}
|
|
return Column(
|
|
children: payments.map((p) {
|
|
return ListTile(
|
|
title: Text('${p.amount} ${p.currency}'),
|
|
subtitle: Text(dateString(p.date)),
|
|
trailing: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
children: [
|
|
Text(p.status.name),
|
|
Text(p.paymentSystem.name),
|
|
Text(
|
|
'packs: [${p.packs.join(',')}] ${p.subscription ? 'subscription' : ''}')
|
|
],
|
|
),
|
|
);
|
|
}).toList(),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
String dateString(DateTime date) =>
|
|
'${date.year}.${date.month.toString().padLeft(2, '0')}.${date.day.toString().padLeft(2, '0')} ${date.hour.toString().padLeft(2, '0')}:${date.minute.toString().padLeft(2, '0')}:${date.second.toString().padLeft(2, '0')}';
|
|
}
|