Files
fanuzu/app/lib/features/home/widgets/home_weekly.dart
T

117 lines
4.2 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/i18n/app_locale.dart';
import '../../../core/theme/tokens.dart';
import '../home_data.dart';
import '../home_screen.dart' show formatPop;
/// HOME 주간 정보 — 발주사 9/9 검토회신 2항 · HOME 정보위계 v1.0 §2 의 2 · 3 · 6 · 7번(A-37).
///
/// 🟡 **배치는 임시다.** 9/7 회신이 기준으로 든 「REFINE v5A · HOME · Default」 는 계약 시점 사본
/// Figma 에 없다(전 페이지 이름 · 문구 검색, 2026-10-06). 정보 위계 v1.0 §7 「프레임 실측과 무관하게 반드시
/// 포함」에 따라 값만 먼저 싣고, 자리 · 모양은 해석 확인 요청 Q-A16 회신을 따른다.
/// 값의 뜻은 [HomeWeekly] — 모르는 값은 0 으로 채우지 않고 「—」.
class HomeWeeklyCard extends StatelessWidget {
const HomeWeeklyCard({super.key, required this.weekly});
final HomeWeekly weekly;
static const _label = TextStyle(
fontFamily: AppFonts.body,
fontSize: 13,
height: 18 / 13,
color: AppColors.onCosmicVariant,
);
static const _value = TextStyle(
fontFamily: AppFonts.body,
fontSize: 14,
fontWeight: FontWeight.w600,
height: 18 / 14,
color: AppColors.onCosmic,
);
static String _signed(num v) => '${v >= 0 ? '+' : '−'}${formatPop(v.abs().round())}';
@override
Widget build(BuildContext context) {
final l10n = context.l10n;
final w = weekly;
final change = w.rankChange;
// 라벨 2 : 값 3 으로 나눈다 — 값이 폭을 다 차지하면 긴 언어(es)에서 라벨이 0 폭이 되어
// 한 글자씩 줄바꿈된다(10/8 r11 「Mis POP」). 넘치면 둘 다 단어 단위로 줄바꿈한다.
Widget row(String label, Widget value) => Padding(
padding: const EdgeInsets.symmetric(vertical: AppSpace.s2),
child: Row(
children: [
Expanded(flex: 2, child: Text(label, style: _label)),
const SizedBox(width: AppSpace.s2),
Flexible(
flex: 3,
child: Align(alignment: Alignment.centerRight, child: value),
),
],
),
);
Text text(String s) => Text(s, style: _value, textAlign: TextAlign.end);
return Container(
padding: const EdgeInsets.symmetric(
horizontal: AppSpace.s4,
vertical: AppSpace.s2,
),
decoration: BoxDecoration(
color: AppColors.cosmicSurfaceContainer,
borderRadius: BorderRadius.circular(AppRadius.lg),
border: Border.all(color: AppColors.cosmicOutline),
),
child: Column(
children: [
row(
l10n.homeWeeklyRank,
Row(
mainAxisSize: MainAxisSize.min,
children: [
text(w.rank == null ? '—' : l10n.homeWeeklyRankValue('${w.rank}')),
if (change != null && change != 0) ...[
const SizedBox(width: AppSpace.s1),
Text(
'${change > 0 ? '▲' : '▼'}${change.abs()}',
style: _value.copyWith(
fontSize: 12,
color: change > 0
? AppColors.cosmicAccent
: AppColors.cosmicBlue,
),
),
],
],
),
),
// 두 축 각각 — 단일 백분율로 합치지 않는다(§3 4번).
row(
l10n.homeWeeklyGrowth,
text(
'${w.weekGrowthPop == null ? '—' : _signed(w.weekGrowthPop!)} POP · '
'${w.weekSfpi == null ? '—' : _signed(w.weekSfpi!)} sFPI',
),
),
row(
l10n.homeWeeklyMine,
text(
'${w.myWeekPop == null ? '—' : formatPop(w.myWeekPop!.round())} POP'
'${w.myShare == null ? '' : ' · ${(w.myShare! * 100).toStringAsFixed(1)}%'}',
),
),
row(
l10n.homeWeeklyBalance,
text(
'${l10n.popKindGeneral} ${formatPop(w.generalPop)} · '
'${l10n.popKindContribution} ${formatPop(w.supportPop)}',
),
),
],
),
);
}
}