fix profile
This commit is contained in:
@@ -39,6 +39,9 @@ class ApiService {
|
|||||||
static const String baseUrl = "https://api.behappybel.by/api/v1";
|
static const String baseUrl = "https://api.behappybel.by/api/v1";
|
||||||
static const String fileBaseUrl = "https://api.behappybel.by/";
|
static const String fileBaseUrl = "https://api.behappybel.by/";
|
||||||
|
|
||||||
|
/*static const String baseUrl = "https://sharing-api.sparkit.by/api/v1";
|
||||||
|
static const String fileBaseUrl = "https://sharing-api.sparkit.by";
|
||||||
|
*/
|
||||||
final SecurityService _securityService;
|
final SecurityService _securityService;
|
||||||
final Dio _dio;
|
final Dio _dio;
|
||||||
|
|
||||||
@@ -172,6 +175,53 @@ class ApiService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> deleteProfile() async {
|
||||||
|
try {
|
||||||
|
final response = await _dio.delete(
|
||||||
|
"$baseUrl/client/me",
|
||||||
|
options: await _getAuthOptions(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
final data = response.data;
|
||||||
|
final profileData = data["profile"];
|
||||||
|
if (profileData == null) return null;
|
||||||
|
|
||||||
|
String? parsedDate;
|
||||||
|
if (profileData["dob"] != null) {
|
||||||
|
try {
|
||||||
|
parsedDate = DateFormat(
|
||||||
|
'dd.MM.yyyy',
|
||||||
|
).format(DateTime.parse(profileData["dob"]));
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
final int? avatarId = profileData["avatarId"];
|
||||||
|
String? avatarUrl;
|
||||||
|
|
||||||
|
if (avatarId != null && profileData["avatar"] != null) {
|
||||||
|
final String? avatarPath = profileData["avatar"]["path"];
|
||||||
|
if (avatarPath != null && avatarPath.isNotEmpty) {
|
||||||
|
avatarUrl = Uri.parse(fileBaseUrl).resolve(avatarPath).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic balanceRaw = profileData["balance"];
|
||||||
|
double? balance;
|
||||||
|
|
||||||
|
if (balanceRaw is num) {
|
||||||
|
balance = balanceRaw.toDouble();
|
||||||
|
} else if (balanceRaw is String) {
|
||||||
|
balance = double.tryParse(balanceRaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<PaymentCard>> getPaymentCards() async {
|
Future<List<PaymentCard>> getPaymentCards() async {
|
||||||
final response = await _dio.get(
|
final response = await _dio.get(
|
||||||
"$baseUrl/client/me",
|
"$baseUrl/client/me",
|
||||||
|
|||||||
@@ -27,6 +27,11 @@ class UserProfileRepositoryImpl implements UserProfileRepository {
|
|||||||
return await _apiService.getProfile() ?? _cachedProfile;
|
return await _apiService.getProfile() ?? _cachedProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> deleteProfile() async {
|
||||||
|
return await _apiService.deleteProfile();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<UserProfile?> updateProfile(UserProfile profile) async {
|
Future<UserProfile?> updateProfile(UserProfile profile) async {
|
||||||
//await Future.delayed(const Duration(milliseconds: 300));
|
//await Future.delayed(const Duration(milliseconds: 300));
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import 'package:be_happy/domain/repositories/scooter_repository.dart';
|
|||||||
import 'package:be_happy/domain/repositories/zone_repository.dart';
|
import 'package:be_happy/domain/repositories/zone_repository.dart';
|
||||||
import 'package:be_happy/domain/service/security_service.dart';
|
import 'package:be_happy/domain/service/security_service.dart';
|
||||||
import 'package:be_happy/domain/usecase/add_payment_card_usecase.dart'; // ← новый
|
import 'package:be_happy/domain/usecase/add_payment_card_usecase.dart'; // ← новый
|
||||||
|
import 'package:be_happy/domain/usecase/delete_profile_usecase.dart';
|
||||||
import 'package:be_happy/domain/usecase/get_certificates_usecase.dart';
|
import 'package:be_happy/domain/usecase/get_certificates_usecase.dart';
|
||||||
import 'package:be_happy/domain/usecase/get_scooter_order_route_history_usecase.dart';
|
import 'package:be_happy/domain/usecase/get_scooter_order_route_history_usecase.dart';
|
||||||
import 'package:be_happy/domain/usecase/is_pin_set_usecase.dart';
|
import 'package:be_happy/domain/usecase/is_pin_set_usecase.dart';
|
||||||
@@ -54,6 +55,7 @@ import 'package:be_happy/domain/usecase/finish_ride_usecase.dart';
|
|||||||
import 'package:be_happy/domain/usecase/pause_ride_usecase.dart';
|
import 'package:be_happy/domain/usecase/pause_ride_usecase.dart';
|
||||||
import 'package:be_happy/domain/usecase/resume_ride_usecase.dart';
|
import 'package:be_happy/domain/usecase/resume_ride_usecase.dart';
|
||||||
import 'package:be_happy/domain/usecase/verify_pin_usecase.dart';
|
import 'package:be_happy/domain/usecase/verify_pin_usecase.dart';
|
||||||
|
import 'package:be_happy/presentation/event/profile_event.dart';
|
||||||
import 'package:be_happy/presentation/viewmodel/active_ride_bloc.dart';
|
import 'package:be_happy/presentation/viewmodel/active_ride_bloc.dart';
|
||||||
import 'package:be_happy/presentation/viewmodel/add_card_bloc.dart'; // ← новый
|
import 'package:be_happy/presentation/viewmodel/add_card_bloc.dart'; // ← новый
|
||||||
import 'package:be_happy/presentation/viewmodel/current_rides_bloc.dart';
|
import 'package:be_happy/presentation/viewmodel/current_rides_bloc.dart';
|
||||||
@@ -205,6 +207,8 @@ Future<void> setupDependencies() async {
|
|||||||
|
|
||||||
getIt.registerSingleton<GetProfileUseCase>(GetProfileUseCase(getIt()));
|
getIt.registerSingleton<GetProfileUseCase>(GetProfileUseCase(getIt()));
|
||||||
|
|
||||||
|
getIt.registerSingleton<DeleteProfileUsecase>(DeleteProfileUsecase(getIt(), getIt(), getIt()));
|
||||||
|
|
||||||
getIt.registerSingleton<UpdateProfileUseCase>(UpdateProfileUseCase(getIt()));
|
getIt.registerSingleton<UpdateProfileUseCase>(UpdateProfileUseCase(getIt()));
|
||||||
|
|
||||||
getIt.registerSingleton<UploadProfilePhotoUsecase>(
|
getIt.registerSingleton<UploadProfilePhotoUsecase>(
|
||||||
@@ -319,7 +323,7 @@ Future<void> setupDependencies() async {
|
|||||||
);
|
);
|
||||||
|
|
||||||
getIt.registerLazySingleton<ProfileBloc>(
|
getIt.registerLazySingleton<ProfileBloc>(
|
||||||
() => ProfileBloc(getIt(), getIt(), getIt()),
|
() => ProfileBloc(getIt(), getIt(), getIt(), getIt(), getIt(), getIt()),
|
||||||
);
|
);
|
||||||
|
|
||||||
getIt.registerFactory<EditProfileBloc>(
|
getIt.registerFactory<EditProfileBloc>(
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ class Tariff {
|
|||||||
final int id;
|
final int id;
|
||||||
final String title;
|
final String title;
|
||||||
final String description;
|
final String description;
|
||||||
|
final String descriptionJson;
|
||||||
final bool isActive;
|
final bool isActive;
|
||||||
final String currency;
|
final String currency;
|
||||||
final double holdPrice; // Старт / бронь
|
final double holdPrice; // Старт / бронь
|
||||||
@@ -15,6 +16,7 @@ class Tariff {
|
|||||||
required this.id,
|
required this.id,
|
||||||
required this.title,
|
required this.title,
|
||||||
required this.description,
|
required this.description,
|
||||||
|
required this.descriptionJson,
|
||||||
required this.isActive,
|
required this.isActive,
|
||||||
required this.currency,
|
required this.currency,
|
||||||
required this.holdPrice,
|
required this.holdPrice,
|
||||||
@@ -33,6 +35,7 @@ class Tariff {
|
|||||||
id: json['id'] ?? 0,
|
id: json['id'] ?? 0,
|
||||||
title: json['title'] ?? 'Unknown',
|
title: json['title'] ?? 'Unknown',
|
||||||
description: json['description'] ?? '',
|
description: json['description'] ?? '',
|
||||||
|
descriptionJson: json['descriptionJson'] ?? '',
|
||||||
isActive: json['isActive'] ?? false,
|
isActive: json['isActive'] ?? false,
|
||||||
currency: currency['currency'] ?? 'BYN',
|
currency: currency['currency'] ?? 'BYN',
|
||||||
holdPrice: (planPrice['hold'] as num?)?.toDouble() ?? 0.0,
|
holdPrice: (planPrice['hold'] as num?)?.toDouble() ?? 0.0,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import '../entities/user_profile.dart';
|
|||||||
|
|
||||||
abstract class UserProfileRepository {
|
abstract class UserProfileRepository {
|
||||||
Future<UserProfile> getProfile();
|
Future<UserProfile> getProfile();
|
||||||
|
Future<void> deleteProfile();
|
||||||
Future<UserProfile?> updateProfile(UserProfile profile);
|
Future<UserProfile?> updateProfile(UserProfile profile);
|
||||||
Future<int?> uploadProfilePhoto(File imageFile);
|
Future<int?> uploadProfilePhoto(File imageFile);
|
||||||
Future<UserCheckFlags?> checkUser();
|
Future<UserCheckFlags?> checkUser();
|
||||||
|
|||||||
21
lib/domain/usecase/delete_profile_usecase.dart
Normal file
21
lib/domain/usecase/delete_profile_usecase.dart
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import '../entities/user_profile.dart';
|
||||||
|
import '../repositories/auth_repository.dart';
|
||||||
|
import '../repositories/pin_repository.dart';
|
||||||
|
import '../repositories/profile_repository.dart';
|
||||||
|
|
||||||
|
class DeleteProfileUsecase {
|
||||||
|
final UserProfileRepository repository;
|
||||||
|
final PinRepository _pinRepository;
|
||||||
|
final AuthRepository _authRepository;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DeleteProfileUsecase(this.repository, this._pinRepository, this._authRepository);
|
||||||
|
|
||||||
|
Future<void> call() {
|
||||||
|
_pinRepository.removePin();
|
||||||
|
repository.deleteProfile();
|
||||||
|
return _authRepository.logout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart'; // 🔹 1. Добавлен импорт
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:bot_toast/bot_toast.dart';
|
import 'package:bot_toast/bot_toast.dart';
|
||||||
import 'package:be_happy/presentation/event/edit_profile_event.dart';
|
import 'package:be_happy/presentation/event/edit_profile_event.dart';
|
||||||
import 'package:be_happy/presentation/event/profile_event.dart';
|
import 'package:be_happy/presentation/event/profile_event.dart';
|
||||||
@@ -69,6 +70,14 @@ class MyApp extends StatelessWidget {
|
|||||||
title: 'BeHappy',
|
title: 'BeHappy',
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
theme: ThemeData.dark(),
|
theme: ThemeData.dark(),
|
||||||
|
localizationsDelegates: const [
|
||||||
|
GlobalMaterialLocalizations.delegate,
|
||||||
|
GlobalWidgetsLocalizations.delegate,
|
||||||
|
GlobalCupertinoLocalizations.delegate,
|
||||||
|
],
|
||||||
|
supportedLocales: const [
|
||||||
|
Locale('ru', 'RU'),
|
||||||
|
],
|
||||||
builder: BotToastInit(),
|
builder: BotToastInit(),
|
||||||
routerConfig: appRouter.router,
|
routerConfig: appRouter.router,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class DeleteAccountDialog extends StatelessWidget {
|
||||||
|
const DeleteAccountDialog({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Dialog(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
insetPadding: const EdgeInsets.symmetric(horizontal: 40),
|
||||||
|
child: Container(
|
||||||
|
padding: const EdgeInsets.all(24),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFF2E3253).withOpacity(0.95),
|
||||||
|
borderRadius: BorderRadius.circular(28),
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
"Удалить\nучётную запись?",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
height: 1.2,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
const Text(
|
||||||
|
"Это действие необратимо. Все ваши\nданные будут удалены безвозвратно",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white70,
|
||||||
|
fontSize: 14,
|
||||||
|
height: 1.4,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
|
Container(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 52,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(26),
|
||||||
|
gradient: const LinearGradient(
|
||||||
|
colors: [Color(0xFFFF8E8E), Color(0xFFFE5F86)],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () => Navigator.pop(context, true),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
shadowColor: Colors.transparent,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(26),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: const Text(
|
||||||
|
"Удалить",
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
|
|
||||||
|
SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
height: 52,
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () => Navigator.pop(context, false),
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: const Color(0xFF0D1024),
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(26),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: const Text(
|
||||||
|
"Отмена",
|
||||||
|
style: TextStyle(color: Colors.white, fontSize: 16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,8 @@ import 'package:be_happy/domain/entities/tariff.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
|
||||||
|
import '../content_parser.dart';
|
||||||
|
|
||||||
class TariffInfoSheet extends StatefulWidget {
|
class TariffInfoSheet extends StatefulWidget {
|
||||||
final Tariff tariff;
|
final Tariff tariff;
|
||||||
final bool isInsurance;
|
final bool isInsurance;
|
||||||
@@ -42,7 +44,6 @@ class _TariffInfoSheetState extends State<TariffInfoSheet> {
|
|||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// Полоска сверху (Handle)
|
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
Container(
|
Container(
|
||||||
width: 40,
|
width: 40,
|
||||||
@@ -81,9 +82,9 @@ class _TariffInfoSheetState extends State<TariffInfoSheet> {
|
|||||||
const SizedBox(height: 30),
|
const SizedBox(height: 30),
|
||||||
|
|
||||||
// Таблица цен
|
// Таблица цен
|
||||||
_buildPriceRow('Старт поездки', '${widget.tariff.startPrice} BYN'),
|
_buildPriceRow('Старт поездки', '${widget.tariff.startPrice} руб.'),
|
||||||
_buildPriceRow('Последующая минута', '${widget.tariff.drivePrice} BYN'),
|
_buildPriceRow('Последующая минута', '${widget.tariff.drivePrice} руб.'),
|
||||||
_buildPriceRow('Пауза', '${widget.tariff.pausePrice} BYN/мин'),
|
_buildPriceRow('Пауза', '${widget.tariff.pausePrice} руб./мин'),
|
||||||
_buildPriceRow('КЕШБЭК', '${widget.tariff.cashback * 100}%', isAccent: true),
|
_buildPriceRow('КЕШБЭК', '${widget.tariff.cashback * 100}%', isAccent: true),
|
||||||
|
|
||||||
const Divider(color: Colors.white24, height: 40),
|
const Divider(color: Colors.white24, height: 40),
|
||||||
@@ -98,7 +99,7 @@ class _TariffInfoSheetState extends State<TariffInfoSheet> {
|
|||||||
Image.asset('assets/icons/info_icon.png', width: 18, height: 18),
|
Image.asset('assets/icons/info_icon.png', width: 18, height: 18),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Text(
|
Text(
|
||||||
'${widget.tariff.insurance} BYN',
|
'${widget.tariff.insurance} руб.',
|
||||||
style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold),
|
style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 12),
|
const SizedBox(width: 12),
|
||||||
@@ -118,10 +119,14 @@ class _TariffInfoSheetState extends State<TariffInfoSheet> {
|
|||||||
|
|
||||||
const Divider(color: Colors.white24, height: 40),
|
const Divider(color: Colors.white24, height: 40),
|
||||||
|
|
||||||
_buildInfoBullet('Оплата страховки осуществляется только по банковской карте отдельным платежом'),
|
Column(
|
||||||
_buildInfoBullet('В режиме паузы время тарифа приостанавливается'),
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
_buildInfoBullet('При старте заказа будет заблокирована сумма в размере 7 рублей для проверки платежеспособности. Сумма разблокируется по факту списания средств за поездку.'),
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: ContentParser.parseContent(
|
||||||
|
textJson: widget.tariff.description,
|
||||||
|
text: widget.tariff.descriptionJson,
|
||||||
|
),
|
||||||
|
),
|
||||||
const SizedBox(height: 30),
|
const SizedBox(height: 30),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ class _TariffSheetState extends State<TariffSheet> {
|
|||||||
subtitle: 'Старт поездки',
|
subtitle: 'Старт поездки',
|
||||||
details: [
|
details: [
|
||||||
'Далее ${tariff.drivePrice.toStringAsFixed(2)} ${tariff.currency}/мин.',
|
'Далее ${tariff.drivePrice.toStringAsFixed(2)} ${tariff.currency}/мин.',
|
||||||
'Минута на паузе ${tariff.pausePrice.toStringAsFixed(0)} ${tariff.currency}',
|
'Минута на паузе ${tariff.pausePrice.toStringAsFixed(2)} ${tariff.currency}',
|
||||||
],
|
],
|
||||||
isSelected: _selectedTariffIndex == index,
|
isSelected: _selectedTariffIndex == index,
|
||||||
isInsurance: state.isInsurance,
|
isInsurance: state.isInsurance,
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ class ProfileStarted extends ProfileEvent {}
|
|||||||
|
|
||||||
class ProfileUpdated extends ProfileEvent {}
|
class ProfileUpdated extends ProfileEvent {}
|
||||||
|
|
||||||
|
class DeleteProfilePressed extends ProfileEvent {}
|
||||||
|
|
||||||
class ProfilePhotoUpdated extends ProfileEvent{
|
class ProfilePhotoUpdated extends ProfileEvent{
|
||||||
final File imageFile;
|
final File imageFile;
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ class _EditProfileScreenState extends State<EditProfileScreen> {
|
|||||||
initialDate: _selectedBirthDate ?? DateTime.now(),
|
initialDate: _selectedBirthDate ?? DateTime.now(),
|
||||||
firstDate: DateTime(DateTime.now().year - 100),
|
firstDate: DateTime(DateTime.now().year - 100),
|
||||||
lastDate: DateTime.now(),
|
lastDate: DateTime.now(),
|
||||||
|
locale: const Locale('ru', 'RU'),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (picked != null && picked != _selectedBirthDate) {
|
if (picked != null && picked != _selectedBirthDate) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import '../../core/app_colors.dart';
|
|||||||
import '../../domain/entities/user_profile.dart';
|
import '../../domain/entities/user_profile.dart';
|
||||||
import '../components/custom_app_bar.dart';
|
import '../components/custom_app_bar.dart';
|
||||||
import '../components/gradient_button.dart';
|
import '../components/gradient_button.dart';
|
||||||
|
import '../components/dialog/delete_account_dialog.dart';
|
||||||
import '../viewmodel/profile_bloc.dart';
|
import '../viewmodel/profile_bloc.dart';
|
||||||
import 'edit_profile_screen.dart';
|
import 'edit_profile_screen.dart';
|
||||||
|
|
||||||
@@ -46,6 +47,18 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
context.go("/home/profile/edit");
|
context.go("/home/profile/edit");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _confirmDeleteAccount(BuildContext context) async {
|
||||||
|
final confirmed = await showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
barrierColor: Colors.black.withOpacity(0.6),
|
||||||
|
builder: (dialogContext) => const DeleteAccountDialog(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (confirmed == true && context.mounted) {
|
||||||
|
context.read<ProfileBloc>().add(DeleteProfilePressed());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@@ -136,12 +149,17 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
onEditTap: () => context.go("/home/profile/edit"),
|
onEditTap: () => context.go("/home/profile/edit"),
|
||||||
),
|
),
|
||||||
|
|
||||||
// const SizedBox(height: 24),
|
Padding(
|
||||||
// _SettingsBlock(
|
padding: const EdgeInsets.all(20),
|
||||||
// notificationsEnabled: notificationsEnabled,
|
child: GradientButton(
|
||||||
// onNotificationsChanged: (v) =>
|
text: 'Удалить учётную запись',
|
||||||
// setState(() => notificationsEnabled = v),
|
onTap: () => _confirmDeleteAccount(context),
|
||||||
// ),
|
showArrows: true,
|
||||||
|
height: 56,
|
||||||
|
width: double.infinity,
|
||||||
|
fontSize: 16,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,25 +1,38 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:be_happy/domain/usecase/delete_profile_usecase.dart';
|
||||||
import 'package:be_happy/domain/usecase/upload_profile_photo_usecase.dart';
|
import 'package:be_happy/domain/usecase/upload_profile_photo_usecase.dart';
|
||||||
|
import 'package:be_happy/presentation/viewmodel/splash_bloc.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
|
||||||
import '../../domain/entities/user_profile.dart';
|
import '../../domain/entities/user_profile.dart';
|
||||||
import '../../domain/usecase/get_profile_usecase.dart';
|
import '../../domain/usecase/get_profile_usecase.dart';
|
||||||
|
import '../../domain/usecase/logout_usecase.dart';
|
||||||
import '../../domain/usecase/update_profile_usecase.dart';
|
import '../../domain/usecase/update_profile_usecase.dart';
|
||||||
import '../event/profile_event.dart';
|
import '../event/profile_event.dart';
|
||||||
|
import '../event/spalsh_event.dart';
|
||||||
import '../state/profile_state.dart';
|
import '../state/profile_state.dart';
|
||||||
|
|
||||||
class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
|
class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
|
||||||
final GetProfileUseCase getProfileUseCase;
|
final GetProfileUseCase getProfileUseCase;
|
||||||
final UploadProfilePhotoUsecase uploadProfilePhotoUsecase;
|
final UploadProfilePhotoUsecase uploadProfilePhotoUsecase;
|
||||||
final UpdateProfileUseCase updateProfileUseCase;
|
final UpdateProfileUseCase updateProfileUseCase;
|
||||||
|
final DeleteProfileUsecase deleteProfileUsecase;
|
||||||
|
final LogoutUseCase logoutUseCase;
|
||||||
|
final SplashBloc splashBloc;
|
||||||
|
|
||||||
|
|
||||||
ProfileBloc(this.getProfileUseCase,
|
ProfileBloc(this.getProfileUseCase,
|
||||||
this.uploadProfilePhotoUsecase,
|
this.uploadProfilePhotoUsecase,
|
||||||
this.updateProfileUseCase)
|
this.updateProfileUseCase,
|
||||||
|
this.deleteProfileUsecase,
|
||||||
|
this.logoutUseCase,
|
||||||
|
this.splashBloc)
|
||||||
: super(ProfileState.initial()) {
|
: super(ProfileState.initial()) {
|
||||||
on<ProfileStarted>(_onStarted);
|
on<ProfileStarted>(_onStarted);
|
||||||
on<ProfileUpdated>(_onUpdated);
|
on<ProfileUpdated>(_onUpdated);
|
||||||
on<ProfilePhotoUpdated>(_onPhotoUploaded);
|
on<ProfilePhotoUpdated>(_onPhotoUploaded);
|
||||||
|
on<DeleteProfilePressed>(_onDeleteProfilePressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onStarted(
|
Future<void> _onStarted(
|
||||||
@@ -55,7 +68,6 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
|
|||||||
final avatarId = await uploadProfilePhotoUsecase(event.imageFile);
|
final avatarId = await uploadProfilePhotoUsecase(event.imageFile);
|
||||||
|
|
||||||
if (avatarId != null) {
|
if (avatarId != null) {
|
||||||
// Отправляем PATCH запрос с новым avatarId
|
|
||||||
await updateProfileUseCase(UserProfile(
|
await updateProfileUseCase(UserProfile(
|
||||||
name: '',
|
name: '',
|
||||||
birthDate: '',
|
birthDate: '',
|
||||||
@@ -72,4 +84,14 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
|
|||||||
emit(state.copyWith(isLoading: false, error: "Ошибка загрузки: ${e.toString()}"));
|
emit(state.copyWith(isLoading: false, error: "Ошибка загрузки: ${e.toString()}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FutureOr<void> _onDeleteProfilePressed(DeleteProfilePressed event, Emitter<ProfileState> emit) async {
|
||||||
|
try {
|
||||||
|
|
||||||
|
await deleteProfileUsecase();
|
||||||
|
splashBloc.add(AuthLogoutRequested());
|
||||||
|
} catch (e) {
|
||||||
|
emit(state.copyWith(isLoading: false, error: "Ошибка удаления профиля: ${e.toString()}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,6 +294,11 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.0.0"
|
version: "5.0.0"
|
||||||
|
flutter_localizations:
|
||||||
|
dependency: "direct main"
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
flutter_native_splash:
|
flutter_native_splash:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@@ -540,10 +545,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
|
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.19.0"
|
version: "0.20.2"
|
||||||
jni:
|
jni:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ name: be_happy
|
|||||||
description: ""
|
description: ""
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
|
|
||||||
version: 1.0.0+22
|
version: 1.0.0+23
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.8.1
|
sdk: ^3.8.1
|
||||||
@@ -10,6 +10,8 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
flutter_localizations:
|
||||||
|
sdk: flutter
|
||||||
cupertino_icons: ^1.0.8
|
cupertino_icons: ^1.0.8
|
||||||
flutter_secure_storage: ^9.2.4
|
flutter_secure_storage: ^9.2.4
|
||||||
shared_preferences: ^2.5.3
|
shared_preferences: ^2.5.3
|
||||||
@@ -21,7 +23,7 @@ dependencies:
|
|||||||
path: ^1.9.0
|
path: ^1.9.0
|
||||||
async: ^2.11.0
|
async: ^2.11.0
|
||||||
mime: ^1.0.5
|
mime: ^1.0.5
|
||||||
intl: ^0.19.0
|
intl: ^0.20.2
|
||||||
url_launcher: ^6.2.5
|
url_launcher: ^6.2.5
|
||||||
go_router: ^14.0.0
|
go_router: ^14.0.0
|
||||||
android_id: ^0.4.0
|
android_id: ^0.4.0
|
||||||
|
|||||||
Reference in New Issue
Block a user