8ea2b97c27
- Added tab navigation for profile, database, users, suggestions, and AI sections. - Implemented database management with inventory, pantry, and products tabs. - Created Admin AI panel to display AI model information. - Introduced Admin Pending Products panel for managing product approvals. - Developed Admin Users panel for user management, including role changes and password resets. - Added data models for AI models and pending products.
119 lines
3.7 KiB
Dart
119 lines
3.7 KiB
Dart
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import '../../../core/api/api_client.dart';
|
|
import '../../../core/api/api_paths.dart';
|
|
import '../../../core/api/guarded_api_call.dart';
|
|
import '../../auth/data/auth_providers.dart';
|
|
import '../domain/ai_model_info.dart';
|
|
import '../domain/pending_product.dart';
|
|
import '../domain/user_admin.dart';
|
|
|
|
final adminRepositoryProvider = Provider<AdminRepository>((ref) {
|
|
return AdminRepository(ref.watch(apiClientProvider), ref);
|
|
});
|
|
|
|
class AdminRepository {
|
|
final ApiClient _apiClient;
|
|
final Ref _ref;
|
|
|
|
AdminRepository(this._apiClient, this._ref);
|
|
|
|
Future<String?> _token() => _ref.read(authStateProvider.future);
|
|
|
|
Future<List<UserAdmin>> listUsers() async {
|
|
final token = await _token();
|
|
final data = await guardedApiCall(
|
|
_ref,
|
|
() => _apiClient.getJson(UserApiPaths.list, token: token),
|
|
);
|
|
return (data as List<dynamic>).map((e) => UserAdmin.fromJson(e as Map<String, dynamic>)).toList();
|
|
}
|
|
|
|
Future<UserAdmin> setRole(int userId, String newRole) async {
|
|
final token = await _token();
|
|
final data = await guardedApiCall(
|
|
_ref,
|
|
() => _apiClient.patchJson(UserApiPaths.setRole(userId), body: {'role': newRole}, token: token),
|
|
);
|
|
return UserAdmin.fromJson(data);
|
|
}
|
|
|
|
Future<UserAdmin> setPremium(int userId, {required bool isPremium}) async {
|
|
final token = await _token();
|
|
final data = await guardedApiCall(
|
|
_ref,
|
|
() => _apiClient.patchJson(UserApiPaths.setPremium(userId), body: {'isPremium': isPremium}, token: token),
|
|
);
|
|
return UserAdmin.fromJson(data);
|
|
}
|
|
|
|
Future<UserAdmin> createUser({
|
|
required String username,
|
|
required String email,
|
|
required String password,
|
|
String role = 'user',
|
|
}) async {
|
|
final token = await _token();
|
|
final data = await guardedApiCall(
|
|
_ref,
|
|
() => _apiClient.postJson(UserApiPaths.list, body: {
|
|
'username': username,
|
|
'email': email,
|
|
'password': password,
|
|
'role': role,
|
|
}, token: token),
|
|
);
|
|
return UserAdmin.fromJson(data as Map<String, dynamic>);
|
|
}
|
|
|
|
Future<void> deleteUser(int userId) async {
|
|
final token = await _token();
|
|
return guardedApiCall(
|
|
_ref,
|
|
() => _apiClient.deleteJson(UserApiPaths.delete(userId), token: token),
|
|
);
|
|
}
|
|
|
|
/// Returns `{ temporaryPassword, to, subject, body }`.
|
|
Future<Map<String, dynamic>> resetPassword(int userId) async {
|
|
final token = await _token();
|
|
final result = await guardedApiCall<dynamic>(
|
|
_ref,
|
|
() => _apiClient.postJson(UserApiPaths.resetPassword(userId), token: token),
|
|
);
|
|
return (result as Map<String, dynamic>);
|
|
}
|
|
|
|
Future<List<PendingProduct>> listPendingProducts() async {
|
|
final token = await _token();
|
|
final data = await guardedApiCall(
|
|
_ref,
|
|
() => _apiClient.getJson(ProductApiPaths.pending, token: token),
|
|
);
|
|
return (data as List<dynamic>)
|
|
.map((e) => PendingProduct.fromJson(e as Map<String, dynamic>))
|
|
.toList();
|
|
}
|
|
|
|
Future<void> setProductStatus(int productId, String status) async {
|
|
final token = await _token();
|
|
await guardedApiCall(
|
|
_ref,
|
|
() => _apiClient.patchJson(
|
|
ProductApiPaths.setStatus(productId),
|
|
body: {'status': status},
|
|
token: token,
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<List<AiModelInfo>> listAiModels() async {
|
|
final data = await guardedApiCall(
|
|
_ref,
|
|
() => _apiClient.getJson(AiApiPaths.models),
|
|
);
|
|
return (data as List<dynamic>)
|
|
.map((e) => AiModelInfo.fromJson(e as Map<String, dynamic>))
|
|
.toList();
|
|
}
|
|
}
|