가입 약관 동의 기록 · 서비스 탈퇴 · 온보딩 6단계 · Coach Mark

This commit is contained in:
Sn-Kinos
2026-10-05 22:48:25 +09:00
parent e7010010bb
commit 55424bd4a2
36 changed files with 2884 additions and 77 deletions
+34 -7
View File
@@ -1,4 +1,8 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../core/data/backend.dart' show BackendException;
import '../../core/i18n/app_locale.dart';
import '../../core/push/push_messaging.dart';
@@ -230,7 +234,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
title: l10n.settingsWithdrawConfirm,
body: l10n.settingsWithdrawBody,
action: l10n.settingsWithdraw,
withdraw: true,
onConfirm: _withdraw,
),
),
],
@@ -339,6 +343,34 @@ class _SettingsScreenState extends State<SettingsScreen> {
await LocaleScope.maybeOf(context)?.select(picked);
}
/// 서비스 탈퇴 — 명세 `554:24885` 「연동 상태값이 있을 경우 비정상 탈퇴 처리 · 게시물 보존 ·
/// 탈퇴 처리 후 앱 종료」. 연동이 남아 있으면 비정상 탈퇴 안내(`554:24908` · `374:14699`)만 띄운다.
/// 서버도 같은 조건을 다시 본다(E-AUTH-14).
Future<void> _withdraw() async {
final l10n = context.l10n;
if (_linked.values.where((e) => e != null).length > 1) {
await _notice(l10n.settingsWithdrawLinked);
return;
}
try {
// 푸시 정리를 먼저 — 계정이 지워지면 이 기기 토큰을 지울 수 없다.
await widget.push?.clearOnSignOut();
await widget.repository.withdraw();
} on BackendException catch (e) {
if (mounted) {
await _notice(
e.code == 'E-AUTH-14' ? l10n.settingsWithdrawLinked : e.message,
);
}
return;
}
await widget.auth?.signOut();
// 「앱 종료」 — Android 만. iOS 는 앱이 스스로 종료하지 않는다(스토어 지침) — 로그인 화면으로 간다.
if (defaultTargetPlatform == TargetPlatform.android) {
await SystemNavigator.pop();
}
}
/// 안내 팝업(확인 하나) — 시안 `554:23103`.
Future<void> _notice(String message) => showAlertDialog(context, message);
@@ -347,7 +379,6 @@ class _SettingsScreenState extends State<SettingsScreen> {
required String title,
String? body,
required String action,
bool withdraw = false,
Future<void> Function()? onConfirm,
}) async {
final ok = await showConfirmDialog(
@@ -356,11 +387,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
body: body,
confirmLabel: action,
);
if (ok == true && onConfirm != null) {
await onConfirm();
} else if (ok == true && withdraw && mounted) {
_toast(context.l10n.settingsWithdrawLater);
}
if (ok == true && onConfirm != null) await onConfirm();
return ok;
}
}