tasq/lib/providers/profile_provider.dart

78 lines
2.3 KiB
Dart

import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import '../models/profile.dart';
import 'auth_provider.dart';
import 'supabase_provider.dart';
final currentUserIdProvider = Provider<String?>((ref) {
final authState = ref.watch(authStateChangesProvider);
return authState.maybeWhen(
data: (state) => state.session?.user.id,
orElse: () => ref.watch(sessionProvider)?.user.id,
);
});
final currentProfileProvider = StreamProvider<Profile?>((ref) {
final userId = ref.watch(currentUserIdProvider);
if (userId == null) {
return const Stream.empty();
}
final client = ref.watch(supabaseClientProvider);
return client
.from('profiles')
.stream(primaryKey: ['id'])
.eq('id', userId)
.map((rows) => rows.isEmpty ? null : Profile.fromMap(rows.first));
});
final profilesProvider = StreamProvider<List<Profile>>((ref) {
final client = ref.watch(supabaseClientProvider);
return client
.from('profiles')
.stream(primaryKey: ['id'])
.order('full_name')
.map((rows) => rows.map(Profile.fromMap).toList());
});
/// Controller for the current user's profile (update full name / password).
final profileControllerProvider = Provider<ProfileController>((ref) {
final client = ref.watch(supabaseClientProvider);
return ProfileController(client);
});
class ProfileController {
ProfileController(this._client);
final SupabaseClient _client;
/// Update the `profiles.full_name` for the given user id.
Future<void> updateFullName({
required String userId,
required String fullName,
}) async {
await _client
.from('profiles')
.update({'full_name': fullName})
.eq('id', userId);
}
/// Update the current user's password (works for OAuth users too).
Future<void> updatePassword(String password) async {
if (password.length < 8) {
throw Exception('Password must be at least 8 characters');
}
await _client.auth.updateUser(UserAttributes(password: password));
}
}
final isAdminProvider = Provider<bool>((ref) {
final profileAsync = ref.watch(currentProfileProvider);
return profileAsync.maybeWhen(
data: (profile) => profile?.role == 'admin',
orElse: () => false,
);
});