fetched remote user

This commit is contained in:
komekh 2024-08-07 18:56:12 +05:00
parent 6a6ab20eb9
commit 67f8deed38
18 changed files with 544 additions and 315 deletions

View File

@ -1,10 +1,7 @@
// navigation_cubit.dart
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../core/enums/enums.dart';
class NavigationCubit extends Cubit<NavigationTab> {
NavigationCubit() : super(NavigationTab.homeTab);

View File

@ -12,18 +12,18 @@ part 'user_state.dart';
class UserBloc extends Bloc<UserEvent, UserState> {
final GetCachedUserUseCase _getCachedUserUseCase;
final GetRemoteUserUsecase _getRemoteUserUseCase;
final SignInUseCase _signInUseCase;
final SignUpUseCase _signUpUseCase;
final SignOutUseCase _signOutUseCase;
UserBloc(
this._signInUseCase,
this._getCachedUserUseCase,
this._getRemoteUserUseCase,
this._signOutUseCase,
this._signUpUseCase,
) : super(UserInitial()) {
on<SignInUser>(_onSignIn);
on<SignUpUser>(_onSignUp);
on<CheckUser>(_onCheckUser);
on<GetRemoteUser>(_onGetRemoteUser);
on<SignOutUser>(_onSignOut);
}
@ -33,7 +33,7 @@ class UserBloc extends Bloc<UserEvent, UserState> {
final result = await _signInUseCase(event.params);
result.fold(
(failure) => emit(UserLoggedFail(failure)),
(user) => emit(UserLogged(user)),
(token) => emit(UserLogged(token)),
);
} catch (e) {
emit(UserLoggedFail(ExceptionFailure()));
@ -46,20 +46,7 @@ class UserBloc extends Bloc<UserEvent, UserState> {
final result = await _getCachedUserUseCase(NoParams());
result.fold(
(failure) => emit(UserLoggedFail(failure)),
(user) => emit(UserLogged(user)),
);
} catch (e) {
emit(UserLoggedFail(ExceptionFailure()));
}
}
FutureOr<void> _onSignUp(SignUpUser event, Emitter<UserState> emit) async {
try {
emit(UserLoading());
final result = await _signUpUseCase(event.params);
result.fold(
(failure) => emit(UserLoggedFail(failure)),
(user) => emit(UserLogged(user)),
(user) => emit(UserFetched(user)),
);
} catch (e) {
emit(UserLoggedFail(ExceptionFailure()));
@ -75,4 +62,36 @@ class UserBloc extends Bloc<UserEvent, UserState> {
emit(UserLoggedFail(ExceptionFailure()));
}
}
FutureOr<void> _onGetRemoteUser(
GetRemoteUser event,
Emitter<UserState> emit,
) async {
try {
emit(UserLoading());
final result = await _getRemoteUserUseCase(NoParams());
result.fold(
(failure) => emit(_mapFailureToState(failure)),
(user) => emit(UserFetched(user)),
);
} catch (e) {
emit(UserLoggedFail(ExceptionFailure()));
}
}
UserState _mapFailureToState(Failure failure) {
if (failure is ServerFailure) {
return UserLoggedFail(ServerFailure());
} else if (failure is CacheFailure) {
return UserLoggedFail(CacheFailure());
} else if (failure is NetworkFailure) {
return UserLoggedFail(NetworkFailure());
} else if (failure is CredentialFailure) {
return UserLoggedFail(CredentialFailure());
} else if (failure is AuthenticationFailure) {
return UserLoggedFail(AuthenticationFailure());
} else {
return UserLoggedFail(ExceptionFailure());
}
}
}

View File

@ -8,11 +8,8 @@ class SignInUser extends UserEvent {
SignInUser(this.params);
}
class SignUpUser extends UserEvent {
final SignUpParams params;
SignUpUser(this.params);
}
class SignOutUser extends UserEvent {}
class CheckUser extends UserEvent {}
class GetRemoteUser extends UserEvent {}

View File

@ -14,8 +14,15 @@ class UserLoading extends UserState {
}
class UserLogged extends UserState {
final String token;
UserLogged(this.token);
@override
List<Object> get props => [token];
}
class UserFetched extends UserState {
final User user;
UserLogged(this.user);
UserFetched(this.user);
@override
List<Object> get props => [user];
}

View File

@ -1 +1 @@
enum NavigationTab { homeTab, categoriesTab, productsTap, cartTab, profileTab }
enum NavigationTab { homeTab, history, profileTab }

View File

@ -1,6 +1,5 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import '../../../core/core.dart';
@ -8,8 +7,8 @@ import '../../../domain/domain.dart';
import '../../data.dart';
abstract class UserRemoteDataSource {
Future<AuthenticationResponseModel> signIn(SignInParams params);
Future<AuthenticationResponseModel> signUp(SignUpParams params);
Future<String> signIn(SignInParams params);
Future<User> getUser(String token);
}
class UserRemoteDataSourceImpl implements UserRemoteDataSource {
@ -17,66 +16,46 @@ class UserRemoteDataSourceImpl implements UserRemoteDataSource {
UserRemoteDataSourceImpl({required this.client});
@override
Future<AuthenticationResponseModel> signIn(SignInParams params) async {
debugPrint('signIn');
try {
final response = await client.post(Uri.parse('$baseUrl/Authentication/Authenticate'),
headers: {
'Content-Type': 'application/json',
'accept': '*/*',
},
body: json.encode({
'UserName': params.username,
'Password': '', // params.password,
}));
if (response.statusCode == 200) {
const userData = '''
{
"token": "",
"user": {
"_id": "user123",
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com"
}
}
''';
AuthenticationResponseModel user = authenticationResponseModelFromJson(userData);
// Update the token value
AuthenticationResponseModel updatedUser = user.copyWith(token: response.body);
return updatedUser;
} else if (response.statusCode == 400 || response.statusCode == 401) {
throw CredentialFailure();
} else {
throw ServerException();
}
} catch (e) {
debugPrint('e $e');
throw ServerException();
}
}
@override
Future<AuthenticationResponseModel> signUp(SignUpParams params) async {
final response = await client.post(Uri.parse('$baseUrl/authentication/local/sign-up'),
headers: {
'Content-Type': 'application/json',
Future<String> signIn(SignInParams params) async {
final response = await client.post(
Uri.parse('$baseUrl/Authentication/Authenticate'),
headers: {
'Content-Type': 'application/json',
'accept': '*/*',
},
body: json.encode(
{
'UserName': params.username,
'Password': params.password,
},
body: json.encode({
'firstName': params.firstName,
'lastName': params.lastName,
'email': params.email,
'password': params.password,
}));
if (response.statusCode == 201) {
return authenticationResponseModelFromJson(response.body);
),
);
if (response.statusCode == 200) {
return response.body;
} else if (response.statusCode == 400 || response.statusCode == 401) {
throw CredentialFailure();
} else {
throw ServerException();
}
}
@override
Future<User> getUser(String token) async {
final response = await client.get(
Uri.parse('$baseUrl/Client/GetClient'),
headers: {
'Content-Type': 'application/json',
'accept': '*/*',
'Authorization': 'Bearer $token',
},
);
if (response.statusCode == 200) {
final user = UserModel.fromJson(json.decode(response.body));
return user;
} else {
throw ServerException();
}
}
}

View File

@ -1,38 +1,38 @@
import 'dart:convert';
// import 'dart:convert';
import 'user_model.dart';
// import 'user_model.dart';
AuthenticationResponseModel authenticationResponseModelFromJson(String str) =>
AuthenticationResponseModel.fromJson(json.decode(str));
// AuthenticationResponseModel authenticationResponseModelFromJson(String str) =>
// AuthenticationResponseModel.fromJson(json.decode(str));
String authenticationResponseModelToJson(AuthenticationResponseModel data) => json.encode(data.toJson());
// String authenticationResponseModelToJson(AuthenticationResponseModel data) => json.encode(data.toJson());
class AuthenticationResponseModel {
final String token;
final UserModel user;
// class AuthenticationResponseModel {
// final String token;
// final UserModel user;
const AuthenticationResponseModel({
required this.token,
required this.user,
});
// const AuthenticationResponseModel({
// required this.token,
// required this.user,
// });
factory AuthenticationResponseModel.fromJson(Map<String, dynamic> json) => AuthenticationResponseModel(
token: json['token'],
user: UserModel.fromJson(json['user']),
);
// factory AuthenticationResponseModel.fromJson(Map<String, dynamic> json) => AuthenticationResponseModel(
// token: json['token'],
// user: UserModel.fromJson(json['user']),
// );
Map<String, dynamic> toJson() => {
'token': token,
'user': user.toJson(),
};
// Map<String, dynamic> toJson() => {
// 'token': token,
// 'user': user.toJson(),
// };
AuthenticationResponseModel copyWith({
String? token,
UserModel? user,
}) {
return AuthenticationResponseModel(
token: token ?? this.token,
user: user ?? this.user,
);
}
}
// AuthenticationResponseModel copyWith({
// String? token,
// UserModel? user,
// }) {
// return AuthenticationResponseModel(
// token: token ?? this.token,
// user: user ?? this.user,
// );
// }
// }

View File

@ -8,23 +8,28 @@ String userModelToJson(UserModel data) => json.encode(data.toJson());
class UserModel extends User {
const UserModel({
required super.id,
required super.firstName,
required super.lastName,
required super.email,
required super.oid,
required super.fullName,
required super.phone,
});
factory UserModel.fromUser(User user) {
return UserModel(
oid: user.oid,
fullName: user.fullName,
phone: user.phone,
);
}
factory UserModel.fromJson(Map<String, dynamic> json) => UserModel(
id: json['_id'],
firstName: json['firstName'],
lastName: json['lastName'],
email: json['email'],
oid: json['Oid'],
fullName: json['FullName'],
phone: json['PhoneNo'],
);
Map<String, dynamic> toJson() => {
'_id': id,
'firstName': firstName,
'lastName': lastName,
'email': email,
'Oid': oid,
'FullName': fullName,
'PhoneNo': phone,
};
}

View File

@ -2,10 +2,7 @@ import 'package:dartz/dartz.dart';
import '../../core/core.dart';
import '../../domain/domain.dart';
import '../data_sources/data_sources.dart';
import '../models/user/authentication_response_model.dart';
typedef _DataSourceChooser = Future<AuthenticationResponseModel> Function();
import '../data.dart';
class UserRepositoryImpl implements UserRepository {
final UserRemoteDataSource remoteDataSource;
@ -19,17 +16,18 @@ class UserRepositoryImpl implements UserRepository {
});
@override
Future<Either<Failure, User>> signIn(params) async {
return await _authenticate(() {
return remoteDataSource.signIn(params);
});
}
@override
Future<Either<Failure, User>> signUp(params) async {
return await _authenticate(() {
return remoteDataSource.signUp(params);
});
Future<Either<Failure, String>> signIn(params) async {
if (await networkInfo.isConnected) {
try {
final token = await remoteDataSource.signIn(params);
localDataSource.saveToken(token);
return Right(token);
} on Failure catch (failure) {
return Left(failure);
}
} else {
return Left(NetworkFailure());
}
}
@override
@ -52,20 +50,23 @@ class UserRepositoryImpl implements UserRepository {
}
}
Future<Either<Failure, User>> _authenticate(
_DataSourceChooser getDataSource,
) async {
if (await networkInfo.isConnected) {
try {
final remoteResponse = await getDataSource();
localDataSource.saveToken(remoteResponse.token);
localDataSource.saveUser(remoteResponse.user);
return Right(remoteResponse.user);
} on Failure catch (failure) {
return Left(failure);
}
} else {
@override
Future<Either<Failure, User>> getRemoteUser() async {
if (!await networkInfo.isConnected) {
return Left(NetworkFailure());
}
if (!await localDataSource.isTokenAvailable()) {
return Left(AuthenticationFailure());
}
try {
final String token = await localDataSource.getToken();
final user = await remoteDataSource.getUser(token);
await localDataSource.saveUser(UserModel.fromUser(user));
return Right(user);
} on Failure catch (failure) {
return Left(failure);
}
}
}

View File

@ -10,8 +10,8 @@ void registerUserFeature() {
sl.registerFactory(() => UserBloc(sl(), sl(), sl(), sl()));
sl.registerLazySingleton(() => GetCachedUserUseCase(sl()));
sl.registerLazySingleton(() => SignInUseCase(sl()));
sl.registerLazySingleton(() => SignUpUseCase(sl()));
sl.registerLazySingleton(() => SignOutUseCase(sl()));
sl.registerLazySingleton(() => GetRemoteUserUsecase(sl()));
// User Repository and Data Sources
sl.registerLazySingleton<UserRepository>(

View File

@ -1,25 +1,20 @@
import 'package:equatable/equatable.dart';
class User extends Equatable {
final String id;
final String firstName;
final String lastName;
final String? image;
final String email;
final String oid;
final String fullName;
final String phone;
const User({
required this.id,
required this.firstName,
required this.lastName,
this.image,
required this.email,
required this.oid,
required this.fullName,
required this.phone,
});
@override
List<Object> get props => [
id,
firstName,
lastName,
email,
oid,
fullName,
phone,
];
}

View File

@ -4,8 +4,8 @@ import '../../core/core.dart';
import '../domain.dart';
abstract class UserRepository {
Future<Either<Failure, User>> signIn(SignInParams params);
Future<Either<Failure, User>> signUp(SignUpParams params);
Future<Either<Failure, String>> signIn(SignInParams params);
Future<Either<Failure, NoParams>> signOut();
Future<Either<Failure, User>> getCachedUser();
Future<Either<Failure, User>> getRemoteUser();
}

View File

@ -0,0 +1,14 @@
import 'package:dartz/dartz.dart';
import '../../../core/core.dart';
import '../../domain.dart';
class GetRemoteUserUsecase implements UseCase<User, NoParams> {
final UserRepository repository;
GetRemoteUserUsecase(this.repository);
@override
Future<Either<Failure, User>> call(NoParams params) async {
return await repository.getRemoteUser();
}
}

View File

@ -3,12 +3,12 @@ import 'package:dartz/dartz.dart';
import '../../../core/core.dart';
import '../../domain.dart';
class SignInUseCase implements UseCase<User, SignInParams> {
class SignInUseCase implements UseCase<String, SignInParams> {
final UserRepository repository;
SignInUseCase(this.repository);
@override
Future<Either<Failure, User>> call(SignInParams params) async {
Future<Either<Failure, String>> call(SignInParams params) async {
return await repository.signIn(params);
}
}

View File

@ -1,27 +1,27 @@
import 'package:dartz/dartz.dart';
// import 'package:dartz/dartz.dart';
import '../../../core/core.dart';
import '../../domain.dart';
// import '../../../core/core.dart';
// import '../../domain.dart';
class SignUpUseCase implements UseCase<User, SignUpParams> {
final UserRepository repository;
SignUpUseCase(this.repository);
// class SignUpUseCase implements UseCase<User, SignUpParams> {
// final UserRepository repository;
// SignUpUseCase(this.repository);
@override
Future<Either<Failure, User>> call(SignUpParams params) async {
return await repository.signUp(params);
}
}
// @override
// Future<Either<Failure, User>> call(SignUpParams params) async {
// return await repository.signUp(params);
// }
// }
class SignUpParams {
final String firstName;
final String lastName;
final String email;
final String password;
const SignUpParams({
required this.firstName,
required this.lastName,
required this.email,
required this.password,
});
}
// class SignUpParams {
// final String firstName;
// final String lastName;
// final String email;
// final String password;
// const SignUpParams({
// required this.firstName,
// required this.lastName,
// required this.email,
// required this.password,
// });
// }

View File

@ -2,3 +2,4 @@ export 'get_cached_user_usecase.dart';
export 'sign_in_usecase.dart';
export 'sign_out_usecase.dart';
export 'sign_up_usecase.dart';
export 'get_remote_user_usecase.dart';

View File

@ -1,166 +1,380 @@
import 'package:cargo/presentation/presentation.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../application/user_bloc/user_bloc.dart';
import '../../configs/configs.dart';
import '../../core/core.dart';
import '../../domain/entities/user/user.dart';
import '../widgets/lang_selection.dart';
class ProfileScreen extends StatelessWidget {
class ProfileScreen extends StatefulWidget {
const ProfileScreen({super.key});
@override
State<ProfileScreen> createState() => _ProfileScreenState();
}
class _ProfileScreenState extends State<ProfileScreen> {
@override
void initState() {
context.read<UserBloc>().add(GetRemoteUser());
super.initState();
}
@override
Widget build(BuildContext context) {
App.init(context);
return Scaffold(
// appBar: AppBar(),
backgroundColor: AppColors.surface,
body: SingleChildScrollView(
child: Padding(
padding: Space.all(1, 1),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/// gap
Space.yf(1),
body: BlocBuilder<UserBloc, UserState>(
builder: (context, state) {
if (state is UserLoading) {
return const Center(child: CircularProgressIndicator());
} else if (state is UserFetched) {
return _buildProfileContent(context, state.user);
} else if (state is UserLoggedFail) {
return _buildErrorContent(context, state.failure);
} else {
return const SizedBox.shrink();
}
},
),
);
}
/// header
Text(
'Şahsy otagym',
style: AppText.h1b,
),
Widget _buildProfileContent(BuildContext context, User user) {
return SingleChildScrollView(
child: Padding(
padding: Space.all(1, 1),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/// gap
Space.yf(1),
Space.y!,
/// header
Text(
'Şahsy otagym',
style: AppText.h1b,
),
/// card
SizedBox(
width: double.infinity,
child: Card(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
/// identity
const RowWidget(
text: 'ABC1234567890!@#',
leadingIcon: Icons.verified_user_outlined,
),
Space.y!,
/// gap
Space.yf(1),
/// card
SizedBox(
width: double.infinity,
child: Card(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
/// name surname
RowWidget(
text: user.fullName,
leadingIcon: Icons.person_2_outlined,
trailingIcon: Icons.mode_edit_outlined,
),
/// name surname
const RowWidget(
text: 'Maksat Üstünlikow',
leadingIcon: Icons.person_2_outlined,
trailingIcon: Icons.mode_edit_outlined,
),
/// gap
Space.yf(1),
/// gap
Space.yf(1),
/// phone
const RowWidget(
text: '+993 (XX) XX-XX-XX',
leadingIcon: Icons.phone_android_outlined,
trailingIcon: Icons.mode_edit_outlined,
),
],
),
/// phone
RowWidget(
text: user.phone,
leadingIcon: Icons.phone_android_outlined,
trailingIcon: Icons.mode_edit_outlined,
),
],
),
),
),
),
///gap
Space.yf(2),
///gap
Space.yf(2),
/// card
const SizedBox(
width: double.infinity,
child: Card(
color: Colors.white,
child: Padding(
padding: EdgeInsets.all(16.0),
child: RowWidget(
text: 'Tehniki goldaw bilen habarlaşmak',
leadingIcon: Icons.contact_support_outlined,
trailingIcon: Icons.arrow_forward_ios,
),
/// card
const SizedBox(
width: double.infinity,
child: Card(
color: Colors.white,
child: Padding(
padding: EdgeInsets.all(16.0),
child: RowWidget(
text: 'Tehniki goldaw bilen habarlaşmak',
leadingIcon: Icons.contact_support_outlined,
trailingIcon: Icons.arrow_forward_ios,
),
),
),
),
///gap
Space.yf(2),
///gap
Space.yf(2),
/// card
SizedBox(
width: double.infinity,
child: Card(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
/// language
GestureDetector(
onTap: () => onSelectLang(context),
child: Container(
color: Colors.transparent,
child: RowWidget(
text: 'profile_select_lang'.tr(),
leadingIcon: Icons.language_outlined,
trailingIcon: Icons.arrow_forward_ios,
),
/// card
SizedBox(
width: double.infinity,
child: Card(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
/// language
GestureDetector(
onTap: () => onSelectLang(context),
child: Container(
color: Colors.transparent,
child: RowWidget(
text: 'profile_select_lang'.tr(),
leadingIcon: Icons.language_outlined,
trailingIcon: Icons.arrow_forward_ios,
),
),
),
/// name surname
const RowWidget(
text: 'Gizlinlik syýasaty',
leadingIcon: Icons.gpp_maybe_outlined,
trailingIcon: Icons.arrow_forward_ios,
),
/// name surname
const RowWidget(
text: 'Gizlinlik syýasaty',
leadingIcon: Icons.gpp_maybe_outlined,
trailingIcon: Icons.arrow_forward_ios,
),
/// phone
const RowWidget(
text: 'Ulanyş şertleri',
leadingIcon: Icons.file_copy_outlined,
trailingIcon: Icons.arrow_forward_ios,
),
],
),
/// phone
const RowWidget(
text: 'Ulanyş şertleri',
leadingIcon: Icons.file_copy_outlined,
trailingIcon: Icons.arrow_forward_ios,
),
],
),
),
),
),
///gap
Space.yf(2),
///gap
Space.yf(2),
/// logout
Align(
alignment: Alignment.center,
child: TextButton(
onPressed: () {},
child: Text(
'Şahsy otagdan çykmak',
style: AppText.b1!.copyWith(
color: Colors.red,
),
/// logout
Align(
alignment: Alignment.center,
child: TextButton(
onPressed: () {},
child: Text(
'Şahsy otagdan çykmak',
style: AppText.b1!.copyWith(
color: Colors.red,
),
),
),
),
///gap
Space.yf(2),
],
),
///gap
Space.yf(2),
],
),
),
);
}
Widget _buildErrorContent(BuildContext context, Failure failure) {
String errorMessage;
if (failure is ServerFailure) {
errorMessage = 'Server failure. Please try again later.';
} else if (failure is CacheFailure) {
errorMessage = 'Cache failure. Please try again later.';
} else if (failure is NetworkFailure) {
errorMessage = 'No network connection. Please check your internet.';
} else if (failure is CredentialFailure) {
errorMessage = 'Invalid credentials. Please try again.';
} else if (failure is AuthenticationFailure) {
errorMessage = 'Authentication failure. Please log in again.';
} else {
errorMessage = 'An unknown error occurred. Please try again.';
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
errorMessage,
style: const TextStyle(color: Colors.red),
textAlign: TextAlign.center,
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Optionally, you can provide a retry mechanism
context.read<UserBloc>().add(GetRemoteUser());
},
child: const Text('Retry'),
),
],
),
);
}
}
// class ProfileScreen extends StatelessWidget {
// const ProfileScreen({super.key});
// @override
// Widget build(BuildContext context) {
// App.init(context);
// return Scaffold(
// // appBar: AppBar(),
// backgroundColor: AppColors.surface,
// body: SingleChildScrollView(
// child: Padding(
// padding: Space.all(1, 1),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// /// gap
// Space.yf(1),
// /// header
// Text(
// 'Şahsy otagym',
// style: AppText.h1b,
// ),
// Space.y!,
// /// card
// SizedBox(
// width: double.infinity,
// child: Card(
// color: Colors.white,
// child: Padding(
// padding: const EdgeInsets.all(16.0),
// child: Column(
// children: [
// /// identity
// // const RowWidget(
// // text: 'ABC1234567890!@#',
// // leadingIcon: Icons.verified_user_outlined,
// // ),
// /// gap
// // Space.yf(1),
// /// name surname
// const RowWidget(
// text: 'Maksat Üstünlikow',
// leadingIcon: Icons.person_2_outlined,
// trailingIcon: Icons.mode_edit_outlined,
// ),
// /// gap
// Space.yf(1),
// /// phone
// const RowWidget(
// text: '+993 (XX) XX-XX-XX',
// leadingIcon: Icons.phone_android_outlined,
// trailingIcon: Icons.mode_edit_outlined,
// ),
// ],
// ),
// ),
// ),
// ),
// ///gap
// Space.yf(2),
// /// card
// const SizedBox(
// width: double.infinity,
// child: Card(
// color: Colors.white,
// child: Padding(
// padding: EdgeInsets.all(16.0),
// child: RowWidget(
// text: 'Tehniki goldaw bilen habarlaşmak',
// leadingIcon: Icons.contact_support_outlined,
// trailingIcon: Icons.arrow_forward_ios,
// ),
// ),
// ),
// ),
// ///gap
// Space.yf(2),
// /// card
// SizedBox(
// width: double.infinity,
// child: Card(
// color: Colors.white,
// child: Padding(
// padding: const EdgeInsets.all(16.0),
// child: Column(
// children: [
// /// language
// GestureDetector(
// onTap: () => onSelectLang(context),
// child: Container(
// color: Colors.transparent,
// child: RowWidget(
// text: 'profile_select_lang'.tr(),
// leadingIcon: Icons.language_outlined,
// trailingIcon: Icons.arrow_forward_ios,
// ),
// ),
// ),
// /// name surname
// const RowWidget(
// text: 'Gizlinlik syýasaty',
// leadingIcon: Icons.gpp_maybe_outlined,
// trailingIcon: Icons.arrow_forward_ios,
// ),
// /// phone
// const RowWidget(
// text: 'Ulanyş şertleri',
// leadingIcon: Icons.file_copy_outlined,
// trailingIcon: Icons.arrow_forward_ios,
// ),
// ],
// ),
// ),
// ),
// ),
// ///gap
// Space.yf(2),
// /// logout
// Align(
// alignment: Alignment.center,
// child: TextButton(
// onPressed: () {},
// child: Text(
// 'Şahsy otagdan çykmak',
// style: AppText.b1!.copyWith(
// color: Colors.red,
// ),
// ),
// ),
// ),
// ///gap
// Space.yf(2),
// ],
// ),
// ),
// ),
// );
// }
// }
class RowWidget extends StatelessWidget {
final String text;
final IconData leadingIcon;

View File

@ -66,9 +66,9 @@ class RootScreen extends StatelessWidget {
switch (activeTab) {
case NavigationTab.homeTab:
return const OrdersScreen();
case NavigationTab.categoriesTab:
case NavigationTab.history:
return const Text(' CategoriesScreen()');
case NavigationTab.productsTap:
case NavigationTab.profileTab:
return const ProfileScreen();
default:
return const OrdersScreen();