Initial commit
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import 'package:cargocalculaterapp/router/app_routes.dart';
|
||||
import 'package:cargocalculaterapp/router/name_routes.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../../data/model/price_calculate_request.dart';
|
||||
import '../../domain/usecase/calculate_price_usecase.dart';
|
||||
import '../arguments/calculator_info_argument.dart';
|
||||
|
||||
part 'calculator_event.dart';
|
||||
|
||||
part 'calculator_state.dart';
|
||||
|
||||
class CalculatorBloc extends Bloc<CalculatorEvent, CalculatorState> {
|
||||
CalculatorBloc(this.calculatePriceUseCase)
|
||||
: super(const CalculatorState(isLoading: false)) {
|
||||
on<WeightSizeEnterEvent>(_weightSizeEntered);
|
||||
on<WareHouseSelectEvent>(_wareHouseSelect);
|
||||
on<CalculateEvent>(_calculate);
|
||||
}
|
||||
|
||||
final CalculatePriceUseCase calculatePriceUseCase;
|
||||
|
||||
|
||||
void _weightSizeEntered(
|
||||
WeightSizeEnterEvent event,
|
||||
Emitter<CalculatorState> emit,
|
||||
) {
|
||||
emit(
|
||||
state.copyWith(
|
||||
size: double.tryParse(event.size.replaceAll(",", "")),
|
||||
weight: double.tryParse(event.weight.replaceAll(",", "")),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _wareHouseSelect(
|
||||
WareHouseSelectEvent event,
|
||||
Emitter<CalculatorState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedWarehouse: event.wareHouse));
|
||||
}
|
||||
|
||||
Future<void> _calculate(
|
||||
CalculateEvent event,
|
||||
Emitter<CalculatorState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(isLoading: true));
|
||||
final response = await calculatePriceUseCase(
|
||||
PriceCalculateRequest(
|
||||
m3: state.size,
|
||||
avg: (state.weight ?? 0) / (state.size ?? 1),
|
||||
),
|
||||
);
|
||||
response.fold(
|
||||
(l) {
|
||||
emit(state.copyWith(isLoading: false));
|
||||
},
|
||||
(r) {
|
||||
emit(state.copyWith(isLoading: false));
|
||||
Navigator.pushNamed(
|
||||
rootNavigatorKey.currentContext!,
|
||||
Routes.calculationInfo,
|
||||
arguments: CalculatorInfoArgument(
|
||||
productName: event.productName,
|
||||
deliveryPrice: r.price ?? 0,
|
||||
size: state.size ?? 0,
|
||||
averageWeight: (state.weight ?? 0) / (state.size ?? 1),
|
||||
weight: state.weight ?? 0,
|
||||
weraHouse: state.selectedWarehouse ?? "",
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
part of 'calculator_bloc.dart';
|
||||
|
||||
sealed class CalculatorEvent extends Equatable {
|
||||
const CalculatorEvent();
|
||||
}
|
||||
|
||||
final class WeightSizeEnterEvent extends CalculatorEvent {
|
||||
final String weight;
|
||||
final String size;
|
||||
|
||||
const WeightSizeEnterEvent({required this.weight, required this.size});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [weight, size];
|
||||
}
|
||||
|
||||
final class WareHouseSelectEvent extends CalculatorEvent {
|
||||
final String wareHouse;
|
||||
|
||||
const WareHouseSelectEvent({required this.wareHouse});
|
||||
|
||||
@override
|
||||
List<Object?> get props => [wareHouse];
|
||||
}
|
||||
|
||||
final class CalculateEvent extends CalculatorEvent {
|
||||
const CalculateEvent({required this.productName});
|
||||
|
||||
final String productName;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [productName];
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import 'package:cargocalculaterapp/core/extension/build_context_extension.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import '../../../../../constants/constants.dart';
|
||||
import '../../../../../generated/l10n.dart';
|
||||
import '../../../../../router/app_routes.dart';
|
||||
import '../../../../../router/name_routes.dart';
|
||||
import '../../../data/model/lead_create_request.dart';
|
||||
import '../../../domain/usecase/create_lead_usecase.dart';
|
||||
import '../../arguments/calculator_info_argument.dart';
|
||||
import '../../pages/calculator_info/dialog/order_dialog.dart';
|
||||
|
||||
part 'calculator_info_event.dart';
|
||||
|
||||
part 'calculator_info_state.dart';
|
||||
|
||||
class CalculatorInfoBloc
|
||||
extends Bloc<CalculatorInfoEvent, CalculatorInfoState> {
|
||||
CalculatorInfoBloc(this.createLeadUseCase)
|
||||
: super(const CalculatorInfoState(isLoading: false)) {
|
||||
on<CreateLeadEvent>(_createLead);
|
||||
on<ShowSuccessDialogEvent>(_showSuccessDialog);
|
||||
}
|
||||
|
||||
final CreateLeadUseCase createLeadUseCase;
|
||||
|
||||
Future<void> _createLead(
|
||||
CreateLeadEvent event,
|
||||
Emitter<CalculatorInfoState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(isLoading: true));
|
||||
final local = Localizations.localeOf(
|
||||
rootNavigatorKey.currentContext!,
|
||||
).languageCode;
|
||||
final response = await createLeadUseCase(
|
||||
LeadCreateRequest(
|
||||
status: "NOT_CONTACTED",
|
||||
m3: "${event.argument.size}",
|
||||
averageWeightKg: "${event.argument.averageWeight}",
|
||||
weight: "${event.argument.weight}",
|
||||
nameRu: local == "ru" ? event.argument.productName : "",
|
||||
nameUz: local == "uz" ? event.argument.productName : "",
|
||||
nameZh: local == "zh" ? event.argument.productName : "",
|
||||
price: "${event.argument.deliveryPrice}",
|
||||
warehouseCode: int.tryParse(event.argument.weraHouse),
|
||||
wharehouseRu: AppConst.warehouseOptions[event.argument.weraHouse]?.ru,
|
||||
wharehouseUz: AppConst.warehouseOptions[event.argument.weraHouse]?.uz,
|
||||
wharehouseZh: AppConst.warehouseOptions[event.argument.weraHouse]?.zh,
|
||||
),
|
||||
);
|
||||
response.fold(
|
||||
(l) {
|
||||
emit(state.copyWith(isLoading: false));
|
||||
},
|
||||
(r) {
|
||||
emit(state.copyWith(isLoading: false));
|
||||
add(ShowSuccessDialogEvent(isCall: event.isCall));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _showSuccessDialog(
|
||||
ShowSuccessDialogEvent event,
|
||||
Emitter<CalculatorInfoState> emit,
|
||||
) {
|
||||
if (event.isCall) {
|
||||
showCupertinoModalPopup(
|
||||
context: rootNavigatorKey.currentContext!,
|
||||
builder: (context) => CupertinoActionSheet(
|
||||
actions: [
|
||||
CupertinoActionSheetAction(
|
||||
child: Text(
|
||||
"+998 99-110-22-22",
|
||||
style: TextStyle(color: context.color.primaryColor),
|
||||
),
|
||||
onPressed: () async {
|
||||
final Uri url = Uri(scheme: 'tel', path: "+998991102222");
|
||||
if (await canLaunchUrl(url)) {
|
||||
await launchUrl(url);
|
||||
}
|
||||
Navigator.pop(rootNavigatorKey.currentContext!, true);
|
||||
},
|
||||
),
|
||||
],
|
||||
cancelButton: CupertinoActionSheetAction(
|
||||
onPressed: () {
|
||||
Navigator.pop(rootNavigatorKey.currentContext!);
|
||||
},
|
||||
child: Text(
|
||||
AppLocalization.current.cancel,
|
||||
style: TextStyle(color: context.color.textColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
).then((value) {
|
||||
if (value is bool) {
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
rootNavigatorKey.currentContext!,
|
||||
Routes.main,
|
||||
(route) => false,
|
||||
);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
showDialog(
|
||||
context: rootNavigatorKey.currentContext!,
|
||||
builder: (context) => OrderDialog(isCall: event.isCall),
|
||||
).then((value) {
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
rootNavigatorKey.currentContext!,
|
||||
Routes.main,
|
||||
(route) => false,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
part of 'calculator_info_bloc.dart';
|
||||
|
||||
sealed class CalculatorInfoEvent extends Equatable {
|
||||
const CalculatorInfoEvent();
|
||||
}
|
||||
|
||||
final class CreateLeadEvent extends CalculatorInfoEvent {
|
||||
const CreateLeadEvent({required this.argument, required this.isCall});
|
||||
|
||||
final bool isCall;
|
||||
final CalculatorInfoArgument argument;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [argument, isCall];
|
||||
}
|
||||
|
||||
final class ShowSuccessDialogEvent extends CalculatorInfoEvent {
|
||||
const ShowSuccessDialogEvent({required this.isCall});
|
||||
|
||||
final bool isCall;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [isCall];
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
part of 'calculator_info_bloc.dart';
|
||||
|
||||
class CalculatorInfoState extends Equatable {
|
||||
const CalculatorInfoState({required this.isLoading});
|
||||
|
||||
final bool isLoading;
|
||||
|
||||
CalculatorInfoState copyWith({bool? isLoading}) {
|
||||
return CalculatorInfoState(isLoading: isLoading ?? this.isLoading);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [isLoading];
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
part of 'calculator_bloc.dart';
|
||||
|
||||
class CalculatorState extends Equatable {
|
||||
const CalculatorState({
|
||||
required this.isLoading,
|
||||
this.weight,
|
||||
this.size,
|
||||
this.selectedWarehouse,
|
||||
});
|
||||
|
||||
final bool isLoading;
|
||||
final double? weight;
|
||||
final double? size;
|
||||
final String? selectedWarehouse;
|
||||
|
||||
CalculatorState copyWith({
|
||||
bool? isLoading,
|
||||
double? weight,
|
||||
double? size,
|
||||
String? selectedWarehouse,
|
||||
}) {
|
||||
return CalculatorState(
|
||||
isLoading: isLoading ?? this.isLoading,
|
||||
weight: weight ?? this.weight,
|
||||
size: size ?? this.size,
|
||||
selectedWarehouse: selectedWarehouse ?? this.selectedWarehouse,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [isLoading, weight, size, selectedWarehouse];
|
||||
}
|
||||
Reference in New Issue
Block a user