Initial commit

This commit is contained in:
jahongireshonqulov
2025-10-18 09:40:06 +05:00
commit 1bf3e41abe
352 changed files with 16315 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../../router/app_routes.dart';
import '../../../data/models/comment_request.dart';
import '../../../domain/usecase/comment_usecase.dart';
part 'comment_event.dart';
part 'comment_state.dart';
class CommentBloc extends Bloc<CommentEvent, CommentState> {
CommentBloc(this.commentUseCase)
: super(const CommentState(rating: 0, isLoading: false)) {
on<RatingChangedEvent>(_ratingChange);
on<CommentEnterEvent>(_commentEnter);
on<SubmitEvent>(_commentSubmit);
}
final CommentUseCase commentUseCase;
void _ratingChange(RatingChangedEvent event, Emitter<CommentState> emit) {
emit(state.copyWith(rating: event.rating));
}
void _commentEnter(CommentEnterEvent event, Emitter<CommentState> emit) {
emit(state.copyWith(comment: event.comment));
}
Future<void> _commentSubmit(
SubmitEvent event,
Emitter<CommentState> emit,
) async {
emit(state.copyWith(isLoading: true));
final response = await commentUseCase(
CommentRequest(
orderNumber: event.orderId,
rate: state.rating.toInt(),
message: state.comment,
),
);
response.fold(
(l) {
emit(state.copyWith(isLoading: false));
},
(r) {
emit(state.copyWith(isLoading: false));
Navigator.pop(rootNavigatorKey.currentContext!);
},
);
}
}

View File

@@ -0,0 +1,32 @@
part of 'comment_bloc.dart';
sealed class CommentEvent extends Equatable {
const CommentEvent();
}
final class RatingChangedEvent extends CommentEvent {
final double rating;
const RatingChangedEvent({required this.rating});
@override
List<Object?> get props => [rating];
}
final class CommentEnterEvent extends CommentEvent {
final String comment;
const CommentEnterEvent({required this.comment});
@override
List<Object?> get props => [comment];
}
final class SubmitEvent extends CommentEvent {
const SubmitEvent({required this.orderId});
final String orderId;
@override
List<Object?> get props => [orderId];
}

View File

@@ -0,0 +1,24 @@
part of 'comment_bloc.dart';
class CommentState extends Equatable {
const CommentState({
required this.rating,
required this.isLoading,
this.comment,
});
final double rating;
final bool isLoading;
final String? comment;
CommentState copyWith({double? rating, bool? isLoading, String? comment}) {
return CommentState(
rating: rating ?? this.rating,
isLoading: isLoading ?? this.isLoading,
comment: comment ?? this.comment,
);
}
@override
List<Object?> get props => [rating, isLoading, comment];
}

View File

@@ -0,0 +1,127 @@
import 'package:cargocalculaterapp/constants/constants.dart';
import 'package:cargocalculaterapp/features/home/data/models/orders_list_response.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../../core/usecase/usecase.dart';
import '../../data/models/banner_response.dart';
import '../../domain/usecase/banners_usecase.dart';
import '../../domain/usecase/orders_list_usecase.dart';
part 'home_event.dart';
part 'home_state.dart';
class HomeBloc extends Bloc<HomeEvent, HomeState> {
HomeBloc(this.ordersListUseCase, this.bannersUseCase)
: super(
const HomeState(
paginationLoading: false,
isLoading: false,
page: 1,
selectedStatus: AppConst.all,
),
) {
on<GetAllOrdersListEvent>(_getAllOrders);
on<GetOrdersEvent>(_getOrders);
on<OrderStatusEvent>(_changeOrderStatus);
on<PaginationEvent>(_paginationLoading);
on<GetBannersEvent>(_getBanner);
on<RefreshEvent>(_refresh);
}
final OrdersListUseCase ordersListUseCase;
final BannersUseCase bannersUseCase;
final Map<String, dynamic> productsRequest = {};
void _getAllOrders(GetAllOrdersListEvent event, Emitter<HomeState> emit) {
productsRequest.remove(AppKeys.status);
productsRequest[AppKeys.page] = 1;
productsRequest[AppKeys.limit] = AppConst.limit;
add(const GetOrdersEvent());
}
Future<void> _getOrders(GetOrdersEvent event, Emitter<HomeState> emit) async {
emit(state.copyWith(isLoading: event.isLoading));
final response = await ordersListUseCase(productsRequest);
response.fold(
(l) {
emit(state.copyWith(isLoading: false, paginationLoading: false));
},
(r) {
emit(
state.copyWith(
isLoading: false,
paginationLoading: false,
ordersList: r,
page: productsRequest[AppKeys.page],
pageCount: ((r.totalCount ?? 1) / 20).ceil(),
),
);
},
);
}
void _changeOrderStatus(OrderStatusEvent event, Emitter<HomeState> emit) {
if (event.status == state.selectedStatus) {
return;
}
emit(state.copyWith(selectedStatus: event.status));
productsRequest[AppKeys.page] = 1;
if (event.status == AppConst.all) {
productsRequest.remove(AppConst.status);
} else {
productsRequest[AppConst.status] = event.status;
}
add(const GetOrdersEvent());
}
Future<void> _paginationLoading(
PaginationEvent event,
Emitter<HomeState> emit,
) async {
productsRequest[AppKeys.page] = productsRequest[AppKeys.page] + 1;
emit(
state.copyWith(
paginationLoading: true,
page: productsRequest[AppKeys.page],
),
);
final response = await ordersListUseCase(productsRequest);
response.fold(
(l) {
emit(state.copyWith(isLoading: false, paginationLoading: false));
},
(r) {
emit(
state.copyWith(
isLoading: false,
paginationLoading: false,
ordersList: OrdersListResponse(
totalCount: r.totalCount,
data: state.ordersList?.data?..addAll(r.data ?? []),
),
page: productsRequest[AppKeys.page],
pageCount: ((r.totalCount ?? 1) / 20).ceil(),
),
);
},
);
}
Future<void> _getBanner(
GetBannersEvent event,
Emitter<HomeState> emit,
) async {
final response = await bannersUseCase(const NoParams());
response.fold((l) {}, (r) {
emit(state.copyWith(banners: r));
});
}
void _refresh(RefreshEvent event, Emitter<HomeState> emit) {
productsRequest[AppKeys.page] = 1;
add(const GetOrdersEvent(isLoading: false));
add(const GetBannersEvent());
}
}

View File

@@ -0,0 +1,51 @@
part of 'home_bloc.dart';
sealed class HomeEvent extends Equatable {
const HomeEvent();
}
final class GetAllOrdersListEvent extends HomeEvent {
const GetAllOrdersListEvent();
@override
List<Object?> get props => [];
}
final class GetOrdersEvent extends HomeEvent {
const GetOrdersEvent({this.isLoading = true});
final bool isLoading;
@override
List<Object?> get props => [isLoading];
}
final class OrderStatusEvent extends HomeEvent {
final String status;
const OrderStatusEvent({required this.status});
@override
List<Object?> get props => [status];
}
final class PaginationEvent extends HomeEvent {
const PaginationEvent();
@override
List<Object?> get props => [];
}
final class GetBannersEvent extends HomeEvent {
const GetBannersEvent();
@override
List<Object?> get props => [];
}
final class RefreshEvent extends HomeEvent {
const RefreshEvent();
@override
List<Object?> get props => [];
}

View File

@@ -0,0 +1,52 @@
part of 'home_bloc.dart';
class HomeState extends Equatable {
const HomeState({
required this.isLoading,
required this.paginationLoading,
required this.page,
this.ordersList,
this.pageCount,
this.banners,
required this.selectedStatus,
});
final bool isLoading;
final bool paginationLoading;
final int page;
final int? pageCount;
final OrdersListResponse? ordersList;
final String selectedStatus;
final List<BannerResponse>? banners;
HomeState copyWith({
bool? isLoading,
bool? paginationLoading,
int? page,
int? pageCount,
OrdersListResponse? ordersList,
String? selectedStatus,
List<BannerResponse>? banners,
}) {
return HomeState(
isLoading: isLoading ?? this.isLoading,
page: page ?? this.page,
pageCount: pageCount ?? this.pageCount,
paginationLoading: paginationLoading ?? this.paginationLoading,
ordersList: ordersList ?? this.ordersList,
selectedStatus: selectedStatus ?? this.selectedStatus,
banners: banners ?? this.banners,
);
}
@override
List<Object?> get props => [
isLoading,
paginationLoading,
page,
ordersList,
pageCount,
selectedStatus,
banners,
];
}

View File

@@ -0,0 +1,102 @@
import 'package:cargocalculaterapp/constants/constants.dart';
import 'package:cargocalculaterapp/features/home/data/models/read_notification_request.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../data/models/notification_response.dart';
import '../../../domain/usecase/notification_read_usecase.dart';
import '../../../domain/usecase/notification_usecase.dart';
part 'notification_event.dart';
part 'notification_state.dart';
class NotificationBloc extends Bloc<NotificationEvent, NotificationState> {
NotificationBloc(this.notificationUseCase, this.notificationReadUseCase)
: super(
const NotificationState(
isLoading: false,
currentPage: 1,
paginationLoading: false,
),
) {
on<GetNotificationsEvent>(_onGetNotifications);
on<NotificationPaginationEvent>(_notificationPagination);
on<ReadNotificationsEvent>(_notificationRead);
}
final NotificationUseCase notificationUseCase;
final NotificationReadUseCase notificationReadUseCase;
final Map<String, dynamic> notificationRequest = {};
Future<void> _onGetNotifications(
GetNotificationsEvent event,
Emitter<NotificationState> emit,
) async {
emit(state.copyWith(isLoading: true));
notificationRequest[AppKeys.page] = 1;
notificationRequest[AppKeys.limit] = AppConst.limit;
final response = await notificationUseCase(notificationRequest);
response.fold(
(l) {
emit(state.copyWith(isLoading: false));
},
(r) {
add(ReadNotificationsEvent(notifications: r.notifications ?? []));
emit(
state.copyWith(
isLoading: false,
currentPage: 1,
notifications: r.notifications,
pageCount: ((r.totalCount ?? 1) / 20).ceil(),
),
);
},
);
}
Future<void> _notificationPagination(
NotificationPaginationEvent event,
Emitter<NotificationState> emit,
) async {
notificationRequest[AppKeys.page] = event.page;
emit(state.copyWith(paginationLoading: true, currentPage: event.page));
final response = await notificationUseCase(notificationRequest);
response.fold(
(l) {
emit(state.copyWith(paginationLoading: false));
},
(r) {
add(ReadNotificationsEvent(notifications: r.notifications ?? []));
final List<Notifications> notifications = [];
notifications.addAll(List.of(state.notifications ?? []));
notifications.addAll(List.of(r.notifications ?? []));
emit(
state.copyWith(
paginationLoading: false,
pageCount: ((r.totalCount ?? 1) / 20).ceil(),
notifications: notifications,
),
);
},
);
}
Future<void> _notificationRead(
ReadNotificationsEvent event,
Emitter<NotificationState> emit,
) async {
final List<String> ids = [];
for (var element in event.notifications) {
if (!(element.isRead ?? false)) {
ids.add(element.id ?? "");
}
}
if (ids.isNotEmpty) {
await notificationReadUseCase(
ReadNotificationRequest(notificationIds: ids),
);
}
}
}

View File

@@ -0,0 +1,30 @@
part of 'notification_bloc.dart';
sealed class NotificationEvent extends Equatable {
const NotificationEvent();
}
final class GetNotificationsEvent extends NotificationEvent {
const GetNotificationsEvent();
@override
List<Object?> get props => [];
}
final class NotificationPaginationEvent extends NotificationEvent {
const NotificationPaginationEvent({required this.page});
final int page;
@override
List<Object?> get props => [page];
}
final class ReadNotificationsEvent extends NotificationEvent {
final List<Notifications> notifications;
const ReadNotificationsEvent({required this.notifications});
@override
List<Object?> get props => [notifications];
}

View File

@@ -0,0 +1,42 @@
part of 'notification_bloc.dart';
class NotificationState extends Equatable {
const NotificationState({
required this.isLoading,
required this.paginationLoading,
required this.currentPage,
this.pageCount,
this.notifications,
});
final bool isLoading;
final bool paginationLoading;
final int currentPage;
final int? pageCount;
final List<Notifications>? notifications;
NotificationState copyWith({
bool? isLoading,
bool? paginationLoading,
int? currentPage,
int? pageCount,
List<Notifications>? notifications,
}) {
return NotificationState(
isLoading: isLoading ?? this.isLoading,
paginationLoading: paginationLoading ?? this.paginationLoading,
currentPage: currentPage ?? this.currentPage,
pageCount: pageCount ?? this.pageCount,
notifications: notifications ?? this.notifications,
);
}
@override
List<Object?> get props => [
isLoading,
paginationLoading,
currentPage,
pageCount,
notifications,
];
}

View File

@@ -0,0 +1,34 @@
import 'package:cargocalculaterapp/features/home/data/models/order_single_response.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../../domain/usecase/order_single_usecase.dart';
part 'order_single_event.dart';
part 'order_single_state.dart';
class OrderSingleBloc extends Bloc<OrderSingleEvent, OrderSingleState> {
OrderSingleBloc(this.orderSingleUseCase)
: super(const OrderSingleState(isLoading: false)) {
on<GetOrderSingleEvent>(_getOrderInfo);
}
final OrderSingleUseCase orderSingleUseCase;
Future<void> _getOrderInfo(
GetOrderSingleEvent event,
Emitter<OrderSingleState> emit,
) async {
emit(state.copyWith(isLoading: true));
final response = await orderSingleUseCase(event.orderId);
response.fold(
(l) {
emit(state.copyWith(isLoading: false));
},
(r) {
emit(state.copyWith(isLoading: false, orderSingleResponse: r));
},
);
}
}

View File

@@ -0,0 +1,14 @@
part of 'order_single_bloc.dart';
sealed class OrderSingleEvent extends Equatable {
const OrderSingleEvent();
}
class GetOrderSingleEvent extends OrderSingleEvent {
const GetOrderSingleEvent({required this.orderId});
final String orderId;
@override
List<Object?> get props => [orderId];
}

View File

@@ -0,0 +1,21 @@
part of 'order_single_bloc.dart';
class OrderSingleState extends Equatable {
const OrderSingleState({required this.isLoading, this.orderSingleResponse});
final bool isLoading;
final OrderSingleResponse? orderSingleResponse;
OrderSingleState copyWith({
bool? isLoading,
OrderSingleResponse? orderSingleResponse,
}) {
return OrderSingleState(
isLoading: isLoading ?? this.isLoading,
orderSingleResponse: orderSingleResponse ?? this.orderSingleResponse,
);
}
@override
List<Object?> get props => [isLoading, orderSingleResponse];
}