179 lines
5.5 KiB
Dart
179 lines
5.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import '../i18n/app_locale.dart';
|
|
import '../theme/tokens.dart';
|
|
|
|
/// 앱 공통 확인 창 — Figma `2066:17799`(행성 생성 확인) · `554:24669`(설정 확인 팝업).
|
|
///
|
|
/// 카드 312 폭 · #282828 r12 · 안쪽 24/16 · 문구 16/600 가운데 정렬,
|
|
/// 그 아래 **취소(흰 테두리) · 실행(분홍 채움)을 가로로 반씩**(48 높이 · 간격 8 · r8).
|
|
/// 단일 버튼 알림(Figma `511:86714` · `554:23103`)은 실행 버튼 하나가 폭을 다 쓴다.
|
|
///
|
|
/// [content] 는 입력 칸이 있는 창(반려 사유 · 인증 제출 등)에서 문구 대신 넣는다.
|
|
class AppDialog extends StatelessWidget {
|
|
const AppDialog({
|
|
super.key,
|
|
required this.title,
|
|
this.body,
|
|
this.content,
|
|
this.cancelLabel,
|
|
required this.confirmLabel,
|
|
});
|
|
|
|
final String title;
|
|
final String? body;
|
|
final Widget? content;
|
|
|
|
/// null 이면 실행 버튼 하나만 둔다.
|
|
final String? cancelLabel;
|
|
final String confirmLabel;
|
|
|
|
static const _shape = RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.all(Radius.circular(AppRadius.sm)),
|
|
);
|
|
|
|
static TextStyle _text(double size, FontWeight weight, Color color) =>
|
|
TextStyle(
|
|
fontFamily: AppFonts.body,
|
|
fontSize: size,
|
|
fontWeight: weight,
|
|
height: 1.5,
|
|
letterSpacing: size * -0.025,
|
|
color: color,
|
|
);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
Widget button(String label, bool value, {required bool filled}) {
|
|
final text = Text(
|
|
label,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: _text(
|
|
16,
|
|
FontWeight.w600,
|
|
filled ? AppColors.onCosmicAccent : AppColors.onCosmic,
|
|
).copyWith(height: 1),
|
|
);
|
|
void pop() => Navigator.of(context).pop(value);
|
|
return Expanded(
|
|
child: filled
|
|
? FilledButton(
|
|
onPressed: pop,
|
|
style: FilledButton.styleFrom(
|
|
minimumSize: const Size.fromHeight(48),
|
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
backgroundColor: AppColors.cosmicAccent,
|
|
shape: _shape,
|
|
),
|
|
child: text,
|
|
)
|
|
: OutlinedButton(
|
|
onPressed: pop,
|
|
style: OutlinedButton.styleFrom(
|
|
minimumSize: const Size.fromHeight(48),
|
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
side: const BorderSide(color: AppColors.onCosmic),
|
|
shape: _shape,
|
|
),
|
|
child: text,
|
|
),
|
|
);
|
|
}
|
|
|
|
return Dialog(
|
|
backgroundColor: const Color(0xFF282828), // Figma 2066:17799 fill
|
|
insetPadding: const EdgeInsets.symmetric(horizontal: 31.5, vertical: 24),
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.all(Radius.circular(AppRadius.md)),
|
|
),
|
|
child: Padding(
|
|
padding: const EdgeInsets.fromLTRB(16, 24, 16, 24),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Flexible(
|
|
child: SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text(
|
|
title,
|
|
textAlign: TextAlign.center,
|
|
style: _text(16, FontWeight.w600, AppColors.onCosmic),
|
|
),
|
|
if (body case final b?) ...[
|
|
const SizedBox(height: 16),
|
|
Text(
|
|
b,
|
|
textAlign: TextAlign.center,
|
|
style: _text(16, FontWeight.w500, AppColors.onCosmic)
|
|
.copyWith(height: 1.4),
|
|
),
|
|
],
|
|
if (content case final c?) ...[
|
|
const SizedBox(height: 16),
|
|
c,
|
|
],
|
|
],
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
Row(
|
|
children: [
|
|
if (cancelLabel case final c?) ...[
|
|
button(c, false, filled: false),
|
|
const SizedBox(width: 8),
|
|
],
|
|
button(confirmLabel, true, filled: true),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
const _barrier = Color(0xB3000000);
|
|
|
|
/// 취소 · 실행 두 갈래. 실행이면 true. [confirmLabel] 기본은 「변경」.
|
|
Future<bool> showConfirmDialog(
|
|
BuildContext context,
|
|
String title, {
|
|
String? body,
|
|
Widget? content,
|
|
String? cancelLabel,
|
|
String? confirmLabel,
|
|
}) async {
|
|
final r = await showDialog<bool>(
|
|
context: context,
|
|
barrierColor: _barrier,
|
|
builder: (context) => AppDialog(
|
|
title: title,
|
|
body: body,
|
|
content: content,
|
|
cancelLabel: cancelLabel ?? context.l10n.commonCancel,
|
|
confirmLabel: confirmLabel ?? context.l10n.commonChange,
|
|
),
|
|
);
|
|
return r ?? false;
|
|
}
|
|
|
|
/// 확인 하나뿐인 알림 — Figma `511:86714`(타이틀 가운데 · 확인 버튼 가운데).
|
|
Future<void> showAlertDialog(
|
|
BuildContext context,
|
|
String title, {
|
|
String? body,
|
|
String? confirmLabel,
|
|
}) => showDialog<void>(
|
|
context: context,
|
|
barrierColor: _barrier,
|
|
builder: (context) => AppDialog(
|
|
title: title,
|
|
body: body,
|
|
confirmLabel: confirmLabel ?? context.l10n.commonConfirm,
|
|
),
|
|
);
|