fix(mining-app): unify color scheme and fix scroll issues

- Update login/register pages to use orange color scheme (#FF6B00)
  matching the navigation pages design
- Fix SafeArea bottom: false on all navigation pages since MainShell
  handles bottom safe area via bottomNavigationBar
- Add AlwaysScrollableScrollPhysics to asset page for consistent scroll
- Increase bottom padding to 100px on all navigation pages to clear
  the navigation bar

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-01-12 12:41:41 -08:00
parent c31d64550b
commit 94d8075970
6 changed files with 232 additions and 86 deletions

View File

@ -30,11 +30,13 @@ class AssetPage extends ConsumerWidget {
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
bottom: false,
child: RefreshIndicator(
onRefresh: () async {
ref.invalidate(shareAccountProvider(accountSequence));
},
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [
//

View File

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../../core/router/routes.dart';
import '../../../core/constants/app_colors.dart';
import '../../providers/user_providers.dart';
class LoginPage extends ConsumerStatefulWidget {
@ -13,6 +12,14 @@ class LoginPage extends ConsumerStatefulWidget {
}
class _LoginPageState extends ConsumerState<LoginPage> {
// -
static const Color _orange = Color(0xFFFF6B00);
static const Color _darkText = Color(0xFF1F2937);
static const Color _grayText = Color(0xFF6B7280);
static const Color _lightGray = Color(0xFF9CA3AF);
static const Color _bgGray = Color(0xFFF3F4F6);
static const Color _borderGray = Color(0xFFE5E7EB);
final _formKey = GlobalKey<FormState>();
final _phoneController = TextEditingController();
final _passwordController = TextEditingController();
@ -113,17 +120,19 @@ class _LoginPageState extends ConsumerState<LoginPage> {
const SizedBox(height: 60),
// Logo
Container(
Center(
child: Container(
width: 80,
height: 80,
decoration: BoxDecoration(
color: AppColors.primary.withOpacity(0.1),
color: _orange.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
),
child: const Icon(
Icons.eco,
size: 48,
color: AppColors.primary,
color: _orange,
),
),
),
@ -134,17 +143,18 @@ class _LoginPageState extends ConsumerState<LoginPage> {
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
color: _darkText,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
Text(
'登录您的榴莲挖矿账户',
const Text(
'登录您的榴莲生态账户',
style: TextStyle(
fontSize: 16,
color: Colors.grey[600],
color: _grayText,
),
textAlign: TextAlign.center,
),
@ -152,7 +162,13 @@ class _LoginPageState extends ConsumerState<LoginPage> {
const SizedBox(height: 48),
//
Row(
Container(
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(color: _borderGray, width: 1),
),
),
child: Row(
children: [
Expanded(
child: GestureDetector(
@ -162,7 +178,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: _isPasswordLogin ? AppColors.primary : Colors.transparent,
color: _isPasswordLogin ? _orange : Colors.transparent,
width: 2,
),
),
@ -173,7 +189,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
style: TextStyle(
fontSize: 16,
fontWeight: _isPasswordLogin ? FontWeight.bold : FontWeight.normal,
color: _isPasswordLogin ? AppColors.primary : Colors.grey,
color: _isPasswordLogin ? _orange : _lightGray,
),
),
),
@ -187,7 +203,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: !_isPasswordLogin ? AppColors.primary : Colors.transparent,
color: !_isPasswordLogin ? _orange : Colors.transparent,
width: 2,
),
),
@ -198,7 +214,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
style: TextStyle(
fontSize: 16,
fontWeight: !_isPasswordLogin ? FontWeight.bold : FontWeight.normal,
color: !_isPasswordLogin ? AppColors.primary : Colors.grey,
color: !_isPasswordLogin ? _orange : _lightGray,
),
),
),
@ -206,6 +222,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
),
],
),
),
const SizedBox(height: 24),
@ -213,12 +230,25 @@ class _LoginPageState extends ConsumerState<LoginPage> {
TextFormField(
controller: _phoneController,
keyboardType: TextInputType.phone,
style: const TextStyle(color: _darkText),
decoration: InputDecoration(
labelText: '手机号',
prefixIcon: const Icon(Icons.phone),
labelStyle: const TextStyle(color: _grayText),
prefixIcon: const Icon(Icons.phone_outlined, color: _grayText),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _orange, width: 2),
),
filled: true,
fillColor: Colors.white,
),
validator: (value) {
if (value == null || value.isEmpty) {
@ -238,18 +268,32 @@ class _LoginPageState extends ConsumerState<LoginPage> {
TextFormField(
controller: _passwordController,
obscureText: _obscurePassword,
style: const TextStyle(color: _darkText),
decoration: InputDecoration(
labelText: '密码',
prefixIcon: const Icon(Icons.lock),
labelStyle: const TextStyle(color: _grayText),
prefixIcon: const Icon(Icons.lock_outline, color: _grayText),
suffixIcon: IconButton(
icon: Icon(
_obscurePassword ? Icons.visibility_off : Icons.visibility,
_obscurePassword ? Icons.visibility_off_outlined : Icons.visibility_outlined,
color: _grayText,
),
onPressed: () => setState(() => _obscurePassword = !_obscurePassword),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _orange, width: 2),
),
filled: true,
fillColor: Colors.white,
),
validator: (value) {
if (value == null || value.isEmpty) {
@ -266,13 +310,26 @@ class _LoginPageState extends ConsumerState<LoginPage> {
controller: _smsCodeController,
keyboardType: TextInputType.number,
maxLength: 6,
style: const TextStyle(color: _darkText),
decoration: InputDecoration(
labelText: '验证码',
prefixIcon: const Icon(Icons.sms),
labelStyle: const TextStyle(color: _grayText),
prefixIcon: const Icon(Icons.sms_outlined, color: _grayText),
counterText: '',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _orange, width: 2),
),
filled: true,
fillColor: Colors.white,
),
validator: (value) {
if (value == null || value.isEmpty) {
@ -292,13 +349,16 @@ class _LoginPageState extends ConsumerState<LoginPage> {
child: ElevatedButton(
onPressed: _countDown > 0 ? null : _sendSmsCode,
style: ElevatedButton.styleFrom(
backgroundColor: _countDown > 0 ? _bgGray : _orange.withOpacity(0.1),
foregroundColor: _countDown > 0 ? _lightGray : _orange,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: Text(
_countDown > 0 ? '${_countDown}s' : '获取验证码',
style: const TextStyle(fontSize: 14),
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
),
),
),
@ -313,7 +373,9 @@ class _LoginPageState extends ConsumerState<LoginPage> {
child: ElevatedButton(
onPressed: userState.isLoading ? null : _login,
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.primary,
backgroundColor: _orange,
disabledBackgroundColor: _orange.withOpacity(0.5),
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
@ -346,9 +408,9 @@ class _LoginPageState extends ConsumerState<LoginPage> {
alignment: Alignment.centerRight,
child: TextButton(
onPressed: () => context.push(Routes.forgotPassword),
child: Text(
child: const Text(
'忘记密码?',
style: TextStyle(color: Colors.grey[600]),
style: TextStyle(color: _grayText),
),
),
),
@ -359,13 +421,19 @@ class _LoginPageState extends ConsumerState<LoginPage> {
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
const Text(
'还没有账号?',
style: TextStyle(color: Colors.grey[600]),
style: TextStyle(color: _grayText),
),
TextButton(
onPressed: () => context.push(Routes.register),
child: const Text('立即注册'),
child: const Text(
'立即注册',
style: TextStyle(
color: _orange,
fontWeight: FontWeight.w600,
),
),
),
],
),

View File

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../../core/router/routes.dart';
import '../../../core/constants/app_colors.dart';
import '../../providers/user_providers.dart';
class RegisterPage extends ConsumerStatefulWidget {
@ -13,6 +12,14 @@ class RegisterPage extends ConsumerStatefulWidget {
}
class _RegisterPageState extends ConsumerState<RegisterPage> {
// -
static const Color _orange = Color(0xFFFF6B00);
static const Color _darkText = Color(0xFF1F2937);
static const Color _grayText = Color(0xFF6B7280);
static const Color _lightGray = Color(0xFF9CA3AF);
static const Color _bgGray = Color(0xFFF3F4F6);
static const Color _borderGray = Color(0xFFE5E7EB);
final _formKey = GlobalKey<FormState>();
final _phoneController = TextEditingController();
final _passwordController = TextEditingController();
@ -100,7 +107,7 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
backgroundColor: Colors.transparent,
elevation: 0,
leading: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.black),
icon: const Icon(Icons.arrow_back_ios, color: _darkText),
onPressed: () => context.pop(),
),
),
@ -117,16 +124,17 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
style: TextStyle(
fontSize: 28,
fontWeight: FontWeight.bold,
color: _darkText,
),
),
const SizedBox(height: 8),
Text(
'加入榴莲挖矿,开启绿色财富之旅',
const Text(
'加入榴莲生态,开启绿色财富之旅',
style: TextStyle(
fontSize: 16,
color: Colors.grey[600],
color: _grayText,
),
),
@ -136,12 +144,25 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
TextFormField(
controller: _phoneController,
keyboardType: TextInputType.phone,
style: const TextStyle(color: _darkText),
decoration: InputDecoration(
labelText: '手机号',
prefixIcon: const Icon(Icons.phone),
labelStyle: const TextStyle(color: _grayText),
prefixIcon: const Icon(Icons.phone_outlined, color: _grayText),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _orange, width: 2),
),
filled: true,
fillColor: Colors.white,
),
validator: (value) {
if (value == null || value.isEmpty) {
@ -164,13 +185,26 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
controller: _smsCodeController,
keyboardType: TextInputType.number,
maxLength: 6,
style: const TextStyle(color: _darkText),
decoration: InputDecoration(
labelText: '验证码',
prefixIcon: const Icon(Icons.sms),
labelStyle: const TextStyle(color: _grayText),
prefixIcon: const Icon(Icons.sms_outlined, color: _grayText),
counterText: '',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _orange, width: 2),
),
filled: true,
fillColor: Colors.white,
),
validator: (value) {
if (value == null || value.isEmpty) {
@ -190,13 +224,16 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
child: ElevatedButton(
onPressed: _countDown > 0 ? null : _sendSmsCode,
style: ElevatedButton.styleFrom(
backgroundColor: _countDown > 0 ? _bgGray : _orange.withOpacity(0.1),
foregroundColor: _countDown > 0 ? _lightGray : _orange,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: Text(
_countDown > 0 ? '${_countDown}s' : '获取验证码',
style: const TextStyle(fontSize: 14),
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
),
),
),
@ -209,18 +246,32 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
TextFormField(
controller: _passwordController,
obscureText: _obscurePassword,
style: const TextStyle(color: _darkText),
decoration: InputDecoration(
labelText: '密码',
prefixIcon: const Icon(Icons.lock),
labelStyle: const TextStyle(color: _grayText),
prefixIcon: const Icon(Icons.lock_outline, color: _grayText),
suffixIcon: IconButton(
icon: Icon(
_obscurePassword ? Icons.visibility_off : Icons.visibility,
_obscurePassword ? Icons.visibility_off_outlined : Icons.visibility_outlined,
color: _grayText,
),
onPressed: () => setState(() => _obscurePassword = !_obscurePassword),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _orange, width: 2),
),
filled: true,
fillColor: Colors.white,
),
validator: (value) {
if (value == null || value.isEmpty) {
@ -239,18 +290,32 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
TextFormField(
controller: _confirmPasswordController,
obscureText: _obscureConfirmPassword,
style: const TextStyle(color: _darkText),
decoration: InputDecoration(
labelText: '确认密码',
prefixIcon: const Icon(Icons.lock_outline),
labelStyle: const TextStyle(color: _grayText),
prefixIcon: const Icon(Icons.lock_outline, color: _grayText),
suffixIcon: IconButton(
icon: Icon(
_obscureConfirmPassword ? Icons.visibility_off : Icons.visibility,
_obscureConfirmPassword ? Icons.visibility_off_outlined : Icons.visibility_outlined,
color: _grayText,
),
onPressed: () => setState(() => _obscureConfirmPassword = !_obscureConfirmPassword),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _borderGray),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: _orange, width: 2),
),
filled: true,
fillColor: Colors.white,
),
validator: (value) {
if (value == null || value.isEmpty) {
@ -271,7 +336,9 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
child: ElevatedButton(
onPressed: userState.isLoading ? null : _register,
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.primary,
backgroundColor: _orange,
disabledBackgroundColor: _orange.withOpacity(0.5),
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
@ -302,13 +369,19 @@ class _RegisterPageState extends ConsumerState<RegisterPage> {
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
const Text(
'已有账号?',
style: TextStyle(color: Colors.grey[600]),
style: TextStyle(color: _grayText),
),
TextButton(
onPressed: () => context.pop(),
child: const Text('立即登录'),
child: const Text(
'立即登录',
style: TextStyle(
color: _orange,
fontWeight: FontWeight.w600,
),
),
),
],
),

View File

@ -34,6 +34,7 @@ class ContributionPage extends ConsumerWidget {
return Scaffold(
backgroundColor: const Color(0xFFF5F5F5),
body: SafeArea(
bottom: false,
child: RefreshIndicator(
onRefresh: () async {
ref.invalidate(contributionProvider(accountSequence));
@ -67,7 +68,7 @@ class ContributionPage extends ConsumerWidget {
const SizedBox(height: 16),
//
_buildExpirationCard(contribution, recordsAsync),
const SizedBox(height: 24),
const SizedBox(height: 100),
]),
),
),

View File

@ -24,6 +24,7 @@ class ProfilePage extends ConsumerWidget {
return Scaffold(
backgroundColor: _bgGray,
body: SafeArea(
bottom: false,
child: SingleChildScrollView(
child: Column(
children: [
@ -76,7 +77,7 @@ class ProfilePage extends ConsumerWidget {
),
),
const SizedBox(height: 32),
const SizedBox(height: 100),
],
),
),

View File

@ -46,6 +46,7 @@ class _TradingPageState extends ConsumerState<TradingPage> {
return Scaffold(
backgroundColor: const Color(0xFFF5F5F5),
body: SafeArea(
bottom: false,
child: Column(
children: [
//
@ -73,7 +74,7 @@ class _TradingPageState extends ConsumerState<TradingPage> {
_buildTradingPanel(accountSequence),
//
_buildMyOrdersCard(),
const SizedBox(height: 24),
const SizedBox(height: 100),
],
),
),