fix: 登录页白底+渐变边框/胶囊加大/底部提示/今日健康优化/发送按钮蓝紫渐变
- 登录页:输入框白底+渐变紫蓝外框,去掉focus内框;登录按钮白底紫字;协议勾选白底 - 首页胶囊:适老化加大(内边距14x8/字号15/图标17/圆角18) - 欢迎卡片底部提示:各智能体专属引导文案,字号加大颜色加深 - 今日健康卡片:健康指标改一行总结(异常提醒/正常显示);用药显示具体药品名+状态 - 发送按钮:蓝→紫渐变 - 设置页菜单:白色卡片+圆角16+轻阴影 - IP改localhost:adb reverse解决IP变动问题 - 服药打卡快捷按钮:改为跳转打卡页,不再一键全打
This commit is contained in:
@@ -3,7 +3,7 @@ import 'package:dio/dio.dart';
|
|||||||
import 'local_database.dart';
|
import 'local_database.dart';
|
||||||
|
|
||||||
/// API 基础地址
|
/// API 基础地址
|
||||||
const String baseUrl = 'http://10.4.164.158:5000';
|
const String baseUrl = 'http://localhost:5000';
|
||||||
|
|
||||||
/// Dio HTTP 客户端封装——带 token 注入、401 自动刷新
|
/// Dio HTTP 客户端封装——带 token 注入、401 自动刷新
|
||||||
class ApiClient {
|
class ApiClient {
|
||||||
|
|||||||
@@ -92,30 +92,40 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
|
|
||||||
// 手机号
|
// 手机号
|
||||||
Container(
|
Container(
|
||||||
height: 52,
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: AppColors.backgroundSoft,
|
gradient: AppColors.primaryGradient,
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
child: Row(children: [
|
padding: const EdgeInsets.all(1.5),
|
||||||
const Padding(padding: EdgeInsets.only(left: 16), child: Text('+86', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: AppColors.textPrimary))),
|
child: Container(
|
||||||
Container(width: 1, height: 24, color: AppColors.border, margin: const EdgeInsets.symmetric(horizontal: 12)),
|
height: 52,
|
||||||
Expanded(
|
decoration: BoxDecoration(
|
||||||
child: TextField(
|
color: Colors.white,
|
||||||
controller: _phoneCtrl,
|
borderRadius: BorderRadius.circular(9),
|
||||||
keyboardType: TextInputType.phone,
|
),
|
||||||
maxLength: 11,
|
child: Row(children: [
|
||||||
style: const TextStyle(fontSize: 16, color: AppColors.textPrimary),
|
const Padding(padding: EdgeInsets.only(left: 16), child: Text('+86', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: AppColors.textPrimary))),
|
||||||
decoration: const InputDecoration(
|
Container(width: 1, height: 24, color: AppColors.border, margin: const EdgeInsets.symmetric(horizontal: 12)),
|
||||||
hintText: '请输入手机号',
|
Expanded(
|
||||||
hintStyle: TextStyle(fontSize: 15, color: AppColors.textHint),
|
child: TextField(
|
||||||
border: InputBorder.none,
|
controller: _phoneCtrl,
|
||||||
counterText: '',
|
keyboardType: TextInputType.phone,
|
||||||
contentPadding: EdgeInsets.symmetric(vertical: 14),
|
maxLength: 11,
|
||||||
|
style: const TextStyle(fontSize: 16, color: AppColors.textPrimary),
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
filled: false,
|
||||||
|
hintText: '请输入手机号',
|
||||||
|
hintStyle: TextStyle(fontSize: 15, color: AppColors.textHint),
|
||||||
|
border: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
counterText: '',
|
||||||
|
contentPadding: EdgeInsets.symmetric(vertical: 14),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
]),
|
||||||
]),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
@@ -123,22 +133,32 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
Row(children: [
|
Row(children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 52,
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: AppColors.backgroundSoft,
|
gradient: AppColors.primaryGradient,
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
child: TextField(
|
padding: const EdgeInsets.all(1.5),
|
||||||
controller: _codeCtrl,
|
child: Container(
|
||||||
keyboardType: TextInputType.number,
|
height: 52,
|
||||||
maxLength: 6,
|
decoration: BoxDecoration(
|
||||||
style: const TextStyle(fontSize: 16, color: AppColors.textPrimary),
|
color: Colors.white,
|
||||||
decoration: const InputDecoration(
|
borderRadius: BorderRadius.circular(9),
|
||||||
hintText: '验证码',
|
),
|
||||||
hintStyle: TextStyle(fontSize: 15, color: AppColors.textHint),
|
child: TextField(
|
||||||
border: InputBorder.none,
|
controller: _codeCtrl,
|
||||||
counterText: '',
|
keyboardType: TextInputType.number,
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
maxLength: 6,
|
||||||
|
style: const TextStyle(fontSize: 16, color: AppColors.textPrimary),
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
filled: false,
|
||||||
|
hintText: '验证码',
|
||||||
|
hintStyle: TextStyle(fontSize: 15, color: AppColors.textHint),
|
||||||
|
border: InputBorder.none,
|
||||||
|
enabledBorder: InputBorder.none,
|
||||||
|
focusedBorder: InputBorder.none,
|
||||||
|
counterText: '',
|
||||||
|
contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -150,7 +170,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
width: 120, height: 52,
|
width: 120, height: 52,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: (_countdown > 0 || _sending) ? AppColors.backgroundSoft : AppColors.primary,
|
color: (_countdown > 0 || _sending) ? Colors.white : AppColors.primary,
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
@@ -170,7 +190,7 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
Container(
|
Container(
|
||||||
width: 18, height: 18, margin: const EdgeInsets.only(right: 6),
|
width: 18, height: 18, margin: const EdgeInsets.only(right: 6),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: _agreed ? AppColors.primary : Colors.transparent,
|
color: _agreed ? AppColors.primary : Colors.white,
|
||||||
borderRadius: BorderRadius.circular(4),
|
borderRadius: BorderRadius.circular(4),
|
||||||
border: Border.all(color: _agreed ? AppColors.primary : AppColors.border, width: 1.5),
|
border: Border.all(color: _agreed ? AppColors.primary : AppColors.border, width: 1.5),
|
||||||
),
|
),
|
||||||
@@ -196,12 +216,13 @@ class _LoginPageState extends ConsumerState<LoginPage> {
|
|||||||
child: Container(
|
child: Container(
|
||||||
width: double.infinity, height: 52, alignment: Alignment.center,
|
width: double.infinity, height: 52, alignment: Alignment.center,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: AppColors.primaryGradient,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
border: Border.all(color: AppColors.primary, width: 1.5),
|
||||||
),
|
),
|
||||||
child: _loading
|
child: _loading
|
||||||
? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2.5, color: Colors.white))
|
? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2.5, color: AppColors.primary))
|
||||||
: const Text('登 录', style: TextStyle(fontSize: 18, color: Colors.white, fontWeight: FontWeight.w600, letterSpacing: 2)),
|
: const Text('登 录', style: TextStyle(fontSize: 18, color: AppColors.primary, fontWeight: FontWeight.w600, letterSpacing: 2)),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
|||||||
@@ -232,7 +232,11 @@ class _HomePageState extends ConsumerState<HomePage> {
|
|||||||
width: 40, height: 40,
|
width: 40, height: 40,
|
||||||
margin: EdgeInsets.only(bottom: _pickedImagePath != null ? 0 : 4),
|
margin: EdgeInsets.only(bottom: _pickedImagePath != null ? 0 : 4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: AppColors.blueMeasure,
|
gradient: const LinearGradient(
|
||||||
|
colors: [AppColors.blueMeasure, AppColors.primary],
|
||||||
|
begin: Alignment.topLeft,
|
||||||
|
end: Alignment.bottomRight,
|
||||||
|
),
|
||||||
borderRadius: BorderRadius.circular(20),
|
borderRadius: BorderRadius.circular(20),
|
||||||
),
|
),
|
||||||
child: const Icon(LucideIcons.send, size: 20, color: Colors.white),
|
child: const Icon(LucideIcons.send, size: 20, color: Colors.white),
|
||||||
|
|||||||
@@ -196,11 +196,18 @@ class ChatMessagesView extends ConsumerWidget {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.fromLTRB(16, 14, 16, 0),
|
padding: const EdgeInsets.fromLTRB(16, 14, 16, 0),
|
||||||
child: features.any((f) => f.imageAsset != null)
|
child: features.any((f) => f.imageAsset != null)
|
||||||
? ClipRRect(
|
? Container(
|
||||||
borderRadius: BorderRadius.circular(20),
|
decoration: BoxDecoration(
|
||||||
child: Image.asset(
|
gradient: iconGradient,
|
||||||
features.firstWhere((f) => f.imageAsset != null).imageAsset!,
|
borderRadius: BorderRadius.circular(20),
|
||||||
width: double.infinity, height: 170, fit: BoxFit.fill,
|
),
|
||||||
|
padding: const EdgeInsets.all(2),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: BorderRadius.circular(18),
|
||||||
|
child: Image.asset(
|
||||||
|
features.firstWhere((f) => f.imageAsset != null).imageAsset!,
|
||||||
|
width: double.infinity, height: 170, fit: BoxFit.fill,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Container(
|
: Container(
|
||||||
@@ -289,7 +296,7 @@ class ChatMessagesView extends ConsumerWidget {
|
|||||||
child: Row(children: [
|
child: Row(children: [
|
||||||
Icon(Icons.lightbulb_outline, size: 18, color: agentColors.accent),
|
Icon(Icons.lightbulb_outline, size: 18, color: agentColors.accent),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Expanded(child: Text('直接描述您的需求,AI 会自动为您记录和分析', style: TextStyle(fontSize: 14, color: agentColors.accent, fontWeight: FontWeight.w500))),
|
Expanded(child: Text(_agentTip(agent), style: TextStyle(fontSize: 15, color: AppColors.textPrimary.withAlpha(180), fontWeight: FontWeight.w500))),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -304,7 +311,7 @@ class ChatMessagesView extends ConsumerWidget {
|
|||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (a.label == '服药打卡') {
|
if (a.label == '服药打卡') {
|
||||||
_medicationCheckIn(ref, context);
|
pushRoute(ref, 'medCheckIn');
|
||||||
} else if (a.action == 'pickFoodCamera' || a.action == 'pickFoodGallery') {
|
} else if (a.action == 'pickFoodCamera' || a.action == 'pickFoodGallery') {
|
||||||
ref.read(dietActionProvider.notifier).trigger(a.action!);
|
ref.read(dietActionProvider.notifier).trigger(a.action!);
|
||||||
} else if (a.route != null) {
|
} else if (a.route != null) {
|
||||||
@@ -346,7 +353,7 @@ class ChatMessagesView extends ConsumerWidget {
|
|||||||
List<_AgentFeature> _getAgentFeatures(ActiveAgent agent) {
|
List<_AgentFeature> _getAgentFeatures(ActiveAgent agent) {
|
||||||
return switch (agent) {
|
return switch (agent) {
|
||||||
ActiveAgent.health => [
|
ActiveAgent.health => [
|
||||||
_AgentFeature(Icons.trending_up, '趋势分析', '查看历史数据'),
|
_AgentFeature(Icons.trending_up, '趋势分析', '查看历史数据', imageAsset: 'assets/images/Data.png'),
|
||||||
_AgentFeature(Icons.add, '快速录入', '血压心率血糖'),
|
_AgentFeature(Icons.add, '快速录入', '血压心率血糖'),
|
||||||
],
|
],
|
||||||
ActiveAgent.diet => [
|
ActiveAgent.diet => [
|
||||||
@@ -354,7 +361,7 @@ class ChatMessagesView extends ConsumerWidget {
|
|||||||
_AgentFeature(Icons.bar_chart, '营养分析', '热量营养成分'),
|
_AgentFeature(Icons.bar_chart, '营养分析', '热量营养成分'),
|
||||||
],
|
],
|
||||||
ActiveAgent.medication => [
|
ActiveAgent.medication => [
|
||||||
_AgentFeature(Icons.list, '用药清单', '管理所有药品'),
|
_AgentFeature(Icons.list, '用药清单', '管理所有药品', imageAsset: 'assets/images/Medicine.png'),
|
||||||
_AgentFeature(Icons.alarm, '智能提醒', '按时服药提醒'),
|
_AgentFeature(Icons.alarm, '智能提醒', '按时服药提醒'),
|
||||||
],
|
],
|
||||||
ActiveAgent.consultation => [
|
ActiveAgent.consultation => [
|
||||||
@@ -1195,6 +1202,16 @@ class ChatMessagesView extends ConsumerWidget {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String _agentTip(ActiveAgent agent) => switch (agent) {
|
||||||
|
ActiveAgent.health => '直接说出您的症状或数据,如"血压130/85,心率72"',
|
||||||
|
ActiveAgent.diet => '拍照或描述您吃了什么,如"早餐吃了两个鸡蛋一杯牛奶"',
|
||||||
|
ActiveAgent.medication => '说出药品名称和用法,如"每天早晚各一片阿司匹林"',
|
||||||
|
ActiveAgent.consultation => '描述您的症状和不适感,如"最近总是头晕胸闷"',
|
||||||
|
ActiveAgent.report => '上传您的检查报告,AI 将自动提取指标并解读',
|
||||||
|
ActiveAgent.exercise => '说出运动计划,如"每天散步30分钟坚持一周"',
|
||||||
|
_ => '直接描述您的需求,AI 会自动为您记录和分析',
|
||||||
|
};
|
||||||
|
|
||||||
static ActiveAgent _parseAgentFromName(String? name) {
|
static ActiveAgent _parseAgentFromName(String? name) {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case 'consultation': return ActiveAgent.consultation;
|
case 'consultation': return ActiveAgent.consultation;
|
||||||
@@ -1246,25 +1263,20 @@ class ChatMessagesView extends ConsumerWidget {
|
|||||||
trailing: '今日暂无记录,点击录入',
|
trailing: '今日暂无记录,点击录入',
|
||||||
status: 'pending', iconColor: healthIconColor, iconBg: healthIconBg,
|
status: 'pending', iconColor: healthIconColor, iconBg: healthIconBg,
|
||||||
onTap: () => pushRoute(ref, 'trend')));
|
onTap: () => pushRoute(ref, 'trend')));
|
||||||
} else {
|
} else if (hasAbnormal) {
|
||||||
final parts = <String>[];
|
// 有异常时显示异常指标
|
||||||
if (bpText != null) parts.add('血压 $bpText');
|
final abnormalParts = <String>[];
|
||||||
if (hrText != null) parts.add('心率 $hrText');
|
if (bpAbnormal) abnormalParts.add('血压 ${bp['systolic']}/${bp['diastolic']} 偏高');
|
||||||
if (bsText != null) parts.add('血糖 $bsText');
|
tasks.add(_taskRow(context, Icons.warning_amber_rounded, '健康指标',
|
||||||
if (boText != null) parts.add('血氧 $boText');
|
trailing: abnormalParts.join(' · '),
|
||||||
if (wtText != null) parts.add('体重 $wtText');
|
status: 'warning', iconColor: healthIconColor, iconBg: healthIconBg,
|
||||||
tasks.add(_taskRow(context, Icons.check_circle, '健康指标',
|
onTap: () => pushRoute(ref, 'trend')));
|
||||||
trailing: parts.join(' · '),
|
} else {
|
||||||
status: hasAbnormal ? 'warning' : 'done',
|
// 全部正常
|
||||||
iconColor: healthIconColor, iconBg: healthIconBg,
|
tasks.add(_taskRow(context, Icons.check_circle, '健康指标',
|
||||||
|
trailing: '指标正常',
|
||||||
|
status: 'done', iconColor: healthIconColor, iconBg: healthIconBg,
|
||||||
onTap: () => pushRoute(ref, 'trend')));
|
onTap: () => pushRoute(ref, 'trend')));
|
||||||
}
|
|
||||||
if (bpAbnormal) {
|
|
||||||
final s = bp['systolic'];
|
|
||||||
final d = bp['diastolic'] ?? '--';
|
|
||||||
tasks.add(_taskRow(context, Icons.warning_amber_rounded, '血压 $s/$d 偏高,请关注',
|
|
||||||
status: 'warning',
|
|
||||||
onTap: () => pushRoute(ref, 'trend', params: {'type': 'blood_pressure'})));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── 2. 运动 ──
|
// ── 2. 运动 ──
|
||||||
@@ -1302,21 +1314,29 @@ class ChatMessagesView extends ConsumerWidget {
|
|||||||
const medIconColor = Color(0xFFEC4899);
|
const medIconColor = Color(0xFFEC4899);
|
||||||
const medIconBg = Color(0xFFFCE7F3);
|
const medIconBg = Color(0xFFFCE7F3);
|
||||||
reminders.whenOrNull(data: (meds) {
|
reminders.whenOrNull(data: (meds) {
|
||||||
final overdue = meds.where((m) => m['status'] == 'overdue').length;
|
if (meds.isNotEmpty) {
|
||||||
final upcoming = meds.where((m) => m['status'] == 'upcoming').length;
|
final overdueMeds = meds.where((m) => m['status'] == 'overdue').toList();
|
||||||
final taken = meds.where((m) => m['status'] == 'taken').length;
|
final upcomingMeds = meds.where((m) => m['status'] == 'upcoming').toList();
|
||||||
final total = overdue + upcoming + taken;
|
final takenMeds = meds.where((m) => m['status'] == 'taken').toList();
|
||||||
if (total > 0) {
|
// 未服/过期的在前面
|
||||||
final parts = <String>[];
|
for (final m in [...overdueMeds, ...upcomingMeds]) {
|
||||||
if (overdue > 0) parts.add('$overdue项过期');
|
final name = m['name']?.toString() ?? '药品';
|
||||||
if (upcoming > 0) parts.add('$upcoming项待服');
|
final time = m['scheduledTime']?.toString() ?? '';
|
||||||
if (taken > 0) parts.add('$taken项已服');
|
final isOverdue = m['status'] == 'overdue';
|
||||||
tasks.add(_taskRow(context, Icons.medication_rounded, '用药打卡 ($total项)',
|
tasks.add(_taskRow(context, Icons.medication_rounded, name,
|
||||||
trailing: parts.join(' · '),
|
trailing: '${isOverdue ? "❗过期" : "⏳待服"} $time',
|
||||||
status: overdue > 0 ? 'overdue' : upcoming > 0 ? 'pending' : 'done',
|
status: isOverdue ? 'overdue' : 'pending',
|
||||||
iconColor: medIconColor, iconBg: medIconBg,
|
iconColor: medIconColor, iconBg: medIconBg,
|
||||||
onTap: () => pushRoute(ref, 'medCheckIn'),
|
onTap: () => pushRoute(ref, 'medCheckIn')));
|
||||||
));
|
}
|
||||||
|
// 已服的合并显示
|
||||||
|
if (takenMeds.isNotEmpty) {
|
||||||
|
final names = takenMeds.map((m) => m['name']?.toString() ?? '药品').join('、');
|
||||||
|
tasks.add(_taskRow(context, Icons.check_circle, names,
|
||||||
|
trailing: '已服用 (${takenMeds.length}项)',
|
||||||
|
status: 'done',
|
||||||
|
iconColor: medIconColor, iconBg: medIconBg));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
final hasMeds = reminders.asData?.value != null && (reminders.asData!.value).isNotEmpty;
|
final hasMeds = reminders.asData?.value != null && (reminders.asData!.value).isNotEmpty;
|
||||||
|
|||||||
@@ -22,45 +22,45 @@ class AppMenuItem extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = ShadTheme.of(context);
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 24, vertical: 2),
|
margin: const EdgeInsets.symmetric(horizontal: 24, vertical: 4),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 14),
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: theme.colorScheme.card,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(AppTheme.rSm),
|
borderRadius: BorderRadius.circular(16),
|
||||||
|
boxShadow: [BoxShadow(color: Colors.black.withAlpha(6), blurRadius: 8, offset: const Offset(0, 2))],
|
||||||
),
|
),
|
||||||
child: Row(children: [
|
child: Row(children: [
|
||||||
Container(
|
Container(
|
||||||
width: 38,
|
width: 40,
|
||||||
height: 38,
|
height: 40,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: AppColors.cardInner,
|
||||||
borderRadius: BorderRadius.circular(AppTheme.rSm),
|
borderRadius: BorderRadius.circular(12),
|
||||||
),
|
),
|
||||||
child: Icon(icon, size: 22, color: AppColors.textPrimary),
|
child: Icon(icon, size: 22, color: AppColors.textPrimary),
|
||||||
),
|
),
|
||||||
const SizedBox(width: AppTheme.sLg),
|
const SizedBox(width: 14),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(title, style: TextStyle(fontSize: 19, fontWeight: FontWeight.w500, color: theme.colorScheme.foreground)),
|
Text(title, style: const TextStyle(fontSize: 17, fontWeight: FontWeight.w500, color: AppColors.textPrimary)),
|
||||||
if (subtitle != null && subtitle!.isNotEmpty)
|
if (subtitle != null && subtitle!.isNotEmpty)
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 2),
|
padding: const EdgeInsets.only(top: 2),
|
||||||
child: Text(subtitle!, style: TextStyle(fontSize: 16, color: theme.colorScheme.mutedForeground)),
|
child: Text(subtitle!, style: const TextStyle(fontSize: 14, color: AppColors.textHint)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (trailing != null && trailing!.isNotEmpty)
|
if (trailing != null && trailing!.isNotEmpty)
|
||||||
Text(trailing!, style: TextStyle(fontSize: 17, color: theme.colorScheme.mutedForeground)),
|
Text(trailing!, style: const TextStyle(fontSize: 15, color: AppColors.textHint)),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Icon(LucideIcons.chevronRight, size: 21, color: theme.colorScheme.mutedForeground),
|
const Icon(Icons.chevron_right, size: 20, color: AppColors.textHint),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user