Base user workflow (create/update)

This commit is contained in:
Andrew 2023-04-12 03:03:48 +07:00
parent eb5d3e2b70
commit 45be2c80ff
8 changed files with 528 additions and 17 deletions

View file

@ -1,36 +1,225 @@
import 'package:bottom_sheet/bottom_sheet.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tuuli_app/api/api_client.dart';
import 'package:tuuli_app/api/model/tables_list_model.dart';
import 'package:tuuli_app/api/model/user_model.dart';
import 'package:tuuli_app/pages/bottomsheets/create_user_bottomsheet.dart';
class UsersListPanel extends StatefulWidget {
const UsersListPanel({super.key});
final TableModel usersTable;
const UsersListPanel({super.key, required this.usersTable});
@override
State<StatefulWidget> createState() => _UsersListPanelState();
}
class _UsersListPanelState extends State<UsersListPanel> {
final apiClient = Get.find<ApiClient>();
final users = <UserModel>[];
@override
void initState() {
super.initState();
_refreshUsers();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: IntrinsicHeight(
child: _buildBody(),
return _buildUserList();
}
Widget _buildUserCard(BuildContext ctx, UserModel user) {
return Card(
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: () => _openUser(user),
child: Container(
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
user.username,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Row(
children: [
Text(
"User id: ${user.id}",
style: const TextStyle(
fontSize: 12,
),
),
],
),
],
),
],
),
),
),
);
}
Widget _buildBody() {
return Column(
children: [
Text(
'Users',
style: Theme.of(context).textTheme.headlineSmall,
Widget get newUserCard => Card(
clipBehavior: Clip.antiAlias,
child: InkWell(
onTap: _createNewUser,
child: Container(
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
child: const Icon(Icons.add),
),
),
],
);
Widget _buildUserList() {
if (users.isEmpty) {
return Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Text(
"No users found",
style: TextStyle(
color: Theme.of(context).disabledColor,
fontSize: 24,
),
),
const SizedBox(height: 4),
Text(
"Maybe create one? Or maybe you don't have permission to view them?",
style: TextStyle(
color: Theme.of(context).disabledColor,
fontSize: 14,
),
),
const SizedBox(height: 16),
ElevatedButton.icon(
onPressed: _createNewUser,
icon: const Icon(Icons.add),
label: const Text("Create user"),
)
],
),
);
}
return GridView.builder(
shrinkWrap: true,
itemCount: users.length + 1,
itemBuilder: (ctx, i) =>
i == 0 ? newUserCard : _buildUserCard(ctx, users[i - 1]),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 5,
childAspectRatio: 5 / 2,
),
);
}
Future<void> _createNewUser() async {
var result = await showFlexibleBottomSheet<CreateUserResult>(
minHeight: 1,
initHeight: 1,
maxHeight: 1,
context: context,
builder: (_, __, ___) => const CreateUserBottomSheet(),
anchors: [0, 0.5, 1],
isSafeArea: true,
isDismissible: false,
);
if (result == null) {
return;
}
final response = await apiClient.createUser(
widget.usersTable, result.username, result.password);
response.unfold((data) {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("User created"),
),
);
_refreshUsers();
}, (error) {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Error: $error"),
),
);
});
}
Future<void> _openUser(UserModel user) async {
final result = await showFlexibleBottomSheet<UpdateUserResult>(
minHeight: 1,
initHeight: 1,
maxHeight: 1,
context: context,
builder: (_, __, ___) => CreateUserBottomSheet(existingUser: user),
anchors: [0, 0.5, 1],
isSafeArea: true,
isDismissible: false,
);
if (result == null) {
return;
}
final response = await apiClient.updateItem(widget.usersTable, {
"username": result.username,
"password": result.password,
"access_token": result.accessToken,
}, {
"id": user.id,
});
response.unfold((data) {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("User updated"),
),
);
_refreshUsers();
}, (error) {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Error: $error"),
),
);
});
}
Future<void> _refreshUsers() async {
final result = await apiClient.getTableItems(widget.usersTable);
result.unfold((data) {
setState(() {
users.clear();
users.addAll(data.map((e) => UserModel.fromJson(e)));
});
}, (error) {
ScaffoldMessenger.of(context).hideCurrentSnackBar();
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Error: $error"),
),
);
});
}
}