생성 때 고른 행성 형태·색 표시 · HOME 주간 정보
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
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).
|
||||
///
|
||||
/// 🟡 **배치는 임시다.** 기준 화면 「REFINE v5A · HOME · Default」 를 아직 실측하지 못해(당사 사본에
|
||||
/// 없고 원본 파일은 로그인 필요) 정보 위계 v1.0 §7 「프레임 실측과 무관하게 반드시 포함」에 따라
|
||||
/// 값만 먼저 싣는다. 자리 · 모양은 해석 확인 요청 영역A 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;
|
||||
Widget row(String label, Widget value) => Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: AppSpace.s2),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: Text(label, style: _label)),
|
||||
value,
|
||||
],
|
||||
),
|
||||
);
|
||||
Text text(String s) => Text(s, style: _value);
|
||||
|
||||
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)}',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user