This commit is contained in:
sion
2026-04-21 08:12:17 +08:00
parent 5264043c21
commit 685202dd55
247 changed files with 18661 additions and 0 deletions

View File

@@ -0,0 +1,129 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../../core/network/dio_client.dart';
import '../../../core/theme/app_theme.dart';
import '../../components/material_input.dart';
class ChangePasswordPage extends StatefulWidget {
const ChangePasswordPage({super.key});
@override
State<ChangePasswordPage> createState() => _ChangePasswordPageState();
}
class _ChangePasswordPageState extends State<ChangePasswordPage> {
final _formKey = GlobalKey<FormState>();
final _oldPasswordController = TextEditingController();
final _newPasswordController = TextEditingController();
final _confirmPasswordController = TextEditingController();
bool _loading = false;
@override
void dispose() {
_oldPasswordController.dispose();
_newPasswordController.dispose();
_confirmPasswordController.dispose();
super.dispose();
}
Future<void> _handleSubmit() async {
if (!_formKey.currentState!.validate()) return;
setState(() => _loading = true);
try {
final dio = context.read<DioClient>();
final response = await dio.post('/api/user/change-password', data: {
'oldPassword': _oldPasswordController.text,
'newPassword': _newPasswordController.text,
});
if (!mounted) return;
if (response.success) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('密碼修改成功')),
);
Navigator.of(context).pop();
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(response.message ?? '修改失敗')),
);
}
} catch (e) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('網絡錯誤:$e')),
);
} finally {
if (mounted) setState(() => _loading = false);
}
}
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Scaffold(
appBar: AppBar(
title: const Text('修改密碼'),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
MaterialInput(
controller: _oldPasswordController,
labelText: '當前密碼',
obscureText: true,
validator: (v) =>
(v == null || v.isEmpty) ? '請輸入當前密碼' : null,
),
const SizedBox(height: 16),
MaterialInput(
controller: _newPasswordController,
labelText: '新密碼',
obscureText: true,
validator: (v) {
if (v == null || v.isEmpty) return '請輸入新密碼';
if (v.length < 6) return '密碼長度不能少於6位';
return null;
},
),
const SizedBox(height: 16),
MaterialInput(
controller: _confirmPasswordController,
labelText: '確認新密碼',
obscureText: true,
validator: (v) {
if (v == null || v.isEmpty) return '請確認新密碼';
if (v != _newPasswordController.text) return '兩次密碼不一致';
return null;
},
),
const SizedBox(height: 32),
FilledButton(
onPressed: _loading ? null : _handleSubmit,
style: FilledButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 14),
),
child: _loading
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
strokeWidth: 2, color: Colors.white),
)
: const Text('確認修改'),
),
],
),
),
),
);
}
}