ponshu-room-lite/lib/screens/guide_screen.dart

187 lines
7.3 KiB
Dart
Raw Permalink Normal View History

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lucide_icons/lucide_icons.dart';
class GuideScreen extends ConsumerWidget {
const GuideScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: AppBar(
title: const Text('ガイド・ヘルプ'),
centerTitle: true,
),
body: ListView(
padding: const EdgeInsets.all(16.0),
children: [
_buildSectionHeader(context, 'レベルと称号', LucideIcons.trophy),
_buildCard(
context,
children: [
_buildGuideItem(context, 'レベルの上げ方', '日本酒を1本登録するごとに 10 EXP 獲得できます。\nメニューを作成するとボーナスが入ることも!'),
const Divider(),
_buildGuideItem(context, '称号一覧', '獲得したEXPに応じて称号が変わります。'),
_buildLevelTable(context),
],
),
const SizedBox(height: 24),
_buildSectionHeader(context, 'バッジコレクション', LucideIcons.medal),
_buildCard(
context,
children: [
_buildBadgeGuide(context, '👹 東北制覇', '「青森・岩手・宮城・秋田・山形・福島」すべての県の日本酒を登録する', '条件: 6県制覇'),
const Divider(),
_buildBadgeGuide(context, '🌶️ 辛口党', '日本酒度が「+5」以上の辛口酒を10本登録する', '条件: 10本登録'),
const Divider(),
_buildBadgeGuide(context, '🍶 初めての一歩', '最初の日本酒を登録する', '条件: 1本登録'),
],
),
const SizedBox(height: 24),
_buildSectionHeader(context, 'AIソムリエ', LucideIcons.sparkles),
_buildCard(
context,
children: [
_buildGuideItem(context, '酒向タイプ診断', 'あなたが登録した日本酒の味覚データ甘辛、酸度などをAIが分析し、あなたの好みの傾向をチャート化します。'),
const Divider(),
_buildGuideItem(context, 'チャートの見方', '• 華やか: 香りが高い\n• 芳醇: コク・旨味が強い\n• 重厚: 苦味やボディ感\n• 穏やか: アルコール感が控えめ'),
],
),
],
),
);
}
Widget _buildSectionHeader(BuildContext context, String title, IconData icon) {
return Padding(
padding: const EdgeInsets.only(bottom: 12.0, left: 4.0),
child: Row(
children: [
// Use secondary color for section headers (warm accent)
Icon(icon, color: Theme.of(context).colorScheme.secondary),
const SizedBox(width: 8),
Text(
title,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
color: Theme.of(context).colorScheme.secondary,
),
),
],
),
);
}
Widget _buildCard(BuildContext context, {required List<Widget> children}) {
return Card(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
side: BorderSide(color: Theme.of(context).dividerColor.withValues(alpha: 0.5)),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: children,
),
),
);
}
Widget _buildGuideItem(BuildContext context, String title, String content) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
// Force White in Dark Mode
color: Theme.of(context).brightness == Brightness.dark ? Colors.white : null,
),
),
const SizedBox(height: 4),
Text(content, style: Theme.of(context).textTheme.bodyMedium?.copyWith(height: 1.5)),
],
),
);
}
Widget _buildBadgeGuide(BuildContext context, String emojiAndName, String desc, String condition) {
return ListTile(
contentPadding: EdgeInsets.zero,
title: Text(
emojiAndName,
style: Theme.of(context).textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.bold,
color: Theme.of(context).brightness == Brightness.dark ? Colors.white : null,
),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(desc, style: Theme.of(context).textTheme.bodyMedium),
const SizedBox(height: 4),
Text(
condition,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).primaryColor,
),
),
],
),
);
}
Widget _buildLevelTable(BuildContext context) {
// Manually recreating table from LevelCalculator concepts since _levelTable is private.
// Ideally LevelCalculator exposes the table, but hardcoding for display is safer than reflection for now.
const levels = [
{'level': 1, 'exp': 0, 'title': '見習い'},
{'level': 2, 'exp': 10, 'title': '歩き飲み'},
{'level': 5, 'exp': 50, 'title': '嗜み人'},
{'level': 10, 'exp': 100, 'title': '呑兵衛'},
{'level': 20, 'exp': 200, 'title': '酒豪'},
{'level': 30, 'exp': 300, 'title': '利き酒師'},
{'level': 50, 'exp': 500, 'title': '日本酒伝道師'},
{'level': 100, 'exp': 1000, 'title': 'ポンシュマスター'},
];
return Container(
margin: const EdgeInsets.only(top: 12),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surfaceContainerHighest.withValues(alpha: 0.3),
borderRadius: BorderRadius.circular(8),
),
child: DataTable(
headingRowHeight: 40,
dataRowMinHeight: 36,
dataRowMaxHeight: 36,
columnSpacing: 20,
columns: [
DataColumn(label: Text('Lv', style: Theme.of(context).textTheme.bodySmall?.copyWith(color: Theme.of(context).brightness == Brightness.dark ? Colors.white70 : null))),
DataColumn(label: Text('必要EXP', style: Theme.of(context).textTheme.bodySmall?.copyWith(color: Theme.of(context).brightness == Brightness.dark ? Colors.white70 : null))),
DataColumn(label: Text('称号', style: Theme.of(context).textTheme.bodySmall?.copyWith(color: Theme.of(context).brightness == Brightness.dark ? Colors.white70 : null))),
],
rows: levels.map((e) {
return DataRow(cells: [
DataCell(Text('${e['level']}', style: Theme.of(context).textTheme.bodyMedium)),
DataCell(Text('${e['exp']}', style: Theme.of(context).textTheme.bodyMedium)),
DataCell(Text(
'${e['title']}',
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontWeight: FontWeight.bold,
color: Theme.of(context).brightness == Brightness.dark ? Colors.white : null,
),
)),
]);
}).toList(),
),
);
}
}