style: 全项目紫色→薄荷绿 Fresh Air 清新风

- 主色 #635BFF→#14B8A6 (薄荷绿)
- 浅紫 #EDEBFF→#E6FAF6 (极浅薄荷)
- 深紫 #4B44D6→#0F9D8E (深薄荷)
- 渐变紫→薄荷渐变
- 全局13种紫色映射替换
This commit is contained in:
MingNian
2026-06-03 20:30:28 +08:00
parent f484c6b66a
commit 8dcf99cac5
18 changed files with 221 additions and 249 deletions

View File

@@ -50,11 +50,11 @@ class _LoginPageState extends ConsumerState<LoginPage> {
return Scaffold(
body: Container(
decoration: const BoxDecoration(gradient: LinearGradient(begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [Color(0xFFF5F3FF), Color(0xFFEDEBFF), Color(0xFFE8E4FF)])),
decoration: const BoxDecoration(gradient: LinearGradient(begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [Color(0xFFF2FAF9), Color(0xFFE6FAF6), Color(0xFFE8E4FF)])),
child: SafeArea(child: SingleChildScrollView(padding: const EdgeInsets.symmetric(horizontal: 32), child: Column(children: [
const SizedBox(height: 60),
Container(width: 140, height: 140, decoration: BoxDecoration(color: const Color(0xFF635BFF).withAlpha(20), borderRadius: BorderRadius.circular(70)), child: Stack(alignment: Alignment.center, children: [
Container(width: 100, height: 100, decoration: BoxDecoration(color: Colors.white.withAlpha(200), borderRadius: BorderRadius.circular(50)), child: Icon(Icons.favorite, size: 50, color: const Color(0xFF635BFF))),
Container(width: 140, height: 140, decoration: BoxDecoration(color: const Color(0xFF14B8A6).withAlpha(20), borderRadius: BorderRadius.circular(70)), child: Stack(alignment: Alignment.center, children: [
Container(width: 100, height: 100, decoration: BoxDecoration(color: Colors.white.withAlpha(200), borderRadius: BorderRadius.circular(50)), child: Icon(Icons.favorite, size: 50, color: const Color(0xFF14B8A6))),
Positioned(right: 10, top: 10, child: Container(width: 30, height: 30, decoration: BoxDecoration(color: const Color(0xFFFFB800), borderRadius: BorderRadius.circular(15), border: Border.all(color: Colors.white, width: 2)), child: const Icon(Icons.add, size: 16, color: Colors.white))),
])),
const SizedBox(height: 24),
@@ -63,22 +63,22 @@ class _LoginPageState extends ConsumerState<LoginPage> {
Text('你的 AI 心脏健康管家', style: TextStyle(fontSize: 15, color: Colors.grey[500])),
const SizedBox(height: 48),
TextField(controller: _phoneCtrl, keyboardType: TextInputType.phone, maxLength: 11,
decoration: InputDecoration(hintText: '请输入手机号', prefixIcon: const Padding(padding: EdgeInsets.only(left: 12), child: Text('+86', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500))), counterText: '', filled: true, fillColor: Colors.white, border: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none), enabledBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none), focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF635BFF), width: 1.5)))),
decoration: InputDecoration(hintText: '请输入手机号', prefixIcon: const Padding(padding: EdgeInsets.only(left: 12), child: Text('+86', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500))), counterText: '', filled: true, fillColor: Colors.white, border: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none), enabledBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none), focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF14B8A6), width: 1.5)))),
const SizedBox(height: 16),
Row(children: [
Expanded(child: TextField(controller: _codeCtrl, keyboardType: TextInputType.number, maxLength: 6,
decoration: InputDecoration(hintText: '验证码', filled: true, fillColor: Colors.white, border: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none), enabledBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none), focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF635BFF), width: 1.5)), counterText: ''))),
decoration: InputDecoration(hintText: '验证码', filled: true, fillColor: Colors.white, border: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none), enabledBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide.none), focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: const BorderSide(color: Color(0xFF14B8A6), width: 1.5)), counterText: ''))),
const SizedBox(width: 12),
GestureDetector(onTap: (_countdown > 0 || _sending) ? null : _sendSms, child: Container(width: 100, height: 48, alignment: Alignment.center, decoration: BoxDecoration(color: _countdown > 0 ? Colors.grey[300] : const Color(0xFF635BFF), borderRadius: BorderRadius.circular(12)), child: Text(_sending ? '发送中' : _countdown > 0 ? '${_countdown}s' : '获取验证码', style: TextStyle(fontSize: 14, color: _countdown > 0 ? Colors.grey[600] : Colors.white, fontWeight: FontWeight.w500)))),
GestureDetector(onTap: (_countdown > 0 || _sending) ? null : _sendSms, child: Container(width: 100, height: 48, alignment: Alignment.center, decoration: BoxDecoration(color: _countdown > 0 ? Colors.grey[300] : const Color(0xFF14B8A6), borderRadius: BorderRadius.circular(12)), child: Text(_sending ? '发送中' : _countdown > 0 ? '${_countdown}s' : '获取验证码', style: TextStyle(fontSize: 14, color: _countdown > 0 ? Colors.grey[600] : Colors.white, fontWeight: FontWeight.w500)))),
]),
const SizedBox(height: 8),
Align(alignment: Alignment.centerLeft, child: GestureDetector(onTap: () => setState(() => _agreed = !_agreed), child: Row(mainAxisSize: MainAxisSize.min, children: [
Container(width: 20, height: 20, margin: const EdgeInsets.only(right: 6), decoration: BoxDecoration(shape: BoxShape.rectangle, color: _agreed ? const Color(0xFF635BFF) : Colors.transparent, border: Border.all(color: _agreed ? const Color(0xFF635BFF) : const Color(0xFFBDBDBD), width: 1.5), borderRadius: BorderRadius.circular(4)), child: _agreed ? const Icon(Icons.check, size: 14, color: Colors.white) : null),
RichText(text: TextSpan(children: [TextSpan(text: '已阅读并同意', style: TextStyle(fontSize: 13, color: Colors.grey[600])), TextSpan(text: '《服务协议》', style: const TextStyle(fontSize: 13, color: Color(0xFF635BFF))), TextSpan(text: '', style: TextStyle(fontSize: 13, color: Colors.grey[600])), TextSpan(text: '《隐私政策》', style: const TextStyle(fontSize: 13, color: Color(0xFF635BFF)))])),
Container(width: 20, height: 20, margin: const EdgeInsets.only(right: 6), decoration: BoxDecoration(shape: BoxShape.rectangle, color: _agreed ? const Color(0xFF14B8A6) : Colors.transparent, border: Border.all(color: _agreed ? const Color(0xFF14B8A6) : const Color(0xFFBDBDBD), width: 1.5), borderRadius: BorderRadius.circular(4)), child: _agreed ? const Icon(Icons.check, size: 14, color: Colors.white) : null),
RichText(text: TextSpan(children: [TextSpan(text: '已阅读并同意', style: TextStyle(fontSize: 13, color: Colors.grey[600])), TextSpan(text: '《服务协议》', style: const TextStyle(fontSize: 13, color: Color(0xFF14B8A6))), TextSpan(text: '', style: TextStyle(fontSize: 13, color: Colors.grey[600])), TextSpan(text: '《隐私政策》', style: const TextStyle(fontSize: 13, color: Color(0xFF14B8A6)))])),
]))),
if (_error != null) Padding(padding: const EdgeInsets.only(top: 12), child: Text(_error!, style: const TextStyle(color: Color(0xFFE53935), fontSize: 13))),
const SizedBox(height: 24),
GestureDetector(onTap: _loading ? null : _login, child: Container(width: double.infinity, height: 50, alignment: Alignment.center, decoration: BoxDecoration(gradient: const LinearGradient(colors: [Color(0xFF7C73FF), Color(0xFF635BFF)]), borderRadius: BorderRadius.circular(25), boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(80), blurRadius: 16, offset: const Offset(0, 8))]), child: _loading ? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2.5, color: Colors.white)) : const Text('登 录', style: TextStyle(fontSize: 17, color: Colors.white, fontWeight: FontWeight.w600, letterSpacing: 2)))),
GestureDetector(onTap: _loading ? null : _login, child: Container(width: double.infinity, height: 50, alignment: Alignment.center, decoration: BoxDecoration(gradient: const LinearGradient(colors: [Color(0xFF2DC4B4), Color(0xFF14B8A6)]), borderRadius: BorderRadius.circular(25), boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(80), blurRadius: 16, offset: const Offset(0, 8))]), child: _loading ? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2.5, color: Colors.white)) : const Text('登 录', style: TextStyle(fontSize: 17, color: Colors.white, fontWeight: FontWeight.w600, letterSpacing: 2)))),
const SizedBox(height: 40),
]))),
),

View File

@@ -265,7 +265,7 @@ class _TrendPageState extends ConsumerState<TrendPage> {
final title = _labels[widget.metricType] ?? '趋势图表';
return Scaffold(
backgroundColor: const Color(0xFFF8F7FF),
backgroundColor: const Color(0xFFF6F9FB),
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
@@ -351,7 +351,7 @@ class _TrendPageState extends ConsumerState<TrendPage> {
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFFEDEBFF), Color(0xFFF3F1FF)],
colors: [Color(0xFFE6FAF6), Color(0xFFF3F1FF)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
@@ -423,7 +423,7 @@ class _TrendPageState extends ConsumerState<TrendPage> {
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: const Color(0xFF635BFF).withValues(alpha: 0.06),
color: const Color(0xFF14B8A6).withValues(alpha: 0.06),
blurRadius: 20,
offset: const Offset(0, 4),
),
@@ -435,7 +435,7 @@ class _TrendPageState extends ConsumerState<TrendPage> {
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildLegendDot(const Color(0xFF635BFF), _isDualLine ? '收缩压' : _labels[widget.metricType]?.replaceAll('趋势', '') ?? ''),
_buildLegendDot(const Color(0xFF14B8A6), _isDualLine ? '收缩压' : _labels[widget.metricType]?.replaceAll('趋势', '') ?? ''),
if (_isDualLine) ...[
const SizedBox(width: 24),
_buildLegendDot(const Color(0xFF43A047), '舒张压'),
@@ -500,7 +500,7 @@ class _TrendPageState extends ConsumerState<TrendPage> {
_buildVerticalDivider(),
Expanded(child: _StatItem(label: '最低值', value: stats['min'].toString(), color: const Color(0xFFFF9800))),
_buildVerticalDivider(),
Expanded(child: _StatItem(label: '平均值', value: stats['avg'].toString(), color: const Color(0xFF635BFF))),
Expanded(child: _StatItem(label: '平均值', value: stats['avg'].toString(), color: const Color(0xFF14B8A6))),
_buildVerticalDivider(),
Expanded(child: _StatItem(label: '测量次数', value: stats['count'].toString(), color: const Color(0xFF78909C))),
]),
@@ -554,7 +554,7 @@ class _TrendPageState extends ConsumerState<TrendPage> {
),
child: Text(
_showAllRecords ? '收起' : '查看全部 (${validRecords.length} 条)',
style: const TextStyle(fontSize: 13, color: Color(0xFF635BFF)),
style: const TextStyle(fontSize: 13, color: Color(0xFF14B8A6)),
),
),
),
@@ -688,7 +688,7 @@ class _TrendPageState extends ConsumerState<TrendPage> {
actions: [
TextButton(
onPressed: () => Navigator.pop(ctx),
child: const Text('关闭', style: TextStyle(color: Color(0xFF635BFF))),
child: const Text('关闭', style: TextStyle(color: Color(0xFF14B8A6))),
),
],
),
@@ -713,10 +713,10 @@ class _TimeChip extends StatelessWidget {
duration: const Duration(milliseconds: 200),
padding: const EdgeInsets.symmetric(horizontal: 22, vertical: 8),
decoration: BoxDecoration(
color: selected ? const Color(0xFF635BFF) : Colors.white,
color: selected ? const Color(0xFF14B8A6) : Colors.white,
borderRadius: BorderRadius.circular(20),
border: Border.all(color: selected ? const Color(0xFF635BFF) : const Color(0xFFE0E0E0)),
boxShadow: selected ? [BoxShadow(color: const Color(0xFF635BFF).withValues(alpha: 0.25), blurRadius: 8, offset: const Offset(0, 3))] : null,
border: Border.all(color: selected ? const Color(0xFF14B8A6) : const Color(0xFFE0E0E0)),
boxShadow: selected ? [BoxShadow(color: const Color(0xFF14B8A6).withValues(alpha: 0.25), blurRadius: 8, offset: const Offset(0, 3))] : null,
),
child: Text(
label,
@@ -770,7 +770,7 @@ class _TrendChartPainter extends CustomPainter {
final String Function(DateTime) formatDateLabel;
final String Function(num) formatValue;
static const _primaryColor = Color(0xFF635BFF);
static const _primaryColor = Color(0xFF14B8A6);
static const _secondaryColor = Color(0xFF43A047);
static const _gridColor = Color(0xFFEEEEEE);
static const _labelColor = Color(0xFF999999);

View File

@@ -36,10 +36,10 @@ class DoctorListPage extends ConsumerWidget {
child: Row(children: [
CircleAvatar(
radius: 28,
backgroundColor: const Color(0xFFEDEBFF),
backgroundColor: const Color(0xFFE6FAF6),
child: Text(
(d['name'] as String?)?.isNotEmpty == true ? d['name']![0] : '?',
style: const TextStyle(fontSize: 22, color: Color(0xFF635BFF)),
style: const TextStyle(fontSize: 22, color: Color(0xFF14B8A6)),
),
),
const SizedBox(width: 16),
@@ -53,7 +53,7 @@ class DoctorListPage extends ConsumerWidget {
Text(d['title'] ?? '', style: const TextStyle(fontSize: 14, color: Color(0xFF666666))),
]),
const SizedBox(height: 4),
Text(d['department'] ?? '', style: const TextStyle(fontSize: 14, color: Color(0xFF635BFF))),
Text(d['department'] ?? '', style: const TextStyle(fontSize: 14, color: Color(0xFF14B8A6))),
const SizedBox(height: 2),
Text(d['introduction'] ?? '', style: const TextStyle(fontSize: 14, color: Color(0xFF999999))),
],

View File

@@ -132,11 +132,11 @@ class DietCapturePage extends ConsumerWidget {
width: 180,
height: 180,
decoration: BoxDecoration(
color: const Color(0xFFF5F3FF),
color: const Color(0xFFF2FAF9),
borderRadius: BorderRadius.circular(90),
border: Border.all(color: const Color(0xFF635BFF), width: 2),
border: Border.all(color: const Color(0xFF14B8A6), width: 2),
),
child: const Icon(Icons.camera_alt, size: 48, color: Color(0xFF635BFF)),
child: const Icon(Icons.camera_alt, size: 48, color: Color(0xFF14B8A6)),
),
const SizedBox(height: 24),
const Text('拍摄或上传您的餐食照片', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500)),
@@ -165,10 +165,10 @@ class DietCapturePage extends ConsumerWidget {
decoration: BoxDecoration(
color: const Color(0xFFFEFEFF),
borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(20), blurRadius: 8, offset: const Offset(0, 2))],
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(20), blurRadius: 8, offset: const Offset(0, 2))],
),
child: IconButton(
icon: Icon(icon, size: 32, color: const Color(0xFF635BFF)),
icon: Icon(icon, size: 32, color: const Color(0xFF14B8A6)),
onPressed: () => _pickImage(context, ref, source),
),
),
@@ -244,11 +244,11 @@ class DietCapturePage extends ConsumerWidget {
child: Column(children: [
Text(meal['icon']!, style: const TextStyle(fontSize: 20)),
const SizedBox(height: 4),
Text(meal['label']!, style: TextStyle(fontSize: 12, color: isSelected ? Colors.white : const Color(0xFF635BFF))),
Text(meal['label']!, style: TextStyle(fontSize: 12, color: isSelected ? Colors.white : const Color(0xFF14B8A6))),
]),
style: ElevatedButton.styleFrom(
backgroundColor: isSelected ? const Color(0xFF635BFF) : const Color(0xFFF5F3FF),
foregroundColor: isSelected ? Colors.white : const Color(0xFF635BFF),
backgroundColor: isSelected ? const Color(0xFF14B8A6) : const Color(0xFFF2FAF9),
foregroundColor: isSelected ? Colors.white : const Color(0xFF14B8A6),
elevation: 0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
padding: const EdgeInsets.symmetric(vertical: 12),
@@ -268,10 +268,10 @@ class DietCapturePage extends ConsumerWidget {
height: 60,
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: const Color(0xFFEDEBFF),
color: const Color(0xFFE6FAF6),
borderRadius: BorderRadius.circular(30),
),
child: const CircularProgressIndicator(strokeWidth: 3, color: Color(0xFF635BFF)),
child: const CircularProgressIndicator(strokeWidth: 3, color: Color(0xFF14B8A6)),
),
const SizedBox(height: 16),
const Text('AI 正在识别食物...', style: TextStyle(fontSize: 16, color: Color(0xFF666666))),
@@ -286,7 +286,7 @@ class DietCapturePage extends ConsumerWidget {
decoration: BoxDecoration(
color: const Color(0xFFFEFEFF),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: const Color(0xFFE8E6FF), width: 1.5),
border: Border.all(color: const Color(0xFFD4EDE8), width: 1.5),
),
child: Column(children: [
Padding(
@@ -297,7 +297,7 @@ class DietCapturePage extends ConsumerWidget {
const Text('识别结果', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600)),
const Spacer(),
IconButton(
icon: const Icon(Icons.add, size: 20, color: Color(0xFF635BFF)),
icon: const Icon(Icons.add, size: 20, color: Color(0xFF14B8A6)),
onPressed: () => ref.read(dietProvider.notifier).addFood(),
),
]),
@@ -312,14 +312,14 @@ class DietCapturePage extends ConsumerWidget {
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: food.selected ? const Color(0xFFF5F3FF) : const Color(0xFFF5F5F5),
color: food.selected ? const Color(0xFFF2FAF9) : const Color(0xFFF5F5F5),
borderRadius: BorderRadius.circular(16),
),
child: Row(children: [
Checkbox(
value: food.selected,
onChanged: (v) => ref.read(dietProvider.notifier).toggleFood(food.id),
activeColor: const Color(0xFF635BFF),
activeColor: const Color(0xFF14B8A6),
),
const SizedBox(width: 8),
Expanded(
@@ -339,7 +339,7 @@ class DietCapturePage extends ConsumerWidget {
controller: TextEditingController(text: food.calories.toString()),
keyboardType: TextInputType.number,
onChanged: (v) => ref.read(dietProvider.notifier).updateFoodCalories(food.id, int.tryParse(v) ?? 0),
style: TextStyle(fontSize: 12, color: const Color(0xFF635BFF)),
style: TextStyle(fontSize: 12, color: const Color(0xFF14B8A6)),
),
),
const Text('kcal', style: TextStyle(fontSize: 12, color: Color(0xFF999999))),
@@ -358,7 +358,7 @@ class DietCapturePage extends ConsumerWidget {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFFF5F3FF),
color: const Color(0xFFF2FAF9),
borderRadius: BorderRadius.circular(16),
),
child: Row(children: [
@@ -383,7 +383,7 @@ class DietCapturePage extends ConsumerWidget {
decoration: BoxDecoration(
color: const Color(0xFFFEFEFF),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: const Color(0xFFE8E6FF), width: 1.5),
border: Border.all(color: const Color(0xFFD4EDE8), width: 1.5),
),
child: Column(children: [
const Text('🥗 健康评分', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600)),
@@ -417,7 +417,7 @@ class DietCapturePage extends ConsumerWidget {
switch (score) {
case 1: return const Color(0xFFE53935);
case 2: return const Color(0xFFF9A825);
case 3: return const Color(0xFF635BFF);
case 3: return const Color(0xFF14B8A6);
case 4: return const Color(0xFF43A047);
case 5: return const Color(0xFF00C853);
default: return Colors.grey[400]!;
@@ -431,13 +431,13 @@ class DietCapturePage extends ConsumerWidget {
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('饮食记录已保存 ✅'),
backgroundColor: Color(0xFF635BFF),
backgroundColor: Color(0xFF14B8A6),
));
popRoute(ref);
},
child: const Text('保存记录'),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF635BFF),
backgroundColor: const Color(0xFF14B8A6),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
padding: const EdgeInsets.symmetric(vertical: 16),

View File

@@ -86,7 +86,7 @@ class _HomePageState extends ConsumerState<HomePage> {
return Scaffold(
drawer: const HealthDrawer(),
backgroundColor: const Color(0xFFF8F7FF),
backgroundColor: const Color(0xFFF6F9FB),
body: SafeArea(
child: Column(children: [
// ── 顶部栏 ──
@@ -110,11 +110,11 @@ class _HomePageState extends ConsumerState<HomePage> {
child: Row(children: [
Builder(builder: (ctx) => GestureDetector(
onTap: () => Scaffold.of(ctx).openDrawer(),
child: CircleAvatar(radius: 20, backgroundColor: const Color(0xFFEDEBFF), backgroundImage: user?.avatarUrl != null ? NetworkImage(user!.avatarUrl!) : null, child: user?.avatarUrl == null ? const Icon(Icons.person, size: 24, color: Color(0xFF635BFF)) : null),
child: CircleAvatar(radius: 20, backgroundColor: const Color(0xFFE6FAF6), backgroundImage: user?.avatarUrl != null ? NetworkImage(user!.avatarUrl!) : null, child: user?.avatarUrl == null ? const Icon(Icons.person, size: 24, color: Color(0xFF14B8A6)) : null),
)),
const SizedBox(width: 10),
Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(mainAxisSize: MainAxisSize.min, children: [Icon(Icons.smart_toy_outlined, size: 16, color: const Color(0xFF635BFF)), const SizedBox(width: 4), Text('AI 健康管家', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w500, color: Colors.grey[600]))]),
Row(mainAxisSize: MainAxisSize.min, children: [Icon(Icons.smart_toy_outlined, size: 16, color: const Color(0xFF14B8A6)), const SizedBox(width: 4), Text('AI 健康管家', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w500, color: Colors.grey[600]))]),
const SizedBox(height: 2),
Text('${_getGreeting()}${user?.name ?? '张三'}', style: const TextStyle(fontSize: 17, fontWeight: FontWeight.bold, color: Color(0xFF1A1A1A))),
])),
@@ -151,11 +151,11 @@ class _HomePageState extends ConsumerState<HomePage> {
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(8), blurRadius: 6, offset: const Offset(0, 1))]),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(8), blurRadius: 6, offset: const Offset(0, 1))]),
child: Row(children: [
const Text('今日任务', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))),
const Spacer(),
const Text('展开 ▾', style: TextStyle(fontSize: 12, color: Color(0xFF635BFF))),
const Text('展开 ▾', style: TextStyle(fontSize: 12, color: Color(0xFF14B8A6))),
]),
),
);
@@ -165,7 +165,7 @@ class _HomePageState extends ConsumerState<HomePage> {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(8), blurRadius: 6, offset: const Offset(0, 1))]),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(8), blurRadius: 6, offset: const Offset(0, 1))]),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(children: [
const Text('今日任务', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))),
@@ -339,7 +339,7 @@ class _HomePageState extends ConsumerState<HomePage> {
borderRadius: BorderRadius.circular(8),
),
child: Row(crossAxisAlignment: CrossAxisAlignment.center, children: [
Container(width: 30, height: 30, decoration: BoxDecoration(color: const Color(0xFFF5F3FF), borderRadius: BorderRadius.circular(8)), child: Icon(icon, size: 15, color: const Color(0xFF635BFF))),
Container(width: 30, height: 30, decoration: BoxDecoration(color: const Color(0xFFF2FAF9), borderRadius: BorderRadius.circular(8)), child: Icon(icon, size: 15, color: const Color(0xFF14B8A6))),
const SizedBox(width: 10), Expanded(child: Text(label, style: const TextStyle(fontSize: 13, color: Color(0xFF333333)))),
Icon(icons[effectiveStatus], size: 18, color: colors[effectiveStatus] ?? Colors.grey),
]),
@@ -351,7 +351,7 @@ class _HomePageState extends ConsumerState<HomePage> {
void _handleMedicationCheck() async {
await ref.read(medicationServiceProvider).confirm('');
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('已记录服药 ✅'), backgroundColor: Color(0xFF635BFF)));
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('已记录服药 ✅'), backgroundColor: Color(0xFF14B8A6)));
}
// ═════════════════════ 智能体选择条(常驻) ═════════════════════
@@ -392,9 +392,9 @@ class _HomePageState extends ConsumerState<HomePage> {
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
decoration: BoxDecoration(
color: isActive ? const Color(0xFF635BFF) : Colors.white,
color: isActive ? const Color(0xFF14B8A6) : Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: isActive ? const Color(0xFF635BFF) : const Color(0xFFE0E0E0)),
border: Border.all(color: isActive ? const Color(0xFF14B8A6) : const Color(0xFFE0E0E0)),
),
child: Row(mainAxisSize: MainAxisSize.min, children: [
Icon(icon, size: 13, color: isActive ? Colors.white : const Color(0xFF666666)),
@@ -456,7 +456,7 @@ class _HomePageState extends ConsumerState<HomePage> {
decoration: const InputDecoration(hintText: '输入你想说的...', hintStyle: TextStyle(fontSize: 15, color: Color(0xFFBBBBBB)), contentPadding: EdgeInsets.symmetric(horizontal: 10, vertical: 10), border: InputBorder.none),
onSubmitted: (_) => _sendMessage(),
)),
IconButton(icon: const Icon(Icons.send, size: 24, color: Color(0xFF635BFF)), onPressed: _sendMessage),
IconButton(icon: const Icon(Icons.send, size: 24, color: Color(0xFF14B8A6)), onPressed: _sendMessage),
]),
);
}

View File

@@ -26,10 +26,10 @@ class ChatMessagesView extends ConsumerWidget {
width: 80,
height: 80,
decoration: BoxDecoration(
color: const Color(0xFFEDEBFF),
color: const Color(0xFFE6FAF6),
borderRadius: BorderRadius.circular(40),
),
child: const Icon(Icons.health_and_safety, size: 40, color: Color(0xFF635BFF)),
child: const Icon(Icons.health_and_safety, size: 40, color: Color(0xFF14B8A6)),
),
const SizedBox(height: 16),
Text('开始和 AI 健康管家对话吧', style: Theme.of(context).textTheme.bodyMedium),
@@ -100,7 +100,7 @@ class ChatMessagesView extends ConsumerWidget {
color: const Color(0xFFFFFFFF),
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(color: const Color(0xFF635BFF).withAlpha(20), blurRadius: 16, offset: const Offset(0, 4)),
BoxShadow(color: const Color(0xFF14B8A6).withAlpha(20), blurRadius: 16, offset: const Offset(0, 4)),
],
),
clipBehavior: Clip.antiAlias,
@@ -113,7 +113,7 @@ class ChatMessagesView extends ConsumerWidget {
padding: const EdgeInsets.fromLTRB(20, 24, 16, 20),
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Color(0xFF7C73FF), Color(0xFF635BFF), Color(0xFF5241D9)],
colors: [Color(0xFF2DC4B4), Color(0xFF14B8A6), Color(0xFF0E8071)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
@@ -143,7 +143,7 @@ class ChatMessagesView extends ConsumerWidget {
color: Colors.white.withAlpha(25),
borderRadius: BorderRadius.circular(10),
),
child: Text(info.$3, style: const TextStyle(fontSize: 12, color: Color(0xFFE0DDFF))),
child: Text(info.$3, style: const TextStyle(fontSize: 12, color: Color(0xFFC6EBE6))),
),
],
),
@@ -157,7 +157,7 @@ class ChatMessagesView extends ConsumerWidget {
color: Colors.white.withAlpha(20),
shape: BoxShape.circle,
),
child: const Icon(Icons.close, size: 16, color: Color(0xFFE0DDFF)),
child: const Icon(Icons.close, size: 16, color: Color(0xFFC6EBE6)),
),
),
],
@@ -182,12 +182,12 @@ class ChatMessagesView extends ConsumerWidget {
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(width: 24, height: 1, color: const Color(0xFFD0CCED)),
Container(width: 24, height: 1, color: const Color(0xFFC6EBE6)),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Text('或直接对我说...', style: TextStyle(fontSize: 13, color: Color(0xFF9E94CF))),
child: Text('或直接对我说...', style: TextStyle(fontSize: 13, color: Color(0xFF9EDBD3))),
),
Container(width: 24, height: 1, color: const Color(0xFFD0CCED)),
Container(width: 24, height: 1, color: const Color(0xFFC6EBE6)),
],
),
),
@@ -216,7 +216,7 @@ class ChatMessagesView extends ConsumerWidget {
decoration: BoxDecoration(
color: const Color(0xFFF7F5FF),
borderRadius: BorderRadius.circular(14),
border: Border.all(color: const Color(0xFFEBE8FF), width: 1),
border: Border.all(color: const Color(0xFFD4EDE8), width: 1),
),
child: Column(
mainAxisSize: MainAxisSize.min,
@@ -228,7 +228,7 @@ class ChatMessagesView extends ConsumerWidget {
color: const Color(0xFFEDEAFF),
borderRadius: BorderRadius.circular(11),
),
child: Icon(a.icon, size: 20, color: const Color(0xFF635BFF)),
child: Icon(a.icon, size: 20, color: const Color(0xFF14B8A6)),
),
const SizedBox(height: 7),
Text(a.label, style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500, color: Color(0xFF333333))),
@@ -257,13 +257,13 @@ class ChatMessagesView extends ConsumerWidget {
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(14),
border: Border.all(color: const Color(0xFFEDEBFF)),
border: Border.all(color: const Color(0xFFE6FAF6)),
),
child: Column(children: [
CircleAvatar(
radius: 24,
backgroundColor: const Color(0xFFEDEBFF),
child: Text(doc['name']![0], style: const TextStyle(fontSize: 20, color: Color(0xFF635BFF))),
backgroundColor: const Color(0xFFE6FAF6),
child: Text(doc['name']![0], style: const TextStyle(fontSize: 20, color: Color(0xFF14B8A6))),
),
const SizedBox(height: 8),
Text(doc['name']!, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w600)),
@@ -272,10 +272,10 @@ class ChatMessagesView extends ConsumerWidget {
Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: const Color(0xFFF5F3FF),
color: const Color(0xFFF2FAF9),
borderRadius: BorderRadius.circular(4),
),
child: Text(doc['dept']!, style: const TextStyle(fontSize: 10, color: Color(0xFF635BFF))),
child: Text(doc['dept']!, style: const TextStyle(fontSize: 10, color: Color(0xFF14B8A6))),
),
const SizedBox(height: 6),
Text(
@@ -310,7 +310,7 @@ class ChatMessagesView extends ConsumerWidget {
decoration: BoxDecoration(
color: const Color(0xFFFFFFFF),
borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
),
clipBehavior: Clip.antiAlias,
child: Column(
@@ -431,7 +431,7 @@ class ChatMessagesView extends ConsumerWidget {
width: 22,
height: h,
decoration: BoxDecoration(
color: e.key == trend.length - 1 ? const Color(0xFF635BFF) : const Color(0xFFD5D0FF),
color: e.key == trend.length - 1 ? const Color(0xFF14B8A6) : const Color(0xFFD5D0FF),
borderRadius: BorderRadius.circular(5),
),
),
@@ -482,7 +482,7 @@ class ChatMessagesView extends ConsumerWidget {
decoration: BoxDecoration(
color: const Color(0xFFFFFFFF),
borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
),
clipBehavior: Clip.antiAlias,
child: Column(
@@ -493,7 +493,7 @@ class ChatMessagesView extends ConsumerWidget {
width: double.infinity,
padding: const EdgeInsets.fromLTRB(18, 20, 18, 16),
decoration: const BoxDecoration(
gradient: LinearGradient(colors: [Color(0xFFE8F0FE), Color(0xFFF5F3FF)]),
gradient: LinearGradient(colors: [Color(0xFFE8F0FE), Color(0xFFF2FAF9)]),
),
child: Row(
children: [
@@ -537,7 +537,7 @@ class ChatMessagesView extends ConsumerWidget {
children: [
const Text('剩余药量', style: TextStyle(fontSize: 13, color: Color(0xFF666666))),
const Spacer(),
Text('${(remaining * 100).toInt()}%', style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF635BFF))),
Text('${(remaining * 100).toInt()}%', style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF14B8A6))),
],
),
const SizedBox(height: 8),
@@ -547,7 +547,7 @@ class ChatMessagesView extends ConsumerWidget {
value: remaining,
minHeight: 8,
backgroundColor: const Color(0xFFEFEDFF),
valueColor: const AlwaysStoppedAnimation<Color>(Color(0xFF635BFF)),
valueColor: const AlwaysStoppedAnimation<Color>(Color(0xFF14B8A6)),
),
),
@@ -601,7 +601,7 @@ class ChatMessagesView extends ConsumerWidget {
decoration: BoxDecoration(
color: const Color(0xFFFFFFFF),
borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
),
clipBehavior: Clip.antiAlias,
child: Column(
@@ -657,7 +657,7 @@ class ChatMessagesView extends ConsumerWidget {
] else ...[
Container(
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(color: const Color(0xFFF5F3FF), borderRadius: BorderRadius.circular(12)),
decoration: BoxDecoration(color: const Color(0xFFF2FAF9), borderRadius: BorderRadius.circular(12)),
child: const Row(mainAxisAlignment: MainAxisAlignment.center, children: [
Icon(Icons.hourglass_empty, size: 18, color: Color(0xFF999999)),
SizedBox(width: 8),
@@ -672,7 +672,7 @@ class ChatMessagesView extends ConsumerWidget {
const SizedBox(height: 6),
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(color: const Color(0xFFF5F3FF), borderRadius: BorderRadius.circular(10)),
decoration: BoxDecoration(color: const Color(0xFFF2FAF9), borderRadius: BorderRadius.circular(10)),
child: Text(advice, style: const TextStyle(fontSize: 13, height: 1.6, color: Color(0xFF555555))),
),
]),
@@ -702,7 +702,7 @@ class ChatMessagesView extends ConsumerWidget {
decoration: BoxDecoration(
color: const Color(0xFFFFFFFF),
borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
),
clipBehavior: Clip.antiAlias,
child: Column(
@@ -839,9 +839,9 @@ class ChatMessagesView extends ConsumerWidget {
children: [
const Row(
children: [
Icon(Icons.auto_awesome, size: 16, color: Color(0xFF635BFF)),
Icon(Icons.auto_awesome, size: 16, color: Color(0xFF14B8A6)),
SizedBox(width: 6),
Text('AI 解读摘要', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF635BFF))),
Text('AI 解读摘要', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF14B8A6))),
],
),
const SizedBox(height: 8),
@@ -883,7 +883,7 @@ class ChatMessagesView extends ConsumerWidget {
decoration: BoxDecoration(
color: const Color(0xFFFFFFFF),
borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(15), blurRadius: 14, offset: const Offset(0, 4))],
),
child: Padding(
padding: const EdgeInsets.fromLTRB(18, 16, 18, 14),
@@ -897,8 +897,8 @@ class ChatMessagesView extends ConsumerWidget {
return ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFF5F3FF),
foregroundColor: const Color(0xFF635BFF),
backgroundColor: const Color(0xFFF2FAF9),
foregroundColor: const Color(0xFF14B8A6),
elevation: 0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 11),
@@ -926,8 +926,8 @@ class ChatMessagesView extends ConsumerWidget {
decoration: BoxDecoration(
color: const Color(0xFFFEFEFF),
borderRadius: const BorderRadius.only(topLeft: Radius.circular(4), topRight: Radius.circular(20), bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)),
border: Border.all(color: const Color(0xFFE8E6FF), width: 1.5),
boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(12), blurRadius: 10, offset: const Offset(0, 3))],
border: Border.all(color: const Color(0xFFD4EDE8), width: 1.5),
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(12), blurRadius: 10, offset: const Offset(0, 3))],
),
child: Row(
mainAxisSize: MainAxisSize.min,
@@ -937,10 +937,10 @@ class ChatMessagesView extends ConsumerWidget {
height: 26,
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
color: const Color(0xFFEDEBFF),
color: const Color(0xFFE6FAF6),
borderRadius: BorderRadius.circular(13),
),
child: const CircularProgressIndicator(strokeWidth: 2.2, color: Color(0xFF635BFF)),
child: const CircularProgressIndicator(strokeWidth: 2.2, color: Color(0xFF14B8A6)),
),
const SizedBox(width: 10),
Text(thinkingText?.isNotEmpty == true ? thinkingText! : '正在分析...', style: const TextStyle(fontSize: 14, color: Color(0xFF999999))),
@@ -963,15 +963,15 @@ class ChatMessagesView extends ConsumerWidget {
constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.82),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
decoration: BoxDecoration(
color: isUser ? const Color(0xFF635BFF) : const Color(0xFFFEFEFF),
color: isUser ? const Color(0xFF14B8A6) : const Color(0xFFFEFEFF),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(isUser ? 20 : 4),
topRight: Radius.circular(isUser ? 4 : 20),
bottomLeft: const Radius.circular(20),
bottomRight: const Radius.circular(20),
),
border: isUser ? null : Border.all(color: const Color(0xFFE8E6FF), width: 1.5),
boxShadow: isUser ? [] : [BoxShadow(color: const Color(0xFF635BFF).withAlpha(12), blurRadius: 10, offset: const Offset(0, 3))],
border: isUser ? null : Border.all(color: const Color(0xFFD4EDE8), width: 1.5),
boxShadow: isUser ? [] : [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(12), blurRadius: 10, offset: const Offset(0, 3))],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@@ -998,14 +998,14 @@ class ChatMessagesView extends ConsumerWidget {
p: const TextStyle(fontSize: 16, color: Color(0xFF1A1A1A), height: 1.5),
h1: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)),
h2: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)),
code: const TextStyle(fontSize: 14, backgroundColor: Color(0xFFF5F3FF)),
code: const TextStyle(fontSize: 14, backgroundColor: Color(0xFFF2FAF9)),
),
),
if (!isUser && msg.content.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: 10),
child: Row(children: [
const CircleAvatar(radius: 10, backgroundColor: Color(0xFFEDEBFF), child: Icon(Icons.chat_bubble_outline, size: 14, color: Color(0xFF635BFF))),
const CircleAvatar(radius: 10, backgroundColor: Color(0xFFE6FAF6), child: Icon(Icons.chat_bubble_outline, size: 14, color: Color(0xFF14B8A6))),
const SizedBox(width: 6),
const Text('健康管家', style: TextStyle(fontSize: 12, color: Color(0xFF9E9E9E))),
const SizedBox(width: 4),
@@ -1038,7 +1038,7 @@ class ChatMessagesView extends ConsumerWidget {
return ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF635BFF),
backgroundColor: const Color(0xFF14B8A6),
foregroundColor: Colors.white,
elevation: 0,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
@@ -1056,8 +1056,8 @@ class ChatMessagesView extends ConsumerWidget {
return OutlinedButton(
onPressed: () {},
style: OutlinedButton.styleFrom(
foregroundColor: const Color(0xFF635BFF),
side: const BorderSide(color: Color(0xFF635BFF), width: 1.2),
foregroundColor: const Color(0xFF14B8A6),
side: const BorderSide(color: Color(0xFF14B8A6), width: 1.2),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
padding: const EdgeInsets.symmetric(vertical: 11),
),
@@ -1195,9 +1195,9 @@ class ChatMessagesView extends ConsumerWidget {
return Container(
margin: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(10), blurRadius: 8, offset: const Offset(0, 2))]),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(10), blurRadius: 8, offset: const Offset(0, 2))]),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(children: [Icon(Icons.today, size: 18, color: const Color(0xFF635BFF)), const SizedBox(width: 8), const Text('今日任务', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)))]),
Row(children: [Icon(Icons.today, size: 18, color: const Color(0xFF14B8A6)), const SizedBox(width: 8), const Text('今日任务', style: TextStyle(fontSize: 15, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)))]),
const SizedBox(height: 10),
Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: [
_miniMetric('血压', bpText, Icons.favorite),
@@ -1211,7 +1211,7 @@ class ChatMessagesView extends ConsumerWidget {
Widget _miniMetric(String label, String value, IconData icon) {
return Column(children: [
Icon(icon, size: 20, color: const Color(0xFF635BFF)),
Icon(icon, size: 20, color: const Color(0xFF14B8A6)),
const SizedBox(height: 4),
Text(value, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.bold, color: Color(0xFF1A1A1A))),
Text(label, style: const TextStyle(fontSize: 10, color: Color(0xFF999999))),
@@ -1298,9 +1298,9 @@ class _ExpandableAdviceState extends State<_ExpandableAdvice> {
children: [
Row(
children: [
const Icon(Icons.lightbulb_outline, size: 16, color: Color(0xFF635BFF)),
const Icon(Icons.lightbulb_outline, size: 16, color: Color(0xFF14B8A6)),
const SizedBox(width: 6),
const Text('AI 建议', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF635BFF))),
const Text('AI 建议', style: TextStyle(fontSize: 13, fontWeight: FontWeight.w600, color: Color(0xFF14B8A6))),
const Spacer(),
Icon(_expanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, size: 18, color: const Color(0xFFAAAAAA)),
],

View File

@@ -99,7 +99,7 @@ class _MedicationEditPageState extends ConsumerState<MedicationEditPage> {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('已添加 ${_items.length} 种药品'),
backgroundColor: const Color(0xFF635BFF),
backgroundColor: const Color(0xFF14B8A6),
),
);
ref.invalidate(medicationListProvider);
@@ -136,7 +136,7 @@ class _MedicationEditPageState extends ConsumerState<MedicationEditPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFF8F7FF),
backgroundColor: const Color(0xFFF6F9FB),
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
@@ -158,7 +158,7 @@ class _MedicationEditPageState extends ConsumerState<MedicationEditPage> {
child: const Text(
'保存',
style: TextStyle(
color: Color(0xFF635BFF),
color: Color(0xFF14B8A6),
fontWeight: FontWeight.w600,
),
),
@@ -204,7 +204,7 @@ class _MedicationEditPageState extends ConsumerState<MedicationEditPage> {
style: const TextStyle(
fontSize: 13,
fontWeight: FontWeight.w600,
color: Color(0xFF635BFF),
color: Color(0xFF14B8A6),
),
),
if (_items.length > 1)
@@ -390,7 +390,7 @@ class _MedicationEditPageState extends ConsumerState<MedicationEditPage> {
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.access_time, size: 16, color: Color(0xFF635BFF)),
const Icon(Icons.access_time, size: 16, color: Color(0xFF14B8A6)),
const SizedBox(width: 6),
Text(
time.format(context),
@@ -410,11 +410,11 @@ class _MedicationEditPageState extends ConsumerState<MedicationEditPage> {
icon: const Icon(Icons.add, size: 18),
label: const Text('添加', style: TextStyle(fontSize: 14)),
style: OutlinedButton.styleFrom(
foregroundColor: const Color(0xFF635BFF),
side: const BorderSide(color: Color(0xFFD5D1FF)),
foregroundColor: const Color(0xFF14B8A6),
side: const BorderSide(color: Color(0xFFC0E8E2)),
padding: const EdgeInsets.symmetric(vertical: 12),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
backgroundColor: const Color(0xFFF5F3FF),
backgroundColor: const Color(0xFFF2FAF9),
),
),
);
@@ -438,7 +438,7 @@ class _MedicationEditPageState extends ConsumerState<MedicationEditPage> {
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: const BorderSide(color: Color(0xFF635BFF)),
borderSide: const BorderSide(color: Color(0xFF14B8A6)),
),
);
}

View File

@@ -9,7 +9,7 @@ class MedicationListPage extends ConsumerWidget {
@override Widget build(BuildContext context, WidgetRef ref) {
final meds = ref.watch(medicationListProvider);
return Scaffold(
backgroundColor: const Color(0xFFF8F7FF),
backgroundColor: const Color(0xFFF6F9FB),
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
@@ -19,9 +19,9 @@ class MedicationListPage extends ConsumerWidget {
TextButton(
onPressed: () => pushRoute(ref, 'medicationEdit'),
child: Row(mainAxisSize: MainAxisSize.min, children: [
const Icon(Icons.add_circle_outline, size: 18, color: Color(0xFF635BFF)),
const Icon(Icons.add_circle_outline, size: 18, color: Color(0xFF14B8A6)),
const SizedBox(width: 4),
const Text('添加新药', style: TextStyle(color: Color(0xFF635BFF), fontSize: 14)),
const Text('添加新药', style: TextStyle(color: Color(0xFF14B8A6), fontSize: 14)),
]),
),
],
@@ -47,7 +47,7 @@ class MedicationListPage extends ConsumerWidget {
},
);
},
loading: () => const Center(child: CircularProgressIndicator(color: Color(0xFF635BFF))),
loading: () => const Center(child: CircularProgressIndicator(color: Color(0xFF14B8A6))),
error: (_, __) => _empty(context),
)),
_buildReminderBar(),
@@ -65,11 +65,11 @@ class MedicationListPage extends ConsumerWidget {
width: 40,
height: 40,
decoration: BoxDecoration(
color: const Color(0xFFEDEBFF),
color: const Color(0xFFE6FAF6),
borderRadius: BorderRadius.circular(20),
border: Border.all(color: const Color(0xFF635BFF).withAlpha(50)),
border: Border.all(color: const Color(0xFF14B8A6).withAlpha(50)),
),
child: const Icon(Icons.notifications_active_outlined, size: 20, color: Color(0xFF635BFF)),
child: const Icon(Icons.notifications_active_outlined, size: 20, color: Color(0xFF14B8A6)),
),
const SizedBox(width: 12),
const Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
@@ -102,9 +102,9 @@ class _TabChip extends StatelessWidget {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 7),
decoration: BoxDecoration(
color: active ? const Color(0xFF635BFF) : Colors.white,
color: active ? const Color(0xFF14B8A6) : Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: active ? const Color(0xFF635BFF) : const Color(0xFFE0E0E0)),
border: Border.all(color: active ? const Color(0xFF14B8A6) : const Color(0xFFE0E0E0)),
),
child: Text(
label,
@@ -130,14 +130,14 @@ class _MedicationCard extends StatelessWidget {
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(10), blurRadius: 4, offset: const Offset(0, 2))],
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(10), blurRadius: 4, offset: const Offset(0, 2))],
),
child: Row(children: [
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: const Color(0xFFF5F3FF),
color: const Color(0xFFF2FAF9),
borderRadius: BorderRadius.circular(14),
),
child: const Center(child: Text('💊', style: TextStyle(fontSize: 24))),

View File

@@ -10,7 +10,7 @@ class ProfileDetailPage extends ConsumerWidget {
final latestHealth = ref.watch(latestHealthProvider);
return Scaffold(
backgroundColor: const Color(0xFFF8F7FF),
backgroundColor: const Color(0xFFF6F9FB),
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
@@ -22,23 +22,23 @@ class ProfileDetailPage extends ConsumerWidget {
]),
centerTitle: true,
),
body: SafeArea(child: SingleChildScrollView(padding: const EdgeInsets.all(16), child: Column(children: [_buildUserCard(), const SizedBox(height: 16), _buildHealthOverview(latestHealth), const SizedBox(height: 16), _buildHistoryList(), const SizedBox(height: 16), SizedBox(width: double.infinity, height: 48, child: OutlinedButton(onPressed: () => pushRoute(ref, 'settings'), style: OutlinedButton.styleFrom(foregroundColor: const Color(0xFF635BFF), side: const BorderSide(color: Color(0xFF635BFF)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24))), child: const Text('退出档案')))]))),
body: SafeArea(child: SingleChildScrollView(padding: const EdgeInsets.all(16), child: Column(children: [_buildUserCard(), const SizedBox(height: 16), _buildHealthOverview(latestHealth), const SizedBox(height: 16), _buildHistoryList(), const SizedBox(height: 16), SizedBox(width: double.infinity, height: 48, child: OutlinedButton(onPressed: () => pushRoute(ref, 'settings'), style: OutlinedButton.styleFrom(foregroundColor: const Color(0xFF14B8A6), side: const BorderSide(color: Color(0xFF14B8A6)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24))), child: const Text('退出档案')))]))),
);
}
Widget _buildUserCard() => Container(width: double.infinity, padding: const EdgeInsets.all(20), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20), boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(10), blurRadius: 8, offset: const Offset(0, 2))]), child: Row(children: [CircleAvatar(radius: 32, backgroundColor: const Color(0xFFEDEBFF), child: const Icon(Icons.person, size: 40, color: Color(0xFF635BFF))), const SizedBox(width: 16), Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [const Text('张三', style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Color(0xFF1A1A1A))), const SizedBox(height: 4), Text('42岁 · 男 · 175cm · 72kg', style: TextStyle(fontSize: 14, color: Colors.grey[500]))])), Icon(Icons.chevron_right, size: 24, color: Colors.grey[400])]));
Widget _buildUserCard() => Container(width: double.infinity, padding: const EdgeInsets.all(20), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20), boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(10), blurRadius: 8, offset: const Offset(0, 2))]), child: Row(children: [CircleAvatar(radius: 32, backgroundColor: const Color(0xFFE6FAF6), child: const Icon(Icons.person, size: 40, color: Color(0xFF14B8A6))), const SizedBox(width: 16), Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [const Text('张三', style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Color(0xFF1A1A1A))), const SizedBox(height: 4), Text('42岁 · 男 · 175cm · 72kg', style: TextStyle(fontSize: 14, color: Colors.grey[500]))])), Icon(Icons.chevron_right, size: 24, color: Colors.grey[400])]));
Widget _buildHealthOverview(AsyncValue<Map<String, dynamic>> healthData) {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20), boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(10), blurRadius: 8, offset: const Offset(0, 2))]),
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20), boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(10), blurRadius: 8, offset: const Offset(0, 2))]),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
const Text('健康概览', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))),
const SizedBox(height: 4),
Text('(最近测量)', style: TextStyle(fontSize: 13, color: Colors.grey[500])),
const SizedBox(height: 16),
healthData.when(data: (data) => _buildMetricsList(data), loading: () => const Center(child: Padding(padding: EdgeInsets.all(24), child: CircularProgressIndicator(strokeWidth: 2, color: Color(0xFF635BFF)))), error: (_, __) => _buildMetricsEmpty()),
healthData.when(data: (data) => _buildMetricsList(data), loading: () => const Center(child: Padding(padding: EdgeInsets.all(24), child: CircularProgressIndicator(strokeWidth: 2, color: Color(0xFF14B8A6)))), error: (_, __) => _buildMetricsEmpty()),
]),
);
}
@@ -54,11 +54,11 @@ class ProfileDetailPage extends ConsumerWidget {
String _formatBP(dynamic bp) { if (bp is Map) { final s = bp['systolic']; final d = bp['diastolic']; if (s != null && d != null) return '$s/$d'; } return '--/--'; }
String _formatMetric(dynamic val, String unit) { if (val is Map) { final v = val['value']; if (v != null) return '$v$unit'; } return '-- $unit'; }
Widget _metricRow(IconData icon, String label, String value) => InkWell(onTap: () {}, borderRadius: BorderRadius.circular(12), child: Padding(padding: const EdgeInsets.symmetric(vertical: 14), child: Row(children: [Container(width: 40, height: 40, decoration: BoxDecoration(color: const Color(0xFFF5F3FF), borderRadius: BorderRadius.circular(10)), child: Icon(icon, size: 18, color: const Color(0xFF635BFF))), const SizedBox(width: 12), Expanded(child: Text(label, style: const TextStyle(fontSize: 15, color: Color(0xFF333333)))), Text(value, style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))), const SizedBox(width: 8), Icon(Icons.chevron_right, size: 18, color: Colors.grey[400])])));
Widget _metricRow(IconData icon, String label, String value) => InkWell(onTap: () {}, borderRadius: BorderRadius.circular(12), child: Padding(padding: const EdgeInsets.symmetric(vertical: 14), child: Row(children: [Container(width: 40, height: 40, decoration: BoxDecoration(color: const Color(0xFFF2FAF9), borderRadius: BorderRadius.circular(10)), child: Icon(icon, size: 18, color: const Color(0xFF14B8A6))), const SizedBox(width: 12), Expanded(child: Text(label, style: const TextStyle(fontSize: 15, color: Color(0xFF333333)))), Text(value, style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))), const SizedBox(width: 8), Icon(Icons.chevron_right, size: 18, color: Colors.grey[400])])));
Widget _buildHistoryList() {
final items = [{'date': '05-31', 'label': '血压 · 餐前', 'value': '128/82', 'status': 'normal'}, {'date': '05-30', 'label': '血压 · 餐后', 'value': '135/85', 'status': 'warning'}, {'date': '05-29', 'label': '血压 · 餐前', 'value': '122/78', 'status': 'normal'}, {'date': '05-28', 'label': '血压 · 餐前', 'value': '118/76', 'status': 'normal'}, {'date': '05-27', 'label': '血糖 · 空腹', 'value': '5.6', 'status': 'normal'}, {'date': '05-26', 'label': '血压 · 餐前', 'value': '120/80', 'status': 'normal'}];
return Container(decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20), boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(10), blurRadius: 8, offset: const Offset(0, 2))]), child: Column(children: [Container(padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), child: Row(children: [const Text('历史记录', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))), const Spacer(), Text('查看更多', style: TextStyle(fontSize: 13, color: const Color(0xFF635BFF)))])), ...items.map(_historyItem)]));
return Container(decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(20), boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(10), blurRadius: 8, offset: const Offset(0, 2))]), child: Column(children: [Container(padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), child: Row(children: [const Text('历史记录', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))), const Spacer(), Text('查看更多', style: TextStyle(fontSize: 13, color: const Color(0xFF14B8A6)))])), ...items.map(_historyItem)]));
}
Widget _historyItem(Map<String, dynamic> item) {

View File

@@ -11,7 +11,7 @@ class ProfilePage extends ConsumerWidget {
final user = auth.user;
return Scaffold(
backgroundColor: const Color(0xFFF8F7FF),
backgroundColor: const Color(0xFFF6F9FB),
body: SafeArea(child: SingleChildScrollView(padding: const EdgeInsets.only(bottom: 20), child: Column(children: [
Container(width: double.infinity, padding: const EdgeInsets.all(24), decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24))), child: Column(children: [
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [Text('9:41', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Colors.grey[800])), Row(children: [Icon(Icons.wifi, size: 18, color: Colors.grey[700]), const SizedBox(width: 4), Icon(Icons.battery_full, size: 18, color: Colors.grey[700])]),]),
@@ -20,8 +20,8 @@ class ProfilePage extends ConsumerWidget {
GestureDetector(
onTap: () => pushRoute(ref, 'editProfile'),
child: Stack(children: [
CircleAvatar(radius: 32, backgroundColor: const Color(0xFFEDEBFF), backgroundImage: user?.avatarUrl != null ? NetworkImage(user!.avatarUrl!) : null, child: user?.avatarUrl == null ? const Icon(Icons.person, size: 40, color: Color(0xFF635BFF)) : null),
Positioned(right: 0, bottom: 0, child: Container(width: 22, height: 22, decoration: BoxDecoration(color: const Color(0xFF635BFF), borderRadius: BorderRadius.circular(11), border: Border.all(color: Colors.white, width: 2)), child: const Icon(Icons.edit, size: 12, color: Colors.white))),
CircleAvatar(radius: 32, backgroundColor: const Color(0xFFE6FAF6), backgroundImage: user?.avatarUrl != null ? NetworkImage(user!.avatarUrl!) : null, child: user?.avatarUrl == null ? const Icon(Icons.person, size: 40, color: Color(0xFF14B8A6)) : null),
Positioned(right: 0, bottom: 0, child: Container(width: 22, height: 22, decoration: BoxDecoration(color: const Color(0xFF14B8A6), borderRadius: BorderRadius.circular(11), border: Border.all(color: Colors.white, width: 2)), child: const Icon(Icons.edit, size: 12, color: Colors.white))),
]),
),
const SizedBox(width: 16),
@@ -87,7 +87,7 @@ class _MenuItem extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 14),
decoration: BoxDecoration(color: Colors.white),
child: Row(children: [
Container(width: 36, height: 36, decoration: BoxDecoration(color: const Color(0xFFF5F3FF), borderRadius: BorderRadius.circular(10)), child: Icon(icon, size: 18, color: const Color(0xFF635BFF))),
Container(width: 36, height: 36, decoration: BoxDecoration(color: const Color(0xFFF2FAF9), borderRadius: BorderRadius.circular(10)), child: Icon(icon, size: 18, color: const Color(0xFF14B8A6))),
const SizedBox(width: 12),
Text(title, style: const TextStyle(fontSize: 16, color: Color(0xFF1A1A1A))),
if (trailing != null && trailing!.isNotEmpty) ...[const Spacer(), Text(trailing!, style: TextStyle(fontSize: 14, color: Colors.grey[400]))],

View File

@@ -51,7 +51,7 @@ class ExercisePlanPage extends ConsumerWidget {
onPressed: () => _createDefaultPlan(ref, context),
icon: const Icon(Icons.add),
label: const Text('创建本周计划'),
backgroundColor: const Color(0xFF635BFF),
backgroundColor: const Color(0xFF14B8A6),
),
body: plan.when(
data: (data) {
@@ -82,7 +82,7 @@ class ExercisePlanPage extends ConsumerWidget {
}),
]);
},
loading: () => const Center(child: CircularProgressIndicator(color: Color(0xFF635BFF))),
loading: () => const Center(child: CircularProgressIndicator(color: Color(0xFF14B8A6))),
error: (_, __) => _empty(context, '运动计划', '暂无运动计划,点击右下角创建'),
),
);
@@ -94,7 +94,7 @@ class ExercisePlanPage extends ConsumerWidget {
margin: const EdgeInsets.all(16),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFFF5F3FF),
color: const Color(0xFFF2FAF9),
borderRadius: BorderRadius.circular(20),
),
child: Column(children: [
@@ -105,7 +105,7 @@ class ExercisePlanPage extends ConsumerWidget {
width: 60,
height: 60,
decoration: BoxDecoration(
color: const Color(0xFF635BFF),
color: const Color(0xFF14B8A6),
borderRadius: BorderRadius.circular(30),
),
child: Center(
@@ -123,7 +123,7 @@ class ExercisePlanPage extends ConsumerWidget {
child: FractionallySizedBox(
widthFactor: progress / 100,
child: Container(
decoration: BoxDecoration(color: const Color(0xFF635BFF), borderRadius: BorderRadius.circular(4)),
decoration: BoxDecoration(color: const Color(0xFF14B8A6), borderRadius: BorderRadius.circular(4)),
),
),
),
@@ -152,7 +152,7 @@ class ExercisePlanPage extends ConsumerWidget {
if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('运动计划已创建 ✅'),
backgroundColor: Color(0xFF635BFF),
backgroundColor: Color(0xFF14B8A6),
));
}
@@ -199,21 +199,21 @@ class _ExercisePlanItem extends StatelessWidget {
color: isToday ? const Color(0xFFFEFCE8) : Colors.white,
borderRadius: BorderRadius.circular(16),
border: isToday ? Border.all(color: const Color(0xFFFCD34D), width: 2) : null,
boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(8), blurRadius: 4, offset: const Offset(0, 2))],
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(8), blurRadius: 4, offset: const Offset(0, 2))],
),
child: Row(children: [
Container(
width: 40,
height: 40,
decoration: BoxDecoration(
color: isDone ? const Color(0xFFDCFCE7) : isRest ? const Color(0xFFF3F4F6) : const Color(0xFFF5F3FF),
color: isDone ? const Color(0xFFDCFCE7) : isRest ? const Color(0xFFF3F4F6) : const Color(0xFFF2FAF9),
borderRadius: BorderRadius.circular(12),
),
child: isDone
? const Icon(Icons.check, size: 20, color: Color(0xFF43A047))
: isRest
? const Icon(Icons.coffee, size: 20, color: Color(0xFF999999))
: const Icon(Icons.directions_run, size: 20, color: Color(0xFF635BFF)),
: const Icon(Icons.directions_run, size: 20, color: Color(0xFF14B8A6)),
),
const SizedBox(width: 12),
Expanded(
@@ -235,7 +235,7 @@ class _ExercisePlanItem extends StatelessWidget {
onPressed: onCheckIn,
child: const Text('打卡'),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF635BFF),
backgroundColor: const Color(0xFF14B8A6),
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
@@ -257,7 +257,7 @@ class FollowUpListPage extends ConsumerWidget {
floatingActionButton: FloatingActionButton(
onPressed: () => _showAddDialog(context),
child: const Icon(Icons.add),
backgroundColor: const Color(0xFF635BFF),
backgroundColor: const Color(0xFF14B8A6),
),
body: ListView(children: _mockFollowUps.map((item) => _FollowUpItem(item: item)).toList()),
);
@@ -284,7 +284,7 @@ class FollowUpListPage extends ConsumerWidget {
Navigator.pop(ctx);
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
content: Text('复查提醒已添加 ✅'),
backgroundColor: Color(0xFF635BFF),
backgroundColor: Color(0xFF14B8A6),
));
},
child: const Text('保存'),
@@ -314,7 +314,7 @@ class _FollowUpItem extends StatelessWidget {
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(10), blurRadius: 4, offset: const Offset(0, 2))],
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(10), blurRadius: 4, offset: const Offset(0, 2))],
),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(children: [
@@ -513,7 +513,7 @@ class _HealthCalendarPageState extends ConsumerState<HealthCalendarPage> {
return Container(
decoration: isToday ? BoxDecoration(
color: const Color(0xFF635BFF),
color: const Color(0xFF14B8A6),
borderRadius: BorderRadius.circular(20),
) : null,
child: Stack(
@@ -555,7 +555,7 @@ class _HealthCalendarPageState extends ConsumerState<HealthCalendarPage> {
Color _getEventColor(String type) {
switch (type) {
case 'medication': return const Color(0xFF635BFF);
case 'medication': return const Color(0xFF14B8A6);
case 'exercise': return const Color(0xFF43A047);
case 'followup': return const Color(0xFFF59E0B);
default: return Colors.grey;
@@ -564,7 +564,7 @@ class _HealthCalendarPageState extends ConsumerState<HealthCalendarPage> {
Widget _buildLegend() {
final items = [
{'color': const Color(0xFF635BFF), 'label': '用药提醒'},
{'color': const Color(0xFF14B8A6), 'label': '用药提醒'},
{'color': const Color(0xFF43A047), 'label': '运动计划'},
{'color': const Color(0xFFF59E0B), 'label': '复查随访'},
];

View File

@@ -14,12 +14,12 @@ class AiAnalysisPage extends ConsumerWidget {
Widget _buildTitle() {
return Row(mainAxisSize: MainAxisSize.min, children: [
Container(padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration(color: const Color(0xFF635BFF).withAlpha(15), borderRadius: BorderRadius.circular(12)), child: Row(mainAxisSize: MainAxisSize.min, children: [const Icon(Icons.auto_awesome, size: 16, color: Color(0xFF635BFF)), const SizedBox(width: 4), const Text('AI预解读', style: TextStyle(fontSize: 13, color: Color(0xFF635BFF), fontWeight: FontWeight.w500))])),
Container(padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration(color: const Color(0xFF14B8A6).withAlpha(15), borderRadius: BorderRadius.circular(12)), child: Row(mainAxisSize: MainAxisSize.min, children: [const Icon(Icons.auto_awesome, size: 16, color: Color(0xFF14B8A6)), const SizedBox(width: 4), const Text('AI预解读', style: TextStyle(fontSize: 13, color: Color(0xFF14B8A6), fontWeight: FontWeight.w500))])),
const SizedBox(width: 4), Text('血常规检查', style: TextStyle(color: Colors.grey[800], fontWeight: FontWeight.w600)),
]);
}
Widget _buildReportPreview() => Container(width: double.infinity, height: 180, decoration: BoxDecoration(color: const Color(0xFFF5F3FF), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFFE8E6FF), width: 1.5)), child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [Icon(Icons.description_outlined, size: 48, color: Colors.grey[400]), const SizedBox(height: 8), Text('检查报告图片', style: TextStyle(fontSize: 14, color: Colors.grey[600]))]));
Widget _buildReportPreview() => Container(width: double.infinity, height: 180, decoration: BoxDecoration(color: const Color(0xFFF2FAF9), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFFD4EDE8), width: 1.5)), child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [Icon(Icons.description_outlined, size: 48, color: Colors.grey[400]), const SizedBox(height: 8), Text('检查报告图片', style: TextStyle(fontSize: 14, color: Colors.grey[600]))]));
Widget _buildIndicators() {
final indicators = [{'name': '红细胞 (RBC)', 'value': '4.68', 'unit': '(×10¹²/L)', 'ref': '4.0-5.50', 'status': 'normal'}, {'name': '白细胞 (WBC)', 'value': '6.55', 'unit': '(×10⁹/L)', 'ref': '3.5-9.50', 'status': 'normal'}, {'name': '血红蛋白 (HGB)', 'value': '135', 'unit': '(g/L)', 'ref': '120-175', 'status': 'normal'}, {'name': '血小板 (PLT)', 'value': '235', 'unit': '(×10⁹/L)', 'ref': '125-350', 'status': 'normal'}];
@@ -31,11 +31,11 @@ class AiAnalysisPage extends ConsumerWidget {
return Container(margin: const EdgeInsets.only(bottom: 10), padding: const EdgeInsets.all(14), decoration: BoxDecoration(color: isNormal ? const Color(0xFFF8FDFB) : const Color(0xFFFFF8F5), borderRadius: BorderRadius.circular(14), border: Border.all(color: isNormal ? const Color(0xFFD4EDDA) : const Color(0xFFFFD7C5))), child: Row(children: [Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [Text(item['name']?.toString() ?? '', style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Color(0xFF333333))), const SizedBox(height: 4), Text('参考范围:${item['ref']?.toString() ?? ''}', style: TextStyle(fontSize: 12, color: Colors.grey[500]))])), Column(crossAxisAlignment: CrossAxisAlignment.end, children: [Text('${item['value']?.toString() ?? ''} ${item['unit']?.toString() ?? ''}', style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Color(0xFF1A1A1A))), const SizedBox(height: 2), Container(padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration(color: isNormal ? const Color(0xFF43A047).withAlpha(20) : const Color(0xFFFF9800).withAlpha(20), borderRadius: BorderRadius.circular(8)), child: Text(isNormal ? '正常' : '偏高', style: TextStyle(fontSize: 11, color: isNormal ? const Color(0xFF43A047) : const Color(0xFFFF9800))))])]));
}
Widget _buildAiInterpretation() => Container(width: double.infinity, padding: const EdgeInsets.all(16), decoration: BoxDecoration(color: const Color(0xFFF5F3FF), borderRadius: BorderRadius.circular(16)), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [Row(children: [Icon(Icons.auto_awesome, size: 18, color: const Color(0xFF635BFF)), const SizedBox(width: 6), Text('AI 智能解读', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))), const Spacer(), Container(padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration(color: const Color(0xFF635BFF).withAlpha(15), borderRadius: BorderRadius.circular(10)), child: const Text('已分析', style: TextStyle(fontSize: 11, color: Color(0xFF635BFF))))]), const SizedBox(height: 12), const Text('您的血常规检查结果基本正常,各项指标均在参考范围内。红细胞、白细胞、血小板计数均处于健康水平,血红蛋白含量充足,说明您的造血功能和免疫功能良好。建议继续保持良好的生活习惯,定期复查。', style: TextStyle(fontSize: 14, height: 1.6, color: Color(0xFF444444)))]));
Widget _buildAiInterpretation() => Container(width: double.infinity, padding: const EdgeInsets.all(16), decoration: BoxDecoration(color: const Color(0xFFF2FAF9), borderRadius: BorderRadius.circular(16)), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [Row(children: [Icon(Icons.auto_awesome, size: 18, color: const Color(0xFF14B8A6)), const SizedBox(width: 6), Text('AI 智能解读', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A))), const Spacer(), Container(padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration(color: const Color(0xFF14B8A6).withAlpha(15), borderRadius: BorderRadius.circular(10)), child: const Text('已分析', style: TextStyle(fontSize: 11, color: Color(0xFF14B8A6))))]), const SizedBox(height: 12), const Text('您的血常规检查结果基本正常,各项指标均在参考范围内。红细胞、白细胞、血小板计数均处于健康水平,血红蛋白含量充足,说明您的造血功能和免疫功能良好。建议继续保持良好的生活习惯,定期复查。', style: TextStyle(fontSize: 14, height: 1.6, color: Color(0xFF444444)))]));
Widget _buildDoctorAdvice() => Column(crossAxisAlignment: CrossAxisAlignment.start, children: [Row(children: [CircleAvatar(radius: 16, backgroundColor: const Color(0xFFEDEBFF), child: const Icon(Icons.local_hospital, size: 16, color: Color(0xFF635BFF))), const SizedBox(width: 8), const Text('医生建议', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)))]), const SizedBox(height: 12), Container(width: double.infinity, padding: const EdgeInsets.all(14), decoration: BoxDecoration(borderRadius: BorderRadius.circular(14), border: Border.all(color: const Color(0xFFEEEEEE))), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [_adviceItem('李医生', '心内科', '各项指标正常,继续保持。注意低盐饮食,适当运动。'), const Divider(), _adviceItem('王医生', '全科', '血常规结果理想,无需特殊处理。下次体检可关注血脂指标.')]))]);
Widget _buildDoctorAdvice() => Column(crossAxisAlignment: CrossAxisAlignment.start, children: [Row(children: [CircleAvatar(radius: 16, backgroundColor: const Color(0xFFE6FAF6), child: const Icon(Icons.local_hospital, size: 16, color: Color(0xFF14B8A6))), const SizedBox(width: 8), const Text('医生建议', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)))]), const SizedBox(height: 12), Container(width: double.infinity, padding: const EdgeInsets.all(14), decoration: BoxDecoration(borderRadius: BorderRadius.circular(14), border: Border.all(color: const Color(0xFFEEEEEE))), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [_adviceItem('李医生', '心内科', '各项指标正常,继续保持。注意低盐饮食,适当运动。'), const Divider(), _adviceItem('王医生', '全科', '血常规结果理想,无需特殊处理。下次体检可关注血脂指标.')]))]);
Widget _adviceItem(String name, String dept, String advice) => Padding(padding: const EdgeInsets.symmetric(vertical: 8), child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [CircleAvatar(radius: 14, backgroundColor: const Color(0xFFF5F3FF), child: Text(name[0], style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xFF635BFF)))), const SizedBox(width: 10), Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [Row(children: [Text(name, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Color(0xFF333333))), const SizedBox(width: 6), Text(dept, style: TextStyle(fontSize: 12, color: Colors.grey[500]))]), const SizedBox(height: 4), Text(advice, style: TextStyle(fontSize: 13, color: Colors.grey[700], height: 1.4))]))]));
Widget _adviceItem(String name, String dept, String advice) => Padding(padding: const EdgeInsets.symmetric(vertical: 8), child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [CircleAvatar(radius: 14, backgroundColor: const Color(0xFFF2FAF9), child: Text(name[0], style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xFF14B8A6)))), const SizedBox(width: 10), Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [Row(children: [Text(name, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Color(0xFF333333))), const SizedBox(width: 6), Text(dept, style: TextStyle(fontSize: 12, color: Colors.grey[500]))]), const SizedBox(height: 4), Text(advice, style: TextStyle(fontSize: 13, color: Colors.grey[700], height: 1.4))]))]));
Widget _buildHealthTips() => Column(crossAxisAlignment: CrossAxisAlignment.start, children: [Row(children: [Icon(Icons.lightbulb_outline, size: 18, color: const Color(0xFFFFB800)), const SizedBox(width: 8), const Text('健康提示', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF1A1A1A)))]), const SizedBox(height: 12), ...['定期进行血常规检查,建议每半年一次', '保持均衡饮食,多吃富含铁和维生素的食物', '适度运动每周至少150分钟中等强度有氧运动', '保证充足睡眠每晚7-8小时'].map((tip) => Padding(padding: const EdgeInsets.only(bottom: 8), child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [Container(margin: const EdgeInsets.only(top: 6), width: 6, height: 6, decoration: const BoxDecoration(color: Color(0xFFFFB800), shape: BoxShape.circle)), const SizedBox(width: 10), Expanded(child: Text(tip, style: TextStyle(fontSize: 14, color: Colors.grey[700], height: 1.4)))])))]);
}

View File

@@ -182,7 +182,7 @@ class ReportListPage extends ConsumerWidget {
appBar: AppBar(title: const Text('看报告')),
body: const Center(
child: Column(mainAxisSize: MainAxisSize.min, children: [
CircularProgressIndicator(color: Color(0xFF635BFF)),
CircularProgressIndicator(color: Color(0xFF14B8A6)),
SizedBox(height: 16),
Text('AI 正在分析报告...'),
]),
@@ -209,7 +209,7 @@ class ReportListPage extends ConsumerWidget {
Widget _buildUploadButton(BuildContext context, WidgetRef ref) {
return FloatingActionButton(
onPressed: () => _showUploadOptions(context, ref),
backgroundColor: const Color(0xFF635BFF),
backgroundColor: const Color(0xFF14B8A6),
child: const Icon(Icons.add),
);
}
@@ -266,10 +266,10 @@ class ReportListPage extends ConsumerWidget {
width: 120,
height: 120,
decoration: BoxDecoration(
color: const Color(0xFFF5F3FF),
color: const Color(0xFFF2FAF9),
borderRadius: BorderRadius.circular(60),
),
child: const Icon(Icons.file_open, size: 48, color: Color(0xFF635BFF)),
child: const Icon(Icons.file_open, size: 48, color: Color(0xFF14B8A6)),
),
const SizedBox(height: 20),
const Text('暂无检查报告', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500)),
@@ -285,14 +285,14 @@ class ReportListPage extends ConsumerWidget {
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [BoxShadow(color: const Color(0xFF635BFF).withAlpha(10), blurRadius: 4, offset: const Offset(0, 2))],
boxShadow: [BoxShadow(color: const Color(0xFF14B8A6).withAlpha(10), blurRadius: 4, offset: const Offset(0, 2))],
),
child: ListTile(
leading: Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: const Color(0xFFF5F3FF),
color: const Color(0xFFF2FAF9),
borderRadius: BorderRadius.circular(12),
),
child: _getReportIcon(report.type),
@@ -315,13 +315,13 @@ class ReportListPage extends ConsumerWidget {
Widget _getReportIcon(String type) {
final icons = {
'血液检查': const Icon(Icons.bloodtype, size: 24, color: Color(0xFF635BFF)),
'心电图': const Icon(Icons.monitor_heart, size: 24, color: Color(0xFF635BFF)),
'超声检查': const Icon(Icons.image, size: 24, color: Color(0xFF635BFF)),
'影像报告': const Icon(Icons.image, size: 24, color: Color(0xFF635BFF)),
'PDF文档': const Icon(Icons.picture_as_pdf, size: 24, color: Color(0xFF635BFF)),
'血液检查': const Icon(Icons.bloodtype, size: 24, color: Color(0xFF14B8A6)),
'心电图': const Icon(Icons.monitor_heart, size: 24, color: Color(0xFF14B8A6)),
'超声检查': const Icon(Icons.image, size: 24, color: Color(0xFF14B8A6)),
'影像报告': const Icon(Icons.image, size: 24, color: Color(0xFF14B8A6)),
'PDF文档': const Icon(Icons.picture_as_pdf, size: 24, color: Color(0xFF14B8A6)),
};
return icons[type] ?? const Icon(Icons.description, size: 24, color: Color(0xFF635BFF));
return icons[type] ?? const Icon(Icons.description, size: 24, color: Color(0xFF14B8A6));
}
String _formatDate(DateTime date) {
@@ -382,8 +382,8 @@ class ReportDetailPage extends ConsumerWidget {
icon: const Icon(Icons.image),
label: const Text('查看原始图片'),
style: OutlinedButton.styleFrom(
foregroundColor: const Color(0xFF635BFF),
side: const BorderSide(color: Color(0xFF635BFF)),
foregroundColor: const Color(0xFF14B8A6),
side: const BorderSide(color: Color(0xFF14B8A6)),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24)),
),
),
@@ -394,7 +394,7 @@ class ReportDetailPage extends ConsumerWidget {
height: 48,
child: ElevatedButton(
onPressed: () => pushRoute(ref, 'aiAnalysis'),
style: ElevatedButton.styleFrom(backgroundColor: const Color(0xFF635BFF), foregroundColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24))),
style: ElevatedButton.styleFrom(backgroundColor: const Color(0xFF14B8A6), foregroundColor: Colors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(24))),
child: const Text('查看 AI 智能解读'),
),
),
@@ -408,7 +408,7 @@ class ReportDetailPage extends ConsumerWidget {
return Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: const Color(0xFFF5F3FF),
color: const Color(0xFFF2FAF9),
borderRadius: BorderRadius.circular(16),
),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
@@ -430,7 +430,7 @@ class ReportDetailPage extends ConsumerWidget {
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: const Color(0xFFE8E6FF), width: 1.5),
border: Border.all(color: const Color(0xFFD4EDE8), width: 1.5),
),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Padding(

View File

@@ -49,7 +49,7 @@ class NotificationPrefsPage extends ConsumerWidget {
final dndOn = prefs['dndEnabled'] ?? false;
return Scaffold(
backgroundColor: const Color(0xFFF8F7FF),
backgroundColor: const Color(0xFFF6F9FB),
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
@@ -107,7 +107,7 @@ class NotificationPrefsPage extends ConsumerWidget {
_SwitchTile(
icon: Icons.smart_toy_outlined,
iconBg: const Color(0xFFF3E5F5),
iconColor: const Color(0xFF635BFF),
iconColor: const Color(0xFF14B8A6),
title: 'AI 回复通知',
subtitle: 'AI 助手回复时发送通知',
value: prefs['aiReply'] ?? false,
@@ -193,7 +193,7 @@ class _SwitchTile extends StatelessWidget {
Text(title, style: const TextStyle(fontSize: 15, color: Color(0xFF1A1A1A), fontWeight: FontWeight.w500)),
if (subtitle != null && subtitle!.isNotEmpty) Text(subtitle!, style: TextStyle(fontSize: 12, color: Colors.grey[500])),
])),
Switch(value: value, onChanged: onChanged, activeThumbColor: const Color(0xFF635BFF), activeTrackColor: const Color(0xFFC5BFFF)),
Switch(value: value, onChanged: onChanged, activeThumbColor: const Color(0xFF14B8A6), activeTrackColor: const Color(0xFFC5BFFF)),
]),
);
}
@@ -210,7 +210,7 @@ class _TimeButton extends StatelessWidget {
return GestureDetector(onTap: onTap, child: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
decoration: BoxDecoration(border: Border.all(color: const Color(0xFFE0E0E0)), borderRadius: BorderRadius.circular(10)),
child: Column(children: [Text(label, style: TextStyle(fontSize: 11, color: Colors.grey[500])), Text(time, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF635BFF)))]),
child: Column(children: [Text(label, style: TextStyle(fontSize: 11, color: Colors.grey[500])), Text(time, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xFF14B8A6)))]),
));
}
}

View File

@@ -8,7 +8,7 @@ class SettingsPage extends ConsumerWidget {
@override Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
backgroundColor: const Color(0xFFF8F7FF),
backgroundColor: const Color(0xFFF6F9FB),
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
@@ -72,7 +72,7 @@ class _SetItem extends StatelessWidget {
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 14),
decoration: BoxDecoration(color: Colors.white),
child: Row(children: [
Container(width: 36, height: 36, decoration: BoxDecoration(color: const Color(0xFFF5F3FF), borderRadius: BorderRadius.circular(10)), child: Icon(icon, size: 18, color: const Color(0xFF635BFF))),
Container(width: 36, height: 36, decoration: BoxDecoration(color: const Color(0xFFF2FAF9), borderRadius: BorderRadius.circular(10)), child: Icon(icon, size: 18, color: const Color(0xFF14B8A6))),
const SizedBox(width: 12),
Expanded(child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [Text(title, style: const TextStyle(fontSize: 16, color: Color(0xFF1A1A1A))), if (subtitle != null && subtitle!.isNotEmpty) Text(subtitle!, style: TextStyle(fontSize: 13, color: Colors.grey[500]))])),
if (trailingText != null && trailingText!.isNotEmpty) Text(trailingText!, style: TextStyle(fontSize: 14, color: Colors.grey[400])),