187 lines
7.3 KiB
Dart
187 lines
7.3 KiB
Dart
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(),
|
||
),
|
||
);
|
||
}
|
||
}
|