Files
fanuzu/app/lib/features/quest/quest_reward_screen.dart
T

123 lines
5.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:flutter/material.dart';
import '../../core/theme/tokens.dart';
import '../home/home_screen.dart' show formatPop;
import 'quest_data.dart';
import '../../core/i18n/app_locale.dart';
/// 보상 완료 — 화면 대조 원장 F4 · Figma `251:113651`(퀘스트 완료) · `482:15084`(광고 시청 후).
///
/// 명세 `518:88630` — *보상 완료 아이콘 · 보상 POP 텍스트 · 중앙 정렬*
/// 명세 `518:88644` — *클릭 시 내 POP + 보유 POP Update ·*
/// *퀘스트 진행 상태값 보상완료 변경 · 퀘스트 상세 화면 이동*
/// 명세 `518:88685` — *광고 시청 POP = 보상 POP × 2 or ×3*
/// 잔액(명세 `518:88644` *보유 POP Update*)은 시안에 표시 자리가 없어 호출부가 다시 읽는다.
///
/// **POP 을 여기서 더하지 않는다.** 잔액과 원장은 서버가 쓰며(`fn-quest-attend`
/// 등), 이 화면은 결과를 보여 주고 상태 전이를 호출부에 알릴 뿐이다.
class QuestRewardScreen extends StatelessWidget {
const QuestRewardScreen({
super.key,
required this.detail,
this.reward,
this.adBonusPop,
});
final QuestDetail detail;
/// 서버가 지급한 결과. 있으면 **이 값만 띄운다** — 설정 보상 POP 과 실제 지급액이
/// 다를 수 있고(운영값 조정·등급 배수), 화면이 설정값을 띄우면 원장과 어긋난다.
final QuestReward? reward;
/// 광고 추가 보상으로 서버가 지급한 기여 POP. 광고를 안 봤거나 청구가 실패했으면 null.
final int? adBonusPop;
int? get rewardPop => reward?.rewardedPop ?? detail.card.rewardPop;
@override
Widget build(BuildContext context) {
final t = Theme.of(context).textTheme;
return Scaffold(
body: SafeArea(
// 시안의 본문 구간(위 56 머리 · 아래 72 버튼 자리) 가운데에 놓는다.
child: Padding(
padding: const EdgeInsets.only(top: 56),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// 120 원 둘레에 그림자 6 을 포함한 132 이미지.
Image.asset('assets/figma/quest-done.png', width: 132, height: 132),
const SizedBox(height: 18),
Text(
context.l10n.questRewardDone,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
height: 1.4,
color: AppColors.onCosmic,
),
),
const SizedBox(height: 8),
Text.rich(
TextSpan(
children: [
TextSpan(
text: rewardPop == null ? 'POP' : '+${formatPop(rewardPop!)}',
style: const TextStyle(color: Color(0xFF67D3A9)),
),
TextSpan(text: context.l10n.questRewardReceived),
],
),
style: const TextStyle(
fontSize: 26,
fontWeight: FontWeight.w600,
height: 1.4,
color: AppColors.onCosmic,
),
),
if (adBonusPop != null) ...[
const SizedBox(height: AppSpace.s2),
Text(
context.l10n.questAdBonus(formatPop(adBonusPop!)),
style: t.bodySmall,
textAlign: TextAlign.center,
),
],
],
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
child: FilledButton(
onPressed: () => Navigator.of(context).pop(true),
style: FilledButton.styleFrom(
minimumSize: const Size.fromHeight(56),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.sm),
),
backgroundColor: AppColors.cosmicAccent,
foregroundColor: Colors.black,
textStyle: const TextStyle(
fontFamily: AppFonts.body,
fontSize: 16,
fontWeight: FontWeight.w600,
height: 24 / 16,
),
),
child: Text(context.l10n.commonDone),
),
),
],
),
),
),
);
}
}