add auth register
This commit is contained in:
245
lib/features/auth/data/datasources/auth_remote_datasource.dart
Normal file
245
lib/features/auth/data/datasources/auth_remote_datasource.dart
Normal file
@@ -0,0 +1,245 @@
|
||||
/// Authentication Remote Data Source
|
||||
///
|
||||
/// Handles all authentication-related API calls.
|
||||
library;
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:worker/core/errors/exceptions.dart';
|
||||
import 'package:worker/features/auth/data/models/auth_session_model.dart';
|
||||
import 'package:worker/features/auth/domain/entities/city.dart';
|
||||
import 'package:worker/features/auth/domain/entities/customer_group.dart';
|
||||
|
||||
/// Authentication Remote Data Source
|
||||
///
|
||||
/// Provides methods for:
|
||||
/// - Getting session (CSRF token and SID)
|
||||
/// - Fetching cities for registration
|
||||
/// - Fetching customer groups (roles) for registration
|
||||
/// - User registration
|
||||
class AuthRemoteDataSource {
|
||||
final Dio _dio;
|
||||
|
||||
AuthRemoteDataSource(this._dio);
|
||||
|
||||
/// Get Session
|
||||
///
|
||||
/// Fetches session data including SID and CSRF token.
|
||||
/// This should be called before making authenticated requests.
|
||||
///
|
||||
/// API: POST /api/method/dbiz_common.dbiz_common.api.auth.get_session
|
||||
Future<GetSessionResponse> getSession() async {
|
||||
try {
|
||||
final response = await _dio.post<Map<String, dynamic>>(
|
||||
'/api/method/dbiz_common.dbiz_common.api.auth.get_session',
|
||||
data: '',
|
||||
);
|
||||
|
||||
if (response.statusCode == 200 && response.data != null) {
|
||||
return GetSessionResponse.fromJson(response.data!);
|
||||
} else {
|
||||
throw ServerException(
|
||||
'Failed to get session: ${response.statusCode}',
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
if (e.response?.statusCode == 401) {
|
||||
throw const UnauthorizedException();
|
||||
} else if (e.response?.statusCode == 404) {
|
||||
throw NotFoundException('Session endpoint not found');
|
||||
} else {
|
||||
throw NetworkException(
|
||||
e.message ?? 'Failed to get session',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw ServerException('Unexpected error: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get Cities
|
||||
///
|
||||
/// Fetches list of cities/provinces for address selection.
|
||||
/// Requires authenticated session (CSRF token and Cookie).
|
||||
///
|
||||
/// API: POST /api/method/frappe.client.get_list
|
||||
/// DocType: City
|
||||
Future<List<City>> getCities({
|
||||
required String csrfToken,
|
||||
required String sid,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _dio.post<Map<String, dynamic>>(
|
||||
'/api/method/frappe.client.get_list',
|
||||
data: {
|
||||
'doctype': 'City',
|
||||
'fields': ['city_name', 'name', 'code'],
|
||||
'limit_page_length': 0,
|
||||
},
|
||||
options: Options(
|
||||
headers: {
|
||||
'X-Frappe-Csrf-Token': csrfToken,
|
||||
'Cookie': 'sid=$sid',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200 && response.data != null) {
|
||||
final message = response.data!['message'];
|
||||
if (message is List) {
|
||||
return message
|
||||
.map((json) => City.fromJson(json as Map<String, dynamic>))
|
||||
.toList();
|
||||
} else {
|
||||
throw ServerException('Invalid response format for cities');
|
||||
}
|
||||
} else {
|
||||
throw ServerException(
|
||||
'Failed to get cities: ${response.statusCode}',
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
if (e.response?.statusCode == 401) {
|
||||
throw const UnauthorizedException();
|
||||
} else if (e.response?.statusCode == 404) {
|
||||
throw NotFoundException('Cities endpoint not found');
|
||||
} else {
|
||||
throw NetworkException(
|
||||
e.message ?? 'Failed to get cities',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw ServerException('Unexpected error: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Get Customer Groups (Roles)
|
||||
///
|
||||
/// Fetches list of customer groups for user role selection.
|
||||
/// Requires authenticated session (CSRF token and Cookie).
|
||||
///
|
||||
/// API: POST /api/method/frappe.client.get_list
|
||||
/// DocType: Customer Group
|
||||
Future<List<CustomerGroup>> getCustomerGroups({
|
||||
required String csrfToken,
|
||||
required String sid,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _dio.post<Map<String, dynamic>>(
|
||||
'/api/method/frappe.client.get_list',
|
||||
data: {
|
||||
'doctype': 'Customer Group',
|
||||
'fields': ['customer_group_name', 'name', 'value'],
|
||||
'filters': {
|
||||
'is_group': 0,
|
||||
'is_active': 1,
|
||||
'customer': 1,
|
||||
},
|
||||
'limit_page_length': 0,
|
||||
},
|
||||
options: Options(
|
||||
headers: {
|
||||
'X-Frappe-Csrf-Token': csrfToken,
|
||||
'Cookie': 'sid=$sid',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200 && response.data != null) {
|
||||
final message = response.data!['message'];
|
||||
if (message is List) {
|
||||
return message
|
||||
.map((json) =>
|
||||
CustomerGroup.fromJson(json as Map<String, dynamic>))
|
||||
.toList();
|
||||
} else {
|
||||
throw ServerException('Invalid response format for customer groups');
|
||||
}
|
||||
} else {
|
||||
throw ServerException(
|
||||
'Failed to get customer groups: ${response.statusCode}',
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
if (e.response?.statusCode == 401) {
|
||||
throw const UnauthorizedException();
|
||||
} else if (e.response?.statusCode == 404) {
|
||||
throw NotFoundException('Customer groups endpoint not found');
|
||||
} else {
|
||||
throw NetworkException(
|
||||
e.message ?? 'Failed to get customer groups',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw ServerException('Unexpected error: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Register User
|
||||
///
|
||||
/// Registers a new user with the provided information.
|
||||
/// Requires authenticated session (CSRF token and Cookie).
|
||||
///
|
||||
/// API: POST /api/method/building_material.building_material.api.user.register
|
||||
Future<Map<String, dynamic>> register({
|
||||
required String csrfToken,
|
||||
required String sid,
|
||||
required String fullName,
|
||||
required String phone,
|
||||
required String email,
|
||||
required String customerGroupCode,
|
||||
required String cityCode,
|
||||
String? companyName,
|
||||
String? taxCode,
|
||||
String? idCardFrontBase64,
|
||||
String? idCardBackBase64,
|
||||
List<String>? certificatesBase64,
|
||||
}) async {
|
||||
try {
|
||||
final response = await _dio.post<Map<String, dynamic>>(
|
||||
'/api/method/building_material.building_material.api.user.register',
|
||||
data: {
|
||||
'full_name': fullName,
|
||||
'phone': phone,
|
||||
'email': email,
|
||||
'customer_group_code': customerGroupCode,
|
||||
'city_code': cityCode,
|
||||
'company_name': companyName,
|
||||
'tax_code': taxCode,
|
||||
'id_card_front_base64': idCardFrontBase64,
|
||||
'id_card_back_base64': idCardBackBase64,
|
||||
'certificates_base64': certificatesBase64 ?? [],
|
||||
},
|
||||
options: Options(
|
||||
headers: {
|
||||
'X-Frappe-Csrf-Token': csrfToken,
|
||||
'Cookie': 'sid=$sid',
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200 && response.data != null) {
|
||||
return response.data!;
|
||||
} else {
|
||||
throw ServerException(
|
||||
'Failed to register: ${response.statusCode}',
|
||||
);
|
||||
}
|
||||
} on DioException catch (e) {
|
||||
if (e.response?.statusCode == 401) {
|
||||
throw const UnauthorizedException();
|
||||
} else if (e.response?.statusCode == 400) {
|
||||
throw ValidationException(
|
||||
e.response?.data?['message'] as String? ?? 'Validation error',
|
||||
);
|
||||
} else if (e.response?.statusCode == 404) {
|
||||
throw NotFoundException('Register endpoint not found');
|
||||
} else {
|
||||
throw NetworkException(
|
||||
e.message ?? 'Failed to register',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw ServerException('Unexpected error: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,48 @@ sealed class AuthSessionResponse with _$AuthSessionResponse {
|
||||
_$AuthSessionResponseFromJson(json);
|
||||
}
|
||||
|
||||
/// Session Data (for GET SESSION API)
|
||||
///
|
||||
/// Represents the session data structure from get_session API.
|
||||
@freezed
|
||||
sealed class GetSessionData with _$GetSessionData {
|
||||
const factory GetSessionData({
|
||||
required String sid,
|
||||
@JsonKey(name: 'csrf_token') required String csrfToken,
|
||||
}) = _GetSessionData;
|
||||
|
||||
factory GetSessionData.fromJson(Map<String, dynamic> json) =>
|
||||
_$GetSessionDataFromJson(json);
|
||||
}
|
||||
|
||||
/// Get Session Message
|
||||
///
|
||||
/// Wrapper for session data in get_session API response.
|
||||
@freezed
|
||||
sealed class GetSessionMessage with _$GetSessionMessage {
|
||||
const factory GetSessionMessage({
|
||||
required GetSessionData data,
|
||||
}) = _GetSessionMessage;
|
||||
|
||||
factory GetSessionMessage.fromJson(Map<String, dynamic> json) =>
|
||||
_$GetSessionMessageFromJson(json);
|
||||
}
|
||||
|
||||
/// Get Session Response
|
||||
///
|
||||
/// Complete response from get_session API.
|
||||
@freezed
|
||||
sealed class GetSessionResponse with _$GetSessionResponse {
|
||||
const factory GetSessionResponse({
|
||||
required GetSessionMessage message,
|
||||
@JsonKey(name: 'home_page') required String homePage,
|
||||
@JsonKey(name: 'full_name') required String fullName,
|
||||
}) = _GetSessionResponse;
|
||||
|
||||
factory GetSessionResponse.fromJson(Map<String, dynamic> json) =>
|
||||
_$GetSessionResponseFromJson(json);
|
||||
}
|
||||
|
||||
/// Session Storage Model
|
||||
///
|
||||
/// Simplified model for storing session data in Hive.
|
||||
@@ -73,7 +115,17 @@ sealed class SessionData with _$SessionData {
|
||||
factory SessionData.fromJson(Map<String, dynamic> json) =>
|
||||
_$SessionDataFromJson(json);
|
||||
|
||||
/// Create from API response
|
||||
/// Create from get_session API response
|
||||
factory SessionData.fromGetSessionResponse(GetSessionResponse response) {
|
||||
return SessionData(
|
||||
sid: response.message.data.sid,
|
||||
csrfToken: response.message.data.csrfToken,
|
||||
fullName: response.fullName,
|
||||
createdAt: DateTime.now(),
|
||||
);
|
||||
}
|
||||
|
||||
/// Create from auth login API response
|
||||
factory SessionData.fromAuthResponse(AuthSessionResponse response) {
|
||||
return SessionData(
|
||||
sid: response.message.sid,
|
||||
|
||||
@@ -834,6 +834,822 @@ $LoginMessageCopyWith<$Res> get message {
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$GetSessionData {
|
||||
|
||||
String get sid;@JsonKey(name: 'csrf_token') String get csrfToken;
|
||||
/// Create a copy of GetSessionData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$GetSessionDataCopyWith<GetSessionData> get copyWith => _$GetSessionDataCopyWithImpl<GetSessionData>(this as GetSessionData, _$identity);
|
||||
|
||||
/// Serializes this GetSessionData to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is GetSessionData&&(identical(other.sid, sid) || other.sid == sid)&&(identical(other.csrfToken, csrfToken) || other.csrfToken == csrfToken));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,sid,csrfToken);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'GetSessionData(sid: $sid, csrfToken: $csrfToken)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $GetSessionDataCopyWith<$Res> {
|
||||
factory $GetSessionDataCopyWith(GetSessionData value, $Res Function(GetSessionData) _then) = _$GetSessionDataCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String sid,@JsonKey(name: 'csrf_token') String csrfToken
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$GetSessionDataCopyWithImpl<$Res>
|
||||
implements $GetSessionDataCopyWith<$Res> {
|
||||
_$GetSessionDataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final GetSessionData _self;
|
||||
final $Res Function(GetSessionData) _then;
|
||||
|
||||
/// Create a copy of GetSessionData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? sid = null,Object? csrfToken = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
sid: null == sid ? _self.sid : sid // ignore: cast_nullable_to_non_nullable
|
||||
as String,csrfToken: null == csrfToken ? _self.csrfToken : csrfToken // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [GetSessionData].
|
||||
extension GetSessionDataPatterns on GetSessionData {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _GetSessionData value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionData() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _GetSessionData value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionData():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _GetSessionData value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionData() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String sid, @JsonKey(name: 'csrf_token') String csrfToken)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionData() when $default != null:
|
||||
return $default(_that.sid,_that.csrfToken);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String sid, @JsonKey(name: 'csrf_token') String csrfToken) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionData():
|
||||
return $default(_that.sid,_that.csrfToken);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String sid, @JsonKey(name: 'csrf_token') String csrfToken)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionData() when $default != null:
|
||||
return $default(_that.sid,_that.csrfToken);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _GetSessionData implements GetSessionData {
|
||||
const _GetSessionData({required this.sid, @JsonKey(name: 'csrf_token') required this.csrfToken});
|
||||
factory _GetSessionData.fromJson(Map<String, dynamic> json) => _$GetSessionDataFromJson(json);
|
||||
|
||||
@override final String sid;
|
||||
@override@JsonKey(name: 'csrf_token') final String csrfToken;
|
||||
|
||||
/// Create a copy of GetSessionData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$GetSessionDataCopyWith<_GetSessionData> get copyWith => __$GetSessionDataCopyWithImpl<_GetSessionData>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$GetSessionDataToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _GetSessionData&&(identical(other.sid, sid) || other.sid == sid)&&(identical(other.csrfToken, csrfToken) || other.csrfToken == csrfToken));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,sid,csrfToken);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'GetSessionData(sid: $sid, csrfToken: $csrfToken)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$GetSessionDataCopyWith<$Res> implements $GetSessionDataCopyWith<$Res> {
|
||||
factory _$GetSessionDataCopyWith(_GetSessionData value, $Res Function(_GetSessionData) _then) = __$GetSessionDataCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String sid,@JsonKey(name: 'csrf_token') String csrfToken
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$GetSessionDataCopyWithImpl<$Res>
|
||||
implements _$GetSessionDataCopyWith<$Res> {
|
||||
__$GetSessionDataCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _GetSessionData _self;
|
||||
final $Res Function(_GetSessionData) _then;
|
||||
|
||||
/// Create a copy of GetSessionData
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? sid = null,Object? csrfToken = null,}) {
|
||||
return _then(_GetSessionData(
|
||||
sid: null == sid ? _self.sid : sid // ignore: cast_nullable_to_non_nullable
|
||||
as String,csrfToken: null == csrfToken ? _self.csrfToken : csrfToken // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$GetSessionMessage {
|
||||
|
||||
GetSessionData get data;
|
||||
/// Create a copy of GetSessionMessage
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$GetSessionMessageCopyWith<GetSessionMessage> get copyWith => _$GetSessionMessageCopyWithImpl<GetSessionMessage>(this as GetSessionMessage, _$identity);
|
||||
|
||||
/// Serializes this GetSessionMessage to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is GetSessionMessage&&(identical(other.data, data) || other.data == data));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,data);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'GetSessionMessage(data: $data)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $GetSessionMessageCopyWith<$Res> {
|
||||
factory $GetSessionMessageCopyWith(GetSessionMessage value, $Res Function(GetSessionMessage) _then) = _$GetSessionMessageCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
GetSessionData data
|
||||
});
|
||||
|
||||
|
||||
$GetSessionDataCopyWith<$Res> get data;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$GetSessionMessageCopyWithImpl<$Res>
|
||||
implements $GetSessionMessageCopyWith<$Res> {
|
||||
_$GetSessionMessageCopyWithImpl(this._self, this._then);
|
||||
|
||||
final GetSessionMessage _self;
|
||||
final $Res Function(GetSessionMessage) _then;
|
||||
|
||||
/// Create a copy of GetSessionMessage
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? data = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
data: null == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
||||
as GetSessionData,
|
||||
));
|
||||
}
|
||||
/// Create a copy of GetSessionMessage
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$GetSessionDataCopyWith<$Res> get data {
|
||||
|
||||
return $GetSessionDataCopyWith<$Res>(_self.data, (value) {
|
||||
return _then(_self.copyWith(data: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [GetSessionMessage].
|
||||
extension GetSessionMessagePatterns on GetSessionMessage {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _GetSessionMessage value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionMessage() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _GetSessionMessage value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionMessage():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _GetSessionMessage value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionMessage() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( GetSessionData data)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionMessage() when $default != null:
|
||||
return $default(_that.data);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( GetSessionData data) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionMessage():
|
||||
return $default(_that.data);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( GetSessionData data)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionMessage() when $default != null:
|
||||
return $default(_that.data);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _GetSessionMessage implements GetSessionMessage {
|
||||
const _GetSessionMessage({required this.data});
|
||||
factory _GetSessionMessage.fromJson(Map<String, dynamic> json) => _$GetSessionMessageFromJson(json);
|
||||
|
||||
@override final GetSessionData data;
|
||||
|
||||
/// Create a copy of GetSessionMessage
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$GetSessionMessageCopyWith<_GetSessionMessage> get copyWith => __$GetSessionMessageCopyWithImpl<_GetSessionMessage>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$GetSessionMessageToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _GetSessionMessage&&(identical(other.data, data) || other.data == data));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,data);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'GetSessionMessage(data: $data)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$GetSessionMessageCopyWith<$Res> implements $GetSessionMessageCopyWith<$Res> {
|
||||
factory _$GetSessionMessageCopyWith(_GetSessionMessage value, $Res Function(_GetSessionMessage) _then) = __$GetSessionMessageCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
GetSessionData data
|
||||
});
|
||||
|
||||
|
||||
@override $GetSessionDataCopyWith<$Res> get data;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$GetSessionMessageCopyWithImpl<$Res>
|
||||
implements _$GetSessionMessageCopyWith<$Res> {
|
||||
__$GetSessionMessageCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _GetSessionMessage _self;
|
||||
final $Res Function(_GetSessionMessage) _then;
|
||||
|
||||
/// Create a copy of GetSessionMessage
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? data = null,}) {
|
||||
return _then(_GetSessionMessage(
|
||||
data: null == data ? _self.data : data // ignore: cast_nullable_to_non_nullable
|
||||
as GetSessionData,
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a copy of GetSessionMessage
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$GetSessionDataCopyWith<$Res> get data {
|
||||
|
||||
return $GetSessionDataCopyWith<$Res>(_self.data, (value) {
|
||||
return _then(_self.copyWith(data: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$GetSessionResponse {
|
||||
|
||||
GetSessionMessage get message;@JsonKey(name: 'home_page') String get homePage;@JsonKey(name: 'full_name') String get fullName;
|
||||
/// Create a copy of GetSessionResponse
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$GetSessionResponseCopyWith<GetSessionResponse> get copyWith => _$GetSessionResponseCopyWithImpl<GetSessionResponse>(this as GetSessionResponse, _$identity);
|
||||
|
||||
/// Serializes this GetSessionResponse to a JSON map.
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is GetSessionResponse&&(identical(other.message, message) || other.message == message)&&(identical(other.homePage, homePage) || other.homePage == homePage)&&(identical(other.fullName, fullName) || other.fullName == fullName));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,message,homePage,fullName);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'GetSessionResponse(message: $message, homePage: $homePage, fullName: $fullName)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class $GetSessionResponseCopyWith<$Res> {
|
||||
factory $GetSessionResponseCopyWith(GetSessionResponse value, $Res Function(GetSessionResponse) _then) = _$GetSessionResponseCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
GetSessionMessage message,@JsonKey(name: 'home_page') String homePage,@JsonKey(name: 'full_name') String fullName
|
||||
});
|
||||
|
||||
|
||||
$GetSessionMessageCopyWith<$Res> get message;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$GetSessionResponseCopyWithImpl<$Res>
|
||||
implements $GetSessionResponseCopyWith<$Res> {
|
||||
_$GetSessionResponseCopyWithImpl(this._self, this._then);
|
||||
|
||||
final GetSessionResponse _self;
|
||||
final $Res Function(GetSessionResponse) _then;
|
||||
|
||||
/// Create a copy of GetSessionResponse
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? message = null,Object? homePage = null,Object? fullName = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
message: null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||
as GetSessionMessage,homePage: null == homePage ? _self.homePage : homePage // ignore: cast_nullable_to_non_nullable
|
||||
as String,fullName: null == fullName ? _self.fullName : fullName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
/// Create a copy of GetSessionResponse
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$GetSessionMessageCopyWith<$Res> get message {
|
||||
|
||||
return $GetSessionMessageCopyWith<$Res>(_self.message, (value) {
|
||||
return _then(_self.copyWith(message: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Adds pattern-matching-related methods to [GetSessionResponse].
|
||||
extension GetSessionResponsePatterns on GetSessionResponse {
|
||||
/// A variant of `map` that fallback to returning `orElse`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _GetSessionResponse value)? $default,{required TResult orElse(),}){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionResponse() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// Callbacks receives the raw object, upcasted.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case final Subclass2 value:
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _GetSessionResponse value) $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionResponse():
|
||||
return $default(_that);}
|
||||
}
|
||||
/// A variant of `map` that fallback to returning `null`.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case final Subclass value:
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _GetSessionResponse value)? $default,){
|
||||
final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionResponse() when $default != null:
|
||||
return $default(_that);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
/// A variant of `when` that fallback to an `orElse` callback.
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return orElse();
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( GetSessionMessage message, @JsonKey(name: 'home_page') String homePage, @JsonKey(name: 'full_name') String fullName)? $default,{required TResult orElse(),}) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionResponse() when $default != null:
|
||||
return $default(_that.message,_that.homePage,_that.fullName);case _:
|
||||
return orElse();
|
||||
|
||||
}
|
||||
}
|
||||
/// A `switch`-like method, using callbacks.
|
||||
///
|
||||
/// As opposed to `map`, this offers destructuring.
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case Subclass2(:final field2):
|
||||
/// return ...;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( GetSessionMessage message, @JsonKey(name: 'home_page') String homePage, @JsonKey(name: 'full_name') String fullName) $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionResponse():
|
||||
return $default(_that.message,_that.homePage,_that.fullName);}
|
||||
}
|
||||
/// A variant of `when` that fallback to returning `null`
|
||||
///
|
||||
/// It is equivalent to doing:
|
||||
/// ```dart
|
||||
/// switch (sealedClass) {
|
||||
/// case Subclass(:final field):
|
||||
/// return ...;
|
||||
/// case _:
|
||||
/// return null;
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( GetSessionMessage message, @JsonKey(name: 'home_page') String homePage, @JsonKey(name: 'full_name') String fullName)? $default,) {final _that = this;
|
||||
switch (_that) {
|
||||
case _GetSessionResponse() when $default != null:
|
||||
return $default(_that.message,_that.homePage,_that.fullName);case _:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
|
||||
class _GetSessionResponse implements GetSessionResponse {
|
||||
const _GetSessionResponse({required this.message, @JsonKey(name: 'home_page') required this.homePage, @JsonKey(name: 'full_name') required this.fullName});
|
||||
factory _GetSessionResponse.fromJson(Map<String, dynamic> json) => _$GetSessionResponseFromJson(json);
|
||||
|
||||
@override final GetSessionMessage message;
|
||||
@override@JsonKey(name: 'home_page') final String homePage;
|
||||
@override@JsonKey(name: 'full_name') final String fullName;
|
||||
|
||||
/// Create a copy of GetSessionResponse
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$GetSessionResponseCopyWith<_GetSessionResponse> get copyWith => __$GetSessionResponseCopyWithImpl<_GetSessionResponse>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$GetSessionResponseToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _GetSessionResponse&&(identical(other.message, message) || other.message == message)&&(identical(other.homePage, homePage) || other.homePage == homePage)&&(identical(other.fullName, fullName) || other.fullName == fullName));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,message,homePage,fullName);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'GetSessionResponse(message: $message, homePage: $homePage, fullName: $fullName)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$GetSessionResponseCopyWith<$Res> implements $GetSessionResponseCopyWith<$Res> {
|
||||
factory _$GetSessionResponseCopyWith(_GetSessionResponse value, $Res Function(_GetSessionResponse) _then) = __$GetSessionResponseCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
GetSessionMessage message,@JsonKey(name: 'home_page') String homePage,@JsonKey(name: 'full_name') String fullName
|
||||
});
|
||||
|
||||
|
||||
@override $GetSessionMessageCopyWith<$Res> get message;
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$GetSessionResponseCopyWithImpl<$Res>
|
||||
implements _$GetSessionResponseCopyWith<$Res> {
|
||||
__$GetSessionResponseCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _GetSessionResponse _self;
|
||||
final $Res Function(_GetSessionResponse) _then;
|
||||
|
||||
/// Create a copy of GetSessionResponse
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? message = null,Object? homePage = null,Object? fullName = null,}) {
|
||||
return _then(_GetSessionResponse(
|
||||
message: null == message ? _self.message : message // ignore: cast_nullable_to_non_nullable
|
||||
as GetSessionMessage,homePage: null == homePage ? _self.homePage : homePage // ignore: cast_nullable_to_non_nullable
|
||||
as String,fullName: null == fullName ? _self.fullName : fullName // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
/// Create a copy of GetSessionResponse
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$GetSessionMessageCopyWith<$Res> get message {
|
||||
|
||||
return $GetSessionMessageCopyWith<$Res>(_self.message, (value) {
|
||||
return _then(_self.copyWith(message: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
mixin _$SessionData {
|
||||
|
||||
|
||||
@@ -93,6 +93,57 @@ Map<String, dynamic> _$AuthSessionResponseToJson(
|
||||
'full_name': instance.fullName,
|
||||
};
|
||||
|
||||
_GetSessionData _$GetSessionDataFromJson(Map<String, dynamic> json) =>
|
||||
$checkedCreate('_GetSessionData', json, ($checkedConvert) {
|
||||
final val = _GetSessionData(
|
||||
sid: $checkedConvert('sid', (v) => v as String),
|
||||
csrfToken: $checkedConvert('csrf_token', (v) => v as String),
|
||||
);
|
||||
return val;
|
||||
}, fieldKeyMap: const {'csrfToken': 'csrf_token'});
|
||||
|
||||
Map<String, dynamic> _$GetSessionDataToJson(_GetSessionData instance) =>
|
||||
<String, dynamic>{'sid': instance.sid, 'csrf_token': instance.csrfToken};
|
||||
|
||||
_GetSessionMessage _$GetSessionMessageFromJson(Map<String, dynamic> json) =>
|
||||
$checkedCreate('_GetSessionMessage', json, ($checkedConvert) {
|
||||
final val = _GetSessionMessage(
|
||||
data: $checkedConvert(
|
||||
'data',
|
||||
(v) => GetSessionData.fromJson(v as Map<String, dynamic>),
|
||||
),
|
||||
);
|
||||
return val;
|
||||
});
|
||||
|
||||
Map<String, dynamic> _$GetSessionMessageToJson(_GetSessionMessage instance) =>
|
||||
<String, dynamic>{'data': instance.data.toJson()};
|
||||
|
||||
_GetSessionResponse _$GetSessionResponseFromJson(Map<String, dynamic> json) =>
|
||||
$checkedCreate(
|
||||
'_GetSessionResponse',
|
||||
json,
|
||||
($checkedConvert) {
|
||||
final val = _GetSessionResponse(
|
||||
message: $checkedConvert(
|
||||
'message',
|
||||
(v) => GetSessionMessage.fromJson(v as Map<String, dynamic>),
|
||||
),
|
||||
homePage: $checkedConvert('home_page', (v) => v as String),
|
||||
fullName: $checkedConvert('full_name', (v) => v as String),
|
||||
);
|
||||
return val;
|
||||
},
|
||||
fieldKeyMap: const {'homePage': 'home_page', 'fullName': 'full_name'},
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$GetSessionResponseToJson(_GetSessionResponse instance) =>
|
||||
<String, dynamic>{
|
||||
'message': instance.message.toJson(),
|
||||
'home_page': instance.homePage,
|
||||
'full_name': instance.fullName,
|
||||
};
|
||||
|
||||
_SessionData _$SessionDataFromJson(Map<String, dynamic> json) => $checkedCreate(
|
||||
'_SessionData',
|
||||
json,
|
||||
|
||||
60
lib/features/auth/domain/entities/city.dart
Normal file
60
lib/features/auth/domain/entities/city.dart
Normal file
@@ -0,0 +1,60 @@
|
||||
/// Domain Entity: City
|
||||
///
|
||||
/// Represents a city/province for address selection.
|
||||
library;
|
||||
|
||||
/// City Entity
|
||||
class City {
|
||||
/// Unique city identifier
|
||||
final String name;
|
||||
|
||||
/// City code (e.g., "01", "02")
|
||||
final String code;
|
||||
|
||||
/// Display name
|
||||
final String cityName;
|
||||
|
||||
const City({
|
||||
required this.name,
|
||||
required this.code,
|
||||
required this.cityName,
|
||||
});
|
||||
|
||||
/// Create from JSON map
|
||||
factory City.fromJson(Map<String, dynamic> json) {
|
||||
return City(
|
||||
name: json['name'] as String,
|
||||
code: json['code'] as String,
|
||||
cityName: json['city_name'] as String,
|
||||
);
|
||||
}
|
||||
|
||||
/// Convert to JSON map
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'name': name,
|
||||
'code': code,
|
||||
'city_name': cityName,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is City &&
|
||||
other.name == name &&
|
||||
other.code == code &&
|
||||
other.cityName == cityName;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return Object.hash(name, code, cityName);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'City(name: $name, code: $code, cityName: $cityName)';
|
||||
}
|
||||
}
|
||||
60
lib/features/auth/domain/entities/customer_group.dart
Normal file
60
lib/features/auth/domain/entities/customer_group.dart
Normal file
@@ -0,0 +1,60 @@
|
||||
/// Domain Entity: Customer Group (Role)
|
||||
///
|
||||
/// Represents a customer group/role for user registration.
|
||||
library;
|
||||
|
||||
/// Customer Group Entity
|
||||
class CustomerGroup {
|
||||
/// Unique identifier
|
||||
final String name;
|
||||
|
||||
/// Display name
|
||||
final String customerGroupName;
|
||||
|
||||
/// Group value/code
|
||||
final String? value;
|
||||
|
||||
const CustomerGroup({
|
||||
required this.name,
|
||||
required this.customerGroupName,
|
||||
this.value,
|
||||
});
|
||||
|
||||
/// Create from JSON map
|
||||
factory CustomerGroup.fromJson(Map<String, dynamic> json) {
|
||||
return CustomerGroup(
|
||||
name: json['name'] as String,
|
||||
customerGroupName: json['customer_group_name'] as String,
|
||||
value: json['value'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
/// Convert to JSON map
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'name': name,
|
||||
'customer_group_name': customerGroupName,
|
||||
if (value != null) 'value': value,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is CustomerGroup &&
|
||||
other.name == name &&
|
||||
other.customerGroupName == customerGroupName &&
|
||||
other.value == value;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return Object.hash(name, customerGroupName, value);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'CustomerGroup(name: $name, customerGroupName: $customerGroupName, value: $value)';
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
/// Matches design from html/register.html
|
||||
library;
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -12,12 +13,17 @@ import 'package:go_router/go_router.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
||||
import 'package:worker/core/constants/ui_constants.dart';
|
||||
import 'package:worker/core/router/app_router.dart';
|
||||
import 'package:worker/core/theme/colors.dart';
|
||||
import 'package:worker/core/utils/validators.dart';
|
||||
import 'package:worker/features/auth/domain/entities/business_unit.dart';
|
||||
import 'package:worker/features/auth/domain/entities/city.dart';
|
||||
import 'package:worker/features/auth/domain/entities/customer_group.dart';
|
||||
import 'package:worker/features/auth/presentation/providers/cities_provider.dart';
|
||||
import 'package:worker/features/auth/presentation/providers/customer_groups_provider.dart';
|
||||
import 'package:worker/features/auth/presentation/providers/session_provider.dart';
|
||||
import 'package:worker/features/auth/presentation/widgets/phone_input_field.dart';
|
||||
import 'package:worker/features/auth/presentation/widgets/file_upload_card.dart';
|
||||
import 'package:worker/features/auth/presentation/widgets/role_dropdown.dart';
|
||||
|
||||
/// Registration Page
|
||||
///
|
||||
@@ -65,16 +71,60 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
|
||||
final _companyFocus = FocusNode();
|
||||
|
||||
// State
|
||||
String? _selectedRole;
|
||||
String? _selectedCity;
|
||||
CustomerGroup? _selectedRole;
|
||||
City? _selectedCity;
|
||||
File? _idCardFile;
|
||||
File? _certificateFile;
|
||||
bool _termsAccepted = false;
|
||||
bool _passwordVisible = false;
|
||||
bool _isLoading = false;
|
||||
bool _isLoadingData = true;
|
||||
bool _hasInitialized = false;
|
||||
|
||||
final _imagePicker = ImagePicker();
|
||||
|
||||
/// Initialize session and load data
|
||||
/// This should be called from build method or after widget is mounted
|
||||
Future<void> _initializeData() async {
|
||||
if (!mounted) return;
|
||||
|
||||
setState(() {
|
||||
_isLoadingData = true;
|
||||
_hasInitialized = true;
|
||||
});
|
||||
|
||||
try {
|
||||
// Step 1: Get session (public API user)
|
||||
await ref.read(sessionProvider.notifier).getSession();
|
||||
|
||||
// Step 2: Fetch cities and customer groups in parallel using the session
|
||||
await Future.wait([
|
||||
ref.read(citiesProvider.notifier).fetchCities(),
|
||||
ref.read(customerGroupsProvider.notifier).fetchCustomerGroups(),
|
||||
]);
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Lỗi tải dữ liệu: $e'),
|
||||
backgroundColor: AppColors.danger,
|
||||
action: SnackBarAction(
|
||||
label: 'Thử lại',
|
||||
textColor: AppColors.white,
|
||||
onPressed: _initializeData,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isLoadingData = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_fullNameController.dispose();
|
||||
@@ -95,8 +145,23 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
|
||||
}
|
||||
|
||||
/// Check if verification section should be shown
|
||||
/// Note: This is based on the old role system
|
||||
/// TODO: Update this logic based on actual customer group requirements
|
||||
bool get _shouldShowVerification {
|
||||
return _selectedRole == 'worker' || _selectedRole == 'dealer';
|
||||
// For now, always hide verification section since we're using customer groups
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Convert file to base64 string
|
||||
Future<String?> _fileToBase64(File? file) async {
|
||||
if (file == null) return null;
|
||||
try {
|
||||
final bytes = await file.readAsBytes();
|
||||
return base64Encode(bytes);
|
||||
} catch (e) {
|
||||
debugPrint('Error converting file to base64: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Pick image from gallery or camera
|
||||
@@ -238,48 +303,60 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
|
||||
});
|
||||
|
||||
try {
|
||||
// TODO: Implement actual registration API call
|
||||
// Include widget.selectedBusinessUnit?.id in the API request
|
||||
// Example:
|
||||
// final result = await authRepository.register(
|
||||
// fullName: _fullNameController.text.trim(),
|
||||
// phone: _phoneController.text.trim(),
|
||||
// email: _emailController.text.trim(),
|
||||
// password: _passwordController.text,
|
||||
// role: _selectedRole,
|
||||
// businessUnitId: widget.selectedBusinessUnit?.id,
|
||||
// ...
|
||||
// );
|
||||
// Get session state for CSRF token and SID
|
||||
final sessionState = ref.read(sessionProvider);
|
||||
|
||||
// For now, simulate API delay
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
if (!sessionState.hasSession) {
|
||||
throw Exception('Session không hợp lệ. Vui lòng thử lại.');
|
||||
}
|
||||
|
||||
// Convert files to base64
|
||||
final idCardFrontBase64 = await _fileToBase64(_idCardFile);
|
||||
final certificatesBase64 = _certificateFile != null
|
||||
? [await _fileToBase64(_certificateFile)]
|
||||
: <String?>[];
|
||||
|
||||
// Remove null values from certificates list
|
||||
final validCertificates = certificatesBase64
|
||||
.whereType<String>()
|
||||
.toList();
|
||||
|
||||
// Call registration API
|
||||
final dataSource = ref.read(authRemoteDataSourceProvider);
|
||||
final response = await dataSource.register(
|
||||
csrfToken: sessionState.csrfToken!,
|
||||
sid: sessionState.sid!,
|
||||
fullName: _fullNameController.text.trim(),
|
||||
phone: _phoneController.text.trim(),
|
||||
email: _emailController.text.trim(),
|
||||
customerGroupCode: _selectedRole?.value ?? _selectedRole?.name ?? '',
|
||||
cityCode: _selectedCity?.code ?? '',
|
||||
companyName: _companyController.text.trim().isEmpty
|
||||
? null
|
||||
: _companyController.text.trim(),
|
||||
taxCode: _taxCodeController.text.trim().isEmpty
|
||||
? null
|
||||
: _taxCodeController.text.trim(),
|
||||
idCardFrontBase64: idCardFrontBase64,
|
||||
idCardBackBase64: null, // Not collecting back side in current UI
|
||||
certificatesBase64: validCertificates,
|
||||
);
|
||||
|
||||
if (mounted) {
|
||||
// Navigate based on role
|
||||
if (_shouldShowVerification) {
|
||||
// For workers/dealers with verification, show pending page
|
||||
// TODO: Navigate to pending approval page
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'Đăng ký thành công! Tài khoản đang chờ xét duyệt.',
|
||||
),
|
||||
backgroundColor: AppColors.success,
|
||||
// Show success message
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
'Đăng ký thành công!',
|
||||
// response['message']?.toString() ?? 'Đăng ký thành công!',
|
||||
),
|
||||
);
|
||||
context.pop();
|
||||
} else {
|
||||
// For other roles, navigate to OTP verification
|
||||
// TODO: Navigate to OTP verification page
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Đăng ký thành công! Vui lòng xác thực OTP.'),
|
||||
backgroundColor: AppColors.success,
|
||||
),
|
||||
);
|
||||
// context.push('/otp-verification');
|
||||
context.pop();
|
||||
}
|
||||
duration: Duration(seconds: 1),
|
||||
backgroundColor: AppColors.success,
|
||||
),
|
||||
);
|
||||
|
||||
Future<void>.delayed(const Duration(seconds: 1)).then((_) => context.goLogin());
|
||||
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
@@ -301,6 +378,14 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// Initialize data on first build
|
||||
if (!_hasInitialized) {
|
||||
// Use addPostFrameCallback to avoid calling setState during build
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
_initializeData();
|
||||
});
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFF4F6F8),
|
||||
appBar: AppBar(
|
||||
@@ -320,8 +405,22 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
|
||||
),
|
||||
centerTitle: false,
|
||||
),
|
||||
body: SafeArea(
|
||||
child: Form(
|
||||
body: _isLoadingData
|
||||
? const Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
CircularProgressIndicator(),
|
||||
SizedBox(height: AppSpacing.md),
|
||||
Text(
|
||||
'Đang tải dữ liệu...',
|
||||
style: TextStyle(color: AppColors.grey500),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: SafeArea(
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(AppSpacing.md),
|
||||
@@ -442,29 +541,9 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
// Role Selection
|
||||
// Role Selection (Customer Groups)
|
||||
_buildLabel('Vai trò *'),
|
||||
RoleDropdown(
|
||||
value: _selectedRole,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_selectedRole = value;
|
||||
// Clear verification fields when role changes
|
||||
if (!_shouldShowVerification) {
|
||||
_idNumberController.clear();
|
||||
_taxCodeController.clear();
|
||||
_idCardFile = null;
|
||||
_certificateFile = null;
|
||||
}
|
||||
});
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Vui lòng chọn vai trò';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
_buildCustomerGroupDropdown(),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
// Verification Section (conditional)
|
||||
@@ -488,47 +567,7 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
|
||||
|
||||
// City/Province
|
||||
_buildLabel('Tỉnh/Thành phố *'),
|
||||
DropdownButtonFormField<String>(
|
||||
value: _selectedCity,
|
||||
decoration: _buildInputDecoration(
|
||||
hintText: 'Chọn tỉnh/thành phố',
|
||||
prefixIcon: Icons.location_city,
|
||||
),
|
||||
items: const [
|
||||
DropdownMenuItem(
|
||||
value: 'hanoi',
|
||||
child: Text('Hà Nội'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'hcm',
|
||||
child: Text('TP. Hồ Chí Minh'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'danang',
|
||||
child: Text('Đà Nẵng'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'haiphong',
|
||||
child: Text('Hải Phòng'),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 'cantho',
|
||||
child: Text('Cần Thơ'),
|
||||
),
|
||||
DropdownMenuItem(value: 'other', child: Text('Khác')),
|
||||
],
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_selectedCity = value;
|
||||
});
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'Vui lòng chọn tỉnh/thành phố';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
_buildCityDropdown(),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
// Terms and Conditions
|
||||
@@ -648,8 +687,8 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -712,6 +751,143 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Build customer group dropdown
|
||||
Widget _buildCustomerGroupDropdown() {
|
||||
final customerGroupsAsync = ref.watch(customerGroupsProvider);
|
||||
|
||||
return customerGroupsAsync.when(
|
||||
data: (groups) {
|
||||
return DropdownButtonFormField<CustomerGroup>(
|
||||
value: _selectedRole,
|
||||
decoration: _buildInputDecoration(
|
||||
hintText: 'Chọn vai trò',
|
||||
prefixIcon: Icons.work,
|
||||
),
|
||||
items: groups
|
||||
.map(
|
||||
(group) => DropdownMenuItem(
|
||||
value: group,
|
||||
child: Text(group.customerGroupName),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_selectedRole = value;
|
||||
// Clear verification fields when role changes
|
||||
if (!_shouldShowVerification) {
|
||||
_idNumberController.clear();
|
||||
_taxCodeController.clear();
|
||||
_idCardFile = null;
|
||||
_certificateFile = null;
|
||||
}
|
||||
});
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null) {
|
||||
return 'Vui lòng chọn vai trò';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
);
|
||||
},
|
||||
loading: () => const SizedBox(
|
||||
height: 48,
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
error: (error, stack) => Container(
|
||||
height: 48,
|
||||
padding: const EdgeInsets.all(AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.danger.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius),
|
||||
border: Border.all(color: AppColors.danger),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.error_outline, color: AppColors.danger, size: 20),
|
||||
const SizedBox(width: AppSpacing.xs),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Lỗi tải vai trò',
|
||||
style: const TextStyle(color: AppColors.danger, fontSize: 12),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: _initializeData,
|
||||
child: const Text('Thử lại', style: TextStyle(fontSize: 12)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Build city dropdown
|
||||
Widget _buildCityDropdown() {
|
||||
final citiesAsync = ref.watch(citiesProvider);
|
||||
|
||||
return citiesAsync.when(
|
||||
data: (cities) {
|
||||
return DropdownButtonFormField<City>(
|
||||
value: _selectedCity,
|
||||
decoration: _buildInputDecoration(
|
||||
hintText: 'Chọn tỉnh/thành phố',
|
||||
prefixIcon: Icons.location_city,
|
||||
),
|
||||
items: cities
|
||||
.map(
|
||||
(city) => DropdownMenuItem(
|
||||
value: city,
|
||||
child: Text(city.cityName),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
_selectedCity = value;
|
||||
});
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null) {
|
||||
return 'Vui lòng chọn tỉnh/thành phố';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
);
|
||||
},
|
||||
loading: () => const SizedBox(
|
||||
height: 48,
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
error: (error, stack) => Container(
|
||||
height: 48,
|
||||
padding: const EdgeInsets.all(AppSpacing.sm),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.danger.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(InputFieldSpecs.borderRadius),
|
||||
border: Border.all(color: AppColors.danger),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(Icons.error_outline, color: AppColors.danger, size: 20),
|
||||
const SizedBox(width: AppSpacing.xs),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Lỗi tải danh sách tỉnh/thành phố',
|
||||
style: const TextStyle(color: AppColors.danger, fontSize: 12),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: _initializeData,
|
||||
child: const Text('Thử lại', style: TextStyle(fontSize: 12)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Build verification section
|
||||
Widget _buildVerificationSection() {
|
||||
return Container(
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/// Cities Provider
|
||||
///
|
||||
/// Manages the list of cities/provinces for address selection
|
||||
library;
|
||||
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:worker/features/auth/data/datasources/auth_remote_datasource.dart';
|
||||
import 'package:worker/features/auth/domain/entities/city.dart';
|
||||
import 'package:worker/features/auth/presentation/providers/session_provider.dart';
|
||||
|
||||
part 'cities_provider.g.dart';
|
||||
|
||||
/// Cities Provider
|
||||
///
|
||||
/// Fetches list of cities from API for registration form.
|
||||
/// Requires active session (CSRF token and SID).
|
||||
/// keepAlive: true ensures the cities list persists and doesn't auto-dispose.
|
||||
@Riverpod(keepAlive: true)
|
||||
class Cities extends _$Cities {
|
||||
@override
|
||||
Future<List<City>> build() async {
|
||||
// Don't auto-fetch on build, wait for manual call
|
||||
return [];
|
||||
}
|
||||
|
||||
/// Fetch cities from API
|
||||
Future<void> fetchCities() async {
|
||||
state = const AsyncValue.loading();
|
||||
|
||||
state = await AsyncValue.guard(() async {
|
||||
final sessionState = ref.read(sessionProvider);
|
||||
|
||||
if (!sessionState.hasSession) {
|
||||
throw Exception('No active session. Please get session first.');
|
||||
}
|
||||
|
||||
final dataSource = ref.read(authRemoteDataSourceProvider);
|
||||
return await dataSource.getCities(
|
||||
csrfToken: sessionState.csrfToken!,
|
||||
sid: sessionState.sid!,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Refresh cities list
|
||||
Future<void> refresh() async {
|
||||
await fetchCities();
|
||||
}
|
||||
}
|
||||
|
||||
/// Provider to get a specific city by code
|
||||
@riverpod
|
||||
City? cityByCode(Ref ref, String code) {
|
||||
final citiesAsync = ref.watch(citiesProvider);
|
||||
|
||||
return citiesAsync.whenOrNull(
|
||||
data: (List<City> cities) => cities.firstWhere(
|
||||
(City city) => city.code == code,
|
||||
orElse: () => cities.first,
|
||||
),
|
||||
);
|
||||
}
|
||||
160
lib/features/auth/presentation/providers/cities_provider.g.dart
Normal file
160
lib/features/auth/presentation/providers/cities_provider.g.dart
Normal file
@@ -0,0 +1,160 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'cities_provider.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
/// Cities Provider
|
||||
///
|
||||
/// Fetches list of cities from API for registration form.
|
||||
/// Requires active session (CSRF token and SID).
|
||||
/// keepAlive: true ensures the cities list persists and doesn't auto-dispose.
|
||||
|
||||
@ProviderFor(Cities)
|
||||
const citiesProvider = CitiesProvider._();
|
||||
|
||||
/// Cities Provider
|
||||
///
|
||||
/// Fetches list of cities from API for registration form.
|
||||
/// Requires active session (CSRF token and SID).
|
||||
/// keepAlive: true ensures the cities list persists and doesn't auto-dispose.
|
||||
final class CitiesProvider extends $AsyncNotifierProvider<Cities, List<City>> {
|
||||
/// Cities Provider
|
||||
///
|
||||
/// Fetches list of cities from API for registration form.
|
||||
/// Requires active session (CSRF token and SID).
|
||||
/// keepAlive: true ensures the cities list persists and doesn't auto-dispose.
|
||||
const CitiesProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'citiesProvider',
|
||||
isAutoDispose: false,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$citiesHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
Cities create() => Cities();
|
||||
}
|
||||
|
||||
String _$citiesHash() => r'0de4a7d44e576d74ecd875ddad46d6cb52a38bf8';
|
||||
|
||||
/// Cities Provider
|
||||
///
|
||||
/// Fetches list of cities from API for registration form.
|
||||
/// Requires active session (CSRF token and SID).
|
||||
/// keepAlive: true ensures the cities list persists and doesn't auto-dispose.
|
||||
|
||||
abstract class _$Cities extends $AsyncNotifier<List<City>> {
|
||||
FutureOr<List<City>> build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<AsyncValue<List<City>>, List<City>>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<AsyncValue<List<City>>, List<City>>,
|
||||
AsyncValue<List<City>>,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
}
|
||||
}
|
||||
|
||||
/// Provider to get a specific city by code
|
||||
|
||||
@ProviderFor(cityByCode)
|
||||
const cityByCodeProvider = CityByCodeFamily._();
|
||||
|
||||
/// Provider to get a specific city by code
|
||||
|
||||
final class CityByCodeProvider extends $FunctionalProvider<City?, City?, City?>
|
||||
with $Provider<City?> {
|
||||
/// Provider to get a specific city by code
|
||||
const CityByCodeProvider._({
|
||||
required CityByCodeFamily super.from,
|
||||
required String super.argument,
|
||||
}) : super(
|
||||
retry: null,
|
||||
name: r'cityByCodeProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$cityByCodeHash();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return r'cityByCodeProvider'
|
||||
''
|
||||
'($argument)';
|
||||
}
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$ProviderElement<City?> $createElement($ProviderPointer pointer) =>
|
||||
$ProviderElement(pointer);
|
||||
|
||||
@override
|
||||
City? create(Ref ref) {
|
||||
final argument = this.argument as String;
|
||||
return cityByCode(ref, argument);
|
||||
}
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(City? value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<City?>(value),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is CityByCodeProvider && other.argument == argument;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return argument.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
String _$cityByCodeHash() => r'4e4a9a72526b0a366b8697244f2e7e2aedf7cabe';
|
||||
|
||||
/// Provider to get a specific city by code
|
||||
|
||||
final class CityByCodeFamily extends $Family
|
||||
with $FunctionalFamilyOverride<City?, String> {
|
||||
const CityByCodeFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'cityByCodeProvider',
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
isAutoDispose: true,
|
||||
);
|
||||
|
||||
/// Provider to get a specific city by code
|
||||
|
||||
CityByCodeProvider call(String code) =>
|
||||
CityByCodeProvider._(argument: code, from: this);
|
||||
|
||||
@override
|
||||
String toString() => r'cityByCodeProvider';
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/// Customer Groups Provider
|
||||
///
|
||||
/// Manages the list of customer groups (roles) for user registration
|
||||
library;
|
||||
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:worker/features/auth/data/datasources/auth_remote_datasource.dart';
|
||||
import 'package:worker/features/auth/domain/entities/customer_group.dart';
|
||||
import 'package:worker/features/auth/presentation/providers/session_provider.dart';
|
||||
|
||||
part 'customer_groups_provider.g.dart';
|
||||
|
||||
/// Customer Groups Provider
|
||||
///
|
||||
/// Fetches list of customer groups (roles) from API for registration form.
|
||||
/// Requires active session (CSRF token and SID).
|
||||
/// keepAlive: true ensures the customer groups list persists and doesn't auto-dispose.
|
||||
@Riverpod(keepAlive: true)
|
||||
class CustomerGroups extends _$CustomerGroups {
|
||||
@override
|
||||
Future<List<CustomerGroup>> build() async {
|
||||
// Don't auto-fetch on build, wait for manual call
|
||||
return [];
|
||||
}
|
||||
|
||||
/// Fetch customer groups from API
|
||||
Future<void> fetchCustomerGroups() async {
|
||||
state = const AsyncValue.loading();
|
||||
|
||||
state = await AsyncValue.guard(() async {
|
||||
final sessionState = ref.read(sessionProvider);
|
||||
|
||||
if (!sessionState.hasSession) {
|
||||
throw Exception('No active session. Please get session first.');
|
||||
}
|
||||
|
||||
final dataSource = ref.read(authRemoteDataSourceProvider);
|
||||
return await dataSource.getCustomerGroups(
|
||||
csrfToken: sessionState.csrfToken!,
|
||||
sid: sessionState.sid!,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Refresh customer groups list
|
||||
Future<void> refresh() async {
|
||||
await fetchCustomerGroups();
|
||||
}
|
||||
}
|
||||
|
||||
/// Provider to get a specific customer group by code/value
|
||||
@riverpod
|
||||
CustomerGroup? customerGroupByCode(
|
||||
Ref ref,
|
||||
String code,
|
||||
) {
|
||||
final groupsAsync = ref.watch(customerGroupsProvider);
|
||||
|
||||
return groupsAsync.whenOrNull(
|
||||
data: (List<CustomerGroup> groups) => groups.firstWhere(
|
||||
(CustomerGroup group) => group.value == code || group.name == code,
|
||||
orElse: () => groups.first,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'customer_groups_provider.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
/// Customer Groups Provider
|
||||
///
|
||||
/// Fetches list of customer groups (roles) from API for registration form.
|
||||
/// Requires active session (CSRF token and SID).
|
||||
/// keepAlive: true ensures the customer groups list persists and doesn't auto-dispose.
|
||||
|
||||
@ProviderFor(CustomerGroups)
|
||||
const customerGroupsProvider = CustomerGroupsProvider._();
|
||||
|
||||
/// Customer Groups Provider
|
||||
///
|
||||
/// Fetches list of customer groups (roles) from API for registration form.
|
||||
/// Requires active session (CSRF token and SID).
|
||||
/// keepAlive: true ensures the customer groups list persists and doesn't auto-dispose.
|
||||
final class CustomerGroupsProvider
|
||||
extends $AsyncNotifierProvider<CustomerGroups, List<CustomerGroup>> {
|
||||
/// Customer Groups Provider
|
||||
///
|
||||
/// Fetches list of customer groups (roles) from API for registration form.
|
||||
/// Requires active session (CSRF token and SID).
|
||||
/// keepAlive: true ensures the customer groups list persists and doesn't auto-dispose.
|
||||
const CustomerGroupsProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'customerGroupsProvider',
|
||||
isAutoDispose: false,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$customerGroupsHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
CustomerGroups create() => CustomerGroups();
|
||||
}
|
||||
|
||||
String _$customerGroupsHash() => r'df9107ef844e3cd320804af8d5dcf2fee2462208';
|
||||
|
||||
/// Customer Groups Provider
|
||||
///
|
||||
/// Fetches list of customer groups (roles) from API for registration form.
|
||||
/// Requires active session (CSRF token and SID).
|
||||
/// keepAlive: true ensures the customer groups list persists and doesn't auto-dispose.
|
||||
|
||||
abstract class _$CustomerGroups extends $AsyncNotifier<List<CustomerGroup>> {
|
||||
FutureOr<List<CustomerGroup>> build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref =
|
||||
this.ref as $Ref<AsyncValue<List<CustomerGroup>>, List<CustomerGroup>>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<AsyncValue<List<CustomerGroup>>, List<CustomerGroup>>,
|
||||
AsyncValue<List<CustomerGroup>>,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
}
|
||||
}
|
||||
|
||||
/// Provider to get a specific customer group by code/value
|
||||
|
||||
@ProviderFor(customerGroupByCode)
|
||||
const customerGroupByCodeProvider = CustomerGroupByCodeFamily._();
|
||||
|
||||
/// Provider to get a specific customer group by code/value
|
||||
|
||||
final class CustomerGroupByCodeProvider
|
||||
extends $FunctionalProvider<CustomerGroup?, CustomerGroup?, CustomerGroup?>
|
||||
with $Provider<CustomerGroup?> {
|
||||
/// Provider to get a specific customer group by code/value
|
||||
const CustomerGroupByCodeProvider._({
|
||||
required CustomerGroupByCodeFamily super.from,
|
||||
required String super.argument,
|
||||
}) : super(
|
||||
retry: null,
|
||||
name: r'customerGroupByCodeProvider',
|
||||
isAutoDispose: true,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$customerGroupByCodeHash();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return r'customerGroupByCodeProvider'
|
||||
''
|
||||
'($argument)';
|
||||
}
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$ProviderElement<CustomerGroup?> $createElement($ProviderPointer pointer) =>
|
||||
$ProviderElement(pointer);
|
||||
|
||||
@override
|
||||
CustomerGroup? create(Ref ref) {
|
||||
final argument = this.argument as String;
|
||||
return customerGroupByCode(ref, argument);
|
||||
}
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(CustomerGroup? value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<CustomerGroup?>(value),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is CustomerGroupByCodeProvider && other.argument == argument;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
return argument.hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
String _$customerGroupByCodeHash() =>
|
||||
r'0ddf96a19d7c20c9fe3ddfd2af80ac49bfe76512';
|
||||
|
||||
/// Provider to get a specific customer group by code/value
|
||||
|
||||
final class CustomerGroupByCodeFamily extends $Family
|
||||
with $FunctionalFamilyOverride<CustomerGroup?, String> {
|
||||
const CustomerGroupByCodeFamily._()
|
||||
: super(
|
||||
retry: null,
|
||||
name: r'customerGroupByCodeProvider',
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
isAutoDispose: true,
|
||||
);
|
||||
|
||||
/// Provider to get a specific customer group by code/value
|
||||
|
||||
CustomerGroupByCodeProvider call(String code) =>
|
||||
CustomerGroupByCodeProvider._(argument: code, from: this);
|
||||
|
||||
@override
|
||||
String toString() => r'customerGroupByCodeProvider';
|
||||
}
|
||||
107
lib/features/auth/presentation/providers/session_provider.dart
Normal file
107
lib/features/auth/presentation/providers/session_provider.dart
Normal file
@@ -0,0 +1,107 @@
|
||||
/// Session Provider
|
||||
///
|
||||
/// Manages authentication session (SID and CSRF token)
|
||||
library;
|
||||
|
||||
import 'package:curl_logger_dio_interceptor/curl_logger_dio_interceptor.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:worker/features/auth/data/datasources/auth_remote_datasource.dart';
|
||||
import 'package:worker/features/auth/data/models/auth_session_model.dart';
|
||||
|
||||
part 'session_provider.g.dart';
|
||||
|
||||
/// Provider for Dio instance
|
||||
@Riverpod(keepAlive: true)
|
||||
Dio dio(Ref ref) {
|
||||
final dio = Dio(
|
||||
BaseOptions(
|
||||
baseUrl: 'https://land.dbiz.com',
|
||||
connectTimeout: const Duration(seconds: 30),
|
||||
receiveTimeout: const Duration(seconds: 30),
|
||||
),
|
||||
);
|
||||
|
||||
// Add curl logger interceptor for debugging
|
||||
dio.interceptors.add(CurlLoggerDioInterceptor(printOnSuccess: true));
|
||||
|
||||
return dio;
|
||||
}
|
||||
|
||||
/// Provider for AuthRemoteDataSource
|
||||
@Riverpod(keepAlive: true)
|
||||
AuthRemoteDataSource authRemoteDataSource(Ref ref) {
|
||||
final dio = ref.watch(dioProvider);
|
||||
return AuthRemoteDataSource(dio);
|
||||
}
|
||||
|
||||
/// Session State
|
||||
class SessionState {
|
||||
final String? sid;
|
||||
final String? csrfToken;
|
||||
final bool isLoading;
|
||||
final String? error;
|
||||
|
||||
const SessionState({
|
||||
this.sid,
|
||||
this.csrfToken,
|
||||
this.isLoading = false,
|
||||
this.error,
|
||||
});
|
||||
|
||||
SessionState copyWith({
|
||||
String? sid,
|
||||
String? csrfToken,
|
||||
bool? isLoading,
|
||||
String? error,
|
||||
}) {
|
||||
return SessionState(
|
||||
sid: sid ?? this.sid,
|
||||
csrfToken: csrfToken ?? this.csrfToken,
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
error: error ?? this.error,
|
||||
);
|
||||
}
|
||||
|
||||
bool get hasSession => sid != null && csrfToken != null;
|
||||
}
|
||||
|
||||
/// Session Provider
|
||||
///
|
||||
/// Manages the authentication session including SID and CSRF token.
|
||||
/// This should be called before making any authenticated requests.
|
||||
/// keepAlive: true ensures the session persists across the app lifecycle.
|
||||
@Riverpod(keepAlive: true)
|
||||
class Session extends _$Session {
|
||||
@override
|
||||
SessionState build() {
|
||||
return const SessionState();
|
||||
}
|
||||
|
||||
/// Get session from API
|
||||
Future<void> getSession() async {
|
||||
state = state.copyWith(isLoading: true, error: null);
|
||||
|
||||
try {
|
||||
final dataSource = ref.read(authRemoteDataSourceProvider);
|
||||
final response = await dataSource.getSession();
|
||||
|
||||
state = SessionState(
|
||||
sid: response.message.data.sid,
|
||||
csrfToken: response.message.data.csrfToken,
|
||||
isLoading: false,
|
||||
);
|
||||
} catch (e) {
|
||||
state = SessionState(
|
||||
isLoading: false,
|
||||
error: e.toString(),
|
||||
);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear session
|
||||
void clearSession() {
|
||||
state = const SessionState();
|
||||
}
|
||||
}
|
||||
181
lib/features/auth/presentation/providers/session_provider.g.dart
Normal file
181
lib/features/auth/presentation/providers/session_provider.g.dart
Normal file
@@ -0,0 +1,181 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'session_provider.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint, type=warning
|
||||
/// Provider for Dio instance
|
||||
|
||||
@ProviderFor(dio)
|
||||
const dioProvider = DioProvider._();
|
||||
|
||||
/// Provider for Dio instance
|
||||
|
||||
final class DioProvider extends $FunctionalProvider<Dio, Dio, Dio>
|
||||
with $Provider<Dio> {
|
||||
/// Provider for Dio instance
|
||||
const DioProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'dioProvider',
|
||||
isAutoDispose: false,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$dioHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$ProviderElement<Dio> $createElement($ProviderPointer pointer) =>
|
||||
$ProviderElement(pointer);
|
||||
|
||||
@override
|
||||
Dio create(Ref ref) {
|
||||
return dio(ref);
|
||||
}
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(Dio value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<Dio>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$dioHash() => r'2bc10725a1b646cfaabd88c722e5101c06837c75';
|
||||
|
||||
/// Provider for AuthRemoteDataSource
|
||||
|
||||
@ProviderFor(authRemoteDataSource)
|
||||
const authRemoteDataSourceProvider = AuthRemoteDataSourceProvider._();
|
||||
|
||||
/// Provider for AuthRemoteDataSource
|
||||
|
||||
final class AuthRemoteDataSourceProvider
|
||||
extends
|
||||
$FunctionalProvider<
|
||||
AuthRemoteDataSource,
|
||||
AuthRemoteDataSource,
|
||||
AuthRemoteDataSource
|
||||
>
|
||||
with $Provider<AuthRemoteDataSource> {
|
||||
/// Provider for AuthRemoteDataSource
|
||||
const AuthRemoteDataSourceProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'authRemoteDataSourceProvider',
|
||||
isAutoDispose: false,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$authRemoteDataSourceHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
$ProviderElement<AuthRemoteDataSource> $createElement(
|
||||
$ProviderPointer pointer,
|
||||
) => $ProviderElement(pointer);
|
||||
|
||||
@override
|
||||
AuthRemoteDataSource create(Ref ref) {
|
||||
return authRemoteDataSource(ref);
|
||||
}
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(AuthRemoteDataSource value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<AuthRemoteDataSource>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$authRemoteDataSourceHash() =>
|
||||
r'6a18a0d3fee86c512b6eec01b8e8fda53a307a4c';
|
||||
|
||||
/// Session Provider
|
||||
///
|
||||
/// Manages the authentication session including SID and CSRF token.
|
||||
/// This should be called before making any authenticated requests.
|
||||
/// keepAlive: true ensures the session persists across the app lifecycle.
|
||||
|
||||
@ProviderFor(Session)
|
||||
const sessionProvider = SessionProvider._();
|
||||
|
||||
/// Session Provider
|
||||
///
|
||||
/// Manages the authentication session including SID and CSRF token.
|
||||
/// This should be called before making any authenticated requests.
|
||||
/// keepAlive: true ensures the session persists across the app lifecycle.
|
||||
final class SessionProvider extends $NotifierProvider<Session, SessionState> {
|
||||
/// Session Provider
|
||||
///
|
||||
/// Manages the authentication session including SID and CSRF token.
|
||||
/// This should be called before making any authenticated requests.
|
||||
/// keepAlive: true ensures the session persists across the app lifecycle.
|
||||
const SessionProvider._()
|
||||
: super(
|
||||
from: null,
|
||||
argument: null,
|
||||
retry: null,
|
||||
name: r'sessionProvider',
|
||||
isAutoDispose: false,
|
||||
dependencies: null,
|
||||
$allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@override
|
||||
String debugGetCreateSourceHash() => _$sessionHash();
|
||||
|
||||
@$internal
|
||||
@override
|
||||
Session create() => Session();
|
||||
|
||||
/// {@macro riverpod.override_with_value}
|
||||
Override overrideWithValue(SessionState value) {
|
||||
return $ProviderOverride(
|
||||
origin: this,
|
||||
providerOverride: $SyncValueProvider<SessionState>(value),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$sessionHash() => r'9c755f010681d87ab3898c4daaa920501104df46';
|
||||
|
||||
/// Session Provider
|
||||
///
|
||||
/// Manages the authentication session including SID and CSRF token.
|
||||
/// This should be called before making any authenticated requests.
|
||||
/// keepAlive: true ensures the session persists across the app lifecycle.
|
||||
|
||||
abstract class _$Session extends $Notifier<SessionState> {
|
||||
SessionState build();
|
||||
@$mustCallSuper
|
||||
@override
|
||||
void runBuild() {
|
||||
final created = build();
|
||||
final ref = this.ref as $Ref<SessionState, SessionState>;
|
||||
final element =
|
||||
ref.element
|
||||
as $ClassProviderElement<
|
||||
AnyNotifier<SessionState, SessionState>,
|
||||
SessionState,
|
||||
Object?,
|
||||
Object?
|
||||
>;
|
||||
element.handleValue(ref, created);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user