import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:im_app/features/login/presentation/login_state.dart'; import 'package:im_app/features/login/presentation/login_view_model.dart'; import 'package:im_app/features/login/view/widgets/login_otp_step.dart'; import 'package:im_app/features/login/view/widgets/login_phone_step.dart'; import 'package:im_app/features/login/view/widgets/login_secondary_passcode_step.dart'; /// 登录页 — 两步流程:手机号 → 验证码 /// /// 步骤 1 [LoginStep.phone]:[LoginPhoneStep] — 输入国家代码 + 手机号 /// 步骤 2 [LoginStep.otp]:[LoginOtpStep] — 输入验证码完成登录 /// /// 页面本身只持有两个 TextEditingController 和三个回调方法, /// 具体 UI 由 widgets/ 下的子组件负责。 class LoginPage extends ConsumerStatefulWidget { const LoginPage({super.key}); @override ConsumerState createState() => _LoginPageState(); } class _LoginPageState extends ConsumerState { // demo 预填,上线前去掉 final _phoneCtrl = TextEditingController(text: '83465308'); final _otpCtrl = TextEditingController(text: '0000'); final _passcodeCtrl = TextEditingController(); @override void dispose() { _phoneCtrl.dispose(); _otpCtrl.dispose(); _passcodeCtrl.dispose(); super.dispose(); } void _sendOtp(LoginState state) { ref .read(loginViewModelProvider.notifier) .sendOtp(state.countryCode, _phoneCtrl.text.trim()); } void _verifyAndLogin() { ref .read(loginViewModelProvider.notifier) .verifyAndLogin(_otpCtrl.text.trim()); } void _verifyPasscode() { ref .read(loginViewModelProvider.notifier) .verifyPasscode(_passcodeCtrl.text); } void _backToPhone() { _otpCtrl.clear(); _passcodeCtrl.clear(); ref.read(loginViewModelProvider.notifier).backToPhone(); } @override Widget build(BuildContext context) { final state = ref.watch(loginViewModelProvider); Widget body; switch (state.step) { case LoginStep.phone: body = LoginPhoneStep( phoneCtrl: _phoneCtrl, state: state, onSendOtp: () => _sendOtp(state), ); case LoginStep.otp: body = LoginOtpStep( otpCtrl: _otpCtrl, state: state, onVerifyAndLogin: _verifyAndLogin, onBackToPhone: _backToPhone, ); case LoginStep.secondaryPasscode: body = LoginSecondaryPasscodeStep( passcodeCtrl: _passcodeCtrl, state: state, onVerifyPasscode: _verifyPasscode, onBackToPhone: _backToPhone, ); } return Scaffold( appBar: AppBar(automaticallyImplyLeading: false, title: const Text('登录')), body: Padding( padding: const EdgeInsets.symmetric(horizontal: 32), child: SingleChildScrollView(child: body), ), ); } }