Files
customer-im-client-dev/apps/im_app/lib/features/login/view/login_page.dart
2026-03-09 19:05:55 +08:00

76 lines
2.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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';
/// 登录页 — 两步流程:手机号 → 验证码
///
/// 步骤 1 [LoginStep.phone][LoginPhoneStep] — 输入国家代码 + 手机号
/// 步骤 2 [LoginStep.otp][LoginOtpStep] — 输入验证码完成登录
///
/// 页面本身只持有两个 TextEditingController 和三个回调方法,
/// 具体 UI 由 widgets/ 下的子组件负责。
class LoginPage extends ConsumerStatefulWidget {
const LoginPage({super.key});
@override
ConsumerState<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends ConsumerState<LoginPage> {
// demo 预填,上线前去掉
final _phoneCtrl = TextEditingController(text: '83465308');
final _otpCtrl = TextEditingController(text: '0000');
@override
void dispose() {
_phoneCtrl.dispose();
_otpCtrl.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 _backToPhone() {
_otpCtrl.clear();
ref.read(loginViewModelProvider.notifier).backToPhone();
}
@override
Widget build(BuildContext context) {
final state = ref.watch(loginViewModelProvider);
return Scaffold(
appBar: AppBar(automaticallyImplyLeading: false, title: const Text('登录')),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 32),
child: state.step == LoginStep.phone
? LoginPhoneStep(
phoneCtrl: _phoneCtrl,
state: state,
onSendOtp: () => _sendOtp(state),
)
: LoginOtpStep(
otpCtrl: _otpCtrl,
state: state,
onVerifyAndLogin: _verifyAndLogin,
onBackToPhone: _backToPhone,
),
),
);
}
}