211 lines
6.8 KiB
Dart
211 lines
6.8 KiB
Dart
import 'dart:io';
|
|
import 'package:dio/dio.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:laundry_seller/models/authentication/authentication_model.dart';
|
|
import 'package:laundry_seller/models/authentication/settings.dart';
|
|
import 'package:laundry_seller/models/authentication/user.dart';
|
|
import 'package:laundry_seller/models/common/common_response_model.dart';
|
|
import 'package:laundry_seller/services/auth_service_provider.dart';
|
|
import 'package:laundry_seller/services/hive_service.dart';
|
|
import 'package:laundry_seller/utils/api_client.dart';
|
|
|
|
class AuthController extends StateNotifier<bool> {
|
|
final Ref ref;
|
|
AuthController(this.ref) : super(false);
|
|
|
|
String? _lastError;
|
|
String? get lastError => _lastError;
|
|
|
|
late Settings _settings;
|
|
Settings get settings => _settings;
|
|
|
|
// get settings info
|
|
Future<bool> getSettingsInfo() async {
|
|
try {
|
|
final response = await ref.read(authServiceProvider).settings();
|
|
_settings =
|
|
Settings.fromMap(Map<String, dynamic>.from(response.data['data']));
|
|
return true;
|
|
} catch (e) {
|
|
debugPrint(e.toString());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// login
|
|
Future<bool> login(
|
|
{required String contact, required String password}) async {
|
|
try {
|
|
state = true;
|
|
_lastError = null;
|
|
final response = await ref
|
|
.read(authServiceProvider)
|
|
.login(contact: contact, password: password);
|
|
|
|
if (response.data == null ||
|
|
response.data['data'] == null ||
|
|
response.data['data']['user'] == null) {
|
|
_lastError =
|
|
response.data?['message'] ?? 'Login failed. Invalid response.';
|
|
state = false;
|
|
return false;
|
|
}
|
|
|
|
final userInfo = User.fromMap(
|
|
Map<String, dynamic>.from(response.data['data']['user']));
|
|
final accessToken = response.data['data']['access']['token'];
|
|
ref.read(hiveStoreService).saveUserInfo(userInfo: userInfo);
|
|
ref.read(hiveStoreService).saveUserAuthToken(authToken: accessToken);
|
|
ref.read(apiClientProvider).updateToken(token: accessToken);
|
|
state = false;
|
|
return true;
|
|
} on DioException catch (e) {
|
|
_lastError = _extractErrorMessage(e);
|
|
debugPrint('Login error: $_lastError');
|
|
state = false;
|
|
return false;
|
|
} catch (e) {
|
|
_lastError = 'Connection error. Please try again.';
|
|
debugPrint(e.toString());
|
|
state = false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// pin login
|
|
Future<bool> pinLogin({required String storeId, required String pin}) async {
|
|
try {
|
|
state = true;
|
|
_lastError = null;
|
|
final response = await ref
|
|
.read(authServiceProvider)
|
|
.pinLogin(storeId: storeId, pin: pin);
|
|
|
|
if (response.data == null ||
|
|
response.data['data'] == null ||
|
|
response.data['data']['user'] == null) {
|
|
_lastError =
|
|
response.data?['message'] ?? 'Login failed. Invalid response.';
|
|
state = false;
|
|
return false;
|
|
}
|
|
|
|
final userInfo = User.fromMap(
|
|
Map<String, dynamic>.from(response.data['data']['user']));
|
|
final accessToken = response.data['data']['access']['token'];
|
|
ref.read(hiveStoreService).saveUserInfo(userInfo: userInfo);
|
|
ref.read(hiveStoreService).saveUserAuthToken(authToken: accessToken);
|
|
ref.read(apiClientProvider).updateToken(token: accessToken);
|
|
state = false;
|
|
return true;
|
|
} on DioException catch (e) {
|
|
_lastError = _extractErrorMessage(e);
|
|
debugPrint('Pin login error: $_lastError');
|
|
state = false;
|
|
return false;
|
|
} catch (e) {
|
|
_lastError = 'Connection error. Please try again.';
|
|
debugPrint(e.toString());
|
|
state = false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// registration
|
|
Future<CommonResponse> registration({
|
|
required SignUpModel signUpModel,
|
|
required File profile,
|
|
required File shopLogo,
|
|
required File shopBanner,
|
|
}) async {
|
|
try {
|
|
state = true;
|
|
final response = await ref.read(authServiceProvider).registration(
|
|
signUpModel: signUpModel,
|
|
profile: profile,
|
|
shopLogo: shopLogo,
|
|
shopBanner: shopBanner,
|
|
);
|
|
final message = response.data['message'];
|
|
if (response.statusCode == 200) {
|
|
return CommonResponse(isSuccess: true, message: message);
|
|
}
|
|
state = false;
|
|
return CommonResponse(isSuccess: false, message: message);
|
|
} catch (e) {
|
|
debugPrint(e.toString());
|
|
state = false;
|
|
return CommonResponse(isSuccess: false, message: e.toString());
|
|
}
|
|
}
|
|
|
|
// send verification OTP
|
|
Future<CommonResponse> sendOTP({required String mobile}) async {
|
|
try {
|
|
state = true;
|
|
final response =
|
|
await ref.read(authServiceProvider).sendOTP(mobile: mobile);
|
|
final message = response.data['message'];
|
|
if (response.statusCode == 200) {
|
|
state = false;
|
|
return CommonResponse(isSuccess: true, message: message);
|
|
}
|
|
state = false;
|
|
return CommonResponse(isSuccess: false, message: message);
|
|
} catch (e) {
|
|
debugPrint(e.toString());
|
|
state = false;
|
|
return CommonResponse(isSuccess: false, message: e.toString());
|
|
}
|
|
}
|
|
|
|
// verify otp
|
|
Future<CommonResponse> verifyOTP(
|
|
{required String mobile, required String otp}) async {
|
|
try {
|
|
state = true;
|
|
final response = await ref
|
|
.read(authServiceProvider)
|
|
.verifyOTP(mobile: mobile, otp: otp);
|
|
final message = response.data['message'];
|
|
if (response.statusCode == 200) {
|
|
state = false;
|
|
return CommonResponse(isSuccess: true, message: message);
|
|
}
|
|
state = false;
|
|
return CommonResponse(isSuccess: false, message: message);
|
|
} catch (e) {
|
|
debugPrint(e.toString());
|
|
state = false;
|
|
return CommonResponse(isSuccess: false, message: e.toString());
|
|
}
|
|
}
|
|
|
|
/// Extract a human-readable error message from a DioException
|
|
String _extractErrorMessage(DioException e) {
|
|
if (e.response?.data != null) {
|
|
final data = e.response!.data;
|
|
if (data is Map) {
|
|
// Laravel returns {"message": "..."}
|
|
return data['message']?.toString() ??
|
|
'Request failed (${e.response?.statusCode})';
|
|
}
|
|
if (data is String && data.isNotEmpty) return data;
|
|
}
|
|
switch (e.type) {
|
|
case DioExceptionType.connectionTimeout:
|
|
return 'Connection timed out. Check your network.';
|
|
case DioExceptionType.connectionError:
|
|
return 'Cannot reach server. Check your connection.';
|
|
case DioExceptionType.receiveTimeout:
|
|
return 'Server took too long to respond.';
|
|
default:
|
|
return 'Request failed. Please try again.';
|
|
}
|
|
}
|
|
}
|
|
|
|
final authController =
|
|
StateNotifierProvider<AuthController, bool>((ref) => AuthController(ref));
|