import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; class OnboardingDialog extends StatefulWidget { final VoidCallback onFinish; final List>? pages; // Optional content const OnboardingDialog({super.key, required this.onFinish, this.pages}); @override State createState() => _OnboardingDialogState(); } class _OnboardingDialogState extends State { final PageController _controller = PageController(); int _currentPage = 0; late final List> _pages; @override void initState() { super.initState(); _pages = widget.pages ?? [ { 'title': '日本酒の『魂』を保存する', 'description': 'Ponshu Roomへようこそ。\n飲んだ日本酒のラベルを撮影するだけで、\nAIが情報を解析し、あなたのリストに加えます。', 'icon': '🍶', }, { 'title': 'ラベルを撮るだけ', 'description': '面倒な入力は不要です。\nラベルの写真を撮れば、銘柄、蔵元、味わいまで\nAIが自動でデータベース化します。', 'icon': '📸', }, { 'title': 'あなただけのお品書き', 'description': '集めたコレクションから、\nボタンひとつで美しいお品書きPDFを作成。\n飲食店の方も、個人の方も楽しめます。', 'icon': '📜', }, { 'title': 'さあ、始めましょう', 'description': 'AIの力で、日本酒ライフをもっと豊かに。\n右下のカメラボタンからスタートしてください。', 'icon': '✨', }, ]; } @override Widget build(BuildContext context) { return Dialog( backgroundColor: Colors.transparent, // Custom shape insetPadding: const EdgeInsets.all(20), child: Container( height: 500, decoration: BoxDecoration( color: Theme.of(context).scaffoldBackgroundColor, borderRadius: BorderRadius.circular(24), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.3), blurRadius: 20, offset: const Offset(0, 10), ) ], ), child: Column( children: [ Expanded( child: PageView.builder( controller: _controller, onPageChanged: (index) => setState(() => _currentPage = index), itemCount: _pages.length, itemBuilder: (context, index) { final page = _pages[index]; return Center( child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(32.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( page['icon']!, style: const TextStyle(fontSize: 80), ), const SizedBox(height: 32), Text( page['title']!, textAlign: TextAlign.center, style: GoogleFonts.zenOldMincho( fontSize: 24, fontWeight: FontWeight.bold, color: Theme.of(context).textTheme.bodyLarge?.color, ), ), const SizedBox(height: 16), Text( page['description']!, textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyMedium?.copyWith( height: 1.6, color: Colors.grey, ), ), ], ), ), ), ); }, ), ), // Indicators Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate(_pages.length, (index) { return AnimatedContainer( duration: const Duration(milliseconds: 300), margin: const EdgeInsets.symmetric(horizontal: 4), height: 8, width: _currentPage == index ? 24 : 8, decoration: BoxDecoration( color: _currentPage == index ? Theme.of(context).primaryColor : Colors.grey[300], borderRadius: BorderRadius.circular(4), ), ); }), ), const SizedBox(height: 24), // Button Padding( padding: const EdgeInsets.symmetric(horizontal: 32.0, vertical: 24.0), child: SizedBox( width: double.infinity, height: 50, child: ElevatedButton( style: ElevatedButton.styleFrom( elevation: 0, backgroundColor: Theme.of(context).primaryColor, foregroundColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), ), onPressed: () { if (_currentPage < _pages.length - 1) { _controller.nextPage( duration: const Duration(milliseconds: 300), curve: Curves.easeIn, ); } else { widget.onFinish(); } }, child: Text( _currentPage < _pages.length - 1 ? '次へ' : 'はじめる', style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16), ), ), ), ), ], ), ), ); } }