import 'package:dio/dio.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'auth_repository.dart'; enum AuthStatus { initial, loading, otpSent, authenticated, error } class AuthState extends Equatable { final AuthStatus status; final String mobile; final bool needsProfile; // پس از ورود، آیا کاربر باید نام/آواتار انتخاب کند final String? error; const AuthState({ this.status = AuthStatus.initial, this.mobile = '', this.needsProfile = false, this.error, }); AuthState copyWith( {AuthStatus? status, String? mobile, bool? needsProfile, String? error}) => AuthState( status: status ?? this.status, mobile: mobile ?? this.mobile, needsProfile: needsProfile ?? this.needsProfile, error: error, ); @override List get props => [status, mobile, needsProfile, error]; } class AuthCubit extends Cubit { final AuthRepository _repo; AuthCubit(this._repo) : super(const AuthState()); Future requestOtp(String mobile) async { emit(state.copyWith(status: AuthStatus.loading, mobile: mobile)); try { await _repo.requestOtp(mobile); emit(state.copyWith(status: AuthStatus.otpSent, mobile: mobile)); } catch (e) { emit(state.copyWith(status: AuthStatus.error, error: _msg(e))); } } Future verifyOtp(String code) async { emit(state.copyWith(status: AuthStatus.loading)); try { final hasName = await _repo.verifyOtp(state.mobile, code); emit(state.copyWith( status: AuthStatus.authenticated, needsProfile: !hasName)); } catch (e) { emit(state.copyWith(status: AuthStatus.error, error: _msg(e))); } } /// ذخیره‌ی نام و آواتار؛ سپس نیازی به صفحه‌ی پروفایل نیست. Future saveProfile(String name, String avatar) async { try { await _repo.updateProfile(name, avatar); emit(state.copyWith(needsProfile: false)); return true; } catch (_) { return false; } } Future logout() async { await _repo.logout(); emit(const AuthState()); } /// بازنشانی وضعیت خطا به حالت مناسب فرم. void resetError({required bool onOtpScreen}) { emit(state.copyWith( status: onOtpScreen ? AuthStatus.otpSent : AuthStatus.initial)); } String _msg(Object e) { if (e is DioException) { final data = e.response?.data; if (data is Map && data['message'] != null) { return data['message'].toString(); } return 'خطا در ارتباط با سرور'; } return 'خطای نامشخص'; } }