Files
ttstd_family_care/lib/page/register_page.dart

389 lines
14 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/cupertino.dart';
import 'package:get/get.dart';
class RegisterPage extends StatefulWidget {
const RegisterPage({super.key});
@override
State<RegisterPage> createState() => _RegisterPageState();
}
class _RegisterPageState extends State<RegisterPage> {
final _formKey = GlobalKey<FormState>();
final _phoneController = TextEditingController();
final _smsCodeController = TextEditingController();
final _passwordController = TextEditingController();
final _confirmPasswordController = TextEditingController();
bool _isLoading = false;
bool _isCountdownRunning = false;
int _countdownSeconds = 0;
bool _obscurePassword = true;
bool _obscureConfirmPassword = true;
@override
void dispose() {
_phoneController.dispose();
_smsCodeController.dispose();
_passwordController.dispose();
_confirmPasswordController.dispose();
super.dispose();
}
Future<void> _sendSmsCode() async {
if (_phoneController.text.isEmpty) {
showCupertinoDialog(
context: context,
builder: (context) => CupertinoAlertDialog(
title: const Text('提示'),
content: const Text('请先输入手机号'),
actions: [
CupertinoDialogAction(
child: const Text('确定'),
onPressed: () => Navigator.pop(context),
),
],
),
);
return;
}
setState(() {
_isCountdownRunning = true;
_countdownSeconds = 60;
});
await Future.delayed(const Duration(seconds: 1));
while (_countdownSeconds > 0 && mounted) {
await Future.delayed(const Duration(seconds: 1));
setState(() {
_countdownSeconds--;
});
}
if (mounted) {
setState(() {
_isCountdownRunning = false;
});
}
if (mounted) {
showCupertinoDialog(
context: context,
builder: (context) => CupertinoAlertDialog(
title: const Text('验证码已发送'),
content: const Text('请输入收到的6位验证码'),
actions: [
CupertinoDialogAction(
child: const Text('确定'),
onPressed: () => Navigator.pop(context),
),
],
),
);
}
}
Future<void> _handleRegister() async {
if (!_formKey.currentState!.validate()) {
return;
}
setState(() {
_isLoading = true;
});
await Future.delayed(const Duration(seconds: 1));
setState(() {
_isLoading = false;
});
if (mounted) {
showCupertinoDialog(
context: context,
builder: (context) => CupertinoAlertDialog(
title: const Text('注册成功'),
content: const Text('欢迎加入!'),
actions: [
CupertinoDialogAction(
isDefaultAction: true,
child: const Text('确定'),
onPressed: () {
Navigator.pop(context);
Navigator.pop(context);
},
),
],
),
);
}
}
@override
Widget build(BuildContext context) {
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: const Text('注册'),
trailing: CupertinoButton(
padding: EdgeInsets.zero,
onPressed: () {
Get.offAndToNamed('/login');
},
child: const Text('取消'),
),
),
child: SafeArea(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24.0),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 32),
const Icon(
CupertinoIcons.person_2_fill,
size: 80,
color: CupertinoColors.activeGreen,
),
const SizedBox(height: 24),
const Text(
'创建新账户',
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
Text(
'使用手机号快速注册',
style: TextStyle(
fontSize: 16,
color: CupertinoColors.inactiveGray,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 40),
CupertinoFormSection.insetGrouped(
header: const Text('手机号'),
children: [
CupertinoTextFormFieldRow(
controller: _phoneController,
keyboardType: TextInputType.phone,
prefix: const Padding(
padding: EdgeInsets.only(left: 8),
child: Icon(CupertinoIcons.phone, size: 20),
),
placeholder: '请输入11位手机号',
validator: (value) {
if (value == null || value.isEmpty) {
return '请输入手机号';
}
if (value.length != 11) {
return '请输入有效的手机号';
}
return null;
},
),
],
),
const SizedBox(height: 16),
Row(
children: [
Expanded(
child: CupertinoFormSection.insetGrouped(
header: const Text('验证码'),
children: [
CupertinoTextFormFieldRow(
controller: _smsCodeController,
keyboardType: TextInputType.number,
prefix: const Padding(
padding: EdgeInsets.only(left: 8),
child: Icon(CupertinoIcons.shield, size: 20),
),
placeholder: '6位验证码',
validator: (value) {
if (value == null || value.isEmpty) {
return '请输入验证码';
}
if (value.length != 6) {
return '验证码为6位';
}
return null;
},
),
],
),
),
const SizedBox(width: 12),
Padding(
padding: const EdgeInsets.only(top: 30),
child: SizedBox(
width: 120,
height: 50,
child: CupertinoButton.filled(
onPressed: _isCountdownRunning ? null : _sendSmsCode,
borderRadius: BorderRadius.circular(12),
padding: EdgeInsets.zero,
child: Text(
_isCountdownRunning ? '${_countdownSeconds}s' : '获取验证码',
style: const TextStyle(fontSize: 14),
),
),
),
),
],
),
const SizedBox(height: 16),
CupertinoFormSection.insetGrouped(
header: const Text('设置密码'),
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
Expanded(
child: CupertinoTextFormFieldRow(
controller: _passwordController,
obscureText: _obscurePassword,
prefix: const Padding(
padding: EdgeInsets.only(left: 8),
child: Icon(CupertinoIcons.lock, size: 20),
),
placeholder: '请设置密码至少6位',
validator: (value) {
if (value == null || value.isEmpty) {
return '请输入密码';
}
if (value.length < 6) {
return '密码至少6位';
}
return null;
},
),
),
CupertinoButton(
padding: const EdgeInsets.only(left: 8),
onPressed: () {
setState(() {
_obscurePassword = !_obscurePassword;
});
},
child: Icon(
_obscurePassword
? CupertinoIcons.eye_slash
: CupertinoIcons.eye,
size: 20,
color: CupertinoColors.inactiveGray,
),
),
],
),
),
],
),
const SizedBox(height: 16),
CupertinoFormSection.insetGrouped(
header: const Text('确认密码'),
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
Expanded(
child: CupertinoTextFormFieldRow(
controller: _confirmPasswordController,
obscureText: _obscureConfirmPassword,
prefix: const Padding(
padding: EdgeInsets.only(left: 8),
child: Icon(CupertinoIcons.lock_shield, size: 20),
),
placeholder: '请再次输入密码',
validator: (value) {
if (value == null || value.isEmpty) {
return '请确认密码';
}
if (value != _passwordController.text) {
return '两次输入的密码不一致';
}
return null;
},
),
),
CupertinoButton(
padding: const EdgeInsets.only(left: 8),
onPressed: () {
setState(() {
_obscureConfirmPassword = !_obscureConfirmPassword;
});
},
child: Icon(
_obscureConfirmPassword
? CupertinoIcons.eye_slash
: CupertinoIcons.eye,
size: 20,
color: CupertinoColors.inactiveGray,
),
),
],
),
),
],
),
const SizedBox(height: 32),
CupertinoButton.filled(
onPressed: _isLoading ? null : _handleRegister,
padding: const EdgeInsets.symmetric(vertical: 16),
borderRadius: BorderRadius.circular(12),
child: _isLoading
? const SizedBox(
height: 20,
width: 20,
child: CupertinoActivityIndicator(
radius: 10,
),
)
: const Text(
'立即注册',
style: TextStyle(fontSize: 17),
),
),
const SizedBox(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'已有账户?',
style: TextStyle(
color: CupertinoColors.inactiveGray,
),
),
CupertinoButton(
padding: EdgeInsets.zero,
onPressed: () {
Get.offAndToNamed('/login');
},
child: const Text('立即登录'),
),
],
),
const SizedBox(height: 16),
Text(
'注册即表示您同意我们的服务条款和隐私政策',
style: TextStyle(
fontSize: 12,
color: CupertinoColors.inactiveGray,
),
textAlign: TextAlign.center,
),
],
),
),
),
),
);
}
}