1
0
forked from baron/baron-sso

동의 화면 '취소' 기능 및 확인 다이얼로그 구현

This commit is contained in:
2026-02-03 15:04:14 +09:00
parent 5bb48191e8
commit 69b1257ad7

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:userfront/core/services/auth_proxy_service.dart';
import 'package:userfront/core/services/web_window.dart';
@@ -103,27 +104,60 @@ class _ConsentScreenState extends State<ConsentScreen> {
);
if (result['redirectTo'] != null) {
html.window.location.href = result['redirectTo'];
webWindow.redirectTo(result['redirectTo']);
} else {
setState(() {
_error = '동의가 처리되었으나, 리다이렉트 URL을 받지 못했습니다.';
_isLoading = false;
_isSubmitting = false;
});
}
} catch (e) {
setState(() {
_error = '동의 처리에 실패했습니다: $e';
_isLoading = false;
_isSubmitting = false;
});
}
}
void _onCancel() {
// 취소 시 동작 (창 닫기 시도 또는 알림)
// 실제 프로덕션에서는 Hydra reject API를 호출하고 리다이렉트 하는 것이 좋습니다.
// 현재는 요구사항에 따라 간단히 처리합니다.
html.window.alert('동의 취소했습니다. 창을 닫아주세요.');
// html.window.close(); // 브라우저 정책상 스크립트로 연 창이 아니면 닫히지 않을 수 있음
Future<void> _onCancel() async {
final confirmed = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: const Text('동의 취소'),
content: const Text('권한 동의를 취소하면 해당 서비스를 이용할 수 없습니다. 취소하시겠습니까?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text('아니오'),
),
TextButton(
onPressed: () => Navigator.pop(context, true),
style: TextButton.styleFrom(foregroundColor: Colors.red),
child: const Text('예, 취소합니다'),
),
],
),
);
if (confirmed == true) {
setState(() => _isSubmitting = true);
try {
final resp = await AuthProxyService.rejectConsent(widget.consentChallenge);
final redirectTo = resp['redirectTo'];
if (redirectTo != null) {
webWindow.redirectTo(redirectTo);
} else {
if (mounted) context.go('/');
}
} catch (e) {
setState(() => _isSubmitting = false);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('취소 처리 중 오류가 발생했습니다: $e')),
);
}
}
}
}
@override
@@ -299,7 +333,7 @@ class _ConsentScreenState extends State<ConsentScreen> {
// 4. 버튼 영역
ElevatedButton(
onPressed: _acceptConsent,
onPressed: _isSubmitting ? null : _acceptConsent,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: const Color(0xFF1A1F2C), // 브랜드 컬러
@@ -309,14 +343,23 @@ class _ConsentScreenState extends State<ConsentScreen> {
),
elevation: 0,
),
child: const Text(
'동의하고 계속하기',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
child: _isSubmitting
? const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
color: Colors.white,
),
)
: const Text(
'동의하고 계속하기',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
),
const SizedBox(height: 12),
OutlinedButton(
onPressed: _onCancel,
onPressed: _isSubmitting ? null : _onCancel,
style: OutlinedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(