account_setting_view.dart 12.3 KB
import 'package:doublefeel_flutter/app/actions/dialog_action.dart';
import 'package:doublefeel_flutter/app/models/dialog_meta_data.dart';
import 'package:doublefeel_flutter/app/modules/home/controllers/my_controller.dart';
import 'package:doublefeel_flutter/app/routes/app_pages.dart';
import 'package:doublefeel_flutter/app/utils/dialog_utils.dart';

import 'package:doublefeel_flutter/core/network/api/user_api.dart';
import 'package:doublefeel_flutter/core/result/app_result.dart';
import 'package:doublefeel_flutter/core/services/loading_service.dart';
import 'package:doublefeel_flutter/core/services/user_state_service.dart';
import 'package:doublefeel_flutter/core/theme/app_colors.dart';
import 'package:doublefeel_flutter/core/theme/app_theme.dart';
import 'package:doublefeel_flutter/core/util/app_toast.dart';

import 'package:doublefeel_flutter/data/local/user_preferences_storage.dart';
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
import 'package:flutter/material.dart';

import 'package:get/get.dart';

class AccountSettingView extends GetView<MyController> {
  const AccountSettingView({super.key});

  @override
  Widget build(BuildContext context) {
    final userPrefs = Get.find<UserPreferencesStorage>();

    return Scaffold(
      appBar: AppBar(
        title: Text(
          context.l10n.accountSettings,
        ),
        leading: IconButton(
          highlightColor: Colors.transparent,
          padding: EdgeInsets.zero,
          onPressed: Get.back,
          icon: Image.asset(
            'assets/images/common/ic_nav_back.webp',
            width: 24,
            height: 24,
          ),
        ),
      ),
      body: Obx(() {
        final telephone =
            userPrefs.preferences.value.meUserInfo?.telephone ?? '';
        final thirdAccountId =
            userPrefs.preferences.value.meUserInfo?.thirdAccountId ?? '';
        return Column(
          children: [
            SizedBox(height: 16),
            if (thirdAccountId.isNotEmpty)
              _buildAccountCard(
                context: context,
                title: 'Apple ID',
                content: thirdAccountId,
              )
            else
              _buildAccountCard(
                context: context,
                title: context.l10n.mobilePhoneNumber,
                content: telephone,
              ),
            SizedBox(height: 20),
            GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: () {
                Get.bottomSheet(
                  _DeleteAccountBottomSheet(onDeleteAccount: _deleteAccount),
                  barrierColor: Colors.black.withValues(alpha: 0.7),
                  enableDrag: true,
                  isScrollControlled: true,
                  persistent: false,
                );
              },
              child: Padding(
                padding: EdgeInsets.symmetric(
                  horizontal: 24,
                  vertical: 8,
                ),
                child: Text(
                  context.l10n.deleteAccount,
                  style: TextStyle(
                    color: AppColors.warning,
                    fontSize: 12,
                    fontWeight: FontWeight.w400,
                    height: 1.4,
                  ),
                ),
              ),
            ),
          ],
        );
      }),
    );
  }

  Widget _buildAccountCard({
    required BuildContext context,
    required String title,
    required String content,
  }) {
    return Container(
      height: 110,
      margin: EdgeInsets.symmetric(horizontal: 15),
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(16),
      ),
      child: Column(
        children: [
          SizedBox(
            height: 54,
            child: Padding(
              padding: EdgeInsets.symmetric(horizontal: 20),
              child: Row(
                children: [
                  Text(
                    title,
                    style: TextStyle(
                      color: AppColors.textPrimary,
                      fontSize: 14,
                      fontWeight: FontWeight.w400,
                      height: 1.4,
                    ),
                  ),
                  SizedBox(width: 16),
                  Expanded(
                    child: Text(
                      content,
                      maxLines: 1,
                      overflow: TextOverflow.ellipsis,
                      textAlign: TextAlign.right,
                      style: const TextStyle(
                        color: AppColors.textSecondary,
                        fontSize: 14,
                        fontWeight: FontWeight.w400,
                        height: 1.4,
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
          Padding(
            padding: EdgeInsets.symmetric(horizontal: 21),
            child: const Divider(
              height: 1,
              thickness: 0.5,
              color: Color(0xFFF3F3F3),
            ),
          ),
          Expanded(
            child: GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: _logout,
              child: Center(
                child: Text(
                  context.l10n.logOut,
                  style: TextStyle(
                    color: AppColors.primary,
                    fontSize: 14,
                    fontWeight: FontWeight.w500,
                    height: 1.4,
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Future<void> _logout() async {
    final confirmResult = await DialogUtils.showCommonDialog(DialogMetaData(
        title: l10n.logOut,
        message: l10n.confirmLogoutPrompt,
        confirmText: l10n.confirmLogout,
        iconAsset: null));
    if (confirmResult.action != DialogAction.confirm) return;

    await LoadingService.instance.run(() async {
      await Get.find<UserStateService>().onLogout();
    });

    AppToast.show(l10n.loggedOutSuccessfully);
    Get.offAllNamed(AppRoutes.login);
  }

  Future<void> _deleteAccount() async {
    await LoadingService.instance.run(() async {
      final deleteResult = await Get.find<UserApi>().deleteAccount();
      if (deleteResult is! AppSuccess<void>) return;

      await Get.find<UserStateService>().onLogout(callServerLogout: false);
    });
    AppToast.show(l10n.accountDeletedSuccessfully);
    Get.offAllNamed(AppRoutes.login);
  }
}

class _DeleteAccountBottomSheet extends StatelessWidget {
  const _DeleteAccountBottomSheet({required this.onDeleteAccount});

  final VoidCallback onDeleteAccount;

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: context.colors.backgroundPage,
        borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
      ),
      child: SafeArea(
        top: false,
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            SizedBox(height: 8),
            SizedBox(
              height: 56,
              child: Stack(
                alignment: Alignment.center,
                children: [
                  Center(
                    child: Padding(
                      padding: EdgeInsets.symmetric(horizontal: 72),
                      child: Text(
                        AppLocalizations.of(context)!
                            .areYouSureYouWantToDeleteYourAccount,
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          color: context.colors.textPrimary,
                          fontSize: 16,
                          fontWeight: FontWeight.w600,
                          height: 1.2,
                        ),
                      ),
                    ),
                  ),
                  Positioned(
                    left: 16,
                    child: GestureDetector(
                      behavior: HitTestBehavior.opaque,
                      onTap: Get.back,
                      child: SizedBox(
                        width: 44,
                        height: 44,
                        child: Center(
                          child: Image.asset(
                            'assets/images/common/ic_close.png',
                            width: 20,
                            height: 20,
                            color: context.colors.chartPurple,
                          ),
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            Container(
              margin: EdgeInsets.symmetric(horizontal: 16),
              padding: EdgeInsets.fromLTRB(20, 20, 20, 18),
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(16),
              ),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    context.l10n.deleteAccountWarningTitle,
                    textAlign: TextAlign.center,
                    style: TextStyle(
                      color: context.colors.warning,
                      fontSize: 14,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                  SizedBox(
                    height: 12,
                  ),
                  Text(
                    context.l10n.deleteAccountWarningPrompt,
                    style: TextStyle(
                      color: context.colors.textSecondary,
                      fontSize: 12,
                      fontWeight: FontWeight.w400,
                    ),
                  ),
                  SizedBox(
                    height: 12,
                  ),
                  Text(
                    context.l10n.deleteAccountWarningNote1,
                    style: TextStyle(
                      color: context.colors.textSecondary,
                      fontSize: 12,
                      fontWeight: FontWeight.w400,
                    ),
                  ),
                  SizedBox(
                    height: 12,
                  ),
                  Text(
                    context.l10n.deleteAccountWarningNote2,
                    style: TextStyle(
                      color: context.colors.textSecondary,
                      fontSize: 12,
                      fontWeight: FontWeight.w400,
                    ),
                  )
                ],
              ),
            ),
            SizedBox(
              height: 45,
            ),
            GestureDetector(
              onTap: onDeleteAccount,
              child: Text(
                AppLocalizations.of(context)!.confirmDeletion,
                style: TextStyle(
                  color: context.colors.warning,
                  fontSize: 16,
                  fontWeight: FontWeight.w500,
                ),
              ),
            ),
            GestureDetector(
              onTap: () {
                Get.back();
              },
              child: Container(
                width: 280,
                height: 48,
                margin: EdgeInsets.only(top: 17, bottom: 20),
                padding:
                    const EdgeInsets.symmetric(horizontal: 24, vertical: 8),
                decoration: ShapeDecoration(
                  color: context.colors.primary,
                  shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(24),
                  ),
                ),
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  spacing: 24,
                  children: [
                    Text(
                      context.l10n.iLlThinkAboutItSomeMore,
                      style: TextStyle(
                        color: Colors.white,
                        fontSize: 16,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  ],
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}