import 'package:flutter/material.dart'; import 'package:asciineverdie/l10n/app_localizations.dart'; import 'package:asciineverdie/src/core/l10n/game_data_l10n.dart'; import 'package:asciineverdie/src/core/model/game_state.dart'; import 'package:asciineverdie/src/features/game/widgets/stats_panel.dart'; /// 캐릭터시트 페이지 (캐로셀 - 기본 페이지) /// /// 트레잇, 스탯, 경험치 표시. class CharacterSheetPage extends StatelessWidget { const CharacterSheetPage({ super.key, required this.traits, required this.stats, required this.exp, }); final Traits traits; final Stats stats; final ProgressBarState exp; @override Widget build(BuildContext context) { final localizations = L10n.of(context); return SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // 트레잇 _buildSectionHeader(context, localizations.traits), _buildTraitsList(context), // 스탯 _buildSectionHeader(context, localizations.stats), StatsPanel(stats: stats), // 경험치 _buildSectionHeader(context, localizations.experience), _buildExpBar(context), ], ), ); } Widget _buildSectionHeader(BuildContext context, String title) { return Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), color: Theme.of(context).colorScheme.primaryContainer, child: Text( title, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 13, color: Theme.of(context).colorScheme.onPrimaryContainer, ), ), ); } Widget _buildTraitsList(BuildContext context) { final localizations = L10n.of(context); final traitData = [ (localizations.traitName, traits.name), (localizations.traitRace, GameDataL10n.getRaceName(context, traits.race)), ( localizations.traitClass, GameDataL10n.getKlassName(context, traits.klass), ), (localizations.traitLevel, '${traits.level}'), ]; return Padding( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), child: Column( children: traitData.map((t) { return Padding( padding: const EdgeInsets.symmetric(vertical: 2), child: Row( children: [ SizedBox( width: 60, child: Text( t.$1, style: TextStyle(fontSize: 12, color: Colors.grey.shade600), ), ), Expanded( child: Text( t.$2, style: const TextStyle( fontSize: 13, fontWeight: FontWeight.bold, ), overflow: TextOverflow.ellipsis, ), ), ], ), ); }).toList(), ), ); } Widget _buildExpBar(BuildContext context) { final progress = exp.max > 0 ? (exp.position / exp.max).clamp(0.0, 1.0) : 0.0; return Padding( padding: const EdgeInsets.all(12), child: Column( children: [ LinearProgressIndicator( value: progress, backgroundColor: Colors.blue.withValues(alpha: 0.2), valueColor: const AlwaysStoppedAnimation(Colors.blue), minHeight: 12, ), const SizedBox(height: 4), Text( '${exp.position} / ${exp.max}', style: TextStyle(fontSize: 10, color: Colors.grey.shade600), ), ], ), ); } }