fix profile
This commit is contained in:
@@ -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/cupertino.dart';
|
||||
|
||||
import '../content_parser.dart';
|
||||
|
||||
class TariffInfoSheet extends StatefulWidget {
|
||||
final Tariff tariff;
|
||||
final bool isInsurance;
|
||||
@@ -42,7 +44,6 @@ class _TariffInfoSheetState extends State<TariffInfoSheet> {
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
// Полоска сверху (Handle)
|
||||
const SizedBox(height: 12),
|
||||
Container(
|
||||
width: 40,
|
||||
@@ -81,9 +82,9 @@ class _TariffInfoSheetState extends State<TariffInfoSheet> {
|
||||
const SizedBox(height: 30),
|
||||
|
||||
// Таблица цен
|
||||
_buildPriceRow('Старт поездки', '${widget.tariff.startPrice} BYN'),
|
||||
_buildPriceRow('Последующая минута', '${widget.tariff.drivePrice} BYN'),
|
||||
_buildPriceRow('Пауза', '${widget.tariff.pausePrice} BYN/мин'),
|
||||
_buildPriceRow('Старт поездки', '${widget.tariff.startPrice} руб.'),
|
||||
_buildPriceRow('Последующая минута', '${widget.tariff.drivePrice} руб.'),
|
||||
_buildPriceRow('Пауза', '${widget.tariff.pausePrice} руб./мин'),
|
||||
_buildPriceRow('КЕШБЭК', '${widget.tariff.cashback * 100}%', isAccent: true),
|
||||
|
||||
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),
|
||||
const Spacer(),
|
||||
Text(
|
||||
'${widget.tariff.insurance} BYN',
|
||||
'${widget.tariff.insurance} руб.',
|
||||
style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
@@ -118,10 +119,14 @@ class _TariffInfoSheetState extends State<TariffInfoSheet> {
|
||||
|
||||
const Divider(color: Colors.white24, height: 40),
|
||||
|
||||
_buildInfoBullet('Оплата страховки осуществляется только по банковской карте отдельным платежом'),
|
||||
_buildInfoBullet('В режиме паузы время тарифа приостанавливается'),
|
||||
_buildInfoBullet('При старте заказа будет заблокирована сумма в размере 7 рублей для проверки платежеспособности. Сумма разблокируется по факту списания средств за поездку.'),
|
||||
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: ContentParser.parseContent(
|
||||
textJson: widget.tariff.description,
|
||||
text: widget.tariff.descriptionJson,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -281,7 +281,7 @@ class _TariffSheetState extends State<TariffSheet> {
|
||||
subtitle: 'Старт поездки',
|
||||
details: [
|
||||
'Далее ${tariff.drivePrice.toStringAsFixed(2)} ${tariff.currency}/мин.',
|
||||
'Минута на паузе ${tariff.pausePrice.toStringAsFixed(0)} ${tariff.currency}',
|
||||
'Минута на паузе ${tariff.pausePrice.toStringAsFixed(2)} ${tariff.currency}',
|
||||
],
|
||||
isSelected: _selectedTariffIndex == index,
|
||||
isInsurance: state.isInsurance,
|
||||
|
||||
@@ -8,6 +8,8 @@ class ProfileStarted extends ProfileEvent {}
|
||||
|
||||
class ProfileUpdated extends ProfileEvent {}
|
||||
|
||||
class DeleteProfilePressed extends ProfileEvent {}
|
||||
|
||||
class ProfilePhotoUpdated extends ProfileEvent{
|
||||
final File imageFile;
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ class _EditProfileScreenState extends State<EditProfileScreen> {
|
||||
initialDate: _selectedBirthDate ?? DateTime.now(),
|
||||
firstDate: DateTime(DateTime.now().year - 100),
|
||||
lastDate: DateTime.now(),
|
||||
locale: const Locale('ru', 'RU'),
|
||||
);
|
||||
|
||||
if (picked != null && picked != _selectedBirthDate) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import '../../core/app_colors.dart';
|
||||
import '../../domain/entities/user_profile.dart';
|
||||
import '../components/custom_app_bar.dart';
|
||||
import '../components/gradient_button.dart';
|
||||
import '../components/dialog/delete_account_dialog.dart';
|
||||
import '../viewmodel/profile_bloc.dart';
|
||||
import 'edit_profile_screen.dart';
|
||||
|
||||
@@ -43,7 +44,19 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
}
|
||||
|
||||
Future<void> _openEditProfile(UserProfile profile) async {
|
||||
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
|
||||
@@ -136,12 +149,17 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
onEditTap: () => context.go("/home/profile/edit"),
|
||||
),
|
||||
|
||||
// const SizedBox(height: 24),
|
||||
// _SettingsBlock(
|
||||
// notificationsEnabled: notificationsEnabled,
|
||||
// onNotificationsChanged: (v) =>
|
||||
// setState(() => notificationsEnabled = v),
|
||||
// ),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(20),
|
||||
child: GradientButton(
|
||||
text: 'Удалить учётную запись',
|
||||
onTap: () => _confirmDeleteAccount(context),
|
||||
showArrows: true,
|
||||
height: 56,
|
||||
width: double.infinity,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -370,4 +388,4 @@ class _SettingsBlock extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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/presentation/viewmodel/splash_bloc.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../domain/entities/user_profile.dart';
|
||||
import '../../domain/usecase/get_profile_usecase.dart';
|
||||
import '../../domain/usecase/logout_usecase.dart';
|
||||
import '../../domain/usecase/update_profile_usecase.dart';
|
||||
import '../event/profile_event.dart';
|
||||
import '../event/spalsh_event.dart';
|
||||
import '../state/profile_state.dart';
|
||||
|
||||
class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
|
||||
final GetProfileUseCase getProfileUseCase;
|
||||
final UploadProfilePhotoUsecase uploadProfilePhotoUsecase;
|
||||
final UpdateProfileUseCase updateProfileUseCase;
|
||||
final DeleteProfileUsecase deleteProfileUsecase;
|
||||
final LogoutUseCase logoutUseCase;
|
||||
final SplashBloc splashBloc;
|
||||
|
||||
|
||||
ProfileBloc(this.getProfileUseCase,
|
||||
this.uploadProfilePhotoUsecase,
|
||||
this.updateProfileUseCase)
|
||||
this.updateProfileUseCase,
|
||||
this.deleteProfileUsecase,
|
||||
this.logoutUseCase,
|
||||
this.splashBloc)
|
||||
: super(ProfileState.initial()) {
|
||||
on<ProfileStarted>(_onStarted);
|
||||
on<ProfileUpdated>(_onUpdated);
|
||||
on<ProfilePhotoUpdated>(_onPhotoUploaded);
|
||||
on<DeleteProfilePressed>(_onDeleteProfilePressed);
|
||||
}
|
||||
|
||||
Future<void> _onStarted(
|
||||
@@ -55,7 +68,6 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
|
||||
final avatarId = await uploadProfilePhotoUsecase(event.imageFile);
|
||||
|
||||
if (avatarId != null) {
|
||||
// Отправляем PATCH запрос с новым avatarId
|
||||
await updateProfileUseCase(UserProfile(
|
||||
name: '',
|
||||
birthDate: '',
|
||||
@@ -72,4 +84,14 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
|
||||
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()}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user