import 'package:flutter/material.dart'; import 'login_page.dart'; class NewResidentStepPage extends StatefulWidget { const NewResidentStepPage({super.key}); @override State createState() => _NewResidentStepPageState(); } class _NewResidentStepPageState extends State { int currentStep = 1; final TextEditingController _emailController = TextEditingController(); final List _codeControllers = List.generate( 6, (_) => TextEditingController(), ); String? statusMessage; bool isSuccess = false; void sendVerification() { final email = _emailController.text.trim(); if (email.contains("@")) { setState(() { isSuccess = true; statusMessage = '📧 驗證碼已寄出至 $email'; currentStep = 2; }); } else { setState(() { isSuccess = false; statusMessage = '❌ 請輸入有效的 Email'; }); } } void verifyCode() { final code = _codeControllers.map((c) => c.text).join(); if (RegExp(r'^\d{6}$').hasMatch(code)) { setState(() { isSuccess = true; statusMessage = '✅ 驗證成功!'; currentStep = 3; }); } else { setState(() { isSuccess = false; statusMessage = '❌ 請輸入正確的 6 位數驗證碼'; }); } } Widget buildStep1() { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Text( '步驟 1 之 3', textAlign: TextAlign.center, style: TextStyle(fontSize: 14, color: Colors.grey), ), const SizedBox(height: 10), const Text( '輸入電子郵件', textAlign: TextAlign.center, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 24), TextField( controller: _emailController, keyboardType: TextInputType.emailAddress, decoration: const InputDecoration( labelText: '電子郵件', border: OutlineInputBorder(), hintText: 'example@mail.com', ), ), const SizedBox(height: 20), ElevatedButton( onPressed: sendVerification, style: ElevatedButton.styleFrom(backgroundColor: Colors.indigo), child: const Text('發送驗證碼', style: TextStyle(color: Colors.white)), ), ], ); } Widget buildStep2() { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Text( '步驟 2 之 3', textAlign: TextAlign.center, style: TextStyle(fontSize: 14, color: Colors.grey), ), const SizedBox(height: 10), const Text( '請輸入驗證碼', textAlign: TextAlign.center, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 10), const Text( '我們已將 6 位數驗證碼寄至您的 Email', textAlign: TextAlign.center, style: TextStyle(color: Colors.grey), ), const SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate(6, (i) { return Container( width: 40, margin: const EdgeInsets.symmetric(horizontal: 4), child: TextField( controller: _codeControllers[i], maxLength: 1, textAlign: TextAlign.center, keyboardType: TextInputType.number, decoration: const InputDecoration(counterText: ''), onChanged: (val) { if (val.length == 1 && i < 5) { FocusScope.of(context).nextFocus(); } }, ), ); }), ), const SizedBox(height: 20), ElevatedButton( onPressed: verifyCode, style: ElevatedButton.styleFrom(backgroundColor: Colors.indigo), child: const Text('驗證並繼續', style: TextStyle(color: Colors.white)), ), TextButton( onPressed: () { setState(() { statusMessage = '📨 驗證碼已重新寄出,請再次查收 Email。'; }); }, child: const Text('重新發送驗證碼'), ), ], ); } // 在 State 裡新增這些 controller 和變數: final nameController = TextEditingController(); final birthdayController = TextEditingController(); final phoneController = TextEditingController(); final roomController = TextEditingController(); final plateController = TextEditingController(); final passwordController = TextEditingController(); final confirmPasswordController = TextEditingController(); String? selectedGender; // 表單驗證 function bool validateStep3Fields() { return true; /* nameController.text.isNotEmpty && selectedGender != null && birthdayController.text.isNotEmpty && phoneController.text.isNotEmpty && roomController.text.isNotEmpty && plateController.text.isNotEmpty && passwordController.text.isNotEmpty && confirmPasswordController.text.isNotEmpty && passwordController.text == confirmPasswordController.text; */ } // buildStep3 widget Widget buildStep3() { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const Text( '步驟 3 之 3', textAlign: TextAlign.center, style: TextStyle(fontSize: 14, color: Colors.grey), ), const SizedBox(height: 10), const Text( '填寫基本資料', textAlign: TextAlign.center, style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), const SizedBox(height: 10), const Text( '請輸入您的基本資訊以完成註冊', textAlign: TextAlign.center, style: TextStyle(color: Colors.grey), ), const SizedBox(height: 20), TextField( controller: nameController, decoration: const InputDecoration( labelText: '姓名', border: OutlineInputBorder(), ), ), const SizedBox(height: 16), DropdownButtonFormField( value: selectedGender, items: const [ DropdownMenuItem(value: '男', child: Text('男')), DropdownMenuItem(value: '女', child: Text('女')), DropdownMenuItem(value: '其他', child: Text('其他')), ], onChanged: (value) { setState(() { selectedGender = value; }); }, decoration: const InputDecoration( labelText: '性別', border: OutlineInputBorder(), ), ), const SizedBox(height: 16), TextField( controller: birthdayController, decoration: const InputDecoration( labelText: '生日', hintText: 'YYYY-MM-DD', border: OutlineInputBorder(), ), keyboardType: TextInputType.datetime, ), const SizedBox(height: 16), TextField( controller: phoneController, decoration: const InputDecoration( labelText: '手機號碼', hintText: '例如:0912345678', border: OutlineInputBorder(), ), keyboardType: TextInputType.phone, ), const SizedBox(height: 16), TextField( controller: roomController, decoration: const InputDecoration( labelText: '房號 / 室別', hintText: '例如:A棟 5F-2', border: OutlineInputBorder(), ), ), const SizedBox(height: 16), TextField( controller: plateController, decoration: const InputDecoration( labelText: '車牌號碼', hintText: '例如:ABC-1234', border: OutlineInputBorder(), ), ), const SizedBox(height: 16), TextField( controller: passwordController, obscureText: true, decoration: const InputDecoration( labelText: '密碼', border: OutlineInputBorder(), ), ), const SizedBox(height: 16), TextField( controller: confirmPasswordController, obscureText: true, decoration: const InputDecoration( labelText: '確認密碼', border: OutlineInputBorder(), ), ), const SizedBox(height: 24), ElevatedButton( onPressed: () { if (validateStep3Fields()) { setState(() { currentStep = 4; statusMessage = null; isSuccess = true; }); ScaffoldMessenger.of( context, ).showSnackBar(const SnackBar(content: Text('✅ 註冊完成!歡迎加入社區!'))); } else { setState(() { isSuccess = false; statusMessage = '❌ 請完整填寫所有欄位,並確認密碼一致'; }); } }, style: ElevatedButton.styleFrom(backgroundColor: Colors.green), child: const Text('完成註冊', style: TextStyle(color: Colors.white)), ), ], ); } Widget buildStep4() { return Column( children: [ // Body content Padding( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), child: Column( mainAxisSize: MainAxisSize.min, // 讓 Column 的高度根據內容來調整 crossAxisAlignment: CrossAxisAlignment.center, children: [ const Text( '親愛的用戶您好', style: TextStyle( fontSize: 22, fontWeight: FontWeight.w600, color: Color(0xFF333333), ), ), const SizedBox(height: 20), const Text( '您的新用戶申請已送至管理室,請您拿手機至管理室由管理員掃描開通。', style: TextStyle(fontSize: 16, color: Color(0xFF666666)), textAlign: TextAlign.center, ), const SizedBox(height: 40), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () { setState(() { currentStep = 5; statusMessage = null; isSuccess = true; }); }, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF4CAF50), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(24), ), padding: const EdgeInsets.symmetric(vertical: 12), ), child: const Text( '掃描開通', style: TextStyle(fontSize: 16, color: Colors.white), ), ), ), ], ), ), ], ); } Widget buildStep5() { return Column( children: [ // Body content Padding( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), child: Column( mainAxisSize: MainAxisSize.min, // 讓 Column 的高度根據內容來調整 crossAxisAlignment: CrossAxisAlignment.center, children: [ const Text( '掃描QR Code 來開通', style: TextStyle( fontSize: 22, fontWeight: FontWeight.w600, color: Color(0xFF333333), ), ), const SizedBox(height: 20), const Text( '請掃描下面的 QR Code 開通此住戶。', style: TextStyle(fontSize: 16, color: Color(0xFF666666)), textAlign: TextAlign.center, ), const SizedBox(height: 20), // 塞入QR CODE 圖片 Image.network( 'https://docs.lightburnsoftware.com/legacy/img/QRCode/ExampleCode.png', width: 200, height: 200, ), const SizedBox(height: 40), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: () { Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => const LoginPage(), ), ); }, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF4CAF50), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(24), ), padding: const EdgeInsets.symmetric(vertical: 12), ), child: const Text( '掃描完畢,返回登入介面', style: TextStyle(fontSize: 16, color: Colors.white), ), ), ), const Text( '如果無法掃描,請調整螢幕亮度。', style: TextStyle( fontSize: 14, color: Color.fromARGB(255, 129, 129, 129), ), textAlign: TextAlign.center, ), ], ), ), ], ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF7F8FA), appBar: AppBar( backgroundColor: const Color(0xFF9EAF9F), foregroundColor: Colors.white, title: const Text('新住戶註冊'), leading: currentStep > 1 ? IconButton( icon: const Icon(Icons.arrow_back), onPressed: () { setState(() { currentStep--; }); }, ) : null, ), body: Padding( padding: const EdgeInsets.all(20), child: Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: const [BoxShadow(color: Colors.black12, blurRadius: 3)], ), child: SingleChildScrollView( child: Column( children: [ buildStepContent(), const SizedBox(height: 20), if (statusMessage != null) Text( statusMessage!, textAlign: TextAlign.center, style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: isSuccess ? Colors.green : Colors.red, ), ), ], ), ), ), ), ); } Widget buildStepContent() { switch (currentStep) { case 1: return buildStep1(); case 2: return buildStep2(); case 3: return buildStep3(); case 4: return buildStep4(); case 5: return buildStep5(); default: return const Text('未知步驟'); } } }